Jump to content
  • 0

XC16 Memory location bank 0 address $A000 till $A7FF


svenvandevelde
 Share

Question

The memory location of bank 0, address  $A000 till $A7FF is utilized or preserved by the kernal ROM.

Wouldn't it be better than this zone of memory would be moved to the upper area of the bank 0, for example to $B800 - $BFFF.

That would allow larger program files to be loaded inside the memory as a sequential file.

Because the address $A000 till $A7FF prevents program files to be loaded including the allocation of memory from $A800 to $BFFF.

I think the design of the CX16 can still be optimised before it is too late. 

I know this creates backward compatibility issues with programs written in assembly or basic, but if the change is not done now then it will always be like this forever.

What are your views?

Sven

Link to comment
Share on other sites

Recommended Posts

  • 0
On 3/26/2022 at 8:30 AM, Scott Robison said:

The "problem" is that IO space is between low memory and banked RAM. You really can't read across that window anyway.

I see! Now that is an answer.  That explains why. Is the hardware enforcing to address IO from $A000 onwards or is it because of kernal design of the CBM "roots".

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 2:21 PM, SlithyMatt said:

In fact, doing a bulk load is better with the status quo, as you can start loading at 00:B000 and automatically continue through the later banks.

True. That requires you however to have separate files to be loaded at runtime in memory.

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 1:12 PM, svenvandevelde said:

True. That requires you however to have separate files to be loaded at runtime in memory.

If you are going to be using banked RAM, that's pretty much a requirement, unless you are populating that memory strictly programmatically.

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 6:15 PM, SlithyMatt said:

If you are going to be using banked RAM, that's pretty much a requirement, unless you are populating that memory strictly programmatically.

I do both. In bank 0 from A800 till BFFF I store the data segments that have the fixed tables for the sprite control logic. In bank 1 I want to keep the fixed tables to control the tile slots (working on it now). I have my own loader which loads in banked ram using my own memory manager for dynamic memory allocation.

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 11:08 AM, svenvandevelde said:

I see! Now that is an answer.  That explains why. Is the hardware enforcing to address IO from $A000 onwards or is it because of kernal design of the CBM "roots".

I've not looked at the kernal to know if it is smart enough to fail a load that tries to use IO space or if it will just load bytes into IO space and corrupt the machine state.

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 1:19 PM, svenvandevelde said:

I do both. In bank 0 from A800 till BFFF I store the data segments that have the fixed tables for the sprite control logic. In bank 1 I want to keep the fixed tables to control the tile slots (working on it now). I have my own loader which loads in banked ram using my own memory manager for dynamic memory allocation.

You should not use Bank 0.  Bank 0 is reserved for system use. Use Bank 1 through 63 or 255 (depending on how many RAM chips are installed).

  • Like 1
Link to comment
Share on other sites

  • 0
On 3/26/2022 at 6:33 PM, Scott Robison said:

I've not looked at the kernal to know if it is smart enough to fail a load that tries to use IO space or if it will just load bytes into IO space and corrupt the machine state.

So is this space between A000 and A7FF not available due to hardware defined addressing? (address line logic on the board).

 

Link to comment
Share on other sites

  • 0
On 3/26/2022 at 10:28 PM, svenvandevelde said:

So is this space between A000 and A7FF not available due to hardware defined addressing? (address line logic on the board).

 

No, the space between $9F00 and $9FFF is IO space, so loading into it is not possible (whether because the kernal disallows it or it just corrupts IO space by overwriting it). You can load into $A000-$BFFF but it must be a separate load from a load into the main system memory.

Bank 0 of high RAM is just reserved by the system, and if you overwrite it you do so at your own risk. Bank 1 and higher are available.

Link to comment
Share on other sites

  • 0
On 3/27/2022 at 6:51 AM, Scott Robison said:

No, the space between $9F00 and $9FFF is IO space,

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 ...

 

Link to comment
Share on other sites

  • 0
On 3/27/2022 at 4:23 AM, svenvandevelde said:

Strange that the IO space is at such low area in memory. Was this done by design?

It was -- I seem to remember 8-Bit-Guy's second video laying out his suggested "flat + banks" memory model.

 

The constraints worked like this:  the design allows a banked 16K block to switch out "KERNAL + BASIC ROM", so that's $C000 to $FFFF.  In retrospect that is a smart and potentially useful move.

Then he has the 8K banked RAM window.  That's $A000 to $BFFF.

The only room left for I/O is either high or low main RAM, because he didn't want to bank that.

 

Here:  at time index 7:16 in his video 

 

1506464047_ScreenShot2022-03-27at7_30_34AM.png.34f003aeee78154466f51c199cf14eeb.png

 

Edited by rje
  • Thanks 1
Link to comment
Share on other sites

  • 0
On 3/27/2022 at 4:23 AM, svenvandevelde said:

Strange that the IO space is at such low area in memory. Was this done by design?

 

