home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / djgpp / go32 / exphdlr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-30  |  16.9 KB  |  703 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. /* History:66,55 */
  16.  
  17. #include <process.h>
  18. #include <stdio.h>
  19. #include <dos.h>
  20. #include <sys/stat.h>
  21. #include <time.h>
  22. #include <errno.h>
  23. #include <fcntl.h>
  24.  
  25. #include "build.h"
  26. #include "types.h"
  27. #include "gdt.h"
  28. #include "idt.h"
  29. #include "tss.h"
  30. #include "utils.h"
  31. #include "paging.h"
  32. #include "npx.h"
  33. #include "mono.h"
  34.  
  35. #define SEGFAULT(p) { \
  36.   printf("Segmentation violation in pointer 0x%08lx\n", (p)); \
  37.   return 1; \
  38.   }
  39.  
  40. extern int was_user_int;
  41. char transfer_buffer[4096];    /* must be near ptr for small model */
  42.  
  43. word32 user_dta;
  44. static struct REGPACK r;
  45.  
  46. static word32 flmerge(word32 rf, word32 tf)
  47. {
  48.   return (rf & 0xcff) | (tf & 0xfffff300L);
  49. }
  50.  
  51. static set_controller(v)
  52. {
  53.   disable();
  54.   outportb(0x20, 0x11);
  55.   outportb(0x21, v);
  56.   outportb(0x21, 4);
  57.   outportb(0x21, 1);
  58.   enable();
  59. }
  60.  
  61. init_controllers()
  62. {
  63.   movedata(0, 0x08*4, 0, 0x78*4, 0x08*4);
  64.   set_controller(0x78);
  65. }
  66.  
  67. uninit_controllers()
  68. {
  69.   set_controller(0x08);
  70. }
  71.  
  72. extern int ctrl_c_flag;
  73.  
  74. exception_handler()
  75. {
  76.   int i;
  77. #if TOPLINEINFO
  78.   char buf[20];
  79.   sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
  80.   for (i=0; buf[i]; i++)
  81.     poke(screen_seg, i*2+80, buf[i] | 0x0600);
  82. #endif
  83.   i = tss_ptr->tss_irqn;
  84. /*  printf("i=%#02x, a0=%02x\n", i, inportb(0xa0)); */
  85.   if ((i>=0x70) && (i<0x7f) && (i != 0x75))
  86.   {
  87.     if (i<0x78)
  88.       intr(i, &r);
  89.     else
  90.       intr(i-0x70, &r);
  91.     if (i == 0x79)
  92.     {
  93.       r.r_ax = 0x0100;
  94.       intr(0x16, &r);
  95.       if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
  96.       {
  97.         _AH = 0;
  98.         geninterrupt(0x16);
  99.         ctrl_c_flag = 1;
  100.       }
  101.     }
  102.     if (ctrl_c_flag)
  103.     {
  104.       ctrl_c_flag = 0;
  105.       return 1;
  106.     }
  107.     return 0;
  108.   }
  109.   switch (i)
  110.   {
  111.     case 8:
  112.       printf("double fault!\n");
  113.       exit(1);
  114.     case 0:
  115.     case 1:
  116.     case 2:
  117.     case 3:
  118.     case 4:
  119.     case 5:
  120.     case 6:
  121.     case 9:
  122.     case 10:
  123.     case 11:
  124.     case 12:
  125.     case 13:
  126.     case 15:
  127.       return 1;
  128.     case 0x75:
  129.       return 1;
  130.     case 7:
  131.       printf("Fatal!  Application attempted to use not-present 80387!\n");
  132.       printf("Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
  133.       return 1;
  134.     case 14:
  135.       return page_in();
  136.  
  137.     case 0x10:
  138.       return i_10();
  139.     case 0x11:
  140.     case 0x12:
  141.     case 0x14:
  142.     case 0x16:
  143.     case 0x17:
  144.     case 0x1a:
  145.       return generic_handler();
  146.     case 0x21:
  147.       return i_21();
  148.     case 0x33:
  149.       return i_33();
  150.     default:
  151.       return 1;
  152.   }
  153. }
  154.  
  155. #if DEBUGGER
  156. static char flset[] = "VMRF  NT    OFDNIETFMIZR  AC  PE  CY";
  157. static char floff[] = "              UPID  PLNZ      PO  NC";
  158. static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
  159.  
  160. tssprint(TSS *t)
  161. {
  162.   int i;
  163.   printf("eax=%08lx  ebx=%08lx  ecx=%08lx  edx=%08lx\n",
  164.     t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
  165.   printf("esi=%08lx  edi=%08lx  ebp=%08lx ",
  166.     t->tss_esi, t->tss_edi, t->tss_ebp);
  167.   for (i=0; i<18; i++)
  168.     if (fluse[i])
  169.       if (t->tss_eflags & (1<<(17-i)))
  170.         printf(" %2.2s", flset+i*2);
  171.       else
  172.         printf(" %2.2s", floff+i*2);
  173.   printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
  174.     t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
  175. }
  176. #endif /* DEBUGGER */
  177.  
  178. int retrieve_string(word32 v, char *transfer_buffer, char tchar)
  179. {
  180.   int i;
  181.   char c;
  182.   for (i=0; i<4096; i++)
  183.   {
  184.     c = peek8(v);
  185.     v++;
  186.     transfer_buffer[i] = c;
  187.     if (c == tchar)
  188.       break;
  189.   }
  190.   return i+1; /* number of characters placed in buffer */
  191. }
  192.  
  193. static int old_text_mode = -1;
  194.  
  195. generic_handler()
  196. {
  197.   tss2reg(&r);
  198.   intr(tss_ptr->tss_irqn, &r);
  199.   reg2tss(&r);
  200.   return 0;
  201. }
  202.  
  203. i_10()
  204. {
  205.   if ((tss_ptr->tss_eax & 0xFF00) == 0xFF00)
  206.   {
  207.     graphics_mode(tss_ptr->tss_eax & 0xff);
  208.     return 0;
  209.   }
  210.   tss2reg(&r);
  211.   intr(0x10, &r);
  212.   reg2tss(&r);
  213.   tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
  214.   return 0;
  215. }
  216.  
  217. i_33()
  218. {
  219.   if (*((unsigned far *)0x000000CEL) == 0)
  220.     return 0;
  221.   r.r_ax = tss_ptr->tss_eax;
  222.   r.r_bx = tss_ptr->tss_ebx;
  223.   r.r_cx = tss_ptr->tss_ecx;
  224.   r.r_dx = tss_ptr->tss_edx;
  225.   intr(0x33, &r);
  226.   tss_ptr->tss_eax = r.r_ax;
  227.   tss_ptr->tss_ebx = r.r_bx;
  228.   tss_ptr->tss_ecx = r.r_cx;
  229.   tss_ptr->tss_edx = r.r_dx;
  230.   return 0;
  231. }
  232.  
  233. TSS last_tss;
  234.  
  235. i_21()
  236. {
  237.   word32 v, trans_total, countleft;
  238.   int i, c, ah, tchar, trans_count;
  239.   char *cp;
  240.   memcpy(&last_tss, tss_ptr, sizeof(TSS));
  241.   tss2reg(&r);
  242.   ah = (tss_ptr->tss_eax >> 8) & 0xff;
  243. #if 0
  244.   printf("int 21h ax=0x%04x bx=0x%04x cx=0x%04x dx=0x%04x\n",
  245.     (int)(tss_ptr->tss_eax),
  246.     (int)(tss_ptr->tss_ebx),
  247.     (int)(tss_ptr->tss_ecx),
  248.     (int)(tss_ptr->tss_edx)
  249.     );
  250. #endif
  251.   switch (ah)
  252.   {
  253.     case 1:
  254.     case 2:
  255.     case 3:
  256.     case 4:
  257.     case 5:
  258.     case 6:
  259.     case 7:
  260.     case 8:
  261.     case 0x0b:
  262.     case 0x2a:
  263.     case 0x2b:
  264.     case 0x2c:
  265.     case 0x2d:
  266.     case 0x33:
  267.     case 0x42:
  268.     case 0x45:
  269.     case 0x46:
  270.     case 0x57:
  271.     case 0x68:
  272.       intr(0x21, &r);
  273.       reg2tss(&r);
  274.       return 0;
  275.     case 0x3e:
  276. #if DEBUGGER
  277.       if (r.r_bx <= 2)
  278.         return 0;
  279. #endif
  280.       intr(0x21, &r);
  281.       reg2tss(&r);
  282.       return 0;
  283.     case 9:
  284.     case 0x39:
  285.     case 0x3a:
  286.     case 0x3b:
  287.     case 0x41:
  288.     case 0x43:
  289.       if (ah == 9)
  290.         tchar = '$';
  291.       else
  292.         tchar = 0;
  293.       v = tss_ptr->tss_edx + ARENA;
  294.       if (!page_is_valid(v))
  295.       {
  296.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  297.         return 1;
  298.       }
  299.       retrieve_string(v, transfer_buffer, tchar);
  300.       r.r_dx = FP_OFF(transfer_buffer);
  301.       r.r_ds = _DS;
  302.       intr(0x21, &r);
  303.       reg2tss(&r);
  304.       return 0;
  305.     case 0x3c:
  306.       v = tss_ptr->tss_edx + ARENA;
  307.       if (!page_is_valid(v))
  308.       {
  309.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  310.         return 1;
  311.       }
  312.       retrieve_string(v, transfer_buffer, 0);
  313.       i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
  314.       if (i < 0)
  315.       {
  316.         tss_ptr->tss_eax = errno;
  317.         tss_ptr->tss_eflags |= 1;
  318.       }
  319.       else
  320.       {
  321.         tss_ptr->tss_eax = i;
  322.         tss_ptr->tss_eflags &= ~1;
  323.       }
  324.       return 0;
  325.     case 0x3d:
  326.       v = tss_ptr->tss_edx + ARENA;
  327.       if (!page_is_valid(v))
  328.       {
  329.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  330.         return 1;
  331.       }
  332.       retrieve_string(v, transfer_buffer, 0);
  333.       i = tss_ptr->tss_eax & 0xf0;
  334.       if (tss_ptr->tss_eax & O_WRONLY) i &= 1;
  335.       if (tss_ptr->tss_eax & O_RDWR) i &= 2;
  336.       i = _open(transfer_buffer, i);
  337.       if (i < 0)
  338.       {
  339.         tss_ptr->tss_eax = errno;
  340.         tss_ptr->tss_eflags |= 1;
  341.       }
  342.       else
  343.       {
  344.         tss_ptr->tss_eax = i;
  345.         tss_ptr->tss_eflags &= ~1;
  346.       }
  347.       return 0;
  348.     case 0x1a:
  349.       user_dta = tss_ptr->tss_edx;
  350.       setdta((char far *)transfer_buffer);
  351.       return 0;
  352.     case 0x2f:
  353.       tss_ptr->tss_ebx = user_dta;
  354.       return 0;
  355.     case 0x30:
  356.       intr(0x21, &r);
  357.       reg2tss(&r);
  358.       return 0;
  359.     case 0x56:
  360.       v = tss_ptr->tss_edx + ARENA;
  361.       if (!page_is_valid(v))
  362.       {
  363.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  364.         return 1;
  365.       }
  366.       i = retrieve_string(v, transfer_buffer, 0);
  367.       r.r_dx = FP_OFF(transfer_buffer);
  368.       r.r_ds = _DS;
  369.       v = tss_ptr->tss_edi + ARENA;
  370.       retrieve_string(v, transfer_buffer+i, 0);
  371.       r.r_di = FP_OFF(transfer_buffer)+i;
  372.       r.r_es = _DS;
  373.       intr(0x21, &r);
  374.       tss_ptr->tss_eax = r.r_ax;
  375.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  376.       return 0;
  377.     case 0x3f:
  378.       trans_total = 0;
  379.       countleft = tss_ptr->tss_ecx;
  380.       v = tss_ptr->tss_edx;
  381.       if (!page_is_valid(v+ARENA))
  382.       {
  383.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  384.         return 1;
  385.       }
  386.       while (countleft > 0)
  387.       {
  388.         trans_count = (countleft <= 4096) ? countleft : 4096;
  389.         i = read(r.r_bx, transfer_buffer, trans_count);
  390.         if (i < 0)
  391.         {
  392.           tss_ptr->tss_eflags |= 1; /* carry */
  393.           tss_ptr->tss_eax = _doserrno;
  394.           return 0;
  395.         }
  396.         memput(v+ARENA, transfer_buffer, i);
  397.         trans_total += i;
  398.         v += i;
  399.         countleft -= i;
  400.         if (isatty(r.r_bx) && (i<trans_count))
  401.           break; /* they're line buffered */
  402.         if (i == 0)
  403.           break;
  404.       }
  405.       tss_ptr->tss_eax = trans_total;
  406.       tss_ptr->tss_eflags &= ~1;
  407.       return 0;
  408.     case 0x40:
  409.       trans_total = 0;
  410.       countleft = tss_ptr->tss_ecx;
  411.       if (countleft == 0)
  412.       {
  413.         r.r_ax = 0x4000;
  414.         r.r_cx = 0;
  415.         intr(0x21,&r);
  416.         tss_ptr->tss_eax = 0;
  417.         tss_ptr->tss_eflags &= ~1;
  418.         return 0;
  419.       }
  420.       v = tss_ptr->tss_edx;
  421.       if (!page_is_valid(v+ARENA))
  422.         SEGFAULT(v);
  423.       r.r_dx = (int)transfer_buffer;
  424.       while (countleft > 0)
  425.       {
  426.         trans_count = (countleft <= 4096) ? countleft : 4096;
  427.         memget(v+ARENA, transfer_buffer, trans_count);
  428.         i = write(r.r_bx, transfer_buffer, trans_count);
  429.         if (i<0) /* carry */
  430.         {
  431.           tss_ptr->tss_eflags |= 1; /* carry */
  432.           tss_ptr->tss_eax = _doserrno;
  433.           return 0;
  434.         }
  435.         trans_total += i;
  436.         v += i;
  437.         countleft -= i;
  438.         if (i < trans_count)
  439.           break;
  440.       }
  441.       tss_ptr->tss_eax = trans_total;
  442.       tss_ptr->tss_eflags &= ~1;
  443.       return 0;
  444.     case 0x44:
  445.       return i_21_44();
  446.     case 0x4e:
  447.       if (!page_is_valid(user_dta+ARENA))
  448.         SEGFAULT(user_dta);
  449.       v = tss_ptr->tss_edx + ARENA;
  450.       if (!page_is_valid(v))
  451.         SEGFAULT(v);
  452.       retrieve_string(v, transfer_buffer+43, 0);
  453.       r.r_dx = FP_OFF(transfer_buffer+43);
  454.       r.r_ds = _DS;
  455.       intr(0x21, &r);
  456.       reg2tss(&r);
  457.       for (i=20; i>=0; i--)
  458.         transfer_buffer[i+28] = transfer_buffer[i+26];
  459.       transfer_buffer[32+13] = 0; /* asciiz termination */
  460.       memput(user_dta+ARENA, transfer_buffer, 48);
  461.       return 0;
  462.     case 0x4f:
  463.       if (!page_is_valid(user_dta+ARENA))
  464.         SEGFAULT(user_dta);
  465.       memget(user_dta+ARENA, transfer_buffer, 48);
  466.       for (i=0; i<=20; i++)
  467.         transfer_buffer[i+26] = transfer_buffer[i+28];
  468.       intr(0x21, &r);
  469.       reg2tss(&r);
  470.       for (i=20; i>=0; i--)
  471.         transfer_buffer[i+28] = transfer_buffer[i+26];
  472.       transfer_buffer[32+13] = 0; /* asciiz termination */
  473.       memput(user_dta+ARENA, transfer_buffer, 48);
  474.       return 0;
  475.     case 0x47:
  476.       getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
  477.       for (cp=transfer_buffer; *cp; cp++)
  478.       {
  479.         if (*cp == '\\') *cp = '/';
  480.         *cp = tolower(*cp);
  481.       }
  482.       memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer));
  483.       tss_ptr->tss_eax = (unsigned)r.r_ax;
  484.       tss_ptr->tss_eflags &= ~1;
  485.       return 0;
  486.     case 0x4a:
  487.       if (tss_ptr->tss_eax & 0xff)
  488.         tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
  489.       else
  490.         tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
  491.       return 0;
  492.     case 0x4c:
  493. #if DEBUGGER
  494.       printf("Program exited normally, return code %d (0x%x)\n",
  495.              (int)(tss_ptr->tss_eax & 0xff), (int)(tss_ptr->tss_eax & 0xff));
  496.       return 1;
  497. #else
  498.       exit(tss_ptr->tss_eax & 0xff);
  499. #endif
  500.     case 0xff:
  501.       return turbo_assist();
  502.     default:
  503.       return 1;
  504.   }
  505. }
  506.  
  507. struct time32 {
  508.   word32 secs;
  509.   word32 usecs;
  510. };
  511.  
  512. struct tz32 {
  513.   word32 offset;
  514.   word32 dst;
  515. };
  516.  
  517. struct    stat32 {
  518.     short st_dev;
  519.     short st_ino;
  520.     short st_mode;
  521.     short st_nlink;
  522.     short st_uid;
  523.     short st_gid;
  524.     short st_rdev;
  525.     short st_align_for_word32;
  526.     long  st_size;
  527.     long  st_atime;
  528.     long  st_mtime;
  529.     long  st_ctime;
  530.     long  st_blksize;
  531. };
  532.  
  533. static int dev_count=1;
  534.  
  535. turbo_assist()
  536. {
  537.   word32 p1, p2, p3, r;
  538.   struct time32 time32;
  539.   struct tz32 tz32;
  540.   struct stat32 statbuf32;
  541.   struct stat statbuf;
  542.   int i;
  543.  
  544.   char buf[128];
  545.   p1 = tss_ptr->tss_ebx;
  546.   p2 = tss_ptr->tss_ecx;
  547.   p3 = tss_ptr->tss_edx;
  548.   switch (tss_ptr->tss_eax & 0xff)
  549.   {
  550.     case 1:
  551.       retrieve_string(p1+ARENA, buf, 0);
  552.       r = creat(buf, S_IREAD | S_IWRITE);
  553.       break;
  554.     case 2:
  555.       retrieve_string(p1+ARENA, buf, 0);
  556.       r = open(buf, (int)p2, S_IREAD | S_IWRITE);
  557.       break;
  558.     case 3:
  559.       memset(&statbuf, 0, sizeof(statbuf));
  560.       r = fstat((int)p1, &statbuf);
  561.       statbuf32.st_dev = dev_count++;
  562.       statbuf32.st_ino = statbuf.st_ino;
  563.       statbuf32.st_mode = statbuf.st_mode;
  564.       statbuf32.st_nlink = statbuf.st_nlink;
  565.       statbuf32.st_uid = statbuf.st_uid;
  566.       statbuf32.st_gid = statbuf.st_gid;
  567.       statbuf32.st_rdev = statbuf.st_rdev;
  568.       statbuf32.st_size = statbuf.st_size;
  569.       statbuf32.st_atime = statbuf.st_atime;
  570.       statbuf32.st_mtime = statbuf.st_mtime;
  571.       statbuf32.st_ctime = statbuf.st_ctime;
  572.       statbuf32.st_blksize = 512;
  573.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  574.       break;
  575.     case 4:
  576.       if (p2)
  577.       {
  578.         if (!page_is_valid(p2+ARENA))
  579.           SEGFAULT(p2);
  580.         tz32.offset = timezone;
  581.         tz32.dst = daylight;
  582.         memput(p2+ARENA, &tz32, sizeof(tz32));
  583.       }
  584.       if (p1)
  585.       {
  586.         if (!page_is_valid(p1+ARENA))
  587.           SEGFAULT(p1);
  588.         time(&(time32.secs));
  589.         _AH = 0x2c;
  590.         geninterrupt(0x21);
  591.         time32.usecs = _DL * 10000L;
  592.         memput(p1+ARENA, &time32, sizeof(time32));
  593.       }
  594.       r = 0;
  595.       break;
  596.     case 5:
  597.       if (p2)
  598.       {
  599.         if (!page_is_valid(p2+ARENA))
  600.           SEGFAULT(p2);
  601.         memget(p2+ARENA, &tz32, sizeof(tz32));
  602.         timezone = tz32.offset;
  603.         daylight = tz32.dst;
  604.       }
  605.       if (p1)
  606.       {
  607.         if (!page_is_valid(p1+ARENA))
  608.           SEGFAULT(p1);
  609.         memget(p1+ARENA, &time32, sizeof(time32));
  610.         stime(&(time32.secs));
  611.       }
  612.       r = 0;
  613.       break;
  614.     case 6:
  615.       memset(&statbuf, 0, sizeof(statbuf));
  616.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  617.       r = stat(transfer_buffer, &statbuf);
  618.       statbuf32.st_dev = dev_count++;
  619.       statbuf32.st_ino = statbuf.st_ino;
  620.       statbuf32.st_mode = statbuf.st_mode;
  621.       statbuf32.st_nlink = statbuf.st_nlink;
  622.       statbuf32.st_uid = statbuf.st_uid;
  623.       statbuf32.st_gid = statbuf.st_gid;
  624.       statbuf32.st_rdev = statbuf.st_rdev;
  625.       statbuf32.st_size = statbuf.st_size;
  626.       statbuf32.st_atime = statbuf.st_atime;
  627.       statbuf32.st_mtime = statbuf.st_mtime;
  628.       statbuf32.st_ctime = statbuf.st_ctime;
  629.       statbuf32.st_blksize = 512;
  630.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  631.       break;
  632.     case 7:
  633.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  634.       page_out_everything();
  635.       uninit_controllers();
  636.       sscanf(transfer_buffer, "%s%n", buf, &i);
  637.       if (strpbrk(transfer_buffer, "<>|") == NULL)
  638.         r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
  639.       else
  640.         r = -1;
  641.       if (r & 0x80000000L)
  642.         r = system(transfer_buffer);
  643.       init_controllers();
  644.       page_in_everything();
  645.       break;
  646.     case 8:
  647.       r = setmode((int)p1, (int)p2);
  648.       break;
  649.     default:
  650.       return 1;
  651.   }
  652.   tss_ptr->tss_eflags &= ~1;
  653.   if (r == -1)
  654.   {
  655.     tss_ptr->tss_eflags |= 1;
  656.     tss_ptr->tss_eax = errno;
  657.     return 0;
  658.   }
  659.   tss_ptr->tss_eax = r;
  660.   return 0;
  661. }
  662.  
  663. i_21_44()
  664. {
  665.   switch (tss_ptr->tss_eax & 0xff)
  666.   {
  667.     case 0x00:
  668.     case 0x01:
  669.     case 0x06:
  670.     case 0x07:
  671.       intr(0x21, &r);
  672.       tss_ptr->tss_edx = r.r_dx;
  673.       tss_ptr->tss_eax = r.r_ax;
  674.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  675.       return 0;
  676.     default:
  677.       return 1;
  678.   }
  679. }
  680.  
  681. tss2reg(struct REGPACK *r)
  682. {
  683.   r->r_ax = tss_ptr->tss_eax;
  684.   r->r_bx = tss_ptr->tss_ebx;
  685.   r->r_cx = tss_ptr->tss_ecx;
  686.   r->r_dx = tss_ptr->tss_edx;
  687.   r->r_si = tss_ptr->tss_esi;
  688.   r->r_di = tss_ptr->tss_edi;
  689.   r->r_flags = tss_ptr->tss_eflags;
  690.   r->r_ds = r->r_es = _DS;
  691. }
  692.  
  693. reg2tss(struct REGPACK *r)
  694. {
  695.   tss_ptr->tss_eax = r->r_ax;
  696.   tss_ptr->tss_ebx = r->r_bx;
  697.   tss_ptr->tss_ecx = r->r_cx;
  698.   tss_ptr->tss_edx = r->r_dx;
  699.   tss_ptr->tss_esi = r->r_si;
  700.   tss_ptr->tss_edi = r->r_di;
  701.   tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
  702. }
  703.