home *** CD-ROM | disk | FTP | other *** search
- ;====================================================================
- ; display a null terminated string with the baseline at x,y in color
- ; using supplied font
- ; struct font {
- ; uchar cell_width // in bytes
- ; uchar cell_depth // in scan lines
- ; uchar baseline // in scan lines from top 0-rel
- ; uchar first_char // ASCII value of 1st cell in font
- ; uchar last_char // ASCII value of last cell in font
- ; struct cell {
- ; uchar width // pixel width of this character
- ; uchar points[cell_depth][cell_width]
- ; } cells[last_char-first_char +1]
- ; }
- ;--------------------------------------------------------------------
- ; etext (int x, int y, char* string, int color, char* font);
- ;
-
- ; Large parms
- pX0 equ [bp+6]
- pY0 equ [bp+8]
- pSoffs equ [bp+10]
- pSseg equ [bp+12]
- pColor equ [bp+14]
- pFoffs equ [bp+16]
- pFseg equ [bp+18]
-
- ; Local storage
- lBytesWide equ WORD PTR [bp-2]
- lHigh equ BYTE PTR [bp-4]
- lHwrk equ BYTE PTR [bp-6]
- lWwrk equ WORD PTR [bp-8]
- lCellsize equ WORD PTR [bp-12]
- lStrPos equ WORD PTR [bp-14]
- lBytesChar equ WORD PTR [bp-16]
- lBwide equ WORD PTR [bp-18]
- lCurrVidSeg equ WORD PTR [bp-20]
-
- ; Font header control structure
- fonthdr struc
- cell_wide db ?
- cell_high db ?
- baseline db ?
- char_wide db ?
- first_ch db ?
- last_ch db ?
- cell_base db ?
- fonthdr ends
-
-
- public _etext
-
- _etext proc far
- push bp ;<1>
- mov bp,sp
- sub sp,22
- pushf
- push si ;<2>
- push di ;<3>
- push ds ;<4>
- push es ;<5>
-
- cld
-
- mov si,pFoffs ;font offset
- mov ax,pSoffs
- mov lStrPos,ax ;save string offset--we will adjust this
-
- ; Make the size of a scan line and video addressable for the stack
- mov ax,_bytes_per_line
- mov lBwide,ax
- mov ax,_curr_vid_seg
- mov lCurrVidSeg,ax
-
- ; Adjust the video image back up to the top of the box
- ; based upon the baseline offset from the top
-
- mov ds,pFseg ;addressability on the font
- xor cx,cx
- mov cl,[si].baseline ;how many to back up
- cmp cl,0 ;no adjustmet needed ?
-
- ; Decrement the pixel base by 80 (640 pixels) for each
- ; scanline that the cell top is above the baseline.
-
- jz PcharBaseSet
- PcharBloop:
- dec WORD PTR pY0 ;up one scan line in bytes
- loop PcharBloop
- PcharBaseSet:
-
- ; Compute the size of the individual cells in the font
- ; character description array (wide(bytes)*deep(scans)) +1
-
- mov al,[si].cell_wide ;DS:SI => font structure
- mul [si].cell_high
- inc ax
- mov lCellsize,ax
-
- ; Set lBytesWide to the number of bits in one scan line
-
- mov al,[si].cell_wide ;byte width
- xor ah,ah ;clear top of 16bit reg
- mov lBytesWide,ax ;save it
-
- ; get a working copy of the depth
-
- mov al,[si].cell_high
- mov lHigh,al
-
- ; Set mode to SET/RESET
-
- mov dx,GRAPHIC12
- mov al,SETRESET
- out dx,al
-
- inc dx
- mov al,pColor
- out dx,al
-
- dec dx
- mov al,ENABLERESET
- out dx,al
- inc dx
- mov al,0fh ; all 4 planes
- out dx,al
-
- ;====================================================================
- ; This loop is done for each char in the string
-
- PcharNextByte:
- mov cx,pX0 ;pick up user coordinates
- mov bx,pY0
- call emapxy ;compute byte & bit offset
-
- ; fetch a character, test that it is in range
-
- push di ;<6>points to video byte
- mov si,pFoffs ;address font structure
- mov es,pSseg ;addressability on the string to print
- mov di,lStrPos ;offset to next character in the string
- mov al,es:[di] ;fetch it
- cmp al,0
- jnz PcharNotEOS ;NULL=end of string 1 extra push on stack!!
- jmp PcharStrEnd
- PcharNotEOS:
- inc di ;prepare for next char
- mov lStrPos,di ;save offset away
- pop di ;<5>points to video again
-
- ; Test that it is within range
-
- cmp al,[si].first_ch ;is it lower that the 1st character
- jb PcharNextByte ;too low - ignore
- cmp al,[si].last_ch ;is it too big?
- jnbe PcharNextByte
-
- ; In range, now determine the offset within the font
-
- sub al,[si].first_ch ;ordinal position
- xor ah,ah ;clear top of ax
- mul lCellSize ;position x cellsize = offset within font
-
- ; Now make an indexed address out of it
-
- lea bx,[si].cell_base ;where the char definitions start
- add bx,ax ;bx = pointer to start of definition
- inc bx ;ignore 1st byte which is a proportional width
-
- ; we are now ready to print ???
-
- mov ax,lCurrVidSeg ;page #1
- mov es,ax ;ES=video DS=font
- mov si,bx ;font char definition
-
- call Pchar ; display this character
-
- ; Now adjust for the next character
-
- mov si,pFoffs ;address the font header
-
- ; Compute next char base from last char and fixed width
- ; of font characters
-
- mov dl,[si].char_wide ;width in pixels
- xor dh,dh ;DL=actual width of character set
- add pX0,dx ;DI=start of next character
-
- jmp PcharNextByte
-
- ; All done
-
- PcharStrEnd:
- pop di ;pop off that Di that was pushed just
- ; b4 fetching the NULL but never poped
- ; reset write mode
- mov dx,GRAPHIC12
- mov al,ENABLERESET
- out dx,al
-
- inc dx
- mov al,00h ;Enable all planes for set
- out dx,al
-
- ; set bitmask to FF
-
- GR12_BITMASK 0ffh ;reset all pixel masks just incase
-
- mov ax,pX0 ; next character position
- pop es ;<4>
- pop ds ;<3>
- pop di ;<2>
- pop si ;<1>
- popf
- mov sp,bp
- pop bp ;<0>
- ret
-
- Pchar proc NEAR
- ;====================================================================
- ;====================================================================
- ; put an individual character on the screen
- ; DS:SI = beginning of char definition in font
- ; ES:DI = top of character cell invideo memory
- ; ah = bit to be used next after shifting
- ; al = 1) bits from font 2) by macro for video controler
- ; bx = count of bits processed
- ; cx = shifting count to align with video memory
- ; dx = 1) video controller 2) temp stuff
- ;
- ;----------------------------------------------------------------------
- mov al,lHigh
- mov lHwrk,al ;count of scan lines
-
- ; compute alignment amount to video memory
-
- mov cx,pX0 ;video position
- and cx,7 ;alignment amount
-
- PcharScanLine:
- push di ;<6>save start of scan line pixel
- mov bx,lBytesWide ;cell width in bytes
- xor ax,ax ;all zeros
-
- PcharScanByte:
- lodsb ;get a byte of of the font 0000000011111111
- dec bx ;bytes -= 1
- ror ax,cl ;rotate unused up into AH 1100000000111111
- push ax ;<7>save current bits
- mov ah,al ;move wanted to ah 0011111100111111
- GR12_BITMASK ah ;mask pixels to be updated ^^^^^^^^
- mov ax,pColor ;retreive the color
- mov ah,es:[di] ;store thru bits set
- stosb ;store color thru bit mask
- pop ax ;<6>get back the scan image 1100000000111111
- rol ah,cl ;leftover bits to end of AH 00000011xxxxxxxx
-
- ; adjust bits/scan line
-
- cmp bx,0 ; is this the 1st or later times through?
- jg PcharScanByte ; more bytes to process
-
- PcharRiteEnd:
- ror ah,cl ;move remaining bits into top of AH
- GR12_BITMASK ah
- mov al,es:[di]
- stosb ;store color thru bit mask
-
- PcharScanDone:
- pop di ;<5>get back start of scan line
- add di,lBwide ;move to next scanline
- dec lHwrk ;
- jnz PcharScanLine ;nope- do another
- ret
- Pchar endp
- _etext endp
-