Jump to content
IGNORED

Help! add music format sap (mads)


Recommended Posts

Hi,

 

I'm trying to add a music file format to sap an assembly (mads) program follows

	ORG $2000
MUSIC
	INS "data/music.bin"

	ORG $3000
PLAYER
	INS "data/player.bin"

START
     lda #$70
     ldx #<MUSIC
     ldy #>MUSIC
     jsr PLAYER+3

and short file puzzlito.sap music and player, but does not work that I am doing wrong?

greetings

 

 

Puzzlito.zip

Edited by ascrnet
Link to comment
Share on other sites

SAP format files contain an ASCII header that you need to get rid of. It looks like this:

 

 

 

SAP
AUTHOR "<?>"
NAME "Puzzlito"
DATE "1988"
TYPE B
INIT 268F
PLAYER 206F
TIME 02:13.43 LOOP

After that, it is just an Atari object file with normal segment headers. You can use a tool like Preston Crow's binload to see the headers:

 

Binary file:  Puzzlito.bin
Puzzlito.bin:  Start:  1F1F     End:  258A      Length  066C
Puzzlito.bin:  Warning:  Block may overwrite area used by DOS
Puzzlito.bin:  Start:  268F     End:  26A2      Length  0014
Puzzlito.bin:  Start:  2700     End:  3223      Length  0B24

These segments include the music data and the player. They probably need to be left at the memory locations they are currently at.

 

So, here's one way to make the SAP into an executable:

 

    opt h-
    ins 'Puzzlito.bin'
    opt h+
    org $3F00
main
    jsr $268F
frame
    lda $14
    cmp:req $14
    jsr $206F
    jmp frame
    run main

puzzlito.zip

 

This tells XASM/MADS to put the binary content of Puzzlito.bin (Puzzlito.sap with the header removed) at the start of the executable. Then you can put your code anywhere where the music data and player don't reside. You just need to call the INIT address once and then repeatedly call the PLAYER address every frame.

 

It may be possible to relocate the music data and reassemble the player to another address but you'll have to figure out which segment the music is located in and dump that out as your "music.bin".

  • Like 1
Link to comment
Share on other sites

thank you very much, I see it was easier to add the entire file without headboard sap instead of chopping the file manually :-D

 

add it applies well for what I needed :grin:

        OPT H-
        INS "DATA/PUZZLITO.BIN"
        OPT H+
        ORG $3F00

VBD
        JSR $206F
	JMP $E462

START
        JSR $268F
	LDA #7
	LDX #>VBD
	LDY #<VBD
	JSR $E45C
.....
.....
.....
        RUN START 

Greetings

Edited by ascrnet
Link to comment
Share on other sites

  • 3 years later...

Hey Xuel,

Would you mind working your magic on the attached SAP file?

I can find the load addresses, but no idea where to find the init and frame addresses...

Thx in advance!

The SAP header gives the needed info:

 

SAP
AUTHOR "Merman (Andrew Fisher)"
NAME "Speednik (SID conversion)"
DATE "18/04/2017"
TYPE B
INIT 3950
PLAYER 3403

Call INIT once, then call PLAYER once per frame.

 

I plugged those into the simple player code that I showed before here:

 

speednik-test.zip

Link to comment
Share on other sites

Relocated to $F000:

 

speednik-reloc.zip

 

This was a bit of a challenge! There are a lot of hard-coded addresses in the song data and the player has some address constants.

 

In order to tackle it I made some modifications to my disassembler to automatically convert address constants into label expressions like "<addr" and ">addr" as appropriate. You just tell it where the high and low address bytes are and it does the rest.

 

For example, if you have a 16-bit address in two consecutive data bytes of the binary then it will automatically determine the address, assign it a label and use the label instead of the hard-coded constants:

 

before:
 
    dta $8B            ; 46FD: 8B
    dta $46            ; 46FE: 46
 
dis specification:

    address 46FD

after:
 
    dta <s2l468B               ; 46FD: 8B
    dta >s2l468B               ; 46FE: 46

It also handles addresses that are split into high-byte and low-byte tables. For example:

 

before:

    dta $18            ; 401A: 18
    dta $48            ; 401B: 48
    dta $78            ; 401C: 78
...

    dta $41            ; 403B: 41
    dta $41            ; 403C: 41
    dta $41            ; 403D: 41

dis specification: (high-byte table address, low-byte table address, table size)

    address 403B_401A+20

after:
 
    dta <s2l4118               ; 401A: 18
    dta <s2l4148               ; 401B: 48
    dta <s2l4178               ; 401C: 78
...

    dta >s2l4118               ; 403B: 41
    dta >s2l4148               ; 403C: 41
    dta >s2l4178               ; 403D: 41

It also handles any arbitrary separation between high and low bytes so it can handle code like this:

 

before:

    ldx #$00           ; 3952: A2 00
    ldy #$40           ; 3954: A0 40

dis specification:

    address 3955_3953

after:

    ldx <song          ; 3952: A2 00
    ldy >song          ; 3954: A0 40

It of course reuses any labels you've explicitly defined, so in the above example it used the user-defined label "song" instead of auto-generating a label.

 

I imagine there are other disassemblers that can do this but it was fun to implement myself.

Edited by Xuel
  • Like 2
Link to comment
Share on other sites

  • 2 months later...

Xuel, I have another question: In cases where I have an RMT (Raster Music Tracker) file, I can use RMT to output a stripped RMT file to an address of my choice. Is there a way to use RMT to ouput a SAP file at the address of my choice? (even if I load a relocated RMT stripped file, the SAP files are always output to the same address in the range 3000-4FFF).

Link to comment
Share on other sites

It doesn't look like the RMT Windows app supports this. Why do you want to relocate the SAP?

If you really need to do this, you can make your own SAP from a stripped RMT file. Instructions and example attached:

rmt-to-sap.zip

Basic steps:

1) Launch RMT
1a) Save stripped RMT file, e.g. sunset.rmt

1b) As your saving the stripped RMT file, copy the feature code into rmt_feat.a65

1c) Save SAP, e.g. sunset.sap
2) Create output.header by extracting the header from 1c)
3) Copy rmtplayr.a65 and comment out "PLAYER equ $5000" line
4) Create output.asm
This code places the stripped RMT, the player code and a short
init routine in memory at the desired locations.
5) Build output.obx, e.g. "make output.obx"
6) Look for "INIT" and "RMT_PLAY" address in output.lab
7) Modify output.header to match addresses from 6)
8) Build output.sap

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

Check out the MADS examples. There is a relocation macro included that allows to load an RMT module to whatever address you like. That's what I use all the time to not waste any space.

And the next version of WUDSN will also allow you to export SAP to CMC/RMT/what it was again (in the cases where it's possible, thanks to fox' asap routines).

  • Like 1
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...