Jump to content
IGNORED

Intellivision Music Tracker Library


DZ-Jay

Recommended Posts

1 hour ago, carlsson said:

Regarding the envelope, it can also be extended with a 17th decle, or maybe the first one specifying speed could have the speed in the LSB and the jump index in the MSB. It would still break existing songs, but not invade the length of existing envelopes.

 

I think adding the jump offset in the MSB of the first word would work.  I do not think it would break anything because existing songs would have an MSB of zero (since the speed is constrained to 0..4), which would default to "no jump."  Any non-zero value in the MSB would be interpreted as a jump offset.

 

Alternatively, the "no jump" value could be treated as a flag to recycle the envelope, making it repeat itself over time; or silence the channel completely until the next note event.

 

What would happen is that newer songs wouldn't work with the old tracker.  But they do not work already, since this tracker changed the data format a bit to fix some drums limitations.

 

I'll have to see how costly this will be, since the position of the envelope is executed once per tick, per channel. Eek! ?

 

    -dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

There is another irregularity that I found in the tracker, that is bothering me.  This one manifests mostly as a side-effect of auto-conversion:  if the very last pattern ends with a non-zero volume note, and the sequence ends with the "stop song" terminator (TRK_END_SONG = $F000), then the last note is sustained forever after the tracker stops playing.

 

I'm cautious not to call these annoyances "bugs," because I think they are actual optimizations that depend on some reasonable assumptions.  In this case, it seems reasonable to expect that the last note to play on the last pattern would decay completely to silence before ending the song.  Under normal circumstances this is true; but when doing an auto-conversion from IBN, for instance, the IntyBASIC music player does silence the song at the end of a MUSIC STOP command, even if the last note was still playing; so there is no such assumption.

 

The test for the song terminator is done during the processing of patterns, which happens before updating the PSG.  At that point, if the end of the song is detected, the song pointer is cleared, but the rest of the data structure is not.  So any active notes will still be sent when updating the PSG right afterwards.  On the next tracker cycle, the cleared song pointer will cause the tracker to skip processing completely (as expected), leaving the PSG playing whatever was already in its registers.

 

To be sure, normally, this would work because the tracker initialization routine (TRKINIT) is called when the song terminator is detected, and if the current notes have been silenced, then the PSG is updated with silence.  Then, on the next cycle, the tracker will just not update because the song pointer had been cleared.

 

Ideally, the PSG should not be updated after resetting by TRKINIT, but that requires additional code (which is why I assume this was an optimization by Arnauld).

 

Obviously, I do not want to make the song terminator test more expensive, since it runs on every cycle.  The most obvious solution seems to be to have the subroutine that initializes the tracker and PSG (TRKINIT) also initialize the song data structure.  However, that responsibility is left to the subroutine that loads new songs (TRKSNGINIT).  This complicates matters a bit because we do not really want to load a new song.

 

It means a bit of refactoring of the initialization routines is in order.  Anybody else has any other ideas?

 

    -dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

OMG!  I came up with the cheesiest, yet most effective hack to patch this bug:  right before calling TRKINIT when the song end is detected, I change the return address of the current procedure to point to the end of the tracker processing, skipping completely the PSG updates.

 

From this:

;; ======================================================================== ;;
;;  TRKPATINIT    Pattern initialization                                    ;;
;; ======================================================================== ;;
TRKPATINIT      PROC
                MVI     _w_var(SONG),  R4
                INCR    R4                                  ; skip speed
                MVI@    R4,     R2                          ; R2 = address of 1st pattern
                ADDI    #2,     R4                          ; skip instruments and drums ptr
                MVI     _b_var(PAT),   R0                   ; R0 = position in patterns order table
                ADDR    R0,     R4

                MVI@    R4,     R1                          ; R1 = pattern number
                TSTR    R1
                BPL     @@pat_ok                            ; end of patterns ? ...

                ; ------------------------------------------
                ; Check if the song has ended
                ; ------------------------------------------
                CMPI    #TRK_END_SONG, R1                   ; ... yes : stop replay ?
                BEQ     TRKINIT

