%if 0 Boot sector loader which displays register values by C. Masloch, 2020 Usage of the works is permitted provided that this instrument is retained with the works, so that any entity that uses the works is notified of this instrument. DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY. %endif struc BS bsJump: resb 3 bsOEM: resb 8 bsBPB: endstruc struc EBPB ; BPB sec bpbBytesPerSector: resw 1 ; offset 00h 0Bh bpbSectorsPerCluster: resb 1 ; offset 02h 0Dh bpbReservedSectors: resw 1 ; offset 03h 0Eh bpbNumFATs: resb 1 ; offset 05h 10h bpbNumRootDirEnts: resw 1 ; offset 06h 11h -- 0 for FAT32 bpbTotalSectors: resw 1 ; offset 08h 13h bpbMediaID: resb 1 ; offset 0Ah 15h bpbSectorsPerFAT: resw 1 ; offset 0Bh 16h -- 0 for FAT32 bpbCHSSectors: resw 1 ; offset 0Dh 18h bpbCHSHeads: resw 1 ; offset 0Fh 1Ah bpbHiddenSectors: resd 1 ; offset 11h 1Ch bpbTotalSectorsLarge: resd 1 ; offset 15h 20h bpbNew: ; offset 19h 24h ebpbSectorsPerFATLarge: resd 1 ; offset 19h 24h ebpbFSFlags: resw 1 ; offset 1Dh 28h ebpbFSVersion: resw 1 ; offset 1Fh 2Ah ebpbRootCluster: resd 1 ; offset 21h 2Ch ebpbFSINFOSector: resw 1 ; offset 25h 30h ebpbBackupSector: resw 1 ; offset 27h 32h ebpbReserved: resb 12 ; offset 29h 34h ebpbNew: ; offset 35h 40h endstruc struc BPBN ; ofs B16 S16 B32 S32 bpbnBootUnit: resb 1 ; 00h 19h 24h 35h 40h resb 1 ; 01h 1Ah 25h 36h 41h bpbnExtBPBSignature: resb 1 ; 02h 1Bh 26h 37h 42h -- 29h for valid BPBN bpbnSerialNumber: resd 1 ; 03h 1Ch 27h 38h 43h bpbnVolumeLabel: resb 11 ; 07h 20h 2Bh 3Ch 47h bpbnFilesystemID: resb 8 ; 12h 2Bh 36h 47h 52h endstruc ; 1Ah 33h 3Eh 4Fh 5Ah cpu 8086 org 7C00h start: jmp short entrypoint nop times (bsBPB + EBPB_size + BPBN_size) - ($ - $$) db 0 entrypoint: pushf cli cld push bx push ds call 0:.next .next: pop bx sub bx, .next - start push bx push cs pop ds mov bx, start pop word [bx + reg_ip] pop word [bx + reg_cs] pop word [bx + reg_ds] pop word [bx + reg_bx] pop word [bx + reg_fl] mov word [bx + reg_sp], sp mov word [bx + reg_ss], ss mov word [bx + reg_ax], ax xor ax, ax mov ss, ax mov sp, bx ; set sp immediately after ss sti mov word [bx + reg_cx], cx mov word [bx + reg_dx], dx mov word [bx + reg_es], es mov word [bx + reg_si], si mov word [bx + reg_di], di mov word [bx + reg_bp], bp mov si, table ; bx -> start loop_table: mov al, 32 call disp_al lodsw call disp_al xchg al, ah call disp_al cmp al, 32 jbe .next mov al, '=' call disp_al mov ax, [bx] inc bx inc bx call disp_ax_hex .next: cmp si, table.end jb loop_table exit: xor ax, ax int 16h int 19h disp_al: push ax push bx push bp mov ah, 0Eh mov bx, 7 int 10h pop bp pop bx pop ax retn disp_ax_hex: ; ax xchg al,ah call disp_al_hex ; display former ah xchg al,ah ; and fall trough for al disp_al_hex: ; al push cx mov cl,4 ror al,cl call disp_al_lownibble_hex ; display former high-nibble rol al,cl pop cx ; and fall trough for low-nibble disp_al_lownibble_hex: push ax ; save ax for call return and al,00001111b ; high nibble must be zero add al,'0' ; if number is 0-9, now it's the correct character cmp al,'9' jna .decimalnum ; if we get decimal number with this, ok --> add al,7 ; otherwise, add 7 and we are inside our alphabet .decimalnum: call disp_al pop ax retn struc registerstorage reg_ss: resw 1 reg_bp: resw 1 reg_sp: resw 1 reg_cs: resw 1 reg_ip: resw 1 reg_fl: resw 1 reg_ds: resw 1 reg_si: resw 1 reg_es: resw 1 reg_di: resw 1 reg_ax: resw 1 reg_bx: resw 1 reg_cx: resw 1 reg_dx: resw 1 endstruc %if registerstorage_size + start > entrypoint %error Entrypoint is not safe %endif align 2 table: dw "SS" dw "BP" dw "SP" dw "CS" dw "IP" dw "FL" db 13,10 dw "DS" dw "SI" dw "ES" dw "DI" db 13,10 dw "AX" dw "BX" dw "CX" dw "DX" db 13,10 .end: times 510 - ($ - $$) db 0 dw 0AA55h