home *** CD-ROM | disk | FTP | other *** search
- code segment byte public
- assume cs:code
- public gtxttran
- page 60,132
- ; val val val val VAR VAR
- ; procedure gtxttran(gdx,gdy,color,fontlines,fontbase,instring);
- ; transparent text writing
- ;
- gdx equ [BP+20]
- gdy equ [BP+18]
- color equ [BP+16]
- fontlines equ [BP+14]
- fontbase equ [BP+10]
- instring equ [BP+6]
-
- gtxttran proc far
-
- push bp
- mov bp,sp
- push ds
- ;
- ; Calculate byte address (segment & offset) and bit mask
-
- ;
- mov dx,040h ; bios data segment
- mov ds,dx
- mov si,062h
- mov al,[si] ; get active display page
-
- mov dx,0A000h ; base page of EGA/VGA memory
- ;
- or al,al ; set flags
- jz page0 ; if zero, skip ofset add
- add dh,8 ; ofset to second page base of A800h
-
- page0:
- mov ds,dx ; DS := EGA buffer segment address
-
- mov dx,3CEh ; Graphics Controller port address
- mov al,8
- out dx,al ; select register 8
-
- mov dx,3C4h ; Sequencer/Map Mode port address
- mov al,2
- out dx,al ; Select "Map Mask" register 2
-
-
- ;
- mov ax,gdx ; get X address from stack frame
- shr ax,1
- shr ax,1
- shr ax,1 ; compute memory address ofset AX := x/8
- mov gdx,ax ; save back on stack
- ;
- les SI,instring ; get doulbleword base address of string
- xor ch,ch ; clear ch
- mov cl,byte ptr ES:[si] ; points to length of string
- strloop: ; loop for number of characters in string
- push CX ; save string count for outer loop
- inc SI ; make si point to nextchar
- mov bl,byte ptr ES:[SI] ; SI points to next char - read into bx
- inc bl ; move to next char: we work from bottom to top
- mov ax,fontlines ; get number of lines/char in font
- mov cx,ax ; keep for use as loop counter
- mul bl ; ax := bl (character) * al (bytes/char)
- mov bx,ax ; leave font character ofset in BX
- push ES ; save char seg.
- push SI ; save char pointer
-
- ;
- ; loop for the number of lines
- charloop: ; loop through the font's scanlines bottom to top
- ;
- mov ax,gdy ; get Y address (a pixel row)
- add ax,cx ; add in scanlin ofset to Y value
- dec ax ; subtract 1 because cx is 1 based inst. of 0
- mov dx,80d
- mul dx ; AX := (y * 80) (80 bytes per row)
-
- add ax,gdx ; AX := (y * 80) + x/8 (offset)
-
- mov di,ax ; save EGA memory ofset in DI
-
- ; Set the "Bit Mask" register
- dec bx ; move to next scanline in font
-
- les SI,fontbase ; get dblword base address of font
- ;
-
- mov dx,3CFh ; bit mask register
- mov al,ES:[BX][SI] ; get bit mask byte from font
- out dx,al ; load the bit mask into reg 8
- mov dx,3C5h ; seq mapmode reg.
- mov al,0Fh ; enablee writes to all planes for
- ; pixels where the char will go
- out dx,al
- ;
-
-
- ; Set all 4 bits in the pixel to '0'
- mov al,[di] ; Read at address A000:offset
- ; This latches all 4 bit planes.
- ; (The byte "read" is ignored.)
- mov al,0
- mov [di],al ; Write at address A000:offset
- ; This sets the bit-masked bits to '0'
- ; and stores the latched bytes to the
- ; bit planes
-
- ; Set bits in the appropriate bit planes to '1'
-
- mov ax,color ; AL := map mask (i.e., pixel color value)
- out dx,al ; Load the map mask into SMM reg 2.
- ; This enables the appropriate bit planes.
-
- mov al,[di] ; Latch the bit plane data.
- mov al,0FFh
- mov [di],al ; Set bits to '1' in appropriate planes.
-
- ;
-
-
- loop charloop ; decrement cx and do next scanline
-
- pop SI ; pop character pointer
- pop ES ; " " segement
- inc word ptr gdx ; move screen position to next char over
-
- pop CX ; get outer loop - counting chars in string
- loop strloop
-
- ; Restore default EGA graphics status
- mov dx,3C4h
- mov al,2 ; Again, select ...
- out dx,al ; ... Sequencer/Map Mask register 2.
-
- mov dx,3C5h
- mov al,0Fh ; Default map mask
- out dx,al ; Enable all 4 bit planes
-
- mov dx,3CEh
- mov al,8 ; Again, select ...
- out dx,al ; ... Graphics Controller register 8
-
- mov dx,3CFh
- mov al,0FFh ; Default bit mask
- out dx,al ; Restore default bit mask
-
- pop ds
- pop bp
- ret 16d
- gtxttran endp
-
- code ends
-
- end