SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintasm.asm 1.2
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintc.c 1.2
+;
+; 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
+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.
public _int_spawn
_int_spawn proc near
public _int_spawn
_int_spawn proc near
- mov sp,bp
- pop bp
- ret
public _start_spawn
_start_spawn proc near
public _start_spawn
_start_spawn proc near
- 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
public _continue_spawn
_continue_spawn proc near
public _continue_spawn
_continue_spawn proc near
- 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
#include <stdlib.h>
#include "../ntn3270/general.h"
#include <stdlib.h>
#include "../ntn3270/general.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 */
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;
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 */
- * 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) {
+ 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",