INT 21 U - Qualitas 386MAX v6.00+ - IOCTL INPUT - GET STATE
AX = 4402h
BX = file handle for device "386MAX$$"
CX = 005Ah
DS:DX -> 386MAX state buffer (see below)
Return: CF clear if successful
buffer filled
AX = number of bytes actually copied
CF set on error
AX = error code (01h,05h,06h,0Dh) (see AH=59h)
Notes:  the buffer must be one byte larger than the value given in CX; if the
value is less than 5Ah, only a partial state record will be returned
the state is 40h bytes for 386MAX (actually ASTEMM) v2.20 ("386MAX$$"
did not exist yet, use "QMMXXXX0" and then "EMMXXXX0" instead) and
56h bytes for v5.11.
to invoke 386MAX API functions, push DX onto the stack, load DX with
the word at offset 25h in the returned state, load all other
registers as needed for the desired function, and execute an
OUT DX,AL or OUT DX,AX; DX will be set to the pushed value on return
if it is not otherwise modified by the API function.
SeeAlso: INT 67/AH=3Fh

Format of 386MAX v6.01 state:
Offset  Size    Description
00h    BYTE    version number of state structure (must be set on entry;
v6.01 returns an error if not 03h)
01h  6 BYTEs   signature "386MAX"
07h  4 BYTEs   version string "N;NN" (i.e. "6;01" for v6.01)
0Bh    WORD    segment of low-memory portion of 386MAX.SYS
0Dh  2 BYTEs   ???
0Fh    WORD    segment of ??? memory block or 0000h
11h    WORD    bit flags
bit 1: ???
bit 2: ???
bit 3: ??? (cleared by calling INT 67 functions)
bit 5: ???
bit 6: 386MAX active???
bit 7: 386MAX is providing EMS services
bit 8: ???
bit 9: ??? (see INT 15/AX=2402h)
bit 10: ???
bit 11: ???
bit 12: ???
bit 13: QPMS has been used
bit 14: ???
bit 15: ???
13h    WORD    starting address of video memory in K
15h  8 BYTEs   ???
1Dh    WORD    KBytes extended memory used by 386MAX
1Fh  2 BYTEs   ???
21h    WORD    ???
23h    WORD    IO port to write (OUT DX,AL) to invoke 386MAX INT 15 functions
25h    WORD    IO port to write (OUT DX,AL) to invoke 386MAX API functions
27h    WORD    ???
29h  2 BYTEs   ???
2Bh    DWORD   ???
2Fh  4 BYTEs   ???
33h    WORD    system configuration??? flags
bit 1: ROM compressed???
bit 3: ???
bit 5: 386MAX loaded into high memory
bit 11: PC/XT (thus only single 8259 interrupt controller
present, DMA only in 1st megabyte, etc)
35h    WORD    ??? bit flags
37h  4 BYTEs   ???
3Bh    WORD    segment of first MCB in high memory chain???
3Dh    WORD    flags
bit 2: no DPMI services
bit 11: don't backfill holes in video memory area
bit 12: don't backfill below video memory???
3Fh    WORD    flags
bit 7: ???
41h    WORD    flags
bit 0: Windows3 support enabled
bit 8: ???
43h  2 BYTEs   ???
45h    WORD    amount of memory to report available on INT 15/AH=88h
47h  4 BYTEs   ???
4Bh    WORD    ???
4Dh  2 BYTEs   ???
4Fh    WORD    ???
51h    WORD    bit flags
bit 12: ???
53h    DWORD   old INT 21h
57h    DWORD   pointer to 386MAX's EMS (INT 67h) handler

Format of high memory info record:
Offset  Size    Description
00h    WORD    segment address of memory region
02h    WORD    size of memory region in paragraphs
04h    BYTE    type or flags???
00h if locked out
02h if EMS page frame
04h if high RAM
42h if ROM
05h    BYTE    ???

Format of ROM shadowing record:
Offset  Size    Description
00h    WORD    segment of ROM???
02h    WORD    segment of ROM???
04h  2 BYTEs   ???
06h    WORD    size of shadowed ROM in paragraphs
08h  4 BYTEs   ???

Values for memory type:
00h unused by EMS
01h DOS
04h page frame overlapping ROM???
80h high memory
84h page frame???
87h video ROM???
Note:   the type may be 00h (unused) if the 16K page is split among different
uses (such as ROM and high RAM)

