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