;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;disk_load_16 ; [bits 16] STR_ERROR: db "Disk Read Error",0 STR_SPACE: db " ",0 STR_OK: db "Kernel Loaded",0 STR_PROGRESS: db ".",0 bpbSectorsPerTrack: dw 18 bpbHeadsPerCylinder: dw 2 LBA: dw 10 ; current lba disk_load_16: ; check if LBA is supported mov ah,0x41 mov bx,0x55aa int 0x13 jnc disk_load_lba jmp disk_load_chs ;####################### disk_load_lba: pusha mov bx,0x1800 ;target es:bx mov es,bx mov bx,0 next_sectors_lba: jmp skip_debug_lba ;show es - target pusha mov bx,es ;mov al,bh ;call print_hex_byte ;mov al,bl ;call print_hex_byte mov bx,[LBA] mov al,bh call print_hex_byte mov al,bl call print_hex_byte popa ;-- skip_debug_lba: mov [lba_addr_sector],es mov ax,[LBA] mov [lba_first_sector],ax mov dl,[BOOT_DRIVE] mov ah,0x42 mov bx,0 mov ds,bx lea si,[lba_adr] int 0x13 jc disk_read_error mov bx,es add bx,0x0800 mov ax,[LBA] add ax,64 ; 64 sectors = 0x2000*4 bytes mov [LBA],ax cmp bx,0x9000 je disk_load_finish mov es,bx ;next target es:bx mov bx,0 jmp next_sectors_lba ;####################### disk_load_chs: pusha ; get boot drive geometry mov ah,8 mov dl,[BOOT_DRIVE] int 0x13 add dh,1 and cl,0x3f mov [bpbSectorsPerTrack],cl mov [bpbHeadsPerCylinder],dh ; ;show geometry mov al,dh call print_hex_byte mov bx, STR_SPACE call print_string mov al,cl call print_hex_byte call print_nextline popa ; pusha mov bx,0x1800 ;target es:bx mov es,bx mov bx,0 next_sectors_chs: ;jmp skip_debug pusha mov bx, STR_SPACE call print_string ;show es - target mov bx,es mov al,bh call print_hex_byte mov al,bl call print_hex_byte mov bx, STR_SPACE call print_string ;show next LBA numer mov ax,[LBA] mov al,ah call print_hex_byte mov ax,[LBA] call print_hex_byte mov bx, STR_SPACE call print_string popa mov ax,[LBA] ;calculate chs call lba_to_chs ;show chs sector/ head / cylinder mov al,cl call print_hex_byte mov al,dh call print_hex_byte mov al,ch call print_hex_byte call print_nextline skip_debug: mov ax,[LBA] ;calculate chs call lba_to_chs ; and now READ it! mov al,1 ;number of sectors to read mov dl,[BOOT_DRIVE] mov ah,0x02 ;BIOS read sector func int 0x13 ;bios interrupt jc disk_read_error mov bx,es add bx,0x0020 cmp bx,0x9000 je disk_load_finish mov es,bx mov bx,0 mov ax,[LBA] add ax,1 mov [LBA],ax jmp next_sectors_chs disk_read_error: mov bx, STR_ERROR call print_string call print_nextline ;jmp $ disk_load_finish: mov bx, STR_PROGRESS call print_string ; call print_nextline popa ret ;lba to chs translation: ; input : ax - lba ; output: cl - sector ; dh - head ; ch - cylinder / track lba_to_chs: xor dx, dx ; prepare dx:ax for operation div WORD [bpbSectorsPerTrack] ; divide by sectors per track inc dl ; add 1 (obsolute sector formula) mov cl, dl xor dx, dx ; prepare dx:ax for operation div WORD [bpbHeadsPerCylinder] ; mod by number of heads (Absolue head formula) mov dh,dl ; everything else was already done from the first formula mov ch, al ; not much else to do :) ret ;; here we hold the lba addr lba_adr: dw 0x10 ; size of packet ( 16 byte) dw 64 ; number of sectors to read ; target is 0x10000 dw 0x0000 ; target addr. offset lba_addr_sector: dw 0x1800 ; target addr. sector lba_first_sector: dw 10 ; first sector to read dw 0 dd 0 ;