@@rewind        ADDR    R1,     R0                          ; ... no : jump to loop position ...
                ADDR    R1,     R4
                DECR    R4
                MVI@    R4,     R1                          ; ... and read again

                ; ...

 

We get this:

;; ======================================================================== ;;
;;  TRKPATINIT    Pattern initialization                                    ;;
;; ======================================================================== ;;
TRKPATINIT      PROC
                MVI     _w_var(SONG),  R4
                INCR    R4                                  ; skip speed
                MVI@    R4,     R2                          ; R2 = address of 1st pattern
                ADDI    #2,     R4                          ; skip instruments and drums ptr
                MVI     _b_var(PAT),   R0                   ; R0 = position in patterns order table
                ADDR    R0,     R4

                MVI@    R4,     R1                          ; R1 = pattern number
                TSTR    R1
                BPL     @@pat_ok                            ; end of patterns ? ...

                ; ------------------------------------------
                ; Check if the song has ended
                ; ------------------------------------------
                CMPI    #TRK_END_SONG, R1                   ; ... yes : stop replay ?
                BNEQ    @@rewind

                MVII    #TRKPLAY.done, R5                   ; NEAT HACK: Change the return address to bypass
                B       TRKINIT                             ;            PSG updates in TRKPLAY().

@@rewind        ADDR    R1,     R0                          ; ... no : jump to loop position ...
                ADDR    R1,     R4
                DECR    R4
                MVI@    R4,     R1                          ; ... and read again

 

The biggest cost is the switch from BEQ to BNEQ, which means that, for most times when the end of song is not found, the branch will be taken, which costs an additional two CPU cycles than just falling through as before.  This seems like a reasonable trade-off for what could have been a more expensive solution.

 

It's simple, it's elegant, it's cheap, and it's a hacky as hell!  What's not to like?  :)

 

     -dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

On 1/15/2021 at 10:52 AM, DZ-Jay said:

I found another issue ... well, more of a potential side-effect.  The tracker does not have any bounds-checking for envelopes, so when it reaches the end of the array, it just continues reading whatever follows (which could be another envelop, or anything else in the data stream).

 

At a glance, it appears that the tracker expects all envelopes to end at zero volume; because when the volume of a channel goes to zero, envelope processing automatically stops.

 

However, if you forget to end an envelope in zero (say, you were trying to make a long, sustaining envelope), then if the note lasts longer than the envelope, it will not work as intended.

 

Note that this only manifests in special circumstances, mostly  when the note is exceedingly long and the envelope is on its highest speed.

 

I am not sure if I should change this behaviour.  I could easily mask the upper bits of the counter to force the envelope to cycle, but I do not know if this is desirable at all.  It could be used for repeating envelopes, though, which are not supported right now and sounds like a useful feature to have.

 

What do you think?

 

     -dZ.

 

Just a quick update on this issue:  I thought of a quick and dirty work-around.  The key is that there are no actual bounds-checking for envelopes, so there is nothing that requires them to be just 64 points.  The only limitation is that the note length counter is stored in 8-bit memory, so you cannot exceed 256 points.

 

Therefore, when utilizing the new fastest envelope speed (4) (which updates on every tick), you can just make your envelope twice as long and avoid it running out early.  Simple. :)

 

I'll leave the envelope backtracking/jump-back feature for some other day.

 

     -dZ.

Link to comment
Share on other sites

Hello everyone,

 

I've updated the distro files on the first post to "revision #2."  This revision includes the following bug fixes and enhancements:

  • FIXED: Procedure TRKPATINIT now skips PSG updates completely when the end-of-song marker is detected.  This ensures that the tracker stays silent after the song ends, even if notes were still active.
  • FIXED: Macro NPK.Note() ignored all NUL events that start at the beginning of a new NPK sub-pattern definition.
  • FIXED: Macro NPK.Note() did not compact properly consecutive note events that use the same instrument.  Consequently the instrument definition is repeated for each one, wasting a 16-bit word of ROM space for each note.
  • NEW: Macro NPK.Note() now validates DRM event instruments to make sure they are non-zero.  (Drum instruments go from 1 to 127; a value of zero is invalid).
  • NEW: Updated the "Global Music" module with new instruments and drum samples.

 

