Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-1


				PAGE    60,132
				TITLE   INDEXMA - 386 XMA Emulator - XMA Emulation
				
				COMMENT #
				* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
				*                                                                             *
				* MODULE NAME     : INDEXMA                                                   *
				*                                                                             *
				*                    5669-196 (C) COPYRIGHT 1988 Microsoft Corp.              *
				*                                                                             *
				* DESCRIPTIVE NAME: Do the XMA emulation for the 80386 XMA Emulator           *
				*                                                                             *
				* STATUS (LEVEL)  : Version (0) Level (1.0)                                   *
				*                                                                             *
				* FUNCTION        : This module does the actual manipulation of the page      *
				*                   tables to emulate the XMA card.  Using the 80386          *
				*                   paging mechanism we let the 4K page frames represent      *
				*                   the 4K XMA blocks on the XMA card.  We let the page       *
				*                   tables represent the translate table.                     *
				*                                                                             *
				*                   The XMA "blocks" start at address 12000:0.  The        D1C*
				*                   Emulator emulates the XMA 2 card with the INDXMAA      D1C*
				*                   device driver.  On initial power up, the XMA 2 card is D1C*
				*                   disabled.  The INDXMAA device driver then disables the D1C*
				*                   memory from 0K to 640K and backs it with memory from   D1C*
				*                   0K to 640K on the XMA 2 card.  The Emulator looks like D1C*
				*                   it does the same thing.  The XMA blocks for 0K to 640K D1C*
				*                   are taken from the system board memory from 0K to      D1C*
				*                   640K.  This memory on the motherboard is treated as    D1C*
				*                   XMA memory.  This emulates the INDXMAA device driver's D1C*
				*                   mapping of 0K to 640K on the XMA card to real memory.  D1C*
				*                   The XMA "blocks" for 640K and up are located in high   D1C*
				*                   memory starting at 12000:0.  These "blocks" run up to  D1C*
				*                   the start of the MOVEBLOCK buffer.  The MOVEBLOCK      D1C*
				*                   buffer is a chunk of storage (in 16K multiples) at the D1C*
				*                   end of available memory that is reserved for the       D1C*
				*                   MOVEBLOCK functions.                                   D1C*
				*                                                                             *
				*                   The page tables are used to emulate the translate         *
				*                   table.  By setting the address of the XMA "block" into    *
				*                   the page table entry for a specific page frame we can     *
				*                   make that address access that particular XMA page         *
				*                   frame.  To the user this looks just like the translate    *
				*                   table is active.                                          *
				*                                                                             *
				*                   The tricky part comes in disabling pages (blocks).  On D1C*
				*                   the XMA 2 card, when a translate table entry is        D1C*
				*                   disabled the addresses for that address range go to    D1C*
				*                   real memory.  If the address is between 0K and 640K    D1C*
				*                   then any access of that storage gets nothing because   D1C*
				*                   there is no memory backed from 0K to 640K on the real  D1C*
				*                   system.  All other addresses go to real memory.  So    D1C*
				*                   when the user disables translation of a translate      D1C*
				*                   table entry we need to check what range that entry     D1C*
				*                   covers.  If the entry points to somewhere between 0K   D1C*
				*                   and 640K then we will set the page table entry that    D1C*
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-2


				*                   corresponds to the translate table entry to point to   D1C*
				*                   non-existent memory.  For all other addresses we will  D1C*
				*                   just point the page table entry back to the real       D1C*
				*                   memory at that address.                                D1C*
				*                                                                             *
				*                   This module receives control on all "IN"s and "OUT"s      *
				*                   done by the user.  If the "IN" or "OUT" is not to an      *
				*                   XMA port then it passes the I/O on to INDEDMA.  If it     *
				*                   is for an XMA port then the request is handled here.      *
				*                                                                             *
				*                   This module keeps its own copies of the XMA registers     *
				*                   and the translate table.  When any I/O comes for the      *
				*                   XMA card it updates its copies of the registers and       *
				*                   the translate table.  Then it does any needed             *
				*                   modifications on the page tables to emulate the XMA       *
				*                   request.                                                  *
				*                                                                             *
				* MODULE TYPE     : ASM                                                       *
				*                                                                             *
				* REGISTER USAGE  : 80386 Standard                                            *
				*                                                                             *
				* RESTRICTIONS    : None                                                      *
				*                                                                             *
				* DEPENDENCIES    : None                                                      *
				*                                                                             *
				* ENTRY POINTS    : INW         - Emulate "IN" for a word with port number    *
				*                                 in DX                                       *
				*                   INWIMMED    - Emulate "IN" for a word with an immediate   *
				*                                 port number                                 *
				*                   INIMMED     - Emulate "IN" for a byte with an immediate   *
				*                                 port number                                 *
				*                   XMAIN       - Emulate "OUT" for a byte with port number   *
				*                                 in DX                                       *
				*                   OUTW        - Emulate "OUT" for a word with port number   *
				*                                 in DX                                       *
				*                   OUTWIMMED   - Emulate "OUT" for a word with an immediate  *
				*                                 port number                                 *
				*                   XMAOUTIMMED - Emulate "OUT" for a byte with an immediate  *
				*                                 port number                                 *
				*                   XMAOUT      - Emulate "OUT" for a byte with port number   *
				*                                 in DX                                       *
				*                                                                             *
				* LINKAGE         : Jumped to by INDEEXC                                      *
				*                                                                             *
				* INPUT PARMS     : None                                                      *
				*                                                                             *
				* RETURN PARMS    : None                                                      *
				*                                                                             *
				* OTHER EFFECTS   : None                                                      *
				*                                                                             *
				* EXIT NORMAL     : Go to POPIO in INDEEMU to IRET to the V86 task            *
				*                                                                             *
				* EXIT ERROR      : None                                                      *
				*                                                                             *
				* EXTERNAL                                                                    *
				* REFERENCES      : POPIO:NEAR     - Entry in INDEEMU to return to V86 task   *
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-3


				*                   HEXW:NEAR      - Entry in INDEEXC to display word in AX   *
				*                   DMAIN:NEAR     - Entry in INDEDMA to "IN" from DMA port   *
				*                   DMAOUT:NEAR    - Entry in INDEDMA to "OUT" to DMA port    *
				*                   PGTBLOFF:WORD  - Offset of the normal page tables         *
				*                   SGTBLOFF:WORD  - Offset of the page directory             *
				*                   NORMPAGE:WORD  - Entry for the 1st page directory entry   *
				*                                    so that it points to the normal          *
				*                                    page tables                              *
				*                   XMAPAGE:WORD   - Entry for the 1st page directory entry   *
				*                                    that points to the XMA page tables       *
				*                   TTTABLE:WORD   - The translate table                      *
				*                   BUFF_SIZE:WORD - Size of the MOVEBLOCK buffer             *
				*                   MAXMEM:WORD    - Number of kilobytes on this machine      *
				*                                                                             *
				* SUB-ROUTINES    : TTARCHANGED - Put the block number at the translate table *
				*                                 entry in 31A0H into "ports" 31A2H and 31A4H *
				*                   UPDATETT    - Update the translate table and page tables  *
				*                                 to reflect the new block number written to  *
				*                                 either 31A2H or 31A4H                       *
				*                                                                             *
				* MACROS          : DATAOV - Add prefix for the next instruction so that it   *
				*                            accesses data as 32 bits wide                    *
				*                   ADDROV - Add prefix for the next instruction so that it   *
				*                            uses addresses that are 32 bits wide             *
				*                   CMOV   - Move to and from control registers               *
				*                                                                             *
				* CONTROL BLOCKS  : INDEDAT.INC - system data structures                      *
				*                                                                             *
				* CHANGE ACTIVITY :                                                           *
				*                                                                             *
				* $MOD(INDEXMA) COMP(LOAD) PROD(3270PC) :                                     *
				*                                                                             *
				* $D0=D0004700 410 870530 D : NEW FOR RELEASE 1.1                             *
				* $P1=P0000293 410 870731 D : LIMIT LINES TO 80 CHARACTERS                    *
				* $P2=P0000312 410 870804 D : CHANGE COMPONENT FROM MISC TO LOAD              *
				* $D1=D0007100 410 870810 D : CHANGE TO EMULATE XMA 2                         *
				*                                                                             *
				* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
				#
				
				        .286P                 ; Enable recognition of 286 privileged instructs.
				
				        .LIST                 ; Turn on the listing
				
 = 0030				CRT_SELECTOR    EQU     00030H          ; Selector for mono display buffer
 = 4B00				SEX_ATTR        EQU     04B00H          ; Attribute for turquoise on red
 = 0700				STACK_ATTR      EQU     00700H          ; Attribute for white o black
 = 0020				BLANK           EQU     00020H          ; ASCII for a blank
 =				XMA_PAGES_SEL   EQU     RSDA_PTR        ; Selector for the XMA pages
 = 0120				HIMEM           EQU     120H            ; Adjustment for XMA pages >= 640K. @D1C
				                                        ;   They start at address 12000:0.
				                                        ;   It's the block number corresponding
				                                        ;   to address 12000:0.
				                                        ;                                   @D1D
				
 0000				PROG    SEGMENT PARA PUBLIC 'PROG'
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-4
                                                            

				
				        ASSUME  CS:PROG
				        ASSUME  DS:PROG
				        ASSUME  ES:NOTHING
				        ASSUME  SS:NOTHING
				
 0000				INDEXMA LABEL   NEAR
				
				; The following entry points are in other modules
				
				        EXTRN   POPIO:NEAR              ; Return to V86 task - in INDEEMU
				        EXTRN   HEXW:NEAR               ; Display word in AX - in INDEEXC
				        EXTRN   DMAIN:NEAR              ; "IN" from DMA port - in INDEDMA
				        EXTRN   DMAOUT:NEAR             ; "OUT" to DMA port  - in INDEDMA
				
				; The following data are in INDEI15.ASM
				
				        EXTRN   PGTBLOFF:WORD           ; Offset of the normal page tables
				        EXTRN   SGTBLOFF:WORD           ; Offset of the page directory
				        EXTRN   NORMPAGE:WORD           ; Entry for the 1st page directory entry
				                                        ;   so that it points to the normal
				                                        ;   page tables
				        EXTRN   XMAPAGE:WORD            ; Entry for the 1st page directory entry
				                                        ;  that points to the XMA page tables
				        EXTRN   TTTABLE:WORD            ; The translate table
				        EXTRN   BUFF_SIZE:WORD          ; Size of the MOVEBLOCK buffer
				        EXTRN   MAXMEM:WORD             ; Number of kilobytes on this machine
				
				; Let the following entries be known to other modules
				
				        PUBLIC  INDEXMA
				        PUBLIC  INW
				        PUBLIC  INWIMMED
				        PUBLIC  INIMMED
				        PUBLIC  XMAIN
				        PUBLIC  OUTW
				        PUBLIC  OUTWIMMED
				        PUBLIC  XMAOUTIMMED
				        PUBLIC  XMAOUT
				        PUBLIC  NOTXMAOUT
				
				; Let the following data be known to other modules
				
				        PUBLIC  WORD_FLAG
				        PUBLIC  XMATTAR
				        PUBLIC  XMATTIO
				        PUBLIC  XMATTII
				        PUBLIC  XMATID
				        PUBLIC  XMACTL
				
				; The following XMA labels represent the XMA ports starting at 31A0H.
				; THEY MUST BE KEPT IN THE FOLLOWING ORDER.
				
 0000  0000			XMATTAR DW      0             ; Port 31A0H - Translate table index
 0002  0000			XMATTIO DW      0             ; Port 31A2H - XMA block number
 0004  0000			XMATTII DW      0             ; Port 31A4H - Block number with auto-increment
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-5
                                                            

 0006  00			XMATID  DB      0             ; Port 31A6H - Bank ID
 0007  02			XMACTL  DB      02H           ; Port 31A7H - Control flags.  Virtual        @D1C
				                              ;              enable bit is initially on.
				
				; How about some flags?
				
 0008  00			WORD_FLAG DB    0             ; If set to 1 then I/O is for a word.
				                              ;   Else, it's for a byte
				
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-6
                                                            

				PAGE
				
				; Control comes here for an "IN" for a word with the port value in DX
				
 0009				INW:
 0009  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS with the selector for our
 000C  8E D8			        MOV     DS,AX                   ;   data segment so we can set WORD_FLAG
 000E  C6 06 0008 R 01		        MOV     WORD_FLAG,1             ; Flag this as a word operation
 0013  EB 35 90			        JMP     XMAIN                   ; Go do the "IN"
				
				; Control comes here for an "IN" for a word with an immediate port value
				
 0016				INWIMMED:
 0016  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS with the selector for our
 0019  8E D8			        MOV     DS,AX                   ;   data segment so we can set WORD_FLAG
 001B  C6 06 0008 R 01		        MOV     WORD_FLAG,1             ; Flag this as a word operation
				
				; Control comes here for an "IN" for a byte with an immediate port value
				
 0020				INIMMED:
				
 0020  83 46 2A 01		        ADD     WORD PTR SS:[BP+BP_IP],1 ; Step IP past the "IN" instruction
				
				; Get the port address from the instruction.  The port address is in the byte
				; immediately following the "IN" op-code.  We will load the port address into
				; DX.  This way when we join the code below it will look like the port address
				; was in DX all along.
				
 0024  B8 0020			        MOV     AX,HUGE_PTR             ; Load DS with a selector that accesses
 0027  8E D8			        MOV     DS,AX                   ;   all of memory as data
				
 0029  C7 46 2C 0000		        MOV     SS:WORD PTR [BP+BP_IP2],0 ; Clear the high words of the V86
 002E  C7 46 30 0000		        MOV     SS:WORD PTR [BP+BP_CS2],0 ;   task's CS and IP
				
				        DATAOV                          ; Load ESI (32 bit SI) with the V86
 0033  66                    1	         DB      066H 
 0034  8B 76 2A			        MOV     SI,SS:[BP+BP_IP]        ;   task's IP
				        DATAOV
 0037  66                    1	         DB      066H 
 0038  8B 46 2E			        MOV     AX,SS:[BP+BP_CS]        ; Load EAX with the V86 task's CS
				        DATAOV                          ;   and then shift left four bits to
 003B  66                    1	         DB      066H 
 003C  C1 E0 04			        SHL     AX,4                    ;   convert it to an offset
				        DATAOV                          ; Add the CS offset to "IP" in SI
 003F  66                    1	         DB      066H 
 0040  03 F0			        ADD     SI,AX                   ; SI now contains CS:IP as a 32 bit
				                                        ;   offset from 0
				        ADDROV                          ; Get the byte after the "IN" instruc-
 0042  67                    1	         DB      067H 
 0043  AC			        LODSB                           ;   tion.  This is the port address.
				
				        ADDROV                          ; Intel bug # A0-119
 0044  67                    1	         DB      067H 
 0045  90			        NOP                             ; Intel bug # A0-119
				
 0046  2B D2			        SUB     DX,DX                   ; Clear DX to prepare for one byte move
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-7
                                                            

 0048  8A D0			        MOV     DL,AL                   ; DX now has the port address
				
				; Control comes here for an "IN" for a byte with the port value in DX
				
 004A				XMAIN   PROC    NEAR
				
 004A  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS with the selector for our
 004D  8E D8			        MOV     DS,AX                   ;    data segment
				
 004F  81 FA 31A0		        CMP     DX,31A0H                ; Is the port address below 31A0H?
 0053  72 2E			        JB      NOTXMAIN                ; Yup.  Then it's not XMA.
				
 0055  81 FA 31A7		        CMP     DX,31A7H                ; Is the port address above 31A7H?
 0059  77 28			        JA      NOTXMAIN                ; Yup.  Then it's not XMA.
				
				; It's an XMA port so lets do the "IN" for the guy.
				
 005B  81 26 0000 R 0FFF	        AND     XMATTAR,0FFFH           ; First lets clear the high nibbles of
 0061  80 26 0006 R 0F		        AND     XMATID,0FH              ;   our ports.  This insures that we
 0066  80 26 0007 R 0F		        AND     XMACTL,0FH              ;   have valid values in our ports.
				
 006B  8D 36 0000 R		        LEA     SI,XMATTAR              ; Point SI to the port requested by
 006F  03 F2			        ADD     SI,DX                   ;   first pointing it to port 31A0H
 0071  81 EE 31A0		        SUB     SI,31A0H                ;   and then adding on the difference
				                                        ;   between 31A0H and the requested port
 0075  80 3E 0008 R 00		        CMP     WORD_FLAG,0             ; Is this a word operation?
 007A  75 0A			        JNE     GETWORD                 ; Yes.  Then go get a word.
				
 007C  AC			        LODSB                           ; Else get a byte from the "port"
 007D  88 46 1E			        MOV     BYTE PTR SS:[BP+BP_AX],AL ; Put it in the V86 task's AL register
 0080  EB 1A 90			        JMP     INEXIT                  ; Th-th-that's all folks!
				
				; For non-XMA ports we just pass the "IN" on to INDEDMA
				
 0083				NOTXMAIN:
 0083  E9 0000 E		        JMP     DMAIN
				
				; The "IN" is for a word
				
 0086				GETWORD:
 0086  AD			        LODSW                           ; Get a word from the "port"
 0087  89 46 1E			        MOV     WORD PTR SS:[BP+BP_AX],AX ; Put it in the V86 task's AX register
				
 008A  C6 06 0008 R 00		        MOV     WORD_FLAG,0             ; Reset the word flag
				
 008F  81 FA 31A4		        CMP     DX,31A4H                ; Is this an "IN" from the auto-
				                                        ;   increment port?
 0093  75 07			        JNE     INEXIT                  ; Nope.  Then just leave.
				
 0095  FF 06 0000 R		        INC     XMATTAR                 ; The "IN" is from the auto-increment
				                                        ;   port so increment the translate
 0099  E8 019C R		        CALL    TTARCHANGED             ;   table index and call TTARCHANGED
				                                        ;   to update the status of the "card"
 009C				INEXIT:
 009C  83 46 2A 01		        ADD     WORD PTR SS:[BP+BP_IP],1 ; Step IP past the instruction (past
				                                        ;   the port value for immediate insts.)
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-8
                                                            

 00A0  E9 0000 E		        JMP     POPIO                   ; Go return to the V86 task
				
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-9
                                                            

				PAGE
				
				; Control comes here for an "OUT" for a word with the port value in DX
				
 00A3				OUTW:
 00A3  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS with the selector for our
 00A6  8E D8			        MOV     DS,AX                   ;   data segment so we can set WORD_FLAG
 00A8  C6 06 0008 R 01		        MOV     WORD_FLAG,1             ; Flag this as a word operation
 00AD  EB 35 90			        JMP     XMAOUT                  ; Go do the "OUT"
				
				; Control comes here for an "OUT" for a word with an immediate port value
				
 00B0				OUTWIMMED:
 00B0  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS with the selector for our
 00B3  8E D8			        MOV     DS,AX                   ;   data segment so we can set WORD_FLAG
 00B5  C6 06 0008 R 01		        MOV     WORD_FLAG,1             ; Flag this as a word operation
				
				; Control comes here for an "OUT" for a byte with an immediate port value
				
 00BA				XMAOUTIMMED:
				
 00BA  83 46 2A 01		        ADD     WORD PTR SS:[BP+BP_IP],1 ; Step IP past the "OUT" instruction
				
				; Get the port address from the instruction.  The port address is in the byte
				; immediately following the "OUT" op-code.  We will load the port address into
				; DX.  This way when we join the code below it will look like the port address
				; was in DX all along.
				
 00BE  B8 0020			        MOV     AX,HUGE_PTR             ; Load DS with a selector that accesses
 00C1  8E D8			        MOV     DS,AX                   ;   all of memory as data
				
 00C3  C7 46 2C 0000		        MOV     SS:WORD PTR [BP+BP_IP2],0 ; Clear the high words of the V86
 00C8  C7 46 30 0000		        MOV     SS:WORD PTR [BP+BP_CS2],0 ;   task's CS and IP
				
				        DATAOV                          ; Load ESI (32 bit SI) with the V86
 00CD  66                    1	         DB      066H 
 00CE  8B 76 2A			        MOV     SI,SS:[BP+BP_IP]        ;   task's IP
				        DATAOV
 00D1  66                    1	         DB      066H 
 00D2  8B 46 2E			        MOV     AX,SS:[BP+BP_CS]        ; Load EAX with the V86 task's CS
				        DATAOV                          ;   and then shift left four bits to
 00D5  66                    1	         DB      066H 
 00D6  C1 E0 04			        SHL     AX,4                    ;   convert it to an offset
				        DATAOV                          ; Add the CS offset to "IP" in SI
 00D9  66                    1	         DB      066H 
 00DA  03 F0			        ADD     SI,AX                   ; SI now contains CS:IP as a 32 bit
				                                        ;   offset from 0
				        ADDROV                          ; Get the byte after the "OUT" instruc-
 00DC  67                    1	         DB      067H 
 00DD  AC			        LODSB                           ;   tion.  This is the port address.
				
				        ADDROV                          ; Intel bug # A0-119
 00DE  67                    1	         DB      067H 
 00DF  90			        NOP                             ; Intel bug # A0-119
				
 00E0  2B D2			        SUB     DX,DX                   ; Clear DX to prepare for one byte move
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-10
                                                            

 00E2  8A D0			        MOV     DL,AL                   ; DX now has the port address
				
				; Control comes here for an "OUT" for a byte with the port value in DX
				
 00E4				XMAOUT:
 00E4  B8 0068			        MOV     AX,SYS_PATCH_DS         ; Load DS and ES with the selector for
 00E7  8E D8			        MOV     DS,AX                   ;   our data area
 00E9  8E C0			        MOV     ES,AX
				
 00EB  81 FA 31A0		        CMP     DX,31A0H                ; Is the port address below 31A0H?
 00EF  72 6A			        JB      NOTXMAOUT               ; Yes.  Then it's not XMA.
				
 00F1  81 FA 31A7		        CMP     DX,31A7H                ; Is the port address above 31A7H?
 00F5  77 64			        JA      NOTXMAOUT               ; Yes.  Then it's not XMA.
				
 00F7  8D 3E 0000 R		        LEA     DI,XMATTAR              ; Point SI to the port requested by
 00FB  03 FA			        ADD     DI,DX                   ;   first pointing it to port 31A0H
 00FD  81 EF 31A0		        SUB     DI,31A0H                ;   and then adding on the difference
				                                        ;   between 31A0H and the requested port
 0101  80 3E 0008 R 00		        CMP     WORD_FLAG,0             ; Is this a word operation?
 0106  75 19			        JNE     PUTWORD                 ; Yes.  Then go put a word.
				
 0108  8A 46 1E			        MOV     AL,BYTE PTR SS:[BP+BP_AX] ; Put the value in the V86 task's AL
 010B  AA			        STOSB                           ;   register into the "port"
				
 010C  81 FA 31A6		        CMP     DX,31A6H                ; Is this "OUT" to the bank ID port?
 0110  74 4C			        JE      CHKCNTRL                ; If so, go set the new bank
				
 0112  81 FA 31A7		        CMP     DX,31A7H                ; Is the "OUT" to the control port?
 0116  74 46			        JE      CHKCNTRL                ; Affirmative.  Go handle control bits.
				
 0118  81 FA 31A1		        CMP     DX,31A1H                ; Is this "OUT" to the TT index?
				                                        ;   (high byte)
 011C  76 37			        JBE     TTAROUT                 ; Yup.  Go update dependent fields.
				
 011E  EB 6D 90			        JMP     OUTEXIT                 ; Any other ports just exit.
				
				; The "OUT" is for a word
				
 0121				PUTWORD:
 0121  8B 46 1E			        MOV     AX,WORD PTR SS:[BP+BP_AX] ; Put the value in the V86 task's AX
 0124  AB			        STOSW                           ;   register into the "port"
				
 0125  C6 06 0008 R 00		        MOV     WORD_FLAG,0             ; Reset the word flag
				
 012A  81 FA 31A0		        CMP     DX,31A0H                ; Is the "OUT" to the TT index port?
 012E  74 25			        JE      TTAROUT                 ; Si.  Go update the dependent fields.
				
 0130  81 FA 31A2		        CMP     DX,31A2H                ; Is the "OUT" to set a block number?
 0134  75 09			        JNE     CHKA4                   ; No.  Go do some more checks.
				
 0136  A3 0004 R		        MOV     XMATTII,AX              ; The "OUT" is to 31A2H.  Set the auto-
				                                        ;   increment port to the same value.
				                                        ;   The two ports should always be in
				                                        ;   sync.
 0139  E8 01B2 R		        CALL    UPDATETT                ; Update the "translate table" with the
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-11
                                                            

				                                        ;   new block number
 013C  EB 4F 90			        JMP     OUTEXIT                 ; That's it.  Let's leave.
				
 013F				CHKA4:
 013F  81 FA 31A4		        CMP     DX,31A4H                ; Is "OUT" to the auto-increment port
 0143  75 19			        JNE     CHKCNTRL                ; No.  Then it must be to the bank ID/
				                                        ;   control byte port (31A6H).
 0145  A3 0002 R		        MOV     XMATTIO,AX              ; The "OUT is to the auto-increment port
 0148  E8 01B2 R		        CALL    UPDATETT                ; Update the "translate table"
 014B  FF 06 0000 R		        INC     XMATTAR                 ; Increment the translate table index
 014F  E8 019C R		        CALL    TTARCHANGED             ; Update fields that depend on the
				                                        ;   translate table index
 0152  EB 39 90			        JMP     OUTEXIT                 ; And return to the V86 task
				
				; The translate table index was changed
				
 0155				TTAROUT:
 0155  E8 019C R		        CALL    TTARCHANGED             ; Update fields that depend on the
				                                        ;   setting of the translate table index
 0158  EB 3B 90			        JMP     OUTEXITDMA              ; Skip flushing the page-translation
				                                        ;   cache since the page tables have
				                                        ;   not changed.
				
				; It's not an XMA "OUT" so pass it on to INDEDMA
				
 015B				NOTXMAOUT:
 015B  E9 0000 E		        JMP     DMAOUT
				
				; The "OUT" is to the bank ID port (31A6H), the control port (31A7H) or both
				
 015E				CHKCNTRL:
				
 015E  F6 06 0007 R 02		        TEST    XMACTL,02H              ; Is the virtual enable bit on?
 0163  75 0D			        JNZ     SETXMA                  ; Aye.  Go make the specified XMA bank
				                                        ;   active.
				        DATAOV                          ; Nay.  We simulate disabling the XMA
 0165  66                    1	         DB      066H 
 0166  A1 0000 E		        MOV     AX,NORMPAGE             ;   card by making the normal page
				                                        ;   tables active.
 0169  8B 3E 0000 E		        MOV     DI,SGTBLOFF             ; This is done by setting the first
				        DATAOV                          ;   entry in the page directory to
 016D  66                    1	         DB      066H 
 016E  AB			        STOSW                           ;   point to the page table for normal
				                                        ;   memory.
 016F  EB 1C 90			        JMP     OUTEXIT                 ; Return to the V86 task
				
 0172				SETXMA:
 0172  80 26 0006 R 0F		        AND     XMATID,0FH              ; Wipe out the high nibble of the bank
 0177  A0 0006 R		        MOV     AL,XMATID               ;   ID.  XMA only has 16 banks.
				        DATAOV                          ; Now multiply by 4K (shift left 12 ;P1C
 017A  66                    1	         DB      066H 
 017B  C1 E0 1C			        SHL     AX,28                   ;   bits) to get the offset from the
				        DATAOV                          ;   base of the XMA page tables of the
 017E  66                    1	         DB      066H 
 017F  C1 E8 10			        SHR     AX,28-12                ;   page table for the requested bank.
				                                        ;   Page tables are 4K in length.  In
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-12
                                                            

				                                        ;   the process of shifting we shift the
				                                        ;   high order 16 bits off the left end
				                                        ;   of EAX so that they are 0 when we
				                                        ;   shift back.
				        DATAOV                          ; Add on the offset of the base of the
 0182  66                    1	         DB      066H 
 0183  03 06 0000 E		        ADD     AX,XMAPAGE              ;   page tables.  EAX now has the offset
				                                        ;   of the page table for the XMA bank.
 0187  8B 3E 0000 E		        MOV     DI,SGTBLOFF             ; Point to the first entry in the page
				                                        ;   directory.
				        DATAOV                          ; Set the first entry in the page
 018B  66                    1	         DB      066H 
 018C  AB			        STOSW                           ;   directory to point to the XMA page
				                                        ;   table
				
				; Since the page tables have changed we need to purge the page-translation
				; cache.  "For greatest efficiency in address translation, the processor
				; stores the most recently used page-table data in an on-chip cache...  The
				; existence of the page-translation cache is invisible to applications
				; programmers but not to systems programmers; operating-system programmers
				; must flush the cache whenever the page tables are changed."
				;   -- 80386 Programmer's Reference Manual (C) Intel 1986
				
 018D				OUTEXIT:
				        CMOV    EAX,CR3                 ; Get the page directory base register
 018D  0F                    1	           DB    0FH 
 018E  20                    1	           DB    20H 
 018F  D8                    1	           DB    0C0H + _CRCNT*8 + _DREGNUM 
 0190  90			        NOP                             ; 386 errata B0-110
				        CMOV    CR3,EAX                 ; Write it back to reset the cache
 0191  0F                    1	           DB    0FH 
 0192  22                    1	           DB    22H 
 0193  D8                    1	           DB    0C0H + _CRCNT*8 + _DREGNUM 
 0194  90			        NOP                             ; 386 errata B0-110
				
 0195				OUTEXITDMA:
 0195  83 46 2A 01		        ADD     WORD PTR SS:[BP+BP_IP],1 ; Step IP past the "OUT" instruction
 0199  E9 0000 E		        JMP     POPIO                   ; Return to the V86 task
				
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-13
                                                            

				PAGE
				
				; TTARCHANGED updates all the fields that depend on the translate table index
				; in port 31A0H.  This is mainly getting the translate table entries for the
				; specified index and putting them in the block number ports 31A2H and 31A4H.
				
 019C				TTARCHANGED     PROC
				
 019C  A1 0000 R		        MOV     AX,XMATTAR              ; Get the new translate table index
 019F  25 0FFF			        AND     AX,0FFFH                ; The high nibble is not used
 01A2  D1 E0			        SHL     AX,1                    ; Change it to a word index.  The
				                                        ;   translate table entries are words.
 01A4  8D 36 0000 E		        LEA     SI,TTTABLE              ; Point SI to the translate table base
 01A8  03 F0			        ADD     SI,AX                   ; Add on the offset into the table
 01AA  AD			        LODSW                           ; Get the XMA block number for the
				                                        ;  specified translate table entry
 01AB  A3 0002 R		        MOV     XMATTIO,AX              ; Put it into "port" 31A2H
 01AE  A3 0004 R		        MOV     XMATTII,AX              ; Put it into "port" 31A4H
				
 01B1  C3			        RET
				
 01B2				TTARCHANGED     ENDP
				
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-14
                                                            

				PAGE
				
				; UPDATETT will update the "translate table" and the corresponding page
				; tables when an XMA block number is written to either port 31A2H or the
				; auto-increment port 31A4H.  A write to either of these ports means to set
				; the XMA block specified at the translate table entry indicated in port
				; 31A0H.
				;
				; The Emulator is set up to look like an XMA 2 card with the INDXMAA device  D1C
				; driver.  When the system comes up the XMA card is initially disabled.      D1C
				; INDXMAA then backs memory from 0K to 640K on the system board with memory  D1C
				; from 0K to 640K on the XMA card.  To emulate this, the Emulator treats     D1C
				; real memory from 0K to 640K as XMA blocks from 0K to 640K on the XMA card. D1C
				; This both saves memory and requires no code to back the real memory from   D1C
				; 0K to 640K with XMA memory on initialization.  The Emulator therefore only D1C
				; needs to allocate XMA memory for the XMA blocks over 640K.  The XMA memory D1C
				; for over 640K starts at 12000:0.  The XMA blocks 00H to 9FH will be mapped D1C
				; to the motherboard memory at 0K to 640K.  The XMA blocks A0H and up will   D1C
				; be mapped to the memory at 12000:0 and up.                                 D1C
				;
				; Bits 15 (IBM bit 0) and 11 (IBM bit 4) of the XMA block number have
				; special meanings.  When bit 15 is on it means that the block number is a
				; 15 bit number.  This is in anticipation of larger block numbers in the
				; future.  Current block numbers are 11 bits.  When bit 11 is on it means
				; that the XMA translation for this translation table entry should be
				; disabled.  The memory for this 4K block should be mapped back to real
				; memory.
				;
				; We also check to make sure that the XMA block is not above the XMA memory
				; limit.  XMA memory ends where the MOVEBLOCK buffer starts.  If the XMA
				; block is above the end of XMA memory then the page table entry for that
				; address is set to point to non-existent memory.
				;
				; When address translation is disabled for addresses above 640K then the     D1C
				; page table entry for that address is set to point back to real memory.     D1C
				; For disabled pages in the range 0K to 640K the page table entry is set to  D1C
				; point to non-existent memory.                                              D1C
				
 01B2				UPDATETT        PROC
				
 01B2  A1 0000 R		        MOV     AX,XMATTAR              ; Get the index of the TT entry that
				                                        ;   is to be changed
 01B5  25 0FFF			        AND     AX,0FFFH                ; Clear the high four bits.  They are
				                                        ;   not used.
 01B8  D1 E0			        SHL     AX,1                    ; Change to a word offset since the TT
				                                        ;   entries are words.
 01BA  8D 3E 0000 E		        LEA     DI,TTTABLE              ; Point DI to the translate table base
 01BE  03 F8			        ADD     DI,AX                   ; Add on the offset of the entry that
				                                        ;   is to be changed
 01C0  A1 0002 R		        MOV     AX,XMATTIO              ; Get the block number to be written
 01C3  AB			        STOSW                           ; Store the block number in the TT
				
				; Convert bank number to a page address.
				; The following code works only with paging enabled at 256k boundary.
				; It is intended to support up to 128M at 4k granularity.
				; It interprets the high order bits as a superset of XMA.
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-15
                                                            

				; Following is a truth table for bits 11 (XMA inhibit bit) and 15 ("enable-hi").
				;   15   11
				;    0    0   =   enabled 11 bit address
				;    0    1   =   disabled address
				;    1    x   =   enabled 15 bit address
				
 01C4  F6 C4 80			        TEST    AH,80H                  ; Is this a 15 bit block number?
 01C7  74 0B			        JZ      SMALL                   ; Far from it.  Go do stuff for 11 bit
				                                        ;   block numbers.
				
				; We have a 15 bit address
				
 01C9  3D FFFF			        CMP     AX,0FFFFH               ; If it's FFFFH then we treat it the
				                                        ;   the same as 0FFFH which means
 01CC  74 39			        JE      DISABLEPAGE             ;   disable the page
				
 01CE  25 7FFF			        AND     AX,7FFFH                ; Turn off the 15 bit address bit
 01D1  EB 09 90			        JMP     BOTH                    ;   leaving a valid block number for
				                                        ;   our calculations later
				
 01D4				SMALL:
 01D4  F6 C4 08			        TEST    AH,08H                  ; Is the disable bit on?
 01D7  75 2E			        JNZ     DISABLEPAGE             ; Yes.  Go disable the page.
				
 01D9  25 07FF			        AND     AX,07FFH                ; No.  Turn off the high nibble and the
				                                        ;   disable bit leaving a valid block
				                                        ;   number for our upcoming calculations
 01DC				BOTH:
 01DC  3D 00A0			        CMP     AX,640/4                ; Is this block number for 640K or over?
 01DF  72 03			        JB      NOADJUST                ; Yup.  There's no adjustment       @D1C
				                                        ;   needed for blocks between 0K and
				                                        ;   640K since we use real memory for
				                                        ;   these blocks.
				                                        ; XMA 1 emulation code deleted     3@D1D
 01E1  05 0080			        ADD     AX,HIMEM-(640/4)        ; Add on the adjustment needed for  @D1C
				                                        ;   blocks above 640K to point to
				                                        ;   the XMA blocks starting at 12000:0.
				                                        ;   But don't forget to subtract the
				                                        ;   block number for 640K.  This makes
				                                        ;   the block number 0 based before we
				                                        ;   add on the block number for 12000:0.
 01E4				NOADJUST:
				        DATAOV                          ; Shift the high order 16 bits of EAX
 01E4  66                    1	         DB      066H 
 01E5  C1 E0 10			        SHL     AX,16                   ;   off the left end of the register.
				        DATAOV                          ; Now shift the block number back four
 01E8  66                    1	         DB      066H 
 01E9  C1 E8 04			        SHR     AX,16-12                ;   bits.  This results in a net shift
				                                        ;   left of 12 bits which converts the
				                                        ;   block number to an offset, and it
				                                        ;   clears the high four bits.
 01EC  0C 07			        OR      AL,7                    ; Set the access and present bits.  This
				                                        ;   converts our offset to a valid page
				                                        ;   table entry.
				        DATAOV                          ; Save the page table entry in EBX for
 01EE  66                    1	         DB      066H 
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-16
                                                            

 01EF  8B D8			        MOV     BX,AX                   ;   now
				
				; Now we must make sure the offset of our XMA page frame is within the address
				; space of the XMA pages, that is, it is below the start of the MOVEBLOCK
				; buffer.
				
				        DATAOV                          ; Clear all 32 bits of EAX
 01F1  66                    1	         DB      066H 
 01F2  2B C0			        SUB     AX,AX
 01F4  A1 0000 E		        MOV     AX,MAXMEM               ; Load up the number of K on the box
 01F7  2B 06 0000 E		        SUB     AX,BUFF_SIZE            ; Subtract the number of K reserved
				                                        ;   for the MOVEBLOCK buffer
				        DATAOV                          ; Multiply by 1K (shift left 10) to
 01FB  66                    1	         DB      066H 
 01FC  C1 E0 0A			        SHL     AX,10                   ;   convert it to an offset
				        DATAOV                          ; Is the XMA page address below the
 01FF  66                    1	         DB      066H 
 0200  3B D8			        CMP     BX,AX                   ;   MOVEBLOCK buffer address?
 0202  72 2C			        JB      ENABLED                 ; Yup.  Whew!  Let's go set up the page
				                                        ;   table entry for this XMA block.
 0204  EB 08 90			        JMP     EMPTY                   ; Nope.  Rats!  Well, we'll just have
				                                        ;   to point this TT entry to unbacked
				                                        ;   memory.
				
				; We come here when we want to disable translation for this translate table
				; entry.  For TT entries for 640K and over we just point the translate table
				; entry back to real memory.  For TT entries between 0K and 640K we point
				; the translate table to unbacked memory.  This memory on the motherboard
				; was disabled under real XMA so we emulate it by pointing to unbacked
				; memory.
				
 0207				DISABLEPAGE:
				                                        ; XMA 1 emulation code deleted     2@D1D
 0207  80 3E 0000 R A0		        CMP     BYTE PTR XMATTAR,640/4  ; Is the address at 640K or above?
 020C  73 12			        JNB     SPECIAL                 ; Aye.  Go point back to real memory.
				
				; The address is between 256K and 640K.  Let's set the page table entry to
				; point to non-exiatent memory.
				
 020E				EMPTY:
				        DATAOV                          ; Clear EAX
 020E  66                    1	         DB      066H 
 020F  2B C0			        SUB     AX,AX
 0211  A1 0000 E		        MOV     AX,MAXMEM               ; Get the total number of K on the box
				        DATAOV                          ; Multiply by 1024 to convert to an
 0214  66                    1	         DB      066H 
 0215  C1 E0 0A			        SHL     AX,10                   ;   offset.  AX now points to the 4K
				                                        ;   page frame after the end of memory.
 0218  0C 07			        OR      AL,7                    ; Turn on the accessed and present bits
				                                        ;    to avoid page faults
				        DATAOV                          ; Save the page table entry in EBX
 021A  66                    1	         DB      066H 
 021B  8B D8			        MOV     BX,AX
 021D  EB 11 90			        JMP     ENABLED                 ; Go set up the page table
				
				; If the address is above 640K then the translate table (page table) entry   D1C
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-17
                                                            

				; is set to point back to real memory.
 0220				SPECIAL:
 0220  A1 0000 R		        MOV     AX,XMATTAR              ; Get the index of the TT entry that is
				                                        ;   to be disabled
				        DATAOV                          ; Dump the high 24 bits off the left end
 0223  66                    1	         DB      066H 
 0224  C1 E0 18			        SHL     AX,24                   ;   of the register
				        DATAOV                          ; Now shift it back 12 bits.  This
 0227  66                    1	         DB      066H 
 0228  C1 E8 0C			        SHR     AX,24-12                ;   results in a net shift left of 12
				                                        ;   bits which multiplies the TT index
				                                        ;   by 4K while at the same time clear-
				                                        ;   ing the high order bits.  EAX is now
				                                        ;   the offset of the memory pointed to
				                                        ;   by the TT entry.
 022B  0C 07			        OR      AL,7                    ; Turn on the accessed and present bits
				                                        ;   to make this a page table entry
				        DATAOV                          ; Save the page table entry in EBX
 022D  66                    1	         DB      066H 
 022E  8B D8			        MOV     BX,AX
				
				; Now let's put the new page table entry in EBX, which represents the XMA block,
				; into the page table.
 0230				ENABLED:
 0230  A1 0000 R		        MOV     AX,XMATTAR              ; Get the index of the TT entry
				
				; Now we want ot convert the index of the TT entry to an offset into our XMA
				; page tables.  The bank number is now in AH and the 4K block number of the
				; bank is in AL.  To point to the right page table we need to multiply the bank
				; number by 4K (shift left 12 bits) since page tables are 4K in length.  The
				; bank number is already shifted left 8 bits by virtue of it being in AH.  It
				; needs to be shifted left four more bits.  In order to access the right entry
				; in the page table, the block number in AL must be multiplied by 4 (shifted
				; left two bits) because the page table entries are 4 bytes in length.  So,
				; first we shift AH left two bits and then shift AX left two bits.  In the end
				; this shifts AH, the bank ID, left four bits and shifts AL, the block number,
				; two bits, which is what we wanted.  A long explanation for two instructions,
				; but they're pretty efficient, don't you think?
				
 0233  C0 E4 02			        SHL     AH,2                    ; Shift the bank ID left two bits
 0236  C1 E0 02			        SHL     AX,2                    ; Shift the bank ID and the block number
				                                        ;   left two bits
 0239  8B F8			        MOV     DI,AX                   ; Load DI with the offset of the page
				                                        ;   table entry that is to be changed
 023B  06			        PUSH    ES                      ; Save ES
 023C  B8 0018			        MOV     AX,XMA_PAGES_SEL        ; Load ES with the selector for our
 023F  8E C0			        MOV     ES,AX                   ;   XMA page tables.  Now ES:DI points
				                                        ;   to the page table entry to be
				                                        ;   changed
				        DATAOV                          ; Get the new value for the page table
 0241  66                    1	         DB      066H 
 0242  8B C3			        MOV     AX,BX                   ;   entry which was saved in EBX.
				        DATAOV                          ; Stuff it into the page table - all
 0244  66                    1	         DB      066H 
 0245  AB			        STOSW                           ;   32 bits of it.
				
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Page     1-18
                                                            

 0246  07			        POP     ES                      ; Restore ES
				
 0247  C3			        RET                             ; And return
				
 0248				UPDATETT        ENDP
				
 0248				XMAIN   ENDP
				
 0248				PROG    ENDS
				
				        END

Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-1


