90 lines
1.3 KiB
NASM
90 lines
1.3 KiB
NASM
|
section .bss
|
||
|
|
||
|
curpsp: resw 1
|
||
|
|
||
|
|
||
|
absolute 0
|
||
|
|
||
|
resb 2 ; ret 0 exit
|
||
|
resb 2 ; allocation length
|
||
|
resb 1
|
||
|
resb 5 ; CP/M entry point
|
||
|
|
||
|
; SS:SP, DS:DX, ES:BX and AX from the program
|
||
|
PSPAX: resw 1
|
||
|
PSPSS: resw 1
|
||
|
PSPSP: resw 1
|
||
|
PSPDS: resw 1
|
||
|
PSPDX: resw 1
|
||
|
PSPES: resw 1
|
||
|
PSPBX: resd 1
|
||
|
|
||
|
|
||
|
section .text
|
||
|
|
||
|
; OUT ds PSP segment
|
||
|
pspds: xor ax, ax
|
||
|
mov ds, ax
|
||
|
mov ds, [curpsp]
|
||
|
ret
|
||
|
|
||
|
int21: push ds
|
||
|
; load program PSP and save userdata
|
||
|
push ax
|
||
|
call pspds
|
||
|
pop word [PSPAX]
|
||
|
pop word [PSPDS]
|
||
|
mov [PSPSS], ss
|
||
|
mov [PSPSP], sp
|
||
|
mov [PSPDX], dx
|
||
|
mov [PSPES], es
|
||
|
mov [PSPBX], bx
|
||
|
|
||
|
mov ss, ax
|
||
|
mov sp, ( stack+stacksize )
|
||
|
|
||
|
mov al, [PSPAX+1]
|
||
|
shl ax, 1
|
||
|
shl ax, 1
|
||
|
call .etbl
|
||
|
; syscall table
|
||
|
; cells: ptr to handler, ptr to sysret
|
||
|
dw restart, sret
|
||
|
dw getc, sretb
|
||
|
dw putc, sret
|
||
|
; set up a return chain and execute it
|
||
|
; first return into handler function
|
||
|
; second return into appropiate sysret
|
||
|
.etbl: pop bx
|
||
|
add bx, ax
|
||
|
push word [cs:bx+2]
|
||
|
push word [cs:bx]
|
||
|
ret
|
||
|
|
||
|
; sysret handlers
|
||
|
; return ES:BX to user
|
||
|
sretd: call pspds
|
||
|
jmp sret.l02
|
||
|
|
||
|
; return BX to user
|
||
|
sretw: call pspds
|
||
|
mov es, [PSPES]
|
||
|
jmp sret.l02
|
||
|
|
||
|
; return AL to user
|
||
|
sretb: push ax
|
||
|
call pspds
|
||
|
pop ax
|
||
|
mov ah, [PSPAX+1]
|
||
|
les bx, [PSPBX]
|
||
|
jmp sret.l03
|
||
|
|
||
|
; return without result
|
||
|
sret: call pspds
|
||
|
.l01: les bx, [PSPBX]
|
||
|
.l02: mov ax, [PSPAX]
|
||
|
.l03: mov ss, [PSPSS]
|
||
|
mov sp, [PSPSP]
|
||
|
lds dx, [PSPDX]
|
||
|
iret
|