[comp.sys.apple2] Hardware Project for II+

mdavis@pro-sol.cts.com (Morgan Davis) (05/28/90)

Hardware hackers, I have a project for you!  This is really neat.

If you've ever tried to write routines on the II+ that require precise
timing, you know you're in for trouble.  Especially now with a proliferation
of faster CPU's and speed-up cards that work in the Apple II+, the problem
is even worse.  On every other Apple, you can read the vertical blanking
signal (which cycles every 60th second) and synchronize timing loops to that.
On the II+, there is no such register you can read.

I started to think that the normally useless cassette tape ports could be
used.  If you could plug a little unit into the tape ports, one which
generated a 60Hz signal, you could read the tape's input register,
then the timing problem would be solved.

The ports provide power for a simple circuit to operate.  Parts needed would
probably be some regular phono input jacks (and interconnect), a small PC
board, an oscillating IC, and a few caps.  I'm not an EE graduate, so I'm
pretty ignorant about electronics.  However, it seems that such a project
would be quite simple to make.

Any electronics nuts out there who might have an idea on a schematic or basic
layout (and parts list) for such a project?

--Morgan

UUCP: crash!pnet01!pro-sol!mdavis		ProLine:  mdavis@pro-sol
ARPA: crash!pnet01!pro-sol!mdavis@nosc.mil	MCI Mail: 137-6036
INET: mdavis@pro-sol.cts.com			America Online, BIX: mdavis

toddpw@tybalt.caltech.edu (Todd P. Whitesel) (05/28/90)

Eh... you don't need any fancy hardware at all. There's a software polling
method that works with a bare motherboard, and many common peripherals can be
pressed into service as interrupt sources if you have some test-clips lying
around (of the kind used to make removable shift key mods, there is a Radio
Schlock part number for them but I forget what it is, I still have plenty of
them in working condition).

You can poll the video data to determine when VBL begins, but you do need to
ensure that the last screen hole of the currently displayed video buffer is a
unique value (say $ab) and that the value appears nowhere else in the buffer.
You can read the last byte read for video by reading any softswitch or unused
location (I like $C040 but any location that doesn't read anything will do, as
long as the effects of that location are inconsequential to your program):

	lda	#$ab	;put your unique value here and in the last screen hole
vblwait	
	cmp	$c040	;or other unused location
	bne	vblwait
	...

You are now synchronized to the start of VBL.

