[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 6502 Delay Loops using Applesoft



Allen Bong wrote:
On Dec 4, 4:12 pm, "Michael J. Mahon" <mjma...@aol.com> wrote:

Scott Alfter wrote:

In article <02b1803a-1471-40cb-a69f-37dbab581...@o23g2000prh.googlegroups.com>,
Allen Bong  <allenbsf6...@gmail.com> wrote:

Has anyone written a gereral delay loop calculating program in
Applesoft, to calculate the constants required to gererate the
required time delays in 6502 codes?

The handful of times I've needed timing-critical delays (in an audio player
way back in the day, and more recently in some hardware bit-banging code),

Scott, I'd like to acknowledge you for your SoftDAC series, and
in particular for your original (mini-assembler) 3-bit version.

I downloaded it from Applelink Personal Edition (now AOL) in 1990, and
it started me on my various sound players/synthesizers, culminating in
DAC522 in 1993.

It was my amazement at hearing my Apple say "Insert Disk" quite
clearly that got me hooked on software DACs and what can be done
with them.

Thank you!


it was easy enough to do them manually.  The 6502 datasheet tells you how
many cycles each instruction needs to execute:

http://archive.6502.org/datasheets/rockwell_r650x_r651x.pdf
(go to page 10; it's the number in the lower right corner for each
instruction)

There are two pages (one for the 6502 and one for the 65C02) in Jim
Sather's _Understanding the Apple //e_ that provides even greater
detail on instruction timing, detailing the bus activity during each
cycle of each op.  This can be very useful in trimming down to one
cycle, since the actual time of an access is often the critical event.
(The .doc I sent Allen contains those two pages as reference material.)


The Apple II runs at approximately 1 MHz (it's actually a smidge faster than
that), so one cycle takes about one microsecond.  The shortest run time for
any instruction is two cycles, or about two microseconds.  For short delays
(small multiples of 2 us), a block of NOPs will do.  For longer delays, the
math to calculate how long a loop will take is fairly simple.

I put together a short table of compact time delay instruction sequences
(depending on which register (if any) is available at the moment.

And for precise timing, Sather computes the actual average clock
frequency of Apple II models precisely.  For most purposes, the rate
of 1.0205MHz is close enough.

When jitter is important, the 140ns "long cycle" at the end of each
scan line may need to be considered.  Hopefully, it is not a problem,
since the only way to control it is to synchronize with the video
generator, which creates its own timing issues.

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page:http://home.comcast.net/~mjmahon

"The wastebasket is our most important design
tool--and it's seriously underused."


Michael,

Sorry that I didn't reply you here sooner as I was tied up by some
projects that I was finishing off.  I read your doc. with great
interest and there was a typo in the tables in Page 5 of your text.


Delay Padding Code
Delay cycles	Bytes	Code sequence	Alternate code sequence
1	-	(Not possible)
2	1	nop
3	2	lda zp	sta zptrash
4	2	nop; nop
5	3	nop; lda zp	nop; sta zptrash
6	3	nop; nop; nop
7	2	php; plp
8	4	nop; nop; nop; nop
9	3	php; plp; nop
10	4	php; plp; lda zp	php; plp; sta zptrash
11	4	php; plp; nop; nop
12	3	jsr rtsloc

In Dealy 3,5,10, instead of "lda zptrash", you typed in "sta zptrash".

Actually, that's not a typo.  ;-)

A reason for using "sta zptrash" instead of "lda zp" is to preserve
the content of the A register and the flags (at the cost of destroying
a zero page location: zptrash).  This is often a good tradeoff.

You used 2 examples to explain how to generate shorter delays of
producing 4KHz audio tone and the longer delays of producing 300Hz
tone.  Both are very well explained, but I have difficulties
understanding hwo to calculate the no. of cycles use in the formulae
used in the delay loop below:


                  ldy	#ycnt	; (2 cycles)
		ldx	#xcnt	; (2 cycles)
delay		dex		; (2 cycles)
		bne	delay	; (3 cycles in loop, 2 cycles at end)
		dey		; (2 cycles)
		bne	delay	; (3 cycles in loop, 2 cycles at end)

is 2 + 2 + (5 * xcnt) - 1 + (ycnt-1) * (5 * 256 � 1 + 5) + 4

I have no problems with 2+2+(5*xcnt)-1, but (ycnt-1)*(5*256-1+5)+4, I
have some difficulties to understand.  Where does the -1 +5 and +4
came from? Would you explain a little bit more?

OK.

The initial "2 + 2 + (5 * xcnt) - 1" is the delay of the initial load
instructions plus the delay of the first execution of the X loop, with
xcnt as the number of iterations.  The "-1" at the end compensates for
the fact that the final execution of the bne with X = 0 only takes 2
cycles, not 3.

The next part of the equation deals with any Y iterations.  If ycnt = 1,
then the "dey; bne" doesn't branch, and the only additional delay is the
4 cycles taken by those instructions (that's what the "+ 4" at the end
is about).  If ycnt is not equal to one, then there will be ycnt-1
iterations of the X loop with X=0 (256 iterations) at "5 * 256 � 1"
cycles per iteration, plus an additional 5 cycles for the dey and the
*taken* bne (thus, "+ 5").

As for the servo delay, I haven't come to that yet.

Thank you very much.

You're very welcome.

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page:  http://home.comcast.net/~mjmahon/

"The wastebasket is our most important design
tool--and it's seriously underused."