;TXT89a.ASM (c) Copyright 1990 Lawrence Gozum & Marvin Gozum, MD.

;Greeting GIF Developers !

;The GIF 89a standard poses some very difficult specs for decoders to
;conform with.  One of them is the VARIABLE character display which
;can range from 1x1 chracters to 256x256 characters <sheesh>.

;Anyway, with this routine you can point CHARseg and CHARptr to ANY
;bitmap character set you desire.  In its present form, it will support
;8x256 character definitions.  You will have to do some tweaking to get
;256x256 character definitions as indicated in relevant segments below.

;The algorithm and routine presented here will be used in an updated
;version of MVGAVU which will support GIF 89a decoding as well as a
;new utility called GIFONT which will miximize text manipulation and
;utilization of the numerous Public Domain bitmap fonts in BBSs.

;This code (ie., TXT89A.ASM) is hereby released to the Public Domain and
;can be used anywhere and by anyone in ANY fashion they choose.  We hope
;this will encourage the acceleration of GIF89a decoder development.  
;A little acknowldegement of its use or variation of its use would be
;more than appreciated.

;This code is easily ported to 'C' applications.  All you have to do is
;change the stack passing parameters to 'C' format.

;Enjoy.

;lawrence - 09 September 1990


data    segment byte    public  'data'  ;1

x               dw      ?
y               dw      ?
xreset          dw      ?
char            dw      ?

line            db      ?
i               db      ?

tcolor          db      ?
bcolor          db      ?
fcolor          db      ?

cxtbl   db      256     dup(?)

Charseg dw      ?
Charptr dw      ?
Charloc dw      ?
Chartmp dw      ?

CharW   db      ?
CharH   db      ?
CharL   db      ?
Ctran   db      ?

cy      db      256      dup(?)
c       db      256      dup(?)
cbits   db      256      dup(?)

data    ends

dgroup  group   data
code    segment byte    public  'code'
                assume  cs:code,    ds:dgroup

chardata        proc    near
                                        ;This routine is a bit wasteful
                                        ;but is very expandable.

                                        ;It is structured this way to
                                        ;accomodate character widths
                                        ;up to 256 pixels wide.
                mov     ax,char
                mov     cbits[0],al
                shl     al,1
                mov     cbits[1],al
                shl     al,1
                mov     cbits[2],al
                shl     al,1
                mov     cbits[3],al
                shl     al,1
                mov     cbits[4],al
                shl     al,1
                mov     cbits[5],al
                shl     al,1
                mov     cbits[6],al
                shl     al,1
                mov     cbits[7],al

                mov     bp,0
                mov     ah,0
cxloop:         mov     al,cxtbl[bp]
                mov     di,ax
                mov     al,cbits[di]
                mov     c[bp],al
                inc     bp
                mov     ax,bp
                cmp     al,CharW
                jne     cxloop
                ret
chardata        endp

                public  CharParms
CharParms       proc    far
                push    bp
                mov     bp,sp
                mov     bx,[bp+18]
                mov     ax,[bx]         ;segment of character bitmap
                mov     CHARseg,ax

                mov     bx,[bp+16]
                mov     ax,[bx]         ;offset of character bitmap
                mov     CHARptr,ax

                mov     bx,[bp+14]
                mov     ax,[bx]         ;Character cell width (DESTINATION)
                mov     CharW,al

                mov     bx,[bp+12]
                mov     ax,[bx]         ;Character cell height (DESTINATION)
                mov     CharH,al

                mov     bx,[bp+10]
                mov     ax,[bx]         ;# of bytes per character fr SOURCE
                mov     CharL,al

                mov     bx,[bp+8]
                mov     ax,[bx]         ;transparency flag
                mov     CTran,al

                mov     bx,[bp+6]
                mov     ax,[bx]         ;transparency color
                mov     tcolor,al

                pop     bp
                ret     14
CharParms       endp

                public  GetCharXpts
GetCharXpts     proc    far             ;This routine get the
                push    bp              ;interpolated x-axis and
                mov     bp,sp           ;saves it to cxtbl for fast
                                        ;indexing up to 256 pixels
                                        ;in width per 89a specs.
                mov     bx,[bp+8]
                mov     ax,[bx]
                mov     es,ax

                mov     bx,[bp+6]
                mov     si,[bx]         ;es:si = QB array of x pts
                mov     cx,0

CXlineloop:     mov     bx,cx
                shl     bx,1
                mov     ax,es:[si]
                mov     bx,cx
                mov     cxtbl[bx],al
                inc     si
                inc     si
                inc     cx
                cmp     cx,256
                jne     CXlineloop

                pop     bp
                ret     4
GetCharXpts     endp

                public  GetCharYpts
GetCharYpts     proc    far             ;Conversely, this routine
                push    bp              ;get the 256 interpolated
                mov     bp,sp           ;y pixels for the Character
                                        ;cell height up to 256 pixels.
                mov     bx,[bp+8]
                mov     ax,[bx]
                mov     es,ax

                mov     bx,[bp+6]
                mov     si,[bx]         ;es:si = QB array of y pts
                mov     cx,0

