[net.micro.6809] 8-bit A/D under OS9

michael@python.UUCP (M. Cain) (04/01/86)

I have recently been experimenting with the Coco Max
8-bit A/D converter using OS9.  The documentation is
scanty -- "the module is addressed at 0xff90" is the
extent of it -- but I have had some success.  The
following code fragment works:

point = (char *)0xff90;
for (i=0; i<4; i++) mouse[i] = *point++;

After the loop, mouse[1] contains a vertical coordinate,
mouse[2] a horizontal, and mouse[3] indicates the status
of the button.  The advantage of the 8-bit A/D values is,
of course, that it is now possible to point to individual
pixels on a high-resolution graphics screen without
resorting to "sliding windows" or the like.

The following attempts at efficiency all break the code:

  - Unrolling the loop,
  - Skipping the "wasted" access of 0xff90,
  - Declaring mouse to be an array of type char rather
    than type int.

I tried taking the cartridge apart, but it appears that
unreasonable amounts of force are needed, and I didn't
want to risk any damage to the internals.  Does anyone
know what's inside, and how it's being used?

Finally, I find that it is necessary for any programs that
poll the module to make a sleep(n) call at the beginning,
with n a small integer -- if I don't, the disk drive motor
continues to run, apparently forever.

Michael Cain

knudsen@ihwpt.UUCP (mike knudsen) (04/03/86)

> I have recently been experimenting with the Coco Max
> 8-bit A/D converter using OS9.  The documentation is
> scanty -- "the module is addressed at 0xff90" is the
> extent of it -- but I have had some success.  The
> following code fragment works:
> 
> point = (char *)0xff90;
> for (i=0; i<4; i++) mouse[i] = *point++;
> 
> After the loop, mouse[1] contains a vertical coordinate,
> mouse[2] a horizontal, and mouse[3] indicates the status
> of the button.  The advantage of the 8-bit A/D values is,
> of course, that it is now possible to point to individual
> pixels on a high-resolution graphics screen without
> resorting to "sliding windows" or the like.

You bet!  I've been using Max in an OS9 music editor,
currently under construction.

> The following attempts at efficiency all break the code:
>   - Unrolling the loop,
>   - Skipping the "wasted" access of 0xff90,
>   - Declaring mouse to be an array of type char rather
>     than type int.

OK, I can answer all the above.
THe local Coco club got a schematic and some text explanations
from somebody about this box.  The secrets of the NatSemi
A/D inside are as follows:
(0) The A/D chip goes straight to the address & data busses,
no PIA chip used.
(1) It has a built-in analog mux to select any of 8 inputs
	(Max only uses 4, incl. an extra fire button):
	0 = Y-axis (yeah, backwards)
	1 = X
	2 = fire (low = button pressed)
	3 = "other" fire (it's on the DIN connector center pin)
	4-7 = unused (hack away...)
(2) The low-order 3 bits of your read address set the
analog mux.
(3) The chip takes about 100 usec to do a conversion.
(4) Each time you read the box, THREE things happen at once
    (since 3 control pins on the chip are all tied to
    the read pulse):
	-- the latest conversion value is output to the bus
	-- a new conversion is started
	-- the mux is set to the low 3 bits as per (2)
	
Now we can talk.  Your C code is like mine
except mine is more conservative (unrolled but with delays).
It's a great example of "pipelining!"
*The first read, to FF90, sets mux to 0 = Y-axis
and starts a conversion, and reads garbage.
See why this "wasted" access is needed?
*Your second read, to FF91, reads the Y value (ASSUMING
the conversion is complete!), steers the mux to the X value,
and starts converting it.
*Third read gets the X value and starts converting the Fire.
*Fourth read gets the Fire value, never mind the rest.

You've been lucky that OS9 C code is so slow -- the looping
provides the 60-100 ms delay required for conversion.
When you soup up the code by unrolling, you read values
before the conversion is complete.  My code is unrolled,
but I have delay loop (about 5 counts) between each
access.
Also, since mouse[] is int, 6809 must SEX each byte you
read from Max before storing away, and do a STD instead
of STB.  That adds about 3 us to the loop (you must be right
on the hairy edge!)

I'm impressed by how well you made out and what you
discovered without the club document.  You've inspired me
to decrease my delay loop constant even further!

> I tried taking the cartridge apart, but it appears that
> unreasonable amounts of force are needed, and I didn't
> want to risk any damage to the internals.  Does anyone
> know what's inside, and how it's being used?

There's a screw hiding under the label somewhere;
then it snaps apart.  I'll post the chip type, but
my docs are at home.  Anyone sends me a SASE, I'll USmail 'em
a copy.
> Finally, I find that it is necessary for any programs that
> poll the module to make a sleep(n) call at the beginning,
> with n a small integer -- if I don't, the disk drive motor
> continues to run, apparently forever.

I never had this problem in OS9.  Sounds like your interrupts
are getting blocked.
OOPS -- did you give a proper (not just ENTER) response to
"setime" when booting up?  Else the clock doesn't start.

> Michael Cain
What's it all about, Maxie?
	mike k
PS: BASIC09 and RS-BASIC are slow enuf that your straightforward
loop should work.  Even unraveled in RS-BASIC.