|
|
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:
13: #ifndef lint
14: static char sccsid[] = "@(#)spintc.c 3.2 (Berkeley) 3/28/88";
15: #endif /* not lint */
16:
17: #include <stdio.h>
18: #include <dos.h>
19: #include <stdlib.h>
20:
21: #include "../general/general.h"
22: #include "spint.h"
23:
24: #define PSP_ENVIRONMENT 0x2c
25: #define PSP_FCB1 0x5c
26: #define PSP_FCB2 0x6c
27:
28: typedef struct {
29: int
30: environment, /* Segment address of environment */
31: cmd_ptr_offset, /* Offset of command to execute */
32: cmd_ptr_segment, /* Segment where command lives */
33: fcb1_ptr_offset, /* Offset of FCB 1 */
34: fcb1_ptr_segment, /* Segment of FCB 1 */
35: fcb2_ptr_offset, /* Offset of FCB 2 */
36: fcb2_ptr_segment; /* Segment of FCB 2 */
37: } ExecList;
38:
39:
40: static int int_offset, int_segment;
41:
42:
43: void
44: spint_finish(spint)
45: Spint *spint;
46: {
47: union REGS regs;
48: struct SREGS sregs;
49:
50: if (spint->done == 0) {
51: return; /* Not done yet */
52: }
53:
54: /*
55: * Restore old interrupt handler.
56: */
57:
58: regs.h.ah = 0x25;
59: regs.h.al = spint->int_no;
60: regs.x.dx = int_offset;
61: sregs.ds = int_segment;
62: intdosx(®s, ®s, &sregs);
63:
64: if (spint->regs.x.cflag) {
65: fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax);
66: spint->done = 1;
67: spint->rc = 99;
68: return;
69: }
70:
71: regs.h.ah = 0x4d; /* Get return code */
72:
73: intdos(®s, ®s);
74:
75: spint->rc = regs.x.ax;
76: }
77:
78: void
79: spint_continue(spint)
80: Spint *spint;
81: {
82: _spint_continue(spint); /* Return to caller */
83: spint_finish(spint);
84: }
85:
86:
87: void
88: spint_start(command, spint)
89: char *command;
90: Spint *spint;
91: {
92: ExecList mylist;
93: char *comspec;
94: void _spint_int();
95: union REGS regs;
96: struct SREGS sregs;
97:
98: /*
99: * Get comspec.
100: */
101: comspec = getenv("COMSPEC");
102: if (comspec == 0) { /* Can't find where command.com is */
103: fprintf(stderr, "Unable to find COMSPEC in the environment.");
104: spint->done = 1;
105: spint->rc = 99; /* XXX */
106: return;
107: }
108:
109: /*
110: * Now, hook up our interrupt routine.
111: */
112:
113: regs.h.ah = 0x35;
114: regs.h.al = spint->int_no;
115: intdosx(®s, ®s, &sregs);
116:
117: /* Save old routine */
118: int_offset = regs.x.bx;
119: int_segment = sregs.es;
120:
121: regs.h.ah = 0x25;
122: regs.h.al = spint->int_no;
123: regs.x.dx = (int) _spint_int;
124: segread(&sregs);
125: sregs.ds = sregs.cs;
126: intdosx(®s, ®s, &sregs);
127:
128: /*
129: * Read in segment registers.
130: */
131:
132: segread(&spint->sregs);
133:
134: /*
135: * Set up registers for the EXEC call.
136: */
137:
138: spint->regs.h.ah = 0x4b;
139: spint->regs.h.al = 0;
140: spint->regs.x.dx = (int) comspec;
141: spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */
142: spint->regs.x.bx = (int) &mylist;
143:
144: /*
145: * Set up EXEC parameter list.
146: */
147:
148: ClearElement(mylist);
149: mylist.cmd_ptr_offset = (int) command;
150: mylist.cmd_ptr_segment = spint->sregs.ds;
151: mylist.fcb1_ptr_offset = PSP_FCB1;
152: mylist.fcb1_ptr_segment = _psp;
153: mylist.fcb2_ptr_offset = PSP_FCB2;
154: mylist.fcb2_ptr_segment = _psp;
155: mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT));
156:
157: /*
158: * Call to assembly language routine to actually set up for
159: * the spint.
160: */
161:
162: _spint_start(spint);
163:
164: spint_finish(spint);
165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.