W65C265S Shadow Vectors
- rehsd

- Jan 14
- 3 min read
When I first started working with the W65C265SXB board, I was trying to get interrupts to work and was having no luck getting the interrupt service routine (ISR) to run. My setup was a simple momentary switch pulling down P41 (IRQB interrupt) or P64 (negative edge P64 interrupt).
As I reviewed the sample LEDP72.asm that was included with the WDC Tools, I found vectors defined at the end of the file. Notice the Shadow_VECTORS section at $7EE0 and the vectors section at $FFE0.


At the time, I had no external flash memory in my SXB, and I was uploading my program to the SXB's static RAM over USB serial with EasySXB. I would then jump to my program from the Mensch Monitor on the '265. My program included appropriate steps to set port directions, enable IRQB and NE64 edge interrupts, and call CLI to globally enable interrupts. I also had to setup an ISR and point to it (interrupt vector). As the sample code had two sets of vectors (shadow and normal), I had to determine where to place the pointer to my ISR. Given the memory map of the system, the interrupt vectors would normally be at $FFxx, but this maps to on-chip ROM (i.e., built into the '265 hardware), which of course I cannot modify. That then led me to the Shadow_VECTORS section. Given the offset address of $7EE0, which is in static RAM, it seemed logical that I would place pointers to my ISRs in the shadow vector table.
But where in the shadow vector table should I create entries for my IRQB and NE64 ISRs? The '265 datasheet includes interrupt vector addresses -- one set if you are running in emulation mode and another set for native mode.
The datasheet does not mention shadow vectors in any way, and I know that $FFxx addresses couldn't be right (unless I was using an external flash with my ISR pointers in vectors at the upper portion of the flash ROM address space).

With everything I was seeing (or not seeing) at this stage, I made the assumption that I needed interrupt vectors setup somewhere in the $7Exx space -- either using sections with appropriate offsets or initialization code that loads the ISR pointer into the interrupt vector. I still had questions on which specific address to use though. Using Copilot and Gemini (AI tools), I was reading that the offsets would be $8000 less than whatever was listed in the tables above (e.g., for NE64 in native mode: $FF98 minus $8000, resulting in $7F98). Other references were listing $7E98 for NE64.
I could not find anything authoritative on shadow addresses, so I pretty much tried them all -- native mode, emulation mode, subtracting $8000, and offsetting by another $0100. I simply could not get interrupts to work.
I then put my program on an external flash, using the addresses in the vector tables above (i.e., $FFxx), and interrupts worked fine. At that point, I just moved on, using my external flash for my program rather than uploading to static RAM. But I was still curious why I couldn't get it to work.
I recently decided to revisit this problem. I had previously posted to 6502.org a question about shadow vectors. I received a suggestion to look at the Mensch Monitor source code (thanks, Andy!). While I had previously reviewed the monitor source code, I reviewed it again. This time through it, I found these fragments in ROM_INIT.ASM and R_RAM.ASM:

This appears to be where the monitor was copying ISR pointers into $0100. Given that, I thought maybe I could place pointers to my ISRs into this $0100 space during my program initialization. Unfortunately, that still didn't work. Doing some more research, I found another important clue. Rather than storing just a pointer, I needed to include a JMP opcode followed by the address to my ISR. Success!
My IRQB ISR worked, and my NE64 ISR worked. Interestingly, if I removed the IRQB vector, the NE64 ISR would fail to work. Maybe there's some interrupt cascading in the monitor / 65265 that requires IRQB to be setup for edge interrupts, like NE64, to also work (?).
Going back to the W65C265S Monitor ROM Reference Manual, I see the listing. I believe I had tried $0118 when troubleshooting this the first time (with no luck), but I likely didn't have both NE64 and IRQB setup.

I am likely still missing details here, but I have it working with the above approach. If you have corrections to any of this, or additional context that would be helpful to me and others, please drop me a note, and I'll update this page. Thanks!
Sample Code: microcontollers/W65C265S/Shadow Vectors/shadow_vectors.asm at main · rehsd/microcontollers · GitHub









Comments