154 lines
2.6 KiB
NASM
154 lines
2.6 KiB
NASM
org 0x7C00
|
|
|
|
bpb:
|
|
jmp _startup ; 2 bytes
|
|
nop ; 1 byte
|
|
.oem:
|
|
db "OEM " ; OEM
|
|
.bps:
|
|
dw 0x200 ; bytes per sector
|
|
.spc:
|
|
db 1 ; sectors per cluster
|
|
.rsectors:
|
|
dw 2 ; number of reserved sectors
|
|
.fats:
|
|
db 2 ; number of file allocation tables
|
|
.dirents:
|
|
dw 2 ; Number of directory entries
|
|
.sectors:
|
|
dw 720 ; total number of sectors
|
|
.mtd: ; media descriptor type
|
|
db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB)
|
|
.spfat: ; sectors per fat
|
|
dw 0
|
|
.spt:
|
|
dw 9 ; sectors per track
|
|
.heads:
|
|
dw 2 ; number of heads
|
|
.hidsecs:
|
|
dd 0 ; number of hidden sectors
|
|
.lrgsectors:
|
|
dd 0 ; large sector count
|
|
.drivenum:
|
|
db 0 ; drive number
|
|
.winntflags:
|
|
db 0
|
|
.signature:
|
|
db 0x28
|
|
|
|
times (0x5A - ($-$$)) nop
|
|
|
|
_startup:
|
|
call adjust_bpb
|
|
mov ax, 0x0500
|
|
mov es, ax
|
|
|
|
mov si, 1
|
|
mov di, 0x7D00
|
|
mov cx, 0x10
|
|
call loadblk
|
|
call dump
|
|
.end:
|
|
hlt
|
|
jmp .end
|
|
|
|
dump:
|
|
mov si, 0x0000
|
|
mov cx, 0x10
|
|
.nextline:
|
|
mov ax, si
|
|
call print16
|
|
mov al, 0x3A
|
|
call printc
|
|
mov al, 0x20
|
|
call printc
|
|
|
|
push cx
|
|
mov cx, 0x0020
|
|
.words:
|
|
es lodsb
|
|
call print8
|
|
loop .words
|
|
pop cx
|
|
|
|
mov al, 0x0A
|
|
call printc
|
|
mov al, 0x0D
|
|
call printc
|
|
|
|
loop .nextline
|
|
|
|
ret
|
|
|
|
; Adjust the bdp data from BIOS-supplied data (if)
|
|
; No args, no output
|
|
adjust_bpb:
|
|
push ax
|
|
push cx
|
|
push dx
|
|
mov ah, 0x08
|
|
int 0x13 ; required, QEMU detects 360kB as 1200kB with CHS 80 2 15
|
|
jc .end ; skip if function does not exist
|
|
inc dh
|
|
mov [bpb.heads], dh
|
|
mov ax, cx
|
|
and ax, 0x003F
|
|
mov [bpb.spt], ax ; no adjustment because sectors are 1-indexed
|
|
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
|
|
mul word [bpb.heads] ; number of tracks = number of cylinders * heads
|
|
mul word [bpb.spt] ; number of sectors = number of tracks * sectors per track
|
|
mov [bpb.sectors], ax
|
|
.end:
|
|
pop dx
|
|
pop cx
|
|
pop ax
|
|
ret
|
|
|
|
; in si sector number,
|
|
; dl drive number
|
|
; es:0000 buffer
|
|
; out al error code,
|
|
; carry set if error
|
|
loadblk:
|
|
push bx
|
|
push cx
|
|
push dx
|
|
xor dx, dx
|
|
mov ax, si
|
|
div word [bpb.spt] ; ax:temp = (lba / spt)
|
|
inc dx ; dx:sector = (lba % spt) + 1
|
|
mov cl, dl ; for int 0x13
|
|
xor dx, dx
|
|
div word [bpb.heads] ; ax:cylinder = (tmp / heads)
|
|
; dx:head = (tmp % heads)
|
|
mov ch, al ; for int 0x13
|
|
mov ax, dx
|
|
pop dx ; drive number comes back into dl
|
|
mov dh, al ; for int 0x13
|
|
|
|
mov bx, 0x0000
|
|
mov ax, 0x0201 ; ah=0x02 al=0x01
|
|
int 0x13
|
|
|
|
call print16
|
|
lahf
|
|
xchg ah, al
|
|
call print8
|
|
mov al, 0x0A
|
|
call printc
|
|
mov al, 0x0D
|
|
call printc
|
|
|
|
pop cx
|
|
pop bx
|
|
ret
|
|
|
|
%include "print.asm"
|
|
|
|
times (0x1FE - ($-$$)) nop
|
|
dw 0xAA55
|