Call 386MAX API (via OUT DX,AL) with:
STACK: WORD value for DX
AH = 01h get high memory information
ES:DI -> buffer for array of high memory info records
(see above)
Return: CX = number of records placed in buffer
AH = 02h get shadowed ROM info???
ES:DI -> buffer for array of ROM shadowing records (see above)
Return: CX = number of records placed in buffer
AH = 03h get 386MAX state
ES:DI -> 90-byte buffer for state (see above)
Return: AH = 00h (successful)
buffer filled
Note:   unlike INT 21/AX=4402h"386MAX", this function omits
the first byte specifying the state buffer version
AH = 04h get memory types???
ES:DI -> buffer for memory type info (array of bytes, one per
16K page) (see above)
Return: CX = number of bytes placed in buffer
AH = 05h get ???
AL = subfunction
00h invoke INT 15/AX=2401h first
01h don't invoke INT 15/AX=2401h first
CX = number of bytes to copy (0000h for default)
SI = ???
ES:DI -> buffer for ???
Return: CX = number of bytes actually copied
???
AH = 06h get memory speed info
ES:DI -> buffer for memory speed records (see below)
Return: AH = 00h (successful)
CX = number of bytes placed in buffer
Note:   this function can take over a second to execute
AH = 07h ???
???
Return: ???
AH = 08h ???
AL = ??? (00h or nonzero)
AH = 09h toggle ??? flags
BX = bitmask of bits of ??? flags (word at state+11h) to toggle
Return: AH = 00h (successful)
Note: invokes INT 15/AX=2401h first
AH = 0Ah toggle ??? flags
BX = bitmask of bits of ??? (word at state+33h) to toggle
Return: AH = 00h (successful)
Notes:  invokes INT 15/AX=2401h first
does ??? if bit 3 on after specified bits are toggled
AH = 0Bh toggle ??? flags
BX = bitmask of bits of ??? (word at state+35h) to toggle
Return: AH = 00h (successful)
Note: invokes INT 15/AX=2401h first
AH = 0Ch toggle ??? flags
BX = bitmask of bits of ??? (word at state+41h) to toggle
Return: AH = 00h (successful)
Note: invokes INT 15/AX=2401h first
AH = 0Dh specify 386MAX high-memory location
BX = segment address of high-memory real-mode portion of 386MAX
???
Return: AH = status (00h successful)
???
AH = 0Eh CRT controller register virtualization
AL = subfunction
00h allow access to CRTC I/O ports 03B4h/03B5h, 03D4h/03D5h
01h trap accesses to CRTC I/O ports
AH = 0Fh reboot system
Return: never
AH = 11h get high memory information
ES:DI -> 96-byte buffer for high memory info
Return: AH = 00h (successful)
ES:DI buffer filled
Notes:  each byte in buffer contains bit flags for a 4K page in
the A000h-FFFFh region
bit 0: ???
bit 1: physical address same as linear address
bit 2: EMS page frame
bit 6: ???
this function can take over a second to execute
AH = 12h ???
AL = subfunction
00h ???
01h ???
???
Return: AH = 00h (successful) if AL=00h or 01h
AH = 8Fh otherwise
AH = 13h page protection???
AL = subfunction
00h set all ??? 4K pages to read-only???
01h set all ??? 4K pages to read-write???
???
Return: AH = 00h (successful) if AL=00h or 01h
AH = 8Fh otherwise
AH = 15h ???
???
Return: ???
AH = 16h get 386MAX memory usage screen
ES:DI -> buffer for memory info display
CX = size of buffer in bytes
Return: ES:DI buffer filled with '$'-terminated string (if
large enough to hold entire usage screen)
AH = 17h Windows 3 startup/termination
AL = subfunction
00h Windows3 initializing
DX (on stack) = Windows startup flags
DI = Windows version number (major in upper byte)
ES:BX = 0000h:0000h
DS:SI = 0000h:0000h
Return: CX = 0000h if OK for Windows to load
<> 0 if Windows should not load
ES:BX -> startup info structure
DS:SI -> Virtual86 mode enable/disable callback
01h Windows3 terminating
ES:BX -> ???
DX (on stack) = Windows exit flags
Return: ???
AH = 18h QPMS (Qualitas Protected Memory Services)
AL = subfunction
00h get QPMS configuration
Return: BX = starting segment of QPMS memory window
CX = number of 4K pages reserved for QPMS???
DX = number of 4K pages in QPMS window???
01h map QPMS memory page???
BX = 4K page number within memory reserved for QPMS???
CL = 4K page number within QPMS memory window???
02h mark all QPMS memory read-only
03h mark all QPMS memory read-write
Return: AH = status (00h,8Ah,8Bh,8Fh)
AH = 19h get linear address for physical address
EDX = physical address (low word on stack)
Return: AH = status
00h successful
EDX = linear address at which physical address
may be accessed
8Bh physical address currently not addressable
Note: calls INT 15/AX=2401h first
AH = 1Ah set page table entry???
EDX = new page table entry??? (low word on stack)
ESI = linear address of page???
Return: AH = status (00h,8Bh)
Note: calls INT 15/AX=2401h first
AH = 1Bh get ???
Return: AH = status
BX = ???
CX = ???
EDX = physical address of ???
AH = 1Ch get original interrupt vector
AL = interrupt vector (00h-7Fh)
Return: AH = 00h (successful)
EDX = original vector before 386MAX loaded (segment in
high word, offset in low word)
Note:   no range checking is performed; requests for INTs 80h-
FFh will return random values
AH = 1Dh display string???
SI = ???
Return: AH = 00h (successful)
???
AH = 1Eh ???
ES:DI -> ???
???
Return: ???
AH = 1Fh ???
???
Return: AX = 0000h if successful
BX = ??? (0001h for 386MAX v6.01)
CL = ???
DL = ??? (5Ah for 386MAX v6.01)
DH = ??? (00h for 386MAX v6.01)
SI = ???
ES???:DI -> ???
AH = 40h-5Dh EMS services (see INT 67/AH=40h etc)
AH = DEh VCPI services (see INT 67/AX=DE00h etc)
Return: AH = status (as for EMS INT 67 calls)
00h successful
80h internal error
81h hardware malfunction
83h invalid handle
84h undefined function
8Ah invalid logical page nuber
8Bh illegal physical page number
8Fh undefined subfunction
A4h access denied
etc.
STACK popped (value placed in DX if no specific return value for DX)

Format of memory speed record:
Offset  Size    Description
00h    DWORD   page table entry for 4K page
04h    WORD    number of microticks (840ns units) required for REP LODSD of
entire 4K page

See also: 214403

214402 - Qualitas 386MAX v6.00+ - IOCTL INPUT - GET STATE