[comp.binaries.ibm.pc] Fast characters in EGA mode 10h

nelson@sun.soe.clarkson.edu (Russ Nelson) (04/29/88)

Here is some (source, not binary :-) code that writes colored
characters in EGA mode 10h, 640x350x16 colors.  I wrote it because I
needed to create characters with varying attributes (bold, underlined,
italics) on the fly and write them quickly.  Also needed to scroll the
screen.  Public domain, do what you want with it.  Showfont.asm by itself
just shows the entire font 16 times for benchmarking purposes.

Challange: make it faster.  I don't think *you* can.  *I* can't.


showfont.asm:----------------cut here--------------------------------------
benchmark	equ	1	;=1 if we are doing a benchmark of output.


code	segment	public
	assume	cs:code, ds:code

	org	100h
start:
	jmp	short start_1

fore_color	db	0eh
back_color	db	03h

screen_offset	dw	0
char_set		dd	?

start_1:
	mov	bh,2			;get the 8x14 font.
	mov	ax,1130h
	int	10h			;es:bp -> font.
	mov	word ptr char_set+0,bp
	mov	word ptr char_set+2,es

	mov	ax,10h			;640 x 350 graphics mode.
	int	10h

  if benchmark
	mov	bh,10
keep_going:
  endif
	mov	bl,25
	mov	dl,0
	mov	al,fore_color
again:
	mov	cx,80
	mov	dh,0
once_more:
	call	xy_chrout
	inc	al
	inc	dh
	loop	once_more
	inc	dl
	dec	bl
	jne	again
  if benchmark
	inc	back_color
	dec	fore_color
	and	back_color,0fh
	and	fore_color,0fh
	dec	bh
	jne	keep_going
  endif

  ife benchmark
	mov	ah,0
	int	16h

	mov	cx,24
scroll_again:
	push	cx
	call	advance_line
	pop	cx
	loop	scroll_again

	mov	ah,0
	int	16h
  endif

	mov	ax,3
	int	10h

	int	20h


advance_line:
	mov	bx,screen_offset
	add	bx,0eh*80		;move down a text line.
	cmp	bx,25*0eh*80		;did we hit the bottom?
	jb	aL1
	xor	bx,bx
aL1:
	mov	screen_offset,bx


	mov	dx,03dah		;wait for vertical retrace.
al3:
	in	al,dx
	test	al,8
	jne	al3
al2:
	in	al,dx
	test	al,8
	je	al2

;bx = starting address offset
	mov	dx,03d4h

	mov	al,0ch
	mov	ah,bh
	out	dx,ax

	mov	al,0dh
	mov	ah,bl
	out	dx,ax

	mov	ax,screen_offset
	mov	dx,0
	mov	bx,80
	div	bx
	mov	bx,350			;compute the distance down the
	sub	bx,ax			;  screen to switch.

	mov	dx,03d4h
	mov	ah,bl
	mov	al,18h			;set the low byte of line compare.
	out	dx,ax
	shl	bh,1			;put the bit in the right place.
	shl	bh,1
	shl	bh,1
	shl	bh,1
	mov	ax,0fh*256 + 7		;set the overflow bits.
	or	ah,bh			;include the line compare bit.
	out	dx,ax

	ret


xy_chrout:
;enter with al = character to print, dh=col, dl=row.
	push	ax
	push	dx
	push	si
	push	di
	push	ds
	push	es

	mov	ah,14			;compute the proper font table entry.
	mul	ah
	lds	si,char_set
	add	si,ax

	mov	al,dh			;compute the column
	cbw
	mov	di,ax
	mov	al,dl			;multiply the row by 80*14
	xor	ah,ah
	mov	dx,80*14
	mul	dx
	add	di,ax			;add the row into the column.
	mov	ax,0a000h
	mov	es,ax
	assume	ds:nothing, es:nothing

	mov	dx,03ceh		;graphics controller
	mov	ax,0205h
	out	dx,ax
	mov	al,08h			;select bitmap register.
	out	dx,al
	inc	dx

	mov	al,back_color		;store the background color.
	mov	es:[di],al
	mov	al,es:[di]		;load the latches with the background.
	mov	ah,fore_color

storef	macro	i
	lodsb
	out	dx,al
	mov	es:[di+80*i],ah
	endm

	storef	0
	storef	1
	storef	2
	storef	3
	storef	4
	storef	5
	storef	6
	storef	7
	storef	8
	storef	9
	storef	0ah
	storef	0bh
	storef	0ch
	storef	0dh

	mov	al,0ffh			;mask = all ones.
	out	dx,al
	dec	dx
	mov	ax,0005h		;write mode 0
	out	dx,ax

	pop	es
	pop	ds
	pop	di
	pop	si
	pop	dx
	pop	ax

	ret


code	ends

	end	start