Load address and C64 screen memory area

All aspects of programming on the Commander X16.
Post Reply
cosmicr
Posts: 43
Joined: Tue Nov 14, 2023 4:29 am

Load address and C64 screen memory area

Post by cosmicr »

Most people use the BASIC load address of $801 to get their programs going. And that makes sense because that's how the C64 did it.

But because the CX16 has it's own VRAM, the memory space from $400 - $7FF (1kb) is free for use. The C64 used that memory for the screen I understand.

Soooo.... What are people's thoughts about starting your program from $400 instead of $800? I know that means you'd have to type
SYS 1024
instead but is there any real issue with that? I do recall from when I was a kid some C64 programs required you do to that. As a kid I never understood why, but now I realise it's because they were carefully managing memory. If you start your program at $400 you get an extra 1kb of contiguous program memory.

If not, what I would like to know is, what do people like to use that extra 1kb for? I notice even in the cfg file for CA65 it doesn't really acknowledge that area by giving it a segment.

I've modified my CX16.cfg file this way:

Code: Select all

MEMORY {
    ZP:       file = "", define = yes, start = $0022,                size = $0080 - $0022;
    USER:     file = %O,               start = $0400,                size = $0800 - $0400; #### add this line
    LOADADDR: file = %O,               start = %S - 2,               size = $0002;
   # ...other memory definitions etc
}

and this line to segments:

Code: Select all

SEGMENTS {
    ZEROPAGE: load = ZP,       type = zp;
    EXTZP:    load = ZP,       type = zp, optional = yes;
    USER:     load = USER,     type = rw; #### add this line
    LOADADDR: load = LOADADDR, type = ro;
    # ... rest of the segments
}
Now I can access the additional memory segment using

.segment "USER"

instead of having to type .org $400

What do others do?
User avatar
ahenry3068
Posts: 1197
Joined: Tue Apr 04, 2023 9:57 pm

Re: Load address and C64 screen memory area

Post by ahenry3068 »

When programming in BASIC I mainly use this "Golden" ram to store small Machine language subroutines to "pep" up the BASIC code.
Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

Re: Load address and C64 screen memory area

Post by Ed Minchau »

The only line of BASIC in my programs is:
1 SYS 1024
Xiphod
Posts: 578
Joined: Thu Apr 15, 2021 8:05 am

Re: Load address and C64 screen memory area

Post by Xiphod »

The only reason $801 is used is because the SAVE and RUN commands in BASIC (as coded in the ROM) chose to use that (well, and that it made sense in the context of those earlier CBM memory map). Certainly, you can do your own custom ROM build (the code and build tools are available) to use something else. But as a community change, at this point it would probably break things more than it's worth (i.e. all the existing PRGs saved with the $801 header).

LOAD interprets the header content of the SAVEd PRG. So you'd just be modifying the behavior of SAVE to write in a different header. I don't think there is any override to the behavior of RUN. But to make it easier for end-user to just LOAD and RUN your program, non-BASIC programs borrow that startup convention, then JSR to their actual start point. The address space is (mostly) yours after that point, especially if you have no need to return back to BASIC.

