-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C64: Memory location for custom character set? #806
Comments
i would put it at the start or the end of the memory. ie either $0800 or below i/o or kernal (somehwhere after $d000, this will require relocating the screen too). both will require custom linker config and possibly a modified crt0/startup code. |
On 2018-11-28, at 21:15, Martin Emrich ***@***.***> wrote:
Hello!
I'd like to define a custom character set. As this works by copying the Character ROM to RAM and switching around VIC banks and offsets, I need a free memory block at a correctly aligned position.
Ideally, the location would be defined at compile/link time.
Some Ideas I had:
• Instruct compiler/Linker to ignore e.g. 0x3800-0x3fff?
• Somehow declare a global unsigned char charset[0x0800] with a fixed memory address?
Is there a way?
Yes. Read the documentation on custom linker configuration files. That's how such things are done with cc65.
|
How could this work? C64 progs start at $0801 by default, if you want a BASIC SYSxxxx starter, unless you load them with ,8,1 (and then type SYS<entry_pt>. |
@silverdr Thanks, that seems to be what I need. Took quite some trial and error.
(left the FEATURES as-is). @mrdudz I decided to steal 4k from between the MAIN and HIMEM thing. Fiddling around at 0x800 just gave crashes, and after 0xD000 is only I/O and KERNAL, I guess cc65 runtime needs them? A little test program seems to run fine, but it would be great if an expert proof-read that my modified configuration is valid. (I have no idea what a BSS or bss is...) Thanks, Martin |
easy, just use some packer on the resulting binary - which you likely want to do anyway. adding "basic starters" to non packed binary isnt a great idea to begin with, its just a waste of bytes :) (this whole discussion once again shows that before using cc65 its a good idea to understand the target and write a bunch of assembler programs) |
there is RAM under I/O and "under" kernal (at the same address, in a different memory configuration), its a perfect location for graphics data. as said, you'd have to relocate the screen to then. (and yet again, it helps to understand the platform) |
I don't see how that would work with a "standard" cc65 C64 which was compiled with "
I disagree. Such a program would be the typical output of a cc65 invocation as I've written above. You can add a packer if you want, but I don't consider that as crucial. To each his own....
I've written quite some assembler programs for C64 30 years ago. So I'm considering myself semi-knowlegeable (or make that semi-semi-knowledgeable, given that I haven't done much C64 related stuff the last 30 years....) |
of course it doesnt. you'll push the low memory boundary to $1000. obviously. every solution for this problem needs a custom linker config...
that doesnt make the statement less valid. in a typical c64 build chain the binary is pretty much always packed in the last step. putting a basic starter into the non packet binary is a pointless exercise in that situation. and $800 is infact a pretty common location for a characterset too :) |
@mrdudz: From the OP's question I cannot infer that he's writing an ASM Program. All what you are saying makes sense to me (except that a final EXE "needs" to be packed). IDK right now if it's currently possible (without much fiddling) to create a cc65 C EXE which starts at e.g. $1000 and doesn't contain the BASIC loader. So I guess, we started from different positions. I was thinking of a C program which which gets compiled with default options with cc65, while you were starting from an already advanced setup where defaults were changed (no BASIC loader). That the linker cfg file needs to be changed is obvious. |
i dont get your point. just read my first answer, its all there. adding a custom charset to a cc65 program required fiddling, no matter how you do it. and you cant do it with default options (because that implies default linkerscript). and no, the exe doesnt "need" to be packed. however in practise you almost always want to do this anyway. and throwing the opportunity to have a charset at $800 away just so you can have a basic start in your non packed binary is just silly. the alternative is to put it at the memory top like in the posted config - now the binary will be really huge, and you want to pack it =) and it will require more fiddling because the screen needs to be relocated too. and as soon you want to add more gfx data, it will go under i/o - which results in a binary that you cant even load in non packed form. did i say you typically end up packing the binary? :=) that said, this linker config doesnt look right. you'll have to use fill=yes to the sections prior those you added so the screen/charset actually ends up at $c000/$c800. you also want to put bss and stack after MAIN and before VIDEO, else they will overwrite the charset/screen. i still recommend to put the charset to $800, that is actually easier and requires less fiddling. but yes, it will require to pack the resulting binary in order to run it. |
Yes. This answer is accurate. I've been just stumbling over the $800 address which is not possible with means out of the cc65 box. At least, to get a program which you can 'LOAD"xxx",8"' and then 'RUN' it. I agree that it makes more sense to put the charset to $800, and not to the end of the program. What I don't like is the need of a 3rd-party packer (or some kind of loader) to setup this memory layout. |
but why in heavens name? 99.999% of all programs made in the last decades are like that. its the norm. and adding yet another layer of moving things around just so you can have that silly basic starter only adds more useless unwanted overhead and makes the program longer than it has to be. and then when you actually pack this program - which you likely want to do anyway - all that overhead becomes even more useless and pointless. just dont. |
Yeah, maybe I'm a bit stubborn in this regard. I'd like to have cc65 be "self-contained", so it can create programs without external tools. This doesn't include tools which convert the EXE to a ROM image, or disk image. But the output of cc65 should be "the thing". Given that I'm not much into the C64 (or any CBM) scene these days, I don't want to argue much more about the issue at hand. If a 3rd-party tool is needed to create such a C64 image from a cc65 program, I'm fine with it. Maybe a documentation update could be done to explain this use case? :-) |
To be honest, for me it all boils down to "know the platform before using cc65". i'd even go as far as saying that if you dont master the platform already, you shouldnt be using cc65 - because most likely, for anything non trivial, you will run into problems that require you to know a lot of things about the platform that the cc65 docs do not, and should not, explain. |
Just to say, that's a nice theory, but sadly doesn't work in real-world :-( |
it does work. i frequently tell them to learn a bit of asm first and stay away from cc65 unless they know what they are doing. C on 8bit systems is not for beginners. period. |
OTOH, I'm always trying to get people into cc65, even beginners. It's not that hard, after all :-) |
It's a bad idea. Neither is cc65 a good platform to learn C, nor is it a good platform to learn programming any 8 bit computer. |
To learn C not, sure. But if anyone wants to write 6502 ASM programs (or learn how to do), ca65 is almost as good as anything else. The concept of linker scripts is the most difficult part I guess. |
the concept of linkerscripts is actually what makes it a lot harder for beginners. traditional assemblers are much better suited for most things that beginners are doing. |
Agreed. |
FWIW - using an external packer is not required and should not be required (IMNSHO). Also you shouldn't have to know all the target's specifics to program something in C. Once you get to know all the more advanced stuff, you can start optimising things. But even then I stopped depending on packers the moment I started to use fast DOS (first Dolphin, then IDEDOS) as it's a pure waste of time to have things loaded in 1 - 2 seconds and then having to wait 15 for it to depack itself (sic!) before you can run it. Yes, if things need to be crunched to fit (e.g. the infamous 202 blocks) it's a different story or if you target audience that is most probably devoid of any fast DOS (who is this non-negligible audience of this kind today?), yes - then OK, but not when you just want to get your program compiled and running. As for linker configs - yes, it's tricky for users who got used to classic assemblers with no proper linker. But if you begin learning, you can jump right into it and never look back once you get to know how these work. I don't know how is this harder than learning bad habits with no-linker-tools. |
it will hardly take a second or two using the right tools for the job. and its still stupid to use 202 blocks on disk only because you have put the charset to $c800. and no, it doesnt have anything to do with bad habits. while the linker is really great for certain situations, for typical small projects like beginners are making its not only unnecessary, it also gets in the way a lot. i moved my demo stuff to acme myself after i made some demo things in ca65 and learned that the linker most of the time causes more hazzle than it solves. again, use the right tool for the job, there is no silver bullet. |
Definitely, if your program ends at $5000 and you fill the memory until $c800 in the output file. I guess nobody is arguing about that.
examples? |
You can pack it then :-P (SCNR :-)
Only if you already have some habits. For all the
Which basically says that you haven't got accustomed to the way things are to be written in cc65/ca65 and tried to carry-in the ways you learned elsewhere. Sorry - if there is only one feature that makes ca65 preferable over other tools of this kind, then it is the linker. <-- period. But you have to unlearn what you have learnt before you started with ca65. I know, I had to. Once you do though, then there is no way back.
Sure, if you look for example for some predefined demo-coding stuff then you may prefer e. g. KickAss or whatever gives you the best set of options but if we talk about efficient, generic 6502 programming then get proficient with the linker and stop saying the same things I kept stubbornly saying some good years ago when I first encountered linker configs in ca65 and kept returning to my earlier toolchain because I sincerely believed that the linker "caused more hazzle than it solves" ;-) |
Although the OP didn't ask for that it might have been beneficial to add the hint in the first place that instead of jumping through loops to have the charset at the right place after loading (and potentially unpacking) one might as well consider to memcpy() it to the right place - obviously with the knowledge that this place isn't used by the program for other purposes. |
I heartily disagree. If I had to chose a single aspect of cc65 that I consider most relevant then it would be for sure that it allows to create significant stuff for targets you don't know because of all the target knowledge distilled into the target libraries. E.g. I some day stumbled over http://www.atari8ethernet.com/. I figured out the CS8900A was mapped at $D500. So I built Contiki for the Atari. I had never done anything whatsoever with or for that machine before. It took me a few hours, of which most were spend figuring out how to create an .ATR disk image containing the binaries. I sent it to Mark and the binaries worked out-of-the-box. I guess you can imagine how surprised he was to get the by far most interesting programs for his hardware from somebody not knowing the platform - not even talking about having his hardware (and there was no emulation of that hardware available by then). In these scenarios cc65 doesn't just simplify or expedite projects like yet another even more overfeatured assembler. It brings projects to the world which just wouldn't exist without it - that's what I personally consider cool ! |
At least as far as I can see the last sentence isn't true. I seem to understand that having the font data at $C800 is aviable option. So one can...
|
At least according to my understanding there's also no need for a custom linker config when the goal is to produce a binary without the BASIC SYS line (and a non-default start addr):
BTW: The Apple II linker config has the very same type of flexibility (using the same names). The only difference is that I created doceumentation for it (https://cc65.github.io/doc/apple2.html#ss4.1) while nobody cared enough to do the same for the C64 - although the C64 is generally perceived as the prime cc65 target... |
that would be a bit much to tell here. however there are various situations when you have to eg put certain data - or even code - to specific places in memory and then carefully craft the rest of the program and data around it. this stuff can get confusing quickly, and having the memory placement in a linker config doesnt really help (you have to do all the placement manually anyway).
nonsense. i am using the linker extensively in other projects (eg the chameleon menu system) and i really wouldnt want to do this stuff without a linker. as said, its not about habits, its about the right tool for the job.
we have different approaches to this for sure. i am not very interested in generic textmode applications, or graphics output so slow its unuseable for anything half serious for that matter. this was different 10 years ago when i played with cc65 first, but it became boring quickly :)
ca65 looks overfeatured compared to the assembler i am using now (acme) :=) that said, i'd really like to see one of those non fiddly solutions for the original problem now :) preferably without sacrificing any other cc65 features (keep conio working, and the mouse drivers, etc). i still say $800 is the way to go =P |
I agree with that one - the question of C64 custom font support has definitively appeared often enough to deserve an out-of-the-box solution suitable for beginners - and as mentioned without breaking stuff. |
Great scott, what happened here? What did I start here? :) Just to give my opinion here as the (beginner to intermediate) target audience(?): I just wanted to code some stuff for my C64 to play around with my new User Port WiFi modem, and I saw 3 options:
And I found cc65, and as a C/C++/Java/Whatever dev, I found myself right at home, and got results fast, also thanks to the serial driver framework, conio and the familiar POSIX C library functions. And indeed, unless I have to, I do not want to dive into platform specifics more than necessary. I now had to do it for the fonts, and (hopefully) got them working. Just my 0.02€ @oliverschmidt A ootb library would indeed be great. I got conio working so far by setting 0x00D1 to the new video memory address 0xC000. |
@MartinEmrich: Thanks for your detailed feedback. It's appreciated :-) |
Hello!
I'd like to define a custom character set. As this works by copying the Character ROM to RAM and switching around VIC banks and offsets, I need a free memory block at a correctly aligned position.
Ideally, the location would be defined at compile/link time.
Some Ideas I had:
unsigned char charset[0x0800]
with a fixed memory address?Is there a way?
Thanks
Martin
/label Question
The text was updated successfully, but these errors were encountered: