2020-04-10 17:00:26 +02:00
|
|
|
cpu 8086
|
|
|
|
org 0x7C00
|
|
|
|
|
2020-04-13 15:53:21 +02:00
|
|
|
stack: equ 0x7C00
|
2020-04-10 17:00:26 +02:00
|
|
|
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 [stack-2], ax
|
|
|
|
mov [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
|
|
|
|
int 3
|
|
|
|
|
|
|
|
; Restore user stack
|
|
|
|
mov sp, [bp+framsz]
|
|
|
|
mov ax, [bp+framsz+2]
|
|
|
|
mov ss, ax
|
|
|
|
|
|
|
|
pop ax
|
|
|
|
pop bp
|
|
|
|
iret
|
|
|
|
|
|
|
|
; 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
|
|
|
|
align 2
|
|
|
|
sftab: dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, setint, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
dw sferr, sferr, sferr, sferr
|
|
|
|
|
|
|
|
; DOS 25h: Set interrupt vector
|
2020-04-10 17:00:26 +02:00
|
|
|
; IN al interrupt number
|
|
|
|
; ds:dx entry point
|
2020-04-13 15:53:21 +02:00
|
|
|
setint: push ax
|
|
|
|
push bx
|
|
|
|
xor ah, ah
|
|
|
|
add al, al
|
|
|
|
add al, al
|
|
|
|
mov bx, ax
|
|
|
|
mov [cs:bx], dx
|
|
|
|
mov ax, ds
|
|
|
|
mov [cs:bx+2], ds
|
|
|
|
pop bx
|
|
|
|
pop ax
|
2020-04-10 17:00:26 +02:00
|
|
|
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
|
2020-04-10 17:00:26 +02:00
|
|
|
mov dx, int21h
|
2020-04-13 15:53:21 +02:00
|
|
|
call setint
|
|
|
|
|
2020-04-10 17:00:26 +02:00
|
|
|
mov ax, 0x2520
|
|
|
|
mov dx, int20h
|
2020-04-13 15:53:21 +02:00
|
|
|
call setint
|
2020-03-25 21:56:00 +01:00
|
|
|
|
2020-04-01 15:09:01 +02:00
|
|
|
main: push cs
|
|
|
|
pop ds
|
|
|
|
mov si, msg
|
2020-03-25 21:56:00 +01:00
|
|
|
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
|