At the time of that video, I wonder if the system used Bank 0 yet?

If not.... I wonder if I/O could be shoved into an upper slice of Bank 0.

On the other hand, that would make I/O less friendly.  Although it could enable a 256 byte window into VERA.

Edited by rje
Link to comment
Share on other sites

  • 0
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.

Edited by BruceMcF
  • Like 1
  • Thanks 2
Link to comment
Share on other sites

  • 0
On 3/27/2022 at 8:36 AM, rje said:

 

At the time of that video, I wonder if the system used Bank 0 yet?

If not.... I wonder if I/O could be shoved into an upper slice of Bank 0.

On the other hand, that would make I/O less friendly.  Although it could enable a 256 byte window into VERA.

You wouldn't put the I/O in a Bank ... then you would have to include the contents of the RAM Bank register in the RAM /OE logic, because RAM output cannot be enabled at the same time as IO or there will be bus contention when an I/O device is read.

  • Thanks 2
Link to comment
Share on other sites

  • 0

@BruceMcF Thank you for your extensive answer. It was very clarifying and a very interesting read.

On 3/27/2022 at 2:56 PM, BruceMcF said:

Now, a couple of year ago, several of us were on FB arguing that the I/O page should be at $0400.

You are right, moving IO into banked ram is not a good idea, and indeed, the alternative would have been to move I/O totally to the front.
It makes a lot of sense to move I/O to address $0400. But would that not have had side effects to the CX16 compatibility of the C64 programs written in BASIC?

On 3/27/2022 at 2:56 PM, BruceMcF said:

A little bit about why they said $04xx as I/O page was "harder" back then.

I am going to read the detailed explanation in a very detailed manner, as this information is extremely interesting to learn.
It is amazing how I am now also starting to understand how actually the C64 hardware worked, address lines etc, and how the addresses were "calculated".
And what you've written is very interesting to analyze and trying to understand. I never learned electronics, you see.

Sven

 

Link to comment
Share on other sites

  • 0
On 3/27/2022 at 10:04 AM, svenvandevelde said:

@BruceMcF Thank you for your extensive answer. It was very clarifying and a very interesting read.

[1] You are right, moving IO into banked ram is not a good idea, and indeed, the alternative would have been to move I/O totally to the front.
It makes a lot of sense to move I/O to address $0400. But would that not have had side effects to the CX16 compatibility of the C64 programs written in BASIC?

[2] I am going to read the detailed explanation in a very detailed manner, as this information is extremely interesting to learn.
It is amazing how I am now also starting to understand how actually the C64 hardware worked, address lines etc, and how the addresses were "calculated".
And what you've written is very interesting to analyze and trying to understand. I never learned electronics, you see.

Sven

[1] $0400-$07FF was the text mode display screen, so with Vera instead of the VIC-II that area is redundant. Basic relied on the KERNAL for those hardware details, and the parts of the C64 KERNAL that used it have already been modified in the CX16.

[2] I always wanted to have a try at tinkering with hardware on the C64 User Port, but when I had the time, I didn't have the money, and visa versa, so I never had a chance to ... but I did for a time have access to a University library that some good 74xxyyy glue logic databooks, so I drew up more than a few fantasy circuits. It was only later reading forums at 6502.org and discussion by Garth Miner at his site that I found out how little I knew about the games you could play with glue logic.

I think one way to get from the above to the actual CX16 memory map (not saying this is the circuit that the CX16 uses!) uses an octal (8bit) inverter and two more 3 to 8 decoders:

  • Run A8-A12 through the inverter, and "wire them together" in a wired or, along with the /IO_CS above. Wired-ORs are cheap, but they are tricky, since the load they will take when they are high depend on how many high signals are included. Anyway, then when A8-A12 is high, the inverted values will be low (and the inverter will isolate the address lines from the wiring together), and when the inverted values AND the $8000-$9FFF output from the 1st decoder are all low, that will be low.
  • Run that as the strobe into the second decoder, and feed A7, A6 and A5 into C1=C2, A and B, and you have eight I/O select lines in $9F00-$9F1F, $9F20-$9F3F,...,$9FE0-$9FFF.
  • Run Phi2 through another one of the inverter lines and use that as Low RAM chip select, /RAM1_CS. An inverter has a low delay, so that puts very little delay between PHI2 rising and /CS falling.
  • For the /RAM1_OE, use the third decoder as an arbitrary 3 input to 1 output logic chip. Feed /ROM_CS, /RAM2_CS and /DECODE2_G1 (the strobe for the IO page decoder) into C1=C2, A and B, and the low output when all three are high is the /RAM1_OE, so there is no contention between LowRAM and IO, Low_RAM and HighRAM, and LowRAM and ROM.

 

 

Edited by BruceMcF
Link to comment
Share on other sites

  • 0
On 3/27/2022 at 3:23 AM, svenvandevelde said:

And also, I had been noticed that A800 till BFFF was available for use in bank 0 in an earlier post ...

