2019-03-28 00:05:46 +01:00
|
|
|
org 0
|
2019-03-25 09:51:37 +01:00
|
|
|
|
2019-03-27 23:05:00 +01:00
|
|
|
fdc: ; FDC Descriptor as per ECMA-107
|
|
|
|
jmp _startup
|
|
|
|
times (0x03 - ($-$$)) nop
|
2019-03-25 09:51:37 +01:00
|
|
|
.oem:
|
2019-03-27 23:05:00 +01:00
|
|
|
db "2B" ; creating system identifier
|
|
|
|
times (0x0B - ($-$$)) db " " ; space-padded
|
|
|
|
.ss:
|
|
|
|
dw 0x200 ; sector size
|
|
|
|
.sc:
|
|
|
|
db 0 ; sectors per cluster
|
|
|
|
.rsc:
|
|
|
|
dw 2 ; reserved sector count
|
|
|
|
.fn:
|
|
|
|
db 0 ; number of file allocation tables
|
|
|
|
.rde:
|
|
|
|
dw 0 ; number of root directory entries
|
2019-03-28 00:06:13 +01:00
|
|
|
.ts:
|
|
|
|
dw 720 ; total number of sectors
|
2019-03-27 23:05:00 +01:00
|
|
|
.mi: ; medium identifier
|
2019-03-25 09:51:37 +01:00
|
|
|
db 0xFD ; 5.25-inch Double sided, 40 tracks per side, 9 sectors per track (360 KB)
|
2019-03-27 23:05:00 +01:00
|
|
|
.sf: ; sectors per fat
|
2019-03-25 09:51:37 +01:00
|
|
|
dw 0
|
|
|
|
.spt:
|
|
|
|
dw 9 ; sectors per track
|
2019-03-27 23:05:00 +01:00
|
|
|
.nos:
|
|
|
|
dw 2 ; number of sides (heads)
|
|
|
|
.po:
|
|
|
|
dd 0 ; partition offset (in LBA blocks)
|
2019-03-28 00:06:13 +01:00
|
|
|
.lrgts:
|
|
|
|
dw 0
|
2019-03-27 23:05:00 +01:00
|
|
|
.drv:
|
2019-03-26 21:46:40 +01:00
|
|
|
db 0 ; drive number
|
|
|
|
db 0
|
2019-03-27 23:05:00 +01:00
|
|
|
db 0x29 ; efdc signature
|
|
|
|
.vid:
|
|
|
|
dd 0 ; volume id
|
|
|
|
.vlabel:
|
|
|
|
db "2B"
|
|
|
|
times (54 - ($-$$)) db " "
|
|
|
|
.fstype:
|
|
|
|
db "FAT12"
|
|
|
|
times (62 - ($-$$)) db " "
|
2019-03-25 09:51:37 +01:00
|
|
|
|
|
|
|
_startup:
|
2019-03-28 00:05:46 +01:00
|
|
|
xor ax, ax
|
|
|
|
mov ds, ax
|
|
|
|
mov es, ax
|
|
|
|
mov cx, 0x0100
|
|
|
|
mov si, 0x7C00
|
|
|
|
mov di, 0x0500
|
|
|
|
rep movsw
|
|
|
|
jmp 0x0050:.lowstart
|
|
|
|
.lowstart:
|
|
|
|
mov ax, cs
|
|
|
|
mov ds, ax
|
|
|
|
mov ss, ax
|
|
|
|
xor sp, sp
|
|
|
|
|
2019-03-29 22:40:44 +01:00
|
|
|
mov [fdc.drv], dl ; backup drive number
|
2019-03-29 23:32:50 +01:00
|
|
|
|
|
|
|
chs_bios:
|
2019-03-27 23:05:00 +01:00
|
|
|
mov ah, 0x08
|
|
|
|
int 0x13 ; required, QEMU detects 360kB as 1200kB with CHS 80 2 15
|
2019-03-29 23:32:50 +01:00
|
|
|
jc chs_print ; skip if function does not exist
|
2019-03-27 23:05:00 +01:00
|
|
|
inc dh
|
|
|
|
mov [fdc.nos], dh
|
|
|
|
mov ax, cx
|
|
|
|
and ax, 0x003F
|
|
|
|
mov [fdc.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 [fdc.nos] ; number of tracks = number of cylinders * heads
|
|
|
|
mul word [fdc.spt] ; number of sectors = number of tracks * sectors per track
|
|
|
|
mov [fdc.ts], ax
|
2019-03-29 23:32:50 +01:00
|
|
|
jmp chs_print
|
2019-03-29 22:40:44 +01:00
|
|
|
|
2019-03-29 23:32:50 +01:00
|
|
|
chs_print:
|
2019-03-29 22:40:44 +01:00
|
|
|
call print_inline
|
2019-03-29 23:32:50 +01:00
|
|
|
db "CHS ", 0
|
2019-03-29 22:40:44 +01:00
|
|
|
|
|
|
|
mov ax, [fdc.ts]
|
|
|
|
div word [fdc.nos]
|
|
|
|
div word [fdc.spt]
|
|
|
|
call print_number
|
|
|
|
|
|
|
|
call print_inline
|
|
|
|
db ",", 0
|
|
|
|
|
|
|
|
mov ax, [fdc.nos]
|
|
|
|
call print_number
|
|
|
|
|
|
|
|
call print_inline
|
|
|
|
db ",", 0
|
|
|
|
|
|
|
|
mov ax, [fdc.spt]
|
|
|
|
call print_number
|
|
|
|
|
|
|
|
call print_inline
|
|
|
|
db 0x0A, 0x0D, 0
|
|
|
|
|
2019-03-28 00:06:13 +01:00
|
|
|
mov ax, 0x0070
|
2019-03-26 21:46:40 +01:00
|
|
|
mov es, ax
|
2019-03-28 00:06:13 +01:00
|
|
|
xor bx, bx
|
|
|
|
call loadrootdir
|
2019-03-29 22:40:44 +01:00
|
|
|
|
2019-03-26 21:46:40 +01:00
|
|
|
call dump
|
2019-03-29 23:32:50 +01:00
|
|
|
|
2019-03-26 21:46:40 +01:00
|
|
|
.end:
|
|
|
|
hlt
|
|
|
|
jmp .end
|
|
|
|
|
2019-03-28 00:06:13 +01:00
|
|
|
; Load root directory into memory
|
2019-03-29 23:32:50 +01:00
|
|
|
; in es data segment
|
2019-03-28 00:06:13 +01:00
|
|
|
loadrootdir:
|
|
|
|
push bx
|
|
|
|
push cx
|
|
|
|
mov bx, [fdc.ss] ; bytes per sector
|
|
|
|
mov cl, 5
|
|
|
|
shr bx, cl ; div by 2^5, 32 bytes per directory entity
|
|
|
|
mov ax, [fdc.rde] ; number of root directory entities
|
|
|
|
xor dx, dx
|
|
|
|
div bx
|
|
|
|
mov cx, ax
|
|
|
|
|
|
|
|
mov ax, [fdc.sf]
|
|
|
|
mul byte [fdc.fn]
|
|
|
|
add ax, [fdc.rsc]
|
|
|
|
|
|
|
|
xor bx, bx ; load at beginning of es
|
|
|
|
.loop:
|
|
|
|
call loadblk
|
|
|
|
loop .loop
|
|
|
|
|
|
|
|
pop cx
|
|
|
|
pop bx
|
|
|
|
ret
|
|
|
|
|
|
|
|
; Load a single block into memory
|
2019-03-27 23:05:00 +01:00
|
|
|
; in ax sector number
|
|
|
|
; es:bx buffer
|
|
|
|
; out al error code,
|
|
|
|
; carry set if error
|
|
|
|
loadblk:
|
2019-03-28 00:06:13 +01:00
|
|
|
push ax
|
|
|
|
push cx
|
|
|
|
push dx
|
2019-03-27 23:05:00 +01:00
|
|
|
xor dx, dx
|
|
|
|
div word [fdc.spt] ; ax:temp = (lba / spt)
|
|
|
|
inc dx ; dx:sector = (lba % spt) + 1
|
|
|
|
mov cl, dl ; sector number
|
|
|
|
xor dx, dx
|
|
|
|
div word [fdc.nos] ; ax:cylinder = (tmp / heads)
|
|
|
|
; dx:head = (tmp % heads)
|
|
|
|
mov ch, al ; cylinder number
|
|
|
|
mov dh, dl ; head number
|
|
|
|
mov dl, [fdc.drv] ; driver number
|
|
|
|
mov ax, 0x0201 ; ah=0x02 al=0x01
|
|
|
|
int 0x13
|
2019-03-29 23:32:50 +01:00
|
|
|
jc .error
|
2019-03-28 00:06:13 +01:00
|
|
|
pop dx
|
|
|
|
pop cx
|
|
|
|
pop ax
|
|
|
|
inc ax
|
|
|
|
add bx, 0x0200
|
2019-03-27 23:05:00 +01:00
|
|
|
ret
|
2019-03-29 23:32:50 +01:00
|
|
|
.error:
|
|
|
|
xor al, al
|
|
|
|
xchg al, ah
|
|
|
|
call print_inline
|
|
|
|
db "disk error ", 0
|
|
|
|
call print_number
|
|
|
|
call print_inline
|
|
|
|
db 0x0A, 0x0D, 0
|
|
|
|
.hlt:
|
|
|
|
hlt
|
|
|
|
jmp .hlt
|
2019-03-27 23:05:00 +01:00
|
|
|
|
2019-03-29 22:40:44 +01:00
|
|
|
print_number:
|
|
|
|
mov cx, 0x000A
|
|
|
|
xor dx, dx
|
|
|
|
div cx ; ax = dx:ax / 10, dx = dx:ax % 10
|
|
|
|
and ax, ax
|
|
|
|
jz .print
|
|
|
|
push dx
|
|
|
|
call print_number
|
|
|
|
pop dx
|
|
|
|
.print:
|
|
|
|
mov al, dl
|
|
|
|
add al, 0x30
|
|
|
|
mov ah, 0x0e
|
|
|
|
int 0x10
|
|
|
|
ret
|
|
|
|
|
|
|
|
print_inline:
|
|
|
|
pop si
|
2019-03-29 23:32:50 +01:00
|
|
|
push ax
|
2019-03-29 22:40:44 +01:00
|
|
|
push bx
|
|
|
|
.loop:
|
|
|
|
lodsb
|
|
|
|
cmp al, 0x00
|
|
|
|
je .end
|
|
|
|
mov bx, 0x0000
|
|
|
|
mov ah, 0x0e
|
|
|
|
int 0x10
|
|
|
|
cmp al, 0x0D
|
|
|
|
jmp .loop
|
|
|
|
.end:
|
|
|
|
pop bx
|
2019-03-29 23:32:50 +01:00
|
|
|
pop ax
|
2019-03-29 22:40:44 +01:00
|
|
|
push si
|
|
|
|
ret
|
|
|
|
|
2019-03-26 21:46:40 +01:00
|
|
|
dump:
|
2019-03-28 00:06:13 +01:00
|
|
|
mov si, bx
|
2019-03-26 21:46:40 +01:00
|
|
|
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
|
|
|
|
|
2019-03-25 09:51:37 +01:00
|
|
|
%include "print.asm"
|
|
|
|
|
2019-03-29 22:40:44 +01:00
|
|
|
times (0x1F0 - ($-$$)) db 0
|
|
|
|
|
|
|
|
str_bootfile:
|
|
|
|
db "BOOT"
|
|
|
|
times (0x1F8 - ($-$$)) db " "
|
|
|
|
db "BIN"
|
|
|
|
|
|
|
|
times (0x1FE - ($-$$)) db 0
|
|
|
|
|
2019-03-25 09:51:37 +01:00
|
|
|
dw 0xAA55
|