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