; 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 db 2 ; FATs dw 112 ; Root directory entries dw 2*320 ; Total sectors db 0ffh ; Media descriptor dw 1 ; Sectors per fat sectorspertrack dw 8 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, 10 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