Macros:

		N a m e			Lines

ADDROV . . . . . . . . . . . . .  	   1
CALLFAR  . . . . . . . . . . . .  	   3
CMOV . . . . . . . . . . . . . .  	  43
DATAOV . . . . . . . . . . . . .  	   1
DMOV . . . . . . . . . . . . . .  	  43
ELFS . . . . . . . . . . . . . .  	   2
ELGS . . . . . . . . . . . . . .  	   2
ELSS . . . . . . . . . . . . . .  	   2
ERIMUL . . . . . . . . . . . . .  	   2
ESHLD  . . . . . . . . . . . . .  	   2
ESHLDI . . . . . . . . . . . . .  	   3
ESHRD  . . . . . . . . . . . . .  	   2
ESHRDI . . . . . . . . . . . . .  	   3
F_BASE . . . . . . . . . . . . .  	  19
F_BREG . . . . . . . . . . . . .  	  17
F_DREG . . . . . . . . . . . . .  	  17
F_INDEX  . . . . . . . . . . . .  	  19
F_MOD  . . . . . . . . . . . . .  	  32
F_SCALE  . . . . . . . . . . . .  	   9
F_WREG . . . . . . . . . . . . .  	  17
JECEXZ . . . . . . . . . . . . .  	   2
JUMPFAR  . . . . . . . . . . . .  	   3
LFS  . . . . . . . . . . . . . .  	   1
LGS  . . . . . . . . . . . . . .  	   1
LJA  . . . . . . . . . . . . . .  	   1
LJAE . . . . . . . . . . . . . .  	   1
LJB  . . . . . . . . . . . . . .  	   1
LJBE . . . . . . . . . . . . . .  	   1
LJC  . . . . . . . . . . . . . .  	   1
LJCOND . . . . . . . . . . . . .  	   5
LJE  . . . . . . . . . . . . . .  	   1
LJG  . . . . . . . . . . . . . .  	   1
LJGE . . . . . . . . . . . . . .  	   1
LJL  . . . . . . . . . . . . . .  	   1
LJLE . . . . . . . . . . . . . .  	   1
LJNA . . . . . . . . . . . . . .  	   1
LJNB . . . . . . . . . . . . . .  	   1
LJNBE  . . . . . . . . . . . . .  	   1
LJNC . . . . . . . . . . . . . .  	   1
LJNE . . . . . . . . . . . . . .  	   1
LJNG . . . . . . . . . . . . . .  	   1
LJNGE  . . . . . . . . . . . . .  	   1
LJNL . . . . . . . . . . . . . .  	   1
LJNLE  . . . . . . . . . . . . .  	   1
LJNO . . . . . . . . . . . . . .  	   1
LJNP . . . . . . . . . . . . . .  	   1
LJNS . . . . . . . . . . . . . .  	   1
LJNZ . . . . . . . . . . . . . .  	   1
LJO  . . . . . . . . . . . . . .  	   1
LJP  . . . . . . . . . . . . . .  	   1
LJPE . . . . . . . . . . . . . .  	   1
LJPO . . . . . . . . . . . . . .  	   1
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-2


