From 50e58765b107c908bf42e875b4c98f0fc4cf3b1b Mon Sep 17 00:00:00 2001 From: Ain <41307858+nero@users.noreply.github.com> Date: Fri, 18 Oct 2019 13:50:42 +0000 Subject: [PATCH] Improve debug rom to catch common exception conditions --- Makefile | 10 +- debug/debug.asm | 127 ------------------- debug/main.asm => rom/debug.asm | 216 ++++++++++++++++++++++---------- 3 files changed, 152 insertions(+), 201 deletions(-) delete mode 100644 debug/debug.asm rename debug/main.asm => rom/debug.asm (61%) diff --git a/Makefile b/Makefile index 5229dd6..2adb2f3 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/debug/debug.asm b/debug/debug.asm deleted file mode 100644 index 05c7910..0000000 --- a/debug/debug.asm +++ /dev/null @@ -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 diff --git a/debug/main.asm b/rom/debug.asm similarity index 61% rename from debug/main.asm rename to rom/debug.asm index 5ca7610..68b4737 100644 --- a/debug/main.asm +++ b/rom/debug.asm @@ -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