Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Anybody Have Code for a Good Z80 Calibrated Timing Loop?

257 views
Skip to first unread message

Jack Strangio

unread,
Mar 28, 2021, 6:20:51 PM3/28/21
to
I'm looking for a Z80 program that is something along the lines of 'Run
the program loop 10,000 times and it should take exactly 5 seconds for
a Z80 with a 4MHz clock speed'

Anybody got something similar stashed away in their archives?

Thanks.

Regards,

Jack
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." Brian W. Kernighan

dxforth

unread,
Mar 29, 2021, 12:54:55 AM3/29/21
to
On 29/03/2021 09:20, Jack Strangio wrote:
> I'm looking for a Z80 program that is something along the lines of 'Run
> the program loop 10,000 times and it should take exactly 5 seconds for
> a Z80 with a 4MHz clock speed'
>
> Anybody got something similar stashed away in their archives?
>
> Thanks.
>
> Regards,
>
> Jack
>

Not a complete program but a routine.
Entry = delay in mS (DE). Speed = mem location holding CPU speed in MHz

; (MS) ( ms -- )

hdr x,'(MS)'
ms0: pop de
ms01: ld a,e
or d
jp z,next ; exit
ld hl,(speed)
add hl,hl
add hl,hl
add hl,hl
ms02: ex (sp),hl ; 19T
ex (sp),hl ; 19T
ex (sp),hl ; 19T
ex (sp),hl ; 19T
push hl ; 11T
pop hl ; 10T
dec hl ; 6T
ld a,0 ; 7T
ld a,l ; 4T
or h ; 4T
jp nz,ms02 ; 10T
dec de
jp ms01

Roger Hanscom

unread,
Mar 29, 2021, 12:50:39 PM3/29/21
to

> Anybody got something similar stashed away in their archives?

Maybe this will work for you?

Roger

;
; ***************************************
; **** SOFTIM: Z80 SOFTWARE TIMER ****
; **** WRITTEN BY: DAN TERPSTRA ****
; ***** CHEMISTRY DEPARTMENT *****
; ** FLORIDA STATE UNIVERSITY **
; *****************************
;
; The execution time of this routine is given by:
; T = (N+2)*40
; where T is the time in t-states, and N is the 3 byte
; (positive integer) delay quantity obtained from memory
; locations LODELA, HIDELA. To calculate the time in
; seconds, multiply the number of t-states by the time of
; one clock cycle (e.g. 4 MHz = 250 ns/cycle). This
; timing assumes memory that operates with no wait
; states. The minimum time of execution for a 4 MHz Z80
; is 30 usec for N = 1 (including the CALL and RET
; sequence), increasing in steps of 10 usec to a maximum
; of over 160 sec. N = 0 is undefined, and N =
; FFFFFF(HEX) is the maximum time period. There is NO
; software jitter in this timing loop.
;
;
;main:
; ld hl,(lodela) ;low order count word
; ld a,(hidela) ;high order count byte
; call softim ;time it
; ...continue with program...
; ret
;
; SOFTIM SUBROUTINE
;
; entry conditions:
; a, hl = 24 bit positive count
; exit conditions:
; a = b = hl = 0
; modifies:
; a, b, hl
;
softim: inc a ;at least one pass
ld b,a ;through outer loop
ld a,0 ;dummy instructions
jp softm2 ;to kill time
softm1: jr softm2 ;delay 16 T states
softm2: nop
softm3: dec hl ;decrement low order
ld a,l
or h ;hl = 0?
jp nz,softm1 ;no, look again
dec b ;b = zero?
jr nz,softm3 ;no, repeat outer loop
ret ;yes, return
;
; storage locations for 24-bit time delay word
;lodela: ds 2 ;low order 16 bits
;hidela: ds 1 ;high order 8 bits
;

Jack Strangio

unread,
Apr 2, 2021, 4:48:09 AM4/2/21
to
Thanks.

That looks simple but effective. Now to put another loop or two around
that to get a much longer interval to make CPU-speed comparisons easier.

I'm comparing the times taken for a 'real' Z80 to do a task and an emulated
Z80 doing the same task. That way I should get an 'effective clock speed'
for the emulated Z80.


Regards,

Jack

--
"I'm a home-loving girl. And that's where I wish I was."
"At home ..."
"Loving."
- Laugh-In, 1968

Jack Strangio

unread,
Apr 2, 2021, 4:48:10 AM4/2/21
to
Roger Hanscom <norwe...@gmail.com> writes:
>
> > Anybody got something similar stashed away in their archives?
>
> Maybe this will work for you?
>
> Roger
>
> ;
> ; ***************************************
> ; **** SOFTIM: Z80 SOFTWARE TIMER ****
> ; **** WRITTEN BY: DAN TERPSTRA ****
> ; ***** CHEMISTRY DEPARTMENT *****
> ; ** FLORIDA STATE UNIVERSITY **
> ; *****************************

