home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / msc7.zip / SEGMENT.CPP < prev    next >
C/C++ Source or Header  |  1992-02-12  |  10KB  |  591 lines

  1. // (c) Copyright 1992, Qualitas, Inc. All Rights Reserved
  2. //
  3. // segment.cpp - member functions for AbstractSegment and related classes
  4. //
  5.  
  6. #include "dpmi.h"
  7. #include "segment.h"
  8.  
  9. boolean addProp(selector_t selector, SegmentProp_t prop);
  10. boolean removeProp(selector_t selector, SegmentProp_t prop);
  11.  
  12. //
  13. // Constructor for Block class
  14. //
  15. Block::Block(uLong requestedSize)
  16. {
  17.     if (DPMIAllocateMemory(size=requestedSize, &base, &handle) != 0)
  18.     {
  19.         size = 0;
  20.         base = 0;
  21.         handle = 0;
  22.     }
  23. }
  24.  
  25. //
  26. // Destructor for Block class
  27. //
  28. Block::~Block(void)
  29. {
  30.     DPMIFreeMemory(handle);
  31. }
  32.  
  33.  
  34. //
  35. // Resize a Block
  36. //
  37. boolean Block::setSize(uLong requestedSize)
  38. {
  39.     if (DPMIResizeMemory(&handle, requestedSize, &base) != 0)
  40.         return FALSE;
  41.     else
  42.     {
  43.         size = requestedSize;
  44.         return TRUE;
  45.     }
  46. }
  47.  
  48. //
  49. // Get segment size from DPMI host
  50. // 
  51. uLong AbstractSegment::segmentSize(void)
  52. {
  53.     uLong s;
  54.     
  55.     if (DPMIGetSegmentLimit(selector, &s) == 0)
  56.         return s+1;
  57.     else
  58.         return 0;
  59. }
  60.  
  61. //
  62. // Get segment base from DPMI host
  63. //
  64. uLong AbstractSegment::segmentBase(void)
  65. {
  66.     uLong b;
  67.     
  68.     if (DPMIGetSegmentBase(selector, &b) == 0)
  69.         return b;
  70.     else
  71.         return 0;
  72. }
  73.  
  74. //
  75. // Query DPMI host for segment properties
  76. //
  77. boolean AbstractSegment::queryProp(SegmentProp_t prop)
  78. {
  79.     uChar arb;
  80.     uChar arb386;
  81.     
  82.     if (DPMIGetSegmentAttributes(selector, &arb, &arb386) != 0)
  83.         return FALSE;
  84.     
  85.     else switch (prop)
  86.     {
  87.     case present:
  88.         if (arb & 0x80)
  89.             return TRUE;
  90.         else
  91.             return FALSE;
  92.  
  93.     case executable:
  94.         if (arb & 0x8)
  95.             return TRUE;
  96.         else
  97.             return FALSE;
  98.  
  99.     case readable:
  100.     case writable:
  101.         if (arb & 0x2)
  102.             return TRUE;
  103.         else
  104.             return FALSE;
  105.     case big:
  106.         if (arb386 & 0x40)
  107.             return TRUE;
  108.         else
  109.             return FALSE;
  110.     default:
  111.         return FALSE;
  112.     }
  113. }
  114.  
  115. //
  116. // Constructor for Segment
  117. //
  118. Segment::Segment(void)
  119. {
  120.     if (DPMIAllocateDescriptors(1, &selector) != 0)
  121.         selector = 0;
  122. }
  123.  
  124. //
  125. // Constructor for Segment - specific descriptor method
  126. //
  127. Segment::Segment(selector_t specific)
  128. {
  129.     struct descriptor_t descriptor;
  130.  
  131.     if (DPMIAllocateSpecificDescriptor(specific) != 0)
  132.         selector = 0;
  133.     else
  134.     {// 386MAX does not set up specific descriptors
  135.         selector = specific;
  136.         DPMIGetDescriptor(selector, &descriptor);
  137.         descriptor.descArb &= ~0x60;
  138.         descriptor.descArb |= 0x82 + ((theCodeSel & 3) << 5);
  139.         DPMISetDescriptor(selector, &descriptor);
  140.     }
  141. }
  142.  
  143. //
  144. // Constructor for Segment - alias descriptor method
  145. //
  146. Segment::Segment(AbstractSegment& segment) 
  147. {
  148.     if (DPMIAllocateDescriptors(1, &selector) != 0)
  149.         selector = 0;
  150.     else
  151.     {
  152.         resize((uShort)segment.segmentSize());
  153.         move(segment.segmentBase());
  154.     }
  155. }
  156.  
  157. //
  158. // Destructor for Segment
  159. //
  160. Segment::~Segment(void)
  161. {
  162.     DPMIFreeDescriptor(selector);
  163. }
  164.  
  165.  
  166. //
  167. // Add property to Segment
  168. //
  169. boolean Segment::operator+(SegmentProp_t prop)
  170. {
  171.     return addProp(selector, prop);
  172. }
  173.  
  174. //
  175. // Remove property from Segment
  176. //
  177. boolean Segment::operator-(SegmentProp_t prop)
  178. {
  179.     return removeProp(selector, prop);
  180. }
  181.  
  182. //
  183. // Resize a Segment
  184. //
  185. boolean Segment::resize(uShort newSize)
  186. {
  187.     uLong size;
  188.     
  189.     if (newSize == 0)
  190.         size = 0x10000;
  191.     else
  192.         size = newSize;
  193.     
  194.  
  195.     if (DPMISetSegmentLimit(selector, size-1) == 0)
  196.         return TRUE;
  197.     else
  198.         return FALSE;
  199. }
  200.  
  201. //
  202. // Change the base of a Segment
  203. //
  204. boolean Segment::move(uLong newBase)
  205. {
  206.     if (DPMISetSegmentBase(selector, newBase) == 0)
  207.         return TRUE;
  208.     else
  209.         return FALSE;
  210. }
  211.  
  212. //
  213. // Constructor for CommonRealSegment
  214. // 
  215. CommonRealSegment::CommonRealSegment(uShort paragraph)
  216. {
  217.     if (DPMIParaToSelector(paragraph, &selector) != 0)
  218.         selector = 0;
  219. }
  220.  
  221.  
  222.  
  223. //
  224. // Constructor for DOSMemory
  225. //
  226. DOSMemory::DOSMemory(uShort nParas)
  227. {
  228.     uShort maxParas;
  229.     uShort paraBase;
  230.  
  231.     if (DPMIAllocateDOSMemory(nParas, ¶Base, &selector, &maxParas)!=0)
  232.         selector = 0;
  233. }
  234.  
  235. //
  236. // Destructor for DOSMemory
  237. //
  238. DOSMemory::~DOSMemory(void)
  239. {
  240.     DPMIFreeDOSMemory(selector);
  241. }
  242.  
  243. //
  244. // Resize a DOSMemory
  245. //
  246. boolean DOSMemory::resize(uShort nParas)
  247. {
  248.     uShort maxParas;
  249.  
  250.     if (DPMIResizeDOSMemory(selector, nParas, &maxParas) != 0)
  251.         return FALSE;
  252.     else
  253.         return TRUE;
  254. }
  255.  
  256.  
  257. //
  258. // Constructor for MemorySegment
  259. //
  260. MemorySegment::MemorySegment(uShort s) : Block(s==0 ? 0x10000L:(uLong)s)
  261. {
  262.     if (base == 0)
  263.     {
  264.         if (selector)
  265.             DPMIFreeDescriptor(selector);
  266.         selector = 0;
  267.     }
  268.     else
  269.     {
  270.         DPMISetSegmentBase(selector, base);
  271.         DPMISetSegmentLimit(selector, size-1);
  272.     }
  273. }
  274.  
  275.  
  276. //
  277. // Constructor for MemorySegment - specific descriptor method
  278. //
  279. MemorySegment::MemorySegment(uShort s, selector_t sel):
  280.             Block(s==0 ? 0x10000L:(uLong)s), Segment(sel)
  281. {
  282.     DPMISetSegmentBase(selector, base);
  283.     DPMISetSegmentLimit(selector, size-1);
  284. }
  285.  
  286.  
  287. //
  288. // Get size of memory segment
  289. //
  290. uLong MemorySegment::segmentSize(void)
  291. {
  292.     return blockSize();
  293. }
  294.  
  295. //
  296. // Resize a memory segment
  297. //
  298. boolean MemorySegment::resize(uShort newSize)
  299. {
  300.  
  301.     uLong lSize = newSize ? newSize:0x10000L;
  302.  
  303.     if (DPMIResizeMemory(&handle, lSize, &base) != 0)
  304.         return FALSE;
  305.  
  306.     if (DPMISetSegmentLimit(selector, lSize-1) != 0)
  307.     {
  308.         DPMIResizeMemory(&handle, size, &base);
  309.         return FALSE;
  310.     }
  311.     else
  312.     {
  313.         size = lSize;
  314.         return TRUE;
  315.     }
  316. }
  317.  
  318. //
  319. // Constructor for HugeSegment
  320. //
  321. HugeSegment::HugeSegment(uLong requestedSize)
  322. {
  323.     int i;
  324.     selector_t sel;
  325.  
  326.     if (requestedSize == 0)
  327.     {
  328.         abstractSize = 0;
  329.         nDescriptors = 0;
  330.         selector = 0;
  331.         return;
  332.     }
  333.     
  334.  
  335.     // compute the number of descriptors required to span the 
  336.     // requested size
  337.  
  338.     nDescriptors = (requestedSize-1)/0x10000 + 1;
  339.     
  340.     if (DPMIAllocateDescriptors(nDescriptors, &selector) != 0)
  341.     {
  342.         abstractSize = 0;
  343.         nDescriptors = 0;
  344.         selector = 0;
  345.         return;
  346.     }
  347.  
  348.     abstractSize = requestedSize;
  349.  
  350.  
  351.     // loop for each descriptor, sets limit and base
  352.  
  353.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  354.     {
  355.         if (requestedSize > 0x10000)
  356.             DPMISetSegmentLimit(sel, 0xffff);
  357.         else
  358.             DPMISetSegmentLimit(sel, requestedSize-1);
  359.  
  360.         requestedSize -= 0x10000;
  361.     }
  362. }
  363.  
  364. //
  365. // Destructor for HugeSegmnet - frees each descriptor
  366. //
  367. HugeSegment::~HugeSegment(void)
  368. {
  369.     int i;
  370.     selector_t sel;
  371.     
  372.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  373.         DPMIFreeDescriptor(sel);
  374. }
  375.  
  376. //
  377. // Change the base of a HugeSegment
  378. //
  379. boolean HugeSegment::move(uLong newBase)
  380. {
  381.     int i;
  382.     selector_t sel;
  383.     
  384.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  385.     {
  386.         if (DPMISetSegmentBase(sel, newBase) != 0)
  387.             return FALSE;
  388.  
  389.         newBase += 0x10000;
  390.     };
  391.  
  392.     return TRUE;
  393. }
  394.  
  395. //
  396. // Resize a huge segment - short size specified
  397. //
  398. boolean HugeSegment::resize(uShort newShortSize)
  399. {
  400.     // call long resize
  401.     return resize(newShortSize ? (uLong)newShortSize : (uLong)0x10000L);
  402. }
  403.  
  404.  
  405. //
  406. // Resize a huge segment - long size specified
  407. //
  408. boolean HugeSegment::resize(uLong newSize)
  409. {
  410.     selector_t sel;
  411.     int i;
  412.     int newDescCount;
  413.  
  414.  
  415.     newDescCount = (newSize-1)/0x10000 + 1;
  416.  
  417.     if (newDescCount > nDescriptors)    // cannot grow 
  418.         return FALSE;
  419.  
  420.     if (newDescCount < nDescriptors)
  421.     {
  422.         // release descriptors no longer needed
  423.  
  424.         sel=selector+(nDescriptors-1)*DPMIGetSelectorDelta();
  425.  
  426.         for (i=nDescriptors-newDescCount; i > 0; i--)
  427.         {
  428.             DPMIFreeDescriptor(sel);
  429.             sel -= DPMIGetSelectorDelta();
  430.         }
  431.     }
  432.  
  433.     nDescriptors = newDescCount;
  434.     abstractSize = newSize;
  435.  
  436.  
  437.     // for each descriptor, reset base and size
  438.  
  439.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  440.     {
  441.         if (newSize > 0x10000)
  442.             DPMISetSegmentLimit(sel, 0xffff);
  443.         else
  444.             DPMISetSegmentLimit(sel, newSize-1);
  445.  
  446.         newSize -= 0x10000;
  447.     }
  448.  
  449.     return TRUE;
  450. }
  451.  
  452.  
  453. //
  454. // Add property to HugeSegmnet
  455. //
  456. boolean HugeSegment::operator+(SegmentProp_t prop)
  457. {
  458.     selector_t sel;
  459.     int i;
  460.     
  461.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  462.         if (addProp(sel, prop) != TRUE)
  463.             return FALSE;
  464.         
  465.     return TRUE;
  466. }
  467.  
  468.  
  469.  
  470. //
  471. // Remove property from HugeSegmnet
  472. //
  473. boolean HugeSegment::operator-(SegmentProp_t prop)
  474. {
  475.     selector_t sel;
  476.     int i;
  477.     
  478.     for (i=0,sel=selector;i<nDescriptors; i++,sel+=DPMIGetSelectorDelta())
  479.         if (removeProp(sel, prop) != TRUE)
  480.             return FALSE;
  481.         
  482.     return TRUE;
  483. }
  484.  
  485.  
  486. boolean addProp(selector_t selector, SegmentProp_t prop)
  487. {
  488.     uChar arb;
  489.     uChar arb386;
  490.  
  491.     if (DPMIGetSegmentAttributes(selector, &arb, &arb386) != 0)
  492.         return FALSE;
  493.     
  494.     else switch (prop)
  495.     {
  496.     case present:
  497.         arb |= 0x80; break;
  498.  
  499.     case executable:
  500.         arb |= 0x8; break;
  501.  
  502.     case readable:
  503.     case writable:
  504.         arb |= 0x2; break;
  505.  
  506.     case big:
  507.         arb386 |= 0x40; break;
  508.         
  509.     default:
  510.         return FALSE;
  511.     }
  512.     
  513.     if (DPMISetSegmentAttributes(selector, arb, arb386) != 0)
  514.         return FALSE;
  515.     else
  516.         return TRUE;
  517. }
  518.  
  519.  
  520.  
  521. boolean removeProp(selector_t selector, SegmentProp_t prop)
  522. {
  523.     uChar arb;
  524.     uChar arb386;
  525.  
  526.     if (DPMIGetSegmentAttributes(selector, &arb, &arb386) != 0)
  527.         return FALSE;
  528.     
  529.     else switch (prop)
  530.     {
  531.     case present:
  532.         arb &= ~0x80; break;
  533.  
  534.     case executable:
  535.         arb &= ~0x8; break;
  536.  
  537.     case readable:
  538.     case writable:
  539.         arb &= ~0x2; break;
  540.  
  541.     case big:
  542.         arb386 &= ~0x40; break;
  543.         
  544.     default:
  545.         return FALSE;
  546.     }
  547.     
  548.     if (DPMISetSegmentAttributes(selector, arb, arb386) != 0)
  549.         return FALSE;
  550.     else
  551.         return TRUE;
  552. }
  553.  
  554. //
  555. // Constructor for HugeMemorySegment
  556. //
  557. HugeMemorySegment::HugeMemorySegment(uLong requestedSize) :
  558.             Block(requestedSize), 
  559.             HugeSegment(requestedSize)
  560. {
  561.     HugeSegment::move(base);
  562. }
  563.  
  564. //
  565. // Resize HugeMemorySegment - short arg
  566. //
  567. boolean HugeMemorySegment::resize(uShort newShortSize)
  568. {
  569.     return resize(newShortSize ? (uLong)newShortSize : (uLong)0x10000L);
  570. }
  571.  
  572.  
  573. //
  574. // Resize HugeMemorySegment - long arg
  575. //
  576. boolean HugeMemorySegment::resize(uLong newSize)
  577. {
  578.     uLong oldSize = size;
  579.  
  580.     if (Block::setSize(newSize) == FALSE)
  581.         return FALSE;
  582.  
  583.     if (HugeSegment::resize(newSize) == FALSE)
  584.     {
  585.         Block::setSize(oldSize);
  586.         return FALSE;
  587.     }
  588.     else
  589.         return TRUE;
  590. }
  591.