MEGA65/mega65-user-guide

"C64-Style Memory Banking" vs "VIC-III ``ROM'' Banking"

Closed this issue · 7 comments

Describe where we can find the problematic topic

appendix-45gs02-registers.tex \subsubsection{C64-Style Memory Banking} and \subsubsection{VIC-III ``ROM'' Banking}

The first paragraph doesn't actually explain anything. I can assume perhaps that I can look it up in the C64 user manual but it would be good to repeat it here.

The second paragraph looks like it covers pretty much the same parts of memory to bank in or out. But nothing is said about what happens if you mix these two methods. Does the last one that you used win? Does it reflect in what you read back from the other register? Is that even possible for all cases?

I read somewhere something about poke 0,65 (or was it 1,65)? How does that relate to this?

Describe the solution you'd like

Some additional text that answers these questions.

Describe alternatives you've considered
.

Additional context
.

I recommend preferring the Memory chapter over the appendices on these topics. The real solution will be to capture the details in new chapters and strip out these older explanations from the appendices.

Maybe I can answer some of my own questions, but then if I understand the vhdl correctly, the table under "VIC-III ``ROM'' Banking" is incorrect.

By way of concrete example, I am looking at the mapping of $A000, what would be the BASIC rom in the C64.
I am looking at mega65-core/src/vhdl/nocpu.vhdl (development branch) which contains this blocks of code:

      -- Now apply C64-style $01 lines first, because MAP and $D030 take precedence
      blocknum := to_integer(short_address(15 downto 12));
...
        if (blocknum=10) and (lhc(0)='1') and (lhc(1)='1') and (writeP=false) then
          
          temp_address(27 downto 12) := x"002A";
        end if;
        if (blocknum=11) and (lhc(0)='1') and (lhc(1)='1') and (writeP=false) then
          temp_address(27 downto 12) := x"002B";      
        end if;

where lhc seems to be the bits from the cpu I/O register at 0/1.
Then below that

      -- $D030 ROM select lines:
...
        if (blocknum=10 or blocknum=11) and (rom_at_a000='1')
          and (hypervisor_mode='0') then
          temp_address(27 downto 12) := x"003A";
          if blocknum=11 then temp_address(12):='1'; end if;
        end if;

The first part conditionally maps $A000 to $002.A000.
The second conditionally part maps $A000 to $003.A000. This seems to contradict the table in the user guide which associates ROMA with $2A000 – $2BFFF.

So the answer seems to be (much more complicated than I thought):

  • if both $00/$01 and $D030 map an address to RAM, you get RAM.
  • $D030 overrides $00/$01 when choosing which ROM to map in. $D030 chooses C65 ROMs, $00/$01 chooses C64 ROMs.

I didn't fully check this for all the other address ranges though.

I see lots of seeming duplicate code/gates in this part of code...

  • duplicate -- Lower 8 address bits are never changed temp_address(7 downto 0):=short_address(7 downto 0); in both arms of the condition below it
  • many cases like temp_address(27 downto 12) := x"002A"; which could leave the lower 4 bits of that unchanged In particular if blocknum=11 then temp_address(12):='1'; end if; would be unneeded.
  • double check for -- $D030 ROM select lines: if hypervisor_mode = '0' then inside the then-part (several times)

Please ignore the appendix and only use the Memory chapter on these topics. The appendix is technically accurate, but the Memory chapter answers all of these questions more clearly.

Both C64-style banking $01 and VIC-III $D030 banking bank in C64 ROM, so they don't conflict in operation. If the given region is not MAP'd and either register requests ROM for a region, the C64 ROM will be present in the 16-bit address space for that region.

Neither mechanism accesses MEGA65 ROM data. MEGA65 ROM is always MAP'd into the 16-bit address space, which overrides $01/$D030.

... The opening sentence below "VIC-III "ROM" Banking" in appendix K is misleading though not technically inaccurate when it refers to "regions of the C65’s 128KB ROM." The table is accurate: bank 2 is all C64 ROM. The final paragraph in that section is accurate: "Both VIC-III banking and C64-style banking can apply to $A000 – $BFFF and $E000 – $FFFF. They have the same effect of mapping those regions to ROM addresses in bank 2. If either mechanism is active for a region, then the region is mapped to ROM."

... Also don't look at nocpu.vhdl, that's cruft. :) There was a misunderstanding early in the project that D030 was supposed to map in bank 3 ROM, but this has been corrected in the appropriate places. Comments and crufty old things may not reflect that reality. I believe viciv.vhdl is the beginning of the thread of the actual implementation for D030.

Ah yes, I found nocpu.vhdl first, and it seemed the same as gs4510.vhdl but upon futher inspection it differs in some crucial elements.