|
|
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 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 4.1 (Berkeley) 12/4/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.