;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;**************************************************************************
;*
;* SOURCE FILE NAME = 8514.INC
;*
;* DESCRIPTIVE NAME = Include for 8514
;*
;*
;*      DISCLAIMER OF WARRANTIES.  The following enclosed code is
;*      sample code created by IBM Corporation. This sample code is not
;*      part of any standard or IBM product and is provided to you solely
;*      for  the purpose of assisting you in the development of your
;*      applications.  The code is provided "AS IS", without
;*      warranty of any kind.  IBM shall not be liable for any damages
;*      arising out of your use of the sample code, even if they have been
;*      advised of the possibility of such damages.
;*
;* VERSION      V2.0
;*
;* DATE         8/4/92
;*
;* DESCRIPTION  General 8514 include.
;*
;* FUNCTIONS
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*
;**************************************************************************

SCR_S3_WIDTH        Equ     2048   ; Width of S3 VRAM/visible screen
SCR_S3_HEIGHT       Equ     1638   ; Height of S3 VRAM
SCR_8514_WIDTH      Equ     1024   ; Width of 8514 VRAM/visible screen
SCR_8514_HEIGHT     Equ     1024   ; Height of 8514 VRAM
SCR_8514_VIS_HEIGHT Equ      768   ; Height of 8514 visible screen

CB_SCAN24           Equ     2048   ; Width in bytes of the 24bit color scanline

START_FONT_CACHE    Equ    0F00CA000h

ifndef  S3
RAMDAC_PMASK    Equ     002eah          ; pixel mask
RAMDAC_RADDR    Equ     002ebh          ; read lut index address
RAMDAC_WADDR    Equ     002ech          ; write lut index address
RAMDAC_RGB      Equ     002edh          ; rgb data port
else
RAMDAC_PMASK    Equ     003c6h          ; pixel mask
RAMDAC_RADDR    Equ     003c7h          ; read lut index address
RAMDAC_WADDR    Equ     003c8h          ; write lut index address
RAMDAC_RGB      Equ     003c9h          ; rgb data port
endif

;
; I/O port definitions for the 8514/A Update Controller (primary decodes):
; (NOTE: We utilize the discard feature i/o ports)
;

WAIT_PORT_BIT   Equ     0100000000000000b; reset this bit in port # to get
                                        ; discard port instead of wait port

Y0              Equ     082e8h          ; src y coordinate for primitives
X0              Equ     086e8h          ; src x coordinate for primitives
Y1              Equ     08ae8h          ; dest y coordinate for Copy Rectangle
X1              Equ     08ee8h          ; dest x coordinate for Copy Rectangle
XY_SIGNIFICANT  Equ     0000011111111111b; significant bits in x,y addr
ifdef S3
  ; Added an extra sign bit for negative coordinates for the S3 chip.  Adding this
  ; bit prevents the cursor from disappearing when moved to the left edge of the
  ; screen.    @RCW
  XY_NEG        Equ     0000111000000000b; x or y coordinate is negative
else
  XY_NEG        Equ     0000011000000000b; x or y coordinate is negative
endif

K1              Equ     08ae8h          ; Bresenham term1 for vectors
K2              Equ     08ee8h          ; Bresenham term2 for vectors
ERR_TERM        Equ     092e8h          ; Bresenham error term accumulator

LX              Equ     096e8h          ; x-axis length for primitives

CMD_FLAGS       Equ     09ae8h          ; command/flags register (w)
CMD_COMMAND     Equ     1110000000000000b; command field
CMD_C_NULL      Equ     0000000000000000b; null command
CMD_C_VECTOR    Equ     0010000000000000b; output vector
CMD_C_HRECT     Equ     0100000000000000b; horizontal rectangle
CMD_C_VRECT     Equ     0110000000000000b; vertical rectangle
CMD_C_FRECT     Equ     1000000000000000b; fast rectangle
CMD_C_OUTLINE   Equ     1010000000000000b; outline draw
CMD_C_CRECT     Equ     1100000000000000b; copy rectangle
CMD_BYTEORDER   Equ     0001000000000000b; byte order field
CMD_BYTE_LO     Equ     0001000000000000b; lo byte first to/from queues
CMD_BYTE_HI     Equ     0000000000000000b; hi byte first to/from queues
CMD_BYTE_WORD   Equ     0000001000000000b; byte/word field
CMD_BYTE        Equ     0000001000000000b; queue access contains 2 bytes
CMD_WORD        Equ     0000000000000000b; queue access contains 1 byte
CMD_FIX_VAR     Equ     0000000100000000b; fixed/variable data field
CMD_FV_VAR      Equ     0000000100000000b; use variable data
CMD_FV_FIX      Equ     0000000000000000b; use fixed data
CMD_DYZX        Equ     0000000011100000b; direction flags
CMD_DY          Equ     0000000010000000b; y increment
CMD_DZ          Equ     0000000001000000b; z increment
CMD_DX          Equ     0000000000100000b; x increment
CMD_D210        Equ     CMD_DYZX        ; coded direction flags
CMD_D2          Equ     CMD_DY
CMD_D1          Equ     CMD_DZ
CMD_D0          Equ     CMD_DX
CMD_MOVE_ACCESS Equ     0000000000010000b; move/access flag field
CMD_MA_MOVE     Equ     0000000000000000b; move (no access of bit planes)
CMD_MA_ACCESS   Equ     0000000000010000b; access bit planes
CMD_CODED_DIR   Equ     0000000000001000b; coded direction flag
CMD_CD_ANGLED   Equ     0000000000000000b; direction flags == DYZX
CMD_CD_45       Equ     0000000000001000b; direction flags == D210
CMD_LAST_PEL_NUL Equ    0000000000000100b; draw last pel field
CMD_LP_NULL     Equ     0000000000000100b; don't draw last pel
CMD_LP_DRAW     Equ     0000000000000000b; draw last pel
CMD_PEL_ACCRUAL Equ     0000000000000010b; pel accrual field
CMD_PA_FOUR     Equ     0000000000000010b; r/w 4 pels at a time
CMD_PA_ONE      Equ     0000000000000000b; r/w 1 pel at a time
CMD_RW          Equ     0000000000000001b; r/w bit planes
CMD_RW_R        Equ     0000000000000000b; read bit planes
CMD_RW_W        Equ     0000000000000001b; write bit planes

