Oric main loop

If you want to ask questions about how the machine works, peculiar details, the differences between models, here it is !
How to program the oric hardware (VIA, FDC, ...) is also welcome.
Post Reply
User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Oric main loop

Post by Symoon » Thu Apr 07, 2011 11:16 pm

Hi,

OK I'll sound like a newbie again, but anyway ;)
When an Oric has started, i guess it enters a permanent loop with, AFAIK:
- flashing the cursor
- look for pressed keys
- other tings?

I have 2 questions:
1- are there many "other things"? (I guess so of course, but how many ?)
2- how long does ONE "standard" loop last? (in microseconds, or CPU cycles, or whatever!)

Thanks!

User avatar
Dbug
Site Admin
Posts: 3052
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug » Fri Apr 08, 2011 8:37 pm

As far as I know, the keyboard pressing and cursor flashing is not handled in the main loop, it's a part of the main IRQ.

The IRQ pushes the pressed keys in the input buffer.

Now sure the main loop (I guess), is testing if there's something the buffer and do something with it :)

About what the main loop does, I'm not quite sure, never disassembled it.

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Fri Apr 08, 2011 9:30 pm

What I'd be interested in, actually, is the time it takes for the main loop, including interrupts.
The idea is that I want to send a short audio signal to the Oric, the shortest possible. The Oric should detect it with an interrupt checking CB1 state.
So to be 100% sure the audio signal is detected, its length should be this "main loop" time + time of the new interrupt to detect it.

User avatar
Dbug
Site Admin
Posts: 3052
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug » Fri Apr 08, 2011 10:44 pm

Sure, but then I believe you have a program running, it's not just waiting on the Ready prompt from the BASIC, correct?

Technically the concept of main loop is whatever you want it to be.

I could write this and call it a main loop:

Code: Select all

label:
  jmp label
If it's your own program, you don't even need an interrupt to detect the value of a port, and if you want something that does nothing else than detect CB1, you can disable every single other source of interruption, have a main loop that does nothing, and have the CB1 handler to react on the standard IRQ vector, it will take the time it normally take for the VIA+6502 to handle an interrupt request.

There's a good tutorial/explanation on this page:
http://6502.org/tutorials/interrupts.html

Basically you can expect the IRQ handler to be called in less than 10 clock cycles.

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Sat Apr 09, 2011 9:56 am

Dbug wrote:Sure, but then I believe you have a program running, it's not just waiting on the Ready prompt from the BASIC, correct?
Well no, actually I'm pursuing my tape-protocol idea, and as a frist try (to learn more about interrupts and to do some tests), I want the Oric to be able to detect a "warning" signal and then automatically switch to CLOAD. So the Oric should permanently listen to the tape input, even at the basic prompt. I don't want the Oric to be stuck listening to the input.

That's why I need to know at which frequency it will listen to the tape input so I can design then minimal time length of the warning signal (if it's too short it might be missed).
I just found the time I'm looking for is at best the interrupt frequency (which I still don't know exactly how long it lasts, I guess it also depends if a key is pressed and so on), or more if I don't want to slow the Oric down too much. So I'll have to test first what Oric speed would remain acceptable, once I have added this "listen" routine, before having the time length of the signal.

For the moment I don't care about anything else - I know that with this way of doing things, any audio signal will swith the Oric to CLOAD, which may be a little bit boring ;-)

Thanks for the link about interrupts, it looks very interesting!

User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte » Sat Apr 09, 2011 12:58 pm

For what its worth the Oric on bootup at the ready prompt is running a rather heafty IRQ routine that does the following stuff..

1) Read the keyboard (scans each individual key for its state, nothing optimised)

2) Updates three page 2 software timers (Flashing cursor delay, WAIT count, etc.)

One trick i remember years ago to speed up your basic program was to slow down the speed of the IRQ (usually runs at 100hz or 100 times a second).

Code: Select all

DOKE #0306,20000
Will half the speed of the IRQ routine but effectively increase (not double tho) the speed of the BASIC program running). It will also double the duration of a WAIT statement.

Bugger, pressed the wrong key and lost my response to an answer to your problem. I was getting on so well. oh well start again we shall..

Ok, it just so happens that CB1 can be trapped using another interrupt.
Turn to page 43 to see that the IFR and IER hold flags for CB1. Also note that the 6522 can trigger the irq flag on the negative or positive active edge and this is set in the PCR on page 38.

The setup routine for this new interrupt routine will need to be done in machine code so that we can disable interrupts whilst setting it all up.
First we need to add CB1 as an interrupt source...

Code: Select all

          SEI
          LDA #0
          STA $030E
          LDA #%11010000
          STA $030E
Then set the type of active edge in the PCR (page 38)...

Code: Select all

          LDA $030C
          AND #%11101111
          ORA #%00010000
          STA $030C
Remove the ORA if you want to detect negative active edge.

We intercept the IRQ at EE22 by redirecting its vector in page 2...

Code: Select all

          LDA #<$BFE0
          STA $0245
          LDA #>$BFE0
          STA $0246
