cpu 8086 org 0x0000 ; interrupt vector we store addr of data segment in bssvec: equ 0xB6 db 0x55, 0xAA db 0x00 jmp near init times (0x18 - ($-$$)) db 0 dw 0 dw pnp pnp: db "$PnP" db 1 ; version 1 db 2 ; 2 * 16 length dw 0 ; offset of next header db 0 db 0 ; checksum (filled by fix-rom) dd 0 ; device identifier dw 0 ; manufacturer string dw name ; product name string db 0,0,0 ; device type string db 0x20 ; device indicator, bit for "read cacheable" set dw 0 ; boot connection vector dw 0 ; boot disconnect vector dw 0 ; bootstrap entry point dw 0 ; reserved zero: dw 0 name: db "rdos debug", 0 init: push ds push ax push cx ; DS := 0 xor ax, ax mov ds, ax ; allocate a single kilobyte from end of lowmem dec word [0x413] ; calculate segment from kilobytes mov ax, [0x413] mov cl, 6 shl ax, cl ; store ptr to our data segment in B6h vector mov word [bssvec*4], ax ; set entry points vectors mov word [1*4], int3entry mov word [1*4+2], cs mov word [3*4], int3entry mov word [3*4+2], cs pop cx pop ax pop ds retf %include "debug/parse.asm" %include "debug/chario.asm" %include "debug/edit.asm" int3entry: ; save DS and load bss segment from IVT push ds mov ds, [cs:zero] mov ds, [bssvec*4] ; save AX so we can work with it mov [reg_ax], ax ; pop DS, IP, CS and flags from stack pop ax mov [reg_ds], ax pop ax mov [reg_ip], ax pop ax mov [reg_cs], ax pop ax mov [reg_fl], ax ; save the other registers mov [reg_cx], cx mov [reg_dx], dx mov [reg_bx], bx mov [reg_sp], sp mov [reg_bp], bp mov [reg_si], si mov [reg_di], di ; save other segment registers we can access mov [reg_ss], ss mov [reg_es], es ; initialize other segments and setup stack mov ax, ds mov es, ax mov ss, ax mov sp, stack call crlf call printregs loop: ; show prompt mov al, '-' call putc ; read data mov byte [inmin], 1 mov byte [inmax], 16 mov word [ingetc], getcu call gets pushf call crlf popf jc loop ; execute call runcmd jmp loop return: ; restore stack pointer mov ss, [reg_ss] mov sp, [reg_sp] ; push flags, CS and IP mov ax, [reg_fl] push ax mov ax, [reg_cs] push ax mov ax, [reg_ip] push ax ; restore GPR mov ax, [reg_ax] mov cx, [reg_cx] mov dx, [reg_dx] mov bx, [reg_bx] mov bp, [reg_bp] mov si, [reg_si] mov di, [reg_di] ; restore segment registers ; DS must be last mov es, [reg_es] mov ds, [reg_ds] ; final jump back iret %include "debug/names.asm" ; Expects DI to mark end of command runcmd: mov si, inbuf lodsb cmp al, 'G' je cmd_g cmp al, 'R' je cmd_r cmp al, 'T' je cmd_t cmp al, '?' je cmd_? cerr: mov al, '?' call putc jmp crlf cmd_?: mov si, .txt jmp putcs .txt: db "G Go", 0x0A, 0x0D db "R[r] Print register values", 0x0A, 0x0D db "T Single-Step", 0x0A, 0x0D db 0 cmd_g: and word [reg_fl+1], 0xfe jmp return cmd_r: cmp byte [si], 0 je printregs call eat_register jc .err mov al, [cs:bx+rnames] call putc mov al, [cs:bx+rnames+1] call putc call space call edit_word call crlf ret .err: mov di, eat_register.emsg jmp parse_error cmd_t: or word [reg_fl+1], 0x03 jmp return printregs: mov cx, 13 xor bx, bx mov ah, 0x0e mov si, reg_ax .loop: push cx mov dx, [cs:si+rnames] lodsw call printreg pop cx loop .loop mov dx, [reg_fl] mov si, fnames mov cx, 16 .floop: mov al, [cs:si] inc si cmp al, '+' je .fskip test dx, 0x8000 jnz .fprnt mov al, '-' .fprnt: int 0x10 .fskip: shl dx, 1 loop .floop call crlf ret printreg: push ax mov al, dl call putc mov al, dh call putc mov al, '=' call putc pop dx call print16 call space ret align 512 absolute 0 reg_ax: resw 1 reg_cx: resw 1 reg_dx: resw 1 reg_bx: resw 1 reg_sp: resw 1 reg_bp: resw 1 reg_si: resw 1 reg_di: resw 1 reg_es: resw 1 reg_cs: resw 1 reg_ss: resw 1 reg_ds: resw 1 reg_ip: resw 1 reg_fl: resw 1 ingetc: resw 1 inmin: resb 1 inmax: resb 1 inbuf: resb 0x20 ; reserve at least 80h words for stack resw 0x80 alignb 1024 stack: