More and better.
authorGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Wed, 20 May 1987 07:13:16 +0000 (23:13 -0800)
committerGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Wed, 20 May 1987 07:13:16 +0000 (23:13 -0800)
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintasm.asm 1.2
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintc.c 1.2

usr/src/usr.bin/tn3270/distribution/sys_dos/spintasm.asm
usr/src/usr.bin/tn3270/distribution/sys_dos/spintc.c

index 5b8b989..bfe70ff 100644 (file)
@@ -1,3 +1,120 @@
+;
+; The code in this file complete the spawn_int calls
+;
+
+spawn  struc
+; union REGS
+spawn_ax       dw      1
+spawn_bx       dw      1
+spawn_cx       dw      1
+spawn_dx       dw      1
+spawn_si       dw      1
+spawn_di       dw      1
+spawn_cflag    dw      1
+; struct SREGS
+spawn_es       dw      1
+spawn_cs       dw      1
+spawn_ss       dw      1
+spawn_ds       dw      1
+; int intno
+spawn_intno    dw      1
+; int done
+spawn_done     dw      1
+; int rc
+spawn_rc       dw      1
+;
+spawn  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:save_sp, sp
+       mov     cs:save_ss, ss
+       ; End enter
+       ENDM
+
+LEAVE  MACRO
+       ; Begin leave
+       mov     sp, cs:save_sp
+       mov     ss, cs:save_ss
+
+       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     spawn_segment, ds
+       mov     spawn_offset, si
+
+       mov     ax, spawn_ax[si]
+       mov     bx, spawn_bx[si]
+       mov     cx, spawn_cx[si]
+       mov     dx, spawn_dx[si]
+       ; XXX mov       si, spawn_si[si]
+       mov     di, spawn_di[si]
+       mov     es, spawn_es[si]
+       ; Now, need to do DS, SI
+       push    spawn_ds[si]
+       mov     si, spawn_si[si]
+       pop     ds
+       ENDM
+
+
+SETREGS        MACRO
+       mov     cs:old_si, si
+       mov     cs:old_ds, ds
+
+       mov     ds, cs:spawn_segment
+       mov     si, cs:spawn_offset
+
+       mov     spawn_ax[si], ax
+       mov     spawn_bx[si], bx
+       mov     spawn_cx[si], cx
+       mov     spawn_dx[si], dx
+
+       mov     spawn_si[si], si
+       mov     spawn_di[si], di
+
+       mov     spawn_cs[si], cs
+       mov     spawn_ds[si], ds
+       mov     spawn_es[si], es
+       mov     spawn_ss[si], ss
+       ; now, need to do SI, DS
+       mov     ax, old_si
+       mov     spawn_si[si], ax
+       mov     ax, old_ds
+       mov     spawn_ds[si], ax
+       ENDM
+
+
 _TEXT  segment byte public 'CODE'
 _TEXT  ends
 
 _TEXT  segment byte public 'CODE'
 _TEXT  ends
 
@@ -16,6 +133,17 @@ DGROUP      group   CONST, _BSS, _DATA
 
 _TEXT  segment
 
 
 _TEXT  segment
 
+save_sp                dw      1               ; For use in our 'longjmp'
+save_ss                dw      1               ; For use in our 'longjmp'
+
+spawn_segment  dw      1               ; Segment of spawn control block
+spawn_offset   dw      1               ; Offset of spawn control block
+
+old_si         dw      1               ; SI of interrupt issuer (temporary)
+old_ds         dw      1               ; DS of interrupt issuer (temporary)
+
+issuer_sp      dw      1               ; sp of person who called us (permanent)
+
 ;
 ; int_spawn gets control on an interrupt.  It switches the stack
 ; and does a 'return' from start_spawn.
 ;
 ; int_spawn gets control on an interrupt.  It switches the stack
 ; and does a 'return' from start_spawn.
@@ -23,12 +151,11 @@ _TEXT      segment
        public  _int_spawn
 
 _int_spawn     proc    near
        public  _int_spawn
 
 _int_spawn     proc    near
-       push    bp
-       mov     bp,sp
+       mov     cs:issuer_sp, sp
 
 
-       mov     sp,bp
-       pop     bp
-       ret
+       SETREGS
+
+       LEAVE
 _int_spawn     endp
 
 ;
 _int_spawn     endp
 
 ;
@@ -38,12 +165,19 @@ _int_spawn endp
        public  _start_spawn
 
 _start_spawn   proc    near
        public  _start_spawn
 
 _start_spawn   proc    near
-       push    bp
-       mov     bp,sp
+       ENTER
 
 
-       mov     sp,bp
-       pop     bp
-       ret
+       GETREGS 4[bp]
+
+       int     21H             ; Issue DOS interrupt
+
+       SETREGS
+
+       mov     ds, cs:spawn_segment
+       mov     si, cs:spawn_offset
+       mov     spawn_done[si], 1       ; We are done
+
+       LEAVE
 _start_spawn   endp
 
 ;
 _start_spawn   endp
 
 ;
@@ -53,12 +187,13 @@ _start_spawn       endp
        public  _continue_spawn
 
 _continue_spawn        proc    near
        public  _continue_spawn
 
 _continue_spawn        proc    near
-       push    bp
-       mov     bp,sp
+       ENTER
 
 
-       mov     sp,bp
-       pop     bp
-       ret
+       GETREGS 4[bp]
+
+       mov     sp, cs:issuer_sp                ; Restore SP
+
+       iret
 _continue_spawn        endp
 
 _TEXT  ends
 _continue_spawn        endp
 
 _TEXT  ends
index 4f0c9b3..3350bd3 100644 (file)
@@ -5,13 +5,12 @@
 #include <stdlib.h>
 
 #include "../ntn3270/general.h"
 #include <stdlib.h>
 
 #include "../ntn3270/general.h"
+#include "spint.h"
 
 #define        PSP_ENVIRONMENT         0x2c
 #define        PSP_FCB1                0x5c
 #define        PSP_FCB2                0x6c
 
 
 #define        PSP_ENVIRONMENT         0x2c
 #define        PSP_FCB1                0x5c
 #define        PSP_FCB2                0x6c
 
-#define        INTERRUPT_NUMBER        73
-
 typedef struct {
     int
        environment,            /* Segment address of environment */
 typedef struct {
     int
        environment,            /* Segment address of environment */
@@ -23,15 +22,6 @@ typedef struct {
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
-typedef struct {
-    union REGS         regs;
-    struct SREGS       sregs;
-    int                        int_no; /* Which interrupt to wait on */
-    int                        done;   /* Are we done, or just took an interrupt? */
-    int                        rc;     /* return code */
-} Spawn;
-
-
 void
 do_spawn(command, spawn)
 char *command;
 void
 do_spawn(command, spawn)
 char *command;
@@ -136,6 +126,10 @@ Spawn *spawn;
     spawn->sregs.ds = int_segment;
     intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
 }
     spawn->sregs.ds = int_segment;
     intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
 }
+\f
+/* XXX */
+
+#define        INTERRUPT_NUMBER        73
 
 main(argc, argv, envp)
 int    argc;                           /* Number of passed arguments */
 
 main(argc, argv, envp)
 int    argc;                           /* Number of passed arguments */
@@ -177,35 +171,36 @@ char      *envp[];                        /* Inherited environment */
     }
 
     /*
     }
 
     /*
-     * do_spawn returns when either the command has finished, or when
+     * do_spawn() returns when either the command has finished, or when
      * the required interrupt comes in.  In the latter case, the appropriate
      * thing to do is to process the interrupt, and then return to
      * the required interrupt comes in.  In the latter case, the appropriate
      * thing to do is to process the interrupt, and then return to
-     * the interrupt issuer.
+     * the interrupt issuer by calling continue_spawn().
      */
     do_spawn(command, &spawned);
      */
     do_spawn(command, &spawned);
-    if (spawned.done == 0) {
+    while (spawned.done == 0) {
        /* Process request */
        /* Process request */
+       spawned.regs.h.al = 0;
+       spawned.regs.x.cflag = 0;               /* No errors (yet) */
        switch (spawned.regs.h.ah) {
        case 1:                 /* Add */
        switch (spawned.regs.h.ah) {
        case 1:                 /* Add */
-           spawned.regs.x.cx += spawned.regs.x.dx;
+           spawned.regs.x.bx += spawned.regs.x.cx;
            break;
        case 2:                 /* Subtract */
            break;
        case 2:                 /* Subtract */
-           spawned.regs.x.cx -= spawned.regs.x.dx;
+           spawned.regs.x.bx -= spawned.regs.x.cx;
            break;
        case 3:                 /* Multiply */
            break;
        case 3:                 /* Multiply */
-           spawned.regs.x.cx *= spawned.regs.x.dx;
+           spawned.regs.x.bx *= spawned.regs.x.cx;
            break;
        case 4:                 /* Divide */
            break;
        case 4:                 /* Divide */
-           spawned.regs.x.cx /= spawned.regs.x.dx;
+           spawned.regs.x.bx /= spawned.regs.x.cx;
            break;
        default:
            spawned.regs.h.al = -1;     /* Error */
            spawned.regs.x.cflag = 1;
            break;
        }
            break;
        default:
            spawned.regs.h.al = -1;     /* Error */
            spawned.regs.x.cflag = 1;
            break;
        }
+       spawned.regs.h.ah = 0;                  /* We saw this */
        continue_spawn(&spawned);
        continue_spawn(&spawned);
-       /*NOTREACHED*/
-       /* continue_spawn() causes an eventual return from do_spawn. */
     }
     if (spawned.rc != 0) {
        fprintf(stderr, "Process generated a return code of 0x%x.\n",
     }
     if (spawned.rc != 0) {
        fprintf(stderr, "Process generated a return code of 0x%x.\n",