home *** CD-ROM | disk | FTP | other *** search
- ; Program to illustrate operation of data rotate and bit mask
- ; features of Graphics Data Controller. Draws 8x8 character at
- ; specified location, using EGA's 8x8 ROM font. Designed
- ; for use with modes 0Dh, 0Eh, 0Fh, and 10h.
- ; Assembled with MASM 4.0, linked with LINK 3.51.
- ; By Michael Abrash, 2/8/87.
- ; Updated 6/25/89.
- ;
- stackseg segment para stack 'STACK'
- db 512 dup(?)
- stackseg ends
- ;
- EGA_VIDEO_SEGMENT equ 0a000h ;EGA display memory segment
- SCREEN_WIDTH_IN_BYTES equ 044ah ;offset of BIOS variable
- FONT_CHARACTER_SIZE equ 8 ;# bytes in each font char
- ;
- ; EGA register equates.
- ;
- GC_INDEX equ 3ceh ;GC index register
- GC_ROTATE equ 3 ;GC data rotate/logical function
- ; register index
- GC_BIT_MASK equ 8 ;GC bit mask register index
- ;
- dseg segment para common 'DATA'
- TEST_TEXT_ROW equ 69 ;row to display test text at
- TEST_TEXT_COL equ 17 ;column to display test text at
- TEST_TEXT_WIDTH equ 8 ;width of a character in pixels
- TestString label byte
- db 'Hello, world!',0 ;test string to print.
- FontPointer dd ? ;font offset
- dseg ends
- ;
- ; Macro to set indexed register INDEX of GC chip to SETTING.
- ;
- SETGC macro INDEX, SETTING
- mov dx,GC_INDEX
- mov ax,(SETTING SHL 8) OR INDEX
- out dx,ax
- 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
- ;
- ; Set driver to use the 8x8 font.
- ;
- call Select8x8Font
- ;
- ; Print the test string.
- ;
- mov si,offset TestString
- mov bx,TEST_TEXT_ROW
- mov cx,TEST_TEXT_COL
- StringOutLoop:
- lodsb
- and al,al
- jz StringOutDone
- call DrawChar
- add cx,TEST_TEXT_WIDTH
- jmp StringOutLoop
- StringOutDone:
- ;
- ; Reset the data rotate and bit mask registers.
- ;
- SETGC GC_ROTATE, 0
- SETGC GC_BIT_MASK, 0ffh
- ;
- ; Exit to DOS. (Still in graphics mode; the MODE CO80 command
- ; can be used to restore the screen to text mode.)
- ;
- mov ah,4ch
- int 21h
- Start endp
- ;
- ; Subroutine to draw a text character in a linear graphics mode
- ; (0Dh, 0Eh, 0Fh, 010h).
- ; Font to be used must be pointed to by FontPointer.
- ;
- ; Input:
- ; AL = character to draw
- ; BX = row to draw text character at
- ; CX = column to draw text character at
- ;
- ; Forces ALU function to "move".
- ;
- DrawChar proc near
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- ;
- ; Set DS:SI to point to font and ES to point to display memory.
- ;
- lds si,[FontPointer] ;point to font
- mov dx,EGA_VIDEO_SEGMENT
- mov es,dx ;point to display memory
- ;
- ; Calculate screen address of byte character starts in.
- ;
- push ds ;point to BIOS data segment
- sub dx,dx
- mov ds,dx
- xchg ax,bx
- mov di,ds:[SCREEN_WIDTH_IN_BYTES] ;retrieve BIOS
- ; screen width
- pop ds
- mul di ;calculate offset of start of row
- push di ;set aside screen width
- mov di,cx ;set aside the column
- and cl,0111b ;keep only the column in-byte address
- shr di,1
- shr di,1
- shr di,1 ;divide column by 8 to make a byte address
- add di,ax ;and point to byte
- ;
- ; Calculate font address of character.
- ;
- sub bh,bh
- shl bx,1 ;assumes 8 bytes per character; use
- shl bx,1 ; a multiply otherwise
- shl bx,1 ;offset in font of character
- add si,bx ;offset in font segment of character
- ;
- ; Set up the GC rotation for the bit alignment of the character
- ; within each display memory byte.
- ;
- mov dx,GC_INDEX
- mov al,GC_ROTATE
- mov ah,cl
- out dx,ax
- ;
- ; Set up BH as bit mask for part of character in left byte,
- ; BL as bit mask for part of character in right byte.
- ;
- mov bx,0ff00h
- shr bx,cl
- ;
- ; Draw the character, the part in left byte first, then the part in
- ; right byte next, using the data rotation to position the character
- ; across the byte boundary and then using the bit mask to get the
- ; proper portion of the character into each byte.
- ;
- ; Does not check for the case where the character is byte-aligned,
- ; so no rotation (and hence only one write) is required; special
- ; code would speed that case considerably.
- ;
- mov bp,FONT_CHARACTER_SIZE
- mov dx,GC_INDEX
- pop cx ;get back screen width
- dec cx
- dec cx ; -2 because do two bytes for each char
- ; Point the GC Index register to the Bit Mask register for the
- ; duration of the loop.
- mov al,GC_BIT_MASK
- out dx,al
- inc dx ;point to GC Data register
- CharacterLoop:
- ;
- ; Set the bit mask for the part of the character in the left byte.
- ;
- mov al,bh
- out dx,al
- ;
- ; Get the next character byte & write it to display memory.
- ; (This draws the part of the character in the left byte.)
- ;
- mov al,es:[di] ;load latches from left byte
- lodsb ;get character byte
- stosb ;write left part of character byte
- ;
- ; Set the bit mask for the part of the character in the right byte.
- ;
- xchg ax,bx ;get right-byte bit mask in AL
- ; and save the font byte
- out dx,al ;set the right-byte bit mask
- xchg ax,bx ;put the font byte back in AL
- ; and the bit masks back in BX
- ;
- ; Write the character byte to display memory again.
- ; (Right part of character.)
- ;
- mov ah,es:[di] ;load latches from right byte
- stosb ;write character byte
- ;
- ; Point to next line of character in display memory.
- ;
- add di,cx
- ;
- dec bp
- jnz CharacterLoop
- ;
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- DrawChar endp
- ;
- ; Set the pointer to the 8x8 font.
- ;
- Select8x8Font proc near
- mov ah,11h ;EGA BIOS character generator function,
- mov al,30h ; return info subfunction
- mov bh,3 ;get 8x8 font pointer
- int 10h
- mov word ptr [FontPointer],bp ;save pointer
- mov word ptr [FontPointer+2],es
- ret
- Select8x8Font endp
- ;
- cseg ends
- end start