OSDN Git Service

ok
authorsparky4 <sparky4@cock.li>
Tue, 21 Jul 2015 01:22:46 +0000 (20:22 -0500)
committersparky4 <sparky4@cock.li>
Tue, 21 Jul 2015 01:22:46 +0000 (20:22 -0500)
new file:   16/EMS.BAS
modified:   src/lib/16_mm.c

16/EMS.BAS [new file with mode: 0644]
src/lib/16_mm.c

diff --git a/16/EMS.BAS b/16/EMS.BAS
new file mode 100644 (file)
index 0000000..a82b1be
--- /dev/null
@@ -0,0 +1,425 @@
+' Using EMS in QuickBASIC: Part 1 of 3\r
+' Source Code\r
+'\r
+' By Jon Petrosky (Plasma)\r
+' www.phatcode.net\r
+'\r
+' [Remember to start QB with the /L switch to enable interrupts]\r
+\r
+DEFINT A-Z\r
+'$DYNAMIC\r
+'$INCLUDE: 'QB.BI'\r
+\r
+DIM SHARED Regs AS RegTypeX\r
+DIM SHARED EMS.Error            'Holds the error code of the last operation\r
+\r
+DECLARE FUNCTION EMS.ErrorMsg$ ()\r
+DECLARE FUNCTION EMS.Init ()\r
+DECLARE FUNCTION EMS.Version$ ()\r
+DECLARE FUNCTION EMS.PageFrame ()\r
+DECLARE FUNCTION EMS.FreeHandles ()\r
+DECLARE FUNCTION EMS.FreePages ()\r
+DECLARE FUNCTION EMS.TotalPages ()\r
+DECLARE FUNCTION EMS.AllocPages (NumPages)\r
+DECLARE SUB EMS.DeallocPages (Handle)\r
+DECLARE SUB EMS.MapPage (Physical, Logical, Handle)\r
+DECLARE SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)\r
+DECLARE SUB EMS.CopyMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)\r
+DECLARE SUB EMS.ExchMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)\r
+\r
+CLS\r
+\r
+IF NOT EMS.Init THEN\r
+  PRINT "No EMM detected."\r
+  END\r
+END IF\r
+\r
+COLOR 14, 1\r
+PRINT SPACE$(22); "Using EMS in QuickBasic: Part 1 of 3"; SPACE$(22)\r
+COLOR 15, 0\r
+PRINT STRING$(31, 196); " EMS Information "; STRING$(32, 196)\r
+COLOR 7\r
+PRINT "EMM Version: "; EMS.Version$\r
+\r
+IF EMS.Version$ < "4.0" THEN\r
+  PRINT\r
+  PRINT "EMM 4.0 or later must be present to use some of the EMS functions."\r
+  END\r
+END IF\r
+\r
+PRINT "Page frame at: "; HEX$(EMS.PageFrame); "h"\r
+PRINT "Free handles:"; EMS.FreeHandles\r
+\r
+IF EMS.FreeHandles = 0 THEN\r
+  PRINT\r
+  PRINT "You need at least one free handle to run this demo."\r
+  END\r
+END IF\r
+\r
+PRINT "Total EMS:"; EMS.TotalPages; "pages /"; EMS.TotalPages * 16&; "KB /"; EMS.TotalPages \ 64; "MB"\r
+PRINT "Free EMS:"; EMS.FreePages; "pages /"; EMS.FreePages * 16&; "KB /"; EMS.FreePages \ 64; "MB"\r
+\r
+IF EMS.FreePages < 64 THEN\r
+  PRINT\r
+  PRINT "You need at least 64 pages (1 MB) free EMS to run this demo."\r
+  END\r
+END IF\r
+\r
+PRINT\r
+COLOR 15, 0\r
+PRINT STRING$(31, 196); " Allocation Test "; STRING$(32, 196)\r
+COLOR 7\r
+PRINT "Allocating 64 pages (1 MB) of EMS...";\r
+\r
+Handle = EMS.AllocPages(64)\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!"\r
+END IF\r
+\r
+PRINT "Pages allocated to handle"; Handle\r
+PRINT\r
+COLOR 15, 0\r
+PRINT STRING$(30, 196); " Page Map/Copy Test "; STRING$(30, 196)\r
+COLOR 7\r
+PRINT "Mapping logical page 0 to physical page 0...";\r
+\r
+EMS.MapPage 0, 0, Handle\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!"\r
+END IF\r
+\r
+PRINT "Mapping logical pages 0-3 to physical pages 0-3...";\r
+\r
+EMS.MapXPages 0, 0, 4, Handle\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!"\r
+END IF\r
+\r
+PRINT "Copying logical pages 0-31 to logical pages 32-63...";\r
+\r
+EMS.CopyMem 512288, Handle, 0, 0, Handle, 32, 0\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!"\r
+END IF\r
+\r
+PRINT "Exchanging logical pages 0-31 with logical pages 32-63...";\r
+\r
+EMS.ExchMem 512288, Handle, 0, 0, Handle, 32, 0\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!"\r
+END IF\r
+\r
+PRINT\r
+COLOR 15, 0\r
+PRINT STRING$(22, 196); " 10-Second Speed Test (Please Wait) "; STRING$(22, 196)\r
+COLOR 7\r
+\r
+Mapped& = 0\r
+StartTime! = TIMER\r
+DO UNTIL StartTime! + 5 <= TIMER\r
+  EMS.MapXPages 0, 0, 4, Handle\r
+  Mapped& = Mapped& + 4\r
+LOOP\r
+\r
+Copied& = 0\r
+StartTime! = TIMER\r
+DO UNTIL StartTime! + 5 <= TIMER\r
+  EMS.CopyMem 512288, Handle, 0, 0, Handle, 32, 0\r
+  Copied& = Copied& + 1\r
+LOOP\r
+\r
+PRINT "Pages Mapped/Sec:"; Mapped& \ 5\r
+PRINT "Bytes copied/Sec:"; (Copied& * 512288) \ 5\r
+PRINT\r
+COLOR 15, 0\r
+PRINT STRING$(30, 196); " Deallocation Test "; STRING$(31, 196)\r
+COLOR 7\r
+PRINT "Deallocating 64 pages...";\r
+\r
+EMS.DeallocPages (Handle)\r
+IF EMS.Error THEN\r
+  PRINT "error!"\r
+  PRINT EMS.ErrorMsg$\r
+  END\r
+ELSE\r
+  PRINT "ok!";\r
+END IF\r
+\r
+KeyPress$ = INPUT$(1)\r
+CLS\r
+END\r
+\r
+FUNCTION EMS.AllocPages (NumPages)\r
+\r
+  'Allocates the number of pages in [NumPages] and\r
+  'returns the EMS handle the memory is allocated to.\r
+\r
+  Regs.ax = &H4300                           'Allocate [NumPages] pages of EMS\r
+  Regs.bx = NumPages\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+  EMS.AllocPages = Regs.dx                   'Return the handle\r
+\r
+END FUNCTION\r
+\r
+SUB EMS.CopyMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)\r
+\r
+  'Copies memory from EMS or base memory to EMS or base memory, where:\r
+  '\r
+  'Length&    = Length of memory to copy in bytes\r
+  'SrcHandle  = EMS handle of source memory (use 0 if source is base memory)\r
+  'SrcSegment = Segment of source memory (or page number if source is EMS)\r
+  'SrcOffset  = Offset of source memory\r
+  'DstHandle  = EMS handle of destination memory (use 0 if destination is base memory)\r
+  'DstSegment = Segment of destination memory (or page number if destination is EMS)\r
+  'DstOffset  = Offset of destination memory\r
+\r
+  'Determine the source and destination memory types by checking the handles\r
+  IF SrcHandle = 0 THEN SrcType$ = CHR$(0) ELSE SrcType$ = CHR$(1)\r
+  IF DstHandle = 0 THEN DstType$ = CHR$(0) ELSE DstType$ = CHR$(1)\r
+\r
+  'Create a buffer containing the copy information\r
+  CopyInfo$ = MKL$(Length&) + SrcType$ + MKI$(SrcHandle) + MKI$(SrcOffset) + MKI$(SrcSegment) + DstType$ + MKI$(DstHandle) + MKI$(DstOffset) + MKI$(DstSegment)\r
+\r
+  Regs.ax = &H5700                           'Copy the memory region\r
+  Regs.ds = VARSEG(CopyInfo$)                'described in the buffer\r
+  Regs.si = SADD(CopyInfo$)\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+END SUB\r
+\r
+SUB EMS.DeallocPages (Handle)\r
+\r
+  'Deallocates the EMS pages allocated the EMS handle [Handle].\r
+  'You MUST remember to call the sub before your program ends\r
+  'if you allocate any memory!\r
+\r
+  Regs.ax = &H4500                           'Release the pages allocated to [Handle]\r
+  Regs.dx = Handle\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+END SUB\r
+\r
+FUNCTION EMS.ErrorMsg$\r
+\r
+  'Returns a text string describing the error code in EMS.Error.\r
+\r
+  SELECT CASE EMS.Error\r
+    CASE &H0: Msg$ = "successful"\r
+    CASE &H80: Msg$ = "internal error"\r
+    CASE &H81: Msg$ = "hardware malfunction"\r
+    CASE &H82: Msg$ = "busy -- retry later"\r
+    CASE &H83: Msg$ = "invalid handle"\r
+    CASE &H84: Msg$ = "undefined function requested by application"\r
+    CASE &H85: Msg$ = "no more handles available"\r
+    CASE &H86: Msg$ = "error in save or restore of mapping context"\r
+    CASE &H87: Msg$ = "insufficient memory pages in system"\r
+    CASE &H88: Msg$ = "insufficient memory pages available"\r
+    CASE &H89: Msg$ = "zero pages requested"\r
+    CASE &H8A: Msg$ = "invalid logical page number encountered"\r
+    CASE &H8B: Msg$ = "invalid physical page number encountered"\r
+    CASE &H8C: Msg$ = "page-mapping hardware state save area is full"\r
+    CASE &H8D: Msg$ = "save of mapping context failed"\r
+    CASE &H8E: Msg$ = "restore of mapping context failed"\r
+    CASE &H8F: Msg$ = "undefined subfunction"\r
+    CASE &H90: Msg$ = "undefined attribute type"\r
+    CASE &H91: Msg$ = "feature not supported"\r
+    CASE &H92: Msg$ = "successful, but a portion of the source region has been overwritten"\r
+    CASE &H93: Msg$ = "length of source or destination region exceeds length of region allocated to either source or destination handle"\r
+    CASE &H94: Msg$ = "conventional and expanded memory regions overlap"\r
+    CASE &H95: Msg$ = "offset within logical page exceeds size of logical page"\r
+    CASE &H96: Msg$ = "region length exceeds 1 MB"\r
+    CASE &H97: Msg$ = "source and destination EMS regions have same handle and overlap"\r
+    CASE &H98: Msg$ = "memory source or destination type undefined"\r
+    CASE &H9A: Msg$ = "specified alternate map register or DMA register set not supported"\r
+    CASE &H9B: Msg$ = "all alternate map register or DMA register sets currently allocated"\r
+    CASE &H9C: Msg$ = "alternate map register or DMA register sets not supported"\r
+    CASE &H9D: Msg$ = "undefined or unallocated alternate map register or DMA register set"\r
+    CASE &H9E: Msg$ = "dedicated DMA channels not supported"\r
+    CASE &H9F: Msg$ = "specified dedicated DMA channel not supported"\r
+    CASE &HA0: Msg$ = "no such handle name"\r
+    CASE &HA1: Msg$ = "a handle found had no name, or duplicate handle name"\r
+    CASE &HA2: Msg$ = "attempted to wrap around 1M conventional address space"\r
+    CASE &HA3: Msg$ = "source array corrupted"\r
+    CASE &HA4: Msg$ = "operating system denied access"\r
+    CASE ELSE: Msg$ = HEX$(EMS.Error) '"undefined error"\r
+  END SELECT\r
+\r
+  EMS.ErrorMsg$ = Msg$\r
+\r
+END FUNCTION\r
+\r
+SUB EMS.ExchMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)\r
+\r
+  'Exhanges memory from EMS or base memory to EMS or base memory, where:\r
+  '\r
+  'Length&    = Length of memory to exchange in bytes\r
+  'SrcHandle  = EMS handle of source memory (use 0 if source is base memory)\r
+  'SrcSegment = Segment of source memory (or page number if source is EMS)\r
+  'SrcOffset  = Offset of source memory\r
+  'DstHandle  = EMS handle of destination memory (use 0 if destination is base memory)\r
+  'DstSegment = Segment of destination memory (or page number if destination is EMS)\r
+  'DstOffset  = Offset of destination memory\r
+\r
+  'Determine the source and destination memory types by checking the handles\r
+  IF SrcHandle = 0 THEN SrcType$ = CHR$(0) ELSE SrcType$ = CHR$(1)\r
+  IF DstHandle = 0 THEN DstType$ = CHR$(0) ELSE DstType$ = CHR$(1)\r
+\r
+  'Create a buffer containing the copy information\r
+  ExchInfo$ = MKL$(Length&) + SrcType$ + MKI$(SrcHandle) + MKI$(SrcOffset) + MKI$(SrcSegment) + DstType$ + MKI$(DstHandle) + MKI$(DstOffset) + MKI$(DstSegment)\r
+\r
+  Regs.ax = &H5701                           'Exchange the memory region\r
+  Regs.ds = VARSEG(ExchInfo$)                'described in the buffer\r
+  Regs.si = SADD(ExchInfo$)\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+END SUB\r
+\r
+FUNCTION EMS.FreeHandles\r
+\r
+  'Returns the number of free (available) EMS handles.\r
+\r
+  Regs.ax = &H4B00                             'Get the # of handles in use\r
+  InterruptX &H67, Regs, Regs\r
+  UsedHandles = Regs.bx\r
+\r
+  Regs.ax = &H5402                             'Get the total # of handles\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100    'Store the status code\r
+  TotalHandles = Regs.bx\r
+\r
+  EMS.FreeHandles = TotalHandles - UsedHandles 'Subtract to get the # of free handles\r
+\r
+END FUNCTION\r
+\r
+FUNCTION EMS.FreePages\r
+\r
+  'Returns the number of free (available) EMS pages\r
+  '(Multiply by 16 to get the amount free EMS in KB.)\r
+\r
+  Regs.ax = &H4200                           'Get the # of free pages\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+  EMS.FreePages = Regs.bx\r
+\r
+END FUNCTION\r
+\r
+FUNCTION EMS.Init\r
+\r
+  'Returns true (-1) if an EMM is installed\r
+  'or false (0) if an EMM is not installed.\r
+\r
+  Regs.ax = &H3567                        'Get the interrupt vector for int 67h\r
+  InterruptX &H21, Regs, Regs\r
+  DEF SEG = Regs.es                       'Point to the interrupt segment\r
+  FOR x = 10 TO 17                        'Store the 8 bytes at ES:0A in EMM$\r
+    EMM$ = EMM$ + CHR$(PEEK(x))\r
+  NEXT\r
+  IF EMM$ <> "EMMXXXX0" THEN\r
+    EMS.Init = 0              'EMM not installed\r
+  ELSE\r
+    EMS.Init = -1             'EMM installed\r
+  END IF\r
+\r
+END FUNCTION\r
+\r
+SUB EMS.MapPage (Physical, Logical, Handle)\r
+\r
+  'Maps the logical EMS page [Logical] (allocated to the handle [Handle])\r
+  'to the physical page [Physical] in the EMS page frame.\r
+\r
+  Regs.ax = &H4400 + Physical                'Map the logical page [Logical]\r
+  Regs.bx = Logical                          'to the physical page [Physical]\r
+  Regs.dx = Handle\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+END SUB\r
+\r
+SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)\r
+\r
+  'Maps up to 4 logical EMS pages to physical pages in the page frame, where:\r
+  '\r
+  'PhysicalStart = Physical page first logical page is mapped to\r
+  'LogicalStart  = First logical page to map\r
+  'NumPages      = Number of pages to map (1 to 4)\r
+  'Handle        = EMS handle logical pages are allocated to\r
+\r
+  'Create a buffer containing the page information\r
+  FOR x = 0 TO NumPages - 1\r
+    MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)\r
+  NEXT\r
+\r
+  Regs.ax = &H5000                           'Map the pages in the buffer\r
+  Regs.cx = NumPages                         'to the pageframe\r
+  Regs.dx = Handle\r
+  Regs.ds = VARSEG(MapInfo$)\r
+  Regs.si = SADD(MapInfo$)\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+\r
+END SUB\r
+\r
+FUNCTION EMS.PageFrame\r
+\r
+  'Returns the segment of the EMS page frame\r
+\r
+  Regs.ax = &H4100                           'Get the segment of the page frame\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Save the status code\r
+  EMS.PageFrame = Regs.bx\r
+\r
+END FUNCTION\r
+\r
+FUNCTION EMS.TotalPages\r
+\r
+  'Returns the total number of EMS pages\r
+  '(Multiply by 16 to get the total amount of EMS in KB.)\r
+\r
+  Regs.ax = &H4200                           'Get the # of total pages\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Store the status code\r
+  EMS.TotalPages = Regs.dx\r
+\r
+END FUNCTION\r
+\r
+FUNCTION EMS.Version$\r
+\r
+  'Returns a string containing the EMM version.\r
+  '(Must be "4.0" or greater to use our routines.)\r
+\r
+  Regs.ax = &H4600                           'Get the EMM version\r
+  InterruptX &H67, Regs, Regs\r
+  EMS.Error = (Regs.ax AND &HFF00&) \ &H100  'Save the status code\r
+\r
+  Version = Regs.ax AND &HFF                 'Split the version number into\r
+  Major = (Version AND &HF0) \ &H10          'its major and minor counterparts\r
+  Minor = Version AND &HF\r
+  EMS.Version$ = LTRIM$(STR$(Major)) + "." + LTRIM$(STR$(Minor))\r
+\r
+END FUNCTION\r
+\r
index 78aa518..d6ce874 100644 (file)
@@ -313,10 +313,10 @@ void MM_MapXEMS(mminfo_t *mm)
        //NumPages      = Number of pages to map (1 to 4)\r
        //Handle        = EMS handle logical pages are allocated to\r
 \r
-  //Create a buffer containing the page information\r
+  /*//Create a buffer containing the page information\r
 //  FOR x = 0 TO NumPages - 1\r
 //    MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)\r
-//  NEXT\r
+//  NEXT*/\r
 \r
 //  Regs.ax = &H5000                           //Map the pages in the buffer\r
 //  Regs.cx = NumPages                         //to the pageframe\r