LJS  . . . . . . . . . . . . . .  	   1
LJZ  . . . . . . . . . . . . . .  	   1
LNAE . . . . . . . . . . . . . .  	   1
LSS  . . . . . . . . . . . . . .  	   1
MK_DISP  . . . . . . . . . . . .  	  12
MK_IMMD  . . . . . . . . . . . .  	  24
NEWLS  . . . . . . . . . . . . .  	  13
POP_FS . . . . . . . . . . . . .  	   2
POP_GS . . . . . . . . . . . . .  	   2
PUSH_FS  . . . . . . . . . . . .  	   2
PUSH_GS  . . . . . . . . . . . .  	   2
RIMUL  . . . . . . . . . . . . .  	  14
SEGOV  . . . . . . . . . . . . .  	  48
SHDOP  . . . . . . . . . . . . .  	  14
SHLD . . . . . . . . . . . . . .  	   1
SHLDI  . . . . . . . . . . . . .  	   2
SHRD . . . . . . . . . . . . . .  	   1
SHRDI  . . . . . . . . . . . . .  	   2
SMOV . . . . . . . . . . . . . .  	  53
TMOV . . . . . . . . . . . . . .  	  45

Structures and Records:

                N a m e                 Width   # fields
                                        Shift   Width   Mask    Initial

