diff options
Diffstat (limited to 'mbr')
| -rw-r--r-- | mbr/stage1.asm | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/mbr/stage1.asm b/mbr/stage1.asm new file mode 100644 index 0000000..ea51f22 --- /dev/null +++ b/mbr/stage1.asm @@ -0,0 +1,79 @@ +[org 0x7C00] + +_start: + xor ax, ax + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + + cli ;; Disable all interrupts + cld ;; Strings shall increment + mov [boot_drive], dl ;; Save the boot drive + + mov si, boot_sig + call print_str + call enable_a20 + call disk_load + + jmp 0x0000:0x8000 + hlt + jmp $ + +;; +;; Write a string to the screen +;; +;; [SI]: Base address of string +;; +print_str: + lodsb ;; Load *(SI++) -> AL + or al, al ;; Null byte? + jz .done ;; Yup, finish + mov ah, 0x0E ;; Print char + int 0x10 ;; BIOS call + jmp print_str ;; Loop again until NUL +.done: + ret + +;; +;; Enable the A20 gate to access the full +;; 16 megs +;; +enable_a20: + in al, 0x92 ;; Check the state + test al, 2 ;; is it already set? + jnz .done ;; Yes, no need to re-enable + or al, 2 ;; No, enable it + out 0x92, al ;; Write the new value back +.done: + ret + +DAP: + .size: db 0x10 + .reserved: db 0x00 + .count: dw 1 + .buffer: dw 0x8000 + .segment: dw 0 + .lba_lo: dd 1 + .lba_hi: dd 0 +disk_load: + mov si, DAP + mov ah, 0x42 + mov dl, [boot_drive] + int 0x13 + jc .disk_err + ret +.disk_err: + mov si, disk_errmsg + call print_str +.hang: + hlt + jmp .hang + +boot_sig: db "* beepboot stage0", 0x0A, 0x0D, 0x00 +disk_errmsg: db "[!] failed to read disk", 0x0A, 0x0D, 0x00 +boot_drive: db 0 + +times 510 - ($ - $$) db 0 +dw 0xAA55 |
