Split out kernel components in kernel/

This commit is contained in:
Nero 2020-04-27 15:56:41 +02:00
parent 2d949a01f8
commit b73bfbe043
3 changed files with 120 additions and 189 deletions

View File

@ -48,6 +48,8 @@ vga11.com: cp437.bin
%.bs: boot/%.asm
$(NASM) $(NASM_ARGS) -o $@ $<
kernel.bs: kernel/*.asm
# Special case: variations of FAT vbr
fat1.bs: boot/fat.asm
$(NASM) $(NASM_ARGS) -DFAT12 -DCHS -o $@ $<

View File

@ -10,8 +10,8 @@
%endmacro
; Far jump via interrupt vector
%macro intjump 1
jump far [cs:%1*4]
%macro intjmp 1
jmp far [cs:%1*4]
%endmacro
; stack size
@ -22,7 +22,7 @@ banner: db "rdos", 0xA, 0xD, '$'
; Alias for Int 21h,AH=0h
int20h: xor ah, ah
; allow extenders to get away with only hooking 21h
jmp [cs:(0x21 * 4)]
intjmp 0x21
int21h: ; inside of kernel, direction always goes up
; the iret will restore it to the user value later
@ -48,6 +48,7 @@ iretfl: push ax
pop ax
; iret frame: IP CS FLAGS
iret: iret
retf: retf
; Subfunction ptr
; this is used as extra register in int21h
@ -171,185 +172,6 @@ getint: xor bx, bx
sferr: stc
ret
; Convert between drive number and BIOS dl
; Bidirectional mapping
; 0 <-> 0, 1 <-> 1, 2 <-> 0x80, 3 <-> 0x81
dnconv: mov cx, 7
ror dx, 1
rol dl, 1
dncl: rcl dl, 1
rcr dh, 1
loop dncl
xchg dh, dl
ret
; Set sector number
seek: mov [drvpos], ax
mov [drvpos+2], dx
ret
; Read sector from disk
read: ; this uses the EBIOS extensions
; qword sector number
xor ax, ax
push ax
push ax
mov ax, [cs:drvpos+2]
push ax
mov ax, [cs:drvpos]
push ax
; dword target buffer
mov ax, buffer
push cs
push ax
; word number of sectors
mov ax, 1
push ax
; size & passing
mov di, 0x10
push di
mov si, sp
mov ah, 0x42
mov dl, [cs:drvnum]
call dnconv
stc
int 0x13
add sp, di
ret
; Select active drive
; IN dl drive number A=0, B=1, C=2, ...
select: mov [cs:drvnum], dl
ret
push es
xor ax, ax
push cs
pop es
mov si, drvoff
stosw
stosw
stosw
stosw
pop es
call read
; load bpb from buffer to bpb
ldbpb: push ds
push es
mov ax, cs
mov ds, ax
mov es, ax
mov si, buffer+0x0B
mov di, bpb
mov cx, bpb_len
rep movsb
pop es
pop ds
ret
; 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
@ -370,6 +192,8 @@ fputc: push ax
pop ax
iret
%include "kernel/diskio.asm"
vects: dw int20h, int21h, retf, retf
dw retf, int25h, int26h, int20h
dw idle, fputc
@ -428,11 +252,4 @@ section .bss
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

112
kernel/diskio.asm Normal file
View File

@ -0,0 +1,112 @@
section .bss
chsspt: equ 0 ; word sectors per track
chsnos: equ 2 ; word number of sides
chspo: equ 4 ; dword partition offset
chssiz: equ 8
chstab: resw (4*chssiz)
section .text
; Convert between drive number and BIOS dl
; Bidirectional mapping
; 0 <-> 0, 1 <-> 1, 2 <-> 0x80, 3 <-> 0x81
dnconv: mov cx, 7
ror dx, 1
rol dl, 1
dncl: rcl dl, 1
rcr dh, 1
loop dncl
xchg dh, dl
ret
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, chssiz
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+chsspt]
inc dx
; sector number
mov cl, dl
; ax is cylinder (track / heads)
; dx is head (track % heads)
xor dx, dx
div word [cs:si+chsnos]
; 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