BPSTACK  . . . . . . . . . . . .  	0050	0028
  BP_ES  . . . . . . . . . . . .  	0000
  BP_DI  . . . . . . . . . . . .  	0002
  BP_SI  . . . . . . . . . . . .  	0006
  BP_BP  . . . . . . . . . . . .  	000A
  BP_PASP  . . . . . . . . . . .  	000E
  BP_PSP2  . . . . . . . . . . .  	0010
  BP_BX  . . . . . . . . . . . .  	0012
  BP_DX  . . . . . . . . . . . .  	0016
  BP_CX  . . . . . . . . . . . .  	001A
  BP_AX  . . . . . . . . . . . .  	001E
  BP_DS  . . . . . . . . . . . .  	0022
  BP_EX  . . . . . . . . . . . .  	0024
  BP_EC  . . . . . . . . . . . .  	0026
  BP_IP  . . . . . . . . . . . .  	002A
  BP_IP2 . . . . . . . . . . . .  	002C
  BP_CS  . . . . . . . . . . . .  	002E
  BP_CS2 . . . . . . . . . . . .  	0030
  BP_FL  . . . . . . . . . . . .  	0032
  BP_FL2 . . . . . . . . . . . .  	0034
  BP_SP  . . . . . . . . . . . .  	0036
  BP_SP2 . . . . . . . . . . . .  	0038
  BP_SS  . . . . . . . . . . . .  	003A
  BP_SS2 . . . . . . . . . . . .  	003C
  BP_VMES  . . . . . . . . . . .  	003E
  BP_VME2  . . . . . . . . . . .  	0040
  BP_VMDS  . . . . . . . . . . .  	0042
  BP_VMFS  . . . . . . . . . . .  	0046
  BP_VMGS  . . . . . . . . . . .  	004A
  BP_STK . . . . . . . . . . . .  	004E
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-3