QSTATUS         Equ     09ae8h          ; queue status register (r)
Q_STATUS_REG    equ     9ae8h
CMD_STATUS_REG  equ     9ae9h
CMD_ACTIVE      equ     0002h       ; command is active
QS_AFC_OPTION   Equ     1000000000000000b; AFC option installed field
QS_BUSY         Equ     0000001000000000b; reset when input queue empty
QS_R_Q_STAT     Equ     0000000100000000b; data available in read queue
QS_W_Q_STAT     Equ     0000000011111111b; # words in write queue field
QS_W_Q_FULL     Equ     0000000011111111b; write queue is full
QS_W_Q_EMPTY    Equ     0000000000000000b; write queue is empty

SHORTSTROKE     Equ     09ee8h          ; short stroke data (w)
SS_D012         Equ     11100000b       ; coded direction flag fields
SS_MOVE_ACCESS  Equ     00010000b       ; move/access field
SS_LX           Equ     00001111b       ; length of short stroke field

COLOR_0         Equ     0a2e8h          ; background color (r/w)
COLOR_1         Equ     0a6e8h          ; foreground color (r/w)
COLOR_0_WAIT    Equ     0e2e8h          ; pixel transfer register (r/w)

WRITE_ENABLE    Equ     0aae8h          ; plane write enable register (w)
READ_ENABLE     Equ     0aee8h          ; plane read enable register (w)

COLOR_COMP      Equ     0b2e8h          ; color comparison register (w)

FUNCTION_0      Equ     0b6e8h          ; background mix (w)
FUNCTION_1      Equ     0bae8h          ; foreground mix (w)
ROP2_FIELD      Equ     00011111b       ; mask for mix bits
FUNC_2OPSRC     Equ     01100000b       ; second operand src field (w)
FUNC_2OP_COL0   Equ     00000000b       ; second operand src is COLOR_0
FUNC_2OP_COL1   Equ     00100000b       ; second operand src is COLOR_1
FUNC_2OP_VAR    Equ     01000000b       ; second operand src is variable data
FUNC_2OP_COPY   Equ     01100000b       ; second operand src is copy rectangle
FUNC_ALU        Equ     00011111b       ; ALU function (mix mode, w)
FUNC_ND         Equ     00000000b       ; ~dest -> dest
FUNC_ZEROS      Equ     00000001b       ; 0s -> dest
FUNC_ONES       Equ     00000010b       ; 1s -> dest
FUNC_D          Equ     00000011b       ; dest -> dest
FUNC_NS         Equ     00000100b       ; ~src -> dest
FUNC_S_XOR_D    Equ     00000101b       ; src xor dest -> dest
FUNC_S_XNOR_D   Equ     00000110b       ; src xnor dest -> dest
FUNC_S          Equ     00000111b       ; src -> dest
FUNC_NS_OR_ND   Equ     00001000b       ; ~src or ~dest -> dest
FUNC_NS_OR_D    Equ     00001001b       ; ~src or dest -> dest
FUNC_S_OR_ND    Equ     00001010b       ; src or ~dest -> dest
FUNC_S_OR_D     Equ     00001011b       ; src or ~dest -> dest
FUNC_S_AND_D    Equ     00001100b       ; src and dest -> dest
FUNC_S_AND_ND   Equ     00001101b       ; src and ~dest -> dest
FUNC_NS_AND_D   Equ     00001110b       ; ~src and dest -> dest
FUNC_NS_AND_ND  Equ     00001111b       ; ~src and ~dest -> dest
FUNC_MIN_S_D    Equ     00010000b       ; min(src,dest) -> dest
FUNC_D_SUB_S    Equ     00010001b       ; dest - src -> dest
FUNC_S_SUB_D    Equ     00010010b       ; src - dest -> dest
FUNC_D_ADD_S    Equ     00010011b       ; src + dest -> dest
FUNC_MAX_S_D    Equ     00010100b       ; max(src,dest) -> dest
FUNC_D_SUB_S_2  Equ     00010101b       ; (dest - src)/2 -> dest
FUNC_S_SUB_D_2  Equ     00010110b       ; (src - dest)/2 -> dest
FUNC_D_ADD_S_2  Equ     00010111b       ; (src + dest)/2 -> dest
FUNC_D_SUBS_S   Equ     00011001b       ; dest - src -> dest w/saturate
FUNC_S_SUBS_D   Equ     00011010b       ; src - dest -> dest w/saturate
FUNC_D_ADDS_S   Equ     00011011b       ; src + dest -> dest w/saturate
FUNC_D_SUBS_S_2 Equ     00011101b       ; (dest - src)/2 -> dest w/saturate
FUNC_S_SUBS_D_2 Equ     00011110b       ; (src - dest)/2 -> dest

HWMIX_ZEROS                    equ        FUNC_ZEROS
HWMIX_SOURCE_AND_DEST          equ        FUNC_S_AND_D
HWMIX_SOURCE_AND_NOTDEST       equ        FUNC_S_AND_ND
HWMIX_SOURCE                   equ        FUNC_S
HWMIX_NOTSOURCE_AND_DEST       equ        FUNC_NS_AND_D
HWMIX_DEST                     equ        FUNC_D
HWMIX_SOURCE_XOR_DEST          equ        FUNC_S_XOR_D
HWMIX_SOURCE_OR_DEST           equ        FUNC_S_OR_D
HWMIX_NOTSOURCE_AND_NOTDEST    equ        FUNC_NS_AND_ND
HWMIX_SOURCE_XOR_NOTDEST       equ        FUNC_S_XNOR_D
HWMIX_NOTDEST                  equ        FUNC_ND
HWMIX_SOURCE_OR_NOTDEST        equ        FUNC_S_OR_ND
HWMIX_NOTSOURCE                equ        FUNC_NS
HWMIX_NOTSOURCE_OR_DEST        equ        FUNC_NS_OR_D
HWMIX_NOTSOURCE_OR_NOTDEST     equ        FUNC_NS_OR_ND
HWMIX_ONES                     equ        FUNC_ONES

