forked from FDOS/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocsupt.asm
More file actions
307 lines (270 loc) · 9.02 KB
/
procsupt.asm
File metadata and controls
307 lines (270 loc) · 9.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
;
; File:
; procsupt.asm
; Description:
; Assembly support routines for process handling, etc.
;
; Copyright (c) 1995,1998
; Pasquale J. Villani
; All Rights Reserved
;
; This file is part of DOS-C.
;
; DOS-C is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version
; 2, or (at your option) any later version.
;
; DOS-C is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
; the GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with DOS-C; see the file COPYING. If not,
; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA.
;
; $Id: procsupt.asm 1591 2011-05-06 01:46:55Z bartoldeman $
;
%include "segs.inc"
extern _user_r
extern _break_flg ; break detected flag
extern _term_type
extern _int21_handler ; far call system services
%include "stacks.inc"
segment HMA_TEXT
extern _DGROUP_
;
; Special call for switching processes
;
; void exec_user(iregs far *irp, int disable_a20)
;
global _exec_user
_exec_user:
; PUSH$ALL
; mov ds,[_DGROUP_]
; cld
;
;
;
pop ax ; return address (unused)
pop bp ; irp (user ss:sp)
pop si
pop cx ; disable A20?
or cx,cx
jz do_iret
cli
mov ss,si
mov sp,bp ; set-up user stack
sti
;
POP$ALL
extern _ExecUserDisableA20
jmp DGROUP:_ExecUserDisableA20
do_iret:
extern _int21_iret
jmp _int21_iret
segment _LOWTEXT
;; Called whenever the BIOS detects a ^Break state
global _got_cbreak
_got_cbreak:
push ds
push ax
mov ax, 40h
mov ds, ax
or byte [71h], 80h ;; set the ^Break flag
pop ax
pop ds
iret
segment HMA_TEXT
;
; Special call for switching processes during break handling
;
; void interrupt far spawn_int23()
;
;
; +---------------+
; | flags | 22
; +---------------+
; | cs | 20
; +---------------+
; | ip | 18
; +---------------+
; | es | 16
; +---------------+
; | ds | 14
; +---------------+
; | bp | 12
; +---------------+
; | di | 10
; +---------------+
; | si | 8
; +---------------+
; | dx | 6
; +---------------+
; | cx | 4
; +---------------+
; | bx | 2
; +---------------+
; | ax | 0 <--- bp & sp after mov bp,sp
; +---------------+
;
global _spawn_int23
_spawn_int23:
;; 1999/03/27 ska - comments: see cmt1.txt
mov ds, [cs:_DGROUP_] ;; Make sure DS is OK
mov bp, [_user_r]
; restore to user stack
cli ;; Pre-8086 don't disable INT autom.
;*TE PATCH
; CtrlC at DosInput (like C:>DATE does)
; Nukes the Kernel.
;
; it looks like ENTRY.ASM+PROCSUPT.ASM
; got out of sync.
;
; spawn_int() assumes a stack layout at
; usr_ss:usr:sp. but usr:ss currently contains 0
;
; this patch helps FreeDos to survive CtrlC,
; but should clearly be done somehow else.
mov ss, [_user_r+2]
RestoreSP
sti
; get all the user registers back
Restore386Registers
POP$ALL
;; Construct the piece of code into the stack
;; stack frame: during generation of code piece
;; <higher address>
;; BP | SP | Meaning
;; 7 | 11 | offset CALL FAR will push onto stack
;; 5 | 9 | CALL FAR segment
;; 3 | 7 | CALL FAR offset
;; 2 | 6 | CALL FAR ??regain_control_int23 | instruction byte
;; 0 | 4 | INT 23 <<should-be value of SP upon return>>
;; -2 | 2 | segment of address of INT-23 \ To jump to INT 23
;; -4 | 0 | offset of address of INT-23 / via RETF
;; Upon return from INT-23 the CALL FAR pushes the address of
;; the byte immediately following the CALL FAR onto the stack.
;; This value POPed and decremented by 7 is the value SP must
;; contain, if the INT-23 was returned with RETF2/IRET.
sub sp, byte 8 ;; code piece needs 7 bytes --> 4 words
push ss ;; prepare jump to INT-23 via RETF
push bp ;; will be offset / temp: saved BP
mov bp, sp
add bp, byte 4 ;; position BP onto INT-23
mov word [bp], 23cdh ;; INT 23h
mov byte [bp+2], 9ah ;; CALL FAR immediate
mov word [bp+3], ??regain_control_int23
mov word [bp+5], cs
;; complete the jump to INT-23 via RETF and restore BP
xchg word [bp-4], bp
clc ;; set default action --> resume
; invoke the int 23 handler its address has been constructed
;; on the stack
retf
??regain_control_int23:
;; stack frame: constructed on entry to INT-23
;; <higher address>
; BP | SP | Meaning
;; 7 | 11 | offset CALL FAR will push onto stack
;; 5 | 9 | CALL FAR segment
;; 3 | 7 | CALL FAR offset
;; 2 | 6 | CALL FAR ??regain_control_int23 | instruction byte
;; 0 | 4 | INT 23 <<should-be value of SP upon return>>
;; -2 | 2 | segment of address of INT-23 \ To jump to INT 23
;; -4 | 0 | offset of address of INT-23 / via RETF
;; Upon return from INT-23 the CALL FAR pushes the address of
;; the byte immediately following the CALL FAR onto the stack.
;; This value POPed and decremented by 7 is the value SP must
;; contain, if the INT-23 was returned with RETF2/IRET.
;; stack frame: used during recovering from INT-23
;; <higher address>
;; BP | Meaning
;; 1 | <<next word onto stack, or value SP has to become>>
;; 0 | <<return address from CALL FAR>>
;; -1 | saved BP
;; -3 | saved AX
;; -7 | INT 23 <<should-be value of SP upon return>>
;; Somewhere on stack:
;; SP | Meaning
;; 4 | segment of return address of CALL FAR
;; 2 | offset of return address of CALL FAR
;; 0 | saved BP
push bp
mov bp, sp
mov bp, [bp+2] ;; get should-be address + 7
mov word [bp-3], ax ;; save AX
pop ax ;; old BP
mov word [bp-1], ax ;; preserve saved BP
mov ax, bp
dec ax ;; last used word of stack
dec ax ;; Don't use SUB to keep Carry flag
dec ax
xchg ax, sp ;; AX := current stack; SP corrected
;; Currently: BP - 7 == address of INT-23
;; should be AX + 4 --> IRET or RETF 2
;; ==> Test if BP - 7 == AX + 4
;; ==> Test if AX + 4 - BP + 7 == 0
pushf ;; preserve Carry flag
add ax, byte 4 + 7
sub ax, bp ;; AX := SP + 4
pop ax ;; saved Carry flag
jz ??int23_ign_carry ;; equal -> IRET --> ignore Carry
;; Carry is already cleared
push ax
popf ;; restore Carry flag
??int23_ign_carry:
pop ax ;; Restore the original register
jnc ??int23_respawn
;; The user returned via RETF 0, Carry is set
;; --> terminate program
;; This is done by set the _break_flg and modify the
;; AH value, which is passed to the _respawn_ call
;; into 0, which is "Terminate program".
push ds ;; we need DGROUP
mov ds, [cs:_DGROUP_]
inc byte [_break_flg]
mov byte [_term_type], 1
; ecm: This is overwritten in the int 21h handler,
; but is passed from the int 23h caller to the
; terminate code in MS-DOS by writing this.
; For us, break_flg is used in function 4Ch to
; re-set term_type to 1 later.
pop ds
xor ah, ah ;; clear ah --> perform DOS-00 --> terminate
??int23_respawn:
pop bp ;; Restore the original register
jmp DGROUP:_int21_handler
;
; interrupt enable and disable routines
;
; public _enable
;_enable proc near
; sti
; ret
;_enable endp
;
; public _disable
;_disable proc near
; cli
; ret
;_disable endp
extern _p_0_tos,_P_0
; prepare to call process 0 (the shell) from P_0() in C
global reloc_call_p_0
reloc_call_p_0:
pop ax ; return address (32-bit, unused)
pop ax
pop ax ; fetch parameter 0 (32-bit) from the old stack
pop dx
mov ds,[cs:_DGROUP_]
cli
mov ss,[cs:_DGROUP_]
mov sp,_p_0_tos ; load the dedicated process 0 stack
sti
push dx ; pass parameter 0 onto the new stack
push ax
call _P_0 ; no return, allow parameter fetch from C