home *** CD-ROM | disk | FTP | other *** search
- Page 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- T P X M S v1.00
-
- for Turbo Pascal v4.0 and above
-
- Extended Memory Routines for HIMEM.SYS
-
- Vernon E. Davis, Jr.
-
- 07/30/89
- Page 2
-
-
-
-
-
- Index ................................................. Page 2
- Introduction to the XMS Specification ................. Page 3
- Introduction to TPXMS.TPU ............................. Page 4
- Type Declarations in TPXMS.TPU
- Bit32Struct ........................................ Page 5
- ExtMemMoveStruct ................................... Page 5
- EMBHandleStruct .................................... Page 6
- UMBSegmentStruct ................................... Page 6
- Variable Declarations in TPXMS.TPU
- isXMS .............................................. Page 7
- XMSResult .......................................... Page 7
- XMSError ........................................... Page 7
- XMM_Control ........................................ Page 7
- High Memory Routines
- Procedure GetMemHMA ................................ Page 8
- Procedure FreeMemHMA ............................... Page 8
- Extended Memory Routines
- Procedure QueryFreeMemXMS .......................... Page 9
- Procedure QueryFreeBlockXMS ........................ Page 9
- Function AllocExtMemBlockXMS ...................... Page 9
- Procedure FreeExtMemBlockXMS ....................... Page 9
- Procedure MoveExtMemBlockXMS ....................... Page 9
- Function LockExtMemBlockXMS ....................... Page 10
- Procedure UnlockExtMemBlockXMS ..................... Page 10
- Procedure EMBHandleInfoXMS ......................... Page 10
- Procedure ReallocExtMemBlockXMS .................... Page 10
- Upper Memory Routines
- Procedure ReqUpperMemBlockUMB ...................... Page 11
- Procedure RelUpperMemBlockUMB ...................... Page 11
- Miscellaneous Routines
- Function XMSErrorMsg .............................. Page 12
- Function ExistXMS ................................. Page 12
- Procedure GetVerHiMem .............................. Page 12
- Procedure GetRevHiMem .............................. Page 12
- Procedure GlobalEnableA20 .......................... Page 12
- Procedure GlobalDisableA20 ......................... Page 12
- Procedure LocalEnableA20 ........................... Page 12
- Procedure LocalDisableA20 .......................... Page 12
- Procedure QueryA20 ................................. Page 12
-
- Appendix A
- Reading and Writing to the High Memory Area ......... Page 13
- Appendix B
- Reading and Writing with the Extended Memory Manager Page 14
- Appendix C
- XMS Error Codes ................................... Page 15
-
- Page 3
-
- INTRODUCTION TO THE XMS SPECIFICATION:
-
- The XMS Specification, which is a Lotus/Intel/Microsoft/AST joint
- venture, lays the groundwork for access to Extended Memory, the memory
- above the 1-Megabyte boundary on AT-Class and above computer systems.
- The heart of this is HIMEM.SYS; a device driver that loads at boot-time
- from CONFIG.SYS and manages the complex task of reading from and writing
- to Extended Memory.
- This is not to be confused with the EMS Specification, which deals with
- Expanded Memory on PC-Class and above computer systems. The EMS set of
- rules govern a paging memory scheme that allow PC's to store large amounts
- of data in EMS Memory without running out of DOS memory.
- The routines of XMS allow access to Extended Memory for storing data
- and, in some cases, actually running code; all from DOS. The problem of
- switching from the Real Mode, which emulates the 8086/8088 processor, to
- the Protected Mode, which allows access to the entire address space, and
- back again is eliminated.
- There are three classes of routines in XMS:
- o High Memory Area (HMA) routines:
- These allow access to the first 64K of Extended Memory. Data can be
- store here and code can be executed.
- o Extended Memory Management (XMM) routines:
- These allow access to the entire physical address space of the
- particular processor (80286 machines can access 16 Megabytes and
- 80386 machines can access 4 Gigabytes). Only data can be stored
- and retrieved; no code can be executed.
- o Upper Memory Block (UMB) routines:
- These allow access to the area of memory between 640K and 1-Megabyte.
- Most AT-Class machines come with at least 1024K of RAM.
- NOTE: The HIMEM.SYS version, as of this writing, does not implement
- these routines and little is known how they will react. The Speci-
- fication does spell out how to call the routines, but they will not
- function.
- There are also routines to manipulate the address line A20 for access
- to the first 64K of Extended Memory and routines for determining the
- version and revision number of HIMEM.SYS.
- The XMS Specification, which includes HIMEM.SYS and documentation, can
- be obtained through a computer club or from the Microsoft Systems Forum on
- CompuServe. The Official XMS Specification can be obtained directly from
- Microsoft.
-
- Page 4
-
-
-
-
-
-
-
-
-
-
- INTRODUCTION TO TPXMS.TPU
-
- The TPXMS.PAS source code is a Turbo Pascal v4.0 and above Unit that
- utilizes the routines in HIMEM.SYS. When compiled, all the functions that
- currently defined in the XMS Specification are easily accessable as Pascal
- Procedures and Functions with Inline Machine Language calls to the XMM
- Manager.
-
- Included in this package ( TPXMS.ZIP ):
-
- o TPXMS.PAS : the latest source code for TPXMS.TPU.
- o XMSTEST.PAS : the latest source code for the TPXMS.TPU tests.
- o TPXMS.DOC : this documentation.
-
- Every effort has been taken to insure compatibility with both the
- Specification and Turbo Pascal. As the Specification changes, so will
- this package. Any comments about the XMS Specification should be directed
- to Microsoft. Any comments concerning Turbo Pascal should be directed to
- Borland International. Any comments concerning this package should be
- directed to the author:
-
- Vernon E. Davis, Jr.
- 17 Bowen Avenue
- Woodstown, NJ 08098
- CompuServe [71330,2705]
-
- I release this package to the Public Domain. All I am asking for is
- recognition for the amount of time and work that went into creating
- this package.
- Vernon E. Davis, Jr. 07/30/89
-
- Page 5
-
- TYPE DECLARATIONS IN TPXMS.TPU
-
- ** Bit32Struct = LongInt;
-
- This is just a reminder that any value stored in this type should be
- treated as an UNSIGNED 32-bit value. Turbo Pascal's LongInt type is a
- SIGNED 32-bit number; however, any constant value assigned to this type
- is stored as an UNSIGNED number.
- Example:
- Var lnum : LongInt;
-
- lnum := $FFFFFFFF;
- Write(lnum); ( the output displays -1 )
-
- However, the actual variable is stored as $FFFFFFFF
-
- The LongInt type has a range of -2,147,483,648 to +2,147,483,647. The
- UNSIGNED number would be 4 Gigabytes or the actual address space of the
- 80386 processor. Very few people, if any, will need even 2 Gigabytes of
- addressing, so this should not be a problem.
-
- ** ExtMemMoveStruct =
- Record
- Length : Bit32Struct; Number of bytes to transfer.
- SourceHandle : Word; The Source Extended Memory Handle or 0.
- SourceOffset : Bit32Struct; The offset into block in which to start.
- DestHandle : Word; The Dest. Extended Memory Handle or 0.
- DestOffset : Bit32Struct The offset into block in which to start.
- End;
-
- This structure sets up the movement of data from Conventional Memory to
- Extended and visa-versa. According to the XMS Specifications, the move
- can also occur from within Conventional Memory or Extended Memory. If
- the SourceHandle or DestHandle is equal to zero, then it is considered
- to be a Conventional Memory location, with the Segment:Offset pair placed
- in the SourceOffset or DestOffset variable, respectively. The Extended
- Memory Handle is obtained through the Allocate Function and the offset
- is how far into the Extended Memory Block to start.
- Example:
- ExtMemMove : ExtMemMoveStruct;
- XMSHandle : Word;
-
- With ExtMemMove Do
- Begin
- Length := 4000; { move the entire video buffer }
- SourceHandle := 0; { Conventional Memory Handle }
- SourceOffset := $B8000000; { VIDEO = $B800:0000 }
- DestHandle := XMSHandle; { obtained via AllocExtMemXMS }
- DestOffset := 0 { start at offset 0 }
- End;
-
- When the MoveExtMemXMS Function is called, the contents of the video
- screen would be written to Extended Memory. ( See the program XMSTEST.PAS
- and Appendix B for actual code. )
-
- Page 6
-
- TYPE DECLARATIONS IN TPXMS.TPU ( continued )
-
- ** EMBHandleStruct =
- Record
- LockCount : Byte; The number of times that the block has been locked.
- FreeHandles : Byte; The number of remaining Extended Memory Handles.
- BlockLenKB : Word The length, in kilobytes, of the current Extended
- Memory Block.
- End;
-
- This structure is used by the EMBHandleInfoXMS procedure to extract
- information about a particular Extended Memory Block.
-
- ** UMBSegmentStruct =
- Record
- Segment : Word; The segment to which the Upper Memory Block has
- been assigned.
- UMBSizePG : Word The actual size of the Upper Memory Block in
- paragraphs (1 paragraph = 16 bytes).
- End;
-
- Please note that this structure is defined, but the functions in the
- current revision of HIMEM.SYS (2.06) does not access the Upper Memory
- Block. All of these functions return $80 (Function not implemented).
-
- Page 7
-
- VARIABLE DECLARATIONS IN TPXMS.TPU
-
- ** isXMS : Boolean; TRUE if HIMEM.SYS is correctly
- installed. NOTE: All Procedures/
- Functions in TPXMS.TPU check for isXMS
- equal TRUE. If NOT TRUE, XMSResult
- equals 0 and XMSError equals $80.
-
- ** XMSResult : Word; Equals 1 if the Function called is
- successful, else 0. Some of these
- functions do not use this as a result;
- instead it is used to return a value
- from the Function.
-
- ** XMSError : Byte; If XMSResult = 0 and this byte is
- greater or equal to $80, an error
- has occurred. See the Appendix C
- for an explanation of each value.
-
- ** XMM_Control : Array[0..1] of Word; This is the holder of the actual
- address of the XMM_Control Function.
- The Offset is contained in [0] and
- the Segment is contained in [1]. This
- is really an internal variable and has
- no other use outside the XMS Functions.
- Page 8
-
- HIGH MEMORY ROUTINES
-
- ** Procedure GetMemHMA(Word);
- This procedure attempts to allocate the High Memory Area with the Word
- value passed. Check XMSResult = 1 for success. NOTE: If the /HMAMIN=
- parameter is greater than the amount of memory requested, the procedure
- will fail. ( See the XMS Specifications for more detail. ) NOTE: If
- this procedure is called, the FreeMemHMA procedure MUST be called to
- free the HMA before the program terminates or other programs cannot use
- that memory. ( See Appendix A for reading and writing to the HMA. )
-
- ** Procedure FreeMemHMA;
- This procedure will attempt to release the High Memory Area. Check
- XMSResult = 1 for success. NOTE: This function MUST be called to free
- up the HMA before the program terminates or other programs will not
- have access to the memory.
-
- Page 9
-
- EXTENDED MEMORY ROUTINES
-
-
- ** Procedure QueryFreeMemXMS;
- This procedure returns the TOTAL amount of free Extended Memory available
- for access. The value is returned in XMSResult in kilobyte increments.
- Example:
-
- QueryFreeMemXMS;
- Write(XMSResult);
- (The screen displays 256, which means there is a total of 256K
- of Extended Memory available for access.)
-
- ** Procedure QueryFreeBlockXMS;
- This procedure returns the LARGEST BLOCK of Extended Memory available
- for access. The value is returned in XMSResult in kilobyte increments.
- Example:
-
- QueryFreeBlockXMS;
- Write(XMSResult);
- (The screen displays 64, which means the largest block of Extended
- Memory available is 64K.)
-
- ** Function AllocExtMemBlockXMS(Word) : Word;
- This function attempts to allocate a block of Extended Memory for data
- storage. If XMSResult = 1 (success), then the value returned from the
- function is the Extended Memory Handle to be used in reference to the
- allocated block. The Word value passed to the function is the amount
- of memory to allocate in kilobytes. Remember that the block must be
- released before the program terminates or that block will remain in
- memory and cannot be accessed again. If XMSResult = 0 (failure), do not
- attempt to use the handle. ( See Appendix B for actual code. )
-
- ** Procedure FreeExtMemBlockXMS(Word);
- This procedure releases a block of Extended Memory that was previously
- allocated. The Word value passed to the procedure is the Extended Memory
- Handle of the allocated block. This procedure must be called to release
- a previously allocated block before the program terminates or the memory
- that the block resides in is lost. Check XMSResult = 1 for success.
- ( See Appendix B for actual code. )
-
- ** Procedure MoveExtMemBlockXMS(Var ExtMemMoveStruct);
- This procedure moves data from Conventional Memory to Extended Memory and
- visa-versa. The structure passed to the procedure contains the data
- length and source/destination addresses. The structure type is defined
- in the TPU Type Declarations. ( See the Type Declarations above. )
- Check XMSResult = 1 for success. ( See Appendix B for actual code. )
-
- Page 10
-
- HIGH MEMORY ROUTINES ( continued )
-
- ** Function LockExtMemBlockXMS(Word) : Bit32Struct;
- This function attempts to lock an allocated Extended Memory Block; that
- is; making the block unmovable. If there are numerous unlocked blocks
- in Extended Memory and one or more of those blocks are released, the XMM
- Manager moves the other blocks around to create one large free block of
- memory. This function prevents the block in question from being moved
- from its location in memory. The Word value passed is the Extended Memory
- Handle of the allocated block. The Bit32Struct value returned is the
- linear (actual) address of the block. Check XMSResult = 1 for success.
-
- * IMPORTANT * A block can be locked more than once. The Lock Count,
- which can be obtained with the EMBHandleInfoXMS procedure, is increased
- by one each time the LockExtMemBlockXMS function is called, up to a
- maximum of 255 times. In order for a block to be released, its Lock Count
- MUST be zero. Use the UnlockExtMemBlockXMS procedure to decrease the Lock
- Count.
-
- ** Procedure UnlockExtMemBlockXMS(Word);
- This procedure reduces the Lock Count of a locked Extended Memory Block
- by one. Because a block can be locked more than once, this routine must
- be called until the Lock Count, obtained through the EMBHandleInfoXMS
- procedure, is zero before the block can be released. The Word value
- passed to the procedure is the Extended Memory Handle. Check XMSResult
- = 1 for success.
-
- ** Procedure EMBHandleInfoXMS(Word; Var EMBHandleStruct);
- This procedure gathers information about a particular Extended Memory
- Block and about the XMM environment. The Word value passed to the
- procedure is the Extended Memory Handle. The structure passed to the
- procedure will contain the following information after returning from
- the call:
-
- o The Lock Count: the number of times that this block has been
- locked via the LockExtMemBlockXMS procedure. If this value is
- zero then the block can be successfully released with the
- FreeExtMemBlockXMS procedure.
- o The Free Handle Count: the number of free Extended Memory Handles
- that are available. If HIMEM.SYS was loaded without the /NUMHANDLES=
- parameter, then there are a total of 32 handles available.
- o The Block Size: this value, in kilobytes, is the current size of
- the block in question.
-
- Check XMSResult = 1 for success.
-
- ** Procedure ReallocExtMemBlockXMS(Word; Word);
- This procedure will attempt to change the current size of the particular
- Extended Memory Block. The first Word value passed to the procedure is
- the Extended Memory Handle. The second Word value passed to the procedure
- is the new size, in kilobytes, of the block.
-
- * NOTE * As of this writing, this procedure is not functional. It is a
- result of HIMEM.SYS, not the source code. If called, XMSResult will
- contain 0 and the value in XMSError will be $80 (Function not implemented).
- When HIMEM.SYS is updated, this procedure should work as planned and
- the TPXMS.TPU need not be recompiled.
-
- Page 11
-
- UPPER MEMORY ROUTINES
-
- ** Procedure ReqUpperMemBlockUMB(Word; Var UMBSegmentStruct);
- This procedure attempts to allocate an Upper Memory Block. The Word value
- passed to the procedure is the amount of memory to allocate in paragraphs
- ( 1 paragraph = 16 bytes ). The structure passed to the procedure will
- contain the following information after returning from the call:
-
- o The Segment : the segment of the UMB.
- o The Block Size : the actual size of the UMB in paragraphs.
-
- * NOTE * As of this writing, this procedure is not functional. It is a
- result of HIMEM.SYS, not the source code. If called, XMSResult will
- contain 0 and the value in XMSError will be $80 (Function not implemented).
- When HIMEM.SYS is updated, this procedure should work as planned and
- the TPXMS.TPU need not be recompiled.
-
- ** Procedure RelUpperMemBlockUMB(Word);
- This procedure releases a previously allocated Upper Memory Block. The
- Word value passed to the procedure is the Segment of the UMB.
-
- * NOTE * As of this writing, this procedure is not functional. It is a
- result of HIMEM.SYS, not the source code. If called, XMSResult will
- contain 0 and the value in XMSError will be $80 (Function not implemented).
- When HIMEM.SYS is updated, this procedure should work as planned and
- the TPXMS.TPU need not be recompiled.
-
- Page 12
-
- MISCELLANEOUS ROUTINES
-
- ** Function XMSErrorMsg : String;
- This function is not part of the XMS Specification, but is provided as
- convienence to the programmer in intrepreting Error Codes returned by
- the XMM_Control Function. A text message is returned based on the value
- in the XMSError byte. Example: If XMSResult = 0 Then Writeln(XMSErrorMsg);
-
- ** Function ExistXMS : Boolean;
- This Function is called once in the TPU and really does not need to be
- called again. It sets the variable isXMS TRUE if HIMEM.SYS is properly
- loaded and loads the XMM_Control array with the address of XMM_Control.
-
- ** Procedure GetVerHiMem;
- This procedure retrieves the version number of HIMEM.SYS in XMSResult.
-
- ** Procedure GetRevHiMem;
- This procedure retrieves the revision number of HIMEM.SYS in XMSResult.
-
- ** Procedure GlobalEnableA20;
- This toggles the address line A20 high so that access to the High Memory
- Area is obtained. THIS PROCEDURE MUST BE CALLED to access the HMA or
- the system will hang when trying to write to it. ( See Appendix A for
- actual code. ) The GlobalDisableA20 procedure MUST be called BEFORE
- releasing the HMA and BEFORE the program terminates. Check XMSResult = 1
- for success.
-
- ** Procedure GlobalDisableA20;
- This toggles the address line A20 low. This procedure MUST be called
- BEFORE releasing the HMA and BEFORE the program terminates. Check
- XMSResult = 1 for success.
-
- ** Procedure LocalEnableA20;
- This toggles the address line A20 high so that access to the first 64K
- of Extended Memory is obtained. THIS PROCEDURE MUST BE CALLED to access
- the memory or the system will hang when trying to write to it. ( See
- Appendix A for actual code. ) The LocalDisableA20 procedure MUST be
- called BEFORE the program terminates. Check XMSResult = 1 for success.
-
- * IMPORTANT * This procedure allows the bypass of the HMA access routines.
- Therefore, if there is another program, such as a TSR, in the HMA area,
- and Extended Memory is directly written to, that program in the HMA could
- be destroyed. One possible way to check if the HMA is in use would be to
- call the QueryA20 procedure to determine if address line A20 is active.
- Another way would be to attempt to allocate the HMA by calling the
- GetMemHMA procedure. In short, use the LocalEnableA20 procedure at the
- risk of hanging the system.
-
- ** Procedure LocalDisableA20;
- This toggles the address line A20 low. This procedure MUST be called
- BEFORE the program terminates. Check XMSResult = 1 for success.
-
- ** Procedure QueryA20;
- This procedure determines the status of address line A20.
- If XMSResult = 1 then A20 is active (enabled).
- If XMSResult = 0 then A20 is inactive (disabled).
-
- Page 13
-
- Appendix A - Reading and Writing to the High Memory Area ( HMA )
-
- The HMA can be directly accessed by DOS and Turbo Pascal. The address of
- the HMA officially begins at $FFFF:$0010 and ends at $FFFF:$FFFF, giving
- a total memory capacity of 65520 bytes ( 64K - 16 bytes ). Study the
- following piece of code:
-
- Program HMA_R_W;
- (*
- NOTE: This program assumes that HIMEM.SYS is properly loaded and that
- there is 64Kbytes free in the HMA area.
- *)
- Uses
- CRT,DOS,TPXMS;
- Var
- vid : Byte Absolute $B800:$0000;
- hma : Byte Absolute $FFFF:$0010;
- i : Integer;
- Begin
- GetMemHMA($FFFF); { Reserve all of the HMA }
- GlobalEnableA20; { Toggle the A20 address line high }
- ClrScr; { Clear the screen }
- For i := 1 To 1999 Do
- Write('A'); { Fill the screen with "A" }
- Move(vid,hma,4000); { Copy the contents of the screen to HMA }
- ClrScr; { Clear the screen }
- Move(hma,vid,4000); { Restore the screen from HMA }
- GlobalDisableA20; { Toggle the A20 address line low }
- FreeMemHMA { Release the HMA }
- End.
-
-
- The HMA can be bypassed by reading and writing to Direct Memory in the
- same fashion using the LocalEnable/DisableA20 procedures. However, any
- program, such as a TSR currently running in the HMA area, could be over-
- written. Use of this method is not recommended unless it is an absolute
- certainty that there is nothing in the HMA.
-
- Program DMA_R_W;
- (*
- NOTE: This program assumes that HIMEM.SYS is properly loaded.
- *)
- Uses
- CRT,DOS,TPXMS;
- Var
- vid : Byte Absolute $B800:$0000;
- dma : Byte Absolute $FFFF:$0010;
- i : Integer;
- Begin
- LocalEnableA20; { Toggle the A20 address line high }
- ClrScr; { Clear the screen }
- For i := 1 To 1999 Do
- Write('A'); { Fill the screen with "A" }
- Move(vid,dma,4000); { Copy the contents of the screen to HMA }
- ClrScr; { Clear the screen }
- Move(dma,vid,4000); { Restore the screen from HMA }
- LocalDisableA20 { Toggle the A20 address line low }
- End.
-
- Page 14
-
- Appendix B - Reading and Writing with the Extended Memory Manager ( XMM )
-
- The XMM routines provide access to Extended Memory that is transparent
- to the programmer in switching from Real Mode to Protected Mode and back
- again. Study the following piece of code:
-
- Program XMM_R_W;
- (*
- NOTE: This program assumes that HIMEM.SYS is properly loaded and that
- there is 4Kbytes free in Extended Memory.
- *)
- Uses
- CRT,DOS,TPXMS;
- Var
- XMSHandle : Word;
- ExtMemMove : ExtMemMoveStruct;
- i : Integer;
- Begin
- XMSHandle := AllocExtMemBlockXMS(4); { Allocate 4 kilobytes }
- With ExtMemMove Do { Load the structure }
- Begin
- Length := 4000; { Size of video screen }
- SourceHandle := 0; { Use Conventional Memory }
- SourceOffset := $B8000000; { VIDEO = $B800:$0000 }
- DestHandle := XMSHandle; { Extended Memory Handle }
- DestOffset := 0 { Offset 0 into the block }
- End;
- ClrScr; { Clear the screen }
- For i := 1 To 1999 Do Write('A'); { Fill the screen with "A" }
- MoveExtMemBlockXMS(ExtMemMove); { Move screen to Ext. Memory }
- ClrScr; { Clear the screen }
- With ExtMemMove Do { Load the structure }
- Begin
- Length := 4000; { Size of video screen }
- SourceHandle := XMSHandle; { Extended Memory Handle }
- SourceOffset := 0; { Offset 0 into the block }
- DestHandle := 0; { Use Conventional Memory }
- DestOffset := $B8000000 { VIDEO = $B800:$0000 }
- End;
- MoveExtMemBlockXMS(ExtMemMove); { Restore screen from Ext. Mem. }
- FreeExtMemBlockXMS(XMSHandle) { Release Extended Memory Block }
- End.
-
- Page 15
-
- Appendix C - XMS ERROR CODES
-
- If XMSResult = 0 and XMSError is greater than or equal to $80 then
- an error has occurred. The following codes are valid as of this
- writing:
-
- $80 : XMS Function not implemented
- $81 : VDISK detected
- $82 : A20 Error
- $8E : General Driver Error
- $8F : Unrecoverable Driver Error
- $90 : HMA does not exist
- $91 : HMA in use by another process
- $92 : Memory requested less than /HMAMIN= parameter
- $93 : HMA not allocated
- $94 : A20 is enabled
- $A0 : All of Extended Memory is allocated
- $A1 : No Extended Memory Handles available
- $A2 : Extended Memory Handle is invalid
- $A3 : Extended Move Structure: Source Handle is invalid
- $A4 : Extended Move Structure: Source Offset is invalid
- $A5 : Extended Move Structure: Destination Handle is invalid
- $A6 : Extended Move Structure: Destination Offset is invalid
- $A7 : Extended Move Structure: Length is invalid
- $A8 : Extended Move Structure: Move has invalid overlap
- $A9 : Parity Error
- $AA : Block is not locked
- $AB : Block is locked
- $AC : Block Lock Count has overflowed
- $AD : Block Lock has failed
- $B0 : A smaller Upper Memory Block is available
- $B1 : No Upper Memory Blocks are available
- $B2 : Upper Memory Block Segment Number is invalid
-