SECOND_DECODE   Equ     0bee8h          ; secondary decodes

CNTL_STATUS     Equ     042e8h          ; control/status register
CS_RESET_CNTL   Equ     1100000000000000b; reset control field (w)
CS_R_NULL       Equ     0000000000000000b; null effect
CS_R_NORMAL     Equ     0100000000000000b; update controller normal operation
CS_R_RESET      Equ     1000000000000000b; reset update controller
CS_TESTMODE_CNTL Equ    0011000000000000b; test mode control field (w)
CS_T_NULL       Equ     0000000000000000b; null effect
CS_T_NORMAL     Equ     0001000000000000b; normal mode
CS_T_TESTMODE   Equ     0010000000000000b; test mode
CS_INTMASK      Equ     0000111100000000b; interrupt mask field (w)
CS_I_OPDONE     Equ     0000100000000000b; op completed interrupt
CS_I_OVERRUN    Equ     0000010000000000b; queue overrun interrupt
CS_I_CORRELATE  Equ     0000001000000000b; correlation interrupt
CS_I_VRETRACE   Equ     0000000100000000b; frame flyback interrupt
CS_MISR         Equ     1111111100000000b; diagnostic MISR bits (r)
CS_OPTIONS      Equ     0000000011110000b; hardware options field (r)
CS_O_4PLANES    Equ     0000000010000000b; 4-bit plane extension installed (r)
CS_O_MONITORS   Equ     0000000001110000b; monitor id field (r)
CS_O_HIRES_MONO Equ     0000000000010000b; 1024x768 mono monitor
CS_O_HIRES_COL  Equ     0000000000100000b; 1024x768 color monitor
CS_O_LORES_MONO Equ     0000000001010000b; 640x480 mono monitor
CS_O_LORES_COL  Equ     0000000001100000b; 640x480 color monitor
CS_O_NONE       Equ     0000000001110000b; no monitor attached
CS_OPDONE       Equ     0000000000001000b; op complete (r/w)
CS_OVERRUN      Equ     0000000000000100b; queue overrun field (r/w)
CS_CORRELATE    Equ     0000000000000010b; correlate status (r/w)
CS_VRETRACE     Equ     0000000000000001b; frame flyback status (r/w)

PROM_PAGE       Equ     046e8h          ; prom page select register

MISC_IO         Equ     04ae8h          ; miscellaneous i/o register
MI_PELCLK       Equ     00000100b       ; pel clock rate
MI_PELCLK_640   Equ     00000000b       ; pel clock for 640 wide
MI_PELCLK_1024  Equ     00000100b       ; pel clock for 1024 wide
MI_AF_MODE      Equ     00000001b       ; advanced function mode select
MI_AF_VGA       Equ     00000000b       ; VGA has control
MI_AF_AFC       Equ     00000001b       ; 8514A has control

ADAPTER_ID      Equ     00100h          ; adapter id register
ADAPTER_ENABLE  Equ     00102h          ; adapter enable register

;
; I/O port definitions for the 8514/A Update Controller (secondary decodes):
; (NOTE: We utilize the discard feature i/o ports)
;
DECODE_FIELD    Equ     1111000000000000b

LY              Equ     0bee8h          ; y-axis length for primitives (w)
LY_2DECODE      Equ     0000000000000000b; secondary decode

YMIN            Equ     0bee8h          ; scissor min y (w)
YMIN_2DECODE    Equ     0001000000000000b; secondary decode

XMIN            Equ     0bee8h          ; scissor min x (w)
XMIN_2DECODE    Equ     0010000000000000b; secondary decode

YMAX            Equ     0bee8h          ; scissor max y (w)
YMAX_2DECODE    Equ     0011000000000000b; secondary decode

XMAX            Equ     0bee8h          ; scissor max x (w)
XMAX_2DECODE    Equ     0100000000000000b; secondary decode

CONFIG          Equ     0bee8h          ; configuration (w)
CONFIG_2DECODE  Equ     0101000000000000b; secondary decode
CFG_UPDATE_BANK Equ     10000b          ; chooses 1k vs 512 line modes (w)
CFG_VRAM_BANK   Equ     01100b          ; vram bank select field (w)
CFG_VRAM_1024   Equ     00100b          ; value for 1k line mode
CFG_VRAM_512    Equ     00000b          ; value for 512 line mode
CFG_INTERLEAVE  Equ     00010b          ; interleave field (w)
CFG_WORDWIDTH   Equ     00001b          ; wordwidth field (w)

PATTERN_0       Equ     0bee8h          ; pattern 0 register (w)
PATTERN_0_2DECODE Equ   1000000000000000b; secondary decode
PATTERN_0_DATA  Equ     00011110b       ; lo 4 bits pattern field

PATTERN_1       Equ     0bee8h          ; pattern 1 register (w)
PATTERN_1_2DECODE Equ   1001000000000000b; secondary decode
PATTERN_1_DATA  Equ     00011110b       ; hi 4 bits pattern field

MODE            Equ     0bee8h          ; mode register (w)
MODE_2DECODE    Equ     1010000000000000b; secondary decode
MD_PATT_SRC     Equ     11000000b       ; pattern source select field
MD_PS_ONES      Equ     00000000b       ; pattern = ONEs
MD_PS_PATT      Equ     01000000b       ; pattern = PATTERN_0,PATTERN_1 regs
MD_PS_VAR       Equ     10000000b       ; pattern = variable data
MD_PS_COPY      Equ     11000000b       ; pattern = copy rectangle (read phase)
MD_UNDERPAINT   Equ     00111000b       ; underpaint control field
MD_UP_FALSE     Equ     00000000b       ; always false
MD_UP_TRUE      Equ     00001000b       ; always true
MD_UP_GE        Equ     00010000b       ; plane data >= color compare
MD_UP_LT        Equ     00011000b       ; plane data <  color compare
MD_UP_NE        Equ     00100000b       ; plane data != color compare
MD_UP_EQ        Equ     00101000b       ; plane data == color compare
MD_UP_LE        Equ     00110000b       ; plane data <= color compare
MD_UP_GT        Equ     00111000b       ; plane data >  color compare
MD_AREAFILL     Equ     00000110b       ; area fill control field
MD_AF_W_NORMAL  Equ     00000000b       ; normal operation for writes
MD_AF_R_THRU    Equ     00000000b       ; thru planes for reads
MD_AF_W_SPP     Equ     00000100b       ; special plane fill for writes
MD_AF_R_ACROSS  Equ     00000100b       ; across planes for reads
MD_AF_W_SPC     Equ     00000110b       ; special color fill for writes
MD_WORDWIDTH    Equ     00000001b       ; word width field

