How to detect the Oric's CPU speed from within the BASIC prg

Comments, problems, suggestions about Oric emulators (Euphoric, Mess, Amoric, etc...) it's the right place to ask. And don't hesitate to give your tips and tricks that help using these emulations in the best possible way on your favorite operating system.
Brana
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

How to detect the Oric's CPU speed from within the BASIC prg

Post by Brana »

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
Brana
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

Summary:

Post by Brana »

... 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?
User avatar
Chema
Game master
Posts: 3020
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Summary:

Post by Chema »

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?
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".

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.
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Re: Summary:

Post by JamesD »

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).
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.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

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 :P
6 REM
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD »

It's not a matter of *if* BASIC can detect it... for timing it's a matter of can it detect it every time. I think you will find that the SYNC will be active too short of time for BASIC to be reliable if it can even detect it at all.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

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. 8)

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. :)
JamesD
Flight Lieutenant
Posts: 358
Joined: Tue Nov 07, 2006 7:38 am

Post by JamesD »

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... :)
User avatar
Dbug
Site Admin
Posts: 4461
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

You can already set the Oric so it runs at 60hz, so technically the NTSC Oric is already there (timing wise) :)
Brana
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

Re:

Post by Brana »

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 :P
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.
Brana
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

Re: Summary:

Post by Brana »

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" ?
User avatar
Chema
Game master
Posts: 3020
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re:

Post by Chema »

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
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.

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
User avatar
Chema
Game master
Posts: 3020
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Summary:

Post by Chema »

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" ?
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
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

Re:

Post by Brana »

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.
Re:

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
Brana
Flying Officer
Posts: 169
Joined: Fri Nov 30, 2007 8:30 pm
Contact:

Re: Summary:

Post by Brana »

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.
Re.. Ouch! :(
Post Reply