WAI instruction

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Kaisha
Posts: 14
Joined: Mon Apr 26, 2021 9:06 am

WAI instruction

Post by Kaisha » Tue Apr 27, 2021 2:13 pm

I'm rather confused as to the handling of the WAI instruction.

As I understand the WAI instruction halts the CPU until an interrupt has occurred (it's never specified but I imagine any interrupt) and then I assume after the interrupt is finished execution continues with the next instruction after the WAI.

The docs also mention that if the I flag is set (interrupts disabled) that it functions a bit differently. While it still halts the CPU waiting on an interrupt, when one does occur it simply resumes on the next instruction, no jump/RTI ect...

Now does that apply to all interrupts, or only the IRQ (ie. maskable) one? For example what happens if the CPU hits WAI and then a NMI is called? Do we jump to it's handler like normal or just continue on with the instruction following the WAI? What about ABORT or RESET? Is the I flag implicitly cleared?

Any ideas or thoughts?

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: WAI instruction

Post by Pokun » Tue Apr 27, 2021 3:32 pm

It's both NMI and IRQ, otherwise it wouldn't be very useful. It also includes ABORT but probably not BRK because it says external hardware interrupts only. I assume it only ignores IRQs when the I-flag is set, NMIs always happens. It says that the IRQ can still wake the CPU up if the I-flag is set and an IRQ is pending before the WAI instruction is executed (the IRQ isn't serviced though).

Kaisha
Posts: 14
Joined: Mon Apr 26, 2021 9:06 am

Re: WAI instruction

Post by Kaisha » Tue Apr 27, 2021 4:08 pm

So if WAI has I set (interrupts disabled) and it's woken up with an NMI... is the NMI interrupt executed, or do we just wake and go? Since the I flag is really only supposed to apply to IRQ.

User avatar
dougeff
Posts: 2883
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: WAI instruction

Post by dougeff » Tue Apr 27, 2021 7:48 pm

NMI can not be prevented with SEI (i flag).

If an NMI does occur, it will jump to the NMI handler, and the NMI code will be executed. When an RTI is reached, it will return to the WAI instruction, and move to the next line beyond it.
nesdoug.com -- blog/tutorial on programming for the NES

creaothceann
Posts: 316
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: WAI instruction

Post by creaothceann » Tue Apr 27, 2021 10:16 pm

Perhaps you could think of it like this: P.i doesn't actually prevent the CPU from detecting IRQs, it just prevents the IRQ interrupt sequence (save PC, load vector etc).
Last edited by creaothceann on Wed Apr 28, 2021 6:22 am, edited 1 time in total.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10

Oziphantom
Posts: 1163
Joined: Tue Feb 07, 2017 2:03 am

Re: WAI instruction

Post by Oziphantom » Wed Apr 28, 2021 4:31 am

sei
wai

This will halt until any interrupt source.
If its a RESET it will reset the chip as normal.
Any other, IRQ, NMI, ABORT it will not run the interrupt handler and it will continue to the next instruction.

Since you are in a WAI state you can't trigger a COP or BRK hence "hardware only"


cli
wai

will run the handler then continue to the next instruction

User avatar
dougeff
Posts: 2883
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: WAI instruction

Post by dougeff » Wed Apr 28, 2021 5:20 am

Kind of the opposite of what I said about NMI. I believe the only way to prevent an NMI is to reset bit 7 of the $4200 register (NMITIMEN).

If bit 7 is set, it will jump to the NMI handler and execute that code.

CLI and SEI do no affect NMIs.
nesdoug.com -- blog/tutorial on programming for the NES

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: WAI instruction

Post by Pokun » Wed Apr 28, 2021 6:59 am

Yeah the I-flag should only affect IRQ right? But from what Oziphantom is saying it sounds like NMI and ABORT are also affected by the I-flag during a WAI?

I'm using WAI in my SNES homebrews when waiting for the next NMI, and NMIs seems to happen as expected (I might have used CLI though).

Oziphantom
Posts: 1163
Joined: Tue Feb 07, 2017 2:03 am

Re: WAI instruction

Post by Oziphantom » Wed Apr 28, 2021 10:42 am

The Programming the 65816, 6502, 65C02 and 65802 book says "interrupt" which to me means IRQ/NMI/Abort rather than just IRQ. Also this page http://sbc.bcstechnology.net/65c816interrupts.html specifies "any".

However looking at the Datasheet, its goes into more detail.
7.13 Wait for Interrupt (WAI) Instruction
The WAI instruction pulls RDY low and places the processor in the WAI "low power" mode. NMIB, IRQB or RESB will terminate the WAI condition and transfer control to the interrupt handler routine. Note that an ABORTB input will abort the WAI instruction, but will not restart the processor. When the Status Register I flag is set (IRQB disabled) the IRQB interrupt will cause the next instruction (following the WAI instruction) to be executed without going to the IRQB interrupt handler. This method results in the highest speed response to an IRQB input. When an interrupt is received after an ABORTB which occurs during the WAI instruction, the processor will return to the WAI instruction. Other than RESB (highest priority), ABORTB is the next highest priority, followed by NMIB or IRQB interrupts.
It only mentions IRQB.
It also points out that an ABORTB will still fire and will return to the WAI ( presumably from the handler?? ) but if you don't have I set, then it aborts the WAI but doesn't wake up the processor, so "dead lock"?
With no mention of what happens with a NMI with I set.

So it could be IRQB only, and an NMI is handled as per normal. However does it exit the WAI upon completion of the handler or does it stay in the WAI state as ABORTB does?

Sadly the VICE emulator test benches don't test this logic. As best I can tell none of the SNES test roms do either. Anomie's docs talk about IRQ and various pipelines issues that are caused buy a few instructions in reqards to IRQs and WAI but don't mention anything about what happens on an NMI in said state.

Looking at BSNES source code I can't find any special handling of WAI except both IRQ and NMI set the custom flag to 0.

From this I conclude I was wrong, it is only IRQB, however I'm unsure if there is any special treatment of NMI with regards to if it returns and holds the WAI or not.

Kaisha
Posts: 14
Joined: Mon Apr 26, 2021 9:06 am

Re: WAI instruction

Post by Kaisha » Wed Apr 28, 2021 11:52 am

I appreciate the thoughts guys. It's too bad edge cases like this aren't properly documented in the official documentation.
So it could be IRQB only, and an NMI is handled as per normal. However does it exit the WAI upon completion of the handler or does it stay in the WAI state as ABORTB does?
From reading other docs it seems to suggest WAI with interrupts disabled is designed to make interrupt handling faster (ie. you don't have to wait for a full instruction to finish before the interrupts triggers). Since ABORT doesn't even finish the full instruction, it seems silly to even use WAI with I disabled. Also there would be no way to determine which interrupt woke the WAI instruction.

The only logical interpretation I can come to is that WAI with interrupts disabled handles interrupts normally (ie. jumps to the interrupt vector table) unless it's an IRQ, and only IRQ triggers the 'short circuit'. This is the only way a programmer could actually make use of this feature.

No whether execution continues after a NMI/ABORT or waits in WAI for an IRQ... that I have no clue (so I guess I have come to the same conclusion as Oziphantom).

Given the different interpretations in this thread... I'm guessing the WAI instruction doesn't come up often in roms?

lidnariq
Posts: 10666
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: WAI instruction

Post by lidnariq » Wed Apr 28, 2021 12:07 pm

Sometimes (although maybe not on the SNES), all you actually want is the "wake up from the low-power state" part, and not the interrupt handler.

Revenant
Posts: 455
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: WAI instruction

Post by Revenant » Wed Apr 28, 2021 2:13 pm

To try and put it simply:
  • An NMI or RESET always ends a WAI instruction, and always calls the interrupt handler
  • An IRQ always ends a WAI instruction, but only calls the interrupt handler if I=0
  • An ABORT always calls the interrupt handler, but does not end a WAI instruction
The ABORT behavior is different because unlike other interrupts, returning from the ABORT handler returns to the current instruction that was being executed when the interrupt occurred. This isn't really relevant to SNES development in particular, though, since it's an external input to the CPU which the SNES does not actually connect to anything.

Oziphantom
Posts: 1163
Joined: Tue Feb 07, 2017 2:03 am

Re: WAI instruction

Post by Oziphantom » Thu Apr 29, 2021 1:37 am

Revenant wrote:
Wed Apr 28, 2021 2:13 pm
  • An ABORT always calls the interrupt handler, but does not end a WAI instruction
But that is the thing, the datasheet states the ABORTB does end a WAI instruction, when I is set. So the I does modify behavior other than IRQB.

creaothceann
Posts: 316
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: WAI instruction

Post by creaothceann » Thu Apr 29, 2021 2:01 am

Oziphantom wrote:
Thu Apr 29, 2021 1:37 am
Revenant wrote:
Wed Apr 28, 2021 2:13 pm
  • An ABORT always calls the interrupt handler, but does not end a WAI instruction
But that is the thing, the datasheet states the ABORTB does end a WAI instruction, when I is set. So the I does modify behavior other than IRQB.
"Upon executing an RTI instruction, the above sequence will be logically reversed to return the 65C816 to the state it was in at the time of the interrupt, and unless the address that was pushed to the stack in steps 2 and 3 is altered within the interrupt service routine, the 65C816 will return to and again execute the aborted instruction in the interrupted program."
- Investigating 65c816 Interrupts

So the WAI instruction ends, the ABORT handler runs, and the CPU is paused again.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10

Oziphantom
Posts: 1163
Joined: Tue Feb 07, 2017 2:03 am

Re: WAI instruction

Post by Oziphantom » Thu Apr 29, 2021 3:45 am

However from the same website
Consider the following code:

sei ;IRQs off
wai ;wait for interrupt
lda via001 ;start of interrupt handler

The above sequence disables IRQs with SEI and then stalls the microprocessor with WAI. WAI actually stops the 65C816's internal clock in the Ø2 high state, putting the microprocessor into a sort of catatonia, reducing its power consumption to micro-amperes and halting all processing (hardware note: executing WAI also causes the 65C816's bi-directional RDY pin to go low—knowing that is a clue to what is going on inside while the 65C816 is WAIting). The system will appear to have gone completely dead.

However, as soon as any hardware interrupt other than a reset occurs the microprocessor will restart and exactly one Ø2 cycle after the interrupt was received, the LDA VIA001 instruction will be executed. In other words, interrupt latency in this scenario will always equal exactly one Ø2 cycle—70 nanoseconds at the 65C816's maximum officially-rated Ø2 frequency of 14 MHz. Unlike the usual behavior when a hardware interrupt input is asserted, there is no delay while the current instruction finishes execution (there is no "current instruction" while WAIting) and the 65C816 performs no stack operations upon awakening.
emphasis mine. This is where I go my any idea from. Thus for this matter I treat that sites info as suss and hence are looking for actual hardware test confirmation to clear up the matter. I've reached at to CSDB and a known SuperCPU owner to see if they have any insights.

Post Reply