twh/f2 Posted March 16, 2017 Share Posted March 16, 2017 Hi everbody, is somebody having an example how gfx/sound data can be included into a CC65 project? For instance I would have an RMT file and some DAT files for PMG gfx data. In Assembler I would use ".incbin" and the "org" directive. Both directives are for good reason not available in the C-source file. I think I would have to define some CC65 linker-configurations. But I can't find a good example for this. I'm not even sure if I still could use CL65? any hint welcome, thanks Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 16, 2017 Share Posted March 16, 2017 (edited) For instance I would have an RMT file and some DAT files for PMG gfx data. In Assembler I would use ".incbin" and the "org" directive. Both directives are for good reason not available in the C-source file. I think I would have to define some CC65 linker-configurations. But I can't find a good example for this. I'm not even sure if I still could use CL65? For general data you can use "xxd" or "bin2c" etc. to convert binary data into C source data. Use that in a source/include file. If you don't like to use an assembler stub you can do the same for the RMT player and song but have to provide "special" segments in a memory configuration which you supply to the linker. Use these segments via "#pragma data-name" in the source file and the linker will produce a complete build. (I'll submit a small test project to explain the usage soon here.) Edited March 16, 2017 by Irgendwer 2 Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 17, 2017 Share Posted March 17, 2017 (edited) Like promised, here the demo project (with executable inside): cc65_RMT_demo.zip I pretty sure it needs some explanation, so here we go: I've build a small bash build script, I'm sure windows users can adapt this or even use the new bash shell of Windows 10. It needs a "xasm-installation" to build the "rmtplayr.a65" which comes with RMT (in folder asm_src). It would be of course a better solution to port the source to ca65, but then you have to adapt the "rmt_feat.a65" include mechanism too. (Maybe when I create a full-fledged RMT cc65 library.) So these are the steps: RMT: Export your song in RMT as "stripped song file" and enter a target address matching to your cc65 memory configuration. Here I used $9D00 and "song.rmt" as file name. Save the features of the RMT export window output as "rmt_feat.a65" to the "RMTPLAYER" subdirectory of the project. Copy the "asm_src/rmtplayr.a65" to the "RMTPLAYER" subdirectory of the project. Adapt the "PLAYER equ" at line 33 according to your memory configuration (here $A500). Memory configuration: Here we use a kind of trick: The song as well as the xasm build of the player (rmtplayr.obx) are already valid Atari com file segments. So we don't need own headers but fully include the segments in the output file. Use e.g. the "ataricom" tool out of HiassofT's SIO tools to get the addresses of the player... >ataricom RMTPLAYER/rmtplayr.obx ataricom 0.30-151130 (c) 2008-2015 Matthias Reichl <hias@horus.com> block 1: a282-a2bf (bytes: 62, offset: 6) block 2: a300-a3bf (bytes: 192, offset: 72) block 3: a400-a8e1 (bytes: 1250, offset: 268) ...and song: > ataricom song.rmt ataricom 0.30-151130 (c) 2008-2015 Matthias Reichl <hias@horus.com> block 1: 9d00-a1ae (bytes: 1199, offset: 6) Please note that the player uses space before our target address $A500! Create segments in the memory configuration which are big enough to hold this data and put them into the output file: MEMORY { ZP: start = $0096, size = $0053, type = rw, define = yes; ... # RMT SONG $9D00 - $A1AE RMTSONGBUF: start = $9D00, size = $0500, file = %O; # RMT PLAYER $A282 - $A8E1, main at $A500 RMTPLAYERBUF: start = $A282, size = $0800, file = %O; ... } SEGMENTS { ZEROPAGE: load = ZP, type = zp; ... RMTSONG: load = RMTSONGBUF, type = rw, define = yes; RMTPLAYER: load = RMTPLAYERBUF, type = rw, define = yes; ... } ... Please be aware that you have to reduce the zero page space, as RMT occupies also space here! The build script now transforms the binary data in to C-source data via use of xxd. Important: xxd creates an additional length parameter after the data, which would destroy the match of the file header information and the following data in respect of segment occupation, so delete this last line. The script does that automatically by using the "head"-command. Finally put the data in the matching memory segments in the C-source file: ... #pragma data-name (push, "RMTSONG") #include "song.h" #pragma data-name (pop) #pragma data-name (push, "RMTPLAYER") #include "rmtplayr.h" #pragma data-name (pop) ... Knowing the location you can call now the RMT routines. (Inspect C-source for that and how I call the player every 50th second without VBI.) It's a little bit more complicated than it should, as there are currently no library functions for RMT - but at least it works... Edited March 17, 2017 by Irgendwer 1 Quote Link to comment Share on other sites More sharing options...
baktra Posted March 17, 2017 Share Posted March 17, 2017 An example where LD65 is completely exhausted is the Curse of the Lost Miner game. The game uses RMT for SFX and music. RMT song files are binary load files that must be loaded to a designated address. That complicates things, but not much. Get full source code of the game here See also this thread to even get a presentation on this topic. Quote Link to comment Share on other sites More sharing options...
twh/f2 Posted March 17, 2017 Author Share Posted March 17, 2017 Hi Irgendwer, Hi Baktra, thank you very much!! It's the quick start I was looking for. I have an Assembler project which was a conversion of an Atari2600 game. After the birth of my son and the break of the project, I have no chance anymore to understand my very own Assembler code I think I stopped it when I was about to implement Enemy AI. Something which is no fun in low level ASM syntax and grown cryptic codebase. Because everything (sound, gfx, screens, pmgs, etc.) is finished I thought about reprogramming the game again - but this time using CC65. Now I have a good starting point. thanks again! \thomas 1 Quote Link to comment Share on other sites More sharing options...
ilmenit Posted March 19, 2017 Share Posted March 19, 2017 Hi, In my games in CC65 (His Dark Majesty, The Hunt) I usually use different method - everything address related is put below START_ADDRESS. The Hunt's source code is here. regards, Jakub 1 Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted March 24, 2017 Share Posted March 24, 2017 ... MEMORY { ZP: start = $0096, size = $0053, type = rw, define = yes; ... ... is wrong. RMT occupies ZP up from $CB in default case, so "size =$0035" would be correct (dec != hex ) here. But more worse my inline assembler for RMTInit was wrong/incomplete (as twh/f2 painfully discovered). Here the correct version: #define RMTInit __asm__("lda #0"); \ <-This is for the song line to start with, could be of course also a variable __asm__("ldx #(<%v)", RMTSong); \ __asm__("ldy #(>%v)", RMTSong); \ __asm__("jsr %w", RMTPlayer); Sorry for any inconvenience. 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.