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 the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)spintc.c 3.3 (Berkeley) 06/29/88"; 20 #endif /* not lint */ 21 22 #include <stdio.h> 23 #include <dos.h> 24 #include <stdlib.h> 25 26 #include "../general/general.h" 27 #include "spint.h" 28 29 #define PSP_ENVIRONMENT 0x2c 30 #define PSP_FCB1 0x5c 31 #define PSP_FCB2 0x6c 32 33 typedef struct { 34 int 35 environment, /* Segment address of environment */ 36 cmd_ptr_offset, /* Offset of command to execute */ 37 cmd_ptr_segment, /* Segment where command lives */ 38 fcb1_ptr_offset, /* Offset of FCB 1 */ 39 fcb1_ptr_segment, /* Segment of FCB 1 */ 40 fcb2_ptr_offset, /* Offset of FCB 2 */ 41 fcb2_ptr_segment; /* Segment of FCB 2 */ 42 } ExecList; 43 44 45 static int int_offset, int_segment; 46 47 48 void 49 spint_finish(spint) 50 Spint *spint; 51 { 52 union REGS regs; 53 struct SREGS sregs; 54 55 if (spint->done == 0) { 56 return; /* Not done yet */ 57 } 58 59 /* 60 * Restore old interrupt handler. 61 */ 62 63 regs.h.ah = 0x25; 64 regs.h.al = spint->int_no; 65 regs.x.dx = int_offset; 66 sregs.ds = int_segment; 67 intdosx(®s, ®s, &sregs); 68 69 if (spint->regs.x.cflag) { 70 fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax); 71 spint->done = 1; 72 spint->rc = 99; 73 return; 74 } 75 76 regs.h.ah = 0x4d; /* Get return code */ 77 78 intdos(®s, ®s); 79 80 spint->rc = regs.x.ax; 81 } 82 83 void 84 spint_continue(spint) 85 Spint *spint; 86 { 87 _spint_continue(spint); /* Return to caller */ 88 spint_finish(spint); 89 } 90 91 92 void 93 spint_start(command, spint) 94 char *command; 95 Spint *spint; 96 { 97 ExecList mylist; 98 char *comspec; 99 void _spint_int(); 100 union REGS regs; 101 struct SREGS sregs; 102 103 /* 104 * Get comspec. 105 */ 106 comspec = getenv("COMSPEC"); 107 if (comspec == 0) { /* Can't find where command.com is */ 108 fprintf(stderr, "Unable to find COMSPEC in the environment."); 109 spint->done = 1; 110 spint->rc = 99; /* XXX */ 111 return; 112 } 113 114 /* 115 * Now, hook up our interrupt routine. 116 */ 117 118 regs.h.ah = 0x35; 119 regs.h.al = spint->int_no; 120 intdosx(®s, ®s, &sregs); 121 122 /* Save old routine */ 123 int_offset = regs.x.bx; 124 int_segment = sregs.es; 125 126 regs.h.ah = 0x25; 127 regs.h.al = spint->int_no; 128 regs.x.dx = (int) _spint_int; 129 segread(&sregs); 130 sregs.ds = sregs.cs; 131 intdosx(®s, ®s, &sregs); 132 133 /* 134 * Read in segment registers. 135 */ 136 137 segread(&spint->sregs); 138 139 /* 140 * Set up registers for the EXEC call. 141 */ 142 143 spint->regs.h.ah = 0x4b; 144 spint->regs.h.al = 0; 145 spint->regs.x.dx = (int) comspec; 146 spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */ 147 spint->regs.x.bx = (int) &mylist; 148 149 /* 150 * Set up EXEC parameter list. 151 */ 152 153 ClearElement(mylist); 154 mylist.cmd_ptr_offset = (int) command; 155 mylist.cmd_ptr_segment = spint->sregs.ds; 156 mylist.fcb1_ptr_offset = PSP_FCB1; 157 mylist.fcb1_ptr_segment = _psp; 158 mylist.fcb2_ptr_offset = PSP_FCB2; 159 mylist.fcb2_ptr_segment = _psp; 160 mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 161 162 /* 163 * Call to assembly language routine to actually set up for 164 * the spint. 165 */ 166 167 _spint_start(spint); 168 169 spint_finish(spint); 170 } 171