Add monitor program for debugging disk i/o

This commit is contained in:
Nero 2021-01-28 21:16:52 +00:00
parent ff179a5e98
commit daeb3891dd
1 changed files with 261 additions and 0 deletions

261
boot/monitor.asm Normal file
View File

@ -0,0 +1,261 @@
; monitor program that fits in a boot sector
; for debugging disk i/o and bootstrapping
%define base (0x10000 - 0x400)
org base
; relocate to end of memory
init: ; set up src addr
xor ax, ax
mov ds, ax
mov si, 0x7C00
; calculate target segment
mov ax, [0x413]
mov cl, 6
shl ax, cl
sub ax, 0x1000
; set up dst addr
mov es, ax
mov di, base
; set up stack
mov ss, ax
mov sp, di
; relocate
mov cx, 0x100
rep movsw
; set up intr vectors
mov bx, 1*4
call .l02
; enter
mov si, 0x7C00-1
mov byte [si], 0xCC
push cs
push si
retf
; call here = run proc tail twice
.l02: call .l01
.l01: mov word [bx], entry
mov word [bx+2], es
add bx, 2*4
ret
nl: mov al, 0x0A
call putc
mov al, 0x0D
jmp putc
; print full register set
printr: call nl
xor si, si
.l01: call .l02
add si, 2
cmp si, 18
jc .l01
mov si, 22
call .l02
les bx, [ss:bp+18]
jmp dump
.l02: mov ah, 0x0e
mov al, [cs:lbls+si]
int 0x10
mov al, [cs:lbls+si+1]
int 0x10
mov al, '='
int 0x10
mov dx, [ss:bp+si]
call printd
space: mov al, ' '
putc: mov ah, 0x0e
int 0x10
ret
; print far ptr ES:BX
printf: mov dx, es
call printd
mov al, ':'
call putc
mov dx, bx
call printd
jmp space
; print 16 bytes from ES:BX
dump: call printf
push bx
mov cx, 0x10
.l01: mov dh, [es:bx]
inc bx
push cx
call printb
call space
pop cx
loop .l01
pop bx
ret
printd: call printb ; print dx
printb: call .l01 ; print dh
.l01: mov cl, 4
; 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
printn: ; 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: mov ah, 0x0e
int 0x10
ret
getc: xor ax, ax
int 0x16
test al, al
jz getc
test al, 0x80
jnz getc
cmp al, 0x60
jc .ret
sub al, 0x20
.ret: ret
; reads CX hex digits into DX
; DX needs to be zero on entry
input: call getc
cmp al, 0x20
je .err
; must be above '0'
sub al, 0x30
jc input
; if >9, turn 'A' to A
cmp al, 0x0A
jc .noadj
sub al, 7
.noadj: ; must be smaller than 'F'
cmp al, 0x10
jnc input
; append to DX
push cx
mov cl, 4
shl dx, cl
or dl, al
pop cx
; print, loop & clear exit
call printn
loop input
call space
clc
ret
.err: call space
stc
ret
; edit word at ES:BX
; space exits with carry
editw: mov dx, [es:bx]
call printd
mov al, '.'
call putc
mov cx, 4
call input
jc .err
mov [es:bx], dx
.err: ret
entry: push es
push ds
push di
push si
push bp
push bx
push dx
push cx
push ax
mov bp, sp
cmd_r: call printr
; reset segment register
cmd: mov ax, cs
mov ds, ax
mov es, ax
; display prompt
call nl
mov al, '-'
call putc
.l01: call getc
cmp al, 0x41
jc .l01
; process input char
call putc
push ax
call space
pop ax
; branch out into commands
les bx, [defptr]
cmp al, 'D'
je cmd_d
cmp al, 'G'
je exit
cmp al, 'R'
je cmd_r
; set working ptr
cmp al, 'S'
je cmd_s
cmp al, 'O'
je cmd_o
err: mov al, '?'
call putc
jmp cmd
cmd_d: mov cx, 8
.l01: push cx
call nl
call dump
pop cx
add bx, 0x10
mov [defptr], bx
loop .l01
jmp cmd
cmd_o: mov bx, defptr
jmp cmd_s.l01
cmd_s: mov bx, defptr+2
.l01: call editw
jmp cmd
hlt: hlt
jmp hlt
exit: pop ax
pop cx
pop dx
pop bx
pop bp
pop si
pop di
pop ds
pop es
iret
; names for registers
lbls: db "AXCXDXBXBPSIDI" ; gpr
db "DSES" ; seg regs
db "IPCSFL" ; iret frmae
defptr: dw 0x7C00, 0
times 510-($-$$) db 0x00
db 0x55,0xaa
section .bss
line: resb 0x100