161 lines
4.3 KiB
NASM
161 lines
4.3 KiB
NASM
; Program to illustrate use of read mode 1 (color compare mode)
|
|
; to detect collisions in display memory. Draws a yellow line on a
|
|
; blue background, then draws a perpendicular green line until the
|
|
; yellow line is reached.
|
|
;
|
|
; By Michael Abrash
|
|
;
|
|
stack segment word stack 'STACK'
|
|
db 512 dup (?)
|
|
stack ends
|
|
;
|
|
VGA_SEGMENT EQU 0a000h
|
|
SCREEN_WIDTH EQU 80 ;in bytes
|
|
GC_INDEX EQU 3ceh ;Graphics Controller Index register
|
|
SET_RESET EQU 0 ;Set/Reset register index in GC
|
|
ENABLE_SET_RESET EQU 1 ;Enable Set/Reset register index in GC
|
|
COLOR_COMPARE EQU 2 ;Color Compare register index in GC
|
|
GRAPHICS_MODE EQU 5 ;Graphics Mode register index in GC
|
|
BIT_MASK EQU 8 ;Bit Mask register index in GC
|
|
;
|
|
code segment word 'CODE'
|
|
assume cs:code
|
|
Start proc near
|
|
cld
|
|
;
|
|
; Select graphics mode 10h.
|
|
;
|
|
mov ax,10h
|
|
int 10h
|
|
;
|
|
; Fill the screen with blue.
|
|
;
|
|
mov al,1 ;blue is color 1
|
|
call SelectSetResetColor ;set to draw in blue
|
|
mov ax,VGA_SEGMENT
|
|
mov es,ax
|
|
sub di,di
|
|
mov cx,7000h
|
|
rep stosb ;the value written actually doesn't
|
|
; matter, since set/reset is providing
|
|
; the data written to display memory
|
|
;
|
|
; Draw a vertical yellow line.
|
|
;
|
|
mov al,14 ;yellow is color 14
|
|
call SelectSetResetColor ;set to draw in yellow
|
|
mov dx,GC_INDEX
|
|
mov al,BIT_MASK
|
|
out dx,al ;point GC Index to Bit Mask
|
|
inc dx ;point to GC Data
|
|
mov al,10h
|
|
out dx,al ;set Bit Mask to 10h
|
|
mov di,40 ;start in the middle of the top line
|
|
mov cx,350 ;do full height of screen
|
|
VLineLoop:
|
|
mov al,es:[di] ;load the latches
|
|
stosb ;write next pixel of yellow line (set/reset
|
|
; provides the data written to display
|
|
; memory, and AL is actually ignored)
|
|
add di,SCREEN_WIDTH-1 ;point to the next scan line
|
|
loop VLineLoop
|
|
;
|
|
; Select write mode 0 and read mode 1.
|
|
;
|
|
mov dx,GC_INDEX
|
|
mov al,GRAPHICS_MODE
|
|
out dx,al ;point GC Index to Graphics Mode register
|
|
inc dx ;point to GC Data
|
|
mov al,00001000b ;bit 3=1 is read mode 1, bits 1 & 0=00
|
|
; is write mode 0
|
|
out dx,al ;set Graphics Mode to read mode 1,
|
|
; write mode 0
|
|
;
|
|
; Draw a horizontal green line, one pixel at a time, from left
|
|
; to right until color compare reports a yellow pixel is encountered.
|
|
;
|
|
; Draw in green.
|
|
;
|
|
mov al,2 ;green is color 2
|
|
call SelectSetResetColor ;set to draw in green
|
|
;
|
|
; Set color compare to look for yellow.
|
|
;
|
|
mov dx,GC_INDEX
|
|
mov al,COLOR_COMPARE
|
|
out dx,al ;point GC Index to Color Compare register
|
|
inc dx ;point to GC Data
|
|
mov al,14 ;we're looking for yellow, color 14
|
|
out dx,al ;set color compare to look for yellow
|
|
dec dx ;point to GC Index
|
|
;
|
|
; Set up for quick access to Bit Mask register.
|
|
;
|
|
mov al,BIT_MASK
|
|
out dx,al ;point GC Index to Bit Mask register
|
|
inc dx ;point to GC Data
|
|
;
|
|
; Set initial pixel mask and display memory offset.
|
|
;
|
|
mov al,80h ;initial pixel mask
|
|
mov di,100*SCREEN_WIDTH
|
|
;start at left edge of scan line 100
|
|
HLineLoop:
|
|
mov ah,es:[di] ;do a read mode 1 (color compare) read.
|
|
; This also loads the latches.
|
|
and ah,al ;is the pixel of current interest yellow?
|
|
jnz WaitKeyAndDone ;yes-we've reached the yellow line, so we're
|
|
; done
|
|
out dx,al ;set the Bit Mask register so that we
|
|
; modify only the pixel of interest
|
|
mov es:[di],al ;draw the pixel. The value written is
|
|
; irrelevant, since set/reset is providing
|
|
; the data written to display memory
|
|
ror al,1 ;shift pixel mask to the next pixel
|
|
adc di,0 ;advance the display memory offset if
|
|
; the pixel mask wrapped
|
|
;
|
|
; Slow things down a bit for visibility (adjust as needed).
|
|
;
|
|
mov cx,0
|
|
DelayLoop:
|
|
loop DelayLoop
|
|
jmp HLineLoop
|
|
;
|
|
; Wait for a key to be pressed to end, then return to text mode and
|
|
; return to DOS.
|
|
;
|
|
WaitKeyAndDone:
|
|
WaitKeyLoop:
|
|
mov ah,1
|
|
int 16h
|
|
jz WaitKeyLoop
|
|
sub ah,ah
|
|
int 16h ;clear the key
|
|
mov ax,3
|
|
int 10h ;return to text mode
|
|
mov ah,4ch
|
|
int 21h ;done
|
|
Start endp
|
|
;
|
|
; Enables set/reset for all planes, and sets the set/reset color
|
|
; to AL.
|
|
;
|
|
SelectSetResetColor proc near
|
|
mov dx,GC_INDEX
|
|
push ax ;preserve color
|
|
mov al,SET_RESET
|
|
out dx,al ;point GC Index to Set/Reset register
|
|
inc dx ;point to GC Data
|
|
pop ax ;get back color
|
|
out dx,al ;set Set/Reset register to selected color
|
|
dec dx ;point to GC Index
|
|
mov al,ENABLE_SET_RESET
|
|
out dx,al ;point GC Index to Enable Set/Reset register
|
|
inc dx ;point to GC Data
|
|
mov al,0fh
|
|
out dx,al ;enable set/reset for all planes
|
|
ret
|
|
SelectSetResetColor endp
|
|
code ends
|
|
end Start
|