I encourage anybody who's playing with the tracker to update to this latest version.  If anybody has any questions or encounters any problems, please let me know.

 

     -dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

By the way, I have an update on the IBN-to-IMT translator program:

 

It's now complete, fully documented, and works rather well.  I will be publishing it in the coming weeks, after I complete a couple of tracks I am preparing to go along with it.  If anybody wants to test it with their own projects, or needs help using the tracker, just let me know.

 

    -dZ.

Link to comment
Share on other sites

  • 3 weeks later...

Hello everyone,

 

I've updated the distro files on the first post to "revision #3."  This revision includes the following bug fixes and enhancements:

  • FIXED: Updated and re-factored IntyBASIC integration interface modules.
  • FIXED: Updated technical guide.
  • NEW: Added support for active channel state, to selectively enable playback channels based on channel priority.
  • NEW: Included new IBN-to-IMT utility program to convert IntyBASIC music files into the tracker format.

 

I encourage anybody who's playing with the tracker to update to this latest version.  If anybody has any questions or encounters any problems, please let me know.

 

The updated technical guide describes the new active channel state feature in comprehensive detail.

 

You can get the full details of the IBN-to-IMT tool from its dedicated thread.

 

     -dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hello everyone,

 

I've updated the distro files on the first post to "revision #4."  This revision includes the following enhancements and fixes:

  • NEW: Instrument envelopes now recycle indefinitely, by backtracking a number of sample points from the end. The backtracking offset is configurable with a global constant.
  • FIXED: Optimized the code for size and speed to compensate for additional code brought in by recent enhancements.
  • FIXED: Changed the behaviour of "NULL" events that include instrument changes, to reset the channel counter.  The old behaviour is believed to be a bug.
  • FIXED: Included the latest version of IBN-to-IMT utility program.

 

I encourage everyone who's download and played with the tracker to update to this latest version.  It includes a ton of optimizations for performance and storage.  I've also updated the user manual to cover the latest enhancements.

 

As always, feel free to ask any questions or provide any feedback -- including bug reports and feature requests! :)

 

     Enjoy!

       -dZ.

  • Like 3
Link to comment
Share on other sites

  • 4 months later...

*** WARNING! *** ACHTUNG! *** WARNING! *** ACHTUNG! ***

 

To anyone using the Intellivision Music Tracker (anyone? anyone? ... Bueller?), I just found two issues with the current Revision #4.

 

 

Quote

FIXED: Changed the behaviour of "NULL" events that include instrument changes, to reset the channel counter.  The old behaviour is believed to be a bug.

Your existing songs -- along with some of the sample songs included with the distribution -- may not handle the new behaviour correctly if they set an instrument number in NULL events that are intended to extend a playing note.

 

Doing so causes the channel counter to reset, which in turn causes the envelope of the instrument to restart.  This may not be the desired behaviour, especially if your intention was to extend the note in order to let it fade out towards release.

 

Quote

NEW: Instrument envelopes now recycle indefinitely, by backtracking a number of sample points from the end. The backtracking offset is configurable with a global constant.

This feature does not work correctly!  In fact, it broke the envelope altogether, except in speed 4 (fastest).  ?

 

I've already fixed this in the current development branch, which I will release as IMT version 1.6 in the near future, complete with the new effects feature.  However, if you are currently using the tracker in your project and need this fixed now, contact me directly for a quick patch.

 

     -dZ.

 

  • Like 1
Link to comment
Share on other sites

  • 7 months later...

A long-belated update:  I'm actively working on the Intellivision Music Tracker again, and will release a new version soon that will include support for classic tracker effects like portamento, channel fade-in and -out, pitch bending, etc.  It will also fix some latent bugs (including the one mentioned above on the envelope looping feature) and several optimizations.

 

In the meantime, enjoy this latest track I made, played on the Intellivision Music Tracker:

 

 

     -dZ.

Edited by DZ-Jay
Fixed link to video
  • Like 3
Link to comment
Share on other sites

23 minutes ago, DZ-Jay said:

