[net.micro.apple] software timing

neves@uwai.UUCP (05/31/85)

I have a question/problem.  I'm writing several timing routines in
software but they are a bit off and I can't figure out why.  On a
1.023 MhZ Apple II there should be 1023 6502 cycles in a millisecond.
Below I have a routine that waits a number of milliseconds.  Each
loop traversal takes up 1023 cycles (or one millisecond).  I have
compared the time on a //e and II+ and against two Mountain Hardware
clocks and the clocks say that the wait routine is about 2.5 clock
cycles too slow (error rate of .25%).  Why?  Are the Mountain Hardware
clocks off by this much (has anyone testing them)?  Is the Apple crystal
(or whatever sets the frequency) really 1.0205 MhZ?  Am I doing something
really stupid in my software routine below?

-Thanks, david neves
Usenet:  {allegra,heurikon,ihnp4,seismo,uwm-evax}!uwvax!neves
Arpanet: neves@uwvax
----------------------------------------------------------------

;; assm routine for Pascal  that waits a number of milliseconds
return  .equ    0
stopmsec .equ   2       ;timeout location
        
;; Wait for a specified number of Msecs
;; wait(msec);
;;
;; 1023 clock cycles in 1 msec
;; 24 + 5n - 1 = 1023, n = 200
        .proc wait,1

;; Note: pull and push are the standard pla, sta or lda, pha macros
;;   defined elsewhere.

        pull return
        pull stopmsec

        lda bfirst+1
        cmp blast+1
        bne bloop2    ;make sure one of the loops is in a page

bloop1  nop             ;2 clock cycles
        nop             ;2
        ldx #200.       ;2
bl1     dex             ;
        bne bl1         ;200 * 5 -1 (-1 for bne dropthough)
        dec stopmsec    ;5
        beq lzero1      ;2
        
        nop             ;2  ;same # as lzero1 (11 clock cycles)
        nop             ;2
        nop             ;2
        clc             ;2
        bcc bloop1      ;3

lzero1  dec stopmsec+1  ;5 + 1 (+1 for sucessful beq jump to lzero1)
        bmi ret         ;2
        bpl bloop1      ;3 - nops above take same time as lzero1
eloop1
;----------------
ret     push return
        rts

bfirst  .word bloop1
blast   .word eloop1

bloop2  nop             ;2
        nop             ;2
        ldx #200.       ;2
bl2     dex             ;
        bne bl2         ;200 * 5 -1 (-1 for bne dropthough)
        dec stopmsec    ;5
        beq lzero2      ;2
        nop             ;2
        nop             ;2
        nop             ;2
        clc             ;2
        bcc bloop2      ;3

lzero2  dec stopmsec+1  ;5 + 1 (+1 for sucessful beq jump)
        bmi ret         ;2
        bpl bloop2      ;3 - 
        
.end

-- 
David Neves
Computer Sciences Department
University of Wisconsin-Madison

Usenet:  {allegra,heurikon,ihnp4,seismo,uwm-evax}!uwvax!neves
Arpanet: neves@uwvax

neves@uwai.UUCP (06/05/85)

Enclosed is an interesting message I received in response to my problem
with software timing routines on the Apple.  I think you will find it
interesting if you need to do anything similar.
------------------------------------------------------------
From: holmer%ucbdali@Berkeley (Bruce K. Holmer)
Message-Id: <8506051120.AA25988@ucbdali.ARPA>
To: neves@uwvax
Subject: apple timing
Cc: holmer%ucbdali@Berkeley
Status: R



> I have a question/problem.  I'm writing several timing routines in
> software but they are a bit off and I can't figure out why.  On a
> 1.023 MHz Apple II there should be 1023 6502 cycles in a millisecond.
> Below I have a routine that waits a number of milliseconds.  Each
> loop traversal takes up 1023 cycles (or one millisecond).  I have
> compared the time on a //e and II+ against two Mountain Hardware
> clocks and the clocks say that the wait routine is about 2.5 clock
> cycles too slow (error rate of .25%).  Why?  Are the Mountain Hardware
> clocks off by this much (has anyone testing them)?  Is the Apple crystal
> (or whatever sets the frequency) really 1.0205 MHz?  Am I doing something
> really stupid in my software routine below?

David Neves:

	I too was once puzzled by seeming timing discrepancies.  While
showing my computer and Mountain Music synthesizer cards to my piano tuner,
he commented on the pitch being slightly off.  He got out his old-fashioned
strobe tuner, and I poked various values into the frequency register on the
synthesizer card until I hit 440 Hz.  Later my calculations showed that
the apple was running at 1.0205 MHz, yet the note tables had all been
calculated using 1.023 MHz.  It was a mystery to me until I read
"Understanding the Apple II" by Jim Sather.  Here I quote Mr. Sather.

	The timing feedback from the video scanner elongates
	one system clock period at the end of each horizontal 
	television scan.  This elongation is necessary to keep
	colors consistent from scan to scan.  It also means the
	clock period of the 6502 is not constant but is 
	elongated on every 65th cycle.  (p. 3-2)

	The composite frequency of the Apple is 1.0205 MHz.  
	1.0205 is the result of 14.31818*(65/(65*14+2))....
	This is the value which should be used for computing 
	exact time durations of Apple programs....
	When possible, [program] loops should be written in
	multiples of 65 cycles.  This will eliminate loop
	output jitter.  Otherwise the application must be able
	to tolerate a 140 nanosecond jitter.  140 nanoseconds
	is the difference between a normal cycle and a long
	cycle.  (p. 3-18)
	
Mr. Sather goes into much more detail.  Actually Sather's book
is a must for all serious Apple hackers.  Although it is for
the II and II+, many sections still hold for the IIe.  Also, I think
that Mr. Sather now has a book just for the IIe.

Hope I've helped,			Bruce Holmer
					holmer@ucbdali


-- 
David Neves
Computer Sciences Department
University of Wisconsin-Madison

Usenet:  {allegra,heurikon,ihnp4,seismo,uwm-evax}!uwvax!neves
Arpanet: neves@uwvax