Jump to content
IGNORED

RMT sfx gets interrupted


Recommended Posts

Hello,

 

i am trying to make some sounds with RMT and when are played in emulator they do get messed up in various ways. Mostly are cut off when in middle or sounding quite different from original. I am using for tests slightly modified sfx test bundled with RMT. Any tips what might be a problem? Thanks.

Link to comment
Share on other sites

Thanks for help, got it working somehow but only on RMT sfx example. Get it running with my cc65 code will be another thing i guess. And it wasnt caused by improper emulation - real atari was giving wrong sound also.

Edited by clth
Link to comment
Share on other sites

Ok, spent two weeks trying figure this out and I am pretty much done. I have two cc65 projects with same relevant linker configuration options but failing to get this work.

 

On Irgendwers RMT example i got is everything ok but on my song and player data get weirdly misaligned. In case of RMT file its probably DOS header but with RMTplayr it makes no sense to me. MD5 sums of every used blob are correct ...

 

I've attached binary diff file, on 0x0100 should start RMT data and on 0x0700 player.

 

Any suggestion welcome, thanks.

dump.txt

Edited by clth
Link to comment
Share on other sites

Well judging by the diff the WRONG version has the DOS header, as you said. RMT module pointer needs to be on that RMT marker. That is considered start of the module. That has to be on the address specified in export (4000 by default).

RMT file is DOS file, so it does contain the header. Ie FFFF, start address, length, 6 bytes in total. In assembler you either use manual ORG and then skip 6 bytes when including the file.

Or you use 'opt h-' (in MADS) to end previous assembler generated segment, and include the file as is, with the header. That way it will simply treat the RMT file as new DOS file segment, and use the address from the header.

I have no idea how to do it correctly in CC65. But all you need is those 'RMT' marker bytes end up on the address specified in RMT export, and used when calling rmt_init.

 

Link to comment
Share on other sites

6 hours ago, R0ger said:

Well judging by the diff the WRONG version has the DOS header, as you said. RMT module pointer needs to be on that RMT marker. That is considered start of the module. That has to be on the address specified in export (4000 by default).

RMT file is DOS file, so it does contain the header. Ie FFFF, start address, length, 6 bytes in total. In assembler you either use manual ORG and then skip 6 bytes when including the file.

Or you use 'opt h-' (in MADS) to end previous assembler generated segment, and include the file as is, with the header. That way it will simply treat the RMT file as new DOS file segment, and use the address from the header.

I have no idea how to do it correctly in CC65. But all you need is those 'RMT' marker bytes end up on the address specified in RMT export, and used when calling rmt_init.

 

Yep, song file can be readjusted but still there is this strange corruption of memory even inside rmtplayr. Gotta check my linker config with working program and test every used linker directive.

 

17 minutes ago, baktra said:

Perhaps the source code of the Curse of the Lost Miner game can provide some guidance. It uses the ld65 and ca65 to incorporate RMT.

Indeed, actually yours culomin was my starting point with CC65 - thanks for providing source code :). It helped me alot but still linker stuff feels pretty much like rocket science. Will look into it definitely, thats a great tip.

Edited by clth
Link to comment
Share on other sites

2 hours ago, clth said:

Yep, song file can be readjusted but still there is this strange corruption of memory even inside rmtplayr. Gotta check my linker config with working program and test every used linker directive.

Then readjust it and send another diff, it's hard for me to see the differences like this. RMT player needs to be specifically aligned and I have no idea how to do it from CC65. Baktra on the other hands has lot of experience with that.

Link to comment
Share on other sites

Found it I guess.

 

My linker.cfg:

FEATURES {
    STARTADDRESS: default = $0d00;
}
SYMBOLS {
    __EXEHDR__:          type = import;
    __SYSTEM_CHECK__:    type = import;  # force inclusion of "system check" load chunk
    __AUTOSTART__:       type = import;  # force inclusion of autostart "trailer"    
    __STACKSIZE__:       type = weak, value = $0100; # 2k stack
    __STARTADDRESS__:    type = export, value = %S;
    __RESERVED_MEMORY__: type = weak, value = $0000;
}
MEMORY {
    ZP:         file = "", define = yes, start = $0082, size = $006B;
    HEADER:     file = %O,               start = $0000, size = $0002;
    
    DATA: file = "", define = yes, start = $0400, size = $0400;
    DATA2: file = "", define = yes, start = $0800, size = $0100;
    
    SYSCHKHDR:  file = %O,               start = $0000, size = $0004;
    SYSCHKCHNK: file = %O,               start = $2E00, size = $0300;
    SYSCHKTRL:  file = %O,               start = $0000, size = $0006;
    
    MAINHDR:    file = %O,               start = $0000, size = $0004;
    MAIN:       file = %O, define = yes, start = %S,    size = $6700;
    TRAILER:    file = %O,               start = $0000, size = $0006;    

    RMTSONGBUF: start = $7600, size = $0300, file = %O, define = yes;
    RMTPLAYERBUF: start = $7982, size = $08FE, file = %O, define =yes;
    
    DATA3: define = yes, start = 32768, size = 15136, file = %O;    
}