DATA_DESC  . . . . . . . . . . .  	0008	0005
  SEG_LIMIT  . . . . . . . . . .  	0000
  BASE_LO_WORD . . . . . . . . .  	0002
  BASE_HI_BYTE . . . . . . . . .  	0004
  DATA_ACC_RIGHTS  . . . . . . .  	0005
  DATA_RESERVED  . . . . . . . .  	0006
GATE_DESC  . . . . . . . . . . .  	0008	0005
  ENTRY_POINT  . . . . . . . . .  	0000
  CS_SELECTOR  . . . . . . . . .  	0002
  WORD_COUNT . . . . . . . . . .  	0004
  GATE_ACC_RIGHTS  . . . . . . .  	0005
  GATE_RESERVED  . . . . . . . .  	0006
GDT_DEF  . . . . . . . . . . . .  	1001	0036
  UNUSED_ENTRY . . . . . . . . .  	0000
  GDT_PTR  . . . . . . . . . . .  	0008
  MON_IDT_PTR  . . . . . . . . .  	0010
  RSDA_PTR . . . . . . . . . . .  	0018
  HUGE_PTR . . . . . . . . . . .  	0020
  LA_PTR . . . . . . . . . . . .  	0028
  C_BWCRT_PTR  . . . . . . . . .  	0030
  C_CCRT_PTR . . . . . . . . . .  	0038
  E_CCRT_PTR . . . . . . . . . .  	0040
  E_CCRT_PTR2  . . . . . . . . .  	0048
  SYS_ROM_CS . . . . . . . . . .  	0050
  SYS_ROM_DS . . . . . . . . . .  	0058
  SYS_PATCH_CS . . . . . . . . .  	0060
  SYS_PATCH_DS . . . . . . . . .  	0068
  V_ROM_CS . . . . . . . . . . .  	0070
  V_ROM_DS . . . . . . . . . . .  	0078
  V_PATCH_CS . . . . . . . . . .  	0080
  V_PATCH_DS . . . . . . . . . .  	0088
  ES_TEMP  . . . . . . . . . . .  	0090
  CS_TEMP  . . . . . . . . . . .  	0098
  SS_TEMP  . . . . . . . . . . .  	00A0
  DS_TEMP  . . . . . . . . . . .  	00A8
  MON_LDTR . . . . . . . . . . .  	00B0
  MON_DS . . . . . . . . . . . .  	00B8
  MON_ES . . . . . . . . . . . .  	00C0
  MON_SS . . . . . . . . . . . .  	00C8
  MON_CS . . . . . . . . . . . .  	00D0
  MON_TR_SS  . . . . . . . . . .  	00D8
  MON_TR_BP  . . . . . . . . . .  	00E0
  MON_TR_HWI . . . . . . . . . .  	00E8
  MON_TR_OI  . . . . . . . . . .  	00F0
  KBD_OWNER_SDA  . . . . . . . .  	00F8
  VTIMER_VECTOR  . . . . . . . .  	0100
  SEX_TSS  . . . . . . . . . . .  	0180
  HWI_TSS  . . . . . . . . . . .  	0280
  DISPATCH_TASK  . . . . . . . .  	0380
  HWI_LDT  . . . . . . . . . . .  	0390
  BASICS_SEG . . . . . . . . . .  	0398
  BIOSS_SEG  . . . . . . . . . .  	03A0
  RSVD_GDT . . . . . . . . . . .  	03A8
  PM_VM  . . . . . . . . . . . .  	0DC0
  USER_CS  . . . . . . . . . . .  	0DE0
  USER_SS  . . . . . . . . . . .  	0DE8
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-4


  USER_DS  . . . . . . . . . . .  	0DF0
  USER_ES  . . . . . . . . . . .  	0DF8
  USER_TSS . . . . . . . . . . .  	0E00
  USER_TSS_DAT . . . . . . . . .  	0E08
  USER_LDT . . . . . . . . . . .  	0E10
  USER_LDT_DAT . . . . . . . . .  	0E18
  USER_VMS . . . . . . . . . . .  	0E20
  SCRUBBER . . . . . . . . . . .  	0FE0
  LAST_GDT_BYTE  . . . . . . . .  	1000
