From 2d949a01f8fbe0376a87f0255434516d24e85344 Mon Sep 17 00:00:00 2001 From: Ain <41307858+nero@users.noreply.github.com> Date: Sun, 26 Apr 2020 23:14:34 +0200 Subject: [PATCH] Implement whacky first version for 25h disk read --- boot/kernel.asm | 177 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 149 insertions(+), 28 deletions(-) diff --git a/boot/kernel.asm b/boot/kernel.asm index fd056b3..954aa03 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -4,6 +4,19 @@ %include "inc/bpb.asm" + ; Far call via interrupt vector + %macro intcall 1 + call far [cs:%1*4] + %endmacro + + ; Far jump via interrupt vector + %macro intjump 1 + jump far [cs:%1*4] + %endmacro + + ; stack size + %define stacks 512 + banner: db "rdos", 0xA, 0xD, '$' ; Alias for Int 21h,AH=0h @@ -26,7 +39,7 @@ int21h: ; inside of kernel, direction always goes up ; do the actual subfunction call call [cs:sfptr] ; inherit the lower 8 flag bits to userspace - push ax +iretfl: push ax push bp mov bp, sp lahf @@ -239,7 +252,105 @@ ldbpb: push ds pop ds ret - ; DOS 2+ - DOS IDLE INTERRUPT + + ; defines for CHS table +chs_spt: equ 0 ; word sectors per track +chs_nos: equ 2 ; word number of sides +chs_po: equ 4 ; dword partition offset +chs_siz: equ 8 + + +fndchs: ; find CHS table entry + ; IN dl DOS drive number (A=0, B=1, ...) + ; OUT cs:si ptr to chs table entry + push ax + mov ax, chs_siz + mul dl + add ax, chstab + mov si, ax + pop ax + ret + + ; compare sector number in disk access packet with zero + ; sets zero flag accordingly +iszero: push ax + mov ax, [bx] + or ax, [bx+2] + pop ax + ret + + ; calculate CHS from dap and CHS table entry + ; IN ds:bx disk access packet + ; cs:si chstab table entry + ; OUT cx,dh chs data for int 13h +calchs: push ax + ; load linear sector number + mov dx, [bx+2] + mov ax, [bx] + ; if any word of it is non-zero, we need to do calculation + call iszero + jz .zero + ; ax is track number (lba / spt) + ; dx is sector (lba % spt) + 1 + div word [cs:si+chs_spt] + inc dx + ; sector number + mov cl, dl + ; ax is cylinder (track / heads) + ; dx is head (track % heads) + xor dx, dx + div word [cs:si+chs_nos] + ; set up cylinder and head number + mov ch, al + mov dh, dl + pop ax + ret + ; set up CHS data for int 13h for reading sector zero +.zero: mov cx, 1 ; C=0, S=1 + mov dh, 0 ; H=0 + pop ax + ret + + ; ABSOLUTE DISK READ / DISK WRITE +int25h: mov ah, 2 + jmp adisk +int26h: mov ah, 3 +adisk: push bp + push ds + push es + mov bp, sp + cmp cx, 0xFFFF + je .islrg + + ; build a disk access packet on the stack + push ds ; dword transfer buffer + push bx + push cx ; word number of sectors + push cs ; dword starting sector number (CS always 0) + push dx + + ; set our freshly created dap as DS:BX + mov bx, sp + push ss + pop ds + +.islrg: mov dl, al + call fndchs + call calchs + mov dl, al + mov al, [bx+4] + mov es, [bx+8] + mov bx, [bx+6] + int 0x13 + jc .ret + +.ret: mov sp, bp + pop es + pop ds + pop bp +retf: retf + + ; DOS IDLE INTERRUPT ; Usually hooked by TSRs idle: sti ; sti takes one instruction to take effect @@ -248,7 +359,7 @@ idle: sti hlt iret - ; DOS 2+ - FAST CONSOLE OUTPUT + ; FAST CONSOLE OUTPUT ; IN al character to print fputc: push ax push bx @@ -259,36 +370,42 @@ fputc: push ax pop ax iret - ; write CS:AX to ES:DI and advance DI - ; used for setting interrupts -stovec: stosw +vects: dw int20h, int21h, retf, retf + dw retf, int25h, int26h, int20h + dw idle, fputc + +main: ; zero out first 64kb except our code + ; bss and boot sector area gets cleared by this + mov di, init + mov cx, di + neg cx + xor ax, ax + rep movsb + + ; install interrupt vectors + mov si, vects + mov di, (0x20*4) + mov cx, 0x0A +intlp: movsw mov ax, cs stosw - ret - -vects: dw int20h, int21h, idle, fputc - -main: mov si, vects - mov di, (0x20*4) - lodsw - call stovec - lodsw - call stovec - mov di, (0x28*4) - lodsw - call stovec - lodsw - call stovec + loop intlp + ; print banner to indicate we are booted mov si, banner mov ah, 9 int 0x21 + call dnconv + mov al, dl + mov cx, 1 + mov dx, 0 + mov bx, buffer + int 3 + intcall 0x25 + int 3 + loop: int 0x28 - mov ah, 7 - int 0x21 - jz loop - int 0x29 jmp loop init: cli @@ -296,7 +413,7 @@ init: cli mov ds, ax mov es, ax mov ss, ax - mov sp, stacke + mov sp, ( stack+stacks ) ; relocate mov si, 0x7C00 @@ -307,11 +424,15 @@ init: cli jmp 0:main section .bss + ; stack to be used during init and disk i/o +stack: resw stacks + ; default int 25h/26h handler use a cache to keep geometry for + ; the first 4 drives +chstab: resw (4*chs_siz) + bpb: resb bpb_len drvnum: resb 1 align 4 drvoff: resd 1; partition offset drvpos: resd 1; absolute physical sector number buffer: resb 512 -stack: resw 512 -stacke: