; VGA macros

; Output a 16 bit value to an I/O port

OUT_16 macro register,value
ifdifi <register>,<dx> ;; If dx not set up
mov dx,register ;; then select register
endif
ifdifi <value>,<ax> ;; If ax not set up
mov ax,value ;; then get data value
endif
out dx,ax ;; Set I/O register(s)
endm


; Output an 8 bit value to an I/O Port

OUT_8 macro register,value
ifdifi <register>,<dx> ;; If dx not set up
mov dx,register ;; then select register
endif
ifdifi <value>,<al> ;; If al not set up
mov al,value ;; then get data value
endif
out dx,al ;; Set I/O register
endm


; Wait until the start of the VGA's vertical retrace period.
; Bit 3 of Input Status #1 register signals:
; 0 : display is in display mode
; 1 : display is in vertical retrace mode

; INPUT_1 = 03DAh ; 03DAh color, 03BAh mono
WAIT_VR macro
local VR1, VR2
mov dx,INPUT_1 ; Input status #1 port
VR1:
in al,dx ; Get port status
test al,08h ; Test bit 3
jnz short VR1 ; If set, we missed the
; beginning, so re-wait
VR2:
in al,dx ; Get port status
test al,08h ; Test bit 3
jz short VR2 ; Wait while in display
; mode (bit 3 = 0)
; Now at the start of
; a full VR period
endm


; Wait until start of either a vertical or a horizontal
; retrace period (the horizontal retrace period is
; significantly shorter).
; Bit 0 of Input Status #1 register signals:
; 0 : display is in display mode
; 1 : display is in horiz. or vert. retrace mode

WAIT_display_off macro
local DO1, DO2
mov dx,INPUT_1 ; Input status #1 port
if (@Cpu and 8) ; 80386+
DO1:
in al,dx ; Get port status
test al,1 ; Test bit 0
jnz short DO1 ; If set, we missed the
; beginning, so re-wait
DO2:
in al,dx ; Get port status
test al,1 ; Test bit 0
jz short DO2 ; Wait while in display
; mode (bit 0 = 0)
else ; 8086-80286:
DO1: ; SHR faster than TEST
in al,dx
shr al,1
jc short DO1
DO2:
in al,dx
shr al,1
jnc short DO2
endif
; Now at the start of
; a (short) HR period
; or a (long) VR period
endm