rdos/boot/floppy.asm

244 lines
4.4 KiB
NASM
Raw Normal View History

2019-03-31 22:53:14 +02:00
org 0x0000
2019-03-25 09:51:37 +01:00
2019-03-27 23:05:00 +01:00
fdc: ; FDC Descriptor as per ECMA-107
jmp _startup
times (0x03 - ($-$$)) nop
2019-03-25 09:51:37 +01:00
.oem:
2019-03-27 23:05:00 +01:00
db "2B" ; creating system identifier
times (0x0B - ($-$$)) db " " ; space-padded
.ss:
dw 0x200 ; sector size
.sc:
2019-03-31 22:53:14 +02:00
db 2 ; sectors per cluster
2019-03-27 23:05:00 +01:00
.rsc:
2019-03-31 22:53:14 +02:00
dw 1 ; reserved sector count
2019-03-27 23:05:00 +01:00
.fn:
2019-03-31 22:53:14 +02:00
db 2 ; number of file allocation tables
2019-03-27 23:05:00 +01:00
.rde:
2019-03-31 22:53:14 +02:00
dw 0x70 ; number of root directory entries
2019-03-28 00:06:13 +01:00
.ts:
dw 720 ; total number of sectors
2019-03-27 23:05:00 +01:00
.mi: ; medium identifier
2019-03-25 09:51:37 +01:00
db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB)
2019-03-27 23:05:00 +01:00
.sf: ; sectors per fat
2019-03-31 22:53:14 +02:00
dw 2
2019-03-25 09:51:37 +01:00
.spt:
dw 9 ; sectors per track
2019-03-27 23:05:00 +01:00
.nos:
dw 2 ; number of sides (heads)
.po:
dd 0 ; partition offset (in LBA blocks)
2019-03-28 00:06:13 +01:00
.lrgts:
dw 0
2019-03-27 23:05:00 +01:00
.drv:
2019-03-26 21:46:40 +01:00
db 0 ; drive number
db 0
2019-03-27 23:05:00 +01:00
db 0x29 ; efdc signature
.vid:
dd 0 ; volume id
.vlabel:
db "2B"
times (54 - ($-$$)) db " "
.fstype:
db "FAT12"
times (62 - ($-$$)) db " "
2019-03-25 09:51:37 +01:00
_startup:
xor ax, ax
; setup stack area growing down from 0x10000
mov ss, ax
mov sp, ax
2019-03-31 14:44:50 +02:00
; adjust CS
jmp 0x07C0:main
2019-03-31 22:53:14 +02:00
; non-fdc variables
rootdir:
.start:
dw 0
.length:
dw 0
2019-03-28 00:05:46 +01:00
main:
2019-05-02 22:51:20 +02:00
cli
; backup important values
push bx
push cx
push dx
; setup buffer area directly at 4k
mov ax, 0x0100
2019-03-31 22:53:14 +02:00
mov ds, ax
mov es, ax
mov [cs:fdc.drv], dl ; backup drive number
2019-03-29 23:32:50 +01:00
call fix_chs
2019-03-31 22:53:14 +02:00
call calc_sectors
call find_first_cluster
xor bx, bx
call load_cluster
2019-03-31 22:53:14 +02:00
; restore important variables
xor ax, ax
pop dx
pop cx
pop bx
mov di, [0x001A]
mov ax, [di+0x1A]
push ds
push ax
retf
call error
db "ROM ERROR", 0
; Write AX, a string and bail out
; Return pointer is the string start
; String must be 0 suffixed
error:
call print16
2019-03-31 22:53:14 +02:00
push cs
pop ds
pop si
mov bx, 0x0000
mov al, 0x20
.loop:
mov ah, 0x0e
int 0x10
lodsb
cmp al, 0x00
jne .loop
.hlt:
hlt
jmp .hlt
; Read CHS data from BIOS and fix fdc values
fix_chs:
2019-03-27 23:05:00 +01:00
mov ah, 0x08
2019-03-31 14:44:50 +02:00
int 0x13
jc .end ; skip if function does not exist
2019-03-27 23:05:00 +01:00
inc dh
2019-03-31 22:53:14 +02:00
mov [cs:fdc.nos], dh
2019-03-27 23:05:00 +01:00
mov ax, cx
and ax, 0x003F
2019-03-31 22:53:14 +02:00
mov [cs:fdc.spt], ax ; no adjustment because sectors are 1-indexed
2019-03-27 23:05:00 +01:00
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
2019-03-31 22:53:14 +02:00
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
2019-03-29 22:40:44 +01:00
2019-03-31 22:53:14 +02:00
calc_sectors:
mov bx, [cs:fdc.ss] ; bytes per sector
2019-03-28 00:06:13 +01:00
mov cl, 5
2019-03-31 22:53:14 +02:00
shr bx, cl ; div by 2^5, 32 bytes per entry
mov ax, [cs:fdc.rde] ; number of entries
2019-03-28 00:06:13 +01:00
xor dx, dx
div bx
2019-03-31 22:53:14 +02:00
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:
2019-03-28 00:06:13 +01:00
call loadblk
2019-03-31 22:53:14 +02:00
add bx, [cs:fdc.ss]
add ax, 1
loop .blkloop
2019-03-31 22:53:14 +02:00
push cs
pop es
mov cx, [cs:fdc.rde]
xor bx, bx
.dirloop:
push cx
mov cx, 0x000B
mov si, bx
mov di, bootfilename
repe cmpsb
2019-03-28 00:06:13 +01:00
pop cx
jz .found
add bx, 0x0020 ; 32 bytes per directory entry
loop .dirloop
2019-03-31 14:44:50 +02:00
call error
db "NOT FOUND", 0
.found:
2019-03-31 22:53:14 +02:00
push ds
pop es
add bx, 26
mov ax, [bx]
ret
2019-03-28 00:06:13 +01:00
2019-03-31 14:44:50 +02:00
; Load a single FAT cluster into memory
; in ax cluster number
2019-03-31 22:53:14 +02:00
; es:bx buffer
2019-03-31 14:44:50 +02:00
;
2019-03-31 22:53:14 +02:00
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
2019-03-31 14:44:50 +02:00
ret
2019-03-28 00:06:13 +01:00
; Load a single block into memory
2019-03-31 14:44:50 +02:00
; Does not return on error
2019-03-27 23:05:00 +01:00
; in ax sector number
2019-03-31 22:53:14 +02:00
; es:bx buffer
2019-03-27 23:05:00 +01:00
loadblk:
2019-03-28 00:06:13 +01:00
push ax
push cx
push dx
2019-03-27 23:05:00 +01:00
xor dx, dx
2019-03-31 22:53:14 +02:00
div word [cs:fdc.spt] ; ax:temp = (lba / spt)
2019-03-27 23:05:00 +01:00
inc dx ; dx:sector = (lba % spt) + 1
mov cl, dl ; sector number
xor dx, dx
2019-03-31 22:53:14 +02:00
div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads)
2019-03-27 23:05:00 +01:00
; dx:head = (tmp % heads)
mov ch, al ; cylinder number
mov dh, dl ; head number
2019-03-31 22:53:14 +02:00
mov dl, [cs:fdc.drv] ; driver number
2019-03-27 23:05:00 +01:00
mov ax, 0x0201 ; ah=0x02 al=0x01
int 0x13
2019-03-29 23:32:50 +01:00
jc .error
2019-03-28 00:06:13 +01:00
pop dx
pop cx
pop ax
2019-03-27 23:05:00 +01:00
ret
2019-03-29 23:32:50 +01:00
.error:
xchg al, ah
2019-03-31 14:44:50 +02:00
call error
db "DISK ERROR", 0
2019-03-26 21:46:40 +01:00
2019-03-25 09:51:37 +01:00
%include "print.asm"
2019-03-29 22:40:44 +01:00
times (0x1F0 - ($-$$)) db 0
bootfilename:
db "KERNEL"
2019-03-29 22:40:44 +01:00
times (0x1F8 - ($-$$)) db " "
db "ROM"
2019-03-29 22:40:44 +01:00
times (0x1FE - ($-$$)) db 0
2019-03-25 09:51:37 +01:00
dw 0xAA55