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