GoatTracker: Difference between revisions

From Foenix F256 / Wildbits/K2 Wiki
Jump to navigationJump to search
 
Line 25: Line 25:
== 3. Pitch and Timing (Important) ==
== 3. Pitch and Timing (Important) ==


Pitch and playback speed are '''separate settings'''.
Pitch and playback speed are '''related but separate settings'''.


* Playback speed is controlled by PAL vs NTSC timing (50 Hz vs 60 Hz).
* '''Playback speed''' is controlled by PAL vs NTSC timing (50 Hz vs 60 Hz).
* Pitch is controlled by the A-4 tuning value.
* '''Pitch''' is controlled by the A-4 tuning value.


The F256K uses '''NTSC (60 Hz)''' timing.
The F256K uses '''NTSC (60 Hz)''' timing so Goattracker must be configured accordingly.


---
---
Line 59: Line 59:
* '''A-4 = 454 Hz'''
* '''A-4 = 454 Hz'''


Always start GoatTracker with:
When packing a song, always start GoatTracker with the correct tuning and the song loaded at startup:


<code>
<code>
Line 65: Line 65:
</code>
</code>


'''Important:''' <code>.sng</code> files store tuning. Loading after startup will overwrite the setting.
'''Important:''' <code>.sng</code> files store tuning. Loading after startup will overwrite the setting and result in an incorrectly tuned packed file.


---
---
Line 71: Line 71:
== 4. Packing the Song ==
== 4. Packing the Song ==


Songs must be packed into a self-playing binary.
Songs must be packed into a self-playing binary for use on the F256.


---
---
Line 79: Line 79:
* Press <code>F9</code> in GoatTracker.
* Press <code>F9</code> in GoatTracker.
* Ensure it was started with <code>-G454</code> and the song loaded.
* Ensure it was started with <code>-G454</code> and the song loaded.
The internal packer always uses the '''current tuning'''.


---
---
Line 109: Line 110:


* <code>-Wxx</code> sets the high byte only
* <code>-Wxx</code> sets the high byte only
** <code>-Wa0</code> = $A000
** Example:<code>-Wa0</code> = $A000
* <code>-Zxx</code> uses two bytes
* <code>-Zxx</code> specifies the '''starting zeropage address'''
** $80/$81 is tested and safe
** uses two bytes
** Avoid $F0–$FF (kernel use)
*** $80/$81 is tested and safe
* <code>-Wxx</code> and <code>-Zxx</code> are configurable
*** Avoid $F0–$FF (kernel use)
* <code>-Wxx</code> and <code>-Zxx</code> are configurable based on your program's memory layout.


---
---
Line 123: Line 125:
=== 5.1 Initialization ===
=== 5.1 Initialization ===


Call the init routine:
Call the music player's init routine once. It is located at the player load address <code>(-Wxx)</code>.


<code>
<code>
JSR $A000
JSR $A000   ; initialize song
</code>
</code>


Line 133: Line 135:
=== 5.2 Per-Frame Playback ===
=== 5.2 Per-Frame Playback ===


Call once per frame:
Call the playback routine '''once per frame''' (SOF / 60 Hz)'''.'''
 
* Playback routine address = <code>init + 3</code>


<code>
<code>
JSR $A003
JSR $A003   ; play song for this frame
</code>
</code>
Repeat this call every frame for continuous playback.


---
---
Line 143: Line 149:
== 6. Additional Notes ==
== 6. Additional Notes ==


* <code>-N</code> controls speed
* Pitch and speed are '''not the same''':
* <code>-Gxx</code> controls pitch
** <code>-N</code> controls speed
* Both are required
** <code>-Gxx</code> controls pitch
* The binary is C64-compatible
* GoatTracker adjusts pitch tables when switching PAL/NTSC, but '''manual A-4 correction is still required.'''
* Correct setup ensures compatibility
* The packed <code>.bin</code> file is unchanged between the C64 and the F256 - compatibility comes from correct timing, tuning, and memory placement.


---
---
Line 157: Line 163:
---
---


This example matches the configuration described in this wiki page:


* Player loaded at '''$A000''' (<code>-Wa0</code>)
* Player routine at '''$A003'''
* Zeropage usage at '''$80/$81''' (used internally by the player)
* NTSC / 60 Hz playback<br />
  ; ============================================================================
  ; ============================================================================
  ; music_min.asm - Minimal Music Player for Wildbits/K & /Jr
  ; music_min.asm - Minimal Music Player for Wildbits/K & /Jr
Line 235: Line 246:
== Cheat Sheet ==
== Cheat Sheet ==


=== Edit / Preview ===
=== Edit / Preview (NTSC, correct pitch) ===


<code>
<code>
Line 257: Line 268:
---
---


=== Playback ===
=== Playback in your program ===


<code>
<code>
Line 267: Line 278:
---
---


=== Tested Defaults ===
=== Tested Defaults for the F256 ===


* SID: $D400
* SID: $D400

Latest revision as of 23:45, 29 January 2026

Using GoatTracker to Create F256K SID Music

This guide explains how to use GoatTracker to compose SID music and generate a packed .bin file that plays correctly on the F256K / F256K2 FPGA SID.

This document focuses on SID-only usage (no PSG or other sound chips).

---

1. Getting GoatTracker

  • GoatTracker is available for Windows, macOS, and Linux.
  • Download page: https://cadaver.github.io/
  • The stereo version (useful for dual SIDs on F256K2) is available on SourceForge under the files tab.

---

2. Creating a Song

  1. Create and edit your song in GoatTracker as you would for a C64.
  2. Most instruments, effects, and patterns work correctly on the F256K FPGA SID.
  3. GoatTracker was tuned for real C64 hardware, so FPGA SIDs may sound slightly different.

---

3. Pitch and Timing (Important)

Pitch and playback speed are related but separate settings.

  • Playback speed is controlled by PAL vs NTSC timing (50 Hz vs 60 Hz).
  • Pitch is controlled by the A-4 tuning value.

The F256K uses NTSC (60 Hz) timing so Goattracker must be configured accordingly.

---

3.1 Editing and Previewing on Your Computer

When composing music on your computer, use NTSC timing and corrected pitch.

Recommended settings:

goattracker -N -G424 song.sng

  • -N — NTSC timing (60 Hz)
  • -G424 — Correct pitch for NTSC preview

This setting is for editing only.

---

3.2 Packing for Playback on the F256K

The F256K requires a different tuning to produce true 440 Hz pitch.

Tested value:

  • A-4 = 454 Hz

When packing a song, always start GoatTracker with the correct tuning and the song loaded at startup:

goattracker -G454 song.sng

Important: .sng files store tuning. Loading after startup will overwrite the setting and result in an incorrectly tuned packed file.

---

4. Packing the Song

Songs must be packed into a self-playing binary for use on the F256.

---

Option A: Internal Pack (F9)

  • Press F9 in GoatTracker.
  • Ensure it was started with -G454 and the song loaded.

The internal packer always uses the current tuning.

---

Option B: External Packer (GT2RELOC.EXE)

Recommended method.

Example command:

GT2RELOC song.sng song.bin -N -G454 -LD400 -Wa0 -Z80

---

Parameter Explanation

  • song.sng — Input song
  • song.bin — Output binary
  • -N — NTSC timing
  • -G454 — F256K tuning
  • -LD400 — SID base address
  • -Wa0 — Player load address ($A000)
  • -Z80 — Zeropage ($80/$81)

---

Notes

  • -Wxx sets the high byte only
    • Example:-Wa0 = $A000
  • -Zxx specifies the starting zeropage address
    • uses two bytes
      • $80/$81 is tested and safe
      • Avoid $F0–$FF (kernel use)
  • -Wxx and -Zxx are configurable based on your program's memory layout.

---

5. Playing the Music

---

5.1 Initialization

Call the music player's init routine once. It is located at the player load address (-Wxx).

JSR $A000  ; initialize song

---

5.2 Per-Frame Playback

Call the playback routine once per frame (SOF / 60 Hz).

  • Playback routine address = init + 3

JSR $A003  ; play song for this frame

Repeat this call every frame for continuous playback.

---

6. Additional Notes

  • Pitch and speed are not the same:
    • -N controls speed
    • -Gxx controls pitch
  • GoatTracker adjusts pitch tables when switching PAL/NTSC, but manual A-4 correction is still required.
  • The packed .bin file is unchanged between the C64 and the F256 - compatibility comes from correct timing, tuning, and memory placement.

---

Appendix: Minimal F256 SID Music Player Example

The following is a minimal working music player using kernel timers.

---

This example matches the configuration described in this wiki page:

  • Player loaded at $A000 (-Wa0)
  • Player routine at $A003
  • Zeropage usage at $80/$81 (used internally by the player)
  • NTSC / 60 Hz playback
; ============================================================================
; music_min.asm - Minimal Music Player for Wildbits/K & /Jr
; ============================================================================

   .cpu "65816"
   MMU_IO_CTRL = $01
   init_music = $A000
   play_music = init_music+3
   timer_cookie = $D0

*=$A0
   .dsection zp
   .cerror * > $AF, "Too many zero page variables"

   .include "api.asm"

   .section zp
   event: .dstruct kernel.event.event_t
   .send

*=$1000

start:
   stz MMU_IO_CTRL

   lda #<event
   sta kernel.args.events
   lda #>event
   sta kernel.args.events+1

   jsr init_music
   jsr SetTimer

loop:
   jsr handle_events
   bra loop

handle_events:
   lda kernel.args.events.pending
   bpl done_handle_events
   jsr kernel.NextEvent
   bcs done_handle_events
   jsr dispatch
   jmp handle_events

done_handle_events:
   rts

dispatch:
   lda event.type
   cmp #kernel.event.timer.EXPIRED
   beq music_playback
   rts

music_playback:
   jsr SetTimer
   jsr play_music
   rts

SetTimer:
   inc timer_cookie
   lda timer_cookie
   sta kernel.args.timer.absolute
   sta kernel.args.timer.cookie
   lda #kernel.args.timer.FRAMES
   sta kernel.args.timer.units
   jsr kernel.Clock.SetTimer
   rts

*=$A000
   .binary "testsong.bin"


---

Cheat Sheet

Edit / Preview (NTSC, correct pitch)

goattracker -N -G424 song.sng

Pack for F256K

GT2RELOC song.sng song.bin -N -G454 -LD400 -Wa0 -Z80

Internal Pack

goattracker -G454 song.sng

Press F9

---

Playback in your program

JSR $A000

JSR $A003

---

Tested Defaults for the F256

  • SID: $D400
  • Player: $A000
  • Zeropage: $80/$81
  • Timing: NTSC (60 Hz)

---

End of document.