ordos/boot.asm
2022-03-28 16:53:55 +03:00

170 lines
2.6 KiB
NASM

; SPDX-License-Identifier: MIT
; Copyright (c) 2021 Juhani 'nortti' Krekelä.
iosegment segment at 60h
ioinit proc far
ioinit endp
iosegment ends
bootloader segment
assume cs:bootloader, ds:bootloader, es:bootloader, ss:bootloader
org 7c00h
jmp code
; BPB
db "Ordos " ; OEM Identifier
dw 512 ; Bytes per sector
db 2 ; Sectors per cluster
dw 1 ; Reserved sectors
fats db 2 ; FATs
dw 112 ; Root directory entries
dw 2*720 ; Total sectors
db 0f9h ; Media descriptor
sectorsperfat dw 3 ; Sectors per fat
sectorspertrack dw 9
heads dw 2
dd 0 ; Hidden sectors
dd 0 ; Total sectors (large)
code:
cld
mov ax, cs
mov ds, ax
mov es, ax
cli
mov ss, ax
mov sp, 7c00h
sti
mov drivenumber, dl
; TODO: Check we actually have the OS
mov ax, 14
mov bx, 600h
mov cx, 17 ; This is what PC-DOS 1.10's full size ends up at
call loadsectors
mov si, offset success_msg
call printstr
jmp ioinit
; IN:
; ax = LBA of first sector
; es:bx = destination buffer
; cx = number of sectors to load
loadsectors proc
push ax
push cx
push dx
push di
loading_loop:
mov di, 3 + 1 ; Retry thrice, + 1 is since we dec first
retry:
push ax
push cx
chs:
xor dx, dx
; cylinder (track) - head - sector
; cylinder = LBA / sectorspertrack / heads
; head = LBA / sectorspertrack % heads
; sector = LBA % sectorspertrack + 1
div sectorspertrack
; ax = LBA / sectorspertrack
; dx = LBA % sectorspertrack
; sector
mov cl, dl
inc cl
xor dx, dx
div 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, 0c0h
or cl, al
mov ax, 0201h
mov dl, drivenumber
int 13h
jc disk_error
mov ax, 0e00h + '.'
int 10h
pop cx
pop ax
inc ax
add bx, 512
loop loading_loop
pop di
pop dx
pop cx
pop ax
ret
disk_error:
; Do we still have retries remaining?
dec di
jnz reset_disk
; No, die
mov si, offset error_msg
call printstr
hang:
hlt
jmp hang
reset_disk:
; Yes, reset disk and retry
xor ah, ah
int 13h
pop cx
pop ax
jmp retry
loadsectors endp
; IN:
; si = null-terminated string
printstr proc
lodsb
test al, al
jz ret_printstr
mov ah, 0eh
int 10h
jmp printstr
ret_printstr:
ret
printstr endp
drivenumber db (?)
success_msg db 13, 10, "DOS Loaded", 13, 10, 0
error_msg db 13, 10, "Disk error", 0
org 7c00h + 510
dw 0aa55h
bootloader ends
end