Page 1 of 1

65816 (W65C265S) - trying to get COP to work from bank $40

Posted: Tue Mar 03, 2026 11:24 pm
by rehsd
In my W65C265S build (internally a 65816), I am looking at COP to call operating system routines from a secondary ROM. My secondary ROM starts at bank $40, with my operating system and interrupt vectors in bank $00. From my secondary ROM, I call cop 1. From my OS ROM, I have:

Code: Select all

cop_handler:
   ; temporary testing
   sei                     ; disable interrupts
   sep #$20                ; force 8-bit accumulator
   lda #'$'                ; debug character
   jsr print_char_serial   ; output to serial
   jsr print_char_lcd
   ...

.org $FFE0
;					;65C816 Interrupt Vectors
;					;Status bit E = 0 (Native mode, 16 bit mode)
	.word	badVec			; $FFE0 - IRQRVD4(816)
	.word	badVec			; $FFE2 - IRQRVD5(816)
	.word	cop_handler		; $FFE4 - COP(816)
Unfortunately, this doesn't appear to get to my cop_handler. I am in native mode. https://sneslab.net/wiki/COP indicates PBR should be set to zero, so I would think this should/could work.

http://sbc.bcstechnology.net/65c816interrupts.html also lists PBR being set to zero, but it also states that COP is being misused if for an operating system service call -- which is what I'm trying to do.

Should this work? If yes, why is it a bad idea to use COP for operating system service calls? Is it due to the stack mess?

Thanks!

Rich

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Wed Mar 04, 2026 1:58 am
by BigDumbDinosaur
rehsd wrote:
In my W65C265S build (internally a 65816), I am looking at COP to call operating system routines from a secondary ROM...
COP is “bank-agnostic”—you can invoke it from any bank, and is a software interrupt, same as BRK.  Note that like all interrupt responses, the steps executed by the MPU when processing COP include disabling IRQs and setting PB to $00.  There is no reason to do either operation in your COP front end, and in fact, when using COP to call operating environment services, you should enable IRQ processing with CLI as soon as possible.
Quote:
http://sbc.bcstechnology.net/65c816interrupts.html also lists PBR being set to zero, but it also states that COP is being misused if for an operating system service call -- which is what I'm trying to do.
You might want to re-read that...
Quote:
As no floating point hardware that is bus-compatible with the 65C816 is known to exist at this time, COP may be (mis)used in a number of ways...
“May be (mis)used...” is a tongue-in-cheek reference to the fact that in assembly language programming, anything that gets the job done is okay, even if the function/feature/service was not intended to be used in whatever way you are using it.  Over the years, my code for various renditions of the 6502 has been peppered with misused instructions—I don’t claim to have invented any of them.  For a classic hardware example of that line of thinking, take a gander at Jeff’s KimKlone.

For what its worth, the BIOS API in my POC V1.3 unit is called with COP #<n>, where <n> is the desired service index.  See attached, which is an excerpt from V1.3’s firmware assembly listing, specifically the COP handler.

cop_isr.txt
COP INTERRUPT SERVICE ROUTINE — POC V1.3 Firmware
(4.6 KiB) Downloaded 18 times

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Wed Mar 04, 2026 2:27 am
by rehsd
Thank you for all of that! I'll need to do more debugging. I moved the COP call to bank $00 to simplify testing (with no luck). I also need to do more research on the 65265 and COP, in case there's something special that needs to be configured on the '265.

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Wed Mar 04, 2026 5:04 am
by rehsd
I tracked down the issue. I was using an incorrect interrupt vector for COP. I was using $FFE4, but that's for the 65816. The 65265 uses $FFB4 instead!

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Wed Mar 04, 2026 7:58 pm
by BigDumbDinosaur
rehsd wrote:
I tracked down the issue. I was using an incorrect interrupt vector for COP. I was using $FFE4, but that's for the 65816. The 65265 uses $FFB4 instead!
It figures!  Why would they do that?  <Rhetorical Question>  What is in the address space where the true vectors would normally be found?

Anything I have published about programming the 65C816 assumes one is using an actual 65C816, not the 65C265.  I know little about the latter...I prefer to mess with bare-metal hardware over tinkering with someone’s notion of how a computer-on-a-chip is supposed to work.

BTW, although the front ends of the interrupt handlers need to be in bank $00, that doesn’t preclude placing the body and back-end code in other banks.  A long jump could be used to get there, at a cost of four cycles.

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Thu Mar 05, 2026 12:24 am
by rehsd
BigDumbDinosaur wrote:
What is in the address space where the true vectors would normally be found?
This is what I'm finding with some AI help... While the '816 is a general-purpose CPU, the '265 includes built-in peripherals like UARTs, timers, and twin sets of bus interfaces (ABUS, XBUS). To manage these without causing "interrupt chaos," Western Design Center (WDC) modified how the hardware handles vector fetching. To support on‑chip boot code, a separate native‑mode vector block, and reserved firmware hooks, WDC relocated all native vectors downward into the $FF80–$FFBF region, making COP land at $FFB4 rather than the 816’s traditional location.

Re: 65816 (W65C265S) - trying to get COP to work from bank $

Posted: Thu Mar 05, 2026 3:35 am
by BigDumbDinosaur
rehsd wrote:
BigDumbDinosaur wrote:
What is in the address space where the true vectors would normally be found?
This is what I'm finding with some AI help... While the '816 is a general-purpose CPU, the '265 includes built-in peripherals like UARTs, timers, and twin sets of bus interfaces (ABUS, XBUS). To manage these without causing "interrupt chaos," Western Design Center (WDC) modified how the hardware handles vector fetching. To support on‑chip boot code, a separate native‑mode vector block, and reserved firmware hooks, WDC relocated all native vectors downward into the $FF80–$FFBF region, making COP land at $FFB4 rather than the 816’s traditional location.
Sounds as though the 816’s VPB is being used to “steer” vectors to the lower addresses.  It seems unlikely the MPU die itself would have been modified.