mon8086/mon8086.asm

298 lines
3.9 KiB
NASM

; monitor program that fits in a boot sector
; for debugging disk i/o and bootstrapping
%define base (0x10000 - 0x200)
org base
cpu 8086
; 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
; push defptr
push ds
push si
; relocate
mov cx, 0x100
rep movsw
; reset ES for later prog
mov es, cx
; set up intr vectors
mov bx, 1*4
call .l02
; enter
mov si, 0x7C00-1
mov byte [si], 0xCC
push cs
push si
sti
retf
; call here = run proc tail twice
.l02: call .l01
.l01: mov word [bx], entry
mov word [bx+2], ss
add bx, 2*4
ret
nl: mov ax, 0x0e0A
int 0x10
mov al, 0x0D
jmp putc
space: mov al, ' '
putc: mov ah, 0x0e
int 0x10
ret
; print register set
printr: call nl
xor si, si
.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, [bp+si]
mov ch, ' '
call prints
add si, 2
cmp si, 24
jc .l02
les bx, [bp+18]
jmp dump
; print 16 bytes from ES:BX
dump: mov dx, es
mov ch, ':'
call prints
mov dx, bx
mov ch, ' '
call prints
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
printw: 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
; print dx and char ch
prints: call printw
mov al, ch
int 0x10
ret
getc: xor ax, ax
int 0x16
test al, al
jz getc
; to uppercase
cmp al, 0x60
jc .ret
sub al, 0x20
.ret: ret
inputw: call inputb
inputb: call inputn
inputn: jc .ret
call getc
cmp al, 0x20
stc
je .ret
sub al, 0x30
; if >9, turn 'A' to A
cmp al, 0x0A
jc .noadj
sub al, 7
.noadj: ; must be smaller than 'F'
cmp al, 0x10
jnc inputn
; append to dx
mov cl, 4
shl dx, cl
or dl, al
; print, loop & clear exit
call printn
clc
.ret: ret
; edit word at ES:BX
; space exits with carry
editw: mov dx, [es:bx]
mov ch, '.'
call prints
clc
call inputw
jc .err
mov [es:bx], dx
.err: ret
cmd_o: mov bx, di
jmp cmd_s.l01
cmd_s: lea bx, [di+2]
.l01: call editw
jmp cmd
cmd_e: les bx, [cs:di]
mov dh, [es:bx]
call printb
mov al, '.'
int 0x10
mov cx, 2
clc
call inputb
jc cmd
mov [es:bx], dl
inc word [cs:di]
call space
jmp cmd_e
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
cmd: ; 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
; set up default for cmds
mov dx, cs
mov ds, dx
mov es, dx
mov di, defptr
; show and edit mem
cmp al, 'D'
je cmd_d
cmp al, 'E'
je cmd_e
; show and edit regs
cmp al, 'R'
je cmd_r
cmp al, 'V'
je cmd_v
; actions
cmp al, 'G'
je cmd_g
cmp al, 'T'
je cmd_t
; set working ptr
cmp al, 'S'
je cmd_s
cmp al, 'O'
je cmd_o
err: mov al, '?'
call putc
jmp cmd
cmd_d: les bx, [di]
mov cx, 8
.l01: push cx
call nl
call dump
pop cx
add bx, 0x10
mov [cs:di], bx
loop .l01
jmp cmd
cmd_v: call regn
mov ax, dx
mov di, lbls
mov cx, 11
repne scasw
jne err
sub di, lbls+2
lea bx, [bp+di]
call space
call editw
jmp cmd
regn: call .l01
xchg dh, dl
.l01: call getc
call putc
mov dh, al
ret
cmd_t: or byte [bp+23], 1
jmp exit
cmd_g: and byte [bp+23], 0xFE
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: equ (base-4)
times 510-($-$$) db 0x00
db 0x55,0xaa