diff --git a/boot/floppy.asm b/boot/floppy.asm index 8c03b57..a0993f5 100644 --- a/boot/floppy.asm +++ b/boot/floppy.asm @@ -1,4 +1,4 @@ -org 0x0600 +org 0x0000 fdc: ; FDC Descriptor as per ECMA-107 jmp _startup @@ -9,19 +9,19 @@ fdc: ; FDC Descriptor as per ECMA-107 .ss: dw 0x200 ; sector size .sc: - db 0 ; sectors per cluster + db 2 ; sectors per cluster .rsc: - dw 2 ; reserved sector count + dw 1 ; reserved sector count .fn: - db 0 ; number of file allocation tables + db 2 ; number of file allocation tables .rde: - dw 0 ; number of root directory entries + dw 0x70 ; number of root directory entries .ts: dw 720 ; total number of sectors .mi: ; medium identifier db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB) .sf: ; sectors per fat - dw 0 + dw 2 .spt: dw 9 ; sectors per track .nos: @@ -44,33 +44,65 @@ fdc: ; FDC Descriptor as per ECMA-107 times (62 - ($-$$)) db " " _startup: - xor ax, ax - mov ds, ax - mov es, ax + mov ax, 0x1050 + ; setup relocated stack area mov ss, ax xor sp, sp - ; relocate + ; backup important values + push bx + push cx + push dx + ; setup relocated code area + mov es, ax + mov di, 0x0000 + ; setup start code area + xor ax, ax + mov ds, ax mov si, 0x7C00 - mov di, 0x0600 + ; relocate 256 words mov cx, 0x0100 rep movsw ; adjust CS - jmp 0x0000:main + jmp 0x1050:main + +; non-fdc variables +rootdir: +.start: + dw 0 +.length: + dw 0 main: - mov [fdc.drv], dl ; backup drive number + ; setup buffer area directly after the BDA + mov ax, 0x0050 + mov ds, ax + mov es, ax + + mov [cs:fdc.drv], dl ; backup drive number call fix_chs - call find_first_sector + call calc_sectors + call find_first_cluster + xor bx, bx + call load_cluster - call error - db "END OF IMPLEMENTATION", 0 + ; restore important variables + xor ax, ax + mov bp, ax + mov si, ax + mov di, ax + pop dx + pop cx + pop bx + jmp 0x0050:0000 ; Write AX, a string and bail out ; Return pointer is the string start ; String must be 0 suffixed error: call print16 + push cs + pop ds pop si mov bx, 0x0000 mov al, 0x20 @@ -90,41 +122,49 @@ fix_chs: int 0x13 jc .end ; skip if function does not exist inc dh - mov [fdc.nos], dh + mov [cs:fdc.nos], dh mov ax, cx and ax, 0x003F - mov [fdc.spt], ax ; no adjustment because sectors are 1-indexed + mov [cs:fdc.spt], ax ; no adjustment because sectors are 1-indexed mov ax, cx xchg al, ah mov cl,6 shr ah,cl inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders - mul word [fdc.nos] ; number of tracks = number of cylinders * heads - mul word [fdc.spt] ; number of sectors = number of tracks * sectors per track - mov [fdc.ts], ax + mul word [cs:fdc.nos] ; number of tracks = number of cylinders * heads + mul word [cs:fdc.spt] ; number of sectors = number of tracks * sectors per track + mov [cs:fdc.ts], ax .end: ret -; Load the root directory [buffer] -find_first_sector: - mov bx, [fdc.ss] ; bytes per sector +calc_sectors: + mov bx, [cs:fdc.ss] ; bytes per sector mov cl, 5 - shr bx, cl ; div by 2^5, 32 bytes per directory entity - mov ax, [fdc.rde] ; number of root directory entities + shr bx, cl ; div by 2^5, 32 bytes per entry + mov ax, [cs:fdc.rde] ; number of entries xor dx, dx div bx - mov cx, ax ; cx = number of rootdir sectors - mov ax, [fdc.sf] ; sectors per fat - mul byte [fdc.fn] ; number of fats - add ax, [fdc.rsc] ; ax = starting sector of rootdir - mov bx, buffer + mov [cs:rootdir.length], ax + mov ax, [cs:fdc.sf] ; sectors per fat + mul byte [cs:fdc.fn] ; number of fats + add ax, [cs:fdc.rsc] ; reserved sectors + mov [cs:rootdir.start], ax + ret + +; Load the root directory +find_first_cluster: + mov ax, [cs:rootdir.start] + mov cx, [cs:rootdir.length] + xor bx, bx .blkloop: call loadblk - add bx, buffer + add bx, [cs:fdc.ss] add ax, 1 loop .blkloop - mov cx, [fdc.rde] - mov bx, buffer + push cs + pop es + mov cx, [cs:fdc.rde] + xor bx, bx .dirloop: push cx mov cx, 0x000B @@ -138,38 +178,49 @@ find_first_sector: call error db "NOT FOUND", 0 .found: + push ds + pop es add bx, 26 mov ax, [bx] ret ; Load a single FAT cluster into memory ; in ax cluster number -; bx buffer +; es:bx buffer ; -loadsec: - call print16 - mov ax, bx - call print16 +load_cluster: + xor ch, ch + mov cl, [cs:fdc.sc] ; sectors per cluster + xor dx, dx + dec ax ; somehow 2 is first cluster + div word cx + add ax, [cs:rootdir.start] + add ax, [cs:rootdir.length] +.loop: + call loadblk + inc ax + add bx, [cs:fdc.ss] + loop .loop ret ; Load a single block into memory ; Does not return on error ; in ax sector number -; bx buffer +; es:bx buffer loadblk: push ax push cx push dx xor dx, dx - div word [fdc.spt] ; ax:temp = (lba / spt) + div word [cs:fdc.spt] ; ax:temp = (lba / spt) inc dx ; dx:sector = (lba % spt) + 1 mov cl, dl ; sector number xor dx, dx - div word [fdc.nos] ; ax:cylinder = (tmp / heads) + div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads) ; dx:head = (tmp % heads) mov ch, al ; cylinder number mov dh, dl ; head number - mov dl, [fdc.drv] ; driver number + mov dl, [cs:fdc.drv] ; driver number mov ax, 0x0201 ; ah=0x02 al=0x01 int 0x13 jc .error @@ -194,5 +245,3 @@ bootfilename: times (0x1FE - ($-$$)) db 0 dw 0xAA55 - -buffer: