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