160 lines
2.7 KiB
NASM
160 lines
2.7 KiB
NASM
org 0x0000
|
|
|
|
jmp 0x07C0:main
|
|
|
|
times (0x0B - ($-$$)) db 0 ; space-padded
|
|
fdc:
|
|
.ss:
|
|
dw 0x200 ; sector size
|
|
.sc:
|
|
db 2 ; sectors per cluster
|
|
.rsc:
|
|
dw 1 ; reserved sector count
|
|
.fn:
|
|
db 2 ; number of file allocation tables
|
|
.rde:
|
|
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 2
|
|
.spt:
|
|
dw 9 ; sectors per track
|
|
.nos:
|
|
dw 2 ; number of sides (heads)
|
|
.po:
|
|
dd 0 ; partition offset (in LBA blocks)
|
|
.lrgts:
|
|
dd 0
|
|
.drv:
|
|
db 0 ; drive number
|
|
db 0
|
|
db 0x29 ; efdc signature
|
|
.vid:
|
|
dd 0 ; volume id
|
|
.vlabel:
|
|
db "2B"
|
|
times (54 - ($-$$)) db " "
|
|
.fstype:
|
|
db "FAT12"
|
|
times (62 - ($-$$)) db " "
|
|
|
|
main:
|
|
cli
|
|
; setup stack area growing down from directly below us
|
|
xor ax, ax
|
|
mov ss, ax
|
|
mov sp, 0x7C00
|
|
; setup base segments
|
|
mov ax, cs
|
|
mov ds, ax
|
|
mov es, ax
|
|
; save initial environment
|
|
push bx
|
|
push cx
|
|
push dx
|
|
|
|
mov [fdc.drv], dl ; fix drive number in fdc
|
|
|
|
%include "chs.inc"
|
|
|
|
mov di, 0x1000 ; loading address for roms
|
|
call search_rootdir
|
|
|
|
mov ax, 0xFFFF
|
|
call error
|
|
db "THING", 0
|
|
|
|
search_rootdir:
|
|
mov ax, [fdc.sf]
|
|
mul byte [fdc.fn]
|
|
add ax, [fdc.rsc]
|
|
mul word [fdc.ss]
|
|
mov si, ax ; now pointing to start of rootdir
|
|
mov cx, [fdc.rde]
|
|
jmp .start
|
|
.next:
|
|
dec cx
|
|
jz .end
|
|
add si, 0x20
|
|
.start:
|
|
call lazy_load
|
|
cmp byte [si], 0 ; end of directory
|
|
je .end
|
|
cmp byte [si], 0xe5 ; deleted entry
|
|
je .next
|
|
cmp word [si+8], 0x4F52 ; first 2 chars of extension: "RO"
|
|
jne .next
|
|
mov ax, [si+10] ; 3rd char of extension, file flags
|
|
and ax, 0x14FF ; zero out flags except directory and system
|
|
cmp ax, 0x044D ; "M" , system flag set, directory flag unset
|
|
jne .next
|
|
mov ax, [si+26]
|
|
push si
|
|
push cx
|
|
call loadrom
|
|
pop cx
|
|
pop si
|
|
jmp .next
|
|
.end:
|
|
ret
|
|
|
|
; in ax cluster number
|
|
loadrom:
|
|
call print16
|
|
ret
|
|
|
|
; Makes sure the block starting with (or under SI) is
|
|
; already fetched from disk
|
|
; in ds:si data expected to be fetched from disk
|
|
; trashes ax, bx and dx
|
|
lazy_load:
|
|
cmp si, [max_si]
|
|
jc .end
|
|
; calculate next sector number
|
|
mov ax, [max_si]
|
|
xor dx, dx
|
|
div word [fdc.ss]
|
|
; write to es:bx
|
|
xor dx, dx
|
|
push cs
|
|
pop es
|
|
mov bx, [max_si]
|
|
call load_sector
|
|
; update max_si counter
|
|
mov ax, [max_si]
|
|
add ax, [fdc.ss]
|
|
mov [max_si], ax
|
|
; loop until requirement is satisfied
|
|
jmp lazy_load
|
|
.end:
|
|
ret
|
|
|
|
error:
|
|
call print16
|
|
pop si
|
|
mov bx, 0x0000
|
|
mov al, 0x20
|
|
.loop:
|
|
mov ah, 0x0e
|
|
int 0x10
|
|
lodsb
|
|
cmp al, 0x00
|
|
jne .loop
|
|
.hlt:
|
|
hlt
|
|
jmp .hlt
|
|
|
|
%include "print.asm"
|
|
|
|
times (0x1FA - ($-$$)) db 0
|
|
|
|
dw 0x2B2B
|
|
|
|
max_si:
|
|
dw 0x200
|
|
|
|
dw 0xAA55
|