CYlineloop:     mov     bx,cx
                shl     bx,1
                mov     ax,es:[si]
                mov     bx,cx
                mov     cy[bx],al
                inc     si
                inc     si
                inc     cx
                cmp     cx,256
                jne     CYlineloop

                pop     bp
                ret     4
GetCharYpts     endp


                public  XVGAtext
XVGAtext        proc    far
                push    bp
                mov     bp,sp

                mov     bx,[bp+12]      ;x
                mov     ax,[bx]
                mov     x,ax
                mov     xreset,ax

                mov     bx,[bp+10]
                mov     ax,[bx]         ;y
                mov     y,ax

                mov     bx,[bp+8]
                mov     ax,[bx]         ;foreground color
                mov     fcolor,al

                mov     bx,[bp+6]
                mov     ax,[bx]         ;background color
                mov     bcolor,al

                mov     bx,[bp+14]
                mov     ax,[bx]         ;actual character (asc value)
                mov     dx,0
                mul     CharL
                add     ax,CHARptr
                mov     CHARloc,ax
                mov     CHARtmp,ax

                mov     al,0
                mov     line,al
                mov     bl,Ctran
                cmp     bl,0            ;if transparency flag ON
                je      charloop2       ;no
                jmp     charloop2t      ;yes, jump to transparency routines
                                        ;since its too far for jxx offset

charloop2:      mov     al,0
                mov     i,al
                mov     es,CHARseg
                mov     si,CHARtmp
                mov     al,es:[si]
                mov     char,ax
                call    chardata

                mov     di,0A000h
                mov     es,di
                mov     ax,xreset
                mov     si,ax
                mov     di,0

charloop1:      mov     al,c[di]
                and     al,128
                jz      cbkgrnd

                call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine


                mov     al,fcolor       ;load al w/ foreground color
                mov     es:[di],al      ;plot it

nextcpix:       inc     si
                inc     i
                mov     ah,0
                mov     al,i
                mov     di,ax
                cmp     al,CharW
                jne     charloop1

                inc     Y
                inc     line
                mov     ax,CHARloc
                mov     bl,line
                mov     bh,0
                add     al,cy[bx]
                mov     CHARtmp,ax
                mov     al,line
                cmp     al,CharH
                jne     charloop2

                pop     bp
                ret     10

cbkgrnd:        call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine

                mov     al,bcolor       ;load al w/ background color
                mov     es:[di],al      ;plot it

                jmp     short nextcpix

charloop2t:     mov     al,0
                mov     i,al
                mov     es,CHARseg
                mov     si,CHARtmp
                mov     al,es:[si]
                mov     char,ax         ;use ax for expansion to 16 bits
                                        ;or larger by adding more indices
                                        ;(eg., es:[si+1])

                call    chardata        ;get the bits

                mov     di,0A000h
                mov     es,di           ;set ES to screen
                mov     ax,xreset       ;reset x
                mov     si,ax
                mov     di,0

charloop1t:     mov     al,c[di]
                and     al,128
                jz      cbkgrndt

                call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine

                mov     al,es:[di]
                cmp     al,tcolor
                je      nextcpixt

                call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine


                mov     al,fcolor       ;load al w/ foreground color
                mov     es:[di],al      ;plot it

nextcpixt:      inc     si
                inc     i
                mov     ah,0
                mov     al,i
                mov     di,ax
                cmp     al,CharW
                jne     charloop1t

                inc     Y
                inc     line
                mov     ax,CHARloc
                mov     bl,line
                mov     bh,0
                add     al,cy[bx]
                mov     CHARtmp,ax
                mov     al,line
                cmp     al,CharH
                je      cdone
                jmp     charloop2t

cdone:          pop     bp
                ret     10

cbkgrndt:       call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine

                mov     al,es:[di]      ;check if transparency color
                cmp     al,tcolor
                je      skiptrans

                call    vDUMMY          ;replace this with your
                                        ;video routine or look-up
                                        ;vector to JUMP to ANY
                                        ;video routine

                mov     al,bcolor       ;load al w/ background color
                mov     es:[di],al      ;plot it
skiptrans:      jmp     short nextcpixt

XVGAtext        endp

vDUMMY          proc    near
                                        ;This routine gets the MCGA
                                        ;320x200x256 mode address
                                        ;for reading and writing a
                                        ;pixel (ie.; character or
                                        ;color to be checked if
                                        ;transparency flag is ON)

                                        ;This routine is NOT optimized.
                                        ;It is here for demo purposes
                                        ;only.  You should use your
                                        ;optimized video drivers
                                        ;instead of this - its soooo
                                        ;slow.
                mov     ax,320
                mul     y               ;ax=y*320
                add     ax,si           ;ax has 64KB address
                                        ;si=x
                mov     di,ax           ;di = 64KB bank address
                ret
vDUMMY          endp



code            ends
                end



