Remove stack switching, implement some syscalls

This commit is contained in:
Nero 2020-04-19 00:35:31 +02:00
parent c1c012c5fc
commit 97f26c1f89

View File

@ -4,79 +4,42 @@
%include "inc/bpb.asm"
banner: db "rdos", 0xA, 0xD, 0
banner: db "rdos", 0xA, 0xD, '$'
; syscalls push a register set to stack
; this is for accessing it
rsdssi: equ 0x08
rsesdi: equ 0x0C
rsbp: equ 0x10
rslpad: equ 0x12
rscsip: equ 0x14
rsflag: equ 0x18
lpads: times 0x30 call entry
entry: push bp
; BX+0C: ES:DI
push es
push di
; BX+08: DS:SI
push ds
push si
; BX+00: AX,CX,DX,BX
int20h: xor ah, ah
int21h: ; inside of kernel, direction always goes up
; the iret will restore it to the user value later
cld
; set sfptr from ah
push bx
push dx
push cx
push ax
mov ax, ss
mov es, ax
mov bx, sp
; This needs to be done when coming from userspace
mov ax, cs
mov ss, ax
xor sp, sp
; Jump back to userspace
ujump: cli
mov ax, es
mov ss, ax
mov sp, bx
; Pop whole registerset
; base registers
pop ax
pop cx
pop dx
xor bx, bx
mov bl, ah
add bl, bl
add bx, sftab
mov bx, [cs:bx]
mov [cs:sfptr], bx
pop bx
; string ptrs
pop si
pop ds
pop di
pop es
; BP is special
; do the actual subfunction call
call [cs:sfptr]
; inherit the lower 8 flag bits to userspace
push ax
push bp
mov bp, sp
lahf
mov [bp+8], ah
pop bp
; skip landing pad number
add sp, 2
; pop IP, CS and flags
pop ax
; iret frame: IP CS FLAGS
iret
; Processes register set DS:BX as syscall
scall: ; Clear status flags
and byte [bx+rsflag], 0
ret
; No such subfunction
sferr: ; set carry
or byte [bx+rsflag], 1
ret
; Subfunction ptr
; this is used as extra register in int21h
sfptr: dw 0
; Subfunction table
sftab: dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
sftab: dw sferr, sferr, putc, sferr
dw sferr, sferr, sferr, sferr
dw sferr, puts, sferr, sferr
dw sferr, sferr, sferr, sferr
; 10
dw sferr, sferr, sferr, sferr
@ -94,19 +57,32 @@ sftab: dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
; DOS 2+ - GET INTERRUPT VECTOR
; IN al interrupt number
; OUT es:bx current interrupt handler
getint: xor bx, bx
; BX=AL*4
mov bl, al
add bl, bl
add bl, bl
; load vector into ES:BX
les bx, [cs:bx]
; DOS 1+ 2h - WRITE CHARACTER TO STANDARD OUTPUT
; IN dl character to write
putc: push ax
push bx
mov ah, 0x0E
mov al, dl
xor bx, bx
int 0x10
pop bx
pop ax
ret
; DOS 25h: Set interrupt vector
; DOS 1+ 9h - WRITE STRING TO STANDARD OUTPUT
; IN ds:dx '$'-terminated string
puts: push si
mov ah, 0x0E
xor bx, bx
.loop: lodsb
cmp al, '$'
je .end
int 0x10
jmp .loop
.end: pop si
ret
; DOS 1+ 25h - SET INTERRUPT VECTOR
; IN al interrupt number
; ds:dx entry point
setint: push bx
@ -121,6 +97,23 @@ setint: push bx
pop bx
ret
; DOS 2+ 35h - GET INTERRUPT VECTOR
; IN al interrupt number
; OUT es:bx current interrupt handler
getint: xor bx, bx
; BX=AL*4
mov bl, al
add bl, bl
add bl, bl
; load vector into ES:BX
les bx, [cs:bx]
ret
; Fallback for non-existant subfunctions
; The carry flag is inherited to user
sferr: stc
ret
bpb: times bpb_len db 0
drvnum: db 0
align 4
@ -210,13 +203,8 @@ ldbpb: push ds
ret
main: mov si, banner
mov ah, 0x0e
xor bx, bx
loop: lodsb
test al, al
jz end
int 0x10
jmp loop
mov ah, 0x09
int 0x21
end: hlt
jmp end
@ -235,4 +223,11 @@ init: cli
call dnconv
call select
mov al, 0x20
mov dx, int20h
call setint
mov al, 0x21
mov dx, int21h
call setint
jmp 0:main