MULTIFUNCTION   Equ     0bee8h          ; multifunction control register
MF_2DECODE      Equ     1110000000000000b ; multifunction secondary decode
MF_COLCOMP      Equ     100000000b      ; color compare enable
MF_SRC_EQ       Equ     000000000b      ; don't update when equal
MF_SRC_NE       Equ     010000000b      ; don't update when not equal

;
; I/O port definitions for the 8514/A Display Controller:
;
LINE_TOTAL      Equ     002e8h          ; line total length
LINE_BLANK      Equ     006e8h          ; line blank start
LINE_SYNC_POS   Equ     00ae8h          ; line sync position
LINE_SYNC_WIDE  Equ     00ee8h          ; line sync width
FRAME_TOTAL     Equ     012e8h          ; frame total length
FRAME_BLANK     Equ     016e8h          ; frame blank start
FRAME_SYNC_POS  Equ     01ae8h          ; frame sync position
FRAME_SYNC_WIDE Equ     01ee8h          ; frame sync width

CRTC_MODE       Equ     022e8h          ; crtc mode
CRTM_RESET      Equ     01100000b       ; crtc reset field
CRTM_R_NULL     Equ     00000000b       ; no effect
CRTM_R_NORMAL   Equ     00100000b       ; normal operation
CRTM_R_RESET    Equ     01000000b       ; reset crt controller
CRTM_INTERLACE  Equ     00010000b       ; interlace field
CRTM_VREPL      Equ     00001000b       ; vertical replication
CRTM_VRAM_BANK  Equ     00000110b       ; vram bank select field
CRTM_VB_1024    Equ     00000010b       ; vram bank select for 1024 lines
CRTM_VB_512     Equ     00000000b       ; vram bank select for 512 lines
CRTM_INTERLEAVE Equ     00000001b       ; interleave mode

CRTC_STATUS     Equ     002e8h          ; crtc status


;
; Configuration information determined at initialization time is described
; in the variable hwFlags in the default data segment. The significance of
; the bits in the flags is described below:
;

HW_OPTIONS      Equ     00000111b       ; hw options field
HW_MON_640      Equ     002h            ; monitor dictates 640x480 mode
HW_MON_1024     Equ     000h            ; monitor allows 1024x768 mode
HW_MONO_MON     Equ     004h            ; monochrome monitor attached
HW_COLOR_MON    Equ     000h            ; color monitor attached
HW_DALLAS       Equ     008h            ; DALLAS monitor attached           @D1A
HW_LEGAL        Equ     08000h          ; legal hw mode detected
HW_ILLEGAL      Equ     00000h          ; illegal hw mode detected


; Plane read enable masks
;
ifndef  S3
READ_PLANE_0    Equ     002h
else
READ_PLANE_0    Equ     001h
endif
READ_PLANE_1    Equ     READ_PLANE_0 SHL 1
READ_PLANE_2    Equ     READ_PLANE_0 SHL 2
READ_PLANE_3    Equ     READ_PLANE_0 SHL 3
READ_PLANE_4    Equ     READ_PLANE_0 SHL 4
READ_PLANE_5    Equ     READ_PLANE_0 SHL 5
READ_PLANE_6    Equ     READ_PLANE_0 SHL 6
ifndef  S3
READ_PLANE_7    Equ     READ_PLANE_0 SHR 1
READ_ALL_PLANES Equ     0ffh
else
READ_PLANE_7    Equ     READ_PLANE_0 SHL 7
READ_ALL_PLANES Equ     0ffffh
endif

; Plane write enable masks

WRITE_PLANE_0   Equ     001h
WRITE_PLANE_1   Equ     WRITE_PLANE_0 SHL 1
WRITE_PLANE_2   Equ     WRITE_PLANE_0 SHL 2
WRITE_PLANE_3   Equ     WRITE_PLANE_0 SHL 3
WRITE_PLANE_4   Equ     WRITE_PLANE_0 SHL 4
WRITE_PLANE_5   Equ     WRITE_PLANE_0 SHL 5
WRITE_PLANE_6   Equ     WRITE_PLANE_0 SHL 6
WRITE_PLANE_7   Equ     WRITE_PLANE_0 SHL 7
ifndef  S3
WRITE_ALL_PLANES    Equ 0ffh
else
WRITE_ALL_PLANES    Equ 0ffffh
endif

; 8514 Registers

MAJ_AXIS_PCNT   equ     (96e8h+WAIT_PORT_BIT)
COMMAND_REG     equ     (9ae8h+WAIT_PORT_BIT)
WRITE_MASK_REG  equ     (0aae8h+WAIT_PORT_BIT)
READ_MASK_REG   equ     (0aee8h+WAIT_PORT_BIT)
BKGD_MIX_REG    equ     (0b6e8h+WAIT_PORT_BIT)
FRGD_MIX_REG    equ     (0bae8h+WAIT_PORT_BIT)
MISC_REG        equ     (0bee8h+WAIT_PORT_BIT)
PIXEL_TRANS_REG equ     0e2e8h


CMD_MCOLOR   = (CMD_C_CRECT+CMD_FV_FIX+CMD_DX+\
                CMD_DY+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW)

CMD_WCUR     = (CMD_C_HRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+\
                CMD_DX+CMD_DY+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W)

CMDPATCOLOR  = (CMD_C_HRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+CMD_DY+\
                CMD_DX+CMD_MA_ACCESS+CMD_PA_ONE+CMD_RW_W)

