Elapsed time in Sinclair BASIC
Elapsed time in Sinclair BASIC
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).
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).
- 1024MAK
- Bugaboo
- Posts: 3141
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Elapsed time in Sinclair BASIC
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
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
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Elapsed time in Sinclair BASIC
Do the Microdrive operations I listed disable interrupts?
Re: Elapsed time in Sinclair BASIC
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.
- ParadigmShifter
- Manic Miner
- Posts: 775
- Joined: Sat Sep 09, 2023 4:55 am
Re: Elapsed time in Sinclair BASIC
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
Spoiler - it's slow and can't handle lambda > 80 or so
and a Normal Distribution Sampler
Output from the normal dist
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.
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
Spoiler - it's slow and can't handle lambda > 80 or so
and a Normal Distribution Sampler
Output from the normal dist
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.
Re: Elapsed time in Sinclair BASIC
The BASIC manual suggests reading the value twice in succession and taking the larger value.
- ParadigmShifter
- Manic Miner
- Posts: 775
- Joined: Sat Sep 09, 2023 4:55 am
Re: Elapsed time in Sinclair BASIC
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
something like
DI
peek the 3 bytes and stash them
EI
copy what you read into another location in RAM
- 1024MAK
- Bugaboo
- Posts: 3141
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Elapsed time in Sinclair BASIC
If you want to time events while interrupts are disabled, without extra hardware there is no practical method.
Mark
Mark
Standby alert
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Elapsed time in Sinclair BASIC
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
- 1024MAK
- Bugaboo
- Posts: 3141
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Elapsed time in Sinclair BASIC
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
Mark
Standby alert
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
- ParadigmShifter
- Manic Miner
- Posts: 775
- Joined: Sat Sep 09, 2023 4:55 am
Re: Elapsed time in Sinclair BASIC
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.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
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.).
- 1024MAK
- Bugaboo
- Posts: 3141
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Elapsed time in Sinclair BASIC
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
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
Re: Elapsed time in Sinclair BASIC
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?
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?
- ParadigmShifter
- Manic Miner
- Posts: 775
- Joined: Sat Sep 09, 2023 4:55 am
Re: Elapsed time in Sinclair BASIC
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
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
Re: Elapsed time in Sinclair BASIC
Code: Select all
10 LET p=23672: POKE p,0: BEEP .003,PEEK p: POKE 23620,3+2*(PEEK p>50): PRINT "HALLO"
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.
- ParadigmShifter
- Manic Miner
- Posts: 775
- Joined: Sat Sep 09, 2023 4:55 am
Re: Elapsed time in Sinclair BASIC
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?).
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?).
Re: Elapsed time in Sinclair BASIC
nope, correct thread, its about a TIMED BEEP repeat...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?).
and i just discovered it seems to work after GO TO only, strange, but it shows the internal use off the nspcc sysvar 23620