SELECTOR . . . . . . . . . . . .  	0010	0003
  INDEX  . . . . . . . . . . . .  	0003	000D	FFF8	0000
  TI . . . . . . . . . . . . . .  	0002	0001	0004	0000
  RPL  . . . . . . . . . . . . .  	0000	0002	0003	0000
TASK_STATE_286 . . . . . . . . .  	002C	0016
  BACK_LINK  . . . . . . . . . .  	0000
  VM_SP0 . . . . . . . . . . . .  	0002
  VM_SS0 . . . . . . . . . . . .  	0004
  VM_SP1 . . . . . . . . . . . .  	0006
  VM_SS1 . . . . . . . . . . . .  	0008
  VM_SP2 . . . . . . . . . . . .  	000A
  VM_SS2 . . . . . . . . . . . .  	000C
  VM_IP  . . . . . . . . . . . .  	000E
  VM_FL  . . . . . . . . . . . .  	0010
  VM_AX  . . . . . . . . . . . .  	0012
  VM_CX  . . . . . . . . . . . .  	0014
  VM_DX  . . . . . . . . . . . .  	0016
  VM_BX  . . . . . . . . . . . .  	0018
  VM_SP  . . . . . . . . . . . .  	001A
  VM_BP  . . . . . . . . . . . .  	001C
  VM_SI  . . . . . . . . . . . .  	001E
  VM_DI  . . . . . . . . . . . .  	0020
  VM_ES  . . . . . . . . . . . .  	0022
  VM_CS  . . . . . . . . . . . .  	0024
  VM_SS  . . . . . . . . . . . .  	0026
  VM_DS  . . . . . . . . . . . .  	0028
  VM_LDT . . . . . . . . . . . .  	002A
