When an IRQ occurs, the 6502 microprocessor and its derivatives in the C64 and C128 push the status register to the stack and then load the contents of a two-byte vector at memory address $FFFE/$FFFF into the program counter to continue program execution at the address specified by the vector. Usually, the address pointed by this vector leads to a Kernal routine that does some register saving and then jumps into the actual interrupt service routine specified by the vector in $0314/$0315.

On a C64 there are thus two possibilities to install a custom interrupt service routine: either by modifying the address in $0314/$0315 or by switching off the ROM and putting the address of your ISR into the RAM at $FFFE/$FFFF. The latter method requires that you do some more register housekeeping, but it saves a considerable number of cycles until your routine starts. Thus, when timing is important, the second method is preferred.

The IRQ mechanisms are very similar on a Commodore 128 in the C128 mode, but according to my understanding, the mapping of memory area $FF00-$FFFF is fixed. In particular, reading $FFFE/$FFFF always gives a predefined vector from ROM, pointing to $FF17 on my machine. The hardware IRQ vector is thus fixed in all memory configurations, allowing the C128 to execute an interrupt no matter what memory configuration is active. However, this would also mean that the direct hardware interrupt configuration is not possible in C128 mode. Since this is necessary for advanced IRQ routines (e.g. the "double IRQ" method used in many demos) this would deprive the C128 mode of an important feature.

Is this analysis correct? Or did I overlook a possibility to customize the IRQ hardware vector on a Commodore 128 in C128 mode?

After checking Brian's answer it becomes clear that this analysis was not correct. The reason why the ROM seems to appear at $FF05-FFFF in every bank is simply because the OS copied it there. But, as shown by Brian's example, this area can be simply overwritten.

  • There's a third option on the 64: A cartridge that puts the PLA into Ultimax mode (by setting /GAME = 0 and /EXROM = 1) can override whatever is located in 0xe000 - 0xfff, including the interrupt vectors. This is used by freezers, and by cartridges that provide a Kernal replacement. – Michael Graf Nov 28 '20 at 23:36

When the C128 is running in its native mode, the only "fixed" memory addresses are $FF00-$FF04. These 5 bytes allow access to the first 5 registers of the MMU regardless of the current memory configuration (which is controlled via the MMU).

The MMU's RAM Configuration Register, which is in I/O space at $D500, but always available at $FF00, controls how ROM, RAM, and I/O are banked in and out of the memory map. Using this register, you can certainly bank the Kernal ROM out, and thus allow access to interrupt vectors stored in RAM.

You may have been considering the other ability of the MMU to allow common areas of RAM that are in Bank 0 but also seen when accessing Bank 1. These optional shared RAM areas can occur at the bottom and at the top of RAM in various configurations. The top RAM sharing does share $FF00-$FFFF between the two RAM banks. But this is independent of the RAM or ROM being visible in that region of the memory map (as described above).

You can test all of this in BASIC right after cold starting.

BANK 15:PRINT PEEK(65534) - this prints "23"
BANK 0:POKE 65534, 18
PRINT PEEK(65534)         - this prints "18"
BANK 15:PRINT PEEK(65534) - back to "23"
  • Are you sure? On my C128, the area $FF00-FF04 is always showing the MMU registers and the area $FF05 to $FFFF is always showing the ROM. – Peter B. Nov 29 '20 at 12:50
  • Following the suggestions of your answer I first tried all 256 possible configurations of $ff00, in all of them there was the ROM at $FFFE. So for example, setting $3F (RAM bank 0, no ROMs) still has the ROM data between $FF05 and $FFFF! But when I switched off common RAM, this ROM block at the last page disappeared. It seems that “enable common RAM” is at the same some “configure system to have ROM at last page (except FF00-FF04”, is this correct? Anyway, thanks a lot! – Peter B. Nov 29 '20 at 14:43
  • @PeterB. It seems to work from BASIC using the BANK statement. – Brian H Nov 29 '20 at 19:31
  • It seems that I was fooled by the copy of the Kernal IRQ routines in the RAM. Thanks a lot for the example! – Peter B. Nov 29 '20 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.