FILES {
    %O: format = atari;
}
FORMATS {
    atari: runad = start,
           initad = SYSCHKCHNK: __SYSTEM_CHECK__;
}
SEGMENTS {
    ZEROPAGE:  load = ZP,         type = zp;
    EXTZP:     load = ZP,         type = zp,                optional = yes;
    EXEHDR:    load = HEADER,     type = ro;
    
    DATA_LOWER:     load = DATA,         type = rw,  optional = yes;
    DATA_BUFFER:     load = DATA2,       type = rw,  optional = yes;
    
    SYSCHKHDR: load = SYSCHKHDR,  type = ro,                optional = yes;
    SYSCHK:    load = SYSCHKCHNK, type = rw,  define = yes, optional = yes;
    SYSCHKTRL: load = SYSCHKTRL,  type = ro,                optional = yes;
    MAINHDR:   load = MAINHDR,    type = ro;
    STARTUP:   load = MAIN,       type = ro,  define = yes;
    LOWBSS:    load = MAIN,       type = rw,                optional = yes;  # not zero initialized
    LOWCODE:   load = MAIN,       type = ro,  define = yes, optional = yes;
    ONCE:      load = MAIN,       type = ro,                optional = yes;
    CODE:      load = MAIN,       type = ro,  define = yes;
    RODATA:    load = MAIN,       type = ro;
    DATA:      load = MAIN,       type = rw;
    INIT:      load = MAIN,       type = rw,                optional = yes;
    BSS:       load = MAIN,       type = bss, define = yes;
    AUTOSTRT:  load = TRAILER,    type = ro;        
    
    RMTSONG:   load = RMTSONGBUF, type = rw, define = yes;
    RMTPLAYER: load = RMTPLAYERBUF, type = rw, define = yes;    
   
    ALL:   load = DATA3, type = rw, define= yes;

}
FEATURES {
    CONDES: type    = constructor,
            label   = __CONSTRUCTOR_TABLE__,
            count   = __CONSTRUCTOR_COUNT__,
            segment = ONCE;
    CONDES: type    = destructor,
            label   = __DESTRUCTOR_TABLE__,
            count   = __DESTRUCTOR_COUNT__,
            segment = RODATA;
    CONDES: type    = interruptor,
            label   = __INTERRUPTOR_TABLE__,
            count   = __INTERRUPTOR_COUNT__,
            segment = RODATA,
            import  = __CALLIRQ__;
}

Tricky is this part

FILES {
    %O: format = atari;
}
FORMATS {
    atari: runad = start,
           initad = SYSCHKCHNK: __SYSTEM_CHECK__;
}

When is present, it is possible for program to boot via XBIOS from ATR but RMT layout gets messed up.

 

After removing memory layout looks ok(though there is few bytes different in RMTplayr which i presume is caused by some sort selfmodifying code). However both resulting ATR and XEX are useless. There is XBIOS crash when booting from ATR and running standalone XEX ends up in some infinite loop( with empty MAIN func).

 

 

 

Edited by clth
Link to comment
Share on other sites

There is possible workaround - just dump player and song ram sections of working variant and load them as file into ram during start. Not nice but only functional one I've found so far.

Edited by clth
Link to comment
Share on other sites

It would be the best if you could post minimal code & compiled XEX. If it works with other examples but not in your code, then for sure there is somewhere a bug on your side. The information you posted currently at least for me is not enough to identify the cause of the problem (it can be in the music/sfx player, it can be in addresses (exported or not), it can be in the linked config, it can be in the RMT "features", it can be in the main program code). The best would be the whole build folder for such minimal example.

Link to comment
Share on other sites

Sorry, maybe i wasn't clear enough. There is no relation with my code at all, this is reproducible easily with some minimal program example. Both player binary, features and linker config(except that one part) are identical. Issue is definitely caused by linker directives FILES and FORMAT part I did outline. It is likely not bug at all, rather my misunderstanding of CC65 linker I guess.

 

There are two variants, both same code and player & song addresses.

 

Working one:

standalone XEX, no special linker directives

 

Not working one:

XEX with extra linker directives(which are needed for some reason to be run from ATR) bundled to ATR + xbios

 

Will post sample projects later though i dont really need to investigate this any further right now. Dumped ram sections are ugly but good enough for me.

 

 

Link to comment
Share on other sites

I just checked different configs I use and I never had those:

FILES {
    %O: format = atari;
}
FORMATS {
    atari: runad = start,
           initad = SYSCHKCHNK: __SYSTEM_CHECK__;
}

Are they needed? Also all SYSCHK* are optional and can be removed - they do some checks if you have enough memory.

 

I'd propose to check if you have enough space before the RMT player. It has some specific requirements:

 

;* 1. RMT player routine needs 19 itself reserved bytes in zero page (no accessed
;*    from any other routines) as well as cca 1KB of memory before the "PLAYER"
;*    address for frequency tables and functionary variables. It's:
;*      a) from PLAYER-$03c0 to PLAYER for stereo RMTplayer
;*    b) from PLAYER-$0320 to PLAYER for mono RMTplayer

Link to comment
Share on other sites

After all, it was really linker issue but different one than I thought.

 

When trying to make sample projects to upload here, i discovered that cause of misalignment was ALL segment(Although no clue why).

 

After making it optional and stopped bundling data inside during linking, it was possible to link RMT in normal way and also remove that mysterious FILES and FORMAT sections.

 

Thanks for help :)

  • Like 2
Link to comment
Share on other sites

4 hours ago, ilmenit said:

No problem. If you have any further questions, do not hesitate to ask ? Is it for Vaults of Nhyrmeth? Looking forward for progress with this game!

 

Yes, slowly getting somewhere :) By solving this, all tricky low level stuff should be done so I can concentrate more on actual game. Planning to release another two level demo in month with automapping, inventory and freely world placeable items.

Edited by clth
  • Like 1
Link to comment
Share on other sites

1 hour ago, clth said:

Yes, slowly getting somewhere :) By solving this, all tricky low level stuff should be done so I can concentrate more on actual game. Planning to release another two level demo in month with automapping, inventory and freely world placeable items.

Great to read! ? Looking forward for it.

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...