home *** CD-ROM | disk | FTP | other *** search
- ; Program to illustrate operation of ALUs and latches in the EGA's
- ; Graphics Data Controller. Draws a variety of patterns against
- ; a horizontally striped background, using each of the 4 available
- ; logical functions (data unmodified, AND, OR, XOR) in turn to combine
- ; the images with the background.
- ; Assembled with MASM 4.0, linked with LINK 3.51.
- ; Copyright by Michael Abrash, 11/27/86.
- ;
- stack segment para stack 'STACK'
- db 512 dup(?)
- stack ends
- ;
- EGA_VIDEO_SEGMENT equ 0a000h ;EGA display memory segment
- SCREEN_HEIGHT equ 350
- SCREEN_WIDTH_IN_BYTES equ 80
- DEMO_AREA_HEIGHT equ 336 ;# of scan lines in area
- ; logical function operation
- ; is demonstrated in
- DEMO_AREA_WIDTH_IN_BYTES equ 40 ;width in bytes of area
- ; logical function operation
- ; is demonstrated in
- VERTICAL_BOX_WIDTH_IN_BYTES equ 10 ;width in bytes of the box used to
- ; demonstrate each logical function
- ;
- ; EGA register equates.
- ;
- GDC_INDEX equ 3ceh ;GDC index register
- GDC_ROTATE equ 3 ;GDC data rotate/logical function
- ; register index
- GDC_MODE equ 5 ;GDC mode register index
- ;
- dseg segment para common 'DATA'
- ;
- ; String used to label logical functions.
- ;
- LabelString label byte
- db 'UNMODIFIED AND OR XOR '
- LABEL_STRING_LENGTH equ $-LabelString
- ;
- ; Strings used to label fill patterns.
- ;
- FillPatternFF db 'Fill Pattern: 0FFh'
- FILL_PATTERN_FF_LENGTH equ $ - FillPatternFF
- FillPattern00 db 'Fill Pattern: 000h'
- FILL_PATTERN_00_LENGTH equ $ - FillPattern00
- FillPatternVert db 'Fill Pattern: Vertical Bar'
- FILL_PATTERN_VERT_LENGTH equ $ - FillPatternVert
- FillPatternHorz db 'Fill Pattern: Horizontal Bar'
- FILL_PATTERN_HORZ_LENGTH equ $ - FillPatternHorz
- ;
- dseg ends
- ;
- ; Macro to set indexed register INDEX of GDC chip to SETTING.
- ;
- SETGDC macro INDEX, SETTING
- mov dx,GDC_INDEX
- mov ax,(SETTING SHL 8) OR INDEX
- out dx,ax
- endm
- ;
- ;
- ; Macro to call BIOS write string function to display text string
- ; TEXT_STRING, of length TEXT_LENGTH, at location ROW,COLUMN.
- ;
- TEXT_UP macro TEXT_STRING, TEXT_LENGTH, ROW, COLUMN
- mov ah,13h ;BIOS write string function
- mov bp,offset TEXT_STRING ;ES:BP points to string
- mov cx,TEXT_LENGTH
- mov dx,(ROW SHL 8) OR COLUMN ;position
- sub al,al ;string is chars only, cursor not moved
- mov bl,7 ;text attribute is white (light gray)
- int 10h
- endm
- ;
- cseg segment para public 'CODE'
- assume cs:cseg, ds:dseg
- start proc near
- mov ax,dseg
- mov ds,ax
- ;
- ; Select 640x350 graphics mode.
- ;
- mov ax,010h
- int 10h
- ;
- ; ES points to EGA memory.
- ;
- mov ax,EGA_VIDEO_SEGMENT
- mov es,ax
- ;
- ; Draw background of horizontal bars.
- ;
- mov dx,SCREEN_HEIGHT/4
- ;# of bars to draw (each 4 pixels high)
- sub di,di ;start at offset 0 in display memory
- mov ax,0ffffh ;fill pattern for light areas of bars
- mov bx,DEMO_AREA_WIDTH_IN_BYTES / 2 ;length of each bar
- mov si,SCREEN_WIDTH_IN_BYTES - DEMO_AREA_WIDTH_IN_BYTES
- mov bp,(SCREEN_WIDTH_IN_BYTES * 3) - DEMO_AREA_WIDTH_IN_BYTES
- BackgroundLoop:
- mov cx,bx ;length of bar
- rep stosw ;draw top half of bar
- add di,si ;point to start of bottom half of bar
- mov cx,bx ;length of bar
- rep stosw ;draw bottom half of bar
- add di,bp ;point to start of top of next bar
- dec dx
- jnz BackgroundLoop
- ;
- ; Draw vertical boxes filled with a variety of fill patterns
- ; using each of the 4 logical functions in turn.
- ;
- SETGDC GDC_ROTATE, 0 ;select data unmodified
- ; logical function...
- mov di,0
- call DrawVerticalBox ;...and draw box
- ;
- SETGDC GDC_ROTATE, 08h ;select AND logical function...
- mov di,10
- call DrawVerticalBox ;...and draw box
- ;
- SETGDC GDC_ROTATE, 10h ;select OR logical function...
- mov di,20
- call DrawVerticalBox ;...and draw box
- ;
- SETGDC GDC_ROTATE, 18h ;select XOR logical function...
- mov di,30
- call DrawVerticalBox ;...and draw box
- ;
- ; Reset the logical function to data unmodified, the default state.
- ;
- SETGDC GDC_ROTATE, 0
- ;
- ; Label the screen.
- ;
- push ds
- pop es ;strings we'll display are passed to BIOS
- ; by pointing ES:BP to them
- ;
- ; Label the logical functions, using the EGA BIOS's
- ; write string function.
- ;
- TEXT_UP LabelString, LABEL_STRING_LENGTH, 24, 0
- ;
- ; Label the fill patterns, using the EGA BIOS's
- ; write string function.
- ;
- TEXT_UP FillPatternFF, FILL_PATTERN_FF_LENGTH, 3, 42
- TEXT_UP FillPattern00, FILL_PATTERN_00_LENGTH, 9, 42
- TEXT_UP FillPatternVert, FILL_PATTERN_VERT_LENGTH, 15, 42
- TEXT_UP FillPatternHorz, FILL_PATTERN_HORZ_LENGTH, 21, 42
- ;
- ; Wait until a key's been hit to reset screen mode & exit.
- ;
- WaitForKey:
- mov ah,1
- int 16h
- jz WaitForKey
- ;
- ; Finished. Clear key, reset screen mode and exit.
- ;
- Done:
- mov ah,0 ;clear key that we just detected
- int 16h
- ;
- mov ax,3 ;reset to text mode
- int 10h
- ;
- mov ah,4ch ;exit to DOS
- int 21h
- ;
- start endp
- ;
- ; Subroutine to draw a box 80x336 in size, using currently selected
- ; logical function, with upper left corner at the display memory offset
- ; in DI. Box is filled with four patterns. Top quarter of area is
- ; filled with 0FFh (solid) pattern, next quarter is filled with 00h
- ; (empty) pattern, next quarter is filled with 33h (double pixel wide
- ; vertical bar) pattern, and bottom quarter is filled with double pixel
- ; high horizontal bar pattern.
- ;
- ; Macro to draw a column of the specified width in bytes, one- quarter
- ; of the height of the box, with the specified fill pattern.
- ;
- DRAW_BOX_QUARTER macro FILL, WIDTH
- local RowLoop, ColumnLoop
- mov al,FILL ;fill pattern
- mov dx,DEMO_AREA_HEIGHT / 4 ;1/4 of the full box height
- RowLoop:
- mov cx,WIDTH
- ColumnLoop:
- mov ah,es:[di] ;load display memory contents into
- ; GDC latches (we don't actually care
- ; about value read into AH)
- stosb ;write pattern, which is logically
- ; combined with latch contents for each
- ; plane and then written to display
- ; memory
- loop ColumnLoop
- add di,SCREEN_WIDTH_IN_BYTES - WIDTH
- ;point to start of next line down in box
- dec dx
- jnz RowLoop
- endm
- ;
- DrawVerticalBox proc near
- DRAW_BOX_QUARTER 0ffh, VERTICAL_BOX_WIDTH_IN_BYTES
- ;first fill pattern: solid fill
- DRAW_BOX_QUARTER 0, VERTICAL_BOX_WIDTH_IN_BYTES
- ;second fill pattern: empty fill
- DRAW_BOX_QUARTER 033h, VERTICAL_BOX_WIDTH_IN_BYTES
- ;third fill pattern: double-pixel
- ; wide vertical bars
- mov dx,DEMO_AREA_HEIGHT / 4 / 4
- ;fourth fill pattern: horizontal bars in
- ; sets of 4 scan lines
- sub ax,ax
- mov si,VERTICAL_BOX_WIDTH_IN_BYTES ;width of fill area
- HorzBarLoop:
- dec ax ;0ffh fill (faster to do word than byte DEC)
- mov cx,si ;width to fill
- HBLoop1:
- mov bl,es:[di] ;load latches (don't care about value)
- stosb ;write solid pattern, through ALUs
- loop HBLoop1
- add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
- mov cx,si ;width to fill
- HBLoop2:
- mov bl,es:[di] ;load latches
- stosb ;write solid pattern, through ALUs
- loop HBLoop2
- add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
- inc ax ;0 fill (faster to do word than byte DEC)
- mov cx,si ;width to fill
- HBLoop3:
- mov bl,es:[di] ;load latches
- stosb ;write empty pattern, through ALUs
- loop HBLoop3
- add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
- mov cx,si ;width to fill
- HBLoop4:
- mov bl,es:[di] ;load latches
- stosb ;write empty pattern, through ALUs
- loop HBLoop4
- add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
- dec dx
- jnz HorzBarLoop
- ;
- ret
- DrawVerticalBox endp
- cseg ends
- end start
-