kensu Posted March 16, 2013 Share Posted March 16, 2013 (edited) Greetings, I've just started working with programming the Atari 8-bit, and recently was attempting to convert thisBASIC program from the Atari Graphics and Arcade Game Design book into c. Here is my attempt (some of the magic numbers (SAVMSC is defined in the header file as a pointer to memory location 88) int main() { char * screen; char char_buffer[1]; char screen_buffer[11]; unsigned char * nmemtop; unsigned char * chrom; unsigned char * chram; unsigned char * charSelect; _graphics(2); screen = (char *) SAVMSC; nmemtop = PEEK(106)-4; chram = (int)nmemtop * 256; chrom = PEEK(756)*256; charSelect = PEEK(756); POKE(756,nmemtop); memcpy(chram,chrom,1024); POKE(756,nmemtop); strcpy(screen_buffer,"aaaaaaaaaa"); memcpy(screen,screen_buffer,10); while(1); return 0; } That causes the screen to look so: Could someone help me figure out what I'm doing wrong? Any help is greatly appreciated, I'd even weather some ribbing about using C instead of assembler. Edited March 16, 2013 by kensu Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted March 16, 2013 Share Posted March 16, 2013 I would check that your screen pointer and character pointer are correct. It seems that instead of writing to your screen (or modifying your char set as the case may be), it is instead modifying your display list, which is itself stored above screen memory whenever you do your GRAPHICS call. I also noticed you did your lowering of memtop after you did the graphics call. That is a no-no. I think you may need to lower MEMTOP before the GRAPHICS call for it to work properly, as it is done in the BASIC program. Quote Link to comment Share on other sites More sharing options...
kensu Posted March 17, 2013 Author Share Posted March 17, 2013 (edited) Well one problem was that I forgot that PEEK actually gives you the contents of the memory location and not the location. Perhaps I should lay off the psuedoBasic from now on.... See haven't gotten the thing working correctly yet, now it looks like this: int main() { char * screen; char char_buffer[1]; char screen_buffer[11]; unsigned char * nmemtop; unsigned char * chrom; unsigned char * chram; unsigned char * charSelect; POKE(106,(int)nmemtop); _graphics(0); screen = (char *) SAVMSC; nmemtop = (unsigned char *)106 - 4; chram = (int)nmemtop * 256; chrom = (unsigned char *)756; chrom *= 256; charSelect = (unsigned char *)756; POKE(756,nmemtop); memcpy(chram,chrom,1024); POKE(756,nmemtop); strcpy(screen_buffer,"aaaaaaaaaa"); memcpy(screen,screen_buffer,10); while(1); return 0; } Edited March 17, 2013 by kensu Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted March 17, 2013 Share Posted March 17, 2013 Actually, I REALLY hope you continue with pseudoBASIC. The 5200 needs a BASIC compiler to get more enthusiasts making games. If you could turn your work into a parser peeps could go pBASIC -> C -> ROM -> Order real cart from AtariAge Quote Link to comment Share on other sites More sharing options...
kenfused Posted March 17, 2013 Share Posted March 17, 2013 int main() { ... unsigned char * nmemtop; ... POKE(106,(int)nmemtop); ... nmemtop = (unsigned char *)106 - 4; ... } You are using nmemtop before you calculate it. --Ken Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 17, 2013 Share Posted March 17, 2013 (edited) 'MEMTOP' isn't of any use in cc65, because it is introduced by Basic. cc65's strength is to work with memory configurations where you can clearly layout your segments and take alignment restrictions (e.g. for fonts) into account. Plan your usage, make a memory configuration out of it and build with that. ATM you produce also a conflict with memory cc65 thinks it can occupy, while you're using it for font data. (Oops - just seen your using RAMTOP ($6A) not MEMTOP ($90) which is more useful, but my argument above is still valid, because the cc65 std. memory configuration is for machines with 48k.) Edited March 17, 2013 by Irgendwer Quote Link to comment Share on other sites More sharing options...
kensu Posted March 17, 2013 Author Share Posted March 17, 2013 Actually, I REALLY hope you continue with pseudoBASIC. The 5200 needs a BASIC compiler to get more enthusiasts making games. If you could turn your work into a parser peeps could go pBASIC -> C -> ROM -> Order real cart from AtariAge This already exists: http://kidsquid.99k.org/compilers/5200bas/5200bas.html Though for reasons beyond all know logic the programs have to be written in GWBasic and not Atari BASIC. o_O Quote Link to comment Share on other sites More sharing options...
kensu Posted March 18, 2013 Author Share Posted March 18, 2013 As a professional programmer, I should've known there was no point in taking the cargo cult route... So I've been able to figure out a lot of the "magic numbers" in the original BASIC code, but there are some parts which still elude me.... CHROM=PEEK(756)*256 CHRAM=NMEMTOP*256 What exactly does this do, and why do we want to start at 256 times NMEMTOP instead of at NMEMTOP, which should be the beginning of the chunk of memory we set aside? Again, since the location stored at 756 is the location of the character set, why are we setting the pointer at the value times 256? I noticed that NMEMTOP pointer arithmetic seems to have 1=1 page, wherease CHROM and CHRAM pointer arithmetic has 1=1 byte. Is that what the multiplication by 256 does? And could someone please please PLEASE post a C program which does the same thing as the BASIC program? I would be eternally grateful. Quote Link to comment Share on other sites More sharing options...
Synthpopalooza Posted March 18, 2013 Share Posted March 18, 2013 This might be of use: http://www.atariarchives.org/mapping/memorymap.php Scroll down to location 756. The key is, your character set HAS to begin on a page boundary, or it won't work. That means, a multiple of 256. Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 18, 2013 Share Posted March 18, 2013 (edited) And could someone please please PLEASE post a C program which does the same thing as the BASIC program? I would be eternally grateful. Ok, that's a motivation. Just execute 'Make' in the cmd shell. Please note: To make things easier, I didn't use an own memory configuration (which I would do normally!), but a 'waste alignment' to fulfil the requirement of the OS that a font has to start on a 1k boundary! Principle (alignment requirement (AR) = 1k here): Allocate size for object (1k for font) + AR -1. The aligned memory location is the starting address + AR-1 masked with the inverse AR. Using this, you 'waste' AR-1 bytes. Example: We need an even starting address (AR=2) for three bytes: char buffer[3+AR-1]; char* evenStartOfBuffer = (char*)((unsigned int)buffer)+AR-1 & 0xFFFE; Got it? FontSample.zip Edited March 18, 2013 by Irgendwer Quote Link to comment Share on other sites More sharing options...
kensu Posted March 18, 2013 Author Share Posted March 18, 2013 Thanks Irgendwer! However, when I try to compile this I get the following error: main.c(18): Error: Too many local variables o_O I didn't even know there was such an error. Anyone familiar with cc65 have a clue about this one? Quote Link to comment Share on other sites More sharing options...
kensu Posted March 19, 2013 Author Share Posted March 19, 2013 This seems to have fixed it: int main(void) { char* pcFontSpace; // perform 'waste'-alignment... char* pOwnFont; char* pOSFont = (char*)(PEEK(756) << ; // get OS-Font address // = (char*)(((unsigned int)pcFontSpace+FONTSIZE-1) & 0xFC00); // ...on 1k boundary pcFontSpace = malloc(FONTSIZE*2-1); pOwnFont = (unsigned int)pcFontSpace+FONTSIZE-1 & 0xFC00; memcpy(pOwnFont, pOSFont, FONTSIZE); memcpy(pOwnFont + 97*8, pFontPatch, sizeof(pFontPatch)); POKE(756, ((unsigned int)pOwnFont) >> ; puts("\n"); puts("ab"); puts("cd"); while(1); return 0; } I was also running into problems on Atari800Win because I had the memory set to 16K (since I was trying to write a program that could run on the 5200). Hopefully I can get it to work at 16K with a custom memory config file.... Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 19, 2013 Share Posted March 19, 2013 (edited) ... to fulfil the requirement of the OS that a font has to start on a 1k boundary! Sorry for that (obviously I was too tired). It is of course a requirement from the hardware. However, when I try to compile this I get the following error: main.c(18): Error: Too many local variables Strange (shoudn't happen) - which version are you using? (Unfortunately the maintainer of cc65 just resigned, so help might be harder to get now.) pcFontSpace = malloc(FONTSIZE*2-1); If you go the dynamic memory allocation way, you also could use directly int __fastcall__ posix_memalign (void** memptr, size_t alignment, size_t size); which does the same. Best solution is the memory config (which is also good to avoid fragmentation). I was also running into problems on Atari800Win because I had the memory set to 16K (since I was trying to write a program that could run on the 5200). Hopefully I can get it to work at 16K with a custom memory config file.... Think so. You definitely need an own configuration, since mem-low in the std. config is set to (AFAIR) $2E00 to let programs work with most DOSes. My 5200 knowledge is very limited, but for cartridges you have to tweak the configuration anyway. Edited March 19, 2013 by Irgendwer Quote Link to comment Share on other sites More sharing options...
danwinslow Posted March 19, 2013 Share Posted March 19, 2013 Irgendwer's point about config files is right on. CC65 is extremely powerful, but you have to know how to set up your memory configs, especially for targets like the 5200. My experience with the 'too many local variables' error relates to having too many bytes declared as 'local' ( ie., as a function local variable instead of declared outside of a function ). I think it has to do with CC65 putting these on the parameter stack instead of the heap, at any rate a fix is to move the declaration outside of the function. So instead of int foo( void ) { char big[1024]; } you'd do char big[1024]; int foo( void ) { } Quote Link to comment Share on other sites More sharing options...
kenfused Posted March 20, 2013 Share Posted March 20, 2013 (edited) Irgendwer's point about config files is right on. CC65 is extremely powerful, but you have to know how to set up your memory configs, especially for targets like the 5200. My experience with the 'too many local variables' error relates to having too many bytes declared as 'local' ( ie., as a function local variable instead of declared outside of a function ). I think it has to do with CC65 putting these on the parameter stack instead of the heap, at any rate a fix is to move the declaration outside of the function. So instead of int foo( void ) { char big[1024]; } you'd do char big[1024]; int foo( void ) { } You might also be able to declare it static within the function. Edited March 20, 2013 by kenfused Quote Link to comment Share on other sites More sharing options...
kensu Posted March 20, 2013 Author Share Posted March 20, 2013 Hmm, ran into an interesting problem when I set graphics mode 1 and 2. It switched to displaying the uppercase version of the letters instead of the pumpkin. I remember reading that the lower rez text modes don't have lowercase letters, so the computer displays them as uppercase letters in a different color. So I suspected this needed to be changed: memcpy(pOwnFont + 97*8, pFontPatch, sizeof(pFontPatch)); Where the magic number 97 is actually the location of "a" in the character set. So I changed this to 65, the location of "A". However, this didn't change anything. I'm assuming the other magic number 8 is to blame. I'm assuming this is 8 bytes, the size of a character. But don't all the screen modes use the same character set? I placed the _graphics(2) call right after all the variables are declared, if that helps. Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 20, 2013 Share Posted March 20, 2013 Where the magic number 97 is actually the location of "a" in the character set. So I changed this to 65, the location of "A". However, this didn't change anything. Yes, without doing a test, I think you problem is that you apply the change with ATASCII-offset calculation, while you have to take the internal one: ATASCII Internal Operation 0-31 64-95 +64 32-95 0-63 -32 96-127 same 128-159 192-223 +64 160-223 128-191 -32 224-255 same So 65 ('A') should be 33 internal offset. Lower case letters where the lucky case... Quote Link to comment Share on other sites More sharing options...
ilmenit Posted March 22, 2013 Share Posted March 22, 2013 (edited) Here is my sample CC65 game with changed characterset and music in RMT To compile it you probably need a newer atari.cfg file that can be generated by ld65. ViperSFX.zip Edited March 22, 2013 by ilmenit 3 Quote Link to comment Share on other sites More sharing options...
jdh Posted April 1, 2013 Share Posted April 1, 2013 Here is my sample CC65 game with changed characterset and music in RMT To compile it you probably need a newer atari.cfg file that can be generated by ld65. Useful stuff in there, thank you . Nice font, can I use the font in a small game I am working on? Quote Link to comment Share on other sites More sharing options...
ilmenit Posted April 3, 2013 Share Posted April 3, 2013 I don't remember well but the font was taken probably from this link: http://atarionline.pl/v01/index.php?subaction=showfull&id=1236639234&archive=&start_from=0&ucat=7&ct=poczatki Quote Link to comment Share on other sites More sharing options...
+Stephen Posted April 3, 2013 Share Posted April 3, 2013 Wow - how can there be so many fonts from a little 8 by 8 grid? Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted April 3, 2013 Share Posted April 3, 2013 Wow - how can there be so many fonts from a little 8 by 8 grid? If you think that's variety, how about the diverse fonts MrFish designed in a 4x8 grid (well, effectively 3x8) for The Last Word! 2 Quote Link to comment Share on other sites More sharing options...
jdh Posted April 11, 2013 Share Posted April 11, 2013 I don't remember well but the font was taken probably from this link: http://atarionline.p...t=7&ct=poczatki Wow, quite a resource, thank you 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.