Elapsed time in Sinclair BASIC

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
8BitSC
Microbot
Posts: 130
Joined: Mon Feb 13, 2023 1:23 am

Elapsed time in Sinclair BASIC

Post by 8BitSC »

Say I need to time a routine in Sinclair BASIC. How best would I go about doing this?

E.g. Timing how long it takes to format a Microdrive cartridge, to return the amount of time it takes to CAT a drive or write 48K of data?

Man, I've forgotten so much in (2023-1986) years. (I'm bad at math, too if you hadn't guessed).
User avatar
1024MAK
Bugaboo
Posts: 3134
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Elapsed time in Sinclair BASIC

Post by 1024MAK »

Use PEEK and POKE to access the system variable FRAMES, which increments 50 times a second. Except when interrupts are disabled.

More information in the programming manual.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
User avatar
8BitSC
Microbot
Posts: 130
Joined: Mon Feb 13, 2023 1:23 am

Re: Elapsed time in Sinclair BASIC

Post by 8BitSC »

Do the Microdrive operations I listed disable interrupts?
dfzx
Manic Miner
Posts: 689
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: Elapsed time in Sinclair BASIC

Post by dfzx »

8BitSC wrote: Tue Oct 03, 2023 12:31 am Do the Microdrive operations I listed disable interrupts?
Yes, Z80 interrupts are disabled when the drive motor is started and re-enabled when the motor is stopped.

Given that the 50Hz interrupt is the only clock the Z80 has in the Spectrum, I don't think there's a way to run a timer with interrupts off.
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
User avatar
ParadigmShifter
Manic Miner
Posts: 734
Joined: Sat Sep 09, 2023 4:55 am

Re: Elapsed time in Sinclair BASIC

Post by ParadigmShifter »

I was thinking about this the other day.

What happens if a byte overflows in between PEEK instructions? It would have to disable interrupts to be sure none of the values had carried into the next byte or else you are going to get subtle bugs. There is no DPEEK which fetches a word (you'd need a triple byte peek anyway to get the entire counter which is 3 bytes).

It's ok if you are only timing less than 256 frames I suppose. That's only 5 and a bit seconds though.

Which is why I was looking at some kind of compiled Basic.

Was doing floating point/maths stuff and that's a lot easier than writing ASM routines for. (Super slow though).

I guess I could write an accurate gettime routine which does disable interrupts and then returns it in 3 bytes I suppose.

Was wanting to write a statistics package and reaction time (pressing button time) was one of the statistics I was going to collect (for a Simon/whackamole simple game), so I could model the user reactions and error rate etc. for a simple computer opponent.

Got around to doing a Poisson Distribution Sampler

Image

Spoiler - it's slow and can't handle lambda > 80 or so

and a Normal Distribution Sampler

Image

Image

Output from the normal dist

Image

That's a nice fast algorithm though (Box-Muller Transform) - very nice :)

I didn't get around to writing a statistics accumulator though where you can add a stat from a sample and you can ask for mean and sample standard deviation though (but that's not hard, done it before). Need that to check the above subroutines give results matching the expected mean and variance etc.
Last edited by ParadigmShifter on Tue Oct 03, 2023 10:24 am, edited 1 time in total.
AndyC
Dynamite Dan
Posts: 1421
Joined: Mon Nov 13, 2017 5:12 am

Re: Elapsed time in Sinclair BASIC

Post by AndyC »

The BASIC manual suggests reading the value twice in succession and taking the larger value.
User avatar
ParadigmShifter
Manic Miner
Posts: 734
Joined: Sat Sep 09, 2023 4:55 am

Re: Elapsed time in Sinclair BASIC

Post by ParadigmShifter »

Hmm I guess so. Probs best to to just write an ASM routine that caches the current value with interrupts off though ;)

something like

DI
peek the 3 bytes and stash them
EI
copy what you read into another location in RAM
User avatar
1024MAK
Bugaboo
Posts: 3134
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Elapsed time in Sinclair BASIC

Post by 1024MAK »

If you want to time events while interrupts are disabled, without extra hardware there is no practical method.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
C.Born
Manic Miner
Posts: 249
Joined: Sat Dec 09, 2017 4:09 pm

Re: Elapsed time in Sinclair BASIC

Post by C.Born »

1024MAK wrote: Tue Oct 03, 2023 5:19 pm If you want to time events while interrupts are disabled, without extra hardware there is no practical method.

Mark
Nope indeed. loading a tape will halt the frame counter up to 5 minutes for a 48k. only setting an IM2 will do and that can be very short luckely.
but mind 48k vs 128k with the IM2 jump at FFFF.
but thats way out of basic.
in basic, i set 23672 TWICE since it counts fast

5 POKE 23672,0:poke 23674,0: poke 23673,0:poke 23672,0
7 for f=0 to 10:next f
10 let t=PEEK 23672+256*peek23673+65536*peek23674
print t
now cut it up in 1/50, succes
User avatar
1024MAK
Bugaboo
Posts: 3134
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Elapsed time in Sinclair BASIC

Post by 1024MAK »

