; ============================================================================
;
; Micro DOS - Program
;
; ============================================================================
PSPFILES EQU 20 ; maximum number of open files in PSP
DTASIZE EQU 128 ; DTA (Data Transfer Address) size
; ------------- Program Segment Prefix, PSP
struc PSP
PSP_Int20: resb 2 ; 0: Int 20h instruction for CALL 0
PSP_FreeMem: resw 1 ; 2: segment of first free memory
resb 1 ; 4: ...reserved (unused)
PSP_Call5: resb 5 ; 5: CP/M Call 5 service
; (far call 0000:00c0h instruction)
PSP_Int22: resd 1 ; 0Ah: Int 22h address (termination)
PSP_Int23: resd 1 ; 0Eh: Int 23h address (Ctrl+C)
PSP_Int24: resd 1 ; 12h: Int 24h address (error)
PSP_Parent: resw 1 ; 16h: segment of parent PSP
PSP_File: resb PSPFILES ; 18h: JFT (Job File Table),0ffh=closed
PSP_Env: resw 1 ; 2Ch: segment of environment
PSP_Stack: resd 1 ; 2Eh: last SS:SP on entry to Int 21h
PSP_Files: resw 1 ; 32h: number of entries in JFT (20)
PSP_FileTab: resd 1 ; 34h: pointer to JFT (PSP:0018h)
PSP_PrevPSP: resd 1 ; 38h: pointer to previous PSP (-1)
resb 20 ; 3Ch: ...reserved (unused)
PSP_Serv: resb 3 ; 50h: service request (Int 21h + retf)
resb 9 ; 53h: ...reserved (unused)
PSP_FCB1: resb UFCB_SIZE ; 5Ch: first default unopen FCB
; (filled from first argument)
PSP_FCB2: resb UFCB_SIZE ; 6Ch: second default unopen FCB
; (filled from second argument)
resb 4 ; 7Ch: ...reserved (unused)
PSP_DTA: resb DTASIZE ; 80h: commandline and default DTA
; contains byte with length of
; commandline and text of commandline
endstruc
PSP_SIZE EQU PSP_size ; 100h = 256 bytes
; ------------- Program environment
; - (x) first environment variable, ASCIIZ string in form "var=value"
; - (x) second environment variable, ASCIIZ string in form "var=value"
; ...
; - (x) last environment variable, ASCIIZ string in form "var=value"
; - (1) terminating byte 0
; - (2) number of strings following environment (normally 1)
; - (x) ASCIIZ full pathname of program owning this environment
; ... other strings
; ----------------------------------------------------------------------------
; Int 21h, function 00h - terminate program
; ----------------------------------------------------------------------------
; INT21 INPUT: AH = 00h (function code)
; CS = PSP segment
; ----------------------------------------------------------------------------
; ------------- Get program PSP segment
Int2100: call GetReg ; get register pointer
mov ds,[si+REG21CS] ; DS <- PSP segment
; ------------- Return Int 22h and Int 23h interrupt vectors
mov si,PSP_Int22 ; SI <- Int 22h in PSP
mov di,22h*4 ; DI <- address of Int 22h vector
xor ax,ax ; AX <- 0
mov es,ax ; ES <- 0
movsw
movsw ; return Int 22h
movsw
movsw ; return Int 23h
; ------------- Terminate program, prepare segments
Terminate: push cs ; push CS
pop ds ; DS <- CS
push cs ; push CS
pop es ; ES <- CS
; ------------- Disk reset
call DiskAllReset ; reset disk system
; ------------- Return old stack pointer
cli ; disable interrupts
mov sp,[cs:OldStack]; SP <- old SP
mov ss,[cs:OldStack+2]; SS <- old SS
; ------------- Load return address from program (Int 22h)
xor ax,ax ; AX <- 0
mov ds,ax ; DS <- 0
mov si,22h*4 ; SI <- address of Int 22h vector
mov di,ReturnInt22 ; buffer for return address
movsw ; load offset of address
movsw ; load segment of address
; ------------- Pop registers
call PopAll ; pop all registers
sti ; enable interupts
; ------------- Jump to parrent program
jmp far [cs:ReturnInt22]
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
; ------------- Current process
CurrentPSP: dw 0 ; segment of PSP for current process
ReturnInt22: dd 0 ; return address from program (Int 22h)
|