CMDPATCOLOR_R= (CMD_C_HRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+CMD_DY+\
                CMD_DX+CMD_MA_ACCESS+CMD_PA_ONE+CMD_RW_R)

CMD_WSAVE    = (CMD_C_CRECT+CMD_FV_FIX+CMD_DX+\
                CMD_DY+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W)

CMD_WMASK    = (CMD_C_CRECT+CMD_DX+CMD_DY+CMD_PA_FOUR)

CMD_WRESTORE =  CMD_WSAVE

CMD_DRAWTEXT = (CMD_C_CRECT+CMD_DX+CMD_DY+CMD_MA_ACCESS+CMD_RW_W)

CMD_CACHEF   = (CMD_C_HRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+\
                CMD_DX+CMD_DY+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W)

CMDSOLID     = (CMD_C_HRECT+CMD_FV_FIX+CMD_MA_ACCESS+CMD_PA_FOUR+\
                CMD_DX+CMD_DY+CMD_RW_W)

CMDPATTERN   = (CMD_C_CRECT+CMD_FV_FIX+CMD_PA_FOUR+CMD_RW_W+\
                CMD_MA_ACCESS+CMD_DX+CMD_DY)

CMDS3_PATTERN= (0E000h+CMD_FV_FIX+CMD_PA_FOUR+CMD_RW_W\
                +CMD_MA_ACCESS+CMD_DX+CMD_DY)

CMDSRCSCR    = (CMD_C_CRECT+CMD_FV_FIX+CMD_PA_FOUR+\
                CMD_MA_ACCESS+CMD_RW_W)

CMDIMAGE     = (CMD_C_CRECT+CMD_BYTE_LO+CMD_BYTE+CMD_FV_VAR+\
                CMD_DY+CMD_DX+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W)

CMDCOL48     = (CMD_C_HRECT+CMD_BYTE+CMD_BYTE_LO+CMD_FV_VAR+CMD_DY+\
                CMD_DX+CMD_MA_ACCESS+CMD_PA_ONE+CMD_RW_W)

CMDCOL24     = (CMD_C_HRECT+CMD_FV_VAR+CMD_DY+\
                CMD_DX+CMD_MA_ACCESS+CMD_PA_ONE+CMD_RW_W)

CMDMONO      = (CMD_C_HRECT+CMD_BYTE+CMD_BYTE_LO+CMD_FV_VAR+CMD_DY+\
                CMD_DX+CMD_MA_ACCESS+CMD_PA_FOUR+CMD_RW_W)

CMDDESTONLY  = (CMD_C_CRECT+CMD_FV_FIX+CMD_PA_FOUR+CMD_RW_W+\
                CMD_MA_ACCESS+CMD_DX+CMD_DY)


Reg8514 struc
; This structure must match the equivalent structure in xgaadapt.h
; that structure should be moved to 8514.h @DMS !!!
sr_X0             dw  ?;/*  86e8  r/w  */
sr_Y0             dw  ?;/*  82e8  r/w  */
sr_X1             dw  ?;/*  8ee8   w   */
sr_Y1             dw  ?;/*  8ae8   w   */
sr_K1             dw  ?;/*  8ae8   w   */
sr_K2             dw  ?;/*  8ee8   w   */
Err_Term          dw  ?;/*  92e8  r/w  */
sr_LX             dw  ?;/*  96e8   w   */

Cmd_Flags         dd  ?;/*  9ae8   w   */
QStatus           dd  ?;/*  9ae8   r   */

ShortStroke       dd  ?;/*  9ee8   w   */

ifndef  BPP24
Color_0           dw  ?;/*  a2e8   w   */
Color_1           dw  ?;/*  a6e8   w   */

Write_Enable      dw  ?;/*  aae8   w   */
Read_Enable       dw  ?;/*  aee8   w   */

Color_Comp        dw  ?;/*  b2e8   w   */
else
Color_0           dd  ?;/*  a2e8   w   */
Color_1           dd  ?;/*  a6e8   w   */

Write_Enable      dd  ?;/*  aae8   w   */
Read_Enable       dd  ?;/*  aee8   w   */

Color_Comp        dd  ?;/*  b2e8   w   */
endif

Function_0        dd  ?;/*  b6e8   w   */
Function_1        dd  ?;/*  bae8   w   */

sr_LY             dw  ?;/*  bee8   w   Index 0  */
YMin              dw  ?;/*  bee8   w   Index 1  */
XMin              dw  ?;/*  bee8   w   Index 2  */
YMax              dw  ?;/*  bee8   w   Index 3  */
XMax              dw  ?;/*  bee8   w   Index 4  */
Config            dw  ?;/*  bee8   w   Index 5  */
Pattern_0         dw  ?;/*  bee8   w   Index 8  */
Pattern_1         dw  ?;/*  bee8   w   Index 9  */
Mode              dd  ?;/*  bee8   w   Index A  */

Color_0_Wait      dw  ?;/*  e2e8  r/w  */
Control           dw  ?;/*  42e8   w   */
Status            dw  ?;/*  42e8   r   */
Prom_Page         dw  ?;/*  46e8   w   */
Misc_IO           dd  ?;/*  4ae8   w   */

dim1              dw  ?; 
dim2              dw  ?; 
mask_org          dd  ?; 
src_map           dd  ?; 
patt_map          dd  ?; 
dest_map          dd  ?; 

pixel_op          dd  ?; 
                  db  ?; fifth step

pi_map_index_A    dw  ?; 
pi_map_base_ptr_A dd  ?; 
pi_map_width_A    dw  ?; 
pi_map_height_A   dw  ?; 
pi_map_format_A   db  ?; 
                  db  ?

pi_map_index_B    dw  ?; 
pi_map_base_ptr_B dd  ?; 
pi_map_width_B    dw  ?; 
pi_map_height_B   dw  ?; 
pi_map_format_B   db  ?; 
                  db  ?

pi_map_index_C    dw  ?; 
pi_map_base_ptr_C dd  ?; 
pi_map_width_C    dw  ?; 
pi_map_height_C   dw  ?; 
pi_map_format_C   db  ?; 
                  db  ?

