Fast screen drawing...

Joseph H Allen jhallen at wpi.wpi.edu
Fri May 4 20:05:11 AEST 1990


In article <24493 at usc.edu> dank at skat.usc.edu (Dan King) writes:
>
>I've been reading this group for a couple of weeks now, and haven't
>seen this mentioned, so I feel fairly confident that it's not a
>question that gets asked every two days.
>
>I'm using Turbo C to write an application that does a lot of text
>drawing (normal characters, not graphics or bitmapped) on platforms
>ranging from XTs to '386s and have noticed that the printing speed
>coming out of printf(), puts(), and putch() is dreadfully slow.  Has
>anyone else noticed this?  Am I missing something?
>
>Even just when puts()ing constant strings in a "tiny" memory model
>(does this make a difference?), it's pretty slow.  I'd rather not
>write inline code to do my own character writing but that looks like
>what it comes down to.  Has anyone else solved this problem?

Yep, all of those functions are slow since they go through DOS.  You have
several options (listed in order of compatibility and reverse order of speed):

1)	Use the undocumented console output function.  All dos console output
	eventually goes through this anyway:

		void cputc(char a)
		{
		_AL=a;
		geninterrupt(0x29);
		}

2)	Use the BIOS functions:

		/* Set cursor position */

		void cpos(unsigned x,unsigned y)
		{
		_DH=y;
		_DL=x;
		_BH=0;
		_AH=2;
		geninterrupt(0x10);
		}

		/* Write character. */

		void cputc(char a)
		{
		_BX=7;
		_AH=0xe;
		_AL=a;
		geninterrupt(0x10);
		}

		/* Write characters without moving the cursor */
		/* The character is written count times.  This can be
		used to clear areas of the screen */

		void cwrite(char a,unsigned count)
		{
		_CX=count;
		_BX=7;
		_AH=10;
		_AL=a;
		geninterrupt(0x10);
		}

		/* Scroll up */
		/* Count is lines to scroll, (x1,y1) is upper left and
		(x2,y2) is lower right of region to scroll */

		void scrup(int x1,int y1,int x2,int y2,int count)
		{
		_DH=y2;
		_DL=x2;
		_CH=y1;
		_CL=x1;
		_BH=7;
		_AH=6;
		_AL=count;
		geninterrupt(0x10);
		}

		/* Scroll down */
		/* Count is lines to scroll, (x1,y1) is upper left and
		(x2,y2) is lower right of region to scroll */

		void scrup(int x1,int y1,int x2,int y2,int count)
		{
		_DH=y2;
		_DL=x2;
		_CH=y1;
		_CL=x1;
		_BH=7;
		_AH=7;
		_AL=count;
		geninterrupt(0x10);
		}

3) Write directly to the screen.  Don't do this if you're using snowy CGA

		unsigned far *screen;
		unsigned height;
		unsigned width;

		/* Get screen parameters */

		void sparms(void)
		{
		_AH=15;
		geninterrupt(0x10);
		width=_AH;
		if(_AL==7) screen=(unsigned far *)0xb0000000;
		else screen=(unsigned far *)0xb8000000;
		height=*(unsigned char far *)0x00400084;
		if(!height) height=25;
		}

		So then to write to the screen you just:

		#define swrite(a,x,y) (*(screen+x+y*width)=0x700+(a))

		And then use the BIOS function to position the cursor.

Oh and there's one other alternative:  Look up the turbo-C function: puttext()
It's also quite fast.
-- 
jhallen at wpi.wpi.edu (130.215.24.1)



More information about the Comp.lang.c mailing list