Date : Wed, 27 Oct 2004 11:31:54 +0100
From : Richard_Talbot-Watkins@...
Subject: Re: &D00
Richard Gellman wrote on 27/10/2004 10:57:34:
> Eep! Don't want to RTI. On BBC Micros, there is almost never a need for
> a user program to use RTI. The 6502 guns all NMIs through the NMI vector
> address at the top end of the MOS ROM. This vector points to a location
> in the MOS which in turn indirects through soft NMI vectors.
No, RTI is correct, *particularly* for NMI handling!
Upon an NMI, the 6502 looks at the address stored in the NMI vector at
&FFFA/&FFFB. In all Beeb OS versions to my knowledge, this contains &0D00.
The stack is set up for returning via an RTI, i.e. the return address
(minus 1) is pushed, followed by the processor status (P flag). There is
no further veneer in the OS for hooking into NMIs - NMI clients simply copy
their NMI handler into the memory starting at &D00 and do it all
themselves.
> The same applies for software interrupts (yes, the 6502 has them.. its
> the BRK instructions) and IRQs. In fact, the 6502 sends IRQ and BRK
> through the same ROM vector, then MOS distriguishes which it is, and
> calls the appropriate software vector (BRKV. IRQ1V, or IRQ2V).
BRKV and IRQ2V handlers should exit via RTS as they are invoked via the
"JSR-JMP" method as you say. The RTS then takes them back to the OS IRQ
handler which will exit via RTI as it should.
But it's correct to write an IRQ1V handler which exits via an RTI - in
fact, all of my (unfinished!) games' interrupt handlers did this, and
passed no control back to the original OS interrupt handler. This way you
do only the interrupt handling you want, you reduce interrupt latency, and
increase performance overall - this was necessary in order to handle very
carefully timed raster palette changes, or the smooth scrolling
Firetrack-stylee.
If you look at OS1.20, its IRQ handler (at &DC1C, which comes from the
6502's IRQ vector at &FFFE/&FFFF) does this:
STA &FC ; keep copy of A
PLA
PHA ; get P flag into A and re-push it to stack
AND #&10 ; test B flag
BNE break_handler
JMP (&204) ; jump through IRQ1V
.break_handler
<rest of code>
If IRQ1V is claimed, and doesn't relinquish control back to the original OS
code, then RTI is required to exit the interrupt. Also, a quirk of the
Beeb OS is that there must be a LDA &FC before the RTI, as A is corrupted
on entry to IRQ1V.
Note also that it is the default IRQ1V code which is responsible for
determining whether it is servicing a "low priority" interrupt, and will
launch the call through IRQ2V. This means that if IRQ1V is claimed, and
exits via RTI, effectively the user code has complete control of the
interrupt handling - which is sometimes a good thing.
> NMIs are
> actually vectored slightly differently due to their nature. The MOS only
> permits "registered" entry points to intercept NMIs, which is why only
> the disk and net controllers use them (and also because they need to
> respond to service requests regardless of CPU state).
I don't know what you mean by this.
> [1] The JSR-JMP construct is a cunning way of implementing JSR (addr).
> The basic code runs as follows:
>
> Store JMP (addr) opcode (&6C):
> LDA #&6C:STA &1000
> Store the address:
> LDA #LSBaddr: STA &1001
> LDA #MSBaddr: STA &1002
> Then JSR it:
> JSR &1000
>
> The JMP jumps to the code, but the RTS will return to the address the
> JSR was called from.
Even more cunning is just to push the return address yourself, i.e.
LDA #(return_addr-1)DIV256:PHA
LDA #(return_addr-1)AND255:PHA
JMP (whatever)
.return_addr
Then the routine at 'whatever' can exit simply via RTS.
(maybe I've pushed that return address the wrong way round, I can't
remember).
Rich
**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
postmaster@...
This footnote also confirms that this email message has been checked
for all known viruses.
**********************************************************************
Sony Computer Entertainment Europe