Improve debug rom to catch common exception conditions

This commit is contained in:
Nero 2019-10-18 13:50:42 +00:00
parent e70386bcfb
commit 50e58765b1
3 changed files with 152 additions and 201 deletions

View File

@ -18,7 +18,7 @@ QEMU_ARGS += --enable-kvm
endif
ifdef DEBUG
ROMS += debug.rom
ROMS += rom/debug.rom
NASM_ARGS += -l $(basename $@).lst
endif
@ -33,15 +33,15 @@ default: fdimage.img
rdos.bin: kernel/*.asm lib/*.asm
$(NASM) $(NASM_ARGS) -o $@ -I kernel kernel/main.asm
debug.rom: debug/*.asm lib/*.asm
$(NASM) $(NASM_ARGS) -o $@ -I debug debug/main.asm && utils/fix-rom.sh $@
boot/%.bs: boot/%.asm
$(NASM) $(NASM_ARGS) -DFLOPPY=$(FLOPPY) -o $@ $<
programs/%.com: programs/%.asm
$(NASM) $(NASM_ARGS) -o $@ $<
rom/%.rom: rom/%.asm
$(NASM) $(NASM_ARGS) -o $@ $< && utils/fix-rom.sh $@
fdimage.img: boot/fat.bs $(DISTFILES)
mformat -C -i $@ -f $(FLOPPY) -B boot/fat.bs ::
mcopy -i $@ $(DISTFILES) ::
@ -51,7 +51,7 @@ hdimage.img: boot/mbr.bs fdimage.img
clean:
find -name '*.lst' -delete
rm -f $$(cat .gitignore) programs/*.com boot/*.bs utils/emul
rm -f $$(cat .gitignore) programs/*.com boot/*.bs rom/*.rom utils/emul
qemu-floppy: fdimage.img $(ROMS)
$(QEMU) $(QEMU_ARGS) -boot c -fda fdimage.img

View File

@ -1,127 +0,0 @@
; Names for words in debug frame
; Two characters per word, 14 words total
debug_frame_names:
; general-purpose registers
db "AXCXDXBXSPBPSIDI"
; extra registers
db "DSESSSIPCSFL"
; Names for bits in debug_frame+26 (FL/Flags register)
; One character per bit, 16 bits total
debug_frame_flags:
db "++++ODIT"
db "SZ+A+P+C"
; Print a single register from the frame
; in SI frame offset for register
debug_frame_register_print:
mov bx, debug_frame_names
mov al, [cs:bx+si] ; first name char load
call putc
mov al, [cs:bx+si+1] ; second name char load
call putc
mov al, '='
call putc
mov ax, [ss:bp+si] ; value load
; prepare call to print_number
push bx
push cx
mov bx, 0x0010
mov cx, 3
call print_number_padded
pop cx
pop bx
mov al, ' '
call putc
ret
debug_frame_print:
mov si, 0
mov cx, 8
.reg1loop:
call debug_frame_register_print
add si, 2
loop .reg1loop
mov dx, [ss:bp+26]
mov di, debug_frame_flags
mov cx, 0x0010
.flag_loop:
mov al, [cs:di]
inc di
cmp al, '+'
je .next
test dx, 0x8000
jnz .write
mov al, '-'
.write:
call putc
.next:
sal dx, 1
loop .flag_loop
call printf
db 0x0A, 0x0D, 0
mov si, 16
mov cx, 3
.reg2loop:
call debug_frame_register_print
add si, 2
loop .reg2loop
mov ax, [bp+24]
mov bx, 0x0010
mov cx, 3
call print_number_padded
mov al, ':'
call putc
mov ax, [bp+22]
mov bx, 0x0010
mov cx, 3
call print_number_padded
call printf
db 0x0A, 0x0D, 0
ret
; this prints registers
; expect to be called as interrupt routine
isr_debug:
push ss
push es
push ds
push di
push si
push bp
push sp
push bx
push dx
push cx
push ax
mov bp, sp
mov [bp+08], bp
add WORD [bp+08], 28
call printf
db 0x0A, 0x0D, 0
call debug_frame_print
pop ax
pop cx
pop dx
pop bx
add sp, 2 ; ignore SP
pop bp
pop bp
pop si
pop di
pop ds
pop es
add sp, 2 ; ignore SS
iret

View File

@ -1,19 +1,49 @@
cpu 8086
org 0x0000
%macro push8086 0
push ss
push es
push ds
push di
push si
push bp
push sp
push bx
push dx
push cx
push ax
; adjust stored SP to be value before interrupt
mov bp, sp
mov [bp+08], bp
add WORD [bp+08], 28
%endmacro
%macro pop8086 0
pop ax
pop cx
pop dx
pop bx
add sp, 2 ; skip SP
pop bp
pop si
pop di
pop ds
pop es
add sp, 2 ; skip SS
%endmacro
rom:
db 0x55, 0xAA
.sectors:
db 0x00
.init:
mov dx, isr_debug
mov al, 0x1
call intr_register
mov al, 0x03
call intr_register
retf
jmp init
nop
.name:
db "rDebug", 0
db "RDOS debug rom", 0
times (0x18 - ($-$$)) db 0
.pcir_ptr:
@ -44,6 +74,48 @@ pnp:
dw 0 ; reserved
dw 0
init:
mov bx, 0
mov dx, isr_divide_error
call hook_int
mov bx, 1
mov dx, isr_singlestep
call hook_int
mov bx, 2
mov dx, isr_nmi
call hook_int
mov bx, 3
mov dx, isr_breakpoint
call hook_int
mov bx, 4
mov dx, isr_overflow
call hook_int
; 5 left out
mov bx, 6
mov dx, isr_invalid_opcode
call hook_int
retf
; Hook interrupt
hook_int:
; bx times 4
add bx, bx
add bx, bx
; store offset
mov [bx], dx
; store segment
push ax
mov ax, cs
mov [bx+2], ax
pop ax
ret
putc:
push bx
push cx
@ -54,26 +126,6 @@ putc:
pop bx
ret
intr_register:
; DI = AL * 4
mov ah, 4
mul ah
mov di, ax
; ES = 0
xor ax, ax
mov es, ax
; store offset
mov ax, dx
stosw
; store segment
mov ax, cs
stosw
ret
; Names for words in debug frame
; Two characters per word, 14 words total
debug_frame_names:
@ -140,67 +192,93 @@ debug_frame_print:
db 0x0A, 0x0D, 0
mov si, 16
mov cx, 3
mov cx, 5
.reg2loop:
call debug_frame_register_print
add si, 2
loop .reg2loop
mov ax, [bp+24]
mov bx, 0x0010
mov cx, 3
call print_number_padded
mov al, ':'
call putc
mov ax, [bp+22]
mov bx, 0x0010
mov cx, 3
call print_number_padded
call printf
db 0x0A, 0x0D, 0
ret
; this prints registers
; expect to be called as interrupt routine
isr_debug:
push ss
push es
push ds
push di
push si
push bp
push sp
push bx
push dx
push cx
push ax
isr_divide_error:
push8086
mov bp, sp
mov [bp+08], bp
add WORD [bp+08], 28
call printf
db 0x0A, 0x0D, "INT 0 - DIVIDE ERROR", 0x0A, 0x0D, 0
call debug_frame_print
jmp halt
isr_singlestep:
push8086
call printf
db 0x0A, 0x0D, 0
call debug_frame_print
pop ax
pop cx
pop dx
pop bx
pop bp
pop bp
pop si
pop di
pop ds
pop es
pop ss
; wait for keypress
xor ax, ax
int 0x16
; enable trace flag so we fire again after next instruction
or word [ss:bp+26], 0x0100
pop8086
iret
isr_nmi:
push8086
call printf
db 0x0A, 0x0D, "INT 2 - NON-MASKABLE INTERRUPT", 0x0A, 0x0D, 0
call debug_frame_print
jmp halt
isr_breakpoint:
push8086
call printf
db 0x0A, 0x0D, 0
call debug_frame_print
pop8086
iret
isr_overflow:
push8086
call printf
db 0x0A, 0x0D, "INT 4 - OVERFLOW", 0x0A, 0x0D, 0
call debug_frame_print
jmp halt
isr_invalid_opcode:
push8086
call printf
db 0x0A, 0x0D, "INT 6 - INVALID OPCODE", 0x0A, 0x0D, 0
call debug_frame_print
jmp halt
halt:
call printf
db "HALTED", 0x0A, 0x0D, 0
.loop:
hlt
jmp halt
%include "printf.asm"
align 512