Metropoli BBS
VIEWER: fasttext.asm MODE: TEXT (ASCII)
; Fast string output - by Leia Kasija

.model tiny
.code
.186
org 100h

start:      call  main              ; call main proc
            mov   ax, 4C00h         ; exit to dos
            int   21h

string1     db    'Fast text writing demo',0
string2     db    'Written by Leia Kasija',0

main        proc

            mov   dx, offset font   ; get 16 point font
            call  getfont

            mov   ax, 12h           ; set video mode 12h
            int   10h

            mov   dx, 03CEh         ; set write mode 03h
            mov   ax, 0305h
            out   dx, ax

            xor   ax, ax            ; seed simple RNG
            mov   es, ax
            mov   di, es:[46Ch]

m_1:        mov   si, 58            ; get random X
            call  rand
            mov   bx, dx
            mov   si, 448           ; get random Y
            call  rand
            mov   cx, dx
            mov   si, 256           ; get random color
            call  rand
            mov   al, dl

            mov   dx, offset string1; display string1
            call  putstr
            add   cx, 16            ; display string2
            mov   dx, offset string2
            call  putstr

            mov   ah, 1             ; loop while no key
            int   16h
            jz    m_1

            xor   ah, ah            ; eat the key
            int   16h
            xor   ah, ah            ; wait for another key
            int   16h

            mov   ax, 03h           ; set text mode
            int   10h
            ret                     ; return

rand:       imul  di, 9421          ; randomize
            inc   di
            ror   di, 1

            mov   ax, di            ; divide by max
            xor   dx, dx
            div   si
            ret

main        endp

;---------------------------------------------------------------------
; putstr -- fast text writing routine
;---------------------------------------------------------------------
; bx = x, cx = y, al = color, ds:dx = string (x position is in bytes)

putstr      proc

            pusha                   ; save all registers
            push  es
            push  0A000h            ; es = video segment
            pop   es

            mov   si, dx            ; si = string

            imul  bp, cx, 80        ; bp = offset
            add   bp, bx

            mov   bl, 0Fh           ; bl = foreground
            and   bl, al

            shl   ax, 4             ; ah = background
            and   ax, 0F00h         ; al = 0
            mov   dx, 03CEh         ; set color
            out   dx, ax

            mov   byte ptr es:[bp], 0FFh
            mov   ah, es:[bp]       ; load latches

            mov   ah, bl            ; ah = foreground
            out   dx, ax            ; set color

p_1:        lodsb                   ; get char
            and   ax, 0FFh          ; zero?
            jz    p_3

            mov   bx, ax            ; bx = font offset
            shl   bx, 4

            mov   di, bp            ; di = offset
            mov   cx, 8             ; 8 words  [16 point font]

p_2:        mov   ax, word ptr cs:[font+bx] ; get font word
            mov   es:[di], al       ; write to screen
            mov   es:[di+80], ah
            add   bx, 2             ; next 2 rows
            add   di, 160
            dec   cx                ; loop
            jnz   p_2

            inc   bp                ; next char space
            jmp   p_1               ; loop

p_3:        pop   es                ; restore registers
            popa
            ret                     ; return

putstr      endp

;---------------------------------------------------------------------
; getfont -- copy bios 16 point font into buffer
;---------------------------------------------------------------------
; ds:dx = buffer for font

getfont     proc

            pusha                   ; save all registers
            push  ds
            push  es

            push  dx                ; save dx
            mov   ax, 1130h         ; get ptr. to font
            mov   bh, 06h
            int   10h

            push  ds                ; switch ds, es
            push  es
            pop   ds
            pop   es

            mov   dx, cx            ; dx = extra bytes  (needed if
            sub   dx, 16            ; this not a real 16 point font)

            mov   bx, 100h          ; bx = number of chars
            mov   si, bp            ; si = ptr. to font
            pop   di                ; di = buffer

g_1:        mov   cx, 16            ; copy 16 bytes
            rep   movsb
            add   si, dx            ; skip extra bytes
            dec   bx                ; loop
            jnz   g_1

            pop   es                ; restore registers
            pop   ds
            popa
            ret                     ; return

getfont     endp

font        db 4096 dup(?)          ; font buffer

end         start
[ RETURN TO DIRECTORY ]