|
|
1.1 root 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 4.1 (Berkeley) 12/4/88
18: ; The code in this file complete the spint calls
19: ;
20:
21: spint struc
22: ; union REGS
23: spint_ax dw 1
24: spint_bx dw 1
25: spint_cx dw 1
26: spint_dx dw 1
27: spint_si dw 1
28: spint_di dw 1
29: spint_cflag dw 1
30: ; struct SREGS
31: spint_es dw 1
32: spint_cs dw 1
33: spint_ss dw 1
34: spint_ds dw 1
35: ; int intno
36: spint_intno dw 1
37: ; int done
38: spint_done dw 1
39: ; int rc
40: spint_rc dw 1
41: ;
42: spint ends
43:
44:
45: ENTER 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:
66: LEAVE 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:
90: GETREGS 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:
109: SETREGS 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:
142: CONST segment word public 'CONST'
143: CONST ends
144:
145: _BSS segment word public 'BSS'
146: _BSS ends
147:
148: DGROUP group CONST, _BSS, _DATA
149:
150: assume cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
151:
152: _TEXT segment
153:
154: start_sp dw 1 dup (?) ; For use in our 'longjmp'
155: start_ss dw 1 dup (?) ; For use in our 'longjmp'
156:
157: spint_segment dw 1 dup (?) ; Segment of spawn control block
158: spint_offset dw 1 dup (?) ; Offset of spawn control block
159:
160: old_si dw 1 dup (?) ; SI of interrupt issuer (temporary)
161: old_ds dw 1 dup (?) ; DS of interrupt issuer (temporary)
162:
163: issuer_ss dw 1 dup (?) ; ss of person who called us (permanent)
164: issuer_sp dw 1 dup (?) ; sp of person who called us (permanent)
165:
166: int21_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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.