1;
2; Copyright (c) 1988 Regents of the University of California.
3; All rights reserved.
4;
5; Redistribution and use in source and binary forms are permitted
6; provided that the above copyright notice and this paragraph are
7; duplicated in all such forms and that any documentation,
8; advertising materials, and other materials related to such
9; distribution and use acknowledge that the software was developed
10; by the University of California, Berkeley.  The name of the
11; University may not be used to endorse or promote products derived
12; from this software without specific prior written permission.
13; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16;
17;	@(#)spintasm.asm	3.3 (Berkeley) 07/09/88
18; The code in this file complete the spint calls
19;
20
21spint	struc
22; union REGS
23spint_ax	dw	1
24spint_bx	dw	1
25spint_cx	dw	1
26spint_dx	dw	1
27spint_si	dw	1
28spint_di	dw	1
29spint_cflag	dw	1
30; struct SREGS
31spint_es	dw	1
32spint_cs	dw	1
33spint_ss	dw	1
34spint_ds	dw	1
35; int intno
36spint_intno	dw	1
37; int done
38spint_done	dw	1
39; int rc
40spint_rc	dw	1
41;
42spint	ends
43
44
45ENTER	MACRO
46	; Begin enter
47	push	bp
48	mov	bp,sp
49
50	push	ax
51	push	bx
52	push	cx
53	push	dx
54	push	bp
55	push	di
56	push	si
57	push	ds
58	push	es
59	pushf
60
61	mov	cs:start_sp, sp
62	mov	cs:start_ss, ss
63	; End enter
64	ENDM
65
66LEAVE	MACRO
67	; Begin leave
68	cli
69	mov	sp, cs:start_sp
70	mov	ss, cs:start_ss
71	sti
72
73	popf
74	pop	es
75	pop	ds
76	pop	si
77	pop	di
78	pop	bp
79	pop	dx
80	pop	cx
81	pop	bx
82	pop	ax
83
84	mov	sp,bp
85	pop	bp
86	ret
87	; End leave
88	ENDM
89
90GETREGS	MACRO	wherefrom
91	mov	si, wherefrom
92	mov	spint_segment, ds
93	mov	spint_offset, si
94
95	mov	ax, spint_ax[si]
96	mov	bx, spint_bx[si]
97	mov	cx, spint_cx[si]
98	mov	dx, spint_dx[si]
99	; XXX mov	si, spint_si[si]
100	mov	di, spint_di[si]
101	mov	es, spint_es[si]
102	; Now, need to do DS, SI
103	push	spint_ds[si]
104	mov	si, spint_si[si]
105	pop	ds
106	ENDM
107
108
109SETREGS	MACRO
110	mov	cs:old_si, si
111	mov	cs:old_ds, ds
112
113	mov	ds, cs:spint_segment
114	mov	si, cs:spint_offset
115
116	mov	spint_ax[si], ax
117	mov	spint_bx[si], bx
118	mov	spint_cx[si], cx
119	mov	spint_dx[si], dx
120
121	mov	spint_si[si], si
122	mov	spint_di[si], di
123
124	mov	spint_cs[si], cs
125	mov	spint_ds[si], ds
126	mov	spint_es[si], es
127	mov	spint_ss[si], ss
128	; now, need to do SI, DS
129	mov	ax, old_si
130	mov	spint_si[si], ax
131	mov	ax, old_ds
132	mov	spint_ds[si], ax
133	ENDM
134
135
136_TEXT	segment	byte public 'CODE'
137_TEXT	ends
138
139_DATA	segment	word public 'DATA'
140_DATA	ends
141
142CONST	segment	word public 'CONST'
143CONST	ends
144
145_BSS	segment word public 'BSS'
146_BSS	ends
147
148DGROUP	group	CONST, _BSS, _DATA
149
150	assume	cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
151
152_TEXT	segment
153
154start_sp	dw	1 dup (?)	; For use in our 'longjmp'
155start_ss	dw	1 dup (?)	; For use in our 'longjmp'
156
157spint_segment	dw	1 dup (?)	; Segment of spawn control block
158spint_offset	dw	1 dup (?)	; Offset of spawn control block
159
160old_si		dw	1 dup (?)	; SI of interrupt issuer (temporary)
161old_ds		dw	1 dup (?)	; DS of interrupt issuer (temporary)
162
163issuer_ss	dw	1 dup (?)	; ss of person who called us (permanent)
164issuer_sp	dw	1 dup (?)	; sp of person who called us (permanent)
165
166int21_stack	db	100 dup (?)	; Stack for int21.
167
168;
169; _spint_int gets control on an interrupt.  It switches the stack
170; and does a 'return' from _spint_start.
171;
172	public	__spint_int
173
174__spint_int	proc	near
175	mov	cs:issuer_sp, sp
176	mov	cs:issuer_ss, ss
177	sti
178
179	SETREGS
180
181	LEAVE
182__spint_int	endp
183
184;
185; _spint_start issues the dos interrupt after setting up the passed
186; registers.  When control returns to it, it sets spint->done to non-zero.
187;
188	public	__spint_start
189
190__spint_start	proc	near
191	ENTER
192
193	GETREGS	4[bp]
194
195	; Now, switch to a different (short) stack.  This is so
196	; that our games won't mess up the stack int 21 (hardware and,
197	; possibly, software) stores things on.
198
199	cli
200	mov	cs:int21_stack, cs
201	mov	ss, cs:int21_stack
202	mov	sp, offset int21_stack
203	add	sp, (length int21_stack) - 4
204	sti
205
206	int	21H		; Issue DOS interrupt
207
208	SETREGS
209
210	mov	ds, cs:spint_segment
211	mov	si, cs:spint_offset
212	mov	spint_done[si], 1	; We are done
213
214	LEAVE
215__spint_start	endp
216
217;
218; After _spint_int has faked a return from start_spawn, we come here to
219; return to the interrupt issuer.
220;
221	public	__spint_continue
222
223__spint_continue	proc	near
224	ENTER
225
226	GETREGS	4[bp]
227
228	mov	sp, cs:issuer_sp		; Restore SP
229	mov	ss, cs:issuer_ss		; Restore SS
230
231	iret
232__spint_continue	endp
233
234_TEXT	ends
235
236	end
237