; 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