TSS386 . . . . . . . . . . . . .  	006C	002B
  ETSS_BACK_LINK . . . . . . . .  	0002
  ETSS_SP0 . . . . . . . . . . .  	0004
  ETSS_SS0 . . . . . . . . . . .  	0008
  ETSS_SP1 . . . . . . . . . . .  	000C
  ETSS_SS1 . . . . . . . . . . .  	0010
  ETSS_SP2 . . . . . . . . . . .  	0014
  ETSS_SS2 . . . . . . . . . . .  	0018
  ETSS_CR3 . . . . . . . . . . .  	001C
  ETSS_IP  . . . . . . . . . . .  	0020
  ETSS_FL  . . . . . . . . . . .  	0024
  ETSS_FL2 . . . . . . . . . . .  	0026
  ETSS_AX  . . . . . . . . . . .  	0028
  ETSS_CX  . . . . . . . . . . .  	002C
  ETSS_DX  . . . . . . . . . . .  	0030
  ETSS_BX  . . . . . . . . . . .  	0034
  ETSS_SP  . . . . . . . . . . .  	0038
  ETSS_BP  . . . . . . . . . . .  	003C
  ETSS_SI  . . . . . . . . . . .  	0040
  ETSS_DI  . . . . . . . . . . .  	0044
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-5


  ETSS_ES  . . . . . . . . . . .  	0048
  ETSS_CS  . . . . . . . . . . .  	004C
  ETSS_SS  . . . . . . . . . . .  	0050
  ETSS_DS  . . . . . . . . . . .  	0054
  ETSS_FS  . . . . . . . . . . .  	0058
  ETSS_GS  . . . . . . . . . . .  	005C
  ETSS_LDT . . . . . . . . . . .  	0060
  ETSS_TRAP  . . . . . . . . . .  	0064
  ETSS_BM_OFFSET . . . . . . . .  	0066
  ETSS_AVL . . . . . . . . . . .  	0068
VM_GDT_ENTRY . . . . . . . . . .  	0020	0004
  VM_TR  . . . . . . . . . . . .  	0000
  TSS_PTR  . . . . . . . . . . .  	0008
  VM_LDTR  . . . . . . . . . . .  	0010
  LDT_PTR  . . . . . . . . . . .  	0018

Segments and Groups:

                N a m e         	Length	 Align	Combine Class

PROG . . . . . . . . . . . . . .  	0248	PARA	PUBLIC	'PROG'

Symbols:            

                N a m e         	Type	 Value	 Attr

BLANK  . . . . . . . . . . . . .  	NUMBER	0020	
BOOT_CS  . . . . . . . . . . . .  	NUMBER	0000	
BOOT_FL  . . . . . . . . . . . .  	NUMBER	0200	
BOOT_IP  . . . . . . . . . . . .  	NUMBER	7C00	
BOOT_SP  . . . . . . . . . . . .  	NUMBER	07FF	
BOOT_SS  . . . . . . . . . . . .  	NUMBER	0030	
BOTH . . . . . . . . . . . . . .  	L NEAR	01DC	PROG
BP_START . . . . . . . . . . . .  	NUMBER	0000	
BUFF_SIZE  . . . . . . . . . . .  	V WORD	0000	PROG	External

