From 9b22a6965579ea1867aea291d910c96f386b518b Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Tue, 24 Aug 2021 14:09:29 -0500 Subject: major backup 8.24.21 --- src/bootloader/bios_disk.asm | 149 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/bootloader/bios_disk.asm (limited to 'src/bootloader/bios_disk.asm') diff --git a/src/bootloader/bios_disk.asm b/src/bootloader/bios_disk.asm new file mode 100644 index 0000000..5992920 --- /dev/null +++ b/src/bootloader/bios_disk.asm @@ -0,0 +1,149 @@ +bios_disk: +.init: +mov [boot_device], dl +mov ah, 0x8 +int 0x13 +;TODO defaults + +jc .init_use_defaults + +mov [max_head], dh +mov [max_sector], cl +and WORD [max_sector], 0x3f + +mov [max_cylinder], cl +shl WORD [max_cylinder], 8 +or [max_cylinder], ch +and WORD [max_cylinder], 0x3ff + +ret + +.init_use_defaults: +mov BYTE [max_sector], 63 +mov WORD [max_head], 15 +mov BYTE [max_cylinder], 1023 + +ret + +; Return: +; CH = low eight bits of maximum cylinder number +; CL = maximum sector number (bits 5-0), high two bits of maximum cylinder number (bits 7-6) +; DH = maximum head number + +.load_sectors_v2: +;AH = 02h +;AL = number of sectors to read (must be nonzero) +;CH = low eight bits of cylinder number +;CL = sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7) +;DH = head number +;DL = drive number (bit 7 set for hard disk) +;ES:BX -> data buffer + +; I don't understand i8086. The base pointer needs to be above the stack pointer, +; yet the stack grows down, +; and we can't address using sp, or by subtraction. +; it's like it's forcing us to use the whole push/pop thing. + +sub sp, 16 +mov bp, sp + +; sector: rbp + 0 (uint8_t) +; head: rbp + 1 (uint8_t) +; cylinder: rbp + 2 (uint16_t) +; sector_cnt: rbp + 4 (uint16_t) +; destination: rbp + 6 (uint32_t) + +; set up variables ______________________________________________ + +;destination to stack +mov [bp + 6], edi + +; find init chs ________________________________________________ + +; divide sector_start / max_sectors +; TODO test for overflow +mov ax, si +shr esi, 16 +mov dx, si + +;find sector +div DWORD [max_sector] +inc dx +mov [bp], edx ; remainder is sector variable + +;find head and cylinder +mov dx, 0 +div DWORD [max_head] +mov [bp + 1], dx ; head +mov [bp + 2], ax ; cylinder + +.sector_for_loop: +mov [bp + 4], cx + +; do bios call ___________________________________________________ +mov ah, 2 +mov al, 1 +; sets up ch and cl +mov cx, [bp + 2] +xchg ch, cl +shl cl, 6 +or cl, [bp] + +mov dh, [bp + 1] +mov dl, [boot_device] +mov bx, 0x500 ; where we store the sector temporarily + +int 0x13 +jc .read_failed + +; mempcy __________________________________________________________ + +; we move it to the place at edi, which I don't think changes +mov esi, 0x500 +mov ecx, 512 +a32 rep movsb + +; recalc chs ______________________________________________________ + +; need to test for more overflows I think +inc WORD [bp] +mov al, [bp]; increase the sector we're on +cmp al, [max_sector] +jbe .continue_loop +mov WORD [bp], 1 + +inc WORD [bp + 1] +mov al, [bp + 1] +cmp al, [max_head] +jbe .continue_loop +mov WORD [bp + 1], 0 +inc DWORD [bp + 2] + +; loopin back ____________________________________________________ +.continue_loop: +mov cx, [bp + 4] + + +loop .sector_for_loop +add bp, 16 +mov sp, bp + + +ret + + + + +.read_failed: +mov bx, .loadsectors_error +call bios_print +cli +hlt + +.loadsectors_error: db "Error loading required sector!", 0 + +boot_device: db 0 +max_sector: db 0 +max_cylinder: dw 0 +max_head: db 0 + -- cgit v1.2.3