You are not logged in.
Checking out my [ asm]-function with the bootsector code..
;------------------------------------------------------------; ; BOS - FAT12 bootsector ; ;------------------------------------------------------------; ; - FAT12 compatible. ; ; - Loads a binary file from the floppy, max ~576kb. ; ; - Sets A20 and protected mode. ; ; ; ; Thanks to: Petroff Heroj and John S. Fine for examples. ; ; ; ; by: Christoffer Bubach, 2003-2005 ; ; http://bubach.1go.dk/BOS/ bubach85@hotmail.com ; ; ; ;------------------------------------------------------------; ; other notes: ; this code is public domain, and you can use it for ; anything you want. but if you do, please act polite and ; give credit. ;-) ; ; mem map ; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff ; 0x0000:0x0500 -> 0x0000:0x2100 root ; 0x0000:0x2100 -> 0x0000:0x3300 fat ; 0x0000:0x3300 -> 0x0000:0x7c00 18,25kb free space ; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector ; 0x0000:0x7e00 <- 0x0000:0xffff 32,5kb stack ; 0x1000:0x0000 -> 0x9000:0xffff 576kb free space ; 0xa000:0x0000 -> ............. VGA mem etc. use16 org 0x7C00 boot: jmp near start nop ;------------------------------------------; ; Standard BIOS Parameter Block, "BPB". ; ;------------------------------------------; bpbOEM db 'BOS 0.03' bpbSectSize dw 512 bpbClustSize db 1 bpbReservedSec dw 1 bpbFats db 2 bpbRootSize dw 224 bpbTotalSect dw 2880 bpbMedia db 240 bpbFatSize dw 9 bpbTrackSect dw 18 bpbHeads dw 2 bpbHiddenSect dd 0 bpbLargeSect dd 0 ;---------------------------------; ; extended BPB for FAT12/FAT16 ; ;---------------------------------; bpbDriveNo db 0 bpbReserved db 0 bpbSignature db 0 ; 0 = nothing more. 41 = three more (below).. ; bpbID dd 1 ; bpbVolumeLabel db 'BOOT FLOPPY' ; bpbFileSystem db 'FAT12 ' ;----------------------------------------; ; starting point of bootsector code ; ;----------------------------------------; start: cli xor ax, ax ; initialize all the necessary mov ds, ax ; registers. mov es, ax mov ss, ax mov sp, 0xFFFF ; Stack.. mov [bpbDriveNo], dl sti ;----------------------------------; ; clear screen and print some ; ;----------------------------------; mov ax, 3 ; Set mode 0x03 int 0x10 mov bp, loading ; Print loading message. mov ax, 0x1301 mov bx, 7 mov cx, 12 mov dx, 0x0102 int 0x10 mov bl, 2 ; Set cursor. mov ah, 2 mov dx, 0x0201 int 0x10 mov ah, 9 ; Print 14 green dots. mov al, '.' mov cx, 14 int 0x10 ;---------------------------; ; load FAT and root ; ;---------------------------; mov di, 0x0050 ; Load the root to mov ax, 19 ; 0x0000:0x0500 (0x500/0x10) mov cx, 14 call read_sectors mov di, 0x0210 ; Load the fat to mov ax, 1 ; 0x0000:0x2100 mov cx, 9 call read_sectors ;------------------------; ; search for the file ; ;------------------------; mov dx, [bpbRootSize] mov bx, 0x0500 filesearch: cld mov si, filename mov cx, 11 mov di, bx repe cmpsb je found add bx, 32 dec dx jz error jmp filesearch ;-----------------------------------; ; variables & functions ; ;-----------------------------------; loading db 'Starting BOS' filename db 'KERNEL SYS' failure db 'Read error!' a20_on db 1 ;-----------------------------------------------; ; read a number of sectors (one at a time) ; ;-----------------------------------------------; ; in: ; ; di = segment to save at ; ; ax = sector to read ; ; cx = number of sectors ; ; out: ; ; di = updated (added for next read) ; ; ax = updated (added for next read) ; ;-----------------------------------------------; read_sectors: pusha mov bl, byte [bpbTrackSect] ; bl = number of sectors per track div bl ; al = ax / bl mov cl, ah ; cl = real sector number add cl, 1 xor ah, ah ; del the rest of the div before mov bl, byte [bpbHeads] ; bl = number of heads div bl ; ah = rest of ( ax / bx ), al = ax / bx mov ch, al ; ch = number of track mov dh, ah ; dh = the head number mov ax, cx ; save cx in ax mov cx, 6 ; try it 6 times .next_try: push es push cx mov cx, ax ; restore cx push cx xor ax, ax mov dl, [bpbDriveNo] ; reset drive push dx int 0x13 jc .failed pop dx pop cx xor bx, bx mov es, di mov ax, 0x0201 ; function 2, 1 sector int 0x13 jnc .ok ; if it was ok, check next.. .failed: pop dx pop ax pop cx pop es loop .next_try ; else try once again if there is an error jmp error ; if cx = 0 and the read operation always failed, halt .ok: pop cx ; from the next_try loop pop es popa add di, 32 ; add 32 (512/16) to segment inc ax ; add sector counter loop read_sectors ret ;----------------------------------------------------; ; show a message and wait for a key before reboot ; ;----------------------------------------------------; error: ;push 0x0000 ;pop es mov bp, failure mov ax, 0x1301 mov bx, 4 mov cx, 43 mov dx, 0x0401 int 0x10 mov ah, 0 int 0x16 int 0x19 ;-----------------------------------; ; the file is found, load it. ; ;-----------------------------------; found: mov bp, [bx+26] ; bp=cluster number from directory entry mov di, 0x1000 ; 1000 (segment) .next_block: xor cx, cx mov cl, [bpbClustSize] ; reset sector count to 1 cluster mov si, bp ; si=next should-be cluster for ; contiguous reads .next_contiguous: mov ax, 3 ; 3 mul si ; multiply cluster number by 3 ; dx assumed to be 0, it's a floppy! shr ax, 1 ; divide by two push bp xchg bp, ax ; bp=ax mov ax, word [0x2100+bp] ; ax=FAT element with junk ; (addressing with bp) pop bp jc byte .odd_cluster ; jump if the value was odd .even_cluster: and ax, 0x0FFF ; leave only lower 12 bits jmp .got_cluster ; got it .odd_cluster: push cx ; preserve sector count mov cl, 4 ; shift four bits right shr ax, cl ; (leave only bits 4-15) pop cx ; restore sector count .got_cluster: inc si ; si=current cluster+1 cmp ax, si ; next cluster=current cluster+1? jne byte .force_read ; is it still contiguous? add cl, [bpbClustSize] ; increase sector count by 1 cluster adc ch, 0 jmp .next_contiguous .force_read: xchg bp, ax ; ax=bp (base cluster), bp=new cluster dec ax ; decrease by 2 to get the actual... (1) dec ax ; ...cluster number (2) xor dx, dx mov dl, [bpbClustSize] mul dx ; multiply by sectors per cluster ; (dx ignored) add ax, 33 ; assume data-area start at sector 33 call read_sectors ; read cx sectors at ax to es:0 :) cmp bp, 0x0FF8 ; the new cluster is EOF (FF8-FFF)? jb byte .next_block ; if not in this range, read next block ;-----------------------; ; the file is loaded ; ;-----------------------; quit: a20: ; Enable A20 in al, 0x64 test al, 2 jnz a20 mov al, 0xD1 out 0x64, al .d6: in al, 0x64 and ax, 2 jnz .d6 mov al, 0xDF out 0x60, al .a20_check: mov al, byte [fs:0] ; check a20, is it on? mov ah, al not al xchg al, byte [gs:0x10] cmp ah, byte [fs:0] mov [gs:0x10], al jz floppy_off mov [a20_on], 0 ; it's not on save for file.. floppy_off: mov dx, 0x3F2 ; turn of the floppy motor. mov al, 0 out dx, al pmode: cli ; set protected mode (32-bit) lgdt [gdtr] mov eax, cr0 or eax, 1 mov cr0, eax jmp 0x08:flush ;----------------------------------------; ; start of 32-bit area. ; ; flush segments and jump to kernel ; ;----------------------------------------; use32 flush: mov eax, 0x10 ; refresh all segment registers mov ds, eax mov es, eax mov fs, eax mov gs, eax mov ss, eax mov esp, 0xfffc mov eax, 0xB05B007 ; report "BOSboot".. ;-) mov bl, [a20_on] ; report if a20 is on. jmp 0x08:0x10000 ; jump to loaded file (64kb in mem) ;--------------------------------; ; global descriptor table (gdt) ; ;--------------------------------; gdt: dw 0x0000, 0x0000, 0x0000, 0x0000 codesel: dw 0xFFFF, 0x0000, 0x9800, 0x00CF datasel: dw 0xFFFF, 0x0000, 0x9200, 0x00CF gdt_end: gdtr: dw gdt_end - gdt - 1 dd gdt ;-------------------------------------; ; set the BOOT-signature at byte 510. ; ;-------------------------------------; rb boot+512-2-$ dw 0xAA55
Offline
Pages: 1