Using banked memory?

All aspects of programming on the Commander X16.
Post Reply
Dacobi
Posts: 292
Joined: Sun Dec 19, 2021 1:44 am
Location: Samsø, Denmark
Contact:

Using banked memory?

Post by Dacobi »

I'm currently trying to load an 8KB file into address 0xA000 using cc65.

my code is:

Code: Select all

...
unsigned char* map;
unsigned char val;

map = 0xA000;

cbm_k_setnam("map.bin"); 
cbm_k_setlfs(1,8,0);
cbm_k_load(0, 0xA000);

val = map[(some int)];
...
When the address is 0xA000 I only get garbled data, but if I change the address in my test program to ie. 0x2000 everything works fine.

Is it necessary to initialize the memory bank somehow?
Would this be a problem with the cc65 compiler?
Dacobi
Posts: 292
Joined: Sun Dec 19, 2021 1:44 am
Location: Samsø, Denmark
Contact:

Re: Using banked memory?

Post by Dacobi »

I found this link https://github.com/mwiedmann/cx16Coding ... Banked-RAM and using this example I have something working. However I don't really understand why.

This is the new code:

Code: Select all

...
#define BANK_NUM (*(unsigned char *)0x00)

unsigned char* map;
unsigned char val;

map = 0xA000;

BANK_NUM = 1;

cbm_k_setnam("map.bin"); 
cbm_k_setlfs(0,8,0);
cbm_k_load(0, 0xA000);

val = map[(some int)];
...
But really, the only thing I changed was removing the first 2 bytes of the binary file. Is this normal procedure when loading files to banked memory? Is there a setting for "cbm_k_setlfs" that works with files that have the first 2 bytes?
DragWx
Posts: 362
Joined: Tue Mar 07, 2023 9:07 pm

Re: Using banked memory?

Post by DragWx »

I'm looking at load.s in the Kernal ROM, and it looks like the sa value (from SETLFS) takes on a special meaning when you use LOAD (vs using OPEN):
If bit 0 is 0, you need to supply the destination address yourself (but the first two bytes of the file are still consumed).
If bit 0 is 1, the first two bytes of the file are consumed and interpreted as the destination address.
If bit 1 is 1, the first two bytes of the file are treated as part of the data (and not a header) and are copied to the destination along with the rest of the file, and I think this forces you to specify the destination address yourself, like when bit 0 is 0.

Also, make sure you set the RAM bank before loading, and make sure the correct RAM bank is set before reading your loaded data.
Dacobi
Posts: 292
Joined: Sun Dec 19, 2021 1:44 am
Location: Samsø, Denmark
Contact:

Re: Using banked memory?

Post by Dacobi »

If bit 0 is 0, you need to supply the destination address yourself (but the first two bytes of the file are still consumed).
I can't replicate this behaviour. The only way I can load a file to 0xA000 is if it doesn't have the leading 2 bytes, no matter which values are passed to "cbm_k_setlfs".

Code: Select all

...
char flag;
RAM_BANK = 1;
	
flag = 0; //Or 1
	 
cbm_k_setnam("map.bin");
cbm_k_setlfs(flag, 8 ,0);
cbm_k_load(0, (unsigned short)BANK_RAM);
...
The only thing that changes anything for me is whether "map.bin" is 8194 or 8192 bytes.

I'm using r43 by the way.
DragWx
Posts: 362
Joined: Tue Mar 07, 2023 9:07 pm

Re: Using banked memory?

Post by DragWx »

The only other thing I can think of is, if LOAD overflows past $BFFF, it wraps back around to $A000 and increases the bank number.

It could be that your data is loading just fine, but you're not in the RAM bank you think you're in when the call returns.
Dacobi
Posts: 292
Joined: Sun Dec 19, 2021 1:44 am
Location: Samsø, Denmark
Contact:

Re: Using banked memory?

Post by Dacobi »

The only other thing I can think of is, if LOAD overflows past $BFFF, it wraps back around to $A000 and increases the bank number.

It could be that your data is loading just fine, but you're not in the RAM bank you think you're in when the call returns.
You were correct about the "wrap around". If I set "RAM_BANK = 1;" after the file load my data is valid.

I guess this behaviour is useful when loading more than one file or files larger than 8KB. Still my file is only 8192 bytes + the 2 byte header.
DragWx
Posts: 362
Joined: Tue Mar 07, 2023 9:07 pm

Re: Using banked memory?

Post by DragWx »

Yeah, that's what's confusing me. Loading an 8194-byte file as a headered 8192-byte file ought to be the same as loading an 8192-byte file as an unheadered 8192-byte file, so I can only assume something else was going on too, like if you were mistakenly loading the 8192-byte file as a headered 8190-byte file; that'd be well under the overflow. The fact that the sa value works differently between OPEN and LOAD caught me off guard too.

I checked the emulator's hostfs code, and the bank will increment after something is loaded to $BFFF, regardless of whether there's another byte after that or not. I wasn't able to confirm whether this happens in the Kernal ROM too or not (crawling through the source code is painful on a phone :P ), but I'd say it's always best to reset the RAM bank before attempting to read any of the loaded data, just to be safe in general.
Dacobi
Posts: 292
Joined: Sun Dec 19, 2021 1:44 am
Location: Samsø, Denmark
Contact:

Re: Using banked memory?

Post by Dacobi »

The reason it worked when the file was 8192 bytes was that the header was still consumed. I just didn't realise because my function (at first) by chance returned the correct data, but as I kept working I found that the data was shifted.
but I'd say it's always best to reset the RAM bank before attempting to read any of the loaded data, just to be safe in general.
Right now I'm using 2 banks, so I always end up setting the bank number depending on the current index.
Post Reply