Then we write our interrupt routine in $BFE0 (not used by BASIC or HIRES).

Note we use BIT for two reasons. First it doesn't corrupt the main registers and second its fast in detecting the interrupts we need to detect :twisted:

If the CB1 interrupt did not occur it will jump to the standard BASIC EE22 IRQ routine :)

Code: Select all

*=$BFE0
          BIT $030D
          BVC ProcessCB1Event
          JMP $EE22
ProcessCB1Event
          'Reset CB1 Interrupt
          BIT $0300
          'Detect Signal using timer2 as counter between pulses
I'm not sure what you want to achieve at this point onwards. It is possible to use Timer2 (not used under BASIC AFAIK) to count the period (duty cycle) between pulses on CB1 and therefore calculate the frequency of the warning signal.

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Sat Apr 09, 2011 2:49 pm

Thanks a lot, this is so far on the edge of my knoledge but I'm reading and learning ;-)
I especially have problems with ASM syntax which I don't know well (my way of programming in ASM is by simply poking the op codes and values I want), but as the programs are not that complicated, that's OK.

In the meantime, I have measured the time it takes to flash the cursor, giving me the result of the (standard) IRQ frequency: ever 0.01 second.
This is confirmed by a recent article in the CEO Mag (real time clock, issue 251).

I also had made a few tests for the signal detection, based on what's existing in ROM. You explanations will help too!
Now I have to experiment ;-)

My first exercise: auto-CLOAD. Simply press PLAY on your tape reader, the Oric should automatically switch to CLOAD (fast) mode, whatever it's doing.

User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte » Sat Apr 09, 2011 2:59 pm

Symoon wrote:Thanks a lot, this is so far on the edge of my knoledge but I'm reading and learning ;-)
Sounds like your knowledge is where i was when i met Alistair Way way back in 1991.
Back then i knew the only way forward, to take full advantage of the computer in CPU, graphics and sound was to master machine code.
But trying to understand it from the Oric Atmos manual section on asm was impossible it seemed. You begin with getting used to using a couple of instructions like LDA and STA, then expand into indexing with DEX, BNE which is a concept that i was only just starting to understand. Eventually you'll 'cotten on' to BPL and eventually indirect addressing like LDA(),Y

It all takes time, and the confidence is very low at the start but when faced with the desire to take full advantage of the Oric's capabilities, the determination overcomes most of the incomprehensible stuff you see today :p

Incidentally, i visited Dave Dick last weekend in Aylesbury, uk. We remonist about old times and i tried to set up Euphoric/Oriculator on his pc.
Symoon wrote:I especially have problems with ASM syntax which I don't know well (my way of programming in ASM is by simply poking the op codes and values I want), but as the programs are not that complicated, that's OK.
Thats how i programmed machine code myself from 1991 to 1997 i think. So its understandable. ASM using a cross compiler is easy once you understand what each op code does and you want to create something bigger.

The problem with giving a reply is that to give a full and complete explanation would take a couple of pages here. To do that is possible but i think would alienate people with too much information and no opportunity of discovery :(

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Sat Apr 09, 2011 4:39 pm

BTW, for our readers, when Twilighte says "page 38", he refers to the Oric Advanced User Guide (by Leycester Whewell).
Twilighte wrote:The setup routine for this new interrupt routine will need to be done in machine code so that we can disable interrupts whilst setting it all up.
First we need to add CB1 as an interrupt source...

Code: Select all

          SEI
          LDA #0
          STA $030E
          LDA #%11010000
          STA $030E
I suspect the 1st STA is actually in 030D, you are resetting the possible existing flags, right?

Cheers.

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Sun Apr 10, 2011 6:08 pm

Tried this, but the Oric hangs (definitely) and nothing happens even with input signal:

Code: Select all

78		SEI
A9 00		LDA #00
8D 0D 03	STA #030D
A9 D0		LDA #D0 (11010000)
8D 0E 03	STA #030E
AD 0C 03	LDA #030C
29 EF		AND #EF (11101111)
09 10		ORA #10 (00010000) - set detect positive edge
8D 0C 03	STA #030C
2C 0D 03	BIT #030D
70 03		BVS +3 - if CB1 did not occur, jump to standard interrupt
EE A7 BB	INC #BBA7 - if CB1 occured, change the last CAPS letter
6C 22 EE	JMP #EE22
Could it be the SEI in the beginning, should I remove it? Or am I doing something wrong ?

User avatar
ibisum
Wing Commander
Posts: 1132
Joined: Fri Apr 03, 2009 8:56 am

Post by ibisum » Mon Apr 11, 2011 10:23 am

[I'm lurking and learning a lot from you guys, just wanted to let you know I'm reading this thread and imhso, no brevity required - dump it on us!]

User avatar
Symoon
Archivist
Posts: 1756
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Post by Symoon » Tue Apr 12, 2011 8:41 pm

Symoon wrote:Could it be the SEI in the beginning, should I remove it? Or am I doing something wrong ?
Tried without the SEI, same symptoms.
Not much time to do more these days, will resume ASAP!

Post Reply