From: sparky4 <sparky4@cock.li>
Date: Tue, 21 Jul 2015 01:22:46 +0000 (-0500)
Subject: ok
X-Git-Url: http://4ch.mooo.com/gitweb/?a=commitdiff_plain;h=cb6c00f1a3dc82e68b0b35d4dcaf92fc47c14671;p=16.git

ok
	new file:   16/EMS.BAS
	modified:   src/lib/16_mm.c
---

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