Jump to content
IGNORED

CC65 and "incbin"


Recommended Posts

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

Link to comment
Share on other sites

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 by Irgendwer
  • Like 2
Link to comment
Share on other sites

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 by Irgendwer
  • Thanks 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

...

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.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...