cpu 8086 org 0x0000 stacksize: equ 0x20 db 0x55, 0xAA db 0x00 jmp init nop 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 dw 0 name: db "rdos debug" init: push ds push es push si push di push ax push cx xor ax, ax mov si, ax mov di, ax ; load DS for mov ds, ax mov al, [cs:2] inc ax shr ax, 1 ; move down int 0x12 ptr to make space for us sub [0x413], ax ; calculate segment from kilobytes mov ax, [0x413] mov cl, 6 shl ax, cl ; load ES for relocate mov es, ax ; store interrupt vector mov word [3*4], int3entry mov word [3*4+2], es ; load DS for relocate push cs pop ds ; calculate our length mov cx, codeend rep movsb pop cx pop ax pop di pop si pop es pop ds retf 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 printregs: mov cx, 14 xor bx, bx mov ah, 0x0e mov si, reg_ax .loop: push cx mov dx, [si+(names-reg_ax)] mov al, dl int 0x10 mov al, dh int 0x10 mov al, '=' int 0x10 lodsw mov dx, ax call print16 mov al, ' ' int 0x10 pop cx loop .loop ret int3entry: ; save DS and AX mov [cs:reg_ds], ds mov [cs:reg_ax], ax ; use AX to load DS=CS mov ax, cs mov ds, ax ; pop IP, CS and flags from stack 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 es, ax mov ss, ax mov sp, (stack+stacksize) call printregs hlt: hlt jmp hlt names: db "AXCXDXBXSPBPSIDI" db "DSESSSCSIPFL" codeend: reg_ax: dw 0 reg_cx: dw 0 reg_dx: dw 0 reg_bx: dw 0 reg_sp: dw 0 reg_bp: dw 0 reg_si: dw 0 reg_di: dw 0 reg_es: dw 0 reg_cs: dw 0 reg_ss: dw 0 reg_ds: dw 0 reg_ip: dw 0 reg_fl: dw 0 stack: times stacksize dw 0 align 512