diff --git a/boot/floppy.asm b/boot/floppy.asm index 5ea7a72..1453f4e 100644 --- a/boot/floppy.asm +++ b/boot/floppy.asm @@ -1,18 +1,17 @@ -org 0x7600 - ; Memory layout: -; 060:0000 PSP for loaded program -; 060:0100 Loaded program -; 060:7800 Our code (= 0:7C00) -; 060:8000 FAT table -; 060:E000 Root directory -; 060:FF00 Stack area +%define mbr 0x00600 ; 1 sector +%define self 0x00800 ; 1 sector +%define fattab 0x01000 ; variable size +%define rootdir 0x06000 ; variable size +%define psp 0x07B00 ; 0x100 bytes +%define prog 0x07C00 ; 64k - psp -init: - jmp 0x060:main +org self -times (0x0B - ($-$$)) db 0 fdc: +.jmp: + jmp short main + times (0x0B - ($-$$)) db 0 .ss: dw 0x200 ; sector size .sc: @@ -50,6 +49,87 @@ fdc: db "FAT12" times (62 - ($-$$)) db " " +main: + cli + + ; Stack grows down from PSP + 64k + mov ax, (psp >> 4) + mov ss, ax + xor sp, sp + + ; Relocate from [prog] to [self] + xor ax, ax + mov ds, ax + mov es, ax + mov si, prog + mov di, self + mov cx, 0x100 + rep movsw + + ; Jump into relocated code + jmp 0:.relocated +.relocated: + + mov [fdc.drv], dl ; save drive number in fd + sti + + ; load fat table into memory + mov ax, [fdc.rsc] + mov cx, [fdc.sf] + xor dx, dx + mov bx, fattab + call load_sectors + + ; calculate length of rootdir + mov ax, [fdc.rde] + mov cl, 4 + shr ax, cl ; 32 bytes per entry + mov cx, ax + + ; load root dir + xor dx, dx + mov ax, [fdc.sf] + mul byte [fdc.fn] + add ax, [fdc.rsc] + mov bx, rootdir + call load_sectors + + ; remember where we left off + ; clusters start after rootdir + mov [cluster_offset], ax + + call load_file + mov bp, 0x0032 + jc error + + ; get length of arguments + mov cx, 0x007F + mov di, arguments + xor ax, ax + repne scasb + dec di + sub di, arguments + mov cx, di + + ; setup arguments field + mov [psp+0x080], cl + mov di, 0x081 + mov si, arguments + rep movsb + mov BYTE [di], 0x0D + + ; setup int 19h call at 0000, and push its address to stack + mov WORD [psp], 0x19CD + push sp + + ; clear out registers and jump into target + xor ax, ax + xor cx, cx + xor dx, dx + xor bx, bx + mov dl, [fdc.drv] + jmp 0x07B0:0x0100 + ; Read sectors from disk ; Does not return on error ; ax and bx will be incremented, cx decremented @@ -99,7 +179,7 @@ load_sectors: ; Load the file in [filename] ; or exit with carry set load_file: - mov si, 0xE000 + mov si, rootdir mov cx, [fdc.rde] .loop: call file_match @@ -127,7 +207,7 @@ file_match: read_clusters: add si, 0x1A lodsw - mov bx, 0x0100 + mov bx, prog .loop: ; read cluster into area for target file push ax @@ -144,7 +224,7 @@ read_clusters: mov si, ax shr si, 1 add si, ax - add si, 0x8000 + add si, fattab ; load entry from FAT, truncate to 12 bit mov dx, [si] @@ -161,76 +241,6 @@ read_clusters: ret -main: - cli - ; Everything in one segment, stack starts on top - mov ax, cs - mov ds, ax - mov es, ax - mov ss, ax - xor sp, sp - mov [fdc.drv], dl ; save drive number in fdc - sti - - ; load fat table into memory - mov ax, [fdc.rsc] - mov cx, [fdc.sf] - xor dx, dx - mov bx, 0x8000 - call load_sectors - - ; calculate length of rootdir - mov ax, [fdc.rde] - dec ax - mov cl, 4 - shr ax, cl ; 32 bytes per entry - inc ax - mov cx, ax - - ; load root dir - xor dx, dx - mov ax, [fdc.sf] - mul byte [fdc.fn] - add ax, [fdc.rsc] - mov bx, 0xE000 - call load_sectors - - ; remember where we left off - ; clusters start after rootdir - mov [cluster_offset], ax - - call load_file - mov bp, 0x0032 - jc error - - ; get length of arguments - mov cx, 0x007F - mov di, arguments - xor ax, ax - repne scasb - dec di - sub di, arguments - mov cx, di - - ; setup arguments field - mov [0x080], cl - mov di, 0x081 - mov si, arguments - rep movsb - mov BYTE [di], 0x0D - - ; setup int 19h call at 0000, and push its address to stack - mov WORD [0000], 0x19CD - push sp - - ; clear out registers and jump into target - xor ax, ax - xor cx, cx - xor dx, dx - xor bx, bx - mov dl, [fdc.drv] - jmp 0x0100 - error: mov ax, bp mov ah, 0x0e @@ -245,8 +255,6 @@ error: cluster_offset: dw 0 -times (0x174 - ($-$$)) db 0 - filename: db "KERNEL COM"