; 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