Access to banked memory by expansion cards

Get help from the community & developers with the X16 hardware if you can't find the solution elsewhere
spargue
Posts: 29
Joined: Thu Apr 13, 2023 8:56 pm

Re: Access to banked memory by expansion cards

Post by spargue »

Wavicle wrote: Wed Jun 28, 2023 8:07 pm
spargue wrote: Wed Jun 28, 2023 12:41 pm From what's been made public of the design and the VPB latch mod I'm not sure if NMI can be accounted for without some HW rework of the main system. Ultimately several design choices have crippled some novel implementations of expansion and you have to do everything the slow way without any form of modern acceleration. I'm not really sure the VPB latch mod is 100% sound as it would change the latch before exiting the ISR. So ISR has to exit from a ram instruction rather than a form a ROM instruction.
I'm the one that proposed using the VPB signal as an additional reset to the ROM bank latch and I looked at it fairly closely. Ultimately the decision was VPB as the only signal, which I disagree with but that's because I'd like an advanced debugger to insert itself after reset but before the CPU starts executing anything in a known state. For all other situations, VPB is adequate. VPB is always asserted on the negative phase of the first cycle of a vector pull. VPB does not glitch during non-vector pull operations and ISR does not initiate a vector pull hence I'm not sure what the concern is.
1 interrupt / NMI is being serviced, (latch is clear, $0001 is old value) ISR has read $0001.
2 card begins bus access, (ISR hasn't gotten to write $0001 to 0 yet)
3 card does Read $0001 (exchanges data then restore $0001)
4 latch is now value before entering ISR (not bank 0), but ISR is still running assuming it's bank 0.
This creates hazards.
Since only 1 card can get bus access at a time, you might as well get the CPU to set the banks needed in the service routine as the CPU has to be the arbiter. No point in getting a card to do its own advanced bus master it just adds complexity to the card.
DragWx
Posts: 340
Joined: Tue Mar 07, 2023 9:07 pm

Re: Access to banked memory by expansion cards

Post by DragWx »

I might know where the confusion is coming from.
spargue wrote: Wed Jun 28, 2023 9:22 pm 4 latch is now value before entering ISR (not bank 0), but ISR is still running assuming it's bank 0.
The very beginning of the ISR, which is responsible for reading $0001, pushing it onto the stack, and setting $0001 to zero, is executing out of RAM, not ROM. Look here if you'd like to verify it for yourself. This is the part of the ISR that comes before the jump to CINV, CBINV, or NMINV, and since it's in RAM, the state of the physical ROM bank latch doesn't matter, as long as nothing changes the value of $0001 unexpectedly. The RAM trampoline will finish by setting $0001 to zero (no matter what state the physical latch is in), and jumping to the respective software ISR vector.

If there were a previous revision of the ROM where the IRQ and NMI vectors pointed directly to a ROM routine, that's not the case anymore; those vectors point to very small RAM trampolines now.
spargue
Posts: 29
Joined: Thu Apr 13, 2023 8:56 pm

Re: Access to banked memory by expansion cards

Post by spargue »

DragWx wrote: Wed Jun 28, 2023 11:02 pm I might know where the confusion is coming from.
spargue wrote: Wed Jun 28, 2023 9:22 pm 4 latch is now value before entering ISR (not bank 0), but ISR is still running assuming it's bank 0.
The very beginning of the ISR, which is responsible for reading $0001, pushing it onto the stack, and setting $0001 to zero, is executing out of RAM, not ROM. Look here if you'd like to verify it for yourself. This is the part of the ISR that comes before the jump to CINV, CBINV, or NMINV, and since it's in RAM, the state of the physical ROM bank latch doesn't matter, as long as nothing changes the value of $0001 unexpectedly. The RAM trampoline will finish by setting $0001 to zero (no matter what state the physical latch is in), and jumping to the respective software ISR vector.

If there were a previous revision of the ROM where the IRQ and NMI vectors pointed directly to a ROM routine, that's not the case anymore; those vectors point to very small RAM trampolines now.
This just looks like a whole bunch of dirty fixes on a shaky house of cards. Why are the ISR vectors in ROM only to point to RAM locations?
This is far from the clean system David described from the beginning. All the really good C64 stuff has been removed for weird and janky cludges.
User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

Re: Access to banked memory by expansion cards

Post by StephenHorn »

spargue wrote: Wed Jun 28, 2023 11:23 pm Why are the ISR vectors in ROM only to point to RAM locations?
They need to be in ROM, or else the system might not boot correctly from a power-on. The 65xx series of processors look at fixed addresses for several events, including the address of a interrupt routine, and these vector locations are closely packed together. It makes no sense to bolt on extra hardware in order differentiate between FFFC/D and FFFE/F and FFFA/B, in an effort to make some interrupts be ROM while others are RAM. If you were going that route, you're better off going full-bore on the additional complexity and have a full-on IRQ manager that listens to the top 8 bytes of the address range and provides a bespoke address based on what it believes is the highest-priority interrupt. And that's the exact opposite of simple hardware.

The simplest solution is to let all the vectors live in ROM space, and program the ROM for a bare-minimal IRQ preamble before jumping to a location that is stored in RAM.
Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
DragWx
Posts: 340
Joined: Tue Mar 07, 2023 9:07 pm

Re: Access to banked memory by expansion cards

Post by DragWx »

spargue wrote: Wed Jun 28, 2023 11:23 pm This just looks like a whole bunch of dirty fixes on a shaky house of cards. Why are the ISR vectors in ROM only to point to RAM locations?
This is far from the clean system David described from the beginning. All the really good C64 stuff has been removed for weird and janky cludges.
When you're dealing with IRQs and especially bankswitched memory, RAM trampolines are very common, and that's what these are.

Code running in ROM bank X -> Trampoline in RAM to change banks -> Code running in ROM bank Y.

IRQ -> Trampoline in RAM which deals with bankswitching -> Jump to CINV which may point to the default handler in the kernal or may not.

This is pretty standard and is actually how the kernal's handled bankswitching (and bankswitched IRQs) since at least 2020.

Before the VPB mod, every single bank in ROM (both the X16's ROM and every bank that your expansion card wanted to map into the ROM region) needed to have a copy of the CPU vectors at the end. After the VPB mod, this is no longer needed; every byte of mapped memory at C000-FFFF is free for you to use however you want. Better yet, bank 0 containing the one and only set of vectors will help with stability in the long run. Even better yet, this change only required one wire to be added to the PCB, and didn't require us to rewrite our ISRs. That seems pretty clean and simplified to me.
kelli217
Posts: 531
Joined: Sun Jul 05, 2020 11:27 pm

Re: Access to banked memory by expansion cards

Post by kelli217 »

spargue wrote: Wed Jun 28, 2023 11:23 pm Why are the ISR vectors in ROM only to point to RAM locations?
The interrupt service request vectors are in ROM because they need to be. They point to RAM locations so that the interrupt service routine can be modified by the end user to include other interrupt-based code and then JMP to the regular kernal ISR code if desired.

"Why do they need to be?"

Because the 65C02 needs to have the six bytes at the top of memory, $FFFA through $FFFF, populated with vectors at startup. And before any system interrupts take place. But if the interrupt vector never points anywhere but ROM, then you can never run any code of your own in the interrupt service routine.

IN THEORY, it might be possible to set up only two bytes at $FFFE and $FFFF as RAM, and have $FFFA through $FFFD as ROM so that NMI and RESET can have ROM routines and IRQ/BRK can have RAM right from system startup. Go ahead and tell me that's somehow "cleaner."
User avatar
StephenHorn
Posts: 565
Joined: Tue Apr 28, 2020 12:00 am
Contact:

Re: Access to banked memory by expansion cards

Post by StephenHorn »

spargue wrote: Wed Jun 28, 2023 12:41 pm Ultimately several design choices have crippled some novel implementations of expansion and you have to do everything the slow way without any form of modern acceleration.
I'm curious what you're trying to design for the X16. Mostly because I've looked at the idea of a basic memory-copying/memory streaming controller that kicks the CPU off of the main bus. I am, however, a rank amateur and this project has proven more demanding than I have realistically have time for -- that said, it seemed to be the opinion of far more qualified individuals on this forum that all of the technical problems have to do with matching and designing around the timings of memory and other components.

Maybe you're thinking of making a Z80 coprocessor expansion card that kicks the CPU off the bus? I know lots of people have suggested such a device on Facebook and in the previous iteration of the forums. I don't see how that's impossible, given what we know about the system.
Developer for Box16, the other X16 emulator. (Box16 on GitHub)
I also accept pull requests for x16emu, the official X16 emulator. (x16-emulator on GitHub)
Wavicle
Posts: 281
Joined: Sun Feb 21, 2021 2:40 am

Re: Access to banked memory by expansion cards

Post by Wavicle »

spargue wrote: Wed Jun 28, 2023 9:22 pm
Wavicle wrote: Wed Jun 28, 2023 8:07 pm
spargue wrote: Wed Jun 28, 2023 12:41 pm From what's been made public of the design and the VPB latch mod I'm not sure if NMI can be accounted for without some HW rework of the main system. Ultimately several design choices have crippled some novel implementations of expansion and you have to do everything the slow way without any form of modern acceleration. I'm not really sure the VPB latch mod is 100% sound as it would change the latch before exiting the ISR. So ISR has to exit from a ram instruction rather than a form a ROM instruction.
I'm the one that proposed using the VPB signal as an additional reset to the ROM bank latch and I looked at it fairly closely. Ultimately the decision was VPB as the only signal, which I disagree with but that's because I'd like an advanced debugger to insert itself after reset but before the CPU starts executing anything in a known state. For all other situations, VPB is adequate. VPB is always asserted on the negative phase of the first cycle of a vector pull. VPB does not glitch during non-vector pull operations and ISR does not initiate a vector pull hence I'm not sure what the concern is.
1 interrupt / NMI is being serviced, (latch is clear, $0001 is old value) ISR has read $0001.
2 card begins bus access, (ISR hasn't gotten to write $0001 to 0 yet)
3 card does Read $0001 (exchanges data then restore $0001)
4 latch is now value before entering ISR (not bank 0), but ISR is still running assuming it's bank 0.
This creates hazards.
Since only 1 card can get bus access at a time, you might as well get the CPU to set the banks needed in the service routine as the CPU has to be the arbiter. No point in getting a card to do its own advanced bus master it just adds complexity to the card.
What exactly is the issue? Use real values and real operations. Why did the card read $01? Does it do something with the value read? A card that isn't doing advanced bus mastering should not do any bus mastering until the CPU asserts the RDY pin indicating it has configured everything and is now quiescent waiting for the card to signal an interrupt at the end of its bus master operation.
spargue
Posts: 29
Joined: Thu Apr 13, 2023 8:56 pm

Re: Access to banked memory by expansion cards

Post by spargue »

Martin Schmalenbach wrote: Tue Jun 27, 2023 1:02 am Do expansion cards of any/all types, whether using the dedicated IO slots or accessing the full 64K address space seen by the CPU also get to 'see' the same banked ROM & RAM as the CPU does?

I'm working on an expansion card design that could really do with accessing at least one of the 8K RAM banks, if not more of them...

Is it possible for an Expansion card to change the RAM bank arbitrarily, and, assuming it puts it back to the bank that was selected prior to the expansion card doing its 'thing', operate without messing up the rest of the system?

For similar reasons can an expansion card access the VERA registers and internal memory space?

Thanks in advance.
To get back on topic, I think the best way to achieve this is to raise an interrupt for attention, have the service routine set the banks then write a byte to the card to trigger the bus access. On the very next sync hold wait and ba for the transfer. If vpb or reset is triggered before the sync your card must abort. The card then presents a status byte to say if the transfer was successful. And exit service routine.
The system isn't flexible enough to allow unmanaged random memory access.
To get your card to do bank switching automatically seems to be difficult and hazards.
I sugjested a mod that would allow full bus access from the cards and not touch the bank address, but it's been ignored.
spargue
Posts: 29
Joined: Thu Apr 13, 2023 8:56 pm

Re: Access to banked memory by expansion cards

Post by spargue »

Wavicle wrote: Thu Jun 29, 2023 7:38 am
spargue wrote: Wed Jun 28, 2023 9:22 pm
Wavicle wrote: Wed Jun 28, 2023 8:07 pm

I'm the one that proposed using the VPB signal as an additional reset to the ROM bank latch and I looked at it fairly closely. Ultimately the decision was VPB as the only signal, which I disagree with but that's because I'd like an advanced debugger to insert itself after reset but before the CPU starts executing anything in a known state. For all other situations, VPB is adequate. VPB is always asserted on the negative phase of the first cycle of a vector pull. VPB does not glitch during non-vector pull operations and ISR does not initiate a vector pull hence I'm not sure what the concern is.
1 interrupt / NMI is being serviced, (latch is clear, $0001 is old value) ISR has read $0001.
2 card begins bus access, (ISR hasn't gotten to write $0001 to 0 yet)
3 card does Read $0001 (exchanges data then restore $0001)
4 latch is now value before entering ISR (not bank 0), but ISR is still running assuming it's bank 0.
This creates hazards.
Since only 1 card can get bus access at a time, you might as well get the CPU to set the banks needed in the service routine as the CPU has to be the arbiter. No point in getting a card to do its own advanced bus master it just adds complexity to the card.
What exactly is the issue? Use real values and real operations. Why did the card read $01? Does it do something with the value read? A card that isn't doing advanced bus mastering should not do any bus mastering until the CPU asserts the RDY pin indicating it has configured everything and is now quiescent waiting for the card to signal an interrupt at the end of its bus master operation.
That's not the function of the RDY pin. You should read the posts further back as to why the card is reading $0001.
The issue is the sequence of operations to enter / exit an interrupt / bank switch and whether the card can do so whenever or if it needs a specific preamble sequence to allow mastering. If the ISR is relying on the RAM $0001 to be a shadow of the latch state is there a specific hazard where a card can jump in and mess with it thus violating the shadow state? the ISR is assuming the latch is still $00 and the RAM $0001 is the old value; but if a bus master occurs during this sequence that does its own bank sequence, then the latch is no longer $00 but the old value.
Post Reply