A long-belated update:  I'm actively working on the Intellivision Music Tracker again, and will release a new version soon that will include support for classic tracker effects like portamento, channel fade-in and -out, pitch bending, etc.  It will also fix some latent bugs (including the one mentioned above on the envelope looping feature) and several optimizations.

 

In the meantime, enjoy this latest track I made, played on the Intellivision Music Tracker:

 

 

     -dZ.


Keep the hits coming. ?

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, First Spear said:

Would you be able to post the video again?

image.thumb.png.678fd346a3b3b7f2b7e54e22b79f310f.png

Done.

 

Sorry about that.  @Nyuundere's video had an issue with audio compression, so he took it down.  I'm uploading all new videos with all the remix tracks and will post a dedicated thread soon.  In the meantime, enjoy the one for Tainted Love Mastermix.

 

     -dZ.

  • Like 2
Link to comment
Share on other sites

Wow......that Intellivision version of Tainted Love is AWESOME!!!!   I'm going to have to use this too to make a song now.  I already have 2 I want to do that I think will sound great on Intellivision

 

I've been busy lately because I've been asked by my friend Karl to be a fill in bass player.  He runs a music studio and is always looking for players to mix in with his students because he hosts a lot of open mic nights for his students to get up and play live so they can learn better.  Apparently he has a shortage of reliable bass players.  This is going to be a great learning experience for me as well.

 

I'm playing 4 songs at a bar this weekend :

Jailbreak - AC/DC

Breaking the Law - Judas Priest

Ain't Talkin' Bout' Love  - Van Halen

Bark at the Moon -  Ozzy

 

As always, great work @DZ-Jay

 

 

Edited by Mik's Arcade
Link to comment
Share on other sites

1 minute ago, Mik's Arcade said:

Wow......that Intellivision version of Tainted Love is AWESOME!!!!   I'm going to have to use this too to make a song now.  I already have 2 I want to do that I think will sound great on Intellivision

Thanks.  Bear in mind that the Intellivision Music Tracker is so far a music player software library for Intellivision games, and not an actual "tracker," as commonly known, for recording music.  Unfortunately, you still need to compose the music song data, by hand, in an arcane format.  This is aided by some macros and a reasonable data structure layout, but it is still a lot of manual work.

 

1 minute ago, Mik's Arcade said:

I've been busy lately because I've been asked by my friend Karl to be a fill in bass player.  He runs a music studio and is always looking for players to mix in with his students because he hosts a lot of open mic nights for his students to get up and play live so they can learn better.  Apparently he has a shortage of reliable bass players.  This is going to be a great learning experience for me as well.

 

I'm playing 4 songs at a bar this weekend :

Jailbreak - AC/DC

Breaking the Law - Judas Priest

Ain't Talkin' Bout' Love  - Van Halen

Bark at the Moon -  Ozzy

Cool!  I hope you get some fans clapping and singing along. ?

1 minute ago, Mik's Arcade said:

As always, great work @DZ-Jay

 

Thanks again!

 

     -dZ.

Link to comment
Share on other sites

A quick update on the Intellivision Music Tracker progress: I started working again on the channel effects.  While I was working on the Sea Venture remixed tracks, I had some inspiration on how to improve on what I started working last.  The result is a new design that can maintain backwards compatibility with the previous versions, and add a bunch of new effects.

 

For the curious, below is the new effects data structure design, along with the list of effects that I plan to implement.  My goal is to implement a handful of the most useful ones first, like portamento and volume fades, and the rest I can add little by little as the library evolves.

 

=============================================================================================
DATA FORMAT:
=============================================================================================

Legacy instrument select and simple effects with a single parameter use a single data word:

                                  FX Record                  Simple FX Parameter
                        ,___________________________,   ,___________________________,
Stand-alone effect:    /                             \ /                             \
                      +---+---+---+---+---+---+---+---,---+---+---+---+---+---+---+---+
                      | C | X | E | E | E | E | E | E : P | P | P | P | P | P | P | P |
                      +---+---+---+---+---+---+---+---'---+---+---+---+---+---+---+---+
      Combo effect:    \_/ \_/ \____________________/     \______________________/
                        C   F         Command                    Instrument

            C: Combo Flag
            F: Effects Flag