How it works: when you read from a location that doesn't put anything on the
data bus, the last value read for video is still floating around and that's
what gets read (unless you have a really bizarre card plugged in). By putting
a unique value in the last screen hole (it gets read during blanking just
before VBL) you can poll for it using the loop above. Note that in a 1 mhz
machine the loop takes 7 cycles, which means that only 7 consecutive unique
bytes are needed to guarantee synchronization (make sure interrupts are set --
if they aren't then you should be using an interrupt source as the time base)
but I prefer using a full 8 just in case.

A much better solution is to use the 30 hz IRQ from an Apple Cat (very easy,
I wrote a cheap clock driver for it) or to program the timers on a Mockingboard
for regular interrupts. If you really want to get cheesy and have a spare
super serial card lying around, you can use transmit interrupts to get a time
base -- the handler should transmit a garbage character and do its processing.

Even better, test-clip the high-order bit from the video counter (it's a pin on
an LS161 at D-something) to either the modem control inputs of a busy SSC
(the serial chip will interrupt when either modem line changes state so you get
interrupts on both edges of the signal) or to an unused CA input on a
Mockingboard's 6522's (with these you can select which edge of the signal you
want an interrupt on).

Todd Whitesel
toddpw @ tybalt.caltech.edu

sb@pro-generic.cts.com (Stephen Brown) (06/03/90)

In-Reply-To: message from mdavis@pro-sol.cts.com

In this message, Morgan Davis says:
 
>If you've ever tried to write routines on the II+ that require precise
>timing, you know you're in for trouble. Especially now with a proliferation
>of faster CPU's and speed-up cards that work on the Apple II+, the problem
>is even worse. On every other Apple, you can read the vertical blanking
>signal (wich cycles every 60th second) and sychronize timing loops to that.

I have a couple of suggestions: First you can connect a resistor up to one of
the joystick (PDL) inputs. There are four, and usually two are used. This will
give you a fairly precise timer.  Alternatively, in Jim Sather's UNDERSTANDIN
G THE APPLE II, there is a small (2 IC) circuit to create an interrupt 416
cycles before the start of the screen display.

Don't forget the clock jitter of 140nS if your loop is not written in a
multiple of 65 cycles.

Hope this helps.  Stephen Brown (Willowdale, Ontario, CANADA)

UUCP: crash!pro-generic!sb
ARPA: crash!pro-generic!sb@nosc.mil
INET: sb@pro-generic.cts.com

paul@athertn.Atherton.COM (Paul Sander) (06/05/90)

In article <13128.infoapple.net@pro-generic> sb@pro-generic.cts.com (Stephen Brown) writes:
>I have a couple of suggestions: First you can connect a resistor up to one of
>the joystick (PDL) inputs. There are four, and usually two are used. This will
>give you a fairly precise timer.  Alternatively, in Jim Sather's UNDERSTANDIN
>G THE APPLE II, there is a small (2 IC) circuit to create an interrupt 416
>cycles before the start of the screen display.
>
>Don't forget the clock jitter of 140nS if your loop is not written in a
>multiple of 65 cycles.

Back around 1982, Don Lancaster wrote a book entitled "Enhancing your Apple II",
where he devotes a chapter or two to synchronizing with the vertical blanking,
with a one-wire mod.

I also understand that some folks reading this newsgroup have some way of
storing particular values in the unused locations scattered about the text
and hires pages, and then watch some unused location in the motherboard's
I/O page for those particular values.  It seems that these values will get
latched someplace where a program can see them during the retrace intervals.
All of this is undocumented by Apple, of course, but I seem to recall quite
a bit of discussion about this around two years ago.  Can someone elaborate
on this technique, and is it still used?
-- 
Paul Sander        (408) 734-9822  | Wisdom is beyond price, my son.  Be
paul@Atherton.COM                  | grateful that you have it.
{decwrl,pyramid,sun}!athertn!paul  | -- Imperius, in "Ladyhawk"

toddpw@tybalt.caltech.edu (Todd P. Whitesel) (06/07/90)

paul@athertn.Atherton.COM (Paul Sander) writes:

>I also understand that some folks reading this newsgroup have some way of
>storing particular values in the unused locations scattered about the text
>and hires pages, and then watch some unused location in the motherboard's
>I/O page for those particular values.  It seems that these values will get
>latched someplace where a program can see them during the retrace intervals.
>All of this is undocumented by Apple, of course, but I seem to recall quite
>a bit of discussion about this around two years ago.  Can someone elaborate
>on this technique, and is it still used?

I did in an earlier response to the first post, but here goes:

The unused locations are what are known as "screen holes" -- in every display
buffer on ][+ and //e the last eight bytes of every half page are not displayed
on the screen. In Main Text Page 1 the screen holes are reserved for the slots,
and some of the values are defined by Apple for various purposes. Using the
text screen holes is probably not such a hot idea unless you know what you are
doing.

The hires screen holes, however, are truly unused, and the technique involves
storing a unique byte value into the last eight bytes of the video buffer (i.e.
the last screen hole) -- this unique value must not appear anywhere else in the
buffer.

On the ][+ and //e (and even on the GS) reading from a location that does not
_in_the_hardware_ return any data (in the GS there are some unused locations
that always read zero) then whatever was last value on the data bus will still
be floating around and will get read; that last value just so happens to be the
last byte read by the video chips. So if you load the unique value into the
accumulator and do

.loop	CMP unused_I/O_loc
	BNE .loop

then you will essentially wait for VBL, because the last screen hole is read by
the video system just after the end of the last line on the screen, i.e. the
start of VBL. Those eight bytes are never displayed, but they _are_ read by the
video system at that time. (There is, of course, a reason for it. The video
address is also used as a refresh counter and while not every byte is displayed
they must all be read every so often, to keep the DRAMs from losing data.)

This technique is no longer in actual use as far as I know, but it is a rather
fascinating exploitation of the original video system design. There are much
better (read more accurate and less CPU overhead) methods of accomplishing the
same objective in the //e and especially in the GS, and this particular quirk
is one I would not mind Apple dropping support for; they would then have the
freedom to implement the video system using newer technology (horrors! An Apple
II that uses new technology!), namely Video RAMs.

Video RAMs are just one of the newer technologies that can save the Apple II,
if Apple would only admit that the IIGS video system is a kludge (which it is,
but doesn't have to be) and that the Video Overlay Card is an overpriced kludge
(which it is, but doesn't have to be).

Apple has always been so concerned about compatibility -- but the turning point
will be when they finally realize that the few issues which really hold back
development would never be missed by 99.9% of the user base.

Todd Whitesel
toddpw @ tybalt.caltech.edu