rdos/boot/kernel.asm

188 lines
2.9 KiB
NASM
Raw Normal View History

cpu 8086
org 0x7C00
2020-04-13 15:53:21 +02:00
stack: equ 0x7C00
framsz: equ 0x300
jmp init
; Data on user stack while in kernel (5 words):
; AX BP IP CS flags
; Kernel stack:
; [frame] SP SS
; BP-^
; The start of the frame is available via BP.
; The frame is followed by a long ptr to the user stack.
; Main entry point
int20h: xor ah, ah
int21h: push bp
push ax
; Test if SS=0, if it is, we assume we are already on kernel stack
mov ax, ss
test ax, ax
jz rentry
; Save user stack
mov ax, ss
mov [cs:stack-2], ax
mov [cs:stack-4], sp
; Set up kernel stack
xor ax, ax
mov ss, ax
mov sp, (stack-4)
jmp scall
; This is like the above, except that it doesnt switch stacks.
; The 'user' stack data is after (below on stack) the kernel frame.
; [frame] SP SS AX BP IP CS flags
; \-\--^
rentry: mov ax, sp
push ss
push ax
scall: sub sp, framsz
mov bp, sp
call getax
call jmptab
; Restore user stack
mov sp, [bp+framsz]
mov ax, [bp+framsz+2]
mov ss, ax
pop ax
pop bp
iret
; Lookup address of subfunction
; Mesh up the stack so we return to subfunction
; and subfunction later returns to scall
jmptab: push ax
push bx
xor bx, bx
add bl, ah
add bl, ah
mov bx, [cs:bx+sftab]
mov [bp-4], bx
pop bx
ret
; Get AX from the user stack
getax: push ds
push si
lds si, [bp+framsz]
lodsw
pop ds
pop si
ret
2020-04-13 15:53:21 +02:00
; No such subfunction - set carry and exit
sferr: stc
ret
; Subfunction table
sftab: dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
; 10
2020-04-13 15:53:21 +02:00
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
; 20
2020-04-13 15:53:21 +02:00
dw sferr, sferr, sferr, sferr
dw sferr, setint, sferr, sferr
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
; 30
2020-04-13 15:53:21 +02:00
dw sferr, sferr, sferr, sferr
dw sferr, getint, sferr, sferr
2020-04-13 15:53:21 +02:00
dw sferr, sferr, sferr, sferr
dw sferr, sferr, sferr, sferr
; IN al number
; OUT bx al * 4
times4: push ax
2020-04-13 15:53:21 +02:00
xor ah, ah
add al, al
add al, al
mov bx, ax
pop ax
ret
; DOS 2+ - GET INTERRUPT VECTOR
; IN al interrupt number
; OUT es:bx current interrupt handler
getint: push ds
; DS=0
xor bx, bx
mov ds, bx
; BX=AL*4
call times4
les bx, [bx]
pop ds
ret
; DOS 25h: Set interrupt vector
; IN al interrupt number
; ds:dx entry point
setint: push es
push bx
; ES=0
xor bx, bx
mov es, bx
; BX=AL*4
call times4
mov [es:bx], dx
2020-04-13 15:53:21 +02:00
mov ax, ds
mov [es:bx+2], ds
2020-04-13 15:53:21 +02:00
pop bx
pop es
ret
; ===== end of resident, begin of transient startup code
init: xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0x1000
mov ss, ax
xor sp, sp
2020-04-13 15:53:21 +02:00
mov al, 0x21
mov dx, int21h
2020-04-13 15:53:21 +02:00
call setint
mov ax, 0x2520
mov dx, int20h
int 0x21
mov ax, 0x3520
int 0x21
mov ah, 0x3f
int 3
int 0x21
int 3
main: push cs
pop ds
mov si, msg
mov ah, 0x0e
xor bx, bx
loop: lodsb
test al, al
jz end
int 0x10
jmp loop
end: hlt
jmp end
msg: db "rdos kernel stub", 0x0A, 0x0D, 0