If it’s only a very short time that you want to measure, and I mean a very short time, you could use a bit of machine code to read the refresh register. But, this is only a seven bit counter and increments when the Z80 executes an instruction (although it’s operation is slightly more complicated than this).

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
User avatar
ParadigmShifter
Manic Miner
Posts: 734
Joined: Sat Sep 09, 2023 4:55 am

Re: Elapsed time in Sinclair BASIC

Post by ParadigmShifter »

1024MAK wrote: Sun Oct 08, 2023 8:15 am If it’s only a very short time that you want to measure, and I mean a very short time, you could use a bit of machine code to read the refresh register. But, this is only a seven bit counter and increments when the Z80 executes an instruction (although it’s operation is slightly more complicated than this).

Mark
Nah that doesn't work because it measures instructions (kinda, some instructions like LDIR increase R for each iteration etc.) and they have variable timing. Also 7 bits is an issue as well.

EDIT: Also in BASIC you can bet that interpreting the line is going to take more than 128 instructions -> R register overflows so it would be useless for basic anyway.

Best way to do it in machine code is DI, read the frames 3 bytes into another address, EI, then basic can PEEK the value read. It will be out by 1/50th of a second max if an interrupt would have gone off while interrupts were disabled.

Can also do a "StartTimer" and "StopTimer" routine which pokes the difference between the 2 somewhere.

I might do those routines in a bit when I have finished what I am currently doing.

Obviously as people said timing does not work if the ROM disables interrupts for stuff like saving and loading of course.

It's only really useful to get a (fairly accurate) way of measuring time for code execution time (or waiting for something like a keypress timer etc.).
User avatar
1024MAK
Bugaboo
Posts: 3134
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Elapsed time in Sinclair BASIC

Post by 1024MAK »

ParadigmShifter wrote: Sun Oct 08, 2023 9:30 am Nah that doesn't work..
I did say it was “more complicated”… It’s also affected when the Z80 accesses contended RAM or IO. So is far from ideal as a timer.

And no, it’s not very useful when running BASIC.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
C.Born
Manic Miner
Posts: 249
Joined: Sat Dec 09, 2017 4:09 pm

Re: Elapsed time in Sinclair BASIC

Post by C.Born »

the 3rd byte,74 has not much use unless you run a clock or kalender, but DI will hinder a lot
for direct use the 1st byte,72 is to short, except for quick reaction with in 5.12 seconds, a lot off fun.
so byte 73 has a nice timer by it self eg for fading an item. 10x5.1 sec is almost a minute.
if routine checks every 2-3 seconds then thats a good fading.
maybe "secret" RND setting with timing with in two y or n questions?
User avatar
ParadigmShifter
Manic Miner
Posts: 734
Joined: Sat Sep 09, 2023 4:55 am

Re: Elapsed time in Sinclair BASIC

Post by ParadigmShifter »

Well if I write routines they will be of the form

RANDOMIZE USR startTimer
; values now poked into 3 bytes. Maybe 2 will be fine as you say. So you can get FRAMES when this was called if you want. This will DI/EI but only for a jiffy or two.

; then you can do this
RANDOMIZE USR getTimer

; which would read FRAMES again with interrupts disabled and poke the difference between now and when you called startTimer so basic can read that
C.Born
Manic Miner
Posts: 249
Joined: Sat Dec 09, 2017 4:09 pm

Re: Elapsed time in Sinclair BASIC

Post by C.Born »

Code: Select all

10 LET p=23672: POKE p,0: BEEP .003,PEEK p: POKE 23620,3+2*(PEEK p>50): PRINT "HALLO"
23620 holds STATEMENT number, its an internal GOTO which some where is missed as a command eg
10 GO TO 25 ; 3
would be sufficient, but 'they' did not
AND
its NOT working as a single LINE with RUN
you have to do a GO TO 10
Last edited by C.Born on Tue Oct 17, 2023 12:04 pm, edited 1 time in total.
User avatar
ParadigmShifter
Manic Miner
Posts: 734
Joined: Sat Sep 09, 2023 4:55 am

Re: Elapsed time in Sinclair BASIC

Post by ParadigmShifter »

Wrong thread I think ;)

GOTO is already bad enough with line numbers and labels but at least they don't change very often. Jumping to a specific statement in a line is best avoided except in 1 liners (or 10 liners or whatever) since every time you add a statement in the middle of a line you have to change it.

What Sinclair Basic really needed was ELSE though ;) And procedures with parameters and return values of course (DEF FN can only use 1 statement IIRC?).
C.Born
Manic Miner
Posts: 249
Joined: Sat Dec 09, 2017 4:09 pm

Re: Elapsed time in Sinclair BASIC

Post by C.Born »

ParadigmShifter wrote: Tue Oct 17, 2023 11:57 am Wrong thread I think ;)

GOTO is already bad enough with line numbers and labels but at least they don't change very often. Jumping to a specific statement in a line is best avoided except in 1 liners (or 10 liners or whatever) since every time you add a statement in the middle of a line you have to change it.

What Sinclair Basic really needed was ELSE though ;) And procedures with parameters and return values of course (DEF FN can only use 1 statement IIRC?).
nope, correct thread, its about a TIMED BEEP repeat...
and i just discovered it seems to work after GO TO only, strange, but it shows the internal use off the nspcc sysvar 23620
Post Reply