; 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