Combo effects and effects that require more than one parameter use an additional data word:

                      +---+---+---+---+---+---+---+---,---+---+---+---+---+---+---+---+
      FX Parameter:   | - | - | - | - | - | - | - | - : y | y | y | y | x | x | x | x |
                      +---+---+---+---+---+---+---+---'---+---+---+---+---+---+---+---+
                       \_____________________________/ \_____________/ \_____________/
                                   Reserved              Parameter #2    Parameter #1


---------------------------------------------------------------------
                     EFFECT COMMAND & PARAMETERS:
---------------------------------------------------------------------

Effect Record:
    The "Effect Record" is a 8-bit value comprised of three fields:
        . Combo Flag:       1 bit
        . Effects Flag:     1 bit
        . Command Number:   6 bits

    The "Command Number" field affords up to 63 different effects, and
    the "Combo Flag" allows for the effect to be combined with an
    instrument select.

    The "Effects Flag" is a discriminator to disambiguate a zero
    "Effect record."  This allows us to distinguish between a stand-
    alone effect number "0" (Arpeggio) and a legacy instrument
    select.

    The effects follow the standard MOD and XM commands from
    FastTracker II.  Not all effects are currently implemented, and
    some will never be implemented due to platform limitations.  The
    available effects are:

        0: Arpeggio
        1: Portamento Up
        2: Portamento Down
        3: Portamento To Note
        4: Vibrato
        5: Portamento To Note With Volume Slide
        6: Vibrato With Volume Slide
        7: Tremolo
        8: -
        9: -
        A: Volume Slide
        B: Jump To Order
        C: -
        D: Pattern Break
        E: Sub-Commands:
            0: -
            1: Fine Portamento Up
            2: Fine Portamento Down
            3: -
            4: -
            5: -
            6: Pattern Loop
            7: -
            8: -
            9: Re-Trigger Note
            A: Fine Volume Slide Up
            B: Fine Volume Slide Down
            C: Note Cut
            D: Note Delay
            E: Pattern Delay
            F: -
        F: Set Song Speed
        G: Set Global Volume
        H: Global Volume Slide
        K: -
        L: Set Envelope Position

    A special Effect Record value of $000000 is reserved for backwards
    compatibility, and represents an instrument select with no
    effect.

    All effects take either one or two parameters, each one 4-bits
    long.  This is consistent with the traditional FT2 effects.

 

  • Like 1
Link to comment
Share on other sites

  • 2 years later...

@DZ-Jay
I think I will post my upcoming questions about IMT in this thread, since the other thread was mainly about an "editor" for the IMT format.

 

I am now able to convert Goat Tracker files to IMT file description. It works quite well in my test program, where I just load and play a song.

However, when putting the routines into my game (I use IntyBASIC), only the very first note is triggered and the tracker does not continue, even though I CALL TRKPLAY in every frame.

 

Does the tracker require the music to be in a specific region in memory? At the moment, all my data (cards, sprites, level, IMT music) starts at $E000 since otherwise I dont have enough memory for my code.

 

 

Link to comment
Share on other sites

41 minutes ago, Eiswuxe said:

@DZ-Jay
I think I will post my upcoming questions about IMT in this thread, since the other thread was mainly about an "editor" for the IMT format.

 

Yes, that is a good point.

 

41 minutes ago, Eiswuxe said:

I am now able to convert Goat Tracker files to IMT file description. It works quite well in my test program, where I just load and play a song.

 

Wow!  That is amazing.  I would be very interested in playing around with GoatTracker and your tool whenever we get all this sorted out.

 

41 minutes ago, Eiswuxe said:

However, when putting the routines into my game (I use IntyBASIC), only the very first note is triggered and the tracker does not continue, even though I CALL TRKPLAY in every frame.

 

Hmm ... That is strange.  Would you mind sharing your song file with me?  You can send it in a PM if you'd like and I can troubleshoot it.

 

41 minutes ago, Eiswuxe said:

Does the tracker require the music to be in a specific region in memory? At the moment, all my data (cards, sprites, level, IMT music) starts at $E000 since otherwise I dont have enough memory for my code.

 

