sanny Posted April 25, 2019 Share Posted April 25, 2019 CC65 however looks to be clever enough to not only spot and warn of this, but consolidate them into one - so presumably it knows they are also identical. Hmm. Don't know. Don't know if it knows. Better would be to throw an error instead of just a warning. Need to check... Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 25, 2019 Share Posted April 25, 2019 (edited) Surprised me too, using a Visual Studio command line compiler: >cl main_bad.c math1.c math2.c Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64 Copyright (C) Microsoft Corporation. All rights reserved. main_bad.c math1.c math2.c Generating Code... Microsoft (R) Incremental Linker Version 11.00.60610.1 Copyright (C) Microsoft Corporation. All rights reserved. /out:main_bad.exe main_bad.obj math1.obj math2.obj math1.obj : error LNK2005: MyMath already defined in main_bad.obj math2.obj : error LNK2005: MyMath already defined in main_bad.obj main_bad.exe : fatal error LNK1169: one or more multiply defined symbols found whereas cc65 reports: >cl65 -t atari -O main_bad.s math1.s math2.s -o bad.xex -LC:\cc65\lib ld65.exe: Warning: Duplicate external identifier: '_MyMath' ld65.exe: Warning: Duplicate external identifier: '_MyMath' Edited April 25, 2019 by Wrathchild Quote Link to comment Share on other sites More sharing options...
baktra Posted April 25, 2019 Share Posted April 25, 2019 I applaud you guys using C on these 6502 machines. It seems so much harder than pure asm to me, but I guess it's all what you get used to. I've been coding in C# full-time for 13 years now, did a little C / C++ before that. On my Atari though, it was BASIC then ASM. It's hard for me to go back to these old BASIC dialects with no structure after all this time of everything being object oriented, etc. Super hard to fight the limitations of C on these old machines too. It is not that difficult to use the C programming language. What is "difficult" is to incorporate data (PMGs, DLISTs, charsets, music) to the atari binary load files. LD65 provides very, very generalized means to do so (because it supports multiple targets, not just 8-bit Atari), therefore it has a steep learning curve. But once you master it, it is very powerful. With C preprocessor (for conditional compilation) and multiple linker .cfg files you can easily make cartridge, tape image, and binary load file from a single source. 1 Quote Link to comment Share on other sites More sharing options...
Yaron Nir Posted April 25, 2019 Author Share Posted April 25, 2019 is there a difference and what is the prefferred method between: 1. using the cfg file (MEMORY/SEGMENTS) to fix memory addresses OR 2. use explicity code to fix the address such as: #define PMGMEM (0x2000) is there a difference between the 2 , if so what is and what is best practice? Quote Link to comment Share on other sites More sharing options...
Yaron Nir Posted April 25, 2019 Author Share Posted April 25, 2019 (edited) Here's my own cleanup (allergic to code in header files, that's ok for c++) and in incorporates the defining your segments in a separate asm file. @sanny, yes, I was ok with the SYSCHKCHNK as the sprite-mem clearing would handle that. Wrathchild, this example works perfectly! also i've examined the memory locations and everything seems to be in place! many many thanks. small comment though: 1. In your defined display list, you left out the last command DL_JMP (is that intentionally?) i saw later on in the code you put the address of DL in the last 2 array bytes so ignore this, 2. if i would not want to use the segments.s file you've created, i could simple use the #pragma data-name directive . correct? Edited April 25, 2019 by Yaron Nir Quote Link to comment Share on other sites More sharing options...
sanny Posted April 25, 2019 Share Posted April 25, 2019 (edited) is there a difference and what is the prefferred method between: 1. using the cfg file (MEMORY/SEGMENTS) to fix memory addresses OR 2. use explicity code to fix the address such as: #define PMGMEM (0x2000) is there a difference between the 2 , if so what is and what is best practice? If you are accessing the memory area only with memcpy() it doesn't matter. If you are accessing single bytes, 1) gives better code. Because the symbol is absolute, and in case 2) you need a pointer. Compare 1) pmgmem[123]=4 and 2) *(unsigned char *)(PMGMEM + 123) = 4; For a "real" program I'm using 1), for a quick test program I'm using 2) most of the time. Edited April 25, 2019 by sanny Quote Link to comment Share on other sites More sharing options...
sanny Posted April 25, 2019 Share Posted April 25, 2019 2. if i would not want to use the segments.s file you've created, i could simple use the #pragma data-name directive . correct? If you put uninitialized data into those segments you have to use #pragma bss-name. But why wouldn't you want to use the segments.s file? Quote Link to comment Share on other sites More sharing options...
Yaron Nir Posted April 25, 2019 Author Share Posted April 25, 2019 Well, thought to leave out external files as much as I can but thats ok... can work with the asm file as well Tnx sanny Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 25, 2019 Share Posted April 25, 2019 Hi, is there a difference and what is the prefferred method between: 1. using the cfg file (MEMORY/SEGMENTS) to fix memory addresses OR 2. use explicity code to fix the address such as: #define PMGMEM (0x2000) is there a difference between the 2 , if so what is and what is best practice? Preference is to roll your own config and use MEMORY & SEGMENTS, especially if you are providing data/code in those segments as it can offer some protection, e.g. in regard to exceeding the size Similar to sanny, I'm happy using the #define approach to do quick tests. Once disadvantage of course with that is that because it is a straight substitution at compile time, you lose the use of a name in the exports. Also I'd tend to add the casting to the define, e.g. #define PMGMEM ((unsigned char *)0x2000) Wrathchild, this example works perfectly! also i've examined the memory locations and everything seems to be in place! many many thanks. small comment though: 1. In your defined display list, you left out the last command DL_JMP (is that intentionally?) i saw later on in the code you put the address of DL in the last 2 array bytes so ignore this, 2. if i would not want to use the segments.s file you've created, i could simple use the #pragma data-name directive . correct? 1) As per posts #7 and #8 here, the DL_JMP would not be reached.2) Why do you consider it an external file, it is a legitimate source file that is part of the solution? If you wanted you could replace it with a segments.c that just included the #pragma blocks for each of your segments. Technically then you could have a segments.h that the other C files could include and move the extern's for the block there. Quote Link to comment Share on other sites More sharing options...
Yaron Nir Posted April 25, 2019 Author Share Posted April 25, 2019 Agree wrathchild, thank you. Quote Link to comment Share on other sites More sharing options...
Gibstov Posted April 17, 2021 Share Posted April 17, 2021 Sorry to bump this topic, but I have a question about CC65 config files and didn't want to create a new topic. If all I want to do is change the starting address for an application, can I just copy the current Atari.cfg and change the starting address there. Or is there more to it. When I created a config file for my game Adventure Ponies, since it was a game, I really didn't care about playing nice with other application because it was going to use pretty all the system resources anyway. My new project is an application, so I want to make sure I am playing nice with other applications and things like APPMHI will be set correctly by CC65, or will I have to do that manually? Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 17, 2021 Share Posted April 17, 2021 1 hour ago, Gibstov said: If all I want to do is change the starting address for an application You should be able to do this with along the lines of: cl65 -t atari --start-addr 0x3000 -o test.xex test.c Quote Link to comment Share on other sites More sharing options...
Gibstov Posted April 17, 2021 Share Posted April 17, 2021 1 minute ago, Wrathchild said: You should be able to do this with along the lines of: cl65 -t atari --start-addr 0x3000 -o test.xex test.c Thanks. This is easier then messing with the cfg files. Quote Link to comment Share on other sites More sharing options...
baktra Posted April 25, 2021 Share Posted April 25, 2021 A nasty thought about the complexity of the '.cfg' files. Imagine that you would need to do the same with let us say GNU Linker - placing data to absolute addresses, aligning segments to 1-KB boundaries, placing variables to precisely defined memory areas, including one ELF file in another (when you include e.g. RMT music), bank-switching ROMs, compiling to RAM, but storing in ROM. Your build script would be flooded with very complex command lines too. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.