Search code examples
assemblygraphicletters

Assembly. How to put letters in grahic mode?


How to put letters in graphic mode on position which I want to. Can I display letters in graphic mode or should I define it pixel by pixel in two-dimensional table? Could you give me a example, because I am trying to write animation letters on sinus. Any guides?

Architecture NASM on DOS. It could be 16 or 32 bit. I use DOSBOX on Windows. And compile code by this script: nasm -f obj -g -F borland %1.asm tlink /v %1.obj io.obj, %1.exe

Ok I use fragment from forum:

segment .data
        msg db "Hello world!$"

segment .code
..start:
mov ax, 13h 
int 10h

mov ax, 0a000h
mov es, ax
xor di, di


mov al, 15
mov cx, 100

; start fragment from forum
mov si,msg_text
call print_colored
print_colored:
.loop:
lodsb
cmp al,0
je .done
inc bl
mov ah,0x0E
Int 0x10
jmp .loop
.done:
ret
;end fragment from forum
xor ah, ah
int 16h

mov ax, 3
int 10h   ; go to text mode

mov ax, 4c00h
int 21h 

; variables

msg_text DB "abc"                  ;Text
msgCol  DB 0x07,0x08,0x09,0x0A,0x0B ;Colours
msgXY   DW 0x0E26                   ;Col/Row
msgLen  DB 0x05                     ;Length

And it doesn't work as I want to. It display text in current time when I write it in keyboard. This program display only: http://i62.tinypic.com/e898q8.jpg

In my program I want to put string in psp or even in code and later display on graphic mode screen. So firstly I want to know how to display letter on position which I want to, because later I will try put this string on sinus and try to animate it.


Solution

  • Inside of the bios of the display device there are some font table and we can get the pointer of it.

    RBIL->inter61a.zip->INTERRUP.A
    --------V-101130-----------------------------
    INT 10 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA)
    AX = 1130h
    BH = pointer specifier
        00h INT 1Fh pointer
        01h INT 43h pointer
        02h ROM 8x14 character font pointer
        03h ROM 8x8 double dot font pointer
        04h ROM 8x8 double dot font (high 128 characters)
        05h ROM alpha alternate (9 by 14) pointer (EGA,VGA)
        06h ROM 8x16 font (MCGA, VGA)
        07h ROM alternate 9x16 font (VGA only) (see #00021)
        11h (UltraVision v2+) 8x20 font (VGA) or 8x19 font (autosync EGA)
        12h (UltraVision v2+) 8x10 font (VGA) or 8x11 font (autosync EGA)
    Return: ES:BP = specified pointer
    CX    = bytes/character of on-screen font (not the requested font!)
    DL    = highest character row on screen
    Note:   for UltraVision v2+, the 9xN alternate fonts follow the corresponding
      8xN font at ES:BP+256N
    BUG:    the IBM EGA and some other EGA cards return in DL the number of rows on
      screen rather than the highest row number (which is one less).
    SeeAlso: AX=1100h,AX=1103h,AX=1120h,INT 1F"SYSTEM DATA",INT 43"VIDEO DATA"
    
    Format of alternate font table [array]:
    Offset  Size    Description (Table 00021)
     00h    BYTE    character to be replaced (00h = end of table)
     01h  N BYTEs   graphics data for character, one byte per scan line
    

    Example of the first pointer:

    RBIL->inter61b.zip->INTERRUP.E
    --------B-1F---------------------------------
    INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT
    Desc:   this vector points at 1024 bytes of graphics data, 8 bytes for each
      character 80h-FFh
    Notes:  graphics data for characters 00h-7Fh stored at F000h:FA6Eh in 100%
      compatible BIOSes
    Under PhysTechSoft's PTS ROM-DOS this table is fictitious.
    SeeAlso: INT 10/AX=5000h,INT 43
    

    But we can also use our own:

    ;-------------------------------------- ────────────────┤
    T34 DB 1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 ;*      **      *│
        DB 1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1 ;**     **     **│
        DB 0,1,0,0,0,1,1,1,1,1,1,0,0,0,1,0 ; *   ******   * │
        DB 0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,0 ; **  ******  ** │
        DB 0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0 ; **    **    ** │
        DB 0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0 ; **    **    ** │
        DB 0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0 ;  *          *  │
        DB 0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0 ;   ***    ***   │
        DB 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0 ;      ****      │
        DB 0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0 ;     ******     │
        DB 0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0 ;    **    **    │
        DB 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0 ;   **      **   │
        DB 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0 ;   **      **   │
        DB 0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0 ;   **      **   │
        DB 0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0 ;    **    **    │
        DB 0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0 ;  ****    ****  │
    ;-------------------------------------- ────────────────┤
    

    Address calculation of the target position= (yposition * scanline) + (xposition * bytes per pixel)
    Mode 13h: scanline = 320; bytes per pixel = 1

    Example:

    mov ax, yposition
    mov bx, 320
    mul bx
    add ax, xposition
    mov di, ax    ; Now DI contains the offset address of the target position
    

    Basic example for to read a font from the screen(80x30;640x480; 16 colors):

    SCREEN 12
    B = -1
    G = 2
    W = 90
    A = 11 * B
    R = 140
    IF B = 1 THEN R = R - G * 13
    P = 3.141592654# / 180
    Z$ = "DOS     DIE PC-Zeitschrift"
    FOR I = 1 TO LEN(Z$)
    LOCATE 1, 1: PRINT MID$(Z$, I, 1)
      FOR X = 0 TO 6
       FOR Y = 1 TO 14
        IF POINT(X, Y) = 15 THEN GOSUB Schreib
       NEXT Y
      NEXT X
      W = W - A
      NEXT I
    END
    Schreib:
     FOR X1 = 1 TO G
      FOR Y1 = 1 TO G
       IF B = 1 THEN X2 = X * G + X1: Y2 = (Y * G + Y1) + R
       IF B = -1 THEN X2 = X1 - X * G: Y2 = (Y1 - Y * G) + R
        XS = X2 * COS(P * W) - Y2 * SIN(P * W)
        YS = X2 * SIN(P * W) + Y2 * COS(P * W)
          PSET (XS + 320, YS + 240), 15
      NEXT Y1
     NEXT X1
    RETURN