1*31895Sminshall /* 2*31895Sminshall * Copyright (c) 1984-1987 by the Regents of the 3*31895Sminshall * University of California and by Gregory Glenn Minshall. 4*31895Sminshall * 5*31895Sminshall * Permission to use, copy, modify, and distribute these 6*31895Sminshall * programs and their documentation for any purpose and 7*31895Sminshall * without fee is hereby granted, provided that this 8*31895Sminshall * copyright and permission appear on all copies and 9*31895Sminshall * supporting documentation, the name of the Regents of 10*31895Sminshall * the University of California not be used in advertising 11*31895Sminshall * or publicity pertaining to distribution of the programs 12*31895Sminshall * without specific prior permission, and notice be given in 13*31895Sminshall * supporting documentation that copying and distribution is 14*31895Sminshall * by permission of the Regents of the University of California 15*31895Sminshall * and by Gregory Glenn Minshall. Neither the Regents of the 16*31895Sminshall * University of California nor Gregory Glenn Minshall make 17*31895Sminshall * representations about the suitability of this software 18*31895Sminshall * for any purpose. It is provided "as is" without 19*31895Sminshall * express or implied warranty. 20*31895Sminshall */ 21*31895Sminshall 22*31895Sminshall #ifndef lint 23*31895Sminshall static char sccsid[] = "@(#)spintc.c 1.6 (Berkeley) 07/17/87"; 24*31895Sminshall #endif /* not lint */ 25*31895Sminshall 2631151Sminshall #include <stdio.h> 2731151Sminshall #include <dos.h> 2831151Sminshall #include <stdlib.h> 2931151Sminshall 3031185Sminshall #include "../general/general.h" 3131152Sminshall #include "spint.h" 3231151Sminshall 3331151Sminshall #define PSP_ENVIRONMENT 0x2c 3431151Sminshall #define PSP_FCB1 0x5c 3531151Sminshall #define PSP_FCB2 0x6c 3631151Sminshall 3731151Sminshall typedef struct { 3831151Sminshall int 3931151Sminshall environment, /* Segment address of environment */ 4031151Sminshall cmd_ptr_offset, /* Offset of command to execute */ 4131151Sminshall cmd_ptr_segment, /* Segment where command lives */ 4231151Sminshall fcb1_ptr_offset, /* Offset of FCB 1 */ 4331151Sminshall fcb1_ptr_segment, /* Segment of FCB 1 */ 4431151Sminshall fcb2_ptr_offset, /* Offset of FCB 2 */ 4531151Sminshall fcb2_ptr_segment; /* Segment of FCB 2 */ 4631151Sminshall } ExecList; 4731151Sminshall 4831155Sminshall 4931155Sminshall static int int_offset, int_segment; 5031155Sminshall 5131155Sminshall 5231151Sminshall void 5331155Sminshall spint_finish(spint) 5431155Sminshall Spint *spint; 5531155Sminshall { 5631155Sminshall union REGS regs; 5731155Sminshall struct SREGS sregs; 5831155Sminshall 5931155Sminshall if (spint->done == 0) { 6031155Sminshall return; /* Not done yet */ 6131155Sminshall } 6231155Sminshall 6331155Sminshall /* 6431155Sminshall * Restore old interrupt handler. 6531155Sminshall */ 6631155Sminshall 6731155Sminshall regs.h.ah = 0x25; 6831155Sminshall regs.h.al = spint->int_no; 6931155Sminshall regs.x.dx = int_offset; 7031155Sminshall sregs.ds = int_segment; 7131155Sminshall intdosx(®s, ®s, &sregs); 7231155Sminshall 7331155Sminshall if (spint->regs.x.cflag) { 7431155Sminshall fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax); 7531155Sminshall spint->done = 1; 7631155Sminshall spint->rc = 99; 7731155Sminshall return; 7831155Sminshall } 7931155Sminshall 8031155Sminshall regs.h.ah = 0x4d; /* Get return code */ 8131155Sminshall 8231155Sminshall intdos(®s, ®s); 8331155Sminshall 8431155Sminshall spint->rc = regs.x.ax; 8531155Sminshall } 8631155Sminshall 8731155Sminshall void 8831155Sminshall spint_continue(spint) 8931155Sminshall Spint *spint; 9031155Sminshall { 9131155Sminshall _spint_continue(spint); /* Return to caller */ 9231155Sminshall spint_finish(spint); 9331155Sminshall } 9431155Sminshall 9531155Sminshall 9631155Sminshall void 9731155Sminshall spint_start(command, spint) 9831151Sminshall char *command; 9931155Sminshall Spint *spint; 10031151Sminshall { 10131151Sminshall ExecList mylist; 10231151Sminshall char *comspec; 10331155Sminshall void _spint_int(); 10431155Sminshall union REGS regs; 10531155Sminshall struct SREGS sregs; 10631151Sminshall 10731151Sminshall /* 10831151Sminshall * Get comspec. 10931151Sminshall */ 11031151Sminshall comspec = getenv("COMSPEC"); 11131151Sminshall if (comspec == 0) { /* Can't find where command.com is */ 11231151Sminshall fprintf(stderr, "Unable to find COMSPEC in the environment."); 11331155Sminshall spint->done = 1; 11431155Sminshall spint->rc = 99; /* XXX */ 11531151Sminshall return; 11631151Sminshall } 11731151Sminshall 11831151Sminshall /* 11931151Sminshall * Now, hook up our interrupt routine. 12031151Sminshall */ 12131151Sminshall 12231155Sminshall regs.h.ah = 0x35; 12331155Sminshall regs.h.al = spint->int_no; 12431155Sminshall intdosx(®s, ®s, &sregs); 12531151Sminshall 12631151Sminshall /* Save old routine */ 12731155Sminshall int_offset = regs.x.bx; 12831155Sminshall int_segment = sregs.es; 12931151Sminshall 13031155Sminshall regs.h.ah = 0x25; 13131155Sminshall regs.h.al = spint->int_no; 13231155Sminshall regs.x.dx = (int) _spint_int; 13331155Sminshall segread(&sregs); 13431155Sminshall sregs.ds = sregs.cs; 13531155Sminshall intdosx(®s, ®s, &sregs); 13631151Sminshall 13731151Sminshall /* 13831151Sminshall * Read in segment registers. 13931151Sminshall */ 14031151Sminshall 14131155Sminshall segread(&spint->sregs); 14231151Sminshall 14331151Sminshall /* 14431151Sminshall * Set up registers for the EXEC call. 14531151Sminshall */ 14631151Sminshall 14731155Sminshall spint->regs.h.ah = 0x4b; 14831155Sminshall spint->regs.h.al = 0; 14931155Sminshall spint->regs.x.dx = (int) comspec; 15031155Sminshall spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */ 15131155Sminshall spint->regs.x.bx = (int) &mylist; 15231151Sminshall 15331151Sminshall /* 15431151Sminshall * Set up EXEC parameter list. 15531151Sminshall */ 15631151Sminshall 15731151Sminshall ClearElement(mylist); 15831151Sminshall mylist.cmd_ptr_offset = (int) command; 15931155Sminshall mylist.cmd_ptr_segment = spint->sregs.ds; 16031151Sminshall mylist.fcb1_ptr_offset = PSP_FCB1; 16131151Sminshall mylist.fcb1_ptr_segment = _psp; 16231151Sminshall mylist.fcb2_ptr_offset = PSP_FCB2; 16331151Sminshall mylist.fcb2_ptr_segment = _psp; 16431151Sminshall mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 16531151Sminshall 16631151Sminshall /* 16731151Sminshall * Call to assembly language routine to actually set up for 16831155Sminshall * the spint. 16931151Sminshall */ 17031151Sminshall 17131155Sminshall _spint_start(spint); 17231151Sminshall 17331155Sminshall spint_finish(spint); 17431151Sminshall } 175