pi_map_index_M    dw  ?; 
pi_map_base_ptr_M dd  ?; 
pi_map_width_M    dw  ?; 
pi_map_height_M   dw  ?; 
pi_map_format_M   db  ?; 
                  db  ?
Reg8514 ends

bres_k1 equ sr_K1
bres_k2 equ sr_K2
bres_error equ Err_Term
dir_steps equ sr_LY
fg_mix equ Function_1
bg_mix equ Function_0
fg_colour equ Color_1
bg_colour equ Color_0
; @DMS only some fields
colour_comp_fun equ Mode
colour_comp_colour equ Color_Comp

; @DMS be very careful where ever this was used !!! update.asm needs cleaning
hw_pi_map_index     equ   pi_map_index_A
hw_pi_map_base_ptr  equ   pi_map_base_ptr_A
hw_pi_map_width     equ   pi_map_width_A
hw_pi_map_height    equ   pi_map_height_A
hw_pi_map_format    equ   pi_map_format_A

Reg8514_2 struc
; This structure must match the equivalent structure in xgaadapt.h
                  dw  ?;/*  86e8  r/w  */
                  dw  ?;/*  82e8  r/w  */
                  dw  ?;/*  8ee8   w   */
                  dw  ?;/*  8ae8   w   */
                  dw  ?;/*  8ae8   w   */
                  dw  ?;/*  8ee8   w   */
                  dw  ?;/*  92e8  r/w  */
                  dw  ?;/*  96e8   w   */

                  dd  ?;/*  9ae8   w   */
                  dd  ?;/*  9ae8   r   */

                  dd  ?;/*  9ee8   w   */

ifndef  BPP24
                  dw  ?;/*  a2e8   w   */
                  dw  ?;/*  a6e8   w   */

                  dw  ?;/*  aae8   w   */
                  dw  ?;/*  aee8   w   */

                  dw  ?;/*  b2e8   w   */
else
                  dd  ?;/*  a2e8   w   */
                  dd  ?;/*  a6e8   w   */

                  dd  ?;/*  aae8   w   */
                  dd  ?;/*  aee8   w   */

                  dd  ?;/*  b2e8   w   */
endif

                  dd  ?;/*  b6e8   w   */
                  dd  ?;/*  bae8   w   */

                  dw  ?;/*  bee8   w   Index 0  */
                  dw  ?;/*  bee8   w   Index 1  */
                  dw  ?;/*  bee8   w   Index 2  */
                  dw  ?;/*  bee8   w   Index 3  */
                  dw  ?;/*  bee8   w   Index 4  */
                  dw  ?;/*  bee8   w   Index 5  */
                  dw  ?;/*  bee8   w   Index 8  */
                  dw  ?;/*  bee8   w   Index 9  */
                  dd  ?;/*  bee8   w   Index A  */

                  dw  ?;/*  e2e8  r/w  */
                  dw  ?;/*  42e8   w   */
                  dw  ?;/*  42e8   r   */
                  dw  ?;/*  46e8   w   */
                  dd  ?;/*  4ae8   w   */

dimensions        dd  ?; 
mask_org_x        dw  ?
mask_org_y        dw  ?
src_map_x         dw  ?
src_map_y         dw  ?
patt_map_x        dw  ?
patt_map_y        dw  ?
dest_map_x        dw  ?
dest_map_y        dw  ?

                  dd  ?; 
                  db  ?; fifth step

                  dw  ?
                  dd  ?; 
pi_map_size_A     dd  ?; 
                  db  ?; 
                  db  ?

                  dw  ?
                  dd  ?; 
pi_map_size_B     dd  ?; 
                  db  ?; 
                  db  ?

                  dw  ?
                  dd  ?; 
pi_map_size_C     dd  ?; 
                  db  ?; 
                  db  ?

                  dw  ?
                  dd  ?; 
pi_map_size_M     dd  ?; 
                  db  ?; 
                  db  ?
Reg8514_2 ends

hw_pi_map_size equ pi_map_size_A

SCRNTX  struc
        stx_Address  dw   ?
        stx_Size     dw   ?
        stx_flFlag   dw   ?
SCRNTX  ends

SCRNRX  struc
        srx_ScrnPtr  dw   ?
SCRNRX  ends

;**************************************************************************
;*                                                                        *
;**************************************************************************
;
; Macros to access the hardware:
;


; WaitIO
; ------
; General purpose macro to sit on an i/o port and test for a particular value:
;
;       Port:           port # to be polled. If not present then it is assumed
;                       that the port # has already been loaded into Dx.
;
;       Sense:          sense of jump needed to remain in polling loop.
;
;       Mask:           if present then the value that will be and'ed with the
;                       polled contents of Port.
;
;       EquVal:         if present then the value that must match the Port
;                       contents, after masking if Mask is present.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
WaitIO  Macro   Port,Sense,Mask,EquVal,SaveRegs
        Local   SpinOnStatus

;; Save registers we will use if requested to do so:
        Ifnb    <SaveRegs>
        mpush   ?AX+?DX
        Endif

;; Load up the port address:
        Ifnb    <Port>
        Mov     Dx,Port
        Endif

;; Now wait for status to go to sense specified:
SpinOnStatus:
        In      Ax,Dx                   ;; fetch the port value
        Ifnb    <Mask>                  ;; if masking off input value
        And     Ax,Mask                 ;;   mask it off
        Endif
        Ifnb    <EquVal>                ;; if comparing to a specific value
        Cmp     Ax,EquVal               ;;   do the comparison
        Endif
        J&Sense SpinOnStatus            ;; spin until required status is met...

;; Restore registers we used if requested to do so:
        Ifnb    <SaveRegs>
        mpop    ?AX+?DX
        Endif
        Endm


;**************************************************************************
;*                                                                        *
;**************************************************************************

;WaitQIdle
; Special purpose macro to wait for the 8514/A adapter processor to be idle.
;
WaitQIdle macro   SaveRegs
          WaitIO  QSTATUS,nz,QS_BUSY,,SaveRegs
          endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

; WaitQIN
; -------
; Special purpose macro to wait for the 8514/A adapter's output queue to
; have available data.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
WaitQIN macro   SaveRegs
        WaitIO  QSTATUS,z,QS_R_Q_STAT,,SaveRegs
        endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