The integration with IntyBASIC should be fairly straightforward, as described in the User's Guide (Appendix B):

  • Include "bas-interface.bas" at the top of your program.
  • Include your song file at the end of your program, with a handy IntyBASIC label preceding the song data so that you can reference it later from IntyBASIC.
  • Call TRKINIT() during your program's initialization phase.
  • Call TRKLOADSONG() with a pointer to your song data, to start song playback.
  • Call TRKPLAY() on every tick to update the playback state of the tracker.

The "bas-interface.bas" library should take care of everything, including RAM allocation and appropriate library module inclusions.

 

A few things to check, just in case:

  • Make sure you call TRKINIT() only once per program.  Calling it again will stop playback and reset the tracker.
  • Make sure you only call TRKLOADSONG() only once -- this loads the song and initializes the tracker for playback, so calling it again would just restart playback.
  • Make sure you are not writing to any of the variables used internally by the tracker.  These would be allocated as two arrays: TRK_BYTEVAR and #TRK_WORDVAR.
  • Check that your song data has the correct number of pattern tracks that match the number of tracks configured (3 or 6).
  • Check that all sub-pattern definitions used in a particular pattern match the length defined for that pattern.
  • Make sure the data format generated matches the IMT format, as described in the documentation.  (It may be easier to troubleshoot if your program generates IMT NOTES() macros rather than the raw data itself).

 

I hope the above helps.  If not, let me know.  IMT has been used successfully in IntyBASIC programs in the past (and integration was as simple as described above), so it should certainly work.

 

     -dZ.

Link to comment
Share on other sites

There is one more thing to try:  See if your program is blowing out of the available address space in its current segment.  It may be the case that your song data is being allocated outside the address space that is visible to the CPU, and thus fails to read data correctly.

 

If that were the case, you can add something like the following right before all your program data, which typically lies at the end of the program (i.e., outside the program execution flow).

ASM ORG $C040

 

Let me know if this helps or not.

 

    -dZ.

Link to comment
Share on other sites

1 hour ago, DZ-Jay said:

Let me know if this helps or not.

Thanks for the quick reply. Unfortunately, the result is the same. The note that I hear is indeed the very first note in the song.

 

Strangely, if I include the 

bas-interface.bas

At the very beginning of my program (after constants.bas), the game does not run at all.

 

Only if I include it directly before the song data, or before the "ASM ORG $C040", then the game runs (with the afforementioned bug)

Link to comment
Share on other sites

14 minutes ago, Eiswuxe said:

Thanks for the quick reply. Unfortunately, the result is the same. The note that I hear is indeed the very first note in the song.

 

Strangely, if I include the 

bas-interface.bas

At the very beginning of my program (after constants.bas), the game does not run at all.

 

Only if I include it directly before the song data, or before the "ASM ORG $C040", then the game runs (with the afforementioned bug)


I may have misspoken.  Let me check what is in the “bas-interface.bas” file.  It may not work at the top, if it includes code modules (I can’t remember right now).
 

If you do not mind sharing your code, I could try to troubleshoot it.  I’m rather handy with the assembler and debugger …

 

Maybe just the generated listing file from the assembler, or the song data itself.

 

I would understand if you rather not, but in that case it would be harder for me to know what is going on.

 

   dZ.

Link to comment
Share on other sites

On 4/19/2024 at 9:40 AM, DZ-Jay said:


I may have misspoken.  Let me check what is in the “bas-interface.bas” file.  It may not work at the top, if it includes code modules (I can’t remember right now).
 

If you do not mind sharing your code, I could try to troubleshoot it.  I’m rather handy with the assembler and debugger …

 

Maybe just the generated listing file from the assembler, or the song data itself.

 

I would understand if you rather not, but in that case it would be harder for me to know what is going on.

 

   dZ.

 

For the record, I misspoke about the "bas-interface.bas" file -- it needs to be included at the bottom of the program (i.e., outside of the program execution flow) because it includes the code library modules and data tables.

 

Here is an excerpt from my test driver to play the "TRON Anthology" track from IntyBASIC:

