; - FAT12 compatible. ;\r
; - Loads a binary file from the floppy. ;\r
; ;\r
+; 16-bit mem map (seg:off) ;\r
+;------------------------------------------------------------;\r
+; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff ;\r
+; 0x0000:0x0500 -> 0x0000:0x2100 FAT12 rootdir ;\r
+; 0x0000:0x2100 -> 0x0000:0x3300 FAT for FAT12 ;\r
+; 0x0000:0x3300 -> 0x0000:0x6c00 14,25kb free space ;\r
+; 0x0000:0x6c00 -> 0x0000:0x7400 IDT, 256 descriptors ;\r
+; 0x0000:0x7400 -> 0x0000:0x7c00 GDT, 256 descriptors ;\r
+; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector ;\r
+; 0x0000:0x7e00 <- 0x0000:0x8000 512b stack for boot ;\r
+; 0x0000:0x8000 -> 0x9000:0xffff 608kb kernel/free space ;\r
+; 0xA000:0x0000 -> ............. VGA mem etc. ;\r
;------------------------------------------------------------;\r
-\r
-; TODO:\r
-; as i moved some 16-bit stuff to the kernel, i now got\r
-; space to do proper testing (for data-area etc),\r
-; fix that...\r
-;\r
-; TODO2:\r
-; find out why this crap takes ages to load the kernel.. :S\r
-\r
-\r
-;\r
-; 16-bit mem map (seg:off)\r
-; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff\r
-; 0x0000:0x0500 -> 0x0000:0x2100 FAT12 rootdir\r
-; 0x0000:0x2100 -> 0x0000:0x3300 FAT for FAT12\r
-; 0x0000:0x3300 -> 0x0000:0x6c00 14,25kb free space\r
-; 0x0000:0x6c00 -> 0x0000:0x7400 IDT, 256 descriptors\r
-; 0x0000:0x7400 -> 0x0000:0x7c00 GDT, 256 descriptors\r
-; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector\r
-; 0x0000:0x7e00 <- 0x0000:0x8000 512b stack for boot\r
-; 0x0000:0x8000 -> 0x9000:0xffff 608kb kernel/free space\r
-;;;; 0x0000:0x7e00 <- 0x0000:0xffff ~32,5kb stack for boot\r
-;;;; 0x1000:0x0000 -> 0x9000:0xffff 576kb kernel/free space\r
-; 0xA000:0x0000 -> ............. VGA mem etc.\r
\r
use16\r
org 0x7C00\r
\r
boot:\r
- jmp short start\r
- nop\r
+ jmp short start\r
+ nop\r
\r
;------------------------------------------;\r
; Standard BIOS Parameter Block, "BPB". ;\r
;------------------------------------------;\r
- bpbOEM db 'BOS 0.04'\r
- bpbSectSize dw 512\r
- bpbClustSize db 1\r
- bpbReservedSec dw 1\r
- bpbFats db 2\r
- bpbRootSize dw 224\r
- bpbTotalSect dw 2880\r
- bpbMedia db 240\r
- bpbFatSize dw 9\r
- bpbTrackSect dw 18\r
- bpbHeads dw 2\r
- bpbHiddenSect dd 0\r
- bpbLargeSect dd 0\r
- ;---------------------------------;\r
- ; extended BPB for FAT12/FAT16 ;\r
- ;---------------------------------;\r
- bpbDriveNo db 0\r
- bpbReserved db 0\r
- bpbSignature db 41 ; 0 = nothing more. 41 = three more (below)..\r
- bpbID dd 1\r
- bpbVolumeLabel db 'BOOT FLOPPY'\r
- bpbFileSystem db 'FAT12 '\r
+ bpbOEM db 'BOS 0.04'\r
+ bpbSectSize dw 512\r
+ bpbClustSize db 1\r
+ bpbReservedSec dw 1\r
+ bpbFats db 2\r
+ bpbRootSize dw 224\r
+ bpbTotalSect dw 2880\r
+ bpbMedia db 240\r
+ bpbFatSize dw 9\r
+ bpbTrackSect dw 18\r
+ bpbHeads dw 2\r
+ bpbHiddenSect dd 0\r
+ bpbLargeSect dd 0\r
+ ;---------------------------------;\r
+ ; extended BPB for FAT12/FAT16 ;\r
+ ;---------------------------------;\r
+ bpbDriveNo db 0\r
+ bpbReserved db 0\r
+ bpbSignature db 41 ; 0 = end. 41 = three more.\r
+ bpbID dd 1\r
+ bpbVolumeLabel db 'BOOT FLOPPY'\r
+ bpbFileSystem db 'FAT12 '\r
\r
\r
;----------------------------------------;\r
; starting point of bootsector code ;\r
;----------------------------------------;\r
start:\r
- cli\r
-\r
- xor ax, ax ; initialize all the necessary\r
- mov ds, ax ; registers.\r
- mov es, ax\r
- mov ss, ax\r
- mov sp, 0x8000 ; Stack..\r
-\r
- mov [bpbDriveNo], dl\r
-\r
- sti\r
-\r
-\r
-;----------------------------------;\r
-; clear screen and print some ;\r
-;----------------------------------;\r
- mov ax, 3 ; Set mode 0x03\r
- int 0x10\r
-\r
- mov bp, loading ; Print loading message.\r
- mov ax, 0x1301\r
- mov bx, 7\r
- mov cx, 12\r
- mov dx, 0x0102\r
- int 0x10\r
-\r
- mov bl, 2 ; Set cursor.\r
- mov ah, 2\r
- mov dx, 0x0201\r
- int 0x10\r
-\r
- mov ah, 9 ; Print 14 green dots.\r
- mov al, '.'\r
- mov cx, 14\r
- int 0x10\r
-\r
-\r
-;---------------------------;\r
-; load FAT and root ;\r
-;---------------------------;\r
- mov di, 0x0050 ; Load the root to\r
- mov ax, 19 ; 0x0000:0x0500 (0x500/0x10)\r
- mov cx, 14\r
- call read_sectors\r
-\r
- mov di, 0x0210 ; Load the fat to\r
- mov ax, 1 ; 0x0000:0x2100\r
- mov cx, 9\r
- call read_sectors\r
-\r
-\r
- ;------------------------;\r
- ; search for the file ;\r
- ;------------------------;\r
- mov dx, [bpbRootSize]\r
- mov bx, 0x0500\r
- filesearch:\r
- cld\r
- mov si, filename\r
- mov cx, 11\r
- mov di, bx\r
- repe cmpsb\r
- je found\r
- add bx, 32\r
- dec dx\r
- jz error\r
- jmp filesearch\r
+ cli\r
+\r
+ xor ax, ax ; initialize all the necessary\r
+ mov ds, ax ; registers.\r
+ mov es, ax\r
+ mov ss, ax\r
+ mov sp, 0x8000 ; Stack..\r
+\r
+ mov [bpbDriveNo], dl\r
+\r
+ sti\r
+\r
+\r
+ ;----------------------------------;\r
+ ; clear screen and print some ;\r
+ ;----------------------------------;\r
+ mov ax, 3 ; Set mode 0x03\r
+ int 0x10\r
+\r
+ mov bp, loading ; Print loading message.\r
+ mov ax, 0x1301\r
+ mov bx, 7\r
+ mov cx, 12\r
+ mov dx, 0x0102\r
+ int 0x10\r
+\r
+ mov bl, 2 ; Set cursor.\r
+ mov ah, 2\r
+ mov dx, 0x0201\r
+ int 0x10\r
+\r
+ mov ah, 9 ; Print 14 green dots.\r
+ mov al, '.'\r
+ mov cx, 14\r
+ int 0x10\r
+\r
+\r
+ ;---------------------------;\r
+ ; load FAT and root ;\r
+ ;---------------------------;\r
+ mov di, 0x0050 ; Load the root to\r
+ mov ax, 19 ; 0x0000:0x0500 (0x500/0x10)\r
+ mov cx, 14\r
+ call read_sectors\r
+\r
+ mov di, 0x0210 ; Load the fat to\r
+ mov ax, 1 ; 0x0000:0x2100\r
+ mov cx, 9\r
+ call read_sectors\r
+\r
+\r
+ ;------------------------;\r
+ ; search for the file ;\r
+ ;------------------------;\r
+ mov dx, [bpbRootSize]\r
+ mov bx, 0x0500\r
+ .filesearch:\r
+ cld\r
+ mov si, filename\r
+ mov cx, 11\r
+ mov di, bx\r
+ repe cmpsb\r
+ je found\r
+ add bx, 32\r
+ dec dx\r
+ jz error\r
+ jmp .filesearch\r
\r
\r
;-----------------------------------;\r
; variables & functions ;\r
;-----------------------------------;\r
- loading db 'Starting BOS'\r
- filename db 'KERNEL SYS'\r
- failure db 'Read error!'\r
-\r
-\r
- ;-----------------------------------------------;\r
- ; read a number of sectors (one at a time) ;\r
- ;-----------------------------------------------;\r
- ; in: ;\r
- ; di = segment to save at ;\r
- ; ax = sector to read ;\r
- ; cx = number of sectors ;\r
- ; out: ;\r
- ; di = updated (added for next read) ;\r
- ; ax = updated (added for next read) ;\r
- ;-----------------------------------------------;\r
- read_sectors:\r
- pusha\r
- mov bl, byte [bpbTrackSect] ; bl = number of sectors per track\r
- div bl ; al = ax / bl\r
- mov cl, ah ; cl = real sector number\r
- add cl, 1\r
-\r
- xor ah, ah ; del the rest of the div before\r
- mov bl, byte [bpbHeads] ; bl = number of heads\r
- div bl ; ah = rest of ( ax / bx ), al = ax / bx\r
- mov ch, al ; ch = number of track\r
- mov dh, ah ; dh = the head number\r
-\r
- mov ax, cx ; save cx in ax\r
- mov cx, 6 ; try it 6 times\r
- .next_try:\r
- push es\r
- push cx\r
- mov cx, ax ; restore cx\r
- push cx\r
-\r
- xor ax, ax\r
- mov dl, [bpbDriveNo] ; reset drive\r
- push dx\r
- int 0x13\r
- jc .failed\r
-\r
- pop dx\r
- pop cx\r
- xor bx, bx\r
- mov es, di\r
- mov ax, 0x0201 ; function 2, 1 sector\r
- int 0x13\r
- jnc .ok ; if it was ok, check next..\r
-\r
- .failed:\r
- pop dx\r
- pop ax\r
-\r
- pop cx\r
- pop es\r
- loop .next_try ; else try once again if there is an error\r
- jmp error ; if cx = 0 and the read operation failed, halt\r
- .ok:\r
- pop cx ; from the next_try loop\r
- pop es\r
- popa\r
- add di, 32 ; add 32 (512/16) to segment\r
- inc ax ; add sector counter\r
- loop read_sectors\r
- ret\r
-\r
-\r
- ;----------------------------------------------------;\r
- ; show a message and wait for a key before reboot ;\r
- ;----------------------------------------------------;\r
- error:\r
- mov bp, failure\r
- mov ax, 0x1301\r
- mov bx, 4\r
- mov cx, 11\r
- mov dx, 0x0401\r
- int 0x10\r
-\r
- mov ah, 0\r
- int 0x16\r
- int 0x19\r
+ loading db 'Starting BOS'\r
+ filename db 'KERNEL SYS'\r
+ failure db 'Read error!'\r
+\r
+\r
+;-----------------------------------------------;\r
+; read a number of sectors (one at a time) ;\r
+;-----------------------------------------------;\r
+; in: ;\r
+; di = segment to save at ;\r
+; ax = sector to read ;\r
+; cx = number of sectors ;\r
+; out: ;\r
+; di = updated (added for next read) ;\r
+; ax = updated (added for next read) ;\r
+;-----------------------------------------------;\r
+read_sectors:\r
+ pusha\r
+ mov bl, byte [bpbTrackSect] ; bl = number of sectors per track\r
+ div bl ; al = ax / bl\r
+ mov cl, ah ; cl = real sector number\r
+ add cl, 1\r
+\r
+ xor ah, ah ; del the rest of the div before\r
+ mov bl, byte [bpbHeads] ; bl = number of heads\r
+ div bl ; ah = rest of ( ax / bx ), al = ax / bx\r
+ mov ch, al ; ch = number of track\r
+ mov dh, ah ; dh = the head number\r
+\r
+ mov ax, cx ; save cx in ax\r
+ mov cx, 6 ; try it 6 times\r
+ .next_try:\r
+ push es\r
+ push cx\r
+ mov cx, ax ; restore cx\r
+ push cx\r
+\r
+ xor ax, ax\r
+ mov dl, [bpbDriveNo] ; reset drive\r
+ push dx\r
+ int 0x13\r
+ jc .failed\r
+\r
+ pop dx\r
+ pop cx\r
+ xor bx, bx\r
+ mov es, di\r
+ mov ax, 0x0201 ; function 2, 1 sector\r
+ int 0x13\r
+ jnc .ok ; if it was ok, check next..\r
+\r
+ .failed:\r
+ pop dx\r
+ pop ax\r
+\r
+ pop cx\r
+ pop es\r
+ loop .next_try ; else try once again if there is an error\r
+ jmp error ; if cx = 0 and the read operation failed, halt\r
+ .ok:\r
+ pop cx ; from the next_try loop\r
+ pop es\r
+ popa\r
+ add di, 32 ; add 32 (512/16) to segment\r
+ inc ax ; add sector counter\r
+ loop read_sectors\r
+ ret\r
+\r
+\r
+;----------------------------------------------------;\r
+; show a message and wait for a key before reboot ;\r
+;----------------------------------------------------;\r
+error:\r
+ mov bp, failure\r
+ mov ax, 0x1301\r
+ mov bx, 4\r
+ mov cx, 11\r
+ mov dx, 0x0401\r
+ int 0x10\r
+\r
+ mov ah, 0\r
+ int 0x16\r
+ int 0x19\r
\r
\r
;-----------------------------------;\r
; the file is found, load it. ;\r
;-----------------------------------;\r
found:\r
- mov bp, [bx+26] ; bp=cluster number from directory entry\r
- mov di, 0x800 ; 1000 (segment)\r
-\r
- .next_block:\r
- xor cx, cx\r
- mov cl, [bpbClustSize] ; reset sector count to 1 cluster\r
- mov si, bp ; si=next should-be cluster for\r
- ; contiguous reads\r
- .next_contiguous:\r
- mov ax, 3 ; 3\r
- mul si ; multiply cluster number by 3\r
- shr ax, 1 ; divide by two\r
- mov bx, ax\r
- mov ax, word [(0x2100+bx)] ; ax=FAT element with junk\r
- jc .odd_cluster ; jump if the value was odd\r
- and ax, 0x0FFF ; leave only lower 12 bits\r
- jmp .got_cluster ; got it\r
- .odd_cluster:\r
- shr ax, 4 ; (leave only bits 4-15)\r
-\r
- .got_cluster:\r
- inc si ; si=current cluster+1\r
- cmp ax, si ; next cluster=current cluster+1?\r
- jne .force_read ; is it still contiguous?\r
-\r
- add cl, [bpbClustSize] ; increase sector count by 1 cluster\r
- adc ch, 0 ; add cf+0 to ch\r
- jmp .next_contiguous\r
-\r
- .force_read:\r
- xchg bp, ax ; ax=bp (base cluster), bp=new cluster\r
- dec ax ; decrease by 2 to get the actual...\r
- dec ax ; ...cluster number\r
-\r
- movzx dx, byte [bpbClustSize]\r
- mul dx ; multiply by sectors per cluster\r
- add ax, 33 ; add data-area location (33)\r
- call read_sectors\r
-\r
- cmp bp, 0x0FF8 ; is the new cluster EOF (FF8-FFF)?\r
- jb .next_block ; if not, read next block\r
+ mov bp, [bx+26] ; bp = cluster from dir entry\r
+ mov di, 0x0800 ; 800 (segment)\r
+\r
+ .next_block:\r
+ xor cx, cx\r
+ mov cl, [bpbClustSize] ; reset sector count to 1 cluster\r
+ mov si, bp ; si = next should-be cluster for\r
+ ; contiguous reads\r
+ .next_contiguous:\r
+ mov ax, 3\r
+ mul si ; multiply cluster number by 3\r
+ shr ax, 1 ; divide by two\r
+ mov bx, ax\r
+ mov ax, word [(0x2100+bx)] ; ax = FAT element with junk\r
+ jc .odd_cluster ; jump if the value was odd\r
+ and ax, 0x0FFF ; leave only lower 12 bits\r
+ jmp .got_cluster ; got it\r
+ .odd_cluster:\r
+ shr ax, 4 ; (leave only bits 4-15)\r
+\r
+ .got_cluster:\r
+ inc si ; si = current cluster+1\r
+ cmp ax, si ; next cluster = current cluster+1?\r
+ jne .force_read ; is it still contiguous?\r
+\r
+ add cl, [bpbClustSize] ; increase sector count by 1 cluster\r
+ adc ch, 0 ; add cf + 0 to ch\r
+ jmp .next_contiguous\r
+\r
+ .force_read:\r
+ xchg bp, ax ; ax = bp (base cluster), bp = new cluster\r
+ dec ax ; decrease by 2 to get the actual...\r
+ dec ax ; ...cluster number\r
+\r
+ movzx dx, byte [bpbClustSize]\r
+ mul dx ; multiply by sectors per cluster\r
+ add ax, 33 ; add data-area location (33)\r
+ call read_sectors\r
+\r
+ cmp bp, 0x0FF8 ; is the new cluster EOF (FF8-FFF)?\r
+ jb .next_block ; if not, read next block\r
\r
;-----------------------;\r
; the file is loaded ;\r
;-----------------------;\r
quit:\r
- jmp 0x0000:0x8000 ; jump to loaded file (64kb in mem)\r
+ jmp 0x0000:0x8000 ; jump to loaded file (64kb in mem)\r
\r
\r
;-------------------------------------;\r
; set the BOOT-signature at byte 510. ;\r
;-------------------------------------;\r
- rb boot+512-2-$\r
- dw 0xAA55
\ No newline at end of file
+ rb boot+512-2-$\r
+ dw 0xAA55
\ No newline at end of file