home *** CD-ROM | disk | FTP | other *** search
/ Internet MPEG Audio Archive / IMAA.mdf / util / dos / l3v100n / rsx / source / start32.c < prev    next >
C/C++ Source or Header  |  1994-01-19  |  10KB  |  295 lines

  1. /* This file is START32.C
  2. **
  3. ** contains :
  4. **
  5. **              - DPMI-switches for DPMI 0.9
  6. **        - init some protected mode interrupts
  7. **        - init exception handlers
  8. **        - clean up for exit
  9. **
  10. ** Copyright (c) Rainer Schnitker 91,92,93
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <malloc.h>
  15. #include "DPMI.H"
  16. #include "DPMIDOS.H"
  17. #include "PROCESS.H"
  18. #include "RSX.H"
  19. #include "ADOSX32.H"
  20. #include "CDOSX32.H"
  21. #include "EXCEP32.H"
  22. #include "START32.H"
  23.  
  24. /* global extender segments,selectors */
  25. WORD cs16real, ds16real;    /* 16-bit segments for extender */
  26. WORD code16sel, data16sel;    /* 16-bit cs,ds for extender */
  27. WORD stack16sel;        /* 16-bit stack sel */
  28. DWORD stackp16;            /* 16-bit stack offset */
  29. WORD sel_incr;            /* increment to next selector */
  30. WORD dosmem_sel;        /* selector for the first MB */
  31. char dpmi10 = 0;
  32.  
  33. /* private vars */
  34. static WORD DPMIdata_para_needed = 0;
  35. static WORD DPMIdata_segm_address = 0;
  36.  
  37. extern WORD _psp;        /* new psp after switch to protmode */
  38.  
  39. /*
  40. ** back to real-mode, terminate ( int0x21 must set to orginal )
  41. */
  42. void protected_to_real(WORD errorlevel)
  43. {
  44.     DpmiDisableFpu();
  45.  
  46.     dos_exit(errorlevel);
  47.     /* program ends here */
  48. }
  49.  
  50. int real_to_protected(WORD mode)
  51. {
  52.     WORD stackp;
  53.     WORD DPMIflags, DPMIversion;
  54.     BYTE processor;
  55.     DWORD PM_jump;        /* switch to protmode jump */
  56.  
  57.     cs16real = GetCS();        /* save real mode segments */
  58.     ds16real = GetDS();        /* for real mode calls */
  59.  
  60.     clearregs();
  61.  
  62.     if (GetDpmiEntryPoint(&PM_jump, &DPMIdata_para_needed,
  63.               &DPMIflags, &DPMIversion, &processor)) {
  64.     puts("No DPMI-host found!");
  65.     return -1;
  66.     }
  67.     if (mode == 1 && !(DPMIflags & 1)) {
  68.     puts("32bit programs not supported\n");
  69.     return -1;
  70.     }
  71.     if (DPMIdata_para_needed) {    /* get DPMI ring 0 stack */
  72.     DPMIdata_segm_address = GetDpmiHostParagraph(DPMIdata_para_needed);
  73.     if (!DPMIdata_segm_address) {
  74.         puts("Can't alloc memory for the DPMI-host-stack");
  75.         return -1;
  76.     }
  77.     }
  78.     if (DpmiEnterProtectedMode(PM_jump, mode, DPMIdata_segm_address)) {
  79.     puts("can't switch to Protected Mode");
  80.     return -1;
  81.     }
  82.     /* Now we are in Protected Mode */
  83.  
  84.     code16sel = GetCS();
  85.     data16sel = stack16sel = GetDS();
  86.     _psp = GetES();
  87.     stackp16 = (WORD) & stackp;
  88.  
  89.     clearregs();
  90.  
  91.     if (copro) {
  92.     if (DpmiEnableFpu(copro)) {
  93.         puts("No DPMI-server 387 support");
  94.         puts("use -e option");
  95.         protected_to_real(1);
  96.     }
  97.     }
  98.     /* to catch a missing 387 we must do this */
  99.     else
  100.     DpmiEnableFpu(3);
  101.  
  102.     sel_incr = SelInc();
  103.     /* build selector for first megabyte */
  104.     AllocLDT(1, &dosmem_sel);
  105.     SetBaseAddress(dosmem_sel, 0L);
  106.     SetAccess(dosmem_sel, APP_DATA_SEL, BIG_BIT | GRANULAR_BIT);
  107.     SetLimit(dosmem_sel, 1024L * 1024L - 1L);
  108.  
  109.  
  110.     /* lock all program memory and memory for locked DPMI-stack */
  111.     LockLinRegion((DWORD) cs16real << 4,
  112.           ((DWORD) (ds16real - cs16real) << 4) + 0x10000L);
  113.     LockLinRegion((DWORD) DPMIdata_segm_address << 4,
  114.           (DWORD) DPMIdata_para_needed << 4);
  115.  
  116.     if ((DPMIversion >> 8) >= 1)
  117.     dpmi10 = 1;
  118.  
  119.     if (opt_printall) {
  120.     printf("DPMI version %d,%d\n", DPMIversion >> 8, DPMIversion & 0xff);
  121.     printf("CPU 80%d86\n", processor);
  122.     printf("16bit real_seg: cs=%04X ds=%04X\n"
  123.            ,cs16real, ds16real);
  124.     printf("16bit prot_sel: cs=%04X ds=%04X ss=%04X es=%04X\n"
  125.            ,code16sel, data16sel, stack16sel, _psp);
  126.     printf("DPMI stack: segment=%04X size=%04X\n"
  127.            ,DPMIdata_segm_address, DPMIdata_para_needed << 4);
  128.     printf("sel increment: %d\n", sel_incr);
  129.     }
  130.     return 0;
  131. }
  132.  
  133. static POINTER16_32 int21v;    /* old int21h handler address */
  134. static POINTER16_32 ctrlcv;    /* old control-c handler */
  135. static POINTER16_32 timerv;    /* old timer handler */
  136. static POINTER16_32 debintv;    /* old int3 handler */
  137.  
  138. extern void debug_entry(void);
  139.  
  140. typedef struct {
  141.     DWORD off;
  142.     WORD sel;
  143. } PWORD;
  144. PWORD criterrv;            /* old critical error handler */
  145.  
  146. static POINTER16_32 excep0v, excep1v, excep2v, excep3v, excep4v, excep5v, excep6v,
  147.  excep7v, excep8v, excep9v, excep10v, excep11v, excep12v, excep13v, excep14v,
  148.  excep15v, excep16v, excep17v;
  149.  
  150. int hangin_extender(void)
  151. {
  152.     WORD alias_cs;        /* alias sel for codesel */
  153.     WORD far *write_cs_word;    /* writing in code */
  154.     DWORD far *write_cs_dword;
  155.  
  156.     /* store ds-sel in code for some interrupt handler */
  157.     if (CreatAlias(code16sel, &alias_cs))    /* get alias for cs */
  158.     return -1;
  159.  
  160.     /* store 16bit data selector in load_ds function */
  161.     write_cs_word = MK_FP(alias_cs, (WORD) load_ds + 2);
  162.     *write_cs_word = data16sel;
  163.  
  164.     /* hang in int 0x21 */
  165.     if (GetProtModeVector32(0x21, &int21v.sel, &int21v.off) == -1) {
  166.     puts("error:can't get int21");
  167.     return -1;
  168.     }
  169.     if (SetProtModeVector32(0x21, code16sel, (DWORD) (WORD) doscall) == -1) {
  170.     puts("error:can't SET int21");
  171.     return -1;
  172.     }
  173.     align_iobuf();
  174.  
  175.     /* if we want to chain to default int 0x21 */
  176.     write_cs_dword = MK_FP(alias_cs, (WORD) int21vsel);
  177.     *write_cs_dword = int21v.sel;
  178.     write_cs_dword = MK_FP(alias_cs, (WORD) int21voff);
  179.     *write_cs_dword = int21v.off;
  180.  
  181.     FreeLDT(alias_cs);
  182.  
  183.     /* get all exception vectors */
  184.     GetExceptionVector32(0, &excep0v.sel, &excep0v.off);
  185.     GetExceptionVector32(1, &excep1v.sel, &excep1v.off);
  186.     GetExceptionVector32(2, &excep2v.sel, &excep2v.off);
  187.     GetExceptionVector32(3, &excep3v.sel, &excep3v.off);
  188.     GetExceptionVector32(4, &excep4v.sel, &excep4v.off);
  189.     GetExceptionVector32(5, &excep5v.sel, &excep5v.off);
  190.     GetExceptionVector32(6, &excep6v.sel, &excep6v.off);
  191.     GetExceptionVector32(7, &excep7v.sel, &excep7v.off);
  192.     GetExceptionVector32(8, &excep8v.sel, &excep8v.off);
  193.     GetExceptionVector32(9, &excep9v.sel, &excep9v.off);
  194.     GetExceptionVector32(10, &excep10v.sel, &excep10v.off);
  195.     GetExceptionVector32(11, &excep11v.sel, &excep11v.off);
  196.     GetExceptionVector32(12, &excep12v.sel, &excep12v.off);
  197.     GetExceptionVector32(13, &excep13v.sel, &excep13v.off);
  198.     GetExceptionVector32(14, &excep14v.sel, &excep14v.off);
  199.     GetExceptionVector32(15, &excep15v.sel, &excep15v.off);
  200.     GetExceptionVector32(16, &excep16v.sel, &excep16v.off);
  201.     GetExceptionVector32(17, &excep17v.sel, &excep17v.off);
  202.  
  203.     /* set all exception vectors */
  204.     SetExceptionVector32(0, code16sel, (DWORD) FP_LO(excep0_386));
  205.     SetExceptionVector32(1, code16sel, (DWORD) FP_LO(excep1_386));
  206.     SetExceptionVector32(2, code16sel, (DWORD) FP_LO(excep2_386));
  207.     SetExceptionVector32(3, code16sel, (DWORD) FP_LO(excep3_386));
  208.     SetExceptionVector32(4, code16sel, (DWORD) FP_LO(excep4_386));
  209.     SetExceptionVector32(5, code16sel, (DWORD) FP_LO(excep5_386));
  210.     SetExceptionVector32(6, code16sel, (DWORD) FP_LO(excep6_386));
  211.     SetExceptionVector32(7, code16sel, (DWORD) FP_LO(excep7_386));
  212.     SetExceptionVector32(8, code16sel, (DWORD) FP_LO(excep8_386));
  213.     SetExceptionVector32(9, code16sel, (DWORD) FP_LO(excep9_386));
  214.     SetExceptionVector32(10, code16sel, (DWORD) FP_LO(excep10_386));
  215.     SetExceptionVector32(11, code16sel, (DWORD) FP_LO(excep11_386));
  216.     SetExceptionVector32(12, code16sel, (DWORD) FP_LO(excep12_386));
  217.     SetExceptionVector32(13, code16sel, (DWORD) FP_LO(excep13_386));
  218.     SetExceptionVector32(14, code16sel, (DWORD) FP_LO(excep14_386));
  219.     SetExceptionVector32(15, code16sel, (DWORD) FP_LO(excep15_386));
  220.     SetExceptionVector32(16, code16sel, (DWORD) FP_LO(excep16_386));
  221.     SetExceptionVector32(17, code16sel, (DWORD) FP_LO(excep17_386));
  222.  
  223.     /* TIMER */
  224.     GetProtModeVector32(0x1C, &timerv.sel, &timerv.off);
  225.     SetProtModeVector32(0x1C, code16sel, (DWORD) (WORD) timer_handler);
  226.  
  227.     /* CTRL-C */
  228.     GetProtModeVector32(0x23, &ctrlcv.sel, &ctrlcv.off);
  229.     SetProtModeVector32(0x23, code16sel, (DWORD) (WORD) prot_cbrk);
  230.  
  231.     /* debug int3 */
  232.     GetProtModeVector32(0x03, &debintv.sel, &debintv.off);
  233.     SetProtModeVector32(0x03, code16sel, (DWORD) (WORD) debug_entry);
  234.     return 0;
  235. }
  236.  
  237. /* clean up interrupt handlers, exceptions, memory ... */
  238. void clean_up(void)
  239. {
  240.     fflush(stdin);
  241.     fflush(stdout);
  242.     fflush(stderr);
  243.  
  244.     clearregs();
  245.  
  246.     if (opt_printall)
  247.     puts("cleanup now");
  248.  
  249.     UnlockLinRegion((DWORD) cs16real << 4,
  250.             ((DWORD) (ds16real - cs16real) << 4) + 0x10000L);
  251.     UnlockLinRegion((DWORD) DPMIdata_segm_address << 4,
  252.             (DWORD) DPMIdata_para_needed << 4);
  253.  
  254.     /* unset 387-usage (otherwise: crash) */
  255.     if (copro) {
  256.     DpmiDisableFpu();
  257.     }
  258.     /* free 387 emulator */
  259.     if (copro == 3 && emu_sel != 0) {
  260.     UnlockLinRegion(RSX_PROCESS.memaddress, RSX_PROCESS.membytes);
  261.     if (rsx387_in_dosmem)
  262.         FreeDosMem((WORD) RSX_PROCESS.memhandle);
  263.     else
  264.         FreeMem(RSX_PROCESS.memhandle);
  265.     FreeLDT(RSX_PROCESS.code32sel);
  266.     FreeLDT(RSX_PROCESS.data32sel);
  267.     FreeLDT(RSX_PROCESS.data32sel + sel_incr);
  268.     }
  269.     copro = 0;
  270.  
  271.     SetProtModeVector32(0x21, int21v.sel, int21v.off);
  272.     SetProtModeVector32(0x1C, timerv.sel, timerv.off);
  273.     SetProtModeVector32(0x23, ctrlcv.sel, ctrlcv.off);
  274.     SetProtModeVector32(0x03, debintv.sel, debintv.off);
  275.  
  276.     SetExceptionVector32(0, excep0v.sel, excep0v.off);
  277.     SetExceptionVector32(1, excep1v.sel, excep1v.off);
  278.     SetExceptionVector32(2, excep2v.sel, excep2v.off);
  279.     SetExceptionVector32(3, excep3v.sel, excep3v.off);
  280.     SetExceptionVector32(4, excep4v.sel, excep4v.off);
  281.     SetExceptionVector32(5, excep5v.sel, excep5v.off);
  282.     SetExceptionVector32(6, excep6v.sel, excep6v.off);
  283.     SetExceptionVector32(7, excep7v.sel, excep7v.off);
  284.     SetExceptionVector32(8, excep8v.sel, excep8v.off);
  285.     SetExceptionVector32(9, excep9v.sel, excep9v.off);
  286.     SetExceptionVector32(10, excep10v.sel, excep10v.off);
  287.     SetExceptionVector32(11, excep11v.sel, excep11v.off);
  288.     SetExceptionVector32(12, excep12v.sel, excep12v.off);
  289.     SetExceptionVector32(13, excep13v.sel, excep13v.off);
  290.     SetExceptionVector32(14, excep14v.sel, excep14v.off);
  291.     SetExceptionVector32(15, excep15v.sel, excep15v.off);
  292.     SetExceptionVector32(16, excep16v.sel, excep16v.off);
  293.     SetExceptionVector32(17, excep17v.sel, excep17v.off);
  294. }
  295.