131151Sminshall #define LINT_ARGS 231151Sminshall 331151Sminshall #include <stdio.h> 431151Sminshall #include <dos.h> 531151Sminshall #include <stdlib.h> 631151Sminshall 731151Sminshall #include "../ntn3270/general.h" 831152Sminshall #include "spint.h" 931151Sminshall 1031151Sminshall #define PSP_ENVIRONMENT 0x2c 1131151Sminshall #define PSP_FCB1 0x5c 1231151Sminshall #define PSP_FCB2 0x6c 1331151Sminshall 1431151Sminshall typedef struct { 1531151Sminshall int 1631151Sminshall environment, /* Segment address of environment */ 1731151Sminshall cmd_ptr_offset, /* Offset of command to execute */ 1831151Sminshall cmd_ptr_segment, /* Segment where command lives */ 1931151Sminshall fcb1_ptr_offset, /* Offset of FCB 1 */ 2031151Sminshall fcb1_ptr_segment, /* Segment of FCB 1 */ 2131151Sminshall fcb2_ptr_offset, /* Offset of FCB 2 */ 2231151Sminshall fcb2_ptr_segment; /* Segment of FCB 2 */ 2331151Sminshall } ExecList; 2431151Sminshall 25*31155Sminshall 26*31155Sminshall static int int_offset, int_segment; 27*31155Sminshall 28*31155Sminshall 2931151Sminshall void 30*31155Sminshall spint_finish(spint) 31*31155Sminshall Spint *spint; 32*31155Sminshall { 33*31155Sminshall union REGS regs; 34*31155Sminshall struct SREGS sregs; 35*31155Sminshall 36*31155Sminshall if (spint->done == 0) { 37*31155Sminshall return; /* Not done yet */ 38*31155Sminshall } 39*31155Sminshall 40*31155Sminshall /* 41*31155Sminshall * Restore old interrupt handler. 42*31155Sminshall */ 43*31155Sminshall 44*31155Sminshall regs.h.ah = 0x25; 45*31155Sminshall regs.h.al = spint->int_no; 46*31155Sminshall regs.x.dx = int_offset; 47*31155Sminshall sregs.ds = int_segment; 48*31155Sminshall intdosx(®s, ®s, &sregs); 49*31155Sminshall 50*31155Sminshall if (spint->regs.x.cflag) { 51*31155Sminshall fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax); 52*31155Sminshall spint->done = 1; 53*31155Sminshall spint->rc = 99; 54*31155Sminshall return; 55*31155Sminshall } 56*31155Sminshall 57*31155Sminshall regs.h.ah = 0x4d; /* Get return code */ 58*31155Sminshall 59*31155Sminshall intdos(®s, ®s); 60*31155Sminshall 61*31155Sminshall spint->rc = regs.x.ax; 62*31155Sminshall } 63*31155Sminshall 64*31155Sminshall void 65*31155Sminshall spint_continue(spint) 66*31155Sminshall Spint *spint; 67*31155Sminshall { 68*31155Sminshall _spint_continue(spint); /* Return to caller */ 69*31155Sminshall spint_finish(spint); 70*31155Sminshall } 71*31155Sminshall 72*31155Sminshall 73*31155Sminshall void 74*31155Sminshall spint_start(command, spint) 7531151Sminshall char *command; 76*31155Sminshall Spint *spint; 7731151Sminshall { 7831151Sminshall ExecList mylist; 7931151Sminshall char *comspec; 80*31155Sminshall void _spint_int(); 81*31155Sminshall union REGS regs; 82*31155Sminshall struct SREGS sregs; 8331151Sminshall 8431151Sminshall /* 8531151Sminshall * Get comspec. 8631151Sminshall */ 8731151Sminshall comspec = getenv("COMSPEC"); 8831151Sminshall if (comspec == 0) { /* Can't find where command.com is */ 8931151Sminshall fprintf(stderr, "Unable to find COMSPEC in the environment."); 90*31155Sminshall spint->done = 1; 91*31155Sminshall spint->rc = 99; /* XXX */ 9231151Sminshall return; 9331151Sminshall } 9431151Sminshall 9531151Sminshall /* 9631151Sminshall * Now, hook up our interrupt routine. 9731151Sminshall */ 9831151Sminshall 99*31155Sminshall regs.h.ah = 0x35; 100*31155Sminshall regs.h.al = spint->int_no; 101*31155Sminshall intdosx(®s, ®s, &sregs); 10231151Sminshall 10331151Sminshall /* Save old routine */ 104*31155Sminshall int_offset = regs.x.bx; 105*31155Sminshall int_segment = sregs.es; 10631151Sminshall 107*31155Sminshall regs.h.ah = 0x25; 108*31155Sminshall regs.h.al = spint->int_no; 109*31155Sminshall regs.x.dx = (int) _spint_int; 110*31155Sminshall segread(&sregs); 111*31155Sminshall sregs.ds = sregs.cs; 112*31155Sminshall intdosx(®s, ®s, &sregs); 11331151Sminshall 11431151Sminshall /* 11531151Sminshall * Read in segment registers. 11631151Sminshall */ 11731151Sminshall 118*31155Sminshall segread(&spint->sregs); 11931151Sminshall 12031151Sminshall /* 12131151Sminshall * Set up registers for the EXEC call. 12231151Sminshall */ 12331151Sminshall 124*31155Sminshall spint->regs.h.ah = 0x4b; 125*31155Sminshall spint->regs.h.al = 0; 126*31155Sminshall spint->regs.x.dx = (int) comspec; 127*31155Sminshall spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */ 128*31155Sminshall spint->regs.x.bx = (int) &mylist; 12931151Sminshall 13031151Sminshall /* 13131151Sminshall * Set up EXEC parameter list. 13231151Sminshall */ 13331151Sminshall 13431151Sminshall ClearElement(mylist); 13531151Sminshall mylist.cmd_ptr_offset = (int) command; 136*31155Sminshall mylist.cmd_ptr_segment = spint->sregs.ds; 13731151Sminshall mylist.fcb1_ptr_offset = PSP_FCB1; 13831151Sminshall mylist.fcb1_ptr_segment = _psp; 13931151Sminshall mylist.fcb2_ptr_offset = PSP_FCB2; 14031151Sminshall mylist.fcb2_ptr_segment = _psp; 14131151Sminshall mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 14231151Sminshall 14331151Sminshall /* 14431151Sminshall * Call to assembly language routine to actually set up for 145*31155Sminshall * the spint. 14631151Sminshall */ 14731151Sminshall 148*31155Sminshall _spint_start(spint); 14931151Sminshall 150*31155Sminshall spint_finish(spint); 15131151Sminshall } 152