; WaitQOUT
; --------
; Special purpose macro to wait for the 8514/A adapter's input queue to
; be ready to accept data.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
WaitQOUT        macro   SaveRegs
        WaitIO  QSTATUS,ne,(QS_BUSY+QS_W_Q_FULL),(QS_BUSY+QS_W_Q_EMPTY),SaveRegs
                endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

; WaitQ
; -----
; Special purpose macro to wait for the 8514A adapter's input queue to have
; a minimum # of words of free space. The queue is up to 8 words deep and
; at any time the # words still to be dequeued can be ascertained.
;
;       MinQSpace:      fall out of wait loop if at least this many words are
;                       available in the queue. This parameter must be present.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
WaitQ   Macro   MinQSpace,SaveRegs
        Local   QBitVec

        if      MinQSpace LT 0
??Qouts         =       ??Qouts + MinQSpace
        else
        errnz   <MinQSpace EQ 0>        ;; waiting on a full queue ?
        errnz   <MinQSpace GT 8>        ;; queue is only 8 words deep

??QMaxOuts      =       MinQSpace       ;; assemble-time indicator of max # outs
                                        ;; allowed
??Qouts         =       0               ;; not yet registered any outs

QBitVec =       80h Shr (MinQSpace - 1) ;; mask to test on
        WaitIO  QSTATUS,nz,QBitVec,,SaveRegs
        endif
        Endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

; outwQ
; -----
; Special purpose macro to output a word value to the 8514A input queue.
;
;       Port:           port # for which data that is written will be queued.
;                       If this parameter is not present the port # will be
;                       assumed to already have been loaded into Dx.
;
;       Data:           immediate or indirect specification of data that will
;                       be output to Port. If this parameter is not present
;                       the data will be assumed to already have been loaded
;                       into the Ax register.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
outwQ   Macro   Port,Data,SaveRegs

??Qouts =       ??Qouts + 1
        If      ??Qouts GT ??QMaxOuts
        ??error <Readjust min # words free space in queue in WaitQ>
        Endif

        Ifnb    <SaveRegs>
        mpush   ?AX+?DX
        Endif

        Ifnb    <Data>
        Ifidn   <Data>,<0>
        Sub     Ax,Ax                   ;; save some code for zero data
        Else
        Ifdifi  <Data>,<Ax>
        Mov     Ax,Data                 ;; fetch data value
        Endif
        Endif
        Endif

        Ifnb    <Port>                  ;; if port # not already loaded
        Mov     Dx,Port                 ;;   we load it here
        Endif
        Out     Dx,Ax                   ;; output queue data

        Ifnb    <SaveRegs>
        mpop    ?AX+?DX
        Endif
        Endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

; outbQ
; -----
; Special purpose macro to output a byte value to the 8514A input queue. This
; macro differs from outwQ in that it is assumed that only the low half of the
; Ax register needs to be loaded. A slight saving in code size is thereby
; achieved.
;
;       Port:           port # for which data that is written will be queued.
;                       If this parameter is not present the port # will be
;                       assumed to already have been loaded into the Dx register
;
;       Data:           immediate or indirect specification of data that will
;                       be output to Port. If this parameter is not present
;                       the data will be assumed to already have been loaded
;                       into the Ax register.
;
;       SaveRegs:       parameter is present if registers used in polling are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
outbQ   Macro   Port,Data,SaveRegs

??Qouts =       ??Qouts + 1
        If      ??Qouts GT ??QMaxOuts
        ??error <Readjust min # of words free space in queue in WaitQ>
        Endif

        Ifnb    <SaveRegs>
        mpush   ?AX+?DX
        Endif

        Ifnb    <Data>
        Ifidn   <Data>,<0>
        Sub     Al,Al                   ;; save some code for zero data
        Else
        Ifdifi  <Data>,<Al>
        Mov     Al,Data                 ;; fetch data value
        Endif
        Endif
        Endif

        Ifnb    <Port>                  ;; if port # not already loaded
        Mov     Dx,Port                 ;;   we load it here
        Endif
        Out     Dx,Ax                   ;; output queue data

        Ifnb    <SaveRegs>
        mpop    ?AX+?DX
        Endif
        Endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

setclip macro    xMin,yMin,xMax,yMax
        WaitQ   4                      ; need room in the queue
        mov     dx,SECOND_DECODE       ; set up scissor rectangle
        mov     ax,xMin
        or      ah,High XMIN_2DECODE
        out     dx,ax                  ;XMIN
        mov     ax,xMax
        or      ah,High XMAX_2DECODE
        out     dx,ax                  ;XMAX
        mov     ax,yMin
        or      ah,High YMIN_2DECODE
        out     dx,ax                  ;YMIN
        mov     ax,yMax
        or      ah,High YMAX_2DECODE
        out     dx,ax                  ;YMAX
endm

SetNoXClip macro
        WaitQ   2
        outwQ   XMIN, XMIN_2DECODE+0
        IFDEF S3
        outwQ   XMAX, XMAX_2DECODE+(SCR_S3_WIDTH-1)
        ELSE
        outwQ   XMAX, XMAX_2DECODE+(SCR_8514_WIDTH-1)
        ENDIF
        endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

setlimits macro cx,cy
        WaitQ   2                       ; need room in the queue
        mov     ax,cx
        outwQ   LX,ax                   ; 0-based width of the save area
        mov     ax,cy
        outwQ   LY,ax                   ; 0-based height of a save area
endm

;**************************************************************************
;*                                                                        *
;**************************************************************************

