commanderx16 / x16-rom

Other
153 stars 44 forks source link

KERNAL vectors currently overlap 65816's interrupt vectors #95

Open Pigu-A opened 4 years ago

Pigu-A commented 4 years ago

This is a problem because once the board uses a 65816 CPU, native mode is impossible to enter stably without disabling interrupts.

Affected vectors are:

Since I'm planning to work on 65816 compatibility and enhancements, I want to know if you would move these around or just remove it altogether.

mist64 commented 4 years ago

This is a problem. All Commodore computers since the 1977 PET support this jump table:

https://www.pagetable.com/?p=926

Moving/removing it breaks Commodore compatibility, which is one of the core ideas of the Commander X16.

What is the importance of these vectors? What if we can't support them? Can we work around it?

Pigu-A commented 4 years ago

65816 uses different interrupt vector locations for each of the mode to ease up mode handling in the interrupt routine and also maintain software compatibility in emulation mode.

I'm pretty sure you can ignore COP and ABORT for this system (they are just additional BRK and NMI, you can tell the board and manual team to not implement those). However, there's no way to ignore BRK, NMI and IRQ obviously. For the current ROM version, those will point to $6c03, $d64c and $d42e on bank 0 respectively (bold indicates opcodes, more on that later). Which means that when the CPU is run in native mode, which is required for 16-bit registers, interrupts will go to those respective address instead, executing garbage data.

However, there is a possible workaround. IRQ actually shares the same vector with jscrog which means that you can do the mode check and branch from there. For BRK and NMI, you could make the target routine reside at fixed address and do the same thing as for NMI. This would get tricky though since opcodes are now involved.

I could try implementing this for my 65816 port after I'm done with term projects next week. Now I know that those KERNAL vectors can't be (re)moved and requiring emulation mode to call.

Kroc commented 4 years ago

Where is it actually confirmed that the system will definitely use a 65816?

gitjeff2 commented 4 years ago

Where is it actually confirmed that the system will definitely use a 65816?

Even if it's not, it's probably a very good idea to code the ROM to be as compatible as possible with as many 6502 variants as can reasonably be arranged.

Why? Because, given the X16's hackable hardware and "legacy free" software environment, I expect a lot of people will eventually try to use different 6502 variants in the system's CPU socket. Logically, this would include everything from a real 6502 or 6510, to the 65816, to custom enhanced versions of the 6502 on an FPGA. Being able to swap 6502 compatible CPU's without having to patch the ROM just to get the system to boot would be huge plus.

Pigu-A commented 4 years ago

Where is it actually confirmed that the system will definitely use a 65816?

If you watch The 8-bit Guy's second video, you realize that he initially wanted to use it and will eventually try experimenting with it to see if it works. So what's wrong with me wanting to implement changes and optimizations for it earlier?

Kroc commented 4 years ago

Though a 65816 would be nice, engineering decisions cannot be made on "what-if"s and "maybe"s alone; whilst a 65816 is a drop-in replacement for a 65C02 when running 8-bit code, it is not the same story when switching to 16-bit mode, there are hardware considerations that have to be made that only David's team can make.

In simple terms, what you're asking for is a 65816, but what's missing is how the 65816 will be wired on the motherboard -- necessary changes to software to support a 65816 can't be made without knowing how the chip will be wired. Good intentions won't provide those details, so whilst I have nothing against going with a 65816, there needs to be a firm decision made first regarding hardware, if that is to be the case.

BruceMcF commented 4 years ago

This is a problem. All Commodore computers since the 1977 PET support this jump table:

https://www.pagetable.com/?p=926

Moving/removing it breaks Commodore compatibility, which is one of the core ideas of the Commander X16.

What is the importance of these vectors? What if we can't support them? Can we work around it?

IOBASE is at $FFF3-$FFF5, so in Emulation Mode: $FFF4/$FFF5 COP, is the address of the IOBASE jmp. PLOT at $FFF0-$FFF2 is clear SCREEN at $FFED-$FFEF, in Native Mode $FFEE/$FFEF is IRQB (parallel to 65c02 IRQB at $FFFE/$FFFF) UDTIM at $FFEA-$FFEC, in Native Mode $FFEA/$FFEB is NMIB CLALL at $FFE7-$FFE9, in Native Mode $FFE6/$FFE7 is BRK, $FFE8.$FFE9 is ABORTB GETIN at $FFE4-$FF6, in Native Mode $FFE4/$FFE5 COP, $FFE6/$FFE7 is BRK

Which makes it all straightforward:

(1) Disallow use of COP, and there is no conflict in emulation mode.

(2) In Native mode, you cannot call emulation mode Kernel locations in any event ... if the call location is for an emulation call, than a different, parallel call location would be for a Native Mode call. So go into Emulation mode before bringing in ROM's with Emulation mode Kernel calls in them, and get a 65816 Native Mode ROM back in the ROM window before returning to Native Mode.

The above mentioned ".byte MIST" trampling the 65c02 Abort vector seems like it is an issue regardless.

Pigu-A commented 4 years ago

there are hardware considerations that have to be made that only David's team can make.

I'm tired of waiting for that too. I wish I could contact them outside of that Facebook group.

However, I know that 65816 can just be wired to act like a 65802 by discarding the bank address output and making new pin functions unused. But using external banking on the CPU that supports it internally is cursed.

So go into Emulation mode before bringing in ROM's with Emulation mode Kernel calls in them, and get a 65816 Native Mode ROM back in the ROM window before returning to Native Mode.

So you basically suggest that you have 65816 KERNAL in the other ROM bank and then switch around when the mode changes. This would be find if it still uses I/O writes to change the bank. But eventually, I want to make this also compatible with 65816's own banking system in case my proposal in the forums actually got accepted.

Kroc commented 4 years ago

I wish I could contact them outside of that Facebook group.

Agreed.

BruceMcF commented 4 years ago

there are hardware considerations that have to be made that only David's team can make.

I'm tired of waiting for that too. I wish I could contact them outside of that Facebook group.

However, I know that 65816 can just be wired to act like a 65802 by discarding the bank address output and making new pin functions unused.

The data bus is a lot busier in the 65C816 than in the 65C02, and there is no guarantee at the datasheet level that there won't be data bus contention that causes problems. Since it seems that the design team will be happy to call it done if it works with a 65C02 at 8.33MHz, if they have a board where that works and the modest changes required to drop in the 65816 (like, a pull up resister on a line that is an input line in the 65C816) are not enough to make the 65816 work, I expect they'll declare it doesn't work and go with the 65C02.

If it works, then from what they have said in the past, they will go with the 65816. But at this point, power up in 65C02 is a known constant, whether user code will have the built-in option to escape hatch into 65C816 code is a TBD in the design.

But using external banking on the CPU that supports it internally is cursed.

It's just pretending that the 65C816 is a 65C802. The upgrades to the instruction set opcodes are the meat: in Forth, it's equivalent to increasing the clock speed by 50% to 100%. I suspect it would be something similar for a well-design hosted Small C compiler.

The direct addressing of more memory is the gravy. I'll take the meat without the gravy if that's how they have decided to lay out the dinner table.

So go into Emulation mode before bringing in ROM's with Emulation mode Kernel calls in them, and get a 65816 Native Mode ROM back in the ROM window before returning to Native Mode.

So you basically suggest that you have 65816 KERNAL in the other ROM bank and then switch around when the mode changes.

I wouldn't have a 65816 Kernel, I'd have a protocol to push the Kernel address on the stack, load the registers as required, then have two functions available to call, one for wide data mode and the other for narrow data mode, to dispatch the Kernel call then return to the caller.

This would be find if it still uses I/O writes to change the bank.

That's the memory map they are going with ... write to a readable I/O register to set the bank. They clearly like the simplicity of that approach. "This would be fine if it still uses I/O to change the bank" therefore translates into "this is fine".

But eventually, I want to make this also compatible with 65816's own banking system in case my proposal in the forums actually got accepted.

That's a design for a different board & project. I'm not saying there is anything wrong with that approach, but the assumption of two I/O registers for the High RAM and ROM address spaces is built into too much of the firmware code at this point to expect that it will be changed.

BruceMcF commented 4 years ago

Though a 65816 would be nice, engineering decisions cannot be made on "what-if"s and "maybe"s alone; whilst a 65816 is a drop-in replacement for a 65C02 when running 8-bit code, it is not the same story when switching to 16-bit mode, there are hardware considerations that have to be made that only David's team can make.

The hardware issues do not appear and disappear with the mode switch ... even if it stays in Bank 0, the bank is asserted during Phi2=1 and into Phi2=0 no matter what mode the chip is in ... "emulation mode" is not emulating a 65C02 processor, it is emulating the execution behavior of legacy 65C02 opcodes.

In simple terms, what you're asking for is a 65816, but what's missing is how the 65816 will be wired on the motherboard -- necessary changes to software to support a 65816 can't be made without knowing how the chip will be wired.

I don't follow this. They've been very specific that if they include the 65816, it will be with the exact same memory map as the current board. Whether there is a pull up resister on a pin that is a redundant clock output line on the 65C02 and an input line on the 65C816 is neither here nor there to programming.

Good intentions won't provide those details, so whilst I have nothing against going with a 65816, there needs to be a firm decision made first regarding hardware, if that is to be the case.

Public comments on the FB forum indicate that the decision will be made when they can physically confirm whether or not there will be databus contention issues with the chipset and address bus they are using and the 65816. That requires getting the board running satisfactorily with the 65C02, otherwise it will be an intractable problem sorting out whether the 65816 is responsible for a problem.

It's a TBD. [Edit:] This "65816 TBD when the 65c02 board is working" plan was confirmed again as the current plan by David Murray in a FB group discussion last week (2019-12-8/2019-12-14).

There's no point in the design team dedicating any effort on 65816 code in advance of the CPU passing the physical "does everything go haywire?" test, but there's no harm in people in the community who have their fingers crossed that it will pass trying to get a jumpstart on developing for it, if that is where their interest lies.

After all, surely there will be an 3rd party drop-in daughter board that presents a 65C02 pin interface if the 65816 doesn't work out directly on the board.