CARD_ENABL . . . . . . . . . . .  	NUMBER	0004	
CCRT@_HI . . . . . . . . . . . .  	NUMBER	000B	
CCRT@_LO . . . . . . . . . . . .  	NUMBER	8000	
CCRT_SIZE  . . . . . . . . . . .  	NUMBER	4000	
CHKA4  . . . . . . . . . . . . .  	L NEAR	013F	PROG
CHKCNTRL . . . . . . . . . . . .  	L NEAR	015E	PROG
CRT_SELECTOR . . . . . . . . . .  	NUMBER	0030	
CSEG@_HI . . . . . . . . . . . .  	NUMBER	000E	
CSEG@_LO . . . . . . . . . . . .  	NUMBER	0000	
CS_HI_CACHE  . . . . . . . . . .  	NUMBER	0000	
CS_LO_CACHE  . . . . . . . . . .  	NUMBER	0000	

DESC_LEN . . . . . . . . . . . .  	NUMBER	0008	
DESC_WIDTH . . . . . . . . . . .  	NUMBER	0003	
DISABLEPAGE  . . . . . . . . . .  	L NEAR	0207	PROG
DISPATCH_LOC . . . . . . . . . .  	NUMBER	D900	
DMAIN  . . . . . . . . . . . . .  	L NEAR	0000	PROG	External
DMAOUT . . . . . . . . . . . . .  	L NEAR	0000	PROG	External

ECCRT@_HI_HI . . . . . . . . . .  	NUMBER	000C	
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-6


ECCRT@_HI_LO . . . . . . . . . .  	NUMBER	0000	
ECCRT@_LO_HI . . . . . . . . . .  	NUMBER	000A	
ECCRT@_LO_LO . . . . . . . . . .  	NUMBER	0000	
ECCRT_SIZE . . . . . . . . . . .  	NUMBER	FFFF	
EMPTY  . . . . . . . . . . . . .  	L NEAR	020E	PROG
ENABLED  . . . . . . . . . . . .  	L NEAR	0230	PROG

GDT_LEN  . . . . . . . . . . . .  	NUMBER	1000	
GDT_LOC  . . . . . . . . . . . .  	NUMBER	C100	
GETWORD  . . . . . . . . . . . .  	L NEAR	0086	PROG
GO_MODE  . . . . . . . . . . . .  	NUMBER	0001	

HEXW . . . . . . . . . . . . . .  	L NEAR	0000	PROG	External
HIMEM  . . . . . . . . . . . . .  	NUMBER	0120	

INDEX  . . . . . . . . . . . . .  		0003	
INDEXMA  . . . . . . . . . . . .  	L NEAR	0000	PROG	Global
INEXIT . . . . . . . . . . . . .  	L NEAR	009C	PROG
INIMMED  . . . . . . . . . . . .  	L NEAR	0020	PROG	Global
INW  . . . . . . . . . . . . . .  	L NEAR	0009	PROG	Global
INWIMMED . . . . . . . . . . . .  	L NEAR	0016	PROG	Global

LA_LEN . . . . . . . . . . . . .  	ALIAS	 GDT_LEN		
LDT_LEN  . . . . . . . . . . . .  	NUMBER	0800	

MAXMEM . . . . . . . . . . . . .  	V WORD	0000	PROG	External
MAX_SEG_LEN  . . . . . . . . . .  	NUMBER	FFFF	
MCRT@_HI . . . . . . . . . . . .  	NUMBER	000B	
MCRT@_LO . . . . . . . . . . . .  	NUMBER	0000	
MCRT_SIZE  . . . . . . . . . . .  	NUMBER	1000	
MEMX . . . . . . . . . . . . . .  	NUMBER	0002	

NEXT_DESC  . . . . . . . . . . .  	NUMBER	0008	
NOADJUST . . . . . . . . . . . .  	L NEAR	01E4	PROG
NORMPAGE . . . . . . . . . . . .  	V WORD	0000	PROG	External
NOTXMAIN . . . . . . . . . . . .  	L NEAR	0083	PROG
NOTXMAOUT  . . . . . . . . . . .  	L NEAR	015B	PROG	Global
NSEG@_HI . . . . . . . . . . . .  	NUMBER	0000	
NSEG@_LO . . . . . . . . . . . .  	NUMBER	0000	
NULL_SEG_LEN . . . . . . . . . .  	NUMBER	0000	

OTHER_CACHE  . . . . . . . . . .  	NUMBER	0000	
OUTEXIT  . . . . . . . . . . . .  	L NEAR	018D	PROG
OUTEXITDMA . . . . . . . . . . .  	L NEAR	0195	PROG
OUTW . . . . . . . . . . . . . .  	L NEAR	00A3	PROG	Global
OUTWIMMED  . . . . . . . . . . .  	L NEAR	00B0	PROG	Global

PGTBLOFF . . . . . . . . . . . .  	V WORD	0000	PROG	External
PM_VM_SIZE . . . . . . . . . . .  	NUMBER	1000	
POPIO  . . . . . . . . . . . . .  	L NEAR	0000	PROG	External
PUTWORD  . . . . . . . . . . . .  	L NEAR	0121	PROG

RPL  . . . . . . . . . . . . . .  		0000	

SETXMA . . . . . . . . . . . . .  	L NEAR	0172	PROG
SEX_ATTR . . . . . . . . . . . .  	NUMBER	4B00	
Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11
INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-7


SGTBLOFF . . . . . . . . . . . .  	V WORD	0000	PROG	External
SHADOW_ID  . . . . . . . . . . .  	ALIAS	 DATA_RESERVED		
SIDT_LEN . . . . . . . . . . . .  	NUMBER	0800	
SIDT_LOC . . . . . . . . . . . .  	NUMBER	D100	
SMALL  . . . . . . . . . . . . .  	L NEAR	01D4	PROG
SPECIAL  . . . . . . . . . . . .  	L NEAR	0220	PROG
SS_HI_CACHE  . . . . . . . . . .  	NUMBER	0000	
SS_LO_CACHE  . . . . . . . . . .  	NUMBER	0300	
STACK_ATTR . . . . . . . . . . .  	NUMBER	0700	
S_MODE . . . . . . . . . . . . .  	NUMBER	2000	

THIRTY_TWO_K . . . . . . . . . .  	NUMBER	8000	
TI . . . . . . . . . . . . . . .  		0002	
TSS_386_LEN  . . . . . . . . . .  	NUMBER	0068	
TSS_BM_LEN . . . . . . . . . . .  	NUMBER	0F97	
TSS_LEN  . . . . . . . . . . . .  	NUMBER	2068	
TTARCHANGED  . . . . . . . . . .  	N PROC	019C	PROG	Length = 0016
TTAROUT  . . . . . . . . . . . .  	L NEAR	0155	PROG
TTTABLE  . . . . . . . . . . . .  	V WORD	0000	PROG	External

UPDATETT . . . . . . . . . . . .  	N PROC	01B2	PROG	Length = 0096

VIRTUAL_ENABLE . . . . . . . . .  	NUMBER	0001	
VM_ENTRY_LENGTH  . . . . . . . .  	NUMBER	0020	
VM_ENTRY_WIDTH . . . . . . . . .  	NUMBER	0005	

WORD_FLAG  . . . . . . . . . . .  	L BYTE	0008	PROG	Global

XMACTL . . . . . . . . . . . . .  	L BYTE	0007	PROG	Global
XMAIN  . . . . . . . . . . . . .  	N PROC	004A	PROG	Global	Length = 01FE
XMAOUT . . . . . . . . . . . . .  	L NEAR	00E4	PROG	Global
XMAOUTIMMED  . . . . . . . . . .  	L NEAR	00BA	PROG	Global
XMAPAGE  . . . . . . . . . . . .  	V WORD	0000	PROG	External
XMATID . . . . . . . . . . . . .  	L BYTE	0006	PROG	Global
XMATTAR  . . . . . . . . . . . .  	L WORD	0000	PROG	Global
XMATTII  . . . . . . . . . . . .  	L WORD	0004	PROG	Global
XMATTIO  . . . . . . . . . . . .  	L WORD	0002	PROG	Global
XMA_PAGES_SEL  . . . . . . . . .  	ALIAS	 RSDA_PTR		

@CPU . . . . . . . . . . . . . .  	TEXT  1415		
@FILENAME  . . . . . . . . . . .  	TEXT  INDEXMA		
@VERSION . . . . . . . . . . . .  	TEXT  510		
_CRCNT . . . . . . . . . . . . .  	NUMBER	0003	
_CREGFD  . . . . . . . . . . . .  	NUMBER	0001	
_DREGNUM . . . . . . . . . . . .  	NUMBER	0000	

Microsoft (R) Macro Assembler Version 5.10                  5/17/24 09:44:11

INDEXMA - 386 XMA Emulator - XMA Emulation                  Symbols-8






   1316 Source  Lines
   1620 Total   Lines
    341 Symbols

  45784 + 138535 Bytes symbol space free

      0 Warning Errors
      0 Severe  Errors
