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