161 lines
2.3 KiB
NASM
161 lines
2.3 KiB
NASM
cpu 8086
|
|
org 0x7c00
|
|
|
|
jmp short _code
|
|
nop
|
|
|
|
; 1440K floppy
|
|
; BPB
|
|
oemidentifier db "nor86 "
|
|
byterpersector dw 512
|
|
sectorspercluster db 1
|
|
reservedsectors dw 1
|
|
fats db 2
|
|
rootdirentries dw 224
|
|
totalsectors dw 2880
|
|
mediadescription db 0xf0
|
|
sectorsperfat dw 9
|
|
sectorspertrack dw 18
|
|
heads dw 2
|
|
hiddensectors dd 0
|
|
totalsectorslarge dd 0
|
|
|
|
; EBPB
|
|
drivenumber db 0 ; useless on-disk, used as a variable
|
|
reserved db 0 ; winnt flags
|
|
signature db 0x29 ; mkdosfs uses this, dunno how 0x28 differs
|
|
serial dd 0
|
|
volumelabel db "nor86 boot "
|
|
fstype db "FAT12 "
|
|
|
|
_code:
|
|
jmp 0:_start
|
|
|
|
_start:
|
|
cld
|
|
; Set up segments
|
|
mov ax, cs
|
|
mov ds, ax
|
|
mov es, ax
|
|
cli
|
|
mov ss, ax
|
|
mov sp, 0x7c00
|
|
sti
|
|
|
|
; Save bootdrive
|
|
mov [drivenumber], dl
|
|
|
|
root_dir:
|
|
; Disk organization:
|
|
; Reserved sectors (MBR)
|
|
; FAT1
|
|
; FAT2
|
|
; Root dir
|
|
; → Root dir starts at LBA reservedsectors + fats*sectorsperfat
|
|
xor ah, ah
|
|
mov al, [fats]
|
|
mul word [sectorsperfat]
|
|
add ax, [reservedsectors]
|
|
mov [rootdir], ax
|
|
|
|
call chs
|
|
|
|
mov ah, 2
|
|
mov al, 14 ; TODO: don't hardcode
|
|
mov dl, [drivenumber]
|
|
mov bx, 0x500
|
|
int 0x13
|
|
|
|
print_root:
|
|
mov byte [0x500 + 32*224], 0 ; TODO: don't hardcode
|
|
mov si, 0x500
|
|
.entry:
|
|
cmp byte [si], 0
|
|
je .end
|
|
|
|
test byte [si + 11], 0x08 + 0x10
|
|
jz .isfile
|
|
|
|
add si, 32
|
|
jmp .entry
|
|
|
|
.isfile:
|
|
mov ah, 0xe
|
|
mov cx, 8
|
|
.name:
|
|
lodsb
|
|
int 0x10
|
|
loop .name
|
|
|
|
mov al, ' '
|
|
int 0x10
|
|
|
|
mov cx, 3
|
|
.ext:
|
|
lodsb
|
|
int 0x10
|
|
loop .ext
|
|
|
|
mov al, 13
|
|
int 0x10
|
|
mov al, 10
|
|
int 0x10
|
|
|
|
add si, 32 - 11
|
|
jmp .entry
|
|
|
|
.end:
|
|
|
|
hang:
|
|
hlt
|
|
jmp hang
|
|
|
|
chs:
|
|
push ax
|
|
push bx
|
|
|
|
; Save drive number
|
|
mov bl, dl
|
|
|
|
xor dx, dx
|
|
; cylinder (track) - head - sector
|
|
; cylinder = LBA / sectorspertrack / heads
|
|
; head = LBA / sectorspertrack % heads
|
|
; sector = LBA % sectorspertrack + 1
|
|
div word [sectorspertrack]
|
|
; ax = LBA / sectorspertrack
|
|
; dx = LBA % sectorspertrack
|
|
|
|
; sector
|
|
mov cl, dl
|
|
inc cl
|
|
|
|
xor dx, dx
|
|
div word [heads]
|
|
; ax = LBA / sectorspertrack / heads
|
|
; dx = LBA / sectorspertrack % heads
|
|
|
|
; head
|
|
mov dh, dl
|
|
|
|
; cylinder (track)
|
|
mov ch, al
|
|
;shr ax, 1
|
|
;shr ax, 1
|
|
;and al, 0xC0
|
|
;or cl, al
|
|
|
|
; Restore drive number
|
|
mov dl, bl
|
|
|
|
pop bx
|
|
pop ax
|
|
ret
|
|
|
|
%include "hexprint.inc"
|
|
|
|
times 510-($-$$) db 0
|
|
db 0x55, 0xaa
|
|
_end:
|
|
rootdir equ _end
|