IOC emulation

Discuss development specific to the Pi version of ADFFS
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

IOC emulation

Post by JonAbbott »

I've coded IOC Timer 1 (device 6), Vsync (device 3) and the IRQv emulator. Could someone confirm my understanding of how IOC Timer 1 works:

1. T1 Latch Low / High are written with the timer value
2. Bit 6 of IRQA mask is set to enable the IRQ
3. T1 Go is written to start the timer
4. IRQ is raised

IRQ handler then does the following:
5. Bit 6 of IRQA clear is set to clear the IRQ
6. Does its thing

Jahangir Khan doesn't seem to be writing to T1 go, but is doing everything else. James Pond starts the music and then pauses.
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: IOC emulation

Post by steve3000 »

JonAbbott wrote:Could someone confirm my understanding of how IOC Timer 1 works
You mean me ;) - sure
JonAbbott wrote:1. T1 Latch Low / High are written with the timer value
2. Bit 6 of IRQA mask is set to enable the IRQ
3. T1 Go is written to start the timer
4. IRQ is raised

IRQ handler then does the following:
5. Bit 6 of IRQA clear is set to clear the IRQ
6. Does its thing

Jahangir Khan doesn't seem to be writing to T1 go, but is doing everything else. James Pond starts the music and then pauses.
Ok, correct... but not complete.

T1-4 count down at 2MHz, starting immediately from the moment of power-up. Reload from the latch occurs when the timer crosses 0. On power-up, the latch is 0, and the timer continuously reloads from the latch. So when a game comes along and pokes a value into the latch, this is loaded and countdown starts immediately - no need to write 'Go'.

It is good practice to write 'Go' because this forces the timer to immediately reload from the latch, however if the programme is just looking for an accurate interrupt driven by the timer, rather than an interrupt synchronised with an accurate start point (ie. VSync/etc.), then there is no real need to write 'Go'. This is because even if T1 latch was previously loaded with the highest possible value, &FFFF, this only equates to a fraction of a second, so reload will occur soon enough and then the interrupt will continue at the desired latch value.

Steve
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: IOC emulation

Post by steve3000 »

So on that basis - for IOC emulation, it's probably best to trigger the timer to start as soon as you've received the first T1 latch high and T1 latch low write. If you then receive a subsequent 'Go', reset the timer to the latch value.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

steve3000 wrote:So on that basis - for IOC emulation, it's probably best to trigger the timer to start as soon as you've received the first T1 latch high and T1 latch low write. If you then receive a subsequent 'Go', reset the timer to the latch value.
That explains the missing GO write then. I'll move the code that starts the timer from GO to latch high/low and change GO to simply reset the timer.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

I've changed the code to set the timer value if there's a write to either T1 latch low/high or GO.

That didn't make any difference however, so I then disassembled the Krisalis code. After claiming the device via OS_ClaimDeviceVector, it enables the IRQ in IRQA mask. At no point does it write to T1 latch low/high or GO. In fact, the only code that writes to latch low/high is within the IRQ handler code itself.

This implies:
1. T1 is set to an initial value so that it immediately triggers an interrupt once enabled
2. OS_ClaimDeviceVector calls the code at least once
3. Something is manually triggering the interrupt or calling the code

On checking (1), T1 latch low/high are initially set to 0 by RO. (2) seems unlikely, so how does the interrupt code get called initially?
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: IOC emulation

Post by steve3000 »

Sorry, I meant to make that clearer in my description above.

(1) is correct, all timers initialise to 0 at power on, so as soon as the Irq mask is cleared they will cause an interrupt. At power on, the RO rom is pulled low to address 0, its default Irq handler response is to mask out the timer interrupt, allowing RO to then set the timers up properly.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

I'll make it immediately trigger an interrupt when the mask is set and keep my fingers crossed.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

IOC T1/IRQv emulation is now complete enough for games, the only problem left to resolve is HAL timers, which seem to randomly hang the machine or corrupt the stack.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

It's getting there, James Pond now shows the loader screen although crashes soon after starting the game. Jahangir Khan shows the butterfly flapping it's wings in the loader, although the core code crashes in the background - the butterfly keeps flapping after the crash so T1 is still firing.

It has to be register or PSR corruption, although they're all being stored and restored around the IRQ.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: IOC emulation

Post by JonAbbott »

Its the abort handler causing the crashing under emulation, it seems to work fine for everything except when its entered from an interrupt routine. Even stripping the handler down to simply skip the aborted instruction (SUBS PC, R14, #4) randomly causes a crash under Red Squirrel - that's a bug in Red Squirrel as the abort handler works fine on a physical RiscPC.

So...there's now no RPC emulators I can use to develop this as they all have fatal bugs. Aarrghhh!

This doesn't of course explain the very similar random crash on the Pi, using Jahangir Khan as an example; if I change the interrupt code so it doesn't write to VIDC, it still crashes in the same way - so the issue on the Pi isn't related to VIDC writes and is more likely related to HAL timers.
Post Reply