c64 Interrupts Eng Part03
c64 Interrupts Eng Part03
c64 Interrupts Eng Part03
The previous times we have seen that some chips of the C64 constitute
the main sources of Hardware Interrupt Requests addressed to the 6510
cpu. Specifically, the VIC (acronym for Video Interface Controller)
and the CIA 1 (Complex Interface Adapter) generate IRQ type Interrupt
Requests while the integrated CIA 2 is a source of Non Maskable
Interrupt Requests (NMI).
This time, Let's study the Flowchart for an NMI Interrupt. See Figure
1, already published in Part 2 of this Tutorial, for reference, which
we'll bring back here again to make it easier for readers.
As explained in figure 1, After completing the currently executing
machine language instruction, the 6510 saves (PUSH) the process status
register as well as the program counter in the stack.
Figure 1 - Flowchart of the operations carried out following both an IRQ and an NMI
Interrupt Request
The Routine sets the Interrupt Disable Flag of the CPU Status Register
and then reads the contents of the NMINV vector $0318-$0319. NMINV is
a RAM vector that contains the start address ($fe47) of the NMI
Handler.
First of all, the NMI Handler saves in the stack (PUSH) the 3 Data
Registers of 6510, i.e. the Accumulator, the Index X Register and the
Index Y Register.
Then the Routine tries to identify the source of the NMI Interrupt;
it checks if the Interrupt Request comes from CIA 2 by testing if the
high bit of $dd0d, the CIA 2 Interrupt Control Register (ICR), is set.
For completeness we remind you that the C64 User Port implements the
RS-232 Protocol managed via software (Kernal).
If instead, the source of the Interrupt Request is NOT the CIA 2, then
the Handler checks for the presence of a possible ROM Cartridge
inserted in the Expansion Port and, if so, it will execute the Warm
Start procedure whose address is contained in the vector $8002-$8003.
If the user has NOT pressed the RUN/STOP and RESTORE key combination,
we first pull Y, X and A Registers from the stack then exit the NMI
Handler through the usual RTI (ReTurn from Interrupt) instruction.
Finally, we would like to point out that the output of our routine is
managed by a JUMP at $ea31, which is the default IRQ handler to perform
the standard system operations performed 60 times per second, i.e.
keyboard scanning, cursor flashing, Jiffy clock update, etc.
As mentioned several times, the IRQ type interruption of the system
is triggered every 1/60 of a second by Timer A of the CIA1.
Remember that both Routines are implemented at address $c000 and must
therefore be executed by writing the command SYS 49152 in the VICE
window which emulates the Commodore 64 screen.
*=$c000
newNMI
inc $d020 ;we increase the border colour
jmp $fe47 ;we jump to $fe47 address
;in order to execute the default NMI handler
Let's just add that this NMI interrupt handler can be tested by
repeatedly pressing the RESTORE key which, as we have said, is NOT
part of the keyboard matrix - containing 64 physical keys of the C64
- cannot be detected by the standard KERNEL keyboard reading routine
(SCNKEY) but generates an NMI type interrupt request.
In VICE 3.4, the RESTORE key of a real C64 corresponds to the F12 key
of a normal extended PC keyboard.
For the moment, we stop here and refer you to the next part of the
tutorial, part 4, where we will start to approach the most interesting
part of the interrupts with a theoretical analysis and a practical
application (code examples) for the implementation of "RASTER
INTERRUPTS" type interrupts (or "frame interrupts"). A "RASTER
INTERRUPT" type interrupt is an interrupt trigger signal that the
Commodore 64 graphics processor (VIC-II) can send whenever the raster
of the VIC video signal reaches a specific line on the screen.