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