How to detect the Oric's CPU speed from within the BASIC prg
How to detect the Oric's CPU speed from within the BASIC prg
Hello, I am wondering is it possible to check the speed of the Oric's CPU from WITHIN the Basic program?
I am thinking of the following:
Try to execute this short Basic program:
PRINT@2,2;CHR$(140);"A":PRINT:PRINT:PRINT SCRN(3,2)
This will give you a "flashing" letter "A" at @3,2 (Text screen)
And you will get the ASCII value of the screen-cell of "65",
And below it, You will have Oric's cursor (flashing) at it's own speed.
Now, press F4 on the keyboard (do double the clock of the Euphoric Emulator)
You will notice the increase of the speed of flashing of the cursor (below),
but the flashing of the letter "A" will remain at the same speed regardless of the CPU speed of the Emulator!
Based on this - I am wondering - is it possible to "trap" and to detect the Oric CPU speed (of the Euphoric Emulator) from WITHIN the BASIC program ("running" Oric Atmos)
I am thinking of the following:
- To detect each "re-appearance" of the flashing of the letter "A", and
- To compare it to the something like "FOR A=0 TO 1000:NEXT A"
This way I could detect the Emulator's CPU speed of the Oric (Atmos), but - only one problem:
Regardless of the flashing "A" state (ON or OFF) whenever I do the PRINT SCRN(3,2) I get "65" in return.
So, this means that I will get the "65" in return even if the "A" is currently "OFF".
So - How could I detect each re-appearance of the flashing "A" at @3,2 (text screen)?
Does anyone have an idea for it?
Brana
I am thinking of the following:
Try to execute this short Basic program:
PRINT@2,2;CHR$(140);"A":PRINT:PRINT:PRINT SCRN(3,2)
This will give you a "flashing" letter "A" at @3,2 (Text screen)
And you will get the ASCII value of the screen-cell of "65",
And below it, You will have Oric's cursor (flashing) at it's own speed.
Now, press F4 on the keyboard (do double the clock of the Euphoric Emulator)
You will notice the increase of the speed of flashing of the cursor (below),
but the flashing of the letter "A" will remain at the same speed regardless of the CPU speed of the Emulator!
Based on this - I am wondering - is it possible to "trap" and to detect the Oric CPU speed (of the Euphoric Emulator) from WITHIN the BASIC program ("running" Oric Atmos)
I am thinking of the following:
- To detect each "re-appearance" of the flashing of the letter "A", and
- To compare it to the something like "FOR A=0 TO 1000:NEXT A"
This way I could detect the Emulator's CPU speed of the Oric (Atmos), but - only one problem:
Regardless of the flashing "A" state (ON or OFF) whenever I do the PRINT SCRN(3,2) I get "65" in return.
So, this means that I will get the "65" in return even if the "A" is currently "OFF".
So - How could I detect each re-appearance of the flashing "A" at @3,2 (text screen)?
Does anyone have an idea for it?
Brana
Summary:
... Or (in short)
When I do
PRINT CHR$(140);"A"
then how to detect each re-appearance of the flashing "A" from within the Basic program on Oric Atmos?
When I do
PRINT CHR$(140);"A"
then how to detect each re-appearance of the flashing "A" from within the Basic program on Oric Atmos?
Re: Summary:
Well not sure, but I think that the flashing letter is done by the ULA, so it should be based on the screen refresh (either 50 or 60 Hz), while the cursor blinking is done by ROM and, so, depends on the CPU "speed".Brana wrote:... Or (in short)
When I do
PRINT CHR$(140);"A"
then how to detect each re-appearance of the flashing "A" from within the Basic program on Oric Atmos?
Anyway all the Orics run at the same CPU speed of 1Mhz, so detecting the CPU speed is rather useless... unless under the emulator, but if the emulator is good enough, then you won't be able to see any difference from within as *everything* will run faster.
But maybe you can use the VIA timer T1C and make some tests. If I recall correctly the addresses are T1C_L $304 (low byte) and T1C_H $305 (high byte), so you can DEEK it and check, but they decrement really quickly (at 1Mhz?).
Another possibility would be using the SYNC cable to catch the vertical retrace signal (emulated in Euphoric) which should work at 50Hz, but I guess you need an interrupt routine to be accurate (not just polling the status).
Surely the hardware masters out there can help better than me, anyway.
Cheers.
Re: Summary:
My first thought was the SYNC timing since that is fixed. You would definitely need to use a small machine code routine for the timing.Chema wrote:Another possibility would be using the SYNC cable to catch the vertical retrace signal (emulated in Euphoric) which should work at 50Hz, but I guess you need an interrupt routine to be accurate (not just polling the status).
Detecting Sync might be possible in basic.
Disable all irq and enable just CB1 (Tape In)
0 POKE #30E,127: POKE #30E,144
We'll store results to memory #B400-#B4FF since printing would be too slow.
1 L = #B400
#30D will indicate when the tape in has triggered and to reset it (which we must) we poke somethiong into Port B (#300).
2 IF PEEK(#30D) THEN POKE #300,0:GOTO4
Write the two alt values to memory.
3 POKE L,0 : L=L+1:IF L<#B500 THEN 2 ELSE 6
4 POKE L,1 : L=L+1:IF L<#B500 THEN 2 ELSE 6
Someone will need to test this code and report the results (whats in memory between #b400 and #b4ff) before we can continue. My current system is running dog slow and keeps crashing in basic
6 REM
Disable all irq and enable just CB1 (Tape In)
0 POKE #30E,127: POKE #30E,144
We'll store results to memory #B400-#B4FF since printing would be too slow.
1 L = #B400
#30D will indicate when the tape in has triggered and to reset it (which we must) we poke somethiong into Port B (#300).
2 IF PEEK(#30D) THEN POKE #300,0:GOTO4
Write the two alt values to memory.
3 POKE L,0 : L=L+1:IF L<#B500 THEN 2 ELSE 6
4 POKE L,1 : L=L+1:IF L<#B500 THEN 2 ELSE 6
Someone will need to test this code and report the results (whats in memory between #b400 and #b4ff) before we can continue. My current system is running dog slow and keeps crashing in basic
6 REM
I've just thought of another way this might be possible to detect sync under BASIC.
If we disable T1 IRQ and enable CB1 then let Interrupts continue, then the standard ROM interrupt routine will continue as normal.
oops. errr.. oh bugger, i don't know if it will, but carrying on with my rather sketchy and umbalanced theory.
The ROM Interrupt routine does many things but importantly it flashes the cursor which apparently can be read in location #271.
The speed is every 25 interrupts which equates to 2 Hz?
This should be much easier to capture in BASIC.
If we disable T1 IRQ and enable CB1 then let Interrupts continue, then the standard ROM interrupt routine will continue as normal.
oops. errr.. oh bugger, i don't know if it will, but carrying on with my rather sketchy and umbalanced theory.
The ROM Interrupt routine does many things but importantly it flashes the cursor which apparently can be read in location #271.
The speed is every 25 interrupts which equates to 2 Hz?
This should be much easier to capture in BASIC.
As long as interrupts don't occur at a different frequency BASIC will have a better chance of timing that fairly accurately.
So... if someone creates an NTSC clone of the ORIC, the code would need to be aware of that and it would need some way of testing for that. (As I sit here holding my breath...
So... if someone creates an NTSC clone of the ORIC, the code would need to be aware of that and it would need some way of testing for that. (As I sit here holding my breath...
Re:
Twilighte wrote:Detecting Sync might be possible in basic.
Someone will need to test this code and report the results (whats in memory between #b400 and #b4ff) before we can continue. My current system is running dog slow and keeps crashing in basic
6 REM
Re:
Between #b400 and #b4ff all values are "1"
that is to say: 1, 1, 1, 1, 1, 1, 1, 1, ... and so on (265 times)
I am wondering about your second line of the program (above)
2 IF PEEK(#30D) THEN POKE #300,0 : GOTO 4
I do not quite understand it, but it could be "translated" as in to something like this:
2 IF 5 THEN POKE #300,0 : GOTO 4
Or:
2 IF 5 THEN PING
(You will ALWAYS have "PING")
What I want to say is:
In the line 2 the "IF" does not compare anything, and ALWAYS goes to the line 4 (GOTO 4) therefore in the memory between #b400 and #b4ff all values will be "1".
Can You check the line number "2" ?
Brana
Last edited by Brana on Mon Jul 14, 2008 5:03 pm, edited 1 time in total.
Re: Summary:
Brana wrote:... Or (in short)
When I do
PRINT CHR$(140);"A"
then how to detect each re-appearance of the flashing "A" from within the Basic program on Oric Atmos?
When I do the:
PRINT CHR$(140);"A"
Then is there ANY memory address between 0 and 65535 that will change it's value at the exact speed of the speed of the flashing "A" ?
Re:
Just quickly read over the messages, so sorry if I misunderstood your question. If there is nothing in the input/output address #30D, then the PEEK will return 0, considered as FALSE for the IF statement. Any other value will be considered as TRUE.Brana wrote:
I am wondering about your second line of the program (above)
2 IF PEEK(#30D) THEN POKE #300,0 : GOTO 4
I do not quite understand it, but it could be "translated" as in to something like this:
2 IF 5 THEN POKE #300,0 : GOTO 4
Or:
2 IF 5 THEN PING
(You will ALWAYS have "PING")
What I want to say is:
In the line 2 the "IF" does not compare anything, and ALWAYS goes to the line 4 (GOTO 4) therefore in the memory between #b400 and #b4ff all values will be "1".
Can You check the line number "2" ?
Brana
What Twi means here is that you can peek the input/output address #39D and if it is different than zero it means that the sync signal has triggered, which is what you want to catch. The BASIC sentence PEEK(#30D) will return this value. Also we need to clear it by hand, therefor the line
2 IF PEEK(#30D) THEN POKE #300,0:GOTO4
Which means "if there is something in the input/output corresponding to 'tape-in' (our sync) then clear it AND go to line 4. Else it goes to line 3, poking a 0.
So, lines 3 and 4 do the work of filling the table with 1's or '0s depending on the value of that signal.
However I have tested it and could not get it to work properly. Line 0 (when Sync to tape in is selected in Euphoric's menu) seems to hang basic and I have to perform a warm reset to recover control. If we supress that line we fill the memory block with 0's and 1's as expected, but we get one or two 1's then one or two 0's and so on.
Put the CPU speed to 4 MHz and you get a much larger series of 0s (but not constant) then only one 1 and so on.
(Surprisingly if we do NOT activate the option in Euphoric, the program runs and we get all the memory block filled with 1's)
Cheers
Re: Summary:
Don't think so. It is the ULA who does the work of making it flash based on the attribute in the video memory, but that memory remains unchanged.Brana wrote:Then is there ANY memory address between 0 and 65535 that will change it's value at the exact speed of the speed of the flashing "A" ?
Re:
Re:Chema wrote:
However I have tested it and could not get it to work properly. Line 0 (when Sync to tape in is selected in Euphoric's menu) seems to hang basic and I have to perform a warm reset to recover control. If we supress that line we fill the memory block with 0's and 1's as expected, but we get one or two 1's then one or two 0's and so on.
Do not perform a warm reset, instead end the program with:
6 POKE #30E,192
The value of 192 is at the address of #30E before the execution of the program.
If the value at the address of #30E is NOT returned back to 192 the cursor (keyboard) will be stuck and then You must use the "warm reset"
If I add the line 6 (above) then the program ends normaly (OK)
But STILL I get all 1, 1, 1, 1, 1, in the memory after it!
Try this, to see what I mean:
0 POKE #30E,127:POKE #30E,144
1 L=#B400
2 IF PEEK(#30D) THEN POKE #300,0:GOTO4
3 POKE L,0:L=L+1:IFL<#B500 THEN2 ELSE6
4 POKE L,1:L=L+1:IFL<#B500 THEN2 ELSE6
6 REM
10 FORA=46080 TO 46335
11 PRINTPEEK(A);
12 NEXTA
13 POKE #30E,192
Brana
Re: Summary:
Re.. Ouch!Chema wrote:
It is the ULA who does the work of making it flash based on the attribute in the video memory, but that memory remains unchanged.