rdos/src/sys.asm

162 lines
2.6 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
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
; 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
; TODO: abort if dx is not zero
mov cx, ax
mov ax, [prog+0x016] ; logical sectors per fat
; TODO: abort if ax is zero (=large FAT32)
mov bl, [prog+0x010]
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]
mul word [prog+0x01A]
mul word [track]
; calculate cluster offset of target track
sub ax, si
mov bl, [prog+0x00D] ; sectors per cluster
mov bh, 0
call debug
div bx
call debug
ret
; TODO:
; calculate cluster offset of target track
; calculate cluster length of target track
; calculate offset into fat table
; load part of fat table spanning our track
; 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