home *** CD-ROM | disk | FTP | other *** search
- /* This is file EXPHDLR.C */
- /*
- ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.dj", available from DJ Delorie at the address above.
- ** A copy of "copying.dj" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.dj".
- **
- ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
- /* History:66,55 */
-
- #include <process.h>
- #include <stdio.h>
- #include <dos.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <errno.h>
- #include <fcntl.h>
-
- #include "build.h"
- #include "types.h"
- #include "gdt.h"
- #include "idt.h"
- #include "tss.h"
- #include "utils.h"
- #include "paging.h"
- #include "npx.h"
- #include "mono.h"
- #include "vcpi.h"
-
- #define SEGFAULT(p) { \
- printf("Segmentation violation in pointer 0x%08lx at %x:%lx\n", (p), tss_ptr->tss_cs, tss_ptr->tss_eip); \
- return 1; \
- }
-
- extern word32 far *graphics_pt;
-
- extern int was_user_int;
- extern word16 vcpi_installed; /* VCPI Installed flag */
- static word16 master_pic = 0x08; /* Default IRQ0 Vector */
- word16 new_pic; /* current IRQ0 Vector */
- char transfer_buffer[4096]; /* must be near ptr for small model */
-
- word32 user_dta;
- static struct REGPACK r;
- static int in_graphics_mode=0;
- static int ctrl_c_causes_break=1;
-
- static word32 flmerge(word32 rf, word32 tf)
- {
- return (rf & 0xcff) | (tf & 0xfffff300L);
- }
-
- static set_controller(v)
- {
- /* disable(); */
- outportb(0x20, 0x11);
- outportb(0x21, v);
- outportb(0x21, 4);
- outportb(0x21, 1);
- /* enable(); */
- }
-
- static char _save_vectors[32];
-
- init_controllers()
- {
- disable();
- master_pic = 0x08;
- if (vcpi_installed)
- master_pic = vcpi_get_pic();
- if (master_pic == 0x08)
- {
- if (vcpi_installed)
- vcpi_set_pic(0x78);
- set_controller(0x78);
- movedata(0, 0x78*4, FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0x08*4);
- movedata(0, 0x08*4, 0, 0x78*4, 0x08*4);
- new_pic = 0x78;
- }
- else
- new_pic = master_pic;
- enable();
- }
-
- uninit_controllers()
- {
- disable();
- if (master_pic == 0x08)
- {
- if (vcpi_installed)
- vcpi_set_pic(master_pic);
- set_controller(master_pic);
- movedata(FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0, 0x78*4, 0x08*4);
- }
- enable();
- }
-
- extern int ctrl_c_flag;
-
- exception_handler()
- {
- int i;
- #if TOPLINEINFO
- char buf[20];
- sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
- for (i=0; buf[i]; i++)
- poke(screen_seg, i*2+80, buf[i] | 0x0600);
- #endif
- i = tss_ptr->tss_irqn;
- /* printf("i=%#02x, a0=%02x\n", i, inportb(0xa0)); */
- if (((i>=0x70) && (i<0x78) && (i != 0x75)) ||
- ((i >= new_pic) && (i<new_pic+8)))
- {
- if ((i>=0x70) && (i<0x78))
- intr(i, &r);
- else
- intr(i-new_pic+8, &r);
- if (ctrl_c_causes_break)
- if (i == new_pic+1)
- {
- r.r_ax = 0x0100;
- intr(0x16, &r);
- if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
- {
- _AH = 0;
- geninterrupt(0x16);
- ctrl_c_flag = 1;
- }
- }
- if (ctrl_c_flag)
- {
- ctrl_c_flag = 0;
- if (ctrl_c_causes_break)
- return 1;
- }
- return 0;
- }
- switch (i)
- {
- case 8:
- printf("double fault!\n");
- exit(1);
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 15:
- return 1;
- case 0x75:
- return 1;
- case 7:
- printf("Fatal! Application attempted to use not-present 80387!\n");
- printf("Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
- return 1;
- case 14:
- return page_in();
-
- case 0x10:
- return i_10();
- case 0x11:
- case 0x12:
- case 0x14:
- case 0x16:
- case 0x17:
- case 0x1a:
- return generic_handler();
- case 0x21:
- return i_21();
- case 0x33:
- return i_33();
- default:
- return 1;
- }
- }
-
- #if DEBUGGER
- static char flset[] = "VMRF NT OFDNIETFMIZR AC PE CY";
- static char floff[] = " UPID PLNZ PO NC";
- static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
-
- tssprint(TSS *t)
- {
- int i;
- printf("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx\n",
- t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
- printf("esi=%08lx edi=%08lx ebp=%08lx ",
- t->tss_esi, t->tss_edi, t->tss_ebp);
- for (i=0; i<18; i++)
- if (fluse[i])
- if (t->tss_eflags & (1<<(17-i)))
- printf(" %2.2s", flset+i*2);
- else
- printf(" %2.2s", floff+i*2);
- printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
- t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
- }
- #endif /* DEBUGGER */
-
- int retrieve_string(word32 v, char *transfer_buffer, char tchar)
- {
- int i;
- char c;
- for (i=0; i<4096; i++)
- {
- c = peek8(v);
- v++;
- transfer_buffer[i] = c;
- if (c == tchar)
- break;
- }
- return i+1; /* number of characters placed in buffer */
- }
-
- static int old_text_mode = -1;
-
- generic_handler()
- {
- tss2reg(&r);
- intr(tss_ptr->tss_irqn, &r);
- reg2tss(&r);
- return 0;
- }
-
- i_10()
- {
- #ifdef NONEWDRIVER
- if ((tss_ptr->tss_eax & 0xFF00) == 0xFF00)
- {
- #else
- switch(tss_ptr->tss_eax & 0xFF00) {
- case 0xFE00:
- graphics_inquiry();
- return 0;
- #endif
- case 0xFF00:
- graphics_mode(tss_ptr->tss_eax & 0xff);
- in_graphics_mode = (peekb(0x40, 0x49) > 7);
- return 0;
- }
- tss2reg(&r);
- intr(0x10, &r);
- reg2tss(&r);
- tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
- return 0;
- }
-
- #ifndef NOEVENTS
-
- #define FOR_GO32
- #include "eventque.h"
-
- #define MSDRAW_STACK 128 /* stack size for mouse callback */
-
- static word32 mousedraw_func32; /* 32-bit mouse cursor drawing function */
- static word32 mousedraw_contaddr; /* jump to this address after mouse draw */
- static char mousedraw_active; /* set while drawing mouse cursor */
- EventQueue *event_queue = NULL; /* event queue */
-
- static void mousedraw_hook(void)
- {
- disable();
- if(!mousedraw_active) {
- mousedraw_active = 1;
- mousedraw_contaddr = a_tss.tss_eip;
- a_tss.tss_eip = mousedraw_func32;
- }
- enable();
- }
-
- i_33()
- {
- void (*msdrawfun)(void);
- int queuesize;
-
- if(tss_ptr->tss_eax == 0x00ff) {
- if(event_queue != NULL) {
- EventQueueDeInit();
- event_queue = NULL;
- }
- if((queuesize = (int)tss_ptr->tss_ebx) > 0) {
- mousedraw_func32 = tss_ptr->tss_ecx;
- mousedraw_active = 0;
- msdrawfun =
- (mousedraw_func32 != 0L) ? mousedraw_hook : NULL;
- event_queue =
- EventQueueInit(queuesize,MSDRAW_STACK,msdrawfun,master_pic,new_pic);
- if(event_queue != NULL) {
- tss_ptr->tss_ebx =
- (((word32)FP_SEG(event_queue)) << 4) +
- ((word32)FP_OFF(event_queue)) +
- 0xe0000000L;
- tss_ptr->tss_ecx =
- (((word32)FP_SEG(&mousedraw_contaddr)) << 4) +
- ((word32)FP_OFF(&mousedraw_contaddr)) +
- 0xe0000000L;
- tss_ptr->tss_edx =
- (((word32)FP_SEG(&mousedraw_active)) << 4) +
- ((word32)FP_OFF(&mousedraw_active)) +
- 0xe0000000L;
- }
- else tss_ptr->tss_ebx = 0L;
- }
- tss_ptr->tss_eax = 0x0ff0; /* acknowledge event handling */
- return(0);
- }
- #else /* NOEVENTS */
- i_33()
- {
- #endif /* NOEVENTS */
- if (*((unsigned far *)0x000000CEL) == 0)
- return 0;
- r.r_ax = tss_ptr->tss_eax;
- r.r_bx = tss_ptr->tss_ebx;
- r.r_cx = tss_ptr->tss_ecx;
- r.r_dx = tss_ptr->tss_edx;
- intr(0x33, &r);
- tss_ptr->tss_eax = r.r_ax;
- tss_ptr->tss_ebx = r.r_bx;
- tss_ptr->tss_ecx = r.r_cx;
- tss_ptr->tss_edx = r.r_dx;
- return 0;
- }
-
- TSS last_tss;
-
- i_21()
- {
- word32 v, trans_total, countleft;
- int i, c, ah, tchar, trans_count;
- char *cp;
- memcpy(&last_tss, tss_ptr, sizeof(TSS));
- tss2reg(&r);
- ah = (tss_ptr->tss_eax >> 8) & 0xff;
- #if 0
- printf("int 21h ax=0x%04x bx=0x%04x cx=0x%04x dx=0x%04x\n",
- (int)(tss_ptr->tss_eax),
- (int)(tss_ptr->tss_ebx),
- (int)(tss_ptr->tss_ecx),
- (int)(tss_ptr->tss_edx)
- );
- #endif
- switch (ah)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 0x0b:
- case 0x0e:
- case 0x19:
- case 0x2a:
- case 0x2b:
- case 0x2c:
- case 0x2d:
- case 0x42:
- case 0x45:
- case 0x46:
- case 0x57:
- case 0x68:
- intr(0x21, &r);
- reg2tss(&r);
- return 0;
- case 0x33: /* ^C checking */
- if ((r.r_ax & 0xff) == 0x01)
- ctrl_c_causes_break = r.r_dx & 0xff;
- intr(0x21, &r);
- reg2tss(&r);
- return 0;
- case 0x3e:
- #if DEBUGGER
- if (r.r_bx <= 2)
- return 0;
- #endif
- if (r.r_bx == 1)
- redir_1_mono = redir_1_2 = 0;
- if (r.r_bx == 2)
- redir_2_mono = redir_2_1 = 0;
- intr(0x21, &r);
- reg2tss(&r);
- return 0;
- case 9:
- case 0x39:
- case 0x3a:
- case 0x3b:
- case 0x41:
- case 0x43:
- if (ah == 9)
- tchar = '$';
- else
- tchar = 0;
- v = tss_ptr->tss_edx + ARENA;
- if (!page_is_valid(v))
- {
- printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
- return 1;
- }
- retrieve_string(v, transfer_buffer, tchar);
- r.r_dx = FP_OFF(transfer_buffer);
- r.r_ds = _DS;
- intr(0x21, &r);
- reg2tss(&r);
- return 0;
- case 0x3c:
- v = tss_ptr->tss_edx + ARENA;
- if (!page_is_valid(v))
- {
- printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
- return 1;
- }
- retrieve_string(v, transfer_buffer, 0);
- i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
- if (i < 0)
- {
- tss_ptr->tss_eax = errno;
- tss_ptr->tss_eflags |= 1;
- }
- else
- {
- tss_ptr->tss_eax = i;
- tss_ptr->tss_eflags &= ~1;
- }
- return 0;
- case 0x3d:
- v = tss_ptr->tss_edx + ARENA;
- if (!page_is_valid(v))
- {
- printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
- return 1;
- }
- retrieve_string(v, transfer_buffer, 0);
- i = tss_ptr->tss_eax & 0xf0;
- if (tss_ptr->tss_eax & O_WRONLY) i &= 1;
- if (tss_ptr->tss_eax & O_RDWR) i &= 2;
- i = _open(transfer_buffer, i);
- if (i < 0)
- {
- tss_ptr->tss_eax = errno;
- tss_ptr->tss_eflags |= 1;
- }
- else
- {
- tss_ptr->tss_eax = i;
- tss_ptr->tss_eflags &= ~1;
- }
- return 0;
- case 0x1a:
- user_dta = tss_ptr->tss_edx;
- setdta((char far *)transfer_buffer);
- return 0;
- case 0x2f:
- tss_ptr->tss_ebx = user_dta;
- return 0;
- case 0x30:
- intr(0x21, &r);
- reg2tss(&r);
- return 0;
- case 0x56:
- v = tss_ptr->tss_edx + ARENA;
- if (!page_is_valid(v))
- {
- printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
- return 1;
- }
- i = retrieve_string(v, transfer_buffer, 0);
- r.r_dx = FP_OFF(transfer_buffer);
- r.r_ds = _DS;
- v = tss_ptr->tss_edi + ARENA;
- retrieve_string(v, transfer_buffer+i, 0);
- r.r_di = FP_OFF(transfer_buffer)+i;
- r.r_es = _DS;
- intr(0x21, &r);
- tss_ptr->tss_eax = r.r_ax;
- tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
- return 0;
- case 0x3f:
- trans_total = 0;
- countleft = tss_ptr->tss_ecx;
- v = tss_ptr->tss_edx;
- if (!page_is_valid(v+ARENA))
- {
- printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
- return 1;
- }
- while (countleft > 0)
- {
- trans_count = (countleft <= 4096) ? countleft : 4096;
- i = read(r.r_bx, transfer_buffer, trans_count);
- if (i < 0)
- {
- tss_ptr->tss_eflags |= 1; /* carry */
- tss_ptr->tss_eax = _doserrno;
- return 0;
- }
- memput(v+ARENA, transfer_buffer, i);
- trans_total += i;
- v += i;
- countleft -= i;
- if (isatty(r.r_bx) && (i<trans_count))
- break; /* they're line buffered */
- if (i == 0)
- break;
- }
- tss_ptr->tss_eax = trans_total;
- tss_ptr->tss_eflags &= ~1;
- return 0;
- case 0x40:
- trans_total = 0;
- countleft = tss_ptr->tss_ecx;
- if (countleft == 0)
- {
- r.r_ax = 0x4000;
- r.r_cx = 0;
- intr(0x21,&r);
- tss_ptr->tss_eax = 0;
- tss_ptr->tss_eflags &= ~1;
- return 0;
- }
- v = tss_ptr->tss_edx;
- if (!page_is_valid(v+ARENA))
- SEGFAULT(v);
- r.r_dx = (int)transfer_buffer;
- while (countleft > 0)
- {
- trans_count = (countleft <= 4096) ? countleft : 4096;
- memget(v+ARENA, transfer_buffer, trans_count);
- if ((r.r_bx == 1) && redir_1_mono)
- i = mono_write(transfer_buffer, trans_count);
- else if ((r.r_bx == 2) && redir_2_mono)
- i = mono_write(transfer_buffer, trans_count);
- else
- {
- int fd = r.r_bx;
- if ((r.r_bx == 2) && redir_2_1)
- fd = 1;
- else if ((r.r_bx == 1) && redir_1_2)
- fd = 2;
- i = write(fd, transfer_buffer, trans_count);
- if (in_graphics_mode && (fd < 3))
- {
- word32 far *p = graphics_pt;
- for (c = 0; c < 256; c++)
- *p++ &= ~PT_P;
- }
- }
- if (i<0) /* carry */
- {
- tss_ptr->tss_eflags |= 1; /* carry */
- tss_ptr->tss_eax = _doserrno;
- return 0;
- }
- trans_total += i;
- v += i;
- countleft -= i;
- if (i < trans_count)
- break;
- }
- tss_ptr->tss_eax = trans_total;
- tss_ptr->tss_eflags &= ~1;
- return 0;
- case 0x44:
- return i_21_44();
- case 0x4e:
- if (!page_is_valid(user_dta+ARENA))
- SEGFAULT(user_dta);
- v = tss_ptr->tss_edx + ARENA;
- if (!page_is_valid(v))
- SEGFAULT(v);
- retrieve_string(v, transfer_buffer+43, 0);
- r.r_dx = FP_OFF(transfer_buffer+43);
- r.r_ds = _DS;
- intr(0x21, &r);
- reg2tss(&r);
- for (i=20; i>=0; i--)
- transfer_buffer[i+28] = transfer_buffer[i+26];
- transfer_buffer[32+13] = 0; /* asciiz termination */
- memput(user_dta+ARENA, transfer_buffer, 48);
- return 0;
- case 0x4f:
- if (!page_is_valid(user_dta+ARENA))
- SEGFAULT(user_dta);
- memget(user_dta+ARENA, transfer_buffer, 48);
- for (i=0; i<=20; i++)
- transfer_buffer[i+26] = transfer_buffer[i+28];
- intr(0x21, &r);
- reg2tss(&r);
- for (i=20; i>=0; i--)
- transfer_buffer[i+28] = transfer_buffer[i+26];
- transfer_buffer[32+13] = 0; /* asciiz termination */
- memput(user_dta+ARENA, transfer_buffer, 48);
- return 0;
- case 0x47:
- getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
- for (cp=transfer_buffer; *cp; cp++)
- {
- if (*cp == '\\') *cp = '/';
- *cp = tolower(*cp);
- }
- memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer)+1);
- tss_ptr->tss_eax = (unsigned)r.r_ax;
- tss_ptr->tss_eflags &= ~1;
- return 0;
- case 0x4a:
- if (tss_ptr->tss_eax & 0xff)
- tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
- else
- tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
- return 0;
- case 0x4c:
- #if DEBUGGER
- printf("Program exited normally, return code %d (0x%x)\n",
- (int)(tss_ptr->tss_eax & 0xff), (int)(tss_ptr->tss_eax & 0xff));
- return 1;
- #else
- #if 0
- {
- int i, ch;
- FILE *f = fopen("con", "w");
- fprintf(f, "zero: ");
- for (i=0; i<20; i++)
- {
- ch = *(char *)i;
- fprintf(f, "%02x ", ch);
- }
- fprintf(f, "\r\n");
- }
- #endif
- exit(tss_ptr->tss_eax & 0xff);
- #endif
- case 0xff:
- return turbo_assist();
- default:
- return 1;
- }
- }
-
- struct time32 {
- word32 secs;
- word32 usecs;
- };
-
- struct tz32 {
- word32 offset;
- word32 dst;
- };
-
- struct stat32 {
- short st_dev;
- short st_ino;
- short st_mode;
- short st_nlink;
- short st_uid;
- short st_gid;
- short st_rdev;
- short st_align_for_word32;
- long st_size;
- long st_atime;
- long st_mtime;
- long st_ctime;
- long st_blksize;
- };
-
- static int dev_count=1;
-
- turbo_assist()
- {
- word32 p1, p2, p3, r;
- struct time32 time32;
- struct tz32 tz32;
- struct stat32 statbuf32;
- struct stat statbuf;
- int i;
-
- char buf[128];
- p1 = tss_ptr->tss_ebx;
- p2 = tss_ptr->tss_ecx;
- p3 = tss_ptr->tss_edx;
- switch (tss_ptr->tss_eax & 0xff)
- {
- case 1:
- retrieve_string(p1+ARENA, buf, 0);
- r = creat(buf, S_IREAD | S_IWRITE);
- break;
- case 2:
- retrieve_string(p1+ARENA, buf, 0);
- r = open(buf, (int)p2, S_IREAD | S_IWRITE);
- break;
- case 3:
- memset(&statbuf, 0, sizeof(statbuf));
- r = fstat((int)p1, &statbuf);
- statbuf32.st_dev = dev_count++;
- statbuf32.st_ino = statbuf.st_ino;
- statbuf32.st_mode = statbuf.st_mode;
- statbuf32.st_nlink = statbuf.st_nlink;
- statbuf32.st_uid = statbuf.st_uid;
- statbuf32.st_gid = statbuf.st_gid;
- statbuf32.st_rdev = statbuf.st_rdev;
- statbuf32.st_size = statbuf.st_size;
- statbuf32.st_atime = statbuf.st_atime;
- statbuf32.st_mtime = statbuf.st_mtime;
- statbuf32.st_ctime = statbuf.st_ctime;
- statbuf32.st_blksize = 512;
- memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
- break;
- case 4:
- if (p2)
- {
- if (!page_is_valid(p2+ARENA))
- SEGFAULT(p2);
- tz32.offset = timezone;
- tz32.dst = daylight;
- memput(p2+ARENA, &tz32, sizeof(tz32));
- }
- if (p1)
- {
- if (!page_is_valid(p1+ARENA))
- SEGFAULT(p1);
- time(&(time32.secs));
- _AH = 0x2c;
- geninterrupt(0x21);
- time32.usecs = _DL * 10000L;
- memput(p1+ARENA, &time32, sizeof(time32));
- }
- r = 0;
- break;
- case 5:
- if (p2)
- {
- if (!page_is_valid(p2+ARENA))
- SEGFAULT(p2);
- memget(p2+ARENA, &tz32, sizeof(tz32));
- timezone = tz32.offset;
- daylight = tz32.dst;
- }
- if (p1)
- {
- if (!page_is_valid(p1+ARENA))
- SEGFAULT(p1);
- memget(p1+ARENA, &time32, sizeof(time32));
- stime(&(time32.secs));
- }
- r = 0;
- break;
- case 6:
- memset(&statbuf, 0, sizeof(statbuf));
- retrieve_string(p1+ARENA, transfer_buffer, 0);
- r = stat(transfer_buffer, &statbuf);
- statbuf32.st_dev = dev_count++;
- statbuf32.st_ino = statbuf.st_ino;
- statbuf32.st_mode = statbuf.st_mode;
- statbuf32.st_nlink = statbuf.st_nlink;
- statbuf32.st_uid = statbuf.st_uid;
- statbuf32.st_gid = statbuf.st_gid;
- statbuf32.st_rdev = statbuf.st_rdev;
- statbuf32.st_size = statbuf.st_size;
- statbuf32.st_atime = statbuf.st_atime;
- statbuf32.st_mtime = statbuf.st_mtime;
- statbuf32.st_ctime = statbuf.st_ctime;
- statbuf32.st_blksize = 512;
- memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
- break;
- case 7:
- retrieve_string(p1+ARENA, transfer_buffer, 0);
- page_out_everything();
- uninit_controllers();
- sscanf(transfer_buffer, "%s%n", buf, &i);
- if (strpbrk(transfer_buffer, "<>|") == NULL)
- r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
- else
- r = -1;
- if (r & 0x80000000L)
- r = system(transfer_buffer);
- init_controllers();
- page_in_everything();
- break;
- case 8:
- _BX=(int)p1;
- _AX=0x4400;
- geninterrupt(0x21);
- i = _DX;
- if (p2 & O_BINARY)
- i |= 0x20;
- else
- i &= ~0x20;
- _BX=(int)p1;
- _DX = i;
- _AX=0x4401;
- geninterrupt(0x21);
- r = setmode((int)p1, (int)p2);
- break;
- case 9:
- retrieve_string(p1+ARENA, buf, 0);
- r = chmod(buf, (int)p2);
- break;
- default:
- return 1;
- }
- tss_ptr->tss_eflags &= ~1;
- if (r == -1)
- {
- tss_ptr->tss_eflags |= 1;
- tss_ptr->tss_eax = errno;
- return 0;
- }
- tss_ptr->tss_eax = r;
- return 0;
- }
-
- i_21_44()
- {
- switch (tss_ptr->tss_eax & 0xff)
- {
- case 0x00:
- case 0x01:
- case 0x06:
- case 0x07:
- intr(0x21, &r);
- tss_ptr->tss_edx = r.r_dx;
- tss_ptr->tss_eax = r.r_ax;
- tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
- return 0;
- default:
- return 1;
- }
- }
-
- tss2reg(struct REGPACK *r)
- {
- r->r_ax = tss_ptr->tss_eax;
- r->r_bx = tss_ptr->tss_ebx;
- r->r_cx = tss_ptr->tss_ecx;
- r->r_dx = tss_ptr->tss_edx;
- r->r_si = tss_ptr->tss_esi;
- r->r_di = tss_ptr->tss_edi;
- r->r_flags = tss_ptr->tss_eflags;
- r->r_ds = r->r_es = _DS;
- }
-
- reg2tss(struct REGPACK *r)
- {
- tss_ptr->tss_eax = r->r_ax;
- tss_ptr->tss_ebx = r->r_bx;
- tss_ptr->tss_ecx = r->r_cx;
- tss_ptr->tss_edx = r->r_dx;
- tss_ptr->tss_esi = r->r_si;
- tss_ptr->tss_edi = r->r_di;
- tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
- }
-