rdos/rom/debug.asm

334 lines
4.9 KiB
NASM

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"
; Print AL
space: mov al, ' '
putc: xor bx, bx
mov ah, 0x0e
int 0x10
ret
; Print code string CS:SI
putcs: push ds
push cs
pop ds
call putds
pop ds
ret
; Print data string DS:SI
putds: lodsb
test al, al
jz .ret
call putc
jmp putds
.ret: ret
crlf: mov al, 0x0A
call putc
mov al, 0x0D
jmp putc
print16:
; setup bx and ah for int 10h call
xor bx, bx
mov ah, 0x0e
mov cl, 4
; this double-call is essentially a 4 times repeating loop
call .c1
.c1: call .c2
.c2: ; grab highest nibble from dx
mov al, dh
; remove highest nibble from dx
shl dx, cl
; shift away second-highest nibble that we accidentally copied
shr al, cl
; map 0-9 to ascii codes for '0' to '9'
add al, 0x30
; if result is larger than '9', ...
cmp al, 0x3a
jl .noadj
; ... add 7 so we continue at 'A'
add al, 7
.noadj: int 0x10
ret
getc: xor ax, ax
int 0x16
test al, al
jz getc
ret
read: mov di, cmdbuf
.loop: call getc
cmp al, 0x03
je .can
cmp al, 0x0D
je .enter
cmp al, 0x08
je .bs
cmp di, cmdbuf+cmdlen-1
jnc .loop
stosb
mov ah, 0x0e
xor bx, bx
int 0x10
jmp .loop
ret
.bs: cmp di, cmdbuf
jbe .loop
xor bx, bx
mov ax, 0x0e08
int 0x10
mov al, 0x20
int 0x10
mov al, 0x08
int 0x10
dec di
jmp .loop
.can: xor al, al
stosb
stc
ret
.enter: xor al, al
stosb
ret
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
call read
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, cmdbuf
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 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
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
cmdlen: equ 16
cmdbuf: resb cmdlen
; reserve at least 80h words for stack
resw 0x80
alignb 1024
stack: