home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cl5sr386.zip / GO32 / EXPHDLR.C < prev    next >
C/C++ Source or Header  |  1992-08-26  |  23KB  |  910 lines

  1. /* This is file EXPHDLR.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:66,55 */
  17.  
  18. #include <process.h>
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <sys/stat.h>
  22. #include <time.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25. #include <setjmp.h>
  26.  
  27. #include "build.h"
  28. #include "types.h"
  29. #include "gdt.h"
  30. #include "idt.h"
  31. #include "tss.h"
  32. #include "utils.h"
  33. #include "paging.h"
  34. #include "npx.h"
  35. #include "mono.h"
  36. #include "vcpi.h"
  37.  
  38. #define SEGFAULT(p) { \
  39.   printf("Segmentation violation in pointer 0x%08lx at %x:%lx\n", (p), tss_ptr->tss_cs, tss_ptr->tss_eip); \
  40.   return 1; \
  41.   }
  42.  
  43. extern word32 far *graphics_pt;
  44.  
  45. extern int was_user_int;
  46. extern word16 vcpi_installed;        /* VCPI Installed flag */
  47. static word16 master_pic = 0x08;    /* Default IRQ0 Vector */
  48. word16 new_pic;                /* current IRQ0 Vector */
  49. char transfer_buffer[4096];    /* must be near ptr for small model */
  50.  
  51. word32 user_dta;
  52. static struct REGPACK r;
  53. static int in_graphics_mode=0;
  54.  
  55. extern int ctrl_c_flag;
  56. extern enum { BREAK = 1, IGNORED = 0, POLLED = 2 } ctrl_c_behavior;
  57. extern int ctrl_c_pending;
  58. extern jmp_buf * ctrl_c_handler;
  59.  
  60. static word32 flmerge(word32 rf, word32 tf)
  61. {
  62.   return (rf & 0xcff) | (tf & 0xfffff300L);
  63. }
  64.  
  65. static set_controller(v)
  66. {
  67. /*  disable();  */
  68.   outportb(0x20, 0x11);
  69.   outportb(0x21, v);
  70.   outportb(0x21, 4);
  71.   outportb(0x21, 1);
  72. /*  enable();  */
  73. }
  74.  
  75. static char _save_vectors[32];
  76.  
  77. init_controllers()
  78. {
  79.   disable();
  80.   master_pic = 0x08;
  81.   if (vcpi_installed)
  82.     master_pic = vcpi_get_pic();
  83.   if (master_pic == 0x08)
  84.   {
  85.     if (vcpi_installed)
  86.       vcpi_set_pic(0x78);
  87.     set_controller(0x78);
  88.     movedata(0, 0x78*4, FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0x08*4);
  89.     movedata(0, 0x08*4, 0, 0x78*4, 0x08*4);
  90.     new_pic = 0x78;
  91.   }
  92.   else
  93.     new_pic = master_pic;
  94.   enable();
  95. }
  96.  
  97. uninit_controllers()
  98. {
  99.   disable();
  100.   if (master_pic == 0x08)
  101.   {
  102.     if (vcpi_installed)
  103.       vcpi_set_pic(master_pic);
  104.     set_controller(master_pic);
  105.     movedata(FP_SEG(_save_vectors), FP_OFF(_save_vectors), 0, 0x78*4, 0x08*4);
  106.   }
  107.   enable();
  108. }
  109.  
  110. exception_handler()
  111. {
  112.   int i;
  113. #if TOPLINEINFO
  114.   char buf[20];
  115.   sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
  116.   for (i=0; buf[i]; i++)
  117.     poke(screen_seg, i*2+80, buf[i] | 0x0600);
  118. #endif
  119.   i = tss_ptr->tss_irqn;
  120. /*  printf("i=%#02x, a0=%02x\n", i, inportb(0xa0)); */
  121.   if (((i>=0x70) && (i<0x78) && (i != 0x75)) ||
  122.       ((i >= new_pic) && (i<new_pic+8)))
  123.   {
  124.     if ((i>=0x70) && (i<0x78))
  125.       intr(i, &r);
  126.     else
  127.       intr(i-new_pic+8, &r);
  128.     if (ctrl_c_behavior != IGNORED)
  129.       if (i == new_pic+1)
  130.       {
  131.         r.r_ax = 0x0100;
  132.         intr(0x16, &r);
  133.         if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
  134.         {
  135.           _AH = 0;
  136.           geninterrupt(0x16);
  137.           ctrl_c_flag = 1;
  138.         }
  139.       }
  140.     if (ctrl_c_flag)
  141.     {
  142.       ctrl_c_flag = 0;
  143.       switch(ctrl_c_behavior) {
  144.         case IGNORED:
  145.       break;
  146.     case BREAK:
  147.       return 1;
  148.     case POLLED:
  149.       ctrl_c_pending = 1;
  150.       break;
  151.       }
  152.     }
  153.     return 0;
  154.   }
  155.   switch (i)
  156.   {
  157.     case 8:
  158.       printf("double fault!\n");
  159.       exit(1);
  160.     case 0:
  161.     case 1:
  162.     case 2:
  163.     case 3:
  164.     case 4:
  165.     case 5:
  166.     case 6:
  167.     case 9:
  168.     case 10:
  169.     case 11:
  170.     case 12:
  171.     case 13:
  172.     case 15:
  173.       return 1;
  174.     case 0x75:
  175.       return 1;
  176.     case 7:
  177.       printf("Fatal!  Application attempted to use not-present 80387!\n");
  178.       printf("Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
  179.       return 1;
  180.     case 14:
  181.       return page_in();
  182.  
  183.     case 0x10:
  184.       return i_10();
  185.     case 0x11:
  186.     case 0x12:
  187.     case 0x14:
  188.     case 0x16:
  189.     case 0x17:
  190.     case 0x1a:
  191.       return generic_handler();
  192.     case 0x21:
  193.       return i_21();
  194.     case 0x33:
  195.       return i_33();
  196.     default:
  197.       return 1;
  198.   }
  199. }
  200.  
  201. #if DEBUGGER
  202. static char flset[] = "VMRF  NT    OFDNIETFMIZR  AC  PE  CY";
  203. static char floff[] = "              UPID  PLNZ      PO  NC";
  204. static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
  205.  
  206. tssprint(TSS *t)
  207. {
  208.   int i;
  209.   printf("eax=%08lx  ebx=%08lx  ecx=%08lx  edx=%08lx\n",
  210.     t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
  211.   printf("esi=%08lx  edi=%08lx  ebp=%08lx ",
  212.     t->tss_esi, t->tss_edi, t->tss_ebp);
  213.   for (i=0; i<18; i++)
  214.     if (fluse[i])
  215.       if (t->tss_eflags & (1<<(17-i)))
  216.         printf(" %2.2s", flset+i*2);
  217.       else
  218.         printf(" %2.2s", floff+i*2);
  219.   printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
  220.     t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
  221. }
  222. #endif /* DEBUGGER */
  223.  
  224. int retrieve_string(word32 v, char *transfer_buffer, char tchar)
  225. {
  226.   int i;
  227.   char c;
  228.   for (i=0; i<4096; i++)
  229.   {
  230.     c = peek8(v);
  231.     v++;
  232.     transfer_buffer[i] = c;
  233.     if (c == tchar)
  234.       break;
  235.   }
  236.   return i+1; /* number of characters placed in buffer */
  237. }
  238.  
  239. static int old_text_mode = -1;
  240.  
  241. generic_handler()
  242. {
  243.   tss2reg(&r);
  244.   intr(tss_ptr->tss_irqn, &r);
  245.   reg2tss(&r);
  246.   return 0;
  247. }
  248.  
  249. i_10()
  250. {
  251. #ifdef NONEWDRIVER
  252.   if ((tss_ptr->tss_eax & 0xFF00) == 0xFF00)
  253.   {
  254. #else
  255.   switch(tss_ptr->tss_eax & 0xFF00) {
  256.     case 0xFE00:
  257.       graphics_inquiry();
  258.       return 0;
  259. #endif
  260.     case 0xFF00:
  261.       graphics_mode(tss_ptr->tss_eax & 0xff);
  262.       in_graphics_mode = (peekb(0x40, 0x49) > 7);
  263.       return 0;
  264.   }
  265.   tss2reg(&r);
  266.   intr(0x10, &r);
  267.   reg2tss(&r);
  268.   tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
  269.   return 0;
  270. }
  271.  
  272. #ifndef NOEVENTS
  273.  
  274. #define  FOR_GO32
  275. #include "eventque.h"
  276.  
  277. #define  MSDRAW_STACK  128              /* stack size for mouse callback */
  278.  
  279. static word32  mousedraw_func32;        /* 32-bit mouse cursor drawing function */
  280. static word32  mousedraw_contaddr;      /* jump to this address after mouse draw */
  281. static char    mousedraw_active;        /* set while drawing mouse cursor */
  282. EventQueue    *event_queue = NULL;      /* event queue */
  283.  
  284. static void mousedraw_hook(void)
  285. {
  286.   disable();
  287.   if(!mousedraw_active) {
  288.     mousedraw_active = 1;
  289.     mousedraw_contaddr = a_tss.tss_eip;
  290.     a_tss.tss_eip = mousedraw_func32;
  291.   }
  292.   enable();
  293. }
  294.  
  295. i_33()
  296. {
  297.   void (*msdrawfun)(void);
  298.   int  queuesize;
  299.  
  300.   if(tss_ptr->tss_eax == 0x00ff) {
  301.     if(event_queue != NULL) {
  302.       EventQueueDeInit();
  303.       event_queue = NULL;
  304.     }
  305.     if((queuesize = (int)tss_ptr->tss_ebx) > 0) {
  306.       mousedraw_func32 = tss_ptr->tss_ecx;
  307.       mousedraw_active = 0;
  308.       msdrawfun =
  309.         (mousedraw_func32 != 0L) ? mousedraw_hook : NULL;
  310.       event_queue =
  311.         EventQueueInit(queuesize,MSDRAW_STACK,msdrawfun,master_pic,new_pic);
  312.       if(event_queue != NULL) {
  313.         tss_ptr->tss_ebx =
  314.           (((word32)FP_SEG(event_queue)) << 4) +
  315.           ((word32)FP_OFF(event_queue)) +
  316.           0xe0000000L;
  317.         tss_ptr->tss_ecx =
  318.           (((word32)FP_SEG(&mousedraw_contaddr)) << 4) +
  319.           ((word32)FP_OFF(&mousedraw_contaddr)) +
  320.           0xe0000000L;
  321.         tss_ptr->tss_edx =
  322.           (((word32)FP_SEG(&mousedraw_active)) << 4) +
  323.           ((word32)FP_OFF(&mousedraw_active)) +
  324.           0xe0000000L;
  325.       }
  326.       else tss_ptr->tss_ebx = 0L;
  327.     }
  328.     tss_ptr->tss_eax = 0x0ff0;              /* acknowledge event handling */
  329.     return(0);
  330.   }
  331. #else  /* NOEVENTS */
  332. i_33()
  333. {
  334. #endif /* NOEVENTS */
  335.   if (*((unsigned far *)0x000000CEL) == 0)
  336.     return 0;
  337.   r.r_ax = tss_ptr->tss_eax;
  338.   r.r_bx = tss_ptr->tss_ebx;
  339.   r.r_cx = tss_ptr->tss_ecx;
  340.   r.r_dx = tss_ptr->tss_edx;
  341.   intr(0x33, &r);
  342.   tss_ptr->tss_eax = r.r_ax;
  343.   tss_ptr->tss_ebx = r.r_bx;
  344.   tss_ptr->tss_ecx = r.r_cx;
  345.   tss_ptr->tss_edx = r.r_dx;
  346.   return 0;
  347. }
  348.  
  349. TSS last_tss;
  350.  
  351. i_21()
  352. {
  353.   word32 v, trans_total, countleft;
  354.   int i, c, ah, tchar, trans_count;
  355.   char *cp;
  356.   memcpy(&last_tss, tss_ptr, sizeof(TSS));
  357.   tss2reg(&r);
  358.   ah = (tss_ptr->tss_eax >> 8) & 0xff;
  359. #if 0
  360.   printf("int 21h ax=0x%04x bx=0x%04x cx=0x%04x dx=0x%04x\n",
  361.     (int)(tss_ptr->tss_eax),
  362.     (int)(tss_ptr->tss_ebx),
  363.     (int)(tss_ptr->tss_ecx),
  364.     (int)(tss_ptr->tss_edx)
  365.     );
  366. #endif
  367.   switch (ah)
  368.   {
  369.     case 1:
  370.     case 2:
  371.     case 3:
  372.     case 4:
  373.     case 5:
  374.     case 6:
  375.     case 7:
  376.     case 8:
  377.     case 0x0b:
  378.     case 0x0e:
  379.     case 0x19:
  380.     case 0x2a:
  381.     case 0x2b:
  382.     case 0x2c:
  383.     case 0x2d:
  384.     case 0x42:
  385.     case 0x45:
  386.     case 0x46:
  387.     case 0x57:
  388.     case 0x68:
  389.       intr(0x21, &r);
  390.       reg2tss(&r);
  391.       return 0;
  392.     case 0x33: /* ^C checking */
  393.       switch(r.r_ax & 0xff) {
  394.         case 3:                /* Check ctrl_c */
  395.       r.r_dx = ctrl_c_pending;
  396.       ctrl_c_pending = 0;
  397.       break;
  398.     case 1:
  399.           ctrl_c_behavior = r.r_dx & 0xff;
  400.       /* fall through */
  401.        default:
  402.          intr(0x21, &r);
  403.       }
  404.       reg2tss(&r);
  405.       return 0;
  406.     case 0x3e:
  407. #if DEBUGGER
  408.       if (r.r_bx <= 2)
  409.         return 0;
  410. #endif
  411.       if (r.r_bx == 1)
  412.         redir_1_mono = redir_1_2 = 0;
  413.       if (r.r_bx == 2)
  414.         redir_2_mono = redir_2_1 = 0;
  415.       intr(0x21, &r);
  416.       reg2tss(&r);
  417.       return 0;
  418.     case 9:
  419.     case 0x39:
  420.     case 0x3a:
  421.     case 0x3b:
  422.     case 0x41:
  423.     case 0x43:
  424.       if (ah == 9)
  425.         tchar = '$';
  426.       else
  427.         tchar = 0;
  428.       v = tss_ptr->tss_edx + ARENA;
  429.       if (!page_is_valid(v))
  430.       {
  431.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  432.         return 1;
  433.       }
  434.       retrieve_string(v, transfer_buffer, tchar);
  435.       r.r_dx = FP_OFF(transfer_buffer);
  436.       r.r_ds = _DS;
  437.       intr(0x21, &r);
  438.       reg2tss(&r);
  439.       return 0;
  440.     case 0x3c:
  441.       v = tss_ptr->tss_edx + ARENA;
  442.       if (!page_is_valid(v))
  443.       {
  444.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  445.         return 1;
  446.       }
  447.       retrieve_string(v, transfer_buffer, 0);
  448.       i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
  449.       if (i < 0)
  450.       {
  451.         tss_ptr->tss_eax = errno;
  452.         tss_ptr->tss_eflags |= 1;
  453.       }
  454.       else
  455.       {
  456.         tss_ptr->tss_eax = i;
  457.         tss_ptr->tss_eflags &= ~1;
  458.       }
  459.       return 0;
  460.     case 0x3d:
  461.       v = tss_ptr->tss_edx + ARENA;
  462.       if (!page_is_valid(v))
  463.       {
  464.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  465.         return 1;
  466.       }
  467.       retrieve_string(v, transfer_buffer, 0);
  468.       i = tss_ptr->tss_eax & 0xf0;
  469.       if (tss_ptr->tss_eax & O_WRONLY) i &= 1;
  470.       if (tss_ptr->tss_eax & O_RDWR) i &= 2;
  471.       i = _open(transfer_buffer, i);
  472.       if (i < 0)
  473.       {
  474.         tss_ptr->tss_eax = errno;
  475.         tss_ptr->tss_eflags |= 1;
  476.       }
  477.       else
  478.       {
  479.         tss_ptr->tss_eax = i;
  480.         tss_ptr->tss_eflags &= ~1;
  481.       }
  482.       return 0;
  483.     case 0x1a:
  484.       user_dta = tss_ptr->tss_edx;
  485.       setdta((char far *)transfer_buffer);
  486.       return 0;
  487.     case 0x2f:
  488.       tss_ptr->tss_ebx = user_dta;
  489.       return 0;
  490.     case 0x30:
  491.       intr(0x21, &r);
  492.       reg2tss(&r);
  493.       return 0;
  494.     case 0x56:
  495.       v = tss_ptr->tss_edx + ARENA;
  496.       if (!page_is_valid(v))
  497.       {
  498.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  499.         return 1;
  500.       }
  501.       i = retrieve_string(v, transfer_buffer, 0);
  502.       r.r_dx = FP_OFF(transfer_buffer);
  503.       r.r_ds = _DS;
  504.       v = tss_ptr->tss_edi + ARENA;
  505.       retrieve_string(v, transfer_buffer+i, 0);
  506.       r.r_di = FP_OFF(transfer_buffer)+i;
  507.       r.r_es = _DS;
  508.       intr(0x21, &r);
  509.       tss_ptr->tss_eax = r.r_ax;
  510.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  511.       return 0;
  512.     case 0x3f:
  513.       trans_total = 0;
  514.       countleft = tss_ptr->tss_ecx;
  515.       v = tss_ptr->tss_edx;
  516.       if (!page_is_valid(v+ARENA))
  517.       {
  518.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  519.         return 1;
  520.       }
  521.       while (countleft > 0)
  522.       {
  523.         trans_count = (countleft <= 4096) ? countleft : 4096;
  524.         i = read(r.r_bx, transfer_buffer, trans_count);
  525.         if (i < 0)
  526.         {
  527.           tss_ptr->tss_eflags |= 1; /* carry */
  528.           tss_ptr->tss_eax = _doserrno;
  529.           return 0;
  530.         }
  531.         memput(v+ARENA, transfer_buffer, i);
  532.         trans_total += i;
  533.         v += i;
  534.         countleft -= i;
  535.         if (isatty(r.r_bx) && (i<trans_count))
  536.           break; /* they're line buffered */
  537.         if (i == 0)
  538.           break;
  539.       }
  540.       tss_ptr->tss_eax = trans_total;
  541.       tss_ptr->tss_eflags &= ~1;
  542.       return 0;
  543.     case 0xA:                    /* Added by Xavier Leroy */
  544.       v = tss_ptr->tss_edx + ARENA;
  545.       if (!page_is_valid(v)) {
  546.         printf("Segmentation violation in pointer 0x%08lx\n",
  547.            tss_ptr->tss_edx);
  548.     return 1;
  549.       }
  550.       transfer_buffer[0] = peek8(v);
  551.       { jmp_buf handler;
  552.         if (setjmp(handler) == 0) {
  553.           ctrl_c_handler = &handler;
  554.           r.r_dx = FP_OFF(transfer_buffer);
  555.           r.r_ds = _DS;
  556.           intr(0x21, &r);
  557.       ctrl_c_handler = NULL;
  558.       r.r_ax = 0;
  559.        } else {
  560.       ctrl_c_handler = NULL;
  561.       transfer_buffer[1] = 0;
  562.       r.r_ax = 1;
  563.        }
  564.       }
  565.       memput(v, transfer_buffer, *((unsigned char *) transfer_buffer+1)+2);
  566.       reg2tss(&r);
  567.       return 0;
  568.     case 0x40:
  569.       trans_total = 0;
  570.       countleft = tss_ptr->tss_ecx;
  571.       if (countleft == 0)
  572.       {
  573.         r.r_ax = 0x4000;
  574.         r.r_cx = 0;
  575.         intr(0x21,&r);
  576.         tss_ptr->tss_eax = 0;
  577.         tss_ptr->tss_eflags &= ~1;
  578.         return 0;
  579.       }
  580.       v = tss_ptr->tss_edx;
  581.       if (!page_is_valid(v+ARENA))
  582.         SEGFAULT(v);
  583.       r.r_dx = (int)transfer_buffer;
  584.       while (countleft > 0)
  585.       {
  586.         trans_count = (countleft <= 4096) ? countleft : 4096;
  587.         memget(v+ARENA, transfer_buffer, trans_count);
  588.         if ((r.r_bx == 1) && redir_1_mono)
  589.           i = mono_write(transfer_buffer, trans_count);
  590.         else if ((r.r_bx == 2) && redir_2_mono)
  591.           i = mono_write(transfer_buffer, trans_count);
  592.         else
  593.         {
  594.           int fd = r.r_bx;
  595.           if ((r.r_bx == 2) && redir_2_1)
  596.             fd = 1;
  597.           else if ((r.r_bx == 1) && redir_1_2)
  598.             fd = 2;
  599.           i = write(fd, transfer_buffer, trans_count);
  600.           if (in_graphics_mode && (fd < 3))
  601.           {
  602.             word32 far *p = graphics_pt;
  603.             for (c = 0; c < 256; c++)
  604.               *p++ &= ~PT_P;
  605.           }
  606.         }
  607.         if (i<0) /* carry */
  608.         {
  609.           tss_ptr->tss_eflags |= 1; /* carry */
  610.           tss_ptr->tss_eax = _doserrno;
  611.           return 0;
  612.         }
  613.         trans_total += i;
  614.         v += i;
  615.         countleft -= i;
  616.         if (i < trans_count)
  617.           break;
  618.       }
  619.       tss_ptr->tss_eax = trans_total;
  620.       tss_ptr->tss_eflags &= ~1;
  621.       return 0;
  622.     case 0x44:
  623.       return i_21_44();
  624.     case 0x4e:
  625.       if (!page_is_valid(user_dta+ARENA))
  626.         SEGFAULT(user_dta);
  627.       v = tss_ptr->tss_edx + ARENA;
  628.       if (!page_is_valid(v))
  629.         SEGFAULT(v);
  630.       retrieve_string(v, transfer_buffer+43, 0);
  631.       r.r_dx = FP_OFF(transfer_buffer+43);
  632.       r.r_ds = _DS;
  633.       intr(0x21, &r);
  634.       reg2tss(&r);
  635.       for (i=20; i>=0; i--)
  636.         transfer_buffer[i+28] = transfer_buffer[i+26];
  637.       transfer_buffer[32+13] = 0; /* asciiz termination */
  638.       memput(user_dta+ARENA, transfer_buffer, 48);
  639.       return 0;
  640.     case 0x4f:
  641.       if (!page_is_valid(user_dta+ARENA))
  642.         SEGFAULT(user_dta);
  643.       memget(user_dta+ARENA, transfer_buffer, 48);
  644.       for (i=0; i<=20; i++)
  645.         transfer_buffer[i+26] = transfer_buffer[i+28];
  646.       intr(0x21, &r);
  647.       reg2tss(&r);
  648.       for (i=20; i>=0; i--)
  649.         transfer_buffer[i+28] = transfer_buffer[i+26];
  650.       transfer_buffer[32+13] = 0; /* asciiz termination */
  651.       memput(user_dta+ARENA, transfer_buffer, 48);
  652.       return 0;
  653.     case 0x47:
  654.       getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
  655.       for (cp=transfer_buffer; *cp; cp++)
  656.       {
  657.         if (*cp == '\\') *cp = '/';
  658.         *cp = tolower(*cp);
  659.       }
  660.       memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer)+1);
  661.       tss_ptr->tss_eax = (unsigned)r.r_ax;
  662.       tss_ptr->tss_eflags &= ~1;
  663.       return 0;
  664.     case 0x4a:
  665.       if (tss_ptr->tss_eax & 0xff)
  666.         tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
  667.       else
  668.         tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
  669.       return 0;
  670.     case 0x4c:
  671. #if DEBUGGER
  672.       printf("Program exited normally, return code %d (0x%x)\n",
  673.              (int)(tss_ptr->tss_eax & 0xff), (int)(tss_ptr->tss_eax & 0xff));
  674.       return 1;
  675. #else
  676. #if 0
  677.       {
  678.         int i, ch;
  679.         FILE *f = fopen("con", "w");
  680.         fprintf(f, "zero: ");
  681.         for (i=0; i<20; i++)
  682.         {
  683.           ch = *(char *)i;
  684.           fprintf(f, "%02x ", ch);
  685.         }
  686.         fprintf(f, "\r\n");
  687.       }
  688. #endif
  689.       exit(tss_ptr->tss_eax & 0xff);
  690. #endif
  691.     case 0xff:
  692.       return turbo_assist();
  693.     default:
  694.       return 1;
  695.   }
  696. }
  697.  
  698. struct time32 {
  699.   word32 secs;
  700.   word32 usecs;
  701. };
  702.  
  703. struct tz32 {
  704.   word32 offset;
  705.   word32 dst;
  706. };
  707.  
  708. struct    stat32 {
  709.     short st_dev;
  710.     short st_ino;
  711.     short st_mode;
  712.     short st_nlink;
  713.     short st_uid;
  714.     short st_gid;
  715.     short st_rdev;
  716.     short st_align_for_word32;
  717.     long  st_size;
  718.     long  st_atime;
  719.     long  st_mtime;
  720.     long  st_ctime;
  721.     long  st_blksize;
  722. };
  723.  
  724. static int dev_count=1;
  725.  
  726. turbo_assist()
  727. {
  728.   word32 p1, p2, p3, r;
  729.   struct time32 time32;
  730.   struct tz32 tz32;
  731.   struct stat32 statbuf32;
  732.   struct stat statbuf;
  733.   int i;
  734.  
  735.   char buf[128];
  736.   p1 = tss_ptr->tss_ebx;
  737.   p2 = tss_ptr->tss_ecx;
  738.   p3 = tss_ptr->tss_edx;
  739.   switch (tss_ptr->tss_eax & 0xff)
  740.   {
  741.     case 1:
  742.       retrieve_string(p1+ARENA, buf, 0);
  743.       r = creat(buf, S_IREAD | S_IWRITE);
  744.       break;
  745.     case 2:
  746.       retrieve_string(p1+ARENA, buf, 0);
  747.       r = open(buf, (int)p2, S_IREAD | S_IWRITE);
  748.       break;
  749.     case 3:
  750.       memset(&statbuf, 0, sizeof(statbuf));
  751.       r = fstat((int)p1, &statbuf);
  752.       statbuf32.st_dev = dev_count++;
  753.       statbuf32.st_ino = statbuf.st_ino;
  754.       statbuf32.st_mode = statbuf.st_mode;
  755.       statbuf32.st_nlink = statbuf.st_nlink;
  756.       statbuf32.st_uid = statbuf.st_uid;
  757.       statbuf32.st_gid = statbuf.st_gid;
  758.       statbuf32.st_rdev = statbuf.st_rdev;
  759.       statbuf32.st_size = statbuf.st_size;
  760.       statbuf32.st_atime = statbuf.st_atime;
  761.       statbuf32.st_mtime = statbuf.st_mtime;
  762.       statbuf32.st_ctime = statbuf.st_ctime;
  763.       statbuf32.st_blksize = 512;
  764.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  765.       break;
  766.     case 4:
  767.       if (p2)
  768.       {
  769.         if (!page_is_valid(p2+ARENA))
  770.           SEGFAULT(p2);
  771.         tz32.offset = timezone;
  772.         tz32.dst = daylight;
  773.         memput(p2+ARENA, &tz32, sizeof(tz32));
  774.       }
  775.       if (p1)
  776.       {
  777.         if (!page_is_valid(p1+ARENA))
  778.           SEGFAULT(p1);
  779.         time(&(time32.secs));
  780.         _AH = 0x2c;
  781.         geninterrupt(0x21);
  782.         time32.usecs = _DL * 10000L;
  783.         memput(p1+ARENA, &time32, sizeof(time32));
  784.       }
  785.       r = 0;
  786.       break;
  787.     case 5:
  788.       if (p2)
  789.       {
  790.         if (!page_is_valid(p2+ARENA))
  791.           SEGFAULT(p2);
  792.         memget(p2+ARENA, &tz32, sizeof(tz32));
  793.         timezone = tz32.offset;
  794.         daylight = tz32.dst;
  795.       }
  796.       if (p1)
  797.       {
  798.         if (!page_is_valid(p1+ARENA))
  799.           SEGFAULT(p1);
  800.         memget(p1+ARENA, &time32, sizeof(time32));
  801.         stime(&(time32.secs));
  802.       }
  803.       r = 0;
  804.       break;
  805.     case 6:
  806.       memset(&statbuf, 0, sizeof(statbuf));
  807.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  808.       r = stat(transfer_buffer, &statbuf);
  809.       statbuf32.st_dev = dev_count++;
  810.       statbuf32.st_ino = statbuf.st_ino;
  811.       statbuf32.st_mode = statbuf.st_mode;
  812.       statbuf32.st_nlink = statbuf.st_nlink;
  813.       statbuf32.st_uid = statbuf.st_uid;
  814.       statbuf32.st_gid = statbuf.st_gid;
  815.       statbuf32.st_rdev = statbuf.st_rdev;
  816.       statbuf32.st_size = statbuf.st_size;
  817.       statbuf32.st_atime = statbuf.st_atime;
  818.       statbuf32.st_mtime = statbuf.st_mtime;
  819.       statbuf32.st_ctime = statbuf.st_ctime;
  820.       statbuf32.st_blksize = 512;
  821.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  822.       break;
  823.     case 7:
  824.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  825.       page_out_everything();
  826.       uninit_controllers();
  827.       sscanf(transfer_buffer, "%s%n", buf, &i);
  828.       if (strpbrk(transfer_buffer, "<>|") == NULL)
  829.         r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
  830.       else
  831.         r = -1;
  832.       if (r & 0x80000000L)
  833.         r = system(transfer_buffer);
  834.       init_controllers();
  835.       page_in_everything();
  836.       break;
  837.     case 8:
  838.       _BX=(int)p1;
  839.       _AX=0x4400;
  840.       geninterrupt(0x21);
  841.       i = _DX;
  842.       if (p2 & O_BINARY)
  843.         i |= 0x20;
  844.       else
  845.         i &= ~0x20;
  846.       _BX=(int)p1;
  847.       _DX = i;
  848.       _AX=0x4401;
  849.       geninterrupt(0x21);
  850.       r = setmode((int)p1, (int)p2);
  851.       break;
  852.     case 9:
  853.       retrieve_string(p1+ARENA, buf, 0);
  854.       r = chmod(buf, (int)p2);
  855.       break;
  856.     default:
  857.       return 1;
  858.   }
  859.   tss_ptr->tss_eflags &= ~1;
  860.   if (r == -1)
  861.   {
  862.     tss_ptr->tss_eflags |= 1;
  863.     tss_ptr->tss_eax = errno;
  864.     return 0;
  865.   }
  866.   tss_ptr->tss_eax = r;
  867.   return 0;
  868. }
  869.  
  870. i_21_44()
  871. {
  872.   switch (tss_ptr->tss_eax & 0xff)
  873.   {
  874.     case 0x00:
  875.     case 0x01:
  876.     case 0x06:
  877.     case 0x07:
  878.       intr(0x21, &r);
  879.       tss_ptr->tss_edx = r.r_dx;
  880.       tss_ptr->tss_eax = r.r_ax;
  881.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  882.       return 0;
  883.     default:
  884.       return 1;
  885.   }
  886. }
  887.  
  888. tss2reg(struct REGPACK *r)
  889. {
  890.   r->r_ax = tss_ptr->tss_eax;
  891.   r->r_bx = tss_ptr->tss_ebx;
  892.   r->r_cx = tss_ptr->tss_ecx;
  893.   r->r_dx = tss_ptr->tss_edx;
  894.   r->r_si = tss_ptr->tss_esi;
  895.   r->r_di = tss_ptr->tss_edi;
  896.   r->r_flags = tss_ptr->tss_eflags;
  897.   r->r_ds = r->r_es = _DS;
  898. }
  899.  
  900. reg2tss(struct REGPACK *r)
  901. {
  902.   tss_ptr->tss_eax = r->r_ax;
  903.   tss_ptr->tss_ebx = r->r_bx;
  904.   tss_ptr->tss_ecx = r->r_cx;
  905.   tss_ptr->tss_edx = r->r_dx;
  906.   tss_ptr->tss_esi = r->r_si;
  907.   tss_ptr->tss_edi = r->r_di;
  908.   tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
  909. }
  910.