Implement syscall interface and version data

This commit is contained in:
Nero 2022-01-01 21:22:37 +00:00
parent 576b2c6546
commit f7d7f48026
3 changed files with 79 additions and 114 deletions

View File

@ -1,6 +1,21 @@
org 0x700
cseg equ 0x0
jmp init
%include "version.inc"
jmp _entry
banner db "RDOS KERNEL 1.0", 0x0A, 0x0D, '$', 0x1A
_entry call .l01
.l01 pop ax
sub ax, .l01
mov cl, 4
shr ax, cl
mov cx, cs
add cx, ax
push cx
mov ax, start
push ax
retf
;;; Character I/O
@ -138,10 +153,15 @@ gets mov si, dx
call putc
ret
;;; System functions
; Return OS version from version.inc
ver mov bx, bdosver | 0x1000
ret
;;; Disk i/o
%include "bpb.inc"
%include "farptr.inc"
; dflags bitfields
DRVLOG equ 0x01 ; bit 0 - drive logged in (see drvnum)
@ -150,23 +170,8 @@ DRVEXT equ 0x04 ; bit 2 - EBIOS supported
DIRTY equ 0x08 ; bit 3 - dskbuf dirty
DRVCHS equ 0x10 ; bit 4 - CHS geometry known
align 16
; IBM Interrupt Sharing Protocol structure
i13isp jmp short int13i
dw 0,0xFFFF
dw 0x424B
db 0
iret
align 16
; Entry point when user program calls int13h
; TODO: flush buffer and log out drive
int13i call int13
iret
; Wrapper around int 13h
int13 pushf
call far [i13isp+2]
int13 int 0x13
; TODO: on error: reset & retry
; TODO: record errors
; TODO: multi-track reading
@ -209,10 +214,10 @@ getprm test byte [dflags], DRVEXT
test ax, ax
jz .ret
; copy BIOS dpt table over ours
mov dx, dpt
mov bx, di
mov cx, 11
call lodfar
;mov dx, dpt
;mov bx, di
;mov cx, 11
;call lodfar
.ret ret
; select a drive for io
@ -379,14 +384,13 @@ flush test word [cs:dflags], DIRTY
; Sector number is read from [drvseek]
diskio mov cl, 1 ; read len
; DS := ES := CS
call rstseg
mov ds, [cs:dseg]
; check if ebios supported
test word [dflags], DRVEXT
jz .noext
; set up regs for ebios call
mov ax, cx
xchg ax, cx
or ah, 0x40
mov si, dap
jmp .do
; check if we can skip controller reset
.noext test word [dflags], DRVCTL
@ -419,15 +423,19 @@ diskio mov cl, 1 ; read len
; shuffle values around for bios
xchg ax, cx
xchg dh, dl
mov bx, dskbuf
.do mov dl, [biosnum]
; ah: subfunction selected via cx previously
; al: 1 = reading 1 sector
; cx: sector and cylinder number
; dh: head number
; dl: drive number
; bx: offset to disk buffer
push es
push si
mov si, dap
les bx, [si+4]
call int13
pop si
pop es
jc .err
; clear dirty flag on success
and word [dflags], ~DIRTY
@ -439,39 +447,6 @@ diskio mov cl, 1 ; read len
stc
ret
init mov ax, cs
; boot failure if loaded wrong
cmp ax, cseg
je $+4
int 0x18
call rstseg
; fetch current DPT
les bx, [4*0x1E]
mov dx, dpt
mov cx, 11
call lodfar
; set interrupt vector
mov word [4*0x1E], dpt
mov word [4*0x1E+2], ds
; save int 13 handler
les bx, [4*0x13]
mov [i13isp+2], bx
mov [i13isp+4], es
; install ours
mov word [4*0x13], int13i
mov [4*0x13+2], cs
; install int21h handler
mov word [4*0x21], int21h
mov [4*0x21+2], cs
mov dl, 0x36
mov ah, 2
int 0x21
halt hlt
jmp halt
;;; Export functions as syscalls
; SP, BP, SI, DI and ES must be preserved by kernel code
; DL, DX or DS:DX is input argument from prog
@ -494,7 +469,9 @@ intE0h push bx
; bx = syscall number
; stack must be -> BX IP CS FL
; for return to prog
sysc add bx, bx
sysc sti
cld
add bx, bx
mov bx, [cs:bx+stab]
test bh, srw >> 8 ; fork off bx returns
jnz .l02
@ -537,6 +514,38 @@ sysc add bx, bx
pop dx
ret
start xor ax, ax
mov ds, ax
; install int20h handler
mov word [4*0x20], start
mov [4*0x20+2], cs
; install int21h handler
mov word [4*0x21], int21h
mov [4*0x21+2], cs
; install intE0h handler
mov word [4*0xE0], intE0h
mov [4*0xE0+2], cs
mov ax, cs
mov ds, ax
mov [dseg], ax
; print banner
mov dx, banner
call puts
; read cmdline
mov dl, '>'
call putc
mov dx, inbuf
mov byte [inbuf], 72
call gets
halt sti
hlt
jmp halt
section .rodata
; syscall table
@ -549,10 +558,10 @@ stab dw 0 ; 0 reboot
dw 0 ; 6 direct console i/o
dw 0 ; 7 read i/o byte
dw 0 ; 8 get i/o byte
dw 0 ; 9 string output
dw 0 ; 10 string input
dw puts ; 9 string output
dw gets ; 10 string input
dw 0 ; 11 console status
dw 0 ; 12 get version number
dw ver ; 12 get version number
dw 0 ; 13 reset disks
dw 0 ; 14 set drive
dw 0 ; 15 open file
@ -587,7 +596,8 @@ section .data
dap db 0x10, 0
dw 1
dw dskbuf, cseg
dw dskbuf
dseg dw 0
drvseek dw 0,0,0,0
; bit 0 (1) - drive logged in (see drvnum)
@ -603,9 +613,6 @@ drvnum resb 1
; number, just for bios
biosnum resb 1
; DPT tables for 4 floppy drives
dpt resb 4*14
; Information for logged in drive
drvss resb 1 ; sector size, 2^(7+n) bytes
drvcs resb 1 ; cluster size, 2^(7+n) bytes
@ -622,3 +629,5 @@ drvfn resb 2 ; sectors per fat table
; disk buffer for I/O operations
alignb 2
dskbuf resb 1024
inbuf resb 128

View File

@ -1,46 +0,0 @@
; reset segments
rstseg mov ax, cs
mov ds, ax
mov es, ax
ret
; copy to far memory
; IN es:bx far memory ptr (preserved)
; ds:dx local ptr (preserved)
; cx number of bytes to transfer
; OUT cx set to zero
; si & di trashed
stofar mov si, dx
mov di, bx
rep movsb
ret
; copy from far memory
; IN es:bx far memory ptr (preserved)
; ds:dx local ptr (preserved)
; cx number of bytes to copy
; OUT cx set to zero
; si & di trashed
lodfar call swpds
mov si, bx
mov di, dx
rep movsb
; exchange es and ds
swpds push ds
push es
pop ds
pop es
ret
; normalize ptr in ds:dx
norm mov ax, ds
mov cl, 4
push dx
ror dx, cl
and dh, 0xF
add ax, dx
mov ds, ax
pop dx
and dx, 0xF
ret

2
src/version.inc Normal file
View File

@ -0,0 +1,2 @@
bdosver equ 0x10 ; CP/M 1.0
bdosrev equ 0