copyrect macro  xD,yD,xS,yS
        WaitQ   2
        ifndef  S3
        Mov     al,0ffh               ; read/write to/from all planes
        outbQ   READ_ENABLE,al
        outbQ   WRITE_ENABLE,al
        else
        mov     ax,0ffffh             ; read/write to/from all planes
        outwQ   READ_ENABLE,ax
        outwQ   WRITE_ENABLE,ax
        endif
        WaitQ   7
        outwQ   X0,xS                   ; send out source x coordinate
        outwQ   Y0,yS                   ; send out source y coordinate
        outwQ   X1,xD                   ; send out destination x coordinate
        outwQ   Y1,yD                   ; send out destination y coordinate
        outbQ   FUNCTION_1,(FUNC_2OP_COPY+FUNC_S); straight replace mode
        outwQ   MODE,(MODE_2DECODE+MD_PS_ONES+MD_UP_FALSE)
                                        ; command to restore save area
        outwQ   CMD_FLAGS,CMD_WSAVE      ; command to restore save area

endm

;**************************************************************************
;*                                                                        *
;**************************************************************************
ifndef  S3
ifndef   MEMMAPIO
twistbits16     macro
        lodsw                           ; 4 nibbles -- N2|N3|N0|N1
        rol     ah,4                    ; now       -- N3|N2|N0|N1
        ror     ax,4                    ; now       -- N1|N3|N2|N0
        rol     ah,4                    ; now       -- N3|N1|N2|N0
        rol     ax,1                    ; as above, shifted up 1 bit
        out     dx,ax                   ; output N1|N0
        ror     ax,4
        out     dx,ax                   ; output N3|N2
        endm
else
twistbits16     macro
        lodsw                           ; 4 nibbles -- N2|N3|N0|N1
        ;bswap if 486 or above
        rol     ah,4                    ; now       -- N3|N2|N0|N1
        ror     ax,4                    ; now       -- N1|N3|N2|N0
        rol     ah,4                    ; now       -- N3|N1|N2|N0
        rol     ax,1                    ; as above, shifted up 1 bit
        stosw                           ; output N1|N0
        ror     ax,4
        stosw                           ; output N3|N2
        endm
endif   ; 

twistbits16nomap     macro
        lodsw                           ; 4 nibbles -- N2|N3|N0|N1
        rol     ah,4                    ; now       -- N3|N2|N0|N1
        ror     ax,4                    ; now       -- N1|N3|N2|N0
        rol     ah,4                    ; now       -- N3|N1|N2|N0
        rol     ax,1                    ; as above, shifted up 1 bit
        out     dx,ax                   ; output N1|N0
        ror     ax,4
        out     dx,ax                   ; output N3|N2
        endm

else    ; S3

ifndef   MEMMAPIO
twistbits16     macro
        outsw
        endm
else
twistbits16     macro
        stosw
        endm
endif   ; 

twistbits16nomap     macro
        outsw                           ; 4 nibbles
        endm

endif   ; S3

;**************************************************************************
;*                                                                        *
;**************************************************************************

ifndef  S3
twistbits8      macro
        lodsb                           ; 4 nibbles -- N2|N3|N0|N1
        rol     ah,4                    ; now       -- N3|N2|N0|N1
        ror     ax,4                    ; now       -- N1|N3|N2|N0
        rol     ah,4                    ; now       -- N3|N1|N2|N0
        rol     ax,1                    ; as above, shifted up 1 bit
        out     dx,ax                   ; output N1|N0
        endm
else
twistbits8      macro
        outsb                           ; 4 nibbles
        endm
endif

; LoadPattern
; -----------
; Load the 8514/A pattern registers with an 8 bit pattern value. The macro
; shields us from the fact that an 8 bit pattern gets loaded into the 8514/A
; as two 4 bit values, each half shifted up 1 bit, and sent out to independent
; ports.
;
;       Pattern:        8 bit pattern to be loaded. If not present then it is
;                       assumed that the pattern is already loaded into Al.
;
;
;       SaveRegs:       parameter is present if registers used are
;                       to be saved and restored, the actual content of this
;                       parameter is ignored, only its presence matters.
;
LoadPattern     Macro   Pattern,SaveRegs

;; Save registers we will use if requested to do so:
        Ifnb    <SaveRegs>
        mpush   ?AX+?DX
        Endif

;; Load up the pattern:
        Ifnb    <Pattern>               ;; if pattern needs to be fetched
        Mov     Al,Pattern              ;;   we fetch it to Ax
        Endif

;; Output the low 4 bits of the pattern:
        Mov     Dx,PATTERN_1            ;; point to low pattern register
        Rol     Al,1                    ;; P0-P3 go out in Al bits 1-4
        Mov     Ah,HIGH PATTERN_1_2DECODE;; add in the secondary decode value
        Out     Dx,Ax

;; Output the high 4 bits of the pattern:
      ; Mov     Dx,PATTERN_0            ;; point to high pattern register
        .errnz  PATTERN_1 - PATTERN_0
        Rol     Al,4                    ;; P4-P7 go out in Al bits 1-4
        Mov     Ah,HIGH PATTERN_0_2DECODE;; add in the secondary decode value
        Out     Dx,Ax

;; Restore registers we used if requested to do so:
        Ifnb    <SaveRegs>
        mpop    ?AX+?DX
        Endif

        Endm

;--------------------------------------------------------------------------;
; usmin_ax
;       returns unsigned min of AX and REG/MEM
; Entry:
;       AX      = unsigned integer
;       REG/MEM = unsigned integer
; Returns:
;       AX      = min(AX,REG/MEM)
; Error Returns:
;       none
; Registers Destroyed:
;       FLAGS
; Registers Preserved:
;       BX,CX,DX,SI,DI,DS,ES,BP
; Calls:
;       none
; History:
;  Mon Apr 04 14:14:19 1988     -by-    Hock Lee        [hockl]
; wrote it
;--------------------------------------------------------------------------;

usmin_ax        macro   REG
        local   got_it
        cmp     ax,REG
        jb      short got_it
        mov     ax,REG
got_it:
        endm

;A macro to calculate the X and Y coordinates from a pointer to
;8514 VRAM.  X is placed in EDX; Y is placed in EAX.  ECX is destroyed.

calc8514xy macro  VRAM_8514_Ptr
       Ifdifi   <VRAM_8514_Ptr>,<eax>
       mov      eax,VRAM_8514_Ptr        ;; fetch data value
       Endif
       and      eax,0fffffffh   ; clear the vram marker
       ror      eax,16
       movzx    edx,ax
       ror      eax,16
       movzx    eax,ax
       endm
