On 3/27/2022 at 5:23 AM, svenvandevelde said:
Thank you. The documentation of the CX16 actually writes it and I oversaw this. It is clear for me now. Strange that the IO space is at such low area in memory. Was this done by design?
And also, I had been noticed that A800 till BFFF was available for use in bank 0 in an earlier post ...
First, the second point: None of that is guaranteed to stay free. As they add functionality to the Kernel, they are free to use any of that space. So relying on any of that being free will break your program if/when they use more of that space. And note, that could be AFTER release, when they fix a bug that comes to their attention!
Also on the second point, if the use of Bank0 was an issue, just switch to Bank1, Bank2, Bank3 (repeat 255 times) and the problem would have gone away, so redesigning the Bank0 layout to allow it would be totally unnecessary.
On the first point, yes, it was by design.
When it was decided to go with a 64K memory map with a 16KB ROM window an 8KB High RAM window, and a page of I/O divided into 8 32byte spaces, ROM with a 6502 typically needs to include the interrupt vectors in the $FFxx page, so the 16KB ROM window is in $C000-$FFFF. The $00xx page and $01xx page are the zero page and hardware stack, so the beginning of the memory map is Low RAM. And so the 8KB HighRAM window and 256 byte I/O page are at $A000-$BFFF and $9F00-$9FFF respectively to give the largest contiguous Low RAM.
Being able to use ANY High RAM bank for a program in Low RAM to overflow into was never an objective. The intended use of HighRAM was for extended data space, so that more of the LowRAM is available for program space.
Now, a couple of year ago, several of us were on FB arguing that the I/O page should be at $0400. $0000-$00FF is zero page, $0100-$01FF is the stack page, the CBM Kernel and Basic make heavy use of $0200-$03FF, but $0400-$07FF was the default text screen, which Vera made redundant, so it would have eliminated the "barrier" between LowRAM and HighRAM.
However, even using HighRAM for program space, using it as "overflow" ONLY allows ONE to be used! It opens up MANY more possibilities to package modules so that they fit into 8KB of RAM (possibly multiple modules in the same one), and have MULTIPLES of 8KB modules that can all be resident and can all be called from the same "master" code in LowRAM. The "overflow into HighRAM" option only increases program RAM from 30KB to 38KB ... 26% more space. Making 8 "packages" of 8KB modules increases program RAM from 30KB to 94KB ... 213% more space! And plenty more where that came from!
In Assembly, that is pretty natural, since you don't program such a large assembly language as one long program, you program in functional pieces and include them.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A little bit about why they said $04xx as I/O page was "harder" back then.
Consider Ben Eater's breadboard 6502 board, with a single quad NAND chip used for selecting RAM, ROM and I/O, with (for example), three VIA's and three ACIA's possible with room to spare:
/ROM_CS = NAND(A15,A15)
/ROM_OE = /ROM_CS
/RAM_CS = NAND(PHI2,/ROM_CS)
/RAM_OE = A14
/IO_CS = NAND(A14,/CS_ROM)
VIA1_C0 = A13
VIA2_C0 = A12
VIA3_C0 = A11
ACIA1_C1 = A10
ACIA2_C1 = A9
ACIA3_C1 = A8
This gives the 32K ROM from $8000-$FFFF, 16KB of RAM at $0000-$3FFF, and IO in the $4000-$7FFF space. It could be brought closer to the CX16 memory map using the fourth NAND on the Quad NAND:
/ROM_CS = NAND(A15,A14)
/ROM_OE = /ROM_CS
/A15 = NAND(A15,A15)
/RAM_CS = NAND(PHI2,/A15)
/RAM_OE = A15
/IO_CS = NAND(/RAM_CS,/ROM_CS)
VIA1_C0 = A13
VIA2_C0 = A12
VIA3_C0 = A11
ACIA1_C1 = A10
ACIA2_C1 = A9
ACIA3_C1 = A8
Now, RAM is $0000-$7FFF, ROM is $C000-$FFFF, and I/O is $8000-$BFFF. But I/O select is three logic layers deep, so if you are trying to run at 8MHz and that is pressing any of your I/O close to its limit, that could be a problem. That can be fixed by used a dual 2 to 4 active low decoder/demultiplexer, a 74xx156, which has two inputs, A and B, two sets of outputs, 1Y1-1Y3 and 2Y1-2Y3 and two sets of strobe inputs, G1 and G2, and data inputs, C1 and C2, where to select a set of outputs, G1 & G2 must be low, while C1 must be high for its set and C2 must be low for it's set. If you tie the strobes together and the data inputs together, you have a 3 to 8 decoder. So invert Phi2 and tie that to Strobe, tie A15 to C1 ad C2, A14 to A and A13 to B, and you have eight selects, each one selecting an 8KB space, so, say, $8000-$9FFF could be I/O, and $A000-$BFFF could select a second "data bank" RAM, getting it's address lines above A12 from some VIA port B lines. If you have 32KB ROMs and 32KB RAMs, you could have:
/ROM_CS = NAND(A15,A14)
/ROM_OE = /ROM_CS
ROM_A14 = VIA1_PB5
/A15 = NAND(A15,A15)
/RAM1_CS = NAND(PHI2,/A15)
/RAM1_OE = A15
DECODE_G1 = DECODE_G2 = NAND(PHI2,PHI2)
DECODE_C1 = DECODE_C2 = A15
DECODE_A = A14
DECODE_B = A13
/IO_CS = DECODE_1Y0
/RAM2_CS = /RAM2_OE = DECODE_1Y1
RAM2_A14 = VIA1_PB4
RAM2_A13 = VIA1_PB3
VIA1_C0 = A12
VIA2_C0 = A13
VIA3_C0 = A10
ACIA1_C1 = A9
ACIA2_C1 = A8
ACIA3_C1 = A7
And have LowRAM at $000-$7FFF, I/O in $8000-$9FFF, HighRAM at $A000-$BFFF, and ROM at $CFFF-$FFFF.
Now, that's just a "poor man's" version of the CX16 memory map. The actual CX 16 doesn't have the sparse I/O space, but eight "spaces" in a single page, so there is another 3 to 8 decode going on, and a narrowing down to a page in the 8KB I/O range. And the LowRAM extends right up to $9EFF, so it's CS and OE are more complex than above. But it might give a clue as to why they were arguing that $9Fxx was easier address decoding than $04xx would have been.