1*48757Sbostic /*- 2*48757Sbostic * Copyright (c) 1988 The Regents of the University of California. 333814Sbostic * All rights reserved. 431895Sminshall * 5*48757Sbostic * %sccs.include.redist.c% 631895Sminshall */ 731895Sminshall 831895Sminshall #ifndef lint 9*48757Sbostic static char sccsid[] = "@(#)spintc.c 4.2 (Berkeley) 04/26/91"; 1033814Sbostic #endif /* not lint */ 1131895Sminshall 1231151Sminshall #include <stdio.h> 1331151Sminshall #include <dos.h> 1431151Sminshall #include <stdlib.h> 1531151Sminshall 1631185Sminshall #include "../general/general.h" 1731152Sminshall #include "spint.h" 1831151Sminshall 1931151Sminshall #define PSP_ENVIRONMENT 0x2c 2031151Sminshall #define PSP_FCB1 0x5c 2131151Sminshall #define PSP_FCB2 0x6c 2231151Sminshall 2331151Sminshall typedef struct { 2431151Sminshall int 2531151Sminshall environment, /* Segment address of environment */ 2631151Sminshall cmd_ptr_offset, /* Offset of command to execute */ 2731151Sminshall cmd_ptr_segment, /* Segment where command lives */ 2831151Sminshall fcb1_ptr_offset, /* Offset of FCB 1 */ 2931151Sminshall fcb1_ptr_segment, /* Segment of FCB 1 */ 3031151Sminshall fcb2_ptr_offset, /* Offset of FCB 2 */ 3131151Sminshall fcb2_ptr_segment; /* Segment of FCB 2 */ 3231151Sminshall } ExecList; 3331151Sminshall 3431155Sminshall 3531155Sminshall static int int_offset, int_segment; 3631155Sminshall 3731155Sminshall 3831151Sminshall void 3931155Sminshall spint_finish(spint) 4031155Sminshall Spint *spint; 4131155Sminshall { 4231155Sminshall union REGS regs; 4331155Sminshall struct SREGS sregs; 4431155Sminshall 4531155Sminshall if (spint->done == 0) { 4631155Sminshall return; /* Not done yet */ 4731155Sminshall } 4831155Sminshall 4931155Sminshall /* 5031155Sminshall * Restore old interrupt handler. 5131155Sminshall */ 5231155Sminshall 5331155Sminshall regs.h.ah = 0x25; 5431155Sminshall regs.h.al = spint->int_no; 5531155Sminshall regs.x.dx = int_offset; 5631155Sminshall sregs.ds = int_segment; 5731155Sminshall intdosx(®s, ®s, &sregs); 5831155Sminshall 5931155Sminshall if (spint->regs.x.cflag) { 6031155Sminshall fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax); 6131155Sminshall spint->done = 1; 6231155Sminshall spint->rc = 99; 6331155Sminshall return; 6431155Sminshall } 6531155Sminshall 6631155Sminshall regs.h.ah = 0x4d; /* Get return code */ 6731155Sminshall 6831155Sminshall intdos(®s, ®s); 6931155Sminshall 7031155Sminshall spint->rc = regs.x.ax; 7131155Sminshall } 7231155Sminshall 7331155Sminshall void 7431155Sminshall spint_continue(spint) 7531155Sminshall Spint *spint; 7631155Sminshall { 7731155Sminshall _spint_continue(spint); /* Return to caller */ 7831155Sminshall spint_finish(spint); 7931155Sminshall } 8031155Sminshall 8131155Sminshall 8231155Sminshall void 8331155Sminshall spint_start(command, spint) 8431151Sminshall char *command; 8531155Sminshall Spint *spint; 8631151Sminshall { 8731151Sminshall ExecList mylist; 8831151Sminshall char *comspec; 8931155Sminshall void _spint_int(); 9031155Sminshall union REGS regs; 9131155Sminshall struct SREGS sregs; 9231151Sminshall 9331151Sminshall /* 9431151Sminshall * Get comspec. 9531151Sminshall */ 9631151Sminshall comspec = getenv("COMSPEC"); 9731151Sminshall if (comspec == 0) { /* Can't find where command.com is */ 9831151Sminshall fprintf(stderr, "Unable to find COMSPEC in the environment."); 9931155Sminshall spint->done = 1; 10031155Sminshall spint->rc = 99; /* XXX */ 10131151Sminshall return; 10231151Sminshall } 10331151Sminshall 10431151Sminshall /* 10531151Sminshall * Now, hook up our interrupt routine. 10631151Sminshall */ 10731151Sminshall 10831155Sminshall regs.h.ah = 0x35; 10931155Sminshall regs.h.al = spint->int_no; 11031155Sminshall intdosx(®s, ®s, &sregs); 11131151Sminshall 11231151Sminshall /* Save old routine */ 11331155Sminshall int_offset = regs.x.bx; 11431155Sminshall int_segment = sregs.es; 11531151Sminshall 11631155Sminshall regs.h.ah = 0x25; 11731155Sminshall regs.h.al = spint->int_no; 11831155Sminshall regs.x.dx = (int) _spint_int; 11931155Sminshall segread(&sregs); 12031155Sminshall sregs.ds = sregs.cs; 12131155Sminshall intdosx(®s, ®s, &sregs); 12231151Sminshall 12331151Sminshall /* 12431151Sminshall * Read in segment registers. 12531151Sminshall */ 12631151Sminshall 12731155Sminshall segread(&spint->sregs); 12831151Sminshall 12931151Sminshall /* 13031151Sminshall * Set up registers for the EXEC call. 13131151Sminshall */ 13231151Sminshall 13331155Sminshall spint->regs.h.ah = 0x4b; 13431155Sminshall spint->regs.h.al = 0; 13531155Sminshall spint->regs.x.dx = (int) comspec; 13631155Sminshall spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */ 13731155Sminshall spint->regs.x.bx = (int) &mylist; 13831151Sminshall 13931151Sminshall /* 14031151Sminshall * Set up EXEC parameter list. 14131151Sminshall */ 14231151Sminshall 14331151Sminshall ClearElement(mylist); 14431151Sminshall mylist.cmd_ptr_offset = (int) command; 14531155Sminshall mylist.cmd_ptr_segment = spint->sregs.ds; 14631151Sminshall mylist.fcb1_ptr_offset = PSP_FCB1; 14731151Sminshall mylist.fcb1_ptr_segment = _psp; 14831151Sminshall mylist.fcb2_ptr_offset = PSP_FCB2; 14931151Sminshall mylist.fcb2_ptr_segment = _psp; 15031151Sminshall mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 15131151Sminshall 15231151Sminshall /* 15331151Sminshall * Call to assembly language routine to actually set up for 15431155Sminshall * the spint. 15531151Sminshall */ 15631151Sminshall 15731155Sminshall _spint_start(spint); 15831151Sminshall 15931155Sminshall spint_finish(spint); 16031151Sminshall } 161