Spoiler
' =========================================================================
' IntyBASIC SDK Project: tron-remix-disco
' -------------------------------------------------------------------------
'     Title:      TRON Anthology (Disco Remix)
'     Programmer: James Pujals
'     Created:    2022-09-10
'     Updated:    2022-09-30
'
'     Project automatically generated by INTYNEW (SDK 1.2.3).
' -------------------------------------------------------------------------
' History:
' 2022-09-10 - tron-remix-disco project created.
' 2022-09-30 - Completed track.
    ' =========================================================================

OPTION WARNINGS
OPTION EXPLICIT

    INCLUDE "constants.bas"
    INCLUDE "metadata.bas"
    INCLUDE "title.bas"

    ' Set up a recurring task to update
    ' the tracker on every frame.
    ON FRAME GOSUB UpdateTracker

' =========================================================================
' Game Program
' =========================================================================

    ' INITIALIZATION:
    '   Initialize the tracker as part of your
    '   game initialization routine.
    CALL TRKINIT

    ' SET ACTIVE CHANNELS:
    '   At any point after initialization, you can
    '   set the number of active channels.  Values
    '   accepted are 1 through 6. The default is 6
    '   for all channels.
    CALL SET_ACTIVE_CHANNELS(6)

    ' LOAD & PLAY SONG:
    '   At any point after initialization, you may
    '   load a song ...
    '
    '   The routine TRKLOADSONG() is a special
    '   IntyBASIC interface that receives a pointer
    '   to the song data structure via R0.
    '
    '   The song will start playing immediately.
    CALL TRKLOADSONG(VARPTR TronAnthology(0))

' MAIN LOOP:
'   This is your main game loop.  It will loop forever
'   keeping your game program engaged.
' ----------------------------------------------------
MainLoop:
Goto MainLoop

' UPDATE TRACKER STATE:
'   The state of the tracker needs to be updated
'   once per frame, ideally at the same place
'   every time.  We use ON FRAME GOSUB in this
'   example, but all you really need to do is
'   invoke TRKPLAY at some point from your regular
'   game engine loop.
UpdateTracker: PROCEDURE
    CALL TRKPLAY
END

' =========================================================================
' Game Data
' =========================================================================

    ' Include the tracker IntyBASIC Interface library
    ' anywhere in your program, along with any other
    ' libraries you use.
    INCLUDE "lib/bas-interface.bas"

    ' INCLUDE SONGS:
    '   Include any songs to play in your program.
    '
    '   Song are still defined using assembler data
    '   structures and macros, and so must be loaded
    '   as assembly language modules.

    '   Include the standard global music definitions
    ASM INCLUDE "music/tron-drm.asm"
    ASM INCLUDE "music/tron-inst.asm"
    ASM INCLUDE "music/tron-pttr.asm"

    '   Include sample song.  Note that assigning a
    '   label before including the song allows us to
    '   address the structure using VARPTR when we
    '   load it.  Otherwise, we would have to dig up
    '   its actual address from the assembler's
    '   output LISTING file.
TronAnthology:
    ASM INCLUDE "music/tron-anthology.asm"

 

 

Notice that the tracker interface module for IntyBASIC is included at the bottom, followed by the instrument and song data (which could have been put in a single file, but I broke it up into separate modules).

 

As for code segment segregation, make sure that the "bas-interface.bas" file occurs within a single ROM segment.  The music data does not need to be all in the same segment, unless it is a single data block.

 

For reference, below are the most common ROM segments.  I intend to include a feature in the next version of the IntyBASIC SDK that will allow you to easily allocate code and data in ROM segments.

; --------------------------------------
; Memory map for 42K ROM cartridge
; --------------------------------------
;   SEGMENT     RANGE
;      0        $5000 - $6FFF :  8K
;      1        $A000 - $BFFF :  8K
;      2        $C040 - $FFFF : 16K
;      3        $2000 - $2FFF :  4K
;      4        $7000 - $7FFF :  4K
;      5        $4800 - $4FFF :  2K
;
;      CARTRAM  $8040 - $9EFF :  8K
; --------------------------------------

* K = Kilo-Decle (16-bit words), not Kilo-Byte (8-bit bytes)

 

Segment #0 is the default memory range that IntyBASIC uses.  You can see that the largest range is in segment #2.

 

     -dZ.

 

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