131151Sminshall #include <stdio.h> 231151Sminshall #include <dos.h> 331151Sminshall #include <stdlib.h> 431151Sminshall 5*31185Sminshall #include "../general/general.h" 631152Sminshall #include "spint.h" 731151Sminshall 831151Sminshall #define PSP_ENVIRONMENT 0x2c 931151Sminshall #define PSP_FCB1 0x5c 1031151Sminshall #define PSP_FCB2 0x6c 1131151Sminshall 1231151Sminshall typedef struct { 1331151Sminshall int 1431151Sminshall environment, /* Segment address of environment */ 1531151Sminshall cmd_ptr_offset, /* Offset of command to execute */ 1631151Sminshall cmd_ptr_segment, /* Segment where command lives */ 1731151Sminshall fcb1_ptr_offset, /* Offset of FCB 1 */ 1831151Sminshall fcb1_ptr_segment, /* Segment of FCB 1 */ 1931151Sminshall fcb2_ptr_offset, /* Offset of FCB 2 */ 2031151Sminshall fcb2_ptr_segment; /* Segment of FCB 2 */ 2131151Sminshall } ExecList; 2231151Sminshall 2331155Sminshall 2431155Sminshall static int int_offset, int_segment; 2531155Sminshall 2631155Sminshall 2731151Sminshall void 2831155Sminshall spint_finish(spint) 2931155Sminshall Spint *spint; 3031155Sminshall { 3131155Sminshall union REGS regs; 3231155Sminshall struct SREGS sregs; 3331155Sminshall 3431155Sminshall if (spint->done == 0) { 3531155Sminshall return; /* Not done yet */ 3631155Sminshall } 3731155Sminshall 3831155Sminshall /* 3931155Sminshall * Restore old interrupt handler. 4031155Sminshall */ 4131155Sminshall 4231155Sminshall regs.h.ah = 0x25; 4331155Sminshall regs.h.al = spint->int_no; 4431155Sminshall regs.x.dx = int_offset; 4531155Sminshall sregs.ds = int_segment; 4631155Sminshall intdosx(®s, ®s, &sregs); 4731155Sminshall 4831155Sminshall if (spint->regs.x.cflag) { 4931155Sminshall fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax); 5031155Sminshall spint->done = 1; 5131155Sminshall spint->rc = 99; 5231155Sminshall return; 5331155Sminshall } 5431155Sminshall 5531155Sminshall regs.h.ah = 0x4d; /* Get return code */ 5631155Sminshall 5731155Sminshall intdos(®s, ®s); 5831155Sminshall 5931155Sminshall spint->rc = regs.x.ax; 6031155Sminshall } 6131155Sminshall 6231155Sminshall void 6331155Sminshall spint_continue(spint) 6431155Sminshall Spint *spint; 6531155Sminshall { 6631155Sminshall _spint_continue(spint); /* Return to caller */ 6731155Sminshall spint_finish(spint); 6831155Sminshall } 6931155Sminshall 7031155Sminshall 7131155Sminshall void 7231155Sminshall spint_start(command, spint) 7331151Sminshall char *command; 7431155Sminshall Spint *spint; 7531151Sminshall { 7631151Sminshall ExecList mylist; 7731151Sminshall char *comspec; 7831155Sminshall void _spint_int(); 7931155Sminshall union REGS regs; 8031155Sminshall struct SREGS sregs; 8131151Sminshall 8231151Sminshall /* 8331151Sminshall * Get comspec. 8431151Sminshall */ 8531151Sminshall comspec = getenv("COMSPEC"); 8631151Sminshall if (comspec == 0) { /* Can't find where command.com is */ 8731151Sminshall fprintf(stderr, "Unable to find COMSPEC in the environment."); 8831155Sminshall spint->done = 1; 8931155Sminshall spint->rc = 99; /* XXX */ 9031151Sminshall return; 9131151Sminshall } 9231151Sminshall 9331151Sminshall /* 9431151Sminshall * Now, hook up our interrupt routine. 9531151Sminshall */ 9631151Sminshall 9731155Sminshall regs.h.ah = 0x35; 9831155Sminshall regs.h.al = spint->int_no; 9931155Sminshall intdosx(®s, ®s, &sregs); 10031151Sminshall 10131151Sminshall /* Save old routine */ 10231155Sminshall int_offset = regs.x.bx; 10331155Sminshall int_segment = sregs.es; 10431151Sminshall 10531155Sminshall regs.h.ah = 0x25; 10631155Sminshall regs.h.al = spint->int_no; 10731155Sminshall regs.x.dx = (int) _spint_int; 10831155Sminshall segread(&sregs); 10931155Sminshall sregs.ds = sregs.cs; 11031155Sminshall intdosx(®s, ®s, &sregs); 11131151Sminshall 11231151Sminshall /* 11331151Sminshall * Read in segment registers. 11431151Sminshall */ 11531151Sminshall 11631155Sminshall segread(&spint->sregs); 11731151Sminshall 11831151Sminshall /* 11931151Sminshall * Set up registers for the EXEC call. 12031151Sminshall */ 12131151Sminshall 12231155Sminshall spint->regs.h.ah = 0x4b; 12331155Sminshall spint->regs.h.al = 0; 12431155Sminshall spint->regs.x.dx = (int) comspec; 12531155Sminshall spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */ 12631155Sminshall spint->regs.x.bx = (int) &mylist; 12731151Sminshall 12831151Sminshall /* 12931151Sminshall * Set up EXEC parameter list. 13031151Sminshall */ 13131151Sminshall 13231151Sminshall ClearElement(mylist); 13331151Sminshall mylist.cmd_ptr_offset = (int) command; 13431155Sminshall mylist.cmd_ptr_segment = spint->sregs.ds; 13531151Sminshall mylist.fcb1_ptr_offset = PSP_FCB1; 13631151Sminshall mylist.fcb1_ptr_segment = _psp; 13731151Sminshall mylist.fcb2_ptr_offset = PSP_FCB2; 13831151Sminshall mylist.fcb2_ptr_segment = _psp; 13931151Sminshall mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 14031151Sminshall 14131151Sminshall /* 14231151Sminshall * Call to assembly language routine to actually set up for 14331155Sminshall * the spint. 14431151Sminshall */ 14531151Sminshall 14631155Sminshall _spint_start(spint); 14731151Sminshall 14831155Sminshall spint_finish(spint); 14931151Sminshall } 150