Within BASIC, you have the 1K at $400 to play with. Then 8K at $A000, that you can rolo-deck using BANK command. But it can get convoluted to manage your own multi-byte integers over to the 5-byte format BASIC uses. It might be nice if we could optionally have DIM allocations remapped over into the $A000 BANK area (it might need a new type like DIM@, but then it's just adjusting the POINTER that BASIC assigns in the DATA portion - might be do-able, but still some expert updates to the System ROM to pull it off - and not sure how much code space is left in the current ROM slot allocations).

For non-BASIC programs, you can BLOAD to $0400 and SYS $0400 - just you need to include the user documentation that explains this. Or, deliver your .PRG with the $400 header, so it works with LOAD - and the LOAD command does state the address it loaded into, but most users will just "RUN" out of habit. I suppose the System ROM could store down that "last LOAD address" (if 2-bytes somewhere in $0300 region available) and maybe RUN could have some argument, like "RUN,L" to basically SYS into whatever that last loaded address was (so your user-documentation then just explains "use RUN,L to start", instead of some "SYS XYZ" with XYZ being some address your program might change over time. Not sure if it's value-added enough to get the KERNAL folks to risk changing the ROM for it (because I can see various corner cases where that can be unstable, and again so many people are trained to just naturally issue a "RUN" with its existing behavior).


EDIT: In hindsight, with the VRAM changes, maybe the X16 system altogether could have moved to $0400 and given its BASIC that extra 1K - but that would have had to been decided early on, like 2019. I think early on, there was a concept/goal that the X16 might be able to load some existing CBM programs (VIC-20, C64, PET). Maybe there are a few cases where that's possible (since they stuck with $0801), but for the most part that didn't pan out.
Last edited by Xiphod on Thu Dec 12, 2024 10:17 pm, edited 2 times in total.
User avatar
desertfish
Posts: 1124
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

Re: Load address and C64 screen memory area

Post by desertfish »

cosmicr wrote: Thu Dec 12, 2024 5:59 am What do others do?
Prog8 has a switch that makes the program it generates put its variables into the $0400-$07ff region (golden ram).
This creates a program that can be loaded at $0801 normally, but still makes use of the $0400-$07ff region.
Problem could be that you won't be able to create large programs with many variables because you'll probably hit the 1kb variable space pretty soon.
User avatar
ahenry3068
Posts: 1197
Joined: Tue Apr 04, 2023 9:57 pm

Re: Load address and C64 screen memory area

Post by ahenry3068 »

voidstar wrote: Thu Dec 12, 2024 5:33 pm The only reason $801 is used is because the SAVE and RUN commands in BASIC (as coded in the ROM) chose to use that. Certainly, you can do your own custom ROM build (the code and build tools are available) to use something else. But as a community change, at this point it would probably break things more than it's worth (i.e. all the existing PRGs saved with the $801 header).

LOAD interprets the header content of the SAVEd PRG. So you'd just be modifying the behavior of SAVE to write in a different header. I don't think there is any override to the behavior of RUN. But to make it easier for end-user to just LOAD and RUN your program, non-BASIC programs borrow that startup convention, then JSR to their actual start point. The address space is (mostly) yours after that point, especially if you have no need to return back to BASIC.

Within BASIC, you have the 1K at $400 to play with. Then 8K at $A000, that you can rolo-deck using BANK command. But it can get convoluted to manage your own multi-byte integers over to the 5-byte format BASIC uses. It might be nice if we could optionally have DIM allocations remapped over into the $A000 BANK area (it might need a new type like DIM@, but then it's just adjusting the POINTER that BASIC assigns in the DATA portion - might be do-able, but still some expert updates to the System ROM).

For non-BASIC programs, you can BLOAD to $0400 and SYS $0400 - just you need to include the user documentation that explains this. Or, deliver your .PRG with the $400 header, so it works with LOAD - and the LOAD command does state the address it loaded into, but most users will just "RUN" out of habit. I suppose the System ROM could store down that "last LOAD address" (if 2-bytes somewhere in $0300 region available) and maybe RUN could have some argument, like "RUN,L" to basically SYS into whatever that last loaded address was (so your user-documentation then just explains "use RUN,L to start", instead of some "SYS XYZ" with XYZ being some address your program might change over time. Not sure if it's value-added enough to get the KERNAL folks to risk changing the ROM for it (because I can see various corner cases where that can be unstable, and again so many people are trained to just naturally issue a "RUN" with its existing behavior).


EDIT: In hindsight, with the VRAM changes, maybe the X16 system altogether could have moved to $0400 and given its BASIC that extra 1K - but that would have had to been decided early on, like 2019. I think early on, there was a concept/goal that the X16 might be able to load some existing CBM programs (VIC-20, C64, PET). Maybe there are a few cases where that's possible (since they stuck with $0801), but for the most part that didn't pan out.

FWIW: I have done some playing with BASIC and stored string data in the Hi-Ram area. You just have to poke the string data pointer in the variable descriptor in VARTAB. This has the added benefit that BASIC garbage collection will now ignore this string. If doing this your code must check that the correct BANK is set before accessing the string though.
Xiphod
Posts: 578
Joined: Thu Apr 15, 2021 8:05 am

Re: Load address and C64 screen memory area

Post by Xiphod »

For completeness, for those who haven't work with BASIC much - there is also a MEMTOP concept. I forget all the implementation details on the X16 (where MEMTOP is stored and all that, it's in the X16 Tech Docs stuff), but most BASIC implementations have a similar concept.

MEMTOP is used to tell BASIC you have less RAM than you physically/actually do. One reason for this is to help test to your code, to verify it can all work on an 8KB system instead of your full 32KB, as an example (since your data isn't allocated until the BASIC runtime encounters the variables).

But another real reason to do this is so you can "hide" programs just past your MEMTOP - or useful ML utilities and such. The ZSM kit uses this, it needs some code space to stream in portions of the audio file and feed the audio chip (or code to help manage the BANK changing to seamlessly support this). So, in this way you can use all the regular BASIC "look and feel" and make use of that software API. It's a little bit better than using addresses in the Golden RAM.

It's sort of like installing a TSR maybe in the old DOS-era, each one eating a little bit of conventional memory. But well behaved TSR's you could unload them and get that memory back without rebooting.

I wondered why BASIC doesn't have closer to a full 64KB when it reports FRE(.). It b/c it butts up against the I/O port addresses around $9000, which are followed by the BANKed RAM. But the 37K or so that we get on the X16 is pretty good (but it has to hold both the BASIC tokenized code and the data that gets initialized at runtime).

Was there recent news about prog8 could now handle large-allocations? It can do a disjoint address-space for a single declaration? Wasn't sure if I read that right (most of my systems don't have JDK, so I don't get to try out prog8 often enough)
Last edited by Xiphod on Fri Dec 13, 2024 3:45 am, edited 2 times in total.
User avatar
ahenry3068
Posts: 1197
Joined: Tue Apr 04, 2023 9:57 pm

Re: Load address and C64 screen memory area

Post by ahenry3068 »

voidstar wrote: Thu Dec 12, 2024 10:38 pm For completeness, for those who haven't work with BASIC much - there is also a MEMTOP concept. I forget all the implementation details on the X16 (where MEMTOP is stored and all that), but most BASIC implementations have a similar concept.

MEMTOP is used to tell BASIC you have less RAM than you physically/actually do. One reason for this is to help test to your code, to verify it can all work on an 8KB system instead of your full 32KB, as an example.

But another real reason to do this is so you can "hide" programs just past your MEMTOP - or useful ML utilities and such. The ZSM kit uses this, it needs some code space to stream in portions of the audio file and feed the audio chip (or code to help manage the BANK changing to seamlessly support this). So, in this way you can use all the regular BASIC "look and feel" and make use of that software API. It's a little bit better than using addresses in the Golden RAM.

It's sort of like installing a TSR maybe in the old DOS-era, each one eating a little bit of conventional memory. But well behaved TSR's you could unload them and get that memory back without rebooting.

I wondered why BASIC doesn't have closer to a full 64KB when it reports FRE(.). It butts up against the I/O port addresses around $9000, which are followed by the BANKed RAM.

Was there recent news about prog8 could now handle large-allocations? It can do a disjoint address-space for a single declaration? Wasn't sure if I read that right (most of my systems don't have JDK, so I don't get to try out prog8 often enough)

You don't need to know where MEMTOP is stored. There is a documented ROM API to set MEMTOP. MooingLemur's ZSMKIT BASIC example illustrates the technique pretty simply.
Edmond D
Posts: 503
Joined: Thu Aug 19, 2021 1:42 am

Re: Load address and C64 screen memory area

Post by Edmond D »

ahenry3068 wrote: Thu Dec 12, 2024 2:08 pm When programming in BASIC I mainly use this "Golden" ram to store small Machine language subroutines to "pep" up the BASIC code.
Is this the "pep you are referring to? :shock:
Attachments
CX16 Pep Screen Shot 2024-12-12 at 9.10.22 AM.png
CX16 Pep Screen Shot 2024-12-12 at 9.10.22 AM.png (65.93 KiB) Viewed 3721 times
User avatar
ahenry3068
Posts: 1197
Joined: Tue Apr 04, 2023 9:57 pm

Re: Load address and C64 screen memory area

Post by ahenry3068 »

Edmond D wrote: Thu Dec 12, 2024 11:55 pm
ahenry3068 wrote: Thu Dec 12, 2024 2:08 pm When programming in BASIC I mainly use this "Golden" ram to store small Machine language subroutines to "pep" up the BASIC code.
Is this the "pep you are referring to? :shock:
NO !!!

The First definition would do. !!!

Image
Post Reply