]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/xtext.asm
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / xlib / xtext.asm
1 ;-----------------------------------------------------------------------\r
2 ; MODULE XTEXT\r
3 ;\r
4 ; Point functions all MODE X 256 Color resolutions\r
5 ;\r
6 ; Compile with Tasm.\r
7 ; C callable.\r
8 ;\r
9 ;\r
10 ; ****** XLIB - Mode X graphics library                ****************\r
11 ; ******                                               ****************\r
12 ; ****** Written By Themie Gouthas                     ****************\r
13 ;\r
14 ; egg@dstos3.dsto.gov.au\r
15 ; teg@bart.dsto.gov.au\r
16 ;-----------------------------------------------------------------------\r
17 \r
18 \r
19 include xlib.inc\r
20 include xtext.inc\r
21 \r
22 .data\r
23 \r
24 _FontDriverActive db 0\r
25 \r
26 \r
27 _CharHeight   db         0\r
28 _CharWidth    db         0\r
29 _FontPtr      dw  2 dup (0)\r
30 _FirstChar    db         0\r
31 \r
32 _UserFontPtr   dw  2 dup (0)\r
33 _UserChHeight  db         0\r
34 _UserChWidth   db         0\r
35 _UserFirstCh   db         0\r
36 \r
37 \r
38 F8x8Ptr       dw  2 dup (0)\r
39 F8x14Ptr      dw  2 dup (0)\r
40 \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
45 ; TELL ME!\r
46 \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
64 \r
65 MirrorTableOffs dw         ?\r
66 .code\r
67 \r
68 ;----------------------------------------------------------------------\r
69 ; x_text_init    - Initializes the Mode X text driver and sets the\r
70 ;                  default font (VGA ROM 8x8)\r
71 ;\r
72 ; C caller:\r
73 ;\r
74 ;  x_text_init()\r
75 ;\r
76 ; Written by Themie Gouthas\r
77 ;----------------------------------------------------------------------\r
78 _x_text_init proc\r
79   push bp\r
80 \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
89 \r
90   mov  word ptr [_FontPtr],bp     ; Default font = 8x8 ROM font\r
91   mov  word ptr [_FontPtr+2],es\r
92 \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
98 \r
99 \r
100   mov  al,8\r
101   mov  [_CharHeight],al            ; Set the font character heights\r
102   mov  [_CharWidth] ,al            ; Set the font character widths\r
103 \r
104   mov  dx,offset MirrorTable       ; Initialize mirror table offset\r
105   mov  [MirrorTableOffs],dx\r
106 \r
107   pop  bp\r
108   ret\r
109 _x_text_init endp\r
110 \r
111 \r
112 ;----------------------------------------------------------------------\r
113 ; x_set_font - Mode X Set current font for text drawing\r
114 ;\r
115 ; C caller:\r
116 ;\r
117 ;  x_set_font(int FontID)\r
118 ;\r
119 ; PARAMETERS  FontID    0 = VGA ROM 8x8\r
120 ;                       1 = VGA ROM 8x14\r
121 ;                       2 = User defined bitmapped font\r
122 ;\r
123 ;\r
124 ; WARNING: A user font must be registered before setting FontID 2\r
125 ;\r
126 ; Written by Themie Gouthas\r
127 ;----------------------------------------------------------------------\r
128 \r
129 _x_set_font proc\r
130   ARG FontID:word\r
131   push bp\r
132   mov  bp,sp\r
133 \r
134   xor  dx,dx             ; Clear DX - Mirror table offset (0 for non ROM fonts)\r
135   mov  cx,FontID\r
136   cmp  cx,2\r
137 \r
138   jne  @@not_userfont     ; Do we have a user font\r
139   mov  ax,[_UserFontPtr]   ; Yes - Activate it\r
140   mov  [_FontPtr],ax\r
141 \r
142   mov  ax,[_UserFontPtr+2]\r
143   mov  [_FontPtr+2],ax\r
144 \r
145   mov  al,[_UserChHeight]\r
146   mov  [_CharHeight],al   ; Set the font character heights\r
147 \r
148   mov  al,[_UserChWidth]\r
149   mov  [_CharWidth],al    ; Set the font character heights\r
150 \r
151   mov  al,[_UserFirstCh]\r
152   mov  [_FirstChar],al\r
153   jmp  short @@done\r
154 \r
155 @@not_userfont:              ; We have a ROM font\r
156 \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
162 \r
163   mov  ax,[F8x14Ptr]         ; Yes Activate it\r
164   mov  [_FontPtr],ax\r
165 \r
166   mov  ax,[F8x14Ptr+2]\r
167   mov  [_FontPtr+2],ax\r
168 \r
169   mov  [_CharHeight],14    ; Set the font character heights\r
170   jmp  short @@done\r
171 \r
172 @@not_8x14font:\r
173   mov  ax,[F8x8Ptr]        ; Activate the 8x8 ROM Font\r
174   mov  [_FontPtr],ax\r
175 \r
176   mov  ax,[F8x8Ptr+2]\r
177   mov  [_FontPtr+2],ax\r
178 \r
179   mov  [_CharHeight],8     ; Set the font character heights\r
180 \r
181 @@done:\r
182   mov  [MirrorTableOffs],dx\r
183 \r
184   pop  bp\r
185   ret\r
186 _x_set_font endp\r
187 \r
188 \r
189 ;----------------------------------------------------------------------\r
190 ; x_register_userfont - Mode X register user font\r
191 ;\r
192 ; C caller:\r
193 ;\r
194 ;  x_register_userfont(void far *user_font)\r
195 ;\r
196 ;\r
197 ; NOTES  registering a user font deregisters the previous user font\r
198 ;        User fonts may be at most 8 pixels wide\r
199 ;\r
200 ;\r
201 ; USER FONT STRUCTURE\r
202 ;\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
207 ;         of chars\r
208 ;\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
212 ;\r
213 ;\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
218 ;\r
219 ; Written by Themie Gouthas\r
220 ;----------------------------------------------------------------------\r
221 _x_register_userfont proc\r
222   ARG  FontToRegister:dword\r
223   push bp\r
224   mov  bp,sp\r
225   push si\r
226 \r
227   mov  ax,word ptr [FontToRegister]\r
228   mov  bx,word ptr [FontToRegister+2]\r
229   add  ax,4\r
230   mov  [_UserFontPtr],ax\r
231   mov  [_UserFontPtr+2],bx\r
232 \r
233   push ds\r
234   lds  si,[FontToRegister]\r
235   lodsw\r
236   mov  bx,ax\r
237   lodsw\r
238   pop  ds\r
239 \r
240   mov  [_UserChHeight],al\r
241   mov  [_UserChWidth],ah\r
242   mov  [_UserFirstCh],bl\r
243   pop  si\r
244   pop  bp\r
245   ret\r
246 _x_register_userfont endp\r
247 \r
248 \r
249 _x_get_char_width  proc\r
250   ARG  Chr:byte\r
251   push bp\r
252   mov  bp,sp\r
253 \r
254   xor  ah,ah\r
255   mov  al,[_CharWidth]\r
256   or   al,al\r
257   jz   @@NotFixed\r
258   pop  bp\r
259   ret\r
260 \r
261 @@NotFixed:\r
262   push si\r
263   mov  al,[_CharHeight]\r
264   mov  bx,ax\r
265   inc  al\r
266   mov  dl,[Chr]                   ; User fonts may have incomplete charsets\r
267   sub  dl,[_FirstChar]            ;  this compensates for fonts not starting at\r
268                                   ;  ascii value 0\r
269   mul  dl                         ; Mult AX by character to draw giving offset\r
270                                   ; of first character byte in font table\r
271   add  ax,bx\r
272   les  si,dword ptr [_FontPtr]\r
273   add  si,ax\r
274   xor  ah,ah\r
275   mov  al,es:[si]\r
276   pop  si\r
277   pop  bp\r
278   ret\r
279 _x_get_char_width  endp\r
280 \r
281 \r
282 ;----------------------------------------------------------------------\r
283 ; x_char_put - Mode X Draw a text character at the specified location\r
284 ;\r
285 ;\r
286 ; C caller:\r
287 ;\r
288 ;  x_char_put(char ch, int x, int y, unsigned ScrnOffs, unsigned Color)\r
289 ;\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
294 ;\r
295 ; NOTES:  Uses the current font settings. See SetFont, InitTextDriver,\r
296 ;         RegisterUserFont\r
297 ;\r
298 ; WARNING: InitTextDriver must be called before using this function\r
299 ;\r
300 ;\r
301 ; Written by Themie Gouthas\r
302 ;----------------------------------------------------------------------\r
303 _x_char_put  proc\r
304   ARG  Chr:byte,X:word,Y:word,ScrnOffs:word,Color:word\r
305   LOCAL ScreenInc:word,Hold:word=LocalStk\r
306   push bp\r
307   mov  bp,sp\r
308   sub  sp,LocalStk\r
309   push si\r
310   push di\r
311   push ds\r
312 \r
313   cld\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
321   mov  cx,di\r
322   shr  di,2\r
323   add  di,ax\r
324   add  di,[ScrnOffs]              ; Dont forget to compensate for page\r
325 \r
326   mov  ax,SCREEN_SEG              ; ES:DI -> first screen dest. byte of char\r
327   mov  es,ax\r
328 \r
329   and  cx,3                       ; CH = 0, CL = Plane of first pixel\r
330 \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
333   xor  ah,ah\r
334   mov  ch,al                      ; CH = Character height\r
335 \r
336   cmp  [_CharWidth],0\r
337   jne  @@NoWidthByte\r
338   inc  al\r
339 @@NoWidthByte:\r
340 \r
341   mov  dl,[Chr]                   ; User fonts may have incomplete charsets\r
342   sub  dl,[_FirstChar]            ;  this compensates for fonts not starting at\r
343                                   ;  ascii value 0\r
344   mul  dl                         ; Mult AX by character to draw giving offset\r
345                                   ; of first character byte in font table\r
346 \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
349 \r
350   mov  dx,SC_INDEX                ; Prepare for VGA out's\r
351 \r
352 @@MainLoop:\r
353 \r
354   lodsb               ; load character byte into AL\r
355   or   al,al\r
356   jz   @@NoCharPixels ; Dont bother if no pixels to draw\r
357 \r
358   or   bx,bx          ; if BX=0 -> User font, so no need to mirror data\r
359   jz   @@DontMirror\r
360   push ds\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
366 \r
367 @@DontMirror:\r
368   xor  ah,ah          ; shift the byte for the dest plane and save it\r
369   shl  ax,cl\r
370   mov  [Hold],ax\r
371 \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
376   jmp  @@SecondNibble\r
377 \r
378 @@p1:\r
379   mov  al,MAP_MASK\r
380   out  dx,ax\r
381   mov  al,byte ptr [Color]\r
382   stosb\r
383 \r
384 @@SecondNibble:\r
385                              ; output low nibble of first byte of shifted char\r
386   mov  ax,[Hold]\r
387   shl  ax,4\r
388   and  ah,0fh\r
389   jnz  @@p2\r
390   inc  di\r
391   jmp  @@ThirdNibble\r
392 \r
393 @@p2:\r
394   mov  al,MAP_MASK\r
395   out  dx,ax\r
396   mov  al,byte ptr [Color]\r
397   stosb\r
398 \r
399 @@ThirdNibble:\r
400   mov  ax,[Hold]             ; output high nibble of last byte of shifted char\r
401   and  ah,0fh\r
402   jnz  @@p3\r
403   inc  di\r
404   jmp  short  @@NextCharRow\r
405 \r
406 @@p3:\r
407   mov  al,MAP_MASK           ; completing the drawing of one character row\r
408   out  dx,ax\r
409   mov  al,byte ptr [Color]\r
410   stosb\r
411 \r
412 @@NextCharRow:\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
415   jnz  @@MainLoop\r
416 \r
417 @@done:\r
418   pop  es\r
419   mov  ah,0\r
420   mov  al,es:[_CharWidth]     ; return the character width (for string fuctions\r
421   or   al,al\r
422   jnz  @@FixedSpacing         ;  using this character drawing function).\r
423   lodsb\r
424 @@FixedSpacing:\r
425 \r
426   mov  bx,es\r
427   mov  ds,bx\r
428 \r
429   pop  di\r
430   pop  si\r
431   mov  sp,bp\r
432   pop  bp\r
433   ret\r
434 \r
435 @@NoCharPixels:\r
436   add  di,3\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
439   jnz  @@MainLoop\r
440   jmp  short @@done\r
441 \r
442 _x_char_put endp\r
443 \r
444 \r
445 end\r
446 \r