Dan Terpstra. Now *there's* a name from the early days of 'home
computing'. <grin>

And a very comprehensive subroutine too, it appears.

Thanks.

fred_...@hotmail.com

unread,
Apr 2, 2021, 4:20:11 PM4/2/21
to
Ah ha! That's what you want it for! Ok -- I use the following code, and have for years....
It clocks out 10 million cycles on an 8080, and very close on a Z80 (9.4million cycles). At 2Mhz, it should take
5 seconds. Scale as appropriate. The source will execute 10,000,000 cycles either once (which takes
5 seconds on the Altair, just under on a 2.5Mhz Z80 (or unlimited Altair-Duino which is around 2.6Mhz),
or 1000x10,000,000 cycles, which takes ~5 seconds on RUNCPM on a Dell 6410). On that Dell, RUNCPM
is like a 2Ghz 8080 (yes, not a typo). Assemble with ASM.COM. Do not know where the original source
is from.

Z80 CYCLE COUNTS
LD rr,nn 10
DEC r 4
JP cc 10

; 10MCYC.ASM
;
; EXECUTE FOR 10 MILLION CYCLES. AT 2MHZ, THIS SHOULD TAKE 5 SECONDS,
; AND GIVES US A WAY TO "SPEED TEST" EMULATORS.
;
; MY DELL 6410 IS APPROXIMATELY EQUIVALENT TO A 2GHZ 8080 (OR, IN
; TURBO PASCAL DELAY LOOP TERMS - 2000MHZ). ALTAIR-DUINO IS APPROXIMATELY
; 2.5MHZ (UNLIMITED Z80 MODE)
;
; ORG 100H
;
LXI H,0
DAD SP
SHLD OSTACK
LXI SP,STACK
LXI D,MSG1
MVI C,9
CALL 5
LXI H,1
;; LXI H,1000 ; 5 SECONDS: DELL 6410, RUNCPM
TOP3: PUSH H
CALL MCYC
POP H
DCX H
MOV A,H
ORA L
JNZ TOP3
LXI D,MSG2
MVI C,9
CALL 5
LHLD OSTACK
SPHL
RET
; 8080 CYCLE COUNT
MCYC: LXI H,0014H ; 10
TOP: LXI B,8200H ; 10 |
TOP2: DCR C ; 5 | 3,840 | |
JNZ TOP2 ; 10 | | |
DCR B ; 5 | |
JNZ TOP2 ; 10 | 501,150 |
DCR L ; 5 |
JNZ TOP ; 10 | 10,023,300
RET
;
DS 32
STACK:
OSTACK: DW 0
MSG1: DB 'BEGIN',13,10,'$'
MSG2: DB 'END',13,10,'$'
END


I do not know the history of the code -- the cycle calculation is my own. Note that a reference is made to this
code at

https://www.tramm.li/i8080/index.html

but notice that the cycle count is claimed to be 10'023'517 The 217 cycle difference -- would be
109 microseconds at 2Mhz... It is much harder to measure RUNCPM on a Linux system because of
interrupts. The measurement was on Dell 6410, RUNCPM, Linux 64 bit Fedora 29. That machine is
retired.

The number of cycles should be
((((10+5)*256+5+10)*130)+5+10)*20 --10 cycles for JNZ, 5 cycles for DCR
A Z80 takes 4 cycles for the DCR r instruction, not 5, so 9,355,080 for the inner loop, or 4.7 seconds
at 2Mhz, just about 10% faster than the 8080.

dxforth

unread,
Apr 2, 2021, 8:35:20 PM4/2/21
to
On 29/03/2021 15:54, dxforth wrote:
>
> Not a complete program but a routine.
> Entry = delay in mS (DE). Speed = mem location holding CPU speed in MHz
> ...

I should have mentioned the origin was Turbo Pascal and its Delay routine
which I modified to suit my needs. Being part of TP, a complete program
would be trivial to write. Here's one for DX-Forth:

\ DELAY.F
\
\ Make for DX-Forth for CP/M:
\
\ A:FORTH - include delay bye

empty forth definitions decimal application

$5C constant FCB1
$6C constant FCB2
$124 constant SPEED \ address of CPU speed (Turbo Pascal compatible)

: GETNUM ( fcb -- u )
1+ 11 -trailing 0 0 2swap >number 2drop drop ;

: HELP ( -- )
." DELAY 0.1" cr cr
." Usage: DELAY mS [MHz]" cr cr
." default: 4MHz Z80"
abort ;

: MAIN ( -- )
4 speed ! \ assume 4 MHz Z80
fcb2 getnum ?dup if speed ! then
fcb1 getnum dup 0= if help then ( ms)
2000 ms \ wait 2 sec
( ms) beep ms beep ; \ run specified delay

turnkey main delay \ create executable

\ end

The compiler (DXCPM444.ZIP) can be obtained here:

https://drive.google.com/drive/folders/1kh2WcPUc3hQpLcz7TQ-YQiowrozvxfGw
0 new messages