It is available at this instant in time but who knows what the future holds. If you are writing a program that is so tight on memory and you need that space, take a chance on the future and use it. Otherwise, just treat bank 0 of high RAM as "reserved for future expansion".

  • Like 1
Link to comment
Share on other sites

  • 0
On 3/27/2022 at 6:51 PM, Scott Robison said:

It is available at this instant in time but who knows what the future holds. If you are writing a program that is so tight on memory and you need that space, take a chance on the future and use it. Otherwise, just treat bank 0 of high RAM as "reserved for future expansion".

Oh, and allocate from the top working down, because they way they got the first quarter filled is starting from the bottom, working up.

But given a program that can't be done with 2,088,996 bytes to work with, it seems unlikely that adding another 6,144 bytes is going to get it over the top.

  • Like 1
Link to comment
Share on other sites

  • 0
On 3/28/2022 at 7:57 AM, Michael Steil said:

It is NOT available.

Hello Michael, nice to see you around. Thanks for your feedback. So it is clear now. I wanted to post a bit more on this answer because i feel that there is a huge confusion and that people are reacting rather emotionally on it. My question was humble.

Link to comment
Share on other sites

  • 0
On 3/28/2022 at 12:00 AM, svenvandevelde said:

Hello Michael, nice to see you around. Thanks for your feedback. So it is clear now. I wanted to post a bit more on this answer because i feel that there is a huge confusion and that people are reacting rather emotionally on it. My question was humble.

My apologies if I came across in an emotional way. I've just been trying to explain why loading can't cross the $9F00 - $9FFF threshold and how to treat block 0. Your questions were not bad or untoward, and people here can vouch for my ability to lash out at what I find inane (which yours was not). Though I'm trying to be better. 🙂

Link to comment
Share on other sites

  • 0
Posted (edited)
On 3/28/2022 at 8:10 AM, Scott Robison said:

My apologies if I came across in an emotional way. I've just been trying to explain why loading can't cross the $9F00 - $9FFF threshold and how to treat block 0. Your questions were not bad or untoward, and people here can vouch for my ability to lash out at what I find inane (which yours was not). Though I'm trying to be better. 🙂

Don't worry guys.

Again, as you can see in this thread, I'm re-experiencing my 16 year old wizz kid feeling again at the age of 52, although now using C and more modern equipment.


You see, the reason why i'm coming up with all these strange questions is because i'm digging now deeply into the machine making this game engine.
I got now into the phase of "segmentation"; where to put code, where to put data, how to manage the "memory".
So this brought me to how to construct the prg file and it appears that prg files for the CX16 will never be larger than 48KB, which is ok.
No issue, i just wondered by there was not a continuous RAM space beyond the 48KB border into banked ram 0.
Where I could load into bank 0 pre-initialized data like math (sine) tables, control blocks, "stuff" as part of the prg file.


I'm in a discovery trying to define the strategy to extend this almost working prototype to a working engine with
- levels,
- state machine control
- more graphics
- more tiles
- more event types
- adding enemy fire-
- more bullet types
- defences
- AI control

And sharing my experiences along the way, I have questions, ideas, things I may have understood wrong etc.
This forum is the platform to ask these questions and to share the ideas, right?

The CX16 platform will become great through its users. I don't know how else it would grow, right?

 

So to come back to the topic, it seems that the design of the game will need to apply dynamic loading of memory in the banks, applying the banks during runtime.
It will need to be done by creating several bin files that are loaded dynamically into the banks as the game execution progresses (loading stages).

I'm using banks already extensively, and the demo shows, all the sprites, tiles and control data is loaded in the banked memory and then gradually copied into the VERA when needed.
 

Sven
 

Edited by svenvandevelde
  • Like 2
Link to comment
Share on other sites

  • 0
On 3/28/2022 at 12:38 AM, svenvandevelde said:

I'm in a discovery trying to define the strategy to extend this almost working prototype to a working engine with
- levels,
- state machine control
- more graphics
- more tiles
- more event types
- adding enemy fire-
- more bullet types
- defences
- AI control

And sharing my experiences along the way, I have questions, ideas, things I may have understood wrong etc.
This forum is the platform to ask these questions and to share the ideas, right?

The CX16 platform will become great through its users. I don't know how else it would grow, right?

 

So to come back to the topic, it seems that the design of the game will need to apply dynamic loading of memory in the banks, applying the banks during runtime.
It will need to be done by creating several bin files that are loaded dynamically into the banks as the game execution progresses (loading stages).

I'm using banks already extensively, and the demo shows, all the sprites, tiles and control data is loaded in the banked memory and then gradually copied into the VERA when needed.
 

Sven
 

Yes, this is exactly the right place to ask these questions. 

Loading 8kb files as you need them can be done pretty quickly.  You can even start loading them a few at a time as the player passes checkpoints, to reduce delays between levels. And an initial splash/title screen can be loaded first and displayed while the program loads the rest of its initial files.

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use