home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 11
/
CD_ASCQ_11_0294.iso
/
maj
/
666
/
xtext.asm
< prev
next >
Wrap
Assembly Source File
|
1993-09-12
|
13KB
|
447 lines
;-----------------------------------------------------------------------
; MODULE XTEXT
;
; Point functions all MODE X 256 Color resolutions
;
; Compile with Tasm.
; C callable.
;
;
; ****** XLIB - Mode X graphics library ****************
; ****** ****************
; ****** Written By Themie Gouthas ****************
;
; egg@dstos3.dsto.gov.au
; teg@bart.dsto.gov.au
;-----------------------------------------------------------------------
include xlib.inc
include xtext.inc
.data
_FontDriverActive db 0
_CharHeight db 0
_CharWidth db 0
_FontPtr dw 2 dup (0)
_FirstChar db 0
_UserFontPtr dw 2 dup (0)
_UserChHeight db 0
_UserChWidth db 0
_UserFirstCh db 0
F8x8Ptr dw 2 dup (0)
F8x14Ptr dw 2 dup (0)
; This is a look up table for the mirror image of a byte eg
; a byte with the value 11001010 has a corresponding byte in the table
; 01010011. This is necessary as the VGA rom font bits are the reverse
; order of what we need for the Mode X. If you know a better-faster way
; TELL ME!
MirrorTable label byte
db 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240
db 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248
db 4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244
db 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252
db 2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242
db 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250
db 6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246
db 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254
db 1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241
db 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249
db 5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245
db 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253
db 3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243
db 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251
db 7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247
db 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255
MirrorTableOffs dw ?
.code
;----------------------------------------------------------------------
; x_text_init - Initializes the Mode X text driver and sets the
; default font (VGA ROM 8x8)
;
; C caller:
;
; x_text_init()
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_text_init proc
push bp
mov [_FontDriverActive],TRUE
mov ax,1130h ; AH = BIOS generator function
; AL = BIOS get font pointer subfunction
push ax ; Save Video interrupt function parameters
mov bh,3 ; Select 8x8 VGA ROM font
int 10h ; Call BIOS video interrupt
mov word ptr [F8x8Ptr],bp ; Save 8x8 Font address in FontPtr table
mov word ptr [F8x8Ptr+2],es
mov word ptr [_FontPtr],bp ; Default font = 8x8 ROM font
mov word ptr [_FontPtr+2],es
pop ax ; Recall Video interrupt function parameters
mov bh,2 ; Select 8x14 VGA ROM font
int 10h ; Call BIOS video interrupt
mov word ptr [F8x14Ptr],bp ; Save 8x14 Font address in FontPtr table
mov word ptr [F8x14Ptr+2],es
mov al,8
mov [_CharHeight],al ; Set the font character heights
mov [_CharWidth] ,al ; Set the font character widths
mov dx,offset MirrorTable ; Initialize mirror table offset
mov [MirrorTableOffs],dx
pop bp
ret
_x_text_init endp
;----------------------------------------------------------------------
; x_set_font - Mode X Set current font for text drawing
;
; C caller:
;
; x_set_font(int FontID)
;
; PARAMETERS FontID 0 = VGA ROM 8x8
; 1 = VGA ROM 8x14
; 2 = User defined bitmapped font
;
;
; WARNING: A user font must be registered before setting FontID 2
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_set_font proc
ARG FontID:word
push bp
mov bp,sp
xor dx,dx ; Clear DX - Mirror table offset (0 for non ROM fonts)
mov cx,FontID
cmp cx,2
jne @@not_userfont ; Do we have a user font
mov ax,[_UserFontPtr] ; Yes - Activate it
mov [_FontPtr],ax
mov ax,[_UserFontPtr+2]
mov [_FontPtr+2],ax
mov al,[_UserChHeight]
mov [_CharHeight],al ; Set the font character heights
mov al,[_UserChWidth]
mov [_CharWidth],al ; Set the font character heights
mov al,[_UserFirstCh]
mov [_FirstChar],al
jmp short @@done
@@not_userfont: ; We have a ROM font
mov dx,offset MirrorTable
mov [_CharWidth],8 ; Set the font character widths
mov [_FirstChar],0 ; Character sets start at ascii 0
cmp cx,1 ; Do we have an 8x14 ROM font
jne @@not_8x14font ; No, we have 8x8 - jump
mov ax,[F8x14Ptr] ; Yes Activate it
mov [_FontPtr],ax
mov ax,[F8x14Ptr+2]
mov [_FontPtr+2],ax
mov [_CharHeight],14 ; Set the font character heights
jmp short @@done
@@not_8x14font:
mov ax,[F8x8Ptr] ; Activate the 8x8 ROM Font
mov [_FontPtr],ax
mov ax,[F8x8Ptr+2]
mov [_FontPtr+2],ax
mov [_CharHeight],8 ; Set the font character heights
@@done:
mov [MirrorTableOffs],dx
pop bp
ret
_x_set_font endp
;----------------------------------------------------------------------
; x_register_userfont - Mode X register user font
;
; C caller:
;
; x_register_userfont(void far *user_font)
;
;
; NOTES registering a user font deregisters the previous user font
; User fonts may be at most 8 pixels wide
;
;
; USER FONT STRUCTURE
;
; Word: ascii code of first char in font
; Byte: Height of chars in font
; Byte: Width of chars in font
; n*h*Byte: the font data where n = number of chars and h = height
; of chars
;
; WARNING: The onus is on the program to ensure that all characters
; drawn whilst this font is active, are within the range of
; characters defined.
;
;
; UPDATE: Variable width fonts are now available (up to 8 pixels max)
; If the Width byte in the font header is 0 then it is assumed that
; the font is variable width. For variable width fonts each characters
; data is followed by one byte representing the characters pixel width.
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_register_userfont proc
ARG FontToRegister:dword
push bp
mov bp,sp
push si
mov ax,word ptr [FontToRegister]
mov bx,word ptr [FontToRegister+2]
add ax,4
mov [_UserFontPtr],ax
mov [_UserFontPtr+2],bx
push ds
lds si,[FontToRegister]
lodsw
mov bx,ax
lodsw
pop ds
mov [_UserChHeight],al
mov [_UserChWidth],ah
mov [_UserFirstCh],bl
pop si
pop bp
ret
_x_register_userfont endp
_x_get_char_width proc
ARG Chr:byte
push bp
mov bp,sp
xor ah,ah
mov al,[_CharWidth]
or al,al
jz @@NotFixed
pop bp
ret
@@NotFixed:
push si
mov al,[_CharHeight]
mov bx,ax
inc al
mov dl,[Chr] ; User fonts may have incomplete charsets
sub dl,[_FirstChar] ; this compensates for fonts not starting at
; ascii value 0
mul dl ; Mult AX by character to draw giving offset
; of first character byte in font table
add ax,bx
les si,dword ptr [_FontPtr]
add si,ax
xor ah,ah
mov al,es:[si]
pop si
pop bp
ret
_x_get_char_width endp
;----------------------------------------------------------------------
; x_char_put - Mode X Draw a text character at the specified location
;
;
; C caller:
;
; x_char_put(char ch, int x, int y, unsigned ScrnOffs, unsigned Color)
;
; PARAMETERS ch char to draw
; x,y screen coords at which to draw ch
; ScrnOffs Starting offset of page on whih to draw
; Color Color of the text
;
; NOTES: Uses the current font settings. See SetFont, InitTextDriver,
; RegisterUserFont
;
; WARNING: InitTextDriver must be called before using this function
;
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_char_put proc
ARG Chr:byte,X:word,Y:word,ScrnOffs:word,Color:word
LOCAL ScreenInc:word,Hold:word=LocalStk
push bp
mov bp,sp
sub sp,LocalStk
push si
push di
push ds
cld
mov ax,[_ScrnLogicalByteWidth] ; AX = Virtual screen width
mov bx,ax ; copy Virt screen width and decrement
sub bx,3 ; by the max number of bytes (whole or part)
; that a character row may occupy on the screen
mov [ScreenInc],bx ; Save it to the local stack var. SceenInc
mul [Y] ; Find the starting dest. screen address of
mov di,[X] ; the character to draw
mov cx,di
shr di,2
add di,ax
add di,[ScrnOffs] ; Dont forget to compensate for page
mov ax,SCREEN_SEG ; ES:DI -> first screen dest. byte of char
mov es,ax
and cx,3 ; CH = 0, CL = Plane of first pixel
mov bx,[MirrorTableOffs] ; set BX to offset of mirror table for XLAT
mov al,[_CharHeight] ; AL = Character height, AH = 0
xor ah,ah
mov ch,al ; CH = Character height
cmp [_CharWidth],0
jne @@NoWidthByte
inc al
@@NoWidthByte:
mov dl,[Chr] ; User fonts may have incomplete charsets
sub dl,[_FirstChar] ; this compensates for fonts not starting at
; ascii value 0
mul dl ; Mult AX by character to draw giving offset
; of first character byte in font table
lds si,dword ptr [_FontPtr] ; DS:SI -> beggining of required font
add si,ax ; DS:SI -> first byte of req. char
mov dx,SC_INDEX ; Prepare for VGA out's
@@MainLoop:
lodsb ; load character byte into AL
or al,al
jz @@NoCharPixels ; Dont bother if no pixels to draw
or bx,bx ; if BX=0 -> User font, so no need to mirror data
jz @@DontMirror
push ds
mov dx,@data ; Set DS to the Mirror lookup table's segment
mov ds,dx ; - BX should already contain the offset addr of table
xlatb ; AL is now replaced by the corresponding table entry
pop ds ; Restore previous data segment
mov dx,SC_INDEX ; Restore DX
@@DontMirror:
xor ah,ah ; shift the byte for the dest plane and save it
shl ax,cl
mov [Hold],ax
mov ah,al ; output high nibble of first byte of shifted char
and ah,0fh ; 4 pixels at a time !
jnz @@p1 ; if nibble has pixels, draw them
inc di ; otherwise go to next nibble
jmp @@SecondNibble
@@p1:
mov al,MAP_MASK
out dx,ax
mov al,byte ptr [Color]
stosb
@@SecondNibble:
; output low nibble of first byte of shifted char
mov ax,[Hold]
shl ax,4
and ah,0fh
jnz @@p2
inc di
jmp @@ThirdNibble
@@p2:
mov al,MAP_MASK
out dx,ax
mov al,byte ptr [Color]
stosb
@@ThirdNibble:
mov ax,[Hold] ; output high nibble of last byte of shifted char
and ah,0fh
jnz @@p3
inc di
jmp short @@NextCharRow
@@p3:
mov al,MAP_MASK ; completing the drawing of one character row
out dx,ax
mov al,byte ptr [Color]
stosb
@@NextCharRow:
add di,[ScreenInc] ; Now move to the next screen row and do the same
dec ch ; any remaining character bytes
jnz @@MainLoop
@@done:
pop es
mov ah,0
mov al,es:[_CharWidth] ; return the character width (for string fuctions
or al,al
jnz @@FixedSpacing ; using this character drawing function).
lodsb
@@FixedSpacing:
mov bx,es
mov ds,bx
pop di
pop si
mov sp,bp
pop bp
ret
@@NoCharPixels:
add di,3
add di,[ScreenInc] ; Now move to the next screen row and do the same
dec ch ; any remaining character bytes
jnz @@MainLoop
jmp short @@done
_x_char_put endp
end