rdos/src/sys.asm

185 lines
3.0 KiB
NASM

fcb1 equ 0x5C
org 0x100
jmp main
%include "scan.inc"
%include "print.inc"
drvnum db 0
track dw 39
main mov di, 0x81
mov al, 0x20
mov ch, 0
mov cl, [0x80]
repe scasb
repne scasb
test cx, cx
jnz rddrv
call putsh
db "BIOS drive number not specified", 0x0A, 0x0D, 0
int 0x20
rddrv mov si, di
call lodnum
mov dx, ax
test dx, ~0x83
jnz drverr
mov byte [drvnum], dl
test dl, 0x80
jz floppy
call drverr
drverr call putsh
db "Failed to access drive", 0x0A, 0x0D, 0
int 0x20
; read bios parameter block
floppy mov ax, 0x0201
mov cx, 0x0001
mov dh, 0
mov bx, prog
int 0x13
jc drverr
mov ax, [prog+0x016]
cmp ax, 12
jbe .gok
call putsh
db "Unsupported FAT size", 0x0A, 0x0D, 0
int 0x20
.gok nop
; calculate start of cluster area
mov ax, [prog+0x011] ; number of dir entries
mov cl, 5
shl ax, cl
mov bx, [prog+0x0B] ; bytes per sector
div bx
mov cx, ax
mov ax, [prog+0x016] ; logical sectors per fat
mov bl, [prog+0x010] ; number of fats
mov bh, 0
mul bx
add ax, cx
add ax, [prog+0x00E] ; reserved sectors
mov si, ax
; calculate sector offset of target track
mov ax, [prog+0x018] ; sectors per track
mul word [prog+0x01A] ; number of heads
mul word [track]
; calculate cluster offset of target track -> SI
sub ax, si
mov bl, [prog+0x00D] ; sectors per cluster
mov bh, 0
xor dx, dx
div bx
mov si, ax
; calculate cluster length of target track -> DI
mov ax, [prog+0x018] ; sectors per track
add ax, dx ; remainder
; add sectors per cluster minus one
add ax, bx
dec ax
; divide by sectors per cluster and floor
xor dx, dx
div bx
mov di, ax
; load fat table
call debug
ret
; TODO:
; calculate offset into fat table
; check that all relevant clusters are 0 or 0xFFF7
; set all relevant clusters to 0xFFF7
; track is now available for direct writing
; set up boot code
mov di, prog
mov ax, 0x7FEB
stosw
mov byte [di], 0x80
add di, 0x7F - b_ld + b_rst
mov si, b_rst
mov cx, b_end - b_rst
rep movsb
; write back bootsector
mov ax, 0x0301
mov cx, 0x0001
mov dh, 0
mov bx, prog
int 0x13
jc drverr
mov dx, fcb1
mov ah, 0xF
int 0x21
test al, al
jz .fok
.ferr call putsh
db "Failed to read input file", 0x0A, 0x0D, 0
ret
.fok mov si, prog
; apply our target address
.rloop mov dx, si
mov ah, 0x1A
int 0x21
; increment address for next iteration
add si, 0x80
; do a read
mov dx, fcb1
mov ah, 0x14
int 0x21
; success: continue
cmp al, 0
jz .rloop
; eof: break
cmp al, 1
jz .cok
; segment wrap: fail
cmp al, 2
jz .ferr
; we assume al=3: eof
.cok nop
mov ax, si
sub ax, args
add ax, 0x1FF
mov cl, 9
shr ax, cl
call debug
ret
; code to copy into boot sector
b_rst mov ah, 0
int 0x13
b_ld mov ax, 0x60
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
mov ax, 0x0208 ; read, 8 sectors
b_len equ $ - 2
mov cx, 0x2701 ; track 39, sector 1
b_trck equ $ - 1
b_strt equ $ - 2
mov dh, 0 ; head 0
xor bx, bx ; es:bx=0x60:0
int 0x13
jc b_rst
mov byte [4], dl
jmp 0x60:0x100
b_end equ $
align 2
psp equ $
args equ psp + 0x80
prog equ psp + 0x100