rdos/src/sys.asm

185 lines
3.0 KiB
NASM
Raw Normal View History

2021-12-11 17:46:00 +01:00
fcb1 equ 0x5C
org 0x100
jmp main
%include "scan.inc"
2021-12-11 17:46:00 +01:00
%include "print.inc"
drvnum db 0
track dw 39
2021-12-11 17:46:00 +01:00
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
2021-12-11 17:46:00 +01:00
call lodnum
mov dx, ax
test dx, ~0x83
jnz drverr
mov byte [drvnum], dl
2021-12-11 17:46:00 +01:00
test dl, 0x80
jz floppy
call drverr
drverr call putsh
db "Failed to access drive", 0x0A, 0x0D, 0
int 0x20
; read bios parameter block
2021-12-11 17:46:00 +01:00
floppy mov ax, 0x0201
mov cx, 0x0001
mov dh, 0
mov bx, prog
2021-12-11 17:46:00 +01:00
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
2021-12-11 17:46:00 +01:00
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
2021-12-11 17:46:00 +01:00
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
2021-12-11 17:46:00 +01:00
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 $
2021-12-11 17:46:00 +01:00
align 2
psp equ $
2021-12-11 17:46:00 +01:00
args equ psp + 0x80
prog equ psp + 0x100