diff --git a/Makefile b/Makefile index 43c79e6..2e1165b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ FLOPPY = 360 PROGRAMS = hello.com -DISTFILES = $(PROGRAMS) rdos86.bs +DISTFILES = $(PROGRAMS) kernel.bs ROMS = QEMU_ARCH = $(shell uname -m) diff --git a/fat32.asm b/fat32.asm index e6b5475..8ca23b8 100644 --- a/fat32.asm +++ b/fat32.asm @@ -1,9 +1,12 @@ ; Bootsector for FAT32 filesystems org 0x0800 - jmp near init + jmp short init + nop ; WORD reserved sector count rsc: equ ( $$ + 0x00E ) + ; BYTE number of sectors per cluster +sc: equ ( $$ + 0x00D ) ; BYTE number of FATs fn: equ ( $$ + 0x010 ) ; DWORD hidden sector count (partition offset) @@ -53,6 +56,7 @@ read: pop bp mov dl, 0x80 mov si, sp + mov di, [si+4] int 0x13 jc err @@ -61,31 +65,33 @@ read: pop bp push bp ret - ; Advances cluster number to next entry -next: ; Upper two words for sector num + ; Advances [clus] to next FAT entry +next: ; push upper two words for sector num xor ax, ax push ax push ax - ; Lower two words for sector num + ; get current cluster number mov ax, [clus] mov dx, [clus+2] - ; 32-bit >> 7 + ; shift 2 left for dword-sized FAT entries + ; shift 9 right for sector size mov cl, 7 shftl: clc rcr dx, 1 rcr ax, 1 loop shftl - ; Add reserved sector count + ; add reserved sector count add ax, word [rsc] adc dx, 0 + ; push lower dword of sector number push dx push ax - ; target buffer + ; push ptr to target buffer push cs mov ax, buf push ax @@ -93,13 +99,16 @@ shftl: clc mov cx, 1 call read - ; Stow off offset in FAT sector + ; get lower part of cluster number mov si, [clus] + ; multiply with 4 sal si, 1 sal si, 1 + ; make sure its within sector range and si, 0x1FF add si, buf mov di, clus + ; copy dword from FAT to [clus] movsw movsw @@ -107,9 +116,67 @@ shftl: clc add sp, 12 ret -main: call next + ; reads current cluster into [dest] +readc: ; load cluster number mov ax, [clus] mov dx, [clus+2] + + ; subtract the two dummy entries from FAT start + sub ax, 2 + sbb dx, 0 + + ; convert cluster number to sector number + ; this is some cheapo multiplication with 2^n + mov ch, [sc] +l02: shr cl, 1 + jz l02e + clc + rcl dx, 1 + rcl ax, 1 + jmp l02 +l02e: + ; dx:ax is now sector num in data area + + ; get number of FATs + xor ch, ch + mov cl, byte [fn] + ; add their sizes up +floop: add ax, [sf] + adc dx, [sf+2] + loop floop + + ; add reserved sector count + add ax, [rsc] + add dx, 0 + + ; push sector num QWORD + xor cx, cx + push cx + push cx + push dx + push ax + + ; push target buffer DWORD + ; dest gives the segment register + mov ax, [dest] + push ax + push cx + + ; push sector count + ; always an full cluster + mov cx, [sc] + xor ch, ch + + call read + + cmp cl, [sc] + jne err + + add sp, 12 + ret + +main: call readc + int 3 xor ah,ah @@ -117,7 +184,17 @@ main: call next int 0x19 jmp hlt + ; the packing is so that it looks nice in a hexdump + times (0x1E0 - ($-$$)) db 0 + ; directory the kernel is in +tdir: db "RDOS " + ; current cluster number clus: dd 2 + times (0x1F0 - ($-$$)) db 0 + ; filename for hte kernel +tfile: db "KERNEL BS " + ; segment register for data +dest: dw 0x07c0 ; Padding and signature times (0x1FE - ($-$$)) db 0 diff --git a/rdos86.asm b/kernel.asm similarity index 100% rename from rdos86.asm rename to kernel.asm