home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tvision / dpmi / clib / dpmish.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-24  |  16.5 KB  |  668 lines

  1. //=====================================================================
  2. //
  3. //  dpmish.cpp
  4. //
  5. //  dos protected mode interface manager class
  6. //
  7. //  Copyright (c) 1994, Kevin Morgan, All rights reserved.
  8. //
  9. //  Parts of this were loosely based on routines 
  10. //  from Al Williams book: "DOS and Windows Protected Mode"
  11. //
  12. //=====================================================================
  13.  
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <dos.h>
  17. #include "dpmish.h"
  18.  
  19.  
  20. //=====================================================================
  21. //
  22. // DpmiApplication::fail
  23. //
  24. //=====================================================================
  25. void DpmiApplication::fail(const char *s, ...)
  26.     puts(s);
  27.     dosExit(1);
  28. }
  29.  
  30. //===================================================================
  31. //
  32. // DpmiApplication::dosExit
  33. //
  34. //===================================================================
  35. void DpmiApplication::dosExit(int retval)
  36. {
  37.     asm {
  38.         mov ah, 04ch
  39.         mov al, byte ptr retval
  40.         int 21h
  41.     }
  42. }
  43.  
  44.  
  45. //===================================================================
  46. //
  47. // DpmiApplication::present(void)
  48. //
  49. // Call the DPMI Mode Detection function (INT 2fh AX=1686h) to see
  50. // if we are already running in protected mode under DPMI.
  51. //
  52. //===================================================================
  53. int DpmiApplication::present(void)
  54. {
  55.     unsigned _ax;
  56.     asm mov ax, 1686h
  57.     asm int 2fh
  58.     asm mov _ax, ax    // returns zero if DPMI is present
  59.     return (!_ax);      // turn it around so WE return 0 if *not* present
  60. }
  61.  
  62.  
  63. //===================================================================
  64. // DpmiApplication::init(void)
  65. //
  66. // Call the DPMI function for Obtaining the Real to Protected Mode Switch
  67. // Entry Point (INT 2Fh AX=1687h), to determine if DPMI is available
  68. // and, if so, switch into protected mode by calling the Switch Entry Point.
  69. // See DPMI 0.9 spec.
  70. //
  71. // 
  72. //===================================================================
  73. int DpmiApplication::init(void)
  74. {
  75.     void (far *dpmi)();
  76.     static unsigned hostdata_seg;
  77.     unsigned hostdata_para, dpmi_flags;
  78.     asm {
  79.         push si
  80.         push di
  81.         mov ax, 1687h              // test for DPMI presence
  82.         int 2fh
  83.         and ax,ax
  84.         jz gotdpmi                 // AX==0 means DPMI is present
  85.         jmp nodpmi
  86.     }
  87. gotdpmi:
  88.     asm {
  89.         mov dpmi_flags, bx
  90.         mov hostdata_para, si      // save paras for DPMI host private data
  91.         mov word ptr dpmi, di
  92.         mov word ptr dpmi+2, es    // save DPMI protected mode switch entry point
  93.         pop di
  94.         pop si
  95.     }
  96.     if (_dos_allocmem(hostdata_para, &hostdata_seg)!=0)
  97.         fail("can't allocate memory");
  98.  
  99.     dpmi_flags &= ~1;               // this is a 16-bit protected mode program
  100.  
  101.     // enter protected mode
  102.     asm {
  103.         mov ax, hostdata_seg
  104.         mov es, ax
  105.         mov ax, dpmi_flags
  106.     }
  107.     (*dpmi)();
  108.     asm jc nodpmi                  // carry set if error
  109.  
  110.     // we should be in protected mode now.
  111.     // Note that segment registers have changed.
  112.  
  113.     return present();          // double check
  114. nodpmi:
  115.     return 0;
  116. }
  117.  
  118.  
  119. //===================================================================
  120. //
  121. // DpmiApplication::makeDescriptor
  122. //
  123. //===================================================================
  124. void _far *DpmiApplication::makeDescriptor(unsigned segaddr)
  125. {
  126.     void _far *p;
  127.     asm {
  128.         mov ax, 0002h
  129.         mov bx, segaddr
  130.         int 31h
  131.         jc  dpmierr
  132.         mov word ptr p+2, ax
  133.         mov word ptr p, 0
  134.     }
  135.     return p;
  136. dpmierr:
  137.     return 0;
  138. }
  139.  
  140. //===================================================================
  141. //
  142. // DpmiApplication::getVersion
  143. //
  144. //===================================================================
  145. int DpmiApplication::getVersion(int& maj, int& min, int& flags)
  146. {
  147.     char aMaj, aMin;
  148.     int aFlags;
  149.     asm {
  150.         mov ax, 0400h
  151.         int 31h
  152.         jc nodpmi
  153.         mov aMaj, ah
  154.         mov aMin, al
  155.         mov aFlags, bx
  156.     }
  157.     maj = aMaj;
  158.     min = aMin;
  159.     flags = aFlags;
  160.     return 0;
  161. nodpmi:
  162.     return 1;
  163. }
  164.  
  165. //===================================================================
  166. //
  167. // DpmiApplication::getCapabilities
  168. //
  169. //===================================================================
  170. int DpmiApplication::getCapabilities(char _far *buf, int& aFlags)
  171. {
  172.     int flags;   
  173.     asm {
  174.         mov ax, 0401h
  175.         mov di, word ptr buf
  176.         mov ax, word ptr buf+2
  177.         mov es, ax
  178.         int 31h
  179.         jc nodpmi
  180.         mov flags, ax
  181.     }
  182.     aFlags = flags;
  183.     return DPMI_OK;
  184. nodpmi:
  185.     return DPMI_ERR;
  186. }
  187.  
  188. //===================================================================
  189. //
  190. // DpmiApplication::allocateMemory
  191. //
  192. //===================================================================
  193. int DpmiApplication::allocateMemory(long sz,  long& addr, long & handle)
  194. {
  195.     long p;
  196.     long hand;
  197.     asm {
  198.         mov    ax, 0501h
  199.         mov cx, word ptr sz
  200.         mov bx, word ptr sz+2
  201.         int 31h          // call dpmi to allocate memory
  202.         jc  nomem
  203.         mov word ptr p, cx
  204.         mov word ptr p+2, bx
  205.         mov word ptr hand, di
  206.         mov word ptr hand+2, si
  207.     }
  208.     addr = p;
  209.     handle = hand;
  210.     return DPMI_OK;
  211. nomem:
  212.     return DPMI_ERR;
  213. }
  214.  
  215. //===================================================================
  216. //
  217. // DpmiApplication::allocateLdtDescriptors
  218. //
  219. //===================================================================
  220. int DpmiApplication::allocateLdtDescriptors(int nSelectors,  unsigned& baseSelector)
  221. {
  222.     asm {
  223.         mov    ax, 0000h
  224.         mov cx, nSelectors
  225.         int 31h          // call dpmi to allocate descriptors
  226.         jc  failed
  227.     }
  228.     baseSelector = _AX;
  229.     return DPMI_OK;
  230. failed:
  231.     errcode = _AX;
  232.     return DPMI_ERR;
  233. }
  234.  
  235. //===================================================================
  236. //
  237. // DpmiApplication::createAlias(unsigned csIn, unsigned& dsOut)
  238. //
  239. //===================================================================
  240. int DpmiApplication::createAlias(unsigned csIn, unsigned& dsOut)
  241. {
  242.     asm {
  243.         mov    ax, 000ah
  244.         mov bx, csIn
  245.         int 31h          // call dpmi to allocate descriptors
  246.         jc  failed
  247.     }
  248.     dsOut = _AX;
  249.     return DPMI_OK;
  250. failed:
  251.     errcode = _AX;
  252.     return DPMI_ERR;
  253. }
  254.  
  255. //===================================================================
  256. //
  257. // DpmiApplication::freeSelector(unsigned selector)
  258. //
  259. //===================================================================
  260. int DpmiApplication::freeSelector(unsigned selector)
  261. {
  262.     asm {
  263.         mov    ax, 0001h
  264.         mov bx, selector
  265.         int 31h          // call dpmi to allocate descriptors
  266.         jc  failed
  267.     }
  268.     return DPMI_OK;
  269. failed:
  270.     errcode = _AX;
  271.     return DPMI_ERR;
  272. }
  273.  
  274. //===================================================================
  275. //
  276. // DpmiApplication::getSelectorIncrementValue
  277. //
  278. //===================================================================
  279. int DpmiApplication::getSelectorIncrementValue(unsigned& incr)
  280. {
  281.     asm {
  282.         mov    ax, 0003h
  283.         int 31h          // call dpmi to determine selector increment
  284.         jc  failed
  285.     }
  286.     incr = _AX;
  287.     return DPMI_OK;
  288. failed:
  289.     errcode = _AX;
  290.     return DPMI_ERR;
  291. }
  292.  
  293. //===================================================================
  294. //
  295. // DpmiApplication::setSelectorBase
  296. //
  297. //===================================================================
  298. int DpmiApplication::setSelectorBase(unsigned selector,  long addr)
  299. {
  300.     asm {
  301.         mov    ax, 0007h
  302.         mov bx, selector
  303.         mov dx, word ptr addr
  304.         mov cx, word ptr addr+2
  305.         int 31h          // call dpmi to allocate memory
  306.         jc  failed
  307.     }
  308.     return DPMI_OK;
  309. failed:
  310.     errcode = _AX;
  311.     return DPMI_ERR;
  312. }
  313.  
  314. //===================================================================
  315. //
  316. // DpmiApplication::setSelectorLimit
  317. //
  318. //===================================================================
  319. int DpmiApplication::setSelectorLimit(unsigned selector,  long addr)
  320. {
  321.     asm {
  322.         mov    ax, 0008h
  323.         mov bx, selector
  324.         mov dx, word ptr addr
  325.         mov cx, word ptr addr+2
  326.         int 31h          // call dpmi to set selector base
  327.         jc  failed
  328.     }
  329.     return DPMI_OK;
  330. failed:
  331.     errcode = _AX;
  332.     return DPMI_ERR;
  333. }
  334.  
  335. //===================================================================
  336. //
  337. // DpmiApplication::setAccessRights
  338. //
  339. //===================================================================
  340. int DpmiApplication::setAccessRights(unsigned selector,  int rights)
  341. {
  342.     asm {
  343.         mov    ax, 0009h
  344.         mov bx, selector
  345.         mov cx, rights
  346.         int 31h          // call dpmi to set selector base
  347.         jc  failed
  348.     }
  349.     return DPMI_OK;
  350. failed:
  351.     errcode = _AX;
  352.     printf("set access rights error: 0x%04x\n", errcode);
  353.     return DPMI_ERR;
  354. }
  355.  
  356.  
  357. //===================================================================
  358. //
  359. // DpmiApplication::getExceptionHandler
  360. //
  361. //===================================================================
  362. DpmiInterruptVector DpmiApplication::getExceptionHandler(int intno)
  363. {
  364.     DpmiInterruptVector func;
  365.     asm {
  366.         mov ax, 0202h
  367.         mov bl, byte ptr intno
  368.         int 31h
  369.         mov word ptr func, dx
  370.         mov word ptr func+2, cx
  371.     }
  372.     return func;
  373. }
  374.  
  375. //===================================================================
  376. //
  377. // DpmiApplication::setExceptionHandler
  378. //
  379. //===================================================================
  380. void DpmiApplication::setExceptionHandler(int intno, DpmiInterruptVector func)
  381. {
  382.     asm {
  383.         mov ax, 0203h
  384.         mov bl, byte ptr intno
  385.         mov cx, word ptr func+2
  386.         mov dx, word ptr func
  387.         int 31h
  388.     }
  389. }
  390.  
  391. //===================================================================
  392. //
  393. // DpmiApplication::getProtVect
  394. //
  395. //===================================================================
  396. DpmiInterruptVector DpmiApplication::getProtVect(int intno)
  397. {
  398.     DpmiInterruptVector func;
  399.     asm {
  400.         mov ax, 0204h
  401.         mov bl, byte ptr intno
  402.         int 31h
  403.         mov word ptr func+2, cx
  404.         mov word ptr func, dx
  405.     }
  406.     return func;
  407. }
  408.  
  409. //===================================================================
  410. //
  411. // DpmiApplication::setProtVect
  412. //
  413. //===================================================================
  414. void DpmiApplication::setProtVect(int intno, DpmiInterruptVector func)
  415. {
  416.     asm {
  417.         mov ax, 0205h
  418.         mov bl, byte ptr intno
  419.         mov cx, word ptr func+2
  420.         mov dx, word ptr func
  421.         int 31h
  422.     }
  423. }
  424.  
  425. //===================================================================
  426. //
  427. // DpmiApplication::getRealVect
  428. //
  429. //===================================================================
  430. DpmiInterruptVector DpmiApplication::getRealVect(int intno)
  431. {
  432.     DpmiInterruptVector func;
  433.     asm {
  434.         mov ax, 0200h
  435.         mov bl, byte ptr intno
  436.         int 31h
  437.         mov word ptr func+2, cx
  438.         mov word ptr func, dx
  439.     }
  440.     return func;
  441. }
  442.  
  443. //===================================================================
  444. //
  445. // DpmiApplication::setRealVect
  446. //
  447. //===================================================================
  448. void DpmiApplication::setRealVect(int intno, DpmiInterruptVector func)
  449. {
  450.         asm {
  451.             mov ax, 0201h
  452.             mov bl, byte ptr intno
  453.             mov cx, word ptr func+2
  454.             mov dx, word ptr func
  455.             int 31h
  456.         }
  457. }
  458.  
  459. //===================================================================
  460. //
  461. // DpmiApplication::getMappedMemory
  462. //
  463. //===================================================================
  464. int DpmiApplication::getMappedMemory(long unsigned memSize, unsigned& selector, unsigned accessRights)
  465. {
  466.     int res;
  467.     long handle, linear;
  468.  
  469.     res = Dpmi.allocateLdtDescriptors(1,  selector);
  470.     if (res!=0) {
  471.         return DPMI_ERR;
  472.     }
  473.  
  474.     // now allocate and map memory
  475.  
  476.     res = Dpmi.allocateMemory(memSize, linear, handle);
  477.     if (res!=DPMI_OK) return DPMI_ERR;
  478.  
  479.     if (accessRights==AccessRightsStack) {
  480.         res = Dpmi.setSelectorBase(selector, linear+memSize);
  481.         if (res!=DPMI_OK) return DPMI_ERR;
  482.  
  483.         res = Dpmi.setSelectorLimit(selector, 0x10000l-memSize);
  484.         if (res!=DPMI_OK) return DPMI_ERR;
  485.     }
  486.     else {
  487.         res = Dpmi.setSelectorBase(selector, linear);
  488.         if (res!=DPMI_OK) return DPMI_ERR;
  489.  
  490.         res = Dpmi.setSelectorLimit(selector, memSize);
  491.         if (res!=DPMI_OK) return DPMI_ERR;
  492.     }
  493.     res = Dpmi.setAccessRights(selector, accessRights);
  494.     if (res!=DPMI_OK) return DPMI_ERR;
  495.     return DPMI_OK;
  496. }
  497.  
  498.  
  499. //===================================================================
  500. //
  501. // DpmiApplication::simulateRealInterrupt
  502. //
  503. //===================================================================
  504. int DpmiApplication::simulateRealInterrupt(unsigned intno, DPMI_Regs *regs)
  505. {
  506.     asm {
  507.         mov ax, 0300h
  508.         mov bl, byte ptr intno  
  509.         mov bh, 0       // 
  510.         mov cx, 0       // number of words to copy to real mode stack
  511.         mov es, word ptr regs+2
  512.         mov di, word ptr regs
  513.         int 31h
  514.         jc  failed
  515.     }
  516.     return DPMI_OK;
  517. failed:
  518.     errcode = _AX;
  519.     printf("simulateRealInterrupt error: 0x%04x\n", errcode);
  520.     return DPMI_ERR;
  521. }
  522.  
  523.  
  524. //===================================================================
  525. //
  526. // DpmiApplication::allocateDosMemory
  527. //
  528. //===================================================================
  529. int DpmiApplication::allocateDosMemory(unsigned nPara, unsigned& para, unsigned& selector)
  530. {
  531.     asm {
  532.         mov ax, 0100h
  533.         mov bx, nPara
  534.         int 31h
  535.         jc failed
  536.     }
  537.     para = _AX;
  538.     selector = _DX;
  539.     return DPMI_OK;
  540. failed:
  541.     errcode = _AX;
  542.     printf("allocateDosMemory error: 0x%04x\n", errcode);
  543.     return DPMI_ERR;
  544. }
  545.  
  546. //===================================================================
  547. //
  548. // DpmiApplication::freeDosMemory
  549. //
  550. //===================================================================
  551. int DpmiApplication::freeDosMemory(unsigned selector)
  552. {
  553.     asm {
  554.         mov ax, 0101h
  555.         mov dx, selector
  556.         int 31h
  557.         jc failed
  558.     }
  559.     return DPMI_OK;
  560. failed:
  561.     errcode = _AX;
  562.     printf("freeDosMemory error: 0x%04x\n", errcode);
  563.     return DPMI_ERR;
  564. }
  565.  
  566. //===================================================================
  567. //
  568. // DpmiApplication::mapDosMemory
  569. //
  570. //===================================================================
  571. int DpmiApplication::mapDosMemory(unsigned para, unsigned long sz, unsigned& selector)
  572. {
  573.     int res = Dpmi.allocateLdtDescriptors(1, selector);
  574.     if (res!=DPMI_OK) return DPMI_ERR;
  575.  
  576.     long linear = ((unsigned long) para) << 4;
  577.  
  578.     res = Dpmi.setSelectorBase(selector, linear);
  579.     if (res!=DPMI_OK) return DPMI_ERR;
  580.  
  581.     res = Dpmi.setSelectorLimit(selector, sz);
  582.     if (res!=DPMI_OK) return DPMI_ERR;
  583.  
  584.     res = Dpmi.setAccessRights(selector, AccessRightsData);
  585.     if (res!=DPMI_OK) return DPMI_ERR;
  586.     return DPMI_OK;
  587. }
  588.  
  589. //===================================================================
  590. //
  591. // DpmiApplication::lockMemory
  592. //
  593. //===================================================================
  594. int DpmiApplication::lockMemory(long addr,  long sz)
  595. {
  596.     asm {
  597.         mov bx, word ptr addr+2
  598.         mov cx, word ptr addr
  599.         mov si, word ptr sz+2
  600.         mov di, word ptr sz
  601.         mov ax, 0600h
  602.         int 31h
  603.         jc failed
  604.     }
  605.     return DPMI_OK;
  606. failed:
  607.     errcode = _AX;
  608.     return DPMI_ERR;
  609. }
  610.  
  611. //===================================================================
  612. //
  613. // DpmiApplication::unlockMemory
  614. //
  615. //===================================================================
  616. int DpmiApplication::unlockMemory(long addr,  long sz)
  617. {
  618.     asm {
  619.         mov bx, word ptr addr+2
  620.         mov cx, word ptr addr
  621.         mov si, word ptr sz+2
  622.         mov di, word ptr sz
  623.         mov ax, 0601h
  624.         int 31h
  625.         jc failed
  626.     }
  627.     return DPMI_OK;
  628. failed:
  629.     errcode = _AX;
  630.     return DPMI_ERR;
  631. }
  632.  
  633.  
  634.  
  635. //===================================================================
  636. //
  637. // DpmiApplication::allocateRealCallback
  638. //
  639. //===================================================================
  640. int DpmiApplication::allocateRealCallback(
  641.     DpmiInterruptVector protFunc,
  642.     DPMI_Regs far *callBlock,
  643.     DpmiInterruptVector& callBack)
  644. {
  645.     DpmiInterruptVector res;
  646.     asm {
  647.         push ds
  648.         mov ds, word ptr protFunc+2
  649.         mov si, word ptr protFunc
  650.         mov es, word ptr callBlock+2
  651.         mov di, word ptr callBlock
  652.         mov ax, 0303h
  653.         int 31h
  654.         pop ds
  655.         jc failed
  656.         mov word ptr res+2, cx
  657.         mov word ptr res,   dx
  658.     }
  659.     callBack = res;
  660.     return DPMI_OK;
  661. failed:
  662.     errcode = _AX;
  663.     return DPMI_ERR;
  664. }
  665.  
  666.  
  667.