New version numbering.
[unix-history] / usr / src / usr.bin / tn3270 / distribution / sys_dos / spintc.c
CommitLineData
992de934
GM
1/*
2 * Copyright (c) 1984-1987 by the Regents of the
3 * University of California and by Gregory Glenn Minshall.
4 *
5 * Permission to use, copy, modify, and distribute these
6 * programs and their documentation for any purpose and
7 * without fee is hereby granted, provided that this
8 * copyright and permission appear on all copies and
9 * supporting documentation, the name of the Regents of
10 * the University of California not be used in advertising
11 * or publicity pertaining to distribution of the programs
12 * without specific prior permission, and notice be given in
13 * supporting documentation that copying and distribution is
14 * by permission of the Regents of the University of California
15 * and by Gregory Glenn Minshall. Neither the Regents of the
16 * University of California nor Gregory Glenn Minshall make
17 * representations about the suitability of this software
18 * for any purpose. It is provided "as is" without
19 * express or implied warranty.
20 */
21
22#ifndef lint
c578271f 23static char sccsid[] = "@(#)spintc.c 3.1 (Berkeley) %G%";
992de934
GM
24#endif /* not lint */
25
211e0a3a
GM
26#include <stdio.h>
27#include <dos.h>
28#include <stdlib.h>
29
f478095f 30#include "../general/general.h"
4599d553 31#include "spint.h"
211e0a3a
GM
32
33#define PSP_ENVIRONMENT 0x2c
34#define PSP_FCB1 0x5c
35#define PSP_FCB2 0x6c
36
211e0a3a
GM
37typedef struct {
38 int
39 environment, /* Segment address of environment */
40 cmd_ptr_offset, /* Offset of command to execute */
41 cmd_ptr_segment, /* Segment where command lives */
42 fcb1_ptr_offset, /* Offset of FCB 1 */
43 fcb1_ptr_segment, /* Segment of FCB 1 */
44 fcb2_ptr_offset, /* Offset of FCB 2 */
45 fcb2_ptr_segment; /* Segment of FCB 2 */
46} ExecList;
47
84f75426
GM
48
49static int int_offset, int_segment;
50
51
211e0a3a 52void
84f75426
GM
53spint_finish(spint)
54Spint *spint;
55{
56 union REGS regs;
57 struct SREGS sregs;
58
59 if (spint->done == 0) {
60 return; /* Not done yet */
61 }
62
63 /*
64 * Restore old interrupt handler.
65 */
66
67 regs.h.ah = 0x25;
68 regs.h.al = spint->int_no;
69 regs.x.dx = int_offset;
70 sregs.ds = int_segment;
71 intdosx(&regs, &regs, &sregs);
72
73 if (spint->regs.x.cflag) {
74 fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax);
75 spint->done = 1;
76 spint->rc = 99;
77 return;
78 }
79
80 regs.h.ah = 0x4d; /* Get return code */
81
82 intdos(&regs, &regs);
83
84 spint->rc = regs.x.ax;
85}
86
87void
88spint_continue(spint)
89Spint *spint;
90{
91 _spint_continue(spint); /* Return to caller */
92 spint_finish(spint);
93}
94
95
96void
97spint_start(command, spint)
211e0a3a 98char *command;
84f75426 99Spint *spint;
211e0a3a
GM
100{
101 ExecList mylist;
102 char *comspec;
84f75426
GM
103 void _spint_int();
104 union REGS regs;
105 struct SREGS sregs;
211e0a3a
GM
106
107 /*
108 * Get comspec.
109 */
110 comspec = getenv("COMSPEC");
111 if (comspec == 0) { /* Can't find where command.com is */
112 fprintf(stderr, "Unable to find COMSPEC in the environment.");
84f75426
GM
113 spint->done = 1;
114 spint->rc = 99; /* XXX */
211e0a3a
GM
115 return;
116 }
117
118 /*
119 * Now, hook up our interrupt routine.
120 */
121
84f75426
GM
122 regs.h.ah = 0x35;
123 regs.h.al = spint->int_no;
124 intdosx(&regs, &regs, &sregs);
211e0a3a
GM
125
126 /* Save old routine */
84f75426
GM
127 int_offset = regs.x.bx;
128 int_segment = sregs.es;
211e0a3a 129
84f75426
GM
130 regs.h.ah = 0x25;
131 regs.h.al = spint->int_no;
132 regs.x.dx = (int) _spint_int;
133 segread(&sregs);
134 sregs.ds = sregs.cs;
135 intdosx(&regs, &regs, &sregs);
211e0a3a
GM
136
137 /*
138 * Read in segment registers.
139 */
140
84f75426 141 segread(&spint->sregs);
211e0a3a
GM
142
143 /*
144 * Set up registers for the EXEC call.
145 */
146
84f75426
GM
147 spint->regs.h.ah = 0x4b;
148 spint->regs.h.al = 0;
149 spint->regs.x.dx = (int) comspec;
150 spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */
151 spint->regs.x.bx = (int) &mylist;
211e0a3a
GM
152
153 /*
154 * Set up EXEC parameter list.
155 */
156
157 ClearElement(mylist);
158 mylist.cmd_ptr_offset = (int) command;
84f75426 159 mylist.cmd_ptr_segment = spint->sregs.ds;
211e0a3a
GM
160 mylist.fcb1_ptr_offset = PSP_FCB1;
161 mylist.fcb1_ptr_segment = _psp;
162 mylist.fcb2_ptr_offset = PSP_FCB2;
163 mylist.fcb2_ptr_segment = _psp;
164 mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT));
165
166 /*
167 * Call to assembly language routine to actually set up for
84f75426 168 * the spint.
211e0a3a
GM
169 */
170
84f75426 171 _spint_start(spint);
211e0a3a 172
84f75426 173 spint_finish(spint);
211e0a3a 174}