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