From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
Subject: Re: Line A: C lib?/ bitmap manipulation on the ST..?
Organization: SAR Systems Development & Processing, JPL
Date: Sat, 26 Sep 1992 23:33:15 GMT

In article <Bv49xE.1s9@iat.holonet.net> wilsont@orac.holonet.net (Timothy Wilson) writes:
>Yes.. more questions for the tech guys..
>
>I was wondering if there are PD C library files for the Line A routines?
>or.. should I bite the bullet and learn ASM?  

If you're using GNU C you can just use the linea.h that's provided in the
GCC C library. As far as I know, Turbo C also comes with linea bindings.
MWC does as well.
>
>also, I just found out, in my TOS book, that one pixel in lowres is
>spread out over 4 bytes. I have heard of this before in other architectures.
>but.. Why do they do this? Isn't it slower to do it this way?

Just a function of how they decided to design their video hardware. First of
all, remember that you're working with a 16-bit architecture, not 8-bit. That
means you can grab 16 bits at a time on every memory reference, so there's no
efficiency gain in using byte-oriented data.

The video hardware is built around a chip known as SHIFTER. This chip is so
named because that's exactly what it does; instead of writing a word of
video data to the screen all at once, it grabs the data for 16 pixels at a time
and shifts them out to the screen one pixel at a time. E.g., ST lo-res:

  word-1  word-2  word-3  word-4  ->    word-1
					word-2
					word-3
					word-4
					     ^
					     |__ 4 bits at a time are peeled
						 off to form the palette index

>I'd like to be able to manipulate bitmaps (rotations etc) but 
>since the pixel info is spread out, how to I convert these types of algorithms?
>
>i would assume that to get one pixel out of a graphics screen long word
>would take 32 shifts and 4 long word masks. Am I underestimating the speed
>of the 68000? it would seem that it would take a while (time that would add up
>over a large bitmap) to compute.

Hm. 4 longword masks? I don't see why that would be, you can simply load one
byte at a time. Actually, you can do it really easily with the movep
instruction. Point an address register at the byte containing the first bit
of the pixel you want, use movep to load the pixel bytes into a register,
shift once to get the right orientation, get the even bits, shift again by 8,
and get the odd bits. Like so:

	/* nothing like real code for examples, eh? */
	/* Copyright 1992 by Howard Chu. You may use this code in
	   your programs provided that you acknowledge the source. */

	int
	getpixel (int x, int y)  /* assumes lo-rez. med-rez is even easier */
	{
	  register char *addr __asm__("a0");
	  register long pixdat __asm__("d1");
	  register int result __asm__("d0");
	  register int shift __asm__("d2");

	  addr = screenbase + y * bytes_per_row + x/2;
	  shift = x & 7;
	  result = 0;

 time	  __asm__("
  24		movepl	a0@,d1	/* get pixel data */
 8-22		lsll	d2,d1	/* shift left to desired bit */
 8-10		jpl	0f	/* first bit is now in sign bit - check it */
   4		moveq	#1,d0
   4	0:	tstw	d1	/* 3rd bit is word sign-bit - check it */
 8-10		jpl	1f
   4		addqw	#4,d0
  24	1:	lsll	#8,d1	/* shift 2nd and 4th bits into place */
 8-10		jpl	2f	/* 2nd bit is sign bit - check it */
   4		addqw	#2,d0
   4	2:	tstw	d1	/* 4th bit is word sign-bit - check it */
 8-10		jpl	3f
   4		addqw	#8,d0
	3:");
	  return(result);
	}

There ya have it, no longword masks, and only two shift instructions.
Piece of cake, and valid GNU-C, t'boot. You can easily convert this into
a loop to decode a block of 16 pixels at a time. For medium rez, you
only need to do a word-length movep. As a further optimization, you can
precompute a table of row_addresses to save time when calculating the
initial addr to use. 

Total execution time for the marked code is 104 to 126 cycles, best to worst
case. (Might actually be 112 best case, I think the 10 cycle branches will
get padded to 12 by the bus timing.) That amounts to 13 to 15 microseconds
per pixel, running at 8MHz. To convert an entire screen would spend just
about 880 milliseconds in this code, best case, to just over 1 second,
worst case. Doesn't seem too bad.
-- 
  -- Howard Chu @ Jet Propulsion Laboratory, Pasadena, CA

California, land of dreams. For many, moving out to CA is their first step
toward fulfilling their dreams. For most of them, it's also their last.
Newsgroups: comp.sys.atari.st.tech