1 ; SCCSID = @(#)disp.asm 1.1 85/04/10
2 ; SCCSID = @(#)disp.asm 1.1 85/04/10
14 AsmVars
<Kanji
, Debug
>
16 BREAK <Copyright notice
and version
>
17 CODE SEGMENT BYTE PUBLIC 'CODE'
20 I_need CurrentPDB
,WORD
40 I_need restore_tmp
,WORD
44 I_need User_In_AX
,WORD
45 I_need EXTERR_LOCUS
,BYTE
47 I_need Printer_Flag
,BYTE
48 I_need CPSWFLAG
,BYTE ;AN000;
49 I_need CPSWSAVE
,BYTE ;AN000;
50 I_need DISK_FULL
,BYTE ;AN000;
51 I_need InterCon
,BYTE ;AN000;
52 I_need BOOTDRIVE
,BYTE ;AN000;
53 I_need EXTOPEN_ON
,BYTE ;AN000;
54 I_need DOS34_FLAG
,WORD ;AN000;
55 I_need ACT_PAGE
,WORD ;AN000;
58 I_need OEM_HANDLER
,DWORD
62 I_am SETVECTFLAG
,BYTE,<0>
63 i_need BUF_EMS_SEG_CNT
,WORD ; DOS 4.00 EMS seg count ;AN000;
64 i_need BUF_EMS_MODE
,BYTE ; DOS 4.00 EMS mode ;AN000;
65 i_am BUF_EMS_MAP_USER
,12,<0,0,0,0,0,0,0,0,0,0,0,0>
68 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
70 BREAK <System
call entry points
and dispatcher
>
71 ASSUME
CS:DOSGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
73 BREAK <$Set_CTRL_C_Trapping
-- En
/Disable ^C check
in dispatcher
>
76 ; AL = 0 read ^C status
77 ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on
78 ; AL = 2 Set ^C status to contents of DL. Output is old state.
79 ; AL = 3 Get CPSW state to DL DOS 3.4
80 ; AL = 4 Set CPSW state from DL DOS 3.4
81 ; AL = 5 get DOS boot drive
83 ; Enable disable ^C checking in dispatcher
85 ; If AL = 0 then DL = 0/1 for ^C off/on
87 procedure $SET_CTRL_C_TRAPPING
,NEAR
88 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
109 ;; DOS 4.00 File Tagging
112 ; PUSH AX ;AN000;;FT.
113 ; MOV AL,[CPSWSAVE] ;AN000;;FT. DOS 3.4
114 ; MOV [CPSWFLAG],AL ;AN000;;FT. DOS 3.4 in case ABORT
116 CMP AL,3 ;AN000;;FT get CPSW state ?
117 JNZ CPSWset
;AN000;;FT. no
118 ; MOV DL,CPSWFLAG ;AN000;;FT. return CPSW state
121 CMP AL,4 ;AN000;;FT. set CPSW state ?
122 JA QueryDOSboot
;AN000;;FT. check query dos boot drive
123 ; PUSH AX ;AN000;;FT.
124 ; CallInstall NLSInstall,NLSFUNC,0 ;AN000;;FT. NLSFUNC installed ?
125 ; CMP AL,0FFH ;AN000;;FT.
127 ; JNZ BadVal ;AN000;;FT. not loaded, therefore ignore
128 ;;;; AND DL,01H ;AN000;;FT. only 0 or 1
129 ;;;; MOV [CPSWFLAG],DL ;AN000;;FT. set the flag
130 ;;;; MOV [CPSWSAVE],DL ;AN000;;FT. save one copy
132 QueryDOSboot: ;AN000;
135 MOV DL,[BOOTDRIVE
] ;AN000;;MS. put boot drive in DL
139 ;; DOS 4.00 File Tagging
141 EndProc $SET_CTRL_C_TRAPPING
143 BREAK <$Get_current_PDB
-- Set
/Get PDB value
>
144 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
145 ; C A V E A T P R O G R A M M E R ;
147 ; The following two routines are dispatched to directly with ints disabled
148 ; immediately after the int 21h entry. no DIS state is set.
150 ; $Set_current_PDB takes BX and sets it to be the current process
151 ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
153 procedure $SET_CURRENT_PDB
,NEAR
154 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
157 EndProc $SET_CURRENT_PDB
160 ; $get_current_PDB returns in BX the current process
161 ; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
163 procedure $GET_CURRENT_PDB
,NEAR
164 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
167 EndProc $GET_CURRENT_PDB
168 ; C A V E A T P R O G R A M M E R ;
170 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
173 ; Sets the Printer Flag to whatever is in AL.
174 ; NOTE: THIS PROCEDURE IS SUBJECT TO CHANGE!!!
176 Procedure $Set_Printer_Flag
177 ASSUME
DS:NOTHING
, ES:NOTHING
, SS:NOTHING
178 mov [Printer_Flag
],al
180 EndProc $Set_Printer_Flag
182 procedure SYSTEM_CALL
,NEAR
184 ; The Quit entry point is where all INT 20h's come from. These are old- style
185 ; exit system calls. The CS of the caller indicates which Process is dying.
186 ; The error code is presumed to be 0. We simulate an ABORT system call.
192 ; The system call in AH is out of the range that we know how to handle. We
193 ; arbitrarily set the contents of AL to 0 and IRET. Note that we CANNOT set
194 ; the carry flag to indicate an error as this may break some programs
202 ; An alternative method of entering the system is to perform a CALL 5 in the
203 ; program segment prefix with the contents of CL indicating what system call
204 ; the user would like. A subset of the possible system calls is allowed here;
205 ; only the CPM-compatible calls may get dispatched.
207 entry CALL_ENTRY
; System call entry point and dispatcher
208 POP AX ; IP from the long call at 5
209 POP AX ; Segment from the long call at 5
210 POP [User_SP
] ; IP from the CALL 5
212 ; Re order the stack to simulate an interrupt 21.
214 PUSHF ; Start re-ordering the stack
216 PUSH AX ; Save segment
217 PUSH [User_SP
] ; Stack now ordered as if INT had been used
218 CMP CL,MAXCALL
; This entry point doesn't get as many calls
223 ; This is the normal INT 21 entry point. We first perform a quick test to see
224 ; if we need to perform expensive DOS-entry functions. Certain system calls
225 ; are done without interrupts being enabled.
228 entry COMMAND
; Interrupt call entry point (INT 21H)
231 CMP AH,SET_OEM_HANDLER
241 ; The following set of calls are issued by the server at *arbitrary* times
242 ; and, therefore, must be executed on the user's entry stack and executed with
246 CMP AH,GET_CURRENT_PDB
250 CMP AH,SET_CURRENT_PDB
252 CMP AH,Set_CTRL_C_Trapping
254 JMP $Set_CTRL_C_Trapping
256 CMP AH,SET_PRINTER_FLAG
259 ; Preserve all user's registers on his own stack.
267 INC [INDOS
] ; Flag that we're in the DOS
270 MOV AX,CurrentPDB
; current process
271 MOV [PROC_ID
],AX ; Assume local machine for the moment
273 ; Provide one level of reentrancy for INT 24 recallability.
284 ; save user stack in his area for later returns (possibly from EXEC)
288 MOV WORD PTR DS:[PDB_User_stack
],SP
289 MOV WORD PTR DS:[PDB_User_stack
+2],SS
291 MOV fSharing
,0 ; allow redirection
293 MOV BX,CS ; no holes here.
298 MOV SP,OFFSET DOSGROUP
:AUXSTACK
; Enough stack for interrupts
299 STI ; stack is in our space now...
301 MOV BH, BYTE PTR DS:[PDB_InterCon
] ;AN000;; get interim mode 2/13/KK
302 MOV SS:[InterCon
], BH ;AN000;; 2/13/KK
306 DOSAssume
CS,<DS>,"MSCODE/ReDisp"
308 ; MOV BL,[CPSWSAVE] ;AN000;;FT. DOS 3.4
309 ; MOV [CPSWFLAG],BL ;AN000;;FT. DOS 3.4 in case ABORT
310 MOV [DISK_FULL
],0 ;AN000;;MS. no disk full
311 MOV [EXTOPEN_ON
],0 ;AN000;;EO. clear extended open flag
312 MOV [DOS34_FLAG
],0 ;AN000;;MS. clear common flag
313 MOV [ACT_PAGE
],-1 ;BN000;BL;AN000;;LB. invalidate active page
316 MOV [CONSWAP
],BH ; random clean up of possibly mis-set flags
317 MOV [IDLEINT
],1 ; presume that we can issue INT 28
318 MOV BYTE PTR [NoSetDir
],BH ; set directories on search
319 MOV BYTE PTR [FAILERR
],BH ; FAIL not in progress
321 SHL BX,1 ; 2 bytes per call in table
324 ; Since the DOS maintains mucho state information across system calls, we
325 ; must be very careful about which stack we use.
327 ; First, all abort operations must be on the disk stack. THis is due to the
328 ; fact that we may be hitting the disk (close operations, flushing) and may
329 ; need to report an INT 24.
334 ; Second, PRINT and PSPRINT and the server issue GetExtendedError calls at
335 ; INT 28 and INT 24 time. This call MUST, therefore, use the AUXSTACK.
337 CMP AH,GetExtendedError
340 ; Old 1-12 system calls may be either on the IOSTACK (normal operation) or
341 ; on the AUXSTACK (at INT 24 time).
345 CMP [ERRORMODE
],0 ; Are we in an INT 24?
346 JNZ DISPCALL
; Stay on AUXSTACK if INT 24.
347 MOV SP,OFFSET DOSGROUP
:IOSTACK
350 ; We are on a system call that is classified as "the rest". We place
351 ; ourselves onto the DSKSTACK and away we go. We know at this point:
353 ; o An INT 24 cannot be in progress. Therefore we reset errormode and
355 ; o That there can be no critical sections in effect. We signal the
356 ; server to remove all the resources.
359 MOV [USER_IN_AX
],AX ; Remember what user is doing
360 MOV [EXTERR_LOCUS
],errLOC_Unk
; Default
361 MOV [ERRORMODE
],0 ; Cannot make non 1-12 calls in
362 MOV [WPERR
],-1 ; error mode, so good place to make
364 ; Release all resource information
372 ; Since we are going to be running on the DSKStack and since INT 28 people
373 ; will use the DSKStack, we must turn OFF the generation of INT 28's.
376 MOV SP,OFFSET DOSGROUP
:DSKSTACK
378 JZ DISPCALL
; Extra ^C checking is disabled
383 MOV BX,CS:Dispatch
[BX]
388 mov cs:[SETVECTFLAG
], 0
393 mov cs:[SETVECTFLAG
], 1
395 invoke SAVE_USER_MAP
;AN000;LB. save EMS map
402 invoke RESTORE_USER_MAP
;AN000;LB. retsore EMS map
406 ASSUME
SS:NOTHING
; User routines may misbehave
412 MOV BYTE PTR [BP.user_AX
],AL
422 ; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from
423 ; the stack prior to giving the user control
425 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
426 procedure restore_world
,NEAR
427 POP restore_tmp
; POP restore_tmp
437 JMP restore_tmp
; PUSH restore_tmp
438 EndProc restore_world
441 ; save_world saves complete registers on the stack
443 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
444 procedure save_world
,NEAR
455 JMP restore_tmp
; PUSH restore_tmp
460 Break <SAVE_USER_MAP
- save map
> ;AN000;
467 ; No other registers altered ;AN000;
469 Procedure SAVE_USER_MAP
,NEAR ;AN000;
470 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
472 CMP cs:[BUF_EMS_MODE
],-1 ;LB. EMS support ;AN000;
473 JZ No_user_save
;LB. no ;AN000;
474 CMP cs:[SETVECTFLAG
], 1
476 ; MOV [ACT_PAGE],-1 ;LB. invalidate active page ;AN000;
477 ; MOV WORD PTR [LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000;
478 PUSH AX ;LB. save regs ;AN000;
479 PUSH DS ;LB. save regs ;AN000;
483 MOV SI,OFFSET DOSGROUP
:BUF_EMS_SEG_CNT
;LB. ;AN000;
484 MOV DI,OFFSET DOSGROUP
:BUF_EMS_MAP_USER
;LB. ;AN000;
488 PUSH CS ;LB. ds:si -> ems seg cnt ;AN000;
491 MOV AX,4F00H
;LB. save map ;AN000;
492 EnterCrit critDisk
;LB. enter critical section ;AN000;
494 LeaveCrit critDisk
;LB. leave critical section ;AN000;
496 POP SI ;LB. restore regs ;AN000;
499 POP AX ;LB. restore ;AN000;
500 No_user_save: ;AN000;
502 EndProc SAVE_USER_MAP
;AN000;
505 Break <RESTORE_USER_MAP
- retore map
> ;AN000;
509 ; restore_map ;AN000;
512 ; No other registers altered ;AN000;
514 Procedure RESTORE_USER_MAP
,NEAR ;AN000;
515 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
517 CMP cs:[BUF_EMS_MODE
],-1 ;LB. EMS support ;AN000;
518 JZ No_user_restore
;LB. no ;AN000;
519 CMP cs:[SETVECTFLAG
], 1
521 PUSH AX ;LB. save regs ;AN000;
522 PUSH DS ;LB. save regs ;AN000;
524 MOV SI,OFFSET DOSGROUP
:BUF_EMS_MAP_USER
;LB. ;AN000;
529 MOV AX,4F01H
;LB. restore map ;AN000;
530 EnterCrit critDisk
;LB. enter critical section ;AN000;
532 LeaveCrit critDisk
;LB. leave critical section ;AN000;
533 POP SI ;LB. restore regs ;AN000;
536 No_user_restore: ;AN000;
538 EndProc RESTORE_USER_MAP
543 ; get_user_stack returns the user's stack (and hence registers) in DS:SI
545 procedure get_user_stack
,NEAR
546 LDS SI,DWORD PTR [user_SP
]
548 EndProc get_user_stack
551 BREAK <Set_OEM_Handler
-- Set OEM sys
call address
and handle OEM Calls
554 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
557 ; User registers, User Stack, INTS disabled
558 ; If CALL F8, DS:DX is new handler address
560 ; Process OEM INT 21 extensions
562 ; Jumps to OEM_HANDLER if appropriate
564 JNE DO_OEM_FUNC
; If above F8 try to jump to handler
565 MOV WORD PTR [OEM_HANDLER
],DX ; Set Handler
566 MOV WORD PTR [OEM_HANDLER
+2],DS
567 IRET ; Quick return, Have altered no registers
570 CMP WORD PTR [OEM_HANDLER
],-1
572 JMP BADCALL
; Handler not initialized