BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / tn3270 / distribution / sys_dos / spintasm.asm
index 5b8b989..cb2780e 100644 (file)
@@ -1,3 +1,138 @@
+;
+; Copyright (c) 1988 Regents of the University of California.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms are permitted
+; provided that the above copyright notice and this paragraph are
+; duplicated in all such forms and that any documentation,
+; advertising materials, and other materials related to such
+; distribution and use acknowledge that the software was developed
+; by the University of California, Berkeley.  The name of the
+; University may not be used to endorse or promote products derived
+; from this software without specific prior written permission.
+; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+;
+;      @(#)spintasm.asm        4.1 (Berkeley) 12/4/88
+; The code in this file complete the spint calls
+;
+
+spint  struc
+; union REGS
+spint_ax       dw      1
+spint_bx       dw      1
+spint_cx       dw      1
+spint_dx       dw      1
+spint_si       dw      1
+spint_di       dw      1
+spint_cflag    dw      1
+; struct SREGS
+spint_es       dw      1
+spint_cs       dw      1
+spint_ss       dw      1
+spint_ds       dw      1
+; int intno
+spint_intno    dw      1
+; int done
+spint_done     dw      1
+; int rc
+spint_rc       dw      1
+;
+spint  ends
+
+
+ENTER  MACRO
+       ; Begin enter
+       push    bp
+       mov     bp,sp
+
+       push    ax
+       push    bx
+       push    cx
+       push    dx
+       push    bp
+       push    di
+       push    si
+       push    ds
+       push    es
+       pushf
+
+       mov     cs:start_sp, sp
+       mov     cs:start_ss, ss
+       ; End enter
+       ENDM
+
+LEAVE  MACRO
+       ; Begin leave
+       cli
+       mov     sp, cs:start_sp
+       mov     ss, cs:start_ss
+       sti
+
+       popf
+       pop     es
+       pop     ds
+       pop     si
+       pop     di
+       pop     bp
+       pop     dx
+       pop     cx
+       pop     bx
+       pop     ax
+
+       mov     sp,bp
+       pop     bp
+       ret
+       ; End leave
+       ENDM
+
+GETREGS        MACRO   wherefrom
+       mov     si, wherefrom
+       mov     spint_segment, ds
+       mov     spint_offset, si
+
+       mov     ax, spint_ax[si]
+       mov     bx, spint_bx[si]
+       mov     cx, spint_cx[si]
+       mov     dx, spint_dx[si]
+       ; XXX mov       si, spint_si[si]
+       mov     di, spint_di[si]
+       mov     es, spint_es[si]
+       ; Now, need to do DS, SI
+       push    spint_ds[si]
+       mov     si, spint_si[si]
+       pop     ds
+       ENDM
+
+
+SETREGS        MACRO
+       mov     cs:old_si, si
+       mov     cs:old_ds, ds
+
+       mov     ds, cs:spint_segment
+       mov     si, cs:spint_offset
+
+       mov     spint_ax[si], ax
+       mov     spint_bx[si], bx
+       mov     spint_cx[si], cx
+       mov     spint_dx[si], dx
+
+       mov     spint_si[si], si
+       mov     spint_di[si], di
+
+       mov     spint_cs[si], cs
+       mov     spint_ds[si], ds
+       mov     spint_es[si], es
+       mov     spint_ss[si], ss
+       ; now, need to do SI, DS
+       mov     ax, old_si
+       mov     spint_si[si], ax
+       mov     ax, old_ds
+       mov     spint_ds[si], ax
+       ENDM
+
+
 _TEXT  segment byte public 'CODE'
 _TEXT  ends
 
 _TEXT  segment byte public 'CODE'
 _TEXT  ends
 
@@ -16,50 +151,85 @@ DGROUP     group   CONST, _BSS, _DATA
 
 _TEXT  segment
 
 
 _TEXT  segment
 
+start_sp       dw      1 dup (?)       ; For use in our 'longjmp'
+start_ss       dw      1 dup (?)       ; For use in our 'longjmp'
+
+spint_segment  dw      1 dup (?)       ; Segment of spawn control block
+spint_offset   dw      1 dup (?)       ; Offset of spawn control block
+
+old_si         dw      1 dup (?)       ; SI of interrupt issuer (temporary)
+old_ds         dw      1 dup (?)       ; DS of interrupt issuer (temporary)
+
+issuer_ss      dw      1 dup (?)       ; ss of person who called us (permanent)
+issuer_sp      dw      1 dup (?)       ; sp of person who called us (permanent)
+
+int21_stack    db      100 dup (?)     ; Stack for int21.
+
 ;
 ;
-; int_spawn gets control on an interrupt.  It switches the stack
-; and does a 'return' from start_spawn.
+; _spint_int gets control on an interrupt.  It switches the stack
+; and does a 'return' from _spint_start.
 ;
 ;
-       public  _int_spawn
+       public  __spint_int
 
 
-_int_spawn     proc    near
-       push    bp
-       mov     bp,sp
+__spint_int    proc    near
+       mov     cs:issuer_sp, sp
+       mov     cs:issuer_ss, ss
+       sti
 
 
-       mov     sp,bp
-       pop     bp
-       ret
-_int_spawn     endp
+       SETREGS
+
+       LEAVE
+__spint_int    endp
 
 ;
 
 ;
-; start_spawn issues the dos interrupt after setting up the passed
-; registers.  When control returns to it, it sets spawn->done to non-zero.
+; _spint_start issues the dos interrupt after setting up the passed
+; registers.  When control returns to it, it sets spint->done to non-zero.
 ;
 ;
-       public  _start_spawn
+       public  __spint_start
 
 
-_start_spawn   proc    near
-       push    bp
-       mov     bp,sp
+__spint_start  proc    near
+       ENTER
 
 
-       mov     sp,bp
-       pop     bp
-       ret
-_start_spawn   endp
+       GETREGS 4[bp]
+
+       ; Now, switch to a different (short) stack.  This is so
+       ; that our games won't mess up the stack int 21 (hardware and,
+       ; possibly, software) stores things on.
+
+       cli
+       mov     cs:int21_stack, cs
+       mov     ss, cs:int21_stack
+       mov     sp, offset int21_stack
+       add     sp, (length int21_stack) - 4
+       sti
+
+       int     21H             ; Issue DOS interrupt
+
+       SETREGS
+
+       mov     ds, cs:spint_segment
+       mov     si, cs:spint_offset
+       mov     spint_done[si], 1       ; We are done
+
+       LEAVE
+__spint_start  endp
 
 ;
 
 ;
-; After int_spawn has faked a return from start_spawn, we come here to
+; After _spint_int has faked a return from start_spawn, we come here to
 ; return to the interrupt issuer.
 ;
 ; return to the interrupt issuer.
 ;
-       public  _continue_spawn
+       public  __spint_continue
 
 
-_continue_spawn        proc    near
-       push    bp
-       mov     bp,sp
+__spint_continue       proc    near
+       ENTER
 
 
-       mov     sp,bp
-       pop     bp
-       ret
-_continue_spawn        endp
+       GETREGS 4[bp]
+
+       mov     sp, cs:issuer_sp                ; Restore SP
+       mov     ss, cs:issuer_ss                ; Restore SS
+
+       iret
+__spint_continue       endp
 
 _TEXT  ends
 
 
 _TEXT  ends