; 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