Every score on the disk, not a named one

The makefile compiled splash.score by name, so intro.score sat beside it
turning into nothing - which is exactly the failure the mirror three
lines above exists to prevent, and its comment says so: a list in a
makefile goes stale the moment somebody adds a file, and what they forgot
is invisible until they go looking for it on the machine.

Found by the user going looking for it on the machine.

Every .score in Programs/Tunes is compiled and put on the disk now, and
every patch in Programs/Sounds is converted first so a score can name any
of them. The source is mirrored to /Source/Tunes with everything else
that was written; the tune goes to the root, where a program looking for
one expects it - which is worth writing down, because the two being in
different places is the thing that sent somebody hunting.

two.score moved to Tests. It is a fixture, it names patches that only
exist in the test build, and it was in the music tree only because that
is where scores were when it was written - which the game disk build
found immediately by failing to compile it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-06 11:15:47 -04:00
co-authored by Claude Opus 5
parent dfc9d9ef7f
commit f351ee8844
16 changed files with 125 additions and 49 deletions
+67
View File
@@ -0,0 +1,67 @@
; Four bars, and the bass is the same one under two of them.
#Tick 0d125000 ; cycles a tick: a sixteenth note at 120 beats a minute
#Patch Oboe oboe.patch
#Voice 0d0 Oboe ; which instrument each voice starts on
#Voice 0d1 Oboe
#Voice 0d2 Oboe
#Voice 0d3 Oboe
#Sequence MotifA
0x30 0d2
0x00 0d2
0x3C 0d2
0x00 0d4
0x48 0d4
0x00 0d4
0x47 0d4
0x00 0d6
; 28 beats
#Sequence MotifB
0x00 0d2
0x35 0d2
0x00 0d2
0x40 0d4
0x00 0d4
0x45 0d4
0x00 0d4
0x43 0d6
#Sequence IntroQuiet
0x00 0d28
#Sequence ChordRoot
0x2C 0x4
0x2E 0x4
0x30 0x4
#Sequence ChordFifth
0x33 0x4
0x35 0x4
0x37 0x4
#Sequence ChordThird
0x3C 0x4
0x3E 0x4
0x40 0x4
#Sequence ChordQuiet
0x00 0d12
#Sequence Bass
0x24 0x8
#Order 0d0
MotifA ChordRoot
#Order 0d1
MotifB ChordFifth
#Order 0d2
IntroQuiet ChordThird
#Order 0d3
IntroQuiet ChordQuiet Bass
+25 -32
View File
@@ -6,62 +6,55 @@
#Voice 0d0 Oboe ; which instrument each voice starts on #Voice 0d0 Oboe ; which instrument each voice starts on
#Voice 0d1 Oboe #Voice 0d1 Oboe
#Voice 0d2 Oboe #Voice 0d2 Oboe
#Voice 0d3 Oboe
#Sequence MotifA #Sequence MotifA
0x30 0d2 0x30 0d2
0x00 0d2 0x00 0d2
0x3C 0d2 0x3C 0d2
0x00 0d4
0x48 0d4
0x00 0d4
0x47 0d4
0x00 0d6 0x00 0d6
; 28 beats
#Sequence MotifB #Sequence MotifB
0x00 0d2 0x00 0d2
0x35 0d2 0x35 0d2
0x00 0d2 0x00 0d2
0x40 0d4 0x41 0d6
0x00 0d4
0x45 0d4
0x00 0d4
0x43 0d6
; Truncate Anachronaut motif to three introductory notes.
#Sequence IntroQuiet #Sequence IntroQuiet
0x00 0d28 0x00 0d12
#Sequence ChordRoot ; new Chords are C-maj, A-maj. "Seeeee-gaaaan"
0x2C 0x4
0x2E 0x4
0x30 0x4
#Sequence ChordFifth #Sequence ChordA
0x33 0x4 ; C
0x35 0x4 0x30 0d6
0x37 0x4 ; A
0x2D 0d6
#Sequence ChordThird ; One continuous note here makes the chords blend together better.
0x3C 0x4
0x3E 0x4 #Sequence ChordB
0x40 0x4 ; E+
0x34 0d12
#Sequence ChordC
; G+
0x37 0d6
; Cs+
0x3D 0x6
#Sequence ChordQuiet #Sequence ChordQuiet
0x00 0d12 0x00 0d12
#Sequence Bass ; The extra rests on the end prevent the splash screen from ending before the voices are silent.
0x24 0x8
#Order 0d0 #Order 0d0
MotifA ChordRoot MotifA ChordA IntroQuiet
#Order 0d1 #Order 0d1
MotifB ChordFifth MotifB ChordB IntroQuiet
#Order 0d2 #Order 0d2
IntroQuiet ChordThird IntroQuiet ChordC IntroQuiet
#Order 0d3
IntroQuiet ChordQuiet Bass
+2
View File
@@ -103,6 +103,8 @@ Nothing is written when anything is refused, so a failed build cannot leave a ha
./SplitDisk put mydisk.img theme.tune ./SplitDisk put mydisk.img theme.tune
``` ```
In this repository, `Programs/Tunes` holds the scores and the build compiles every one of them onto the disk - the source mirrored to `/Source/Tunes` with everything else that was written, and the compiled tune at the root, where a program looking for one expects to find it.
**A `.score` is written and a `.tune` is what the machine reads**, the same way a `.asm` is written and a `.sbx` or a `.bin` is what it loads. One is a source and the other is bytes, and giving them different names means never wondering which a file is - or handing a player a source and being told, correctly, that it is not a tune. **A `.score` is written and a `.tune` is what the machine reads**, the same way a `.asm` is written and a `.sbx` or a `.bin` is what it loads. One is a source and the other is bytes, and giving them different names means never wondering which a file is - or handing a player a source and being told, correctly, that it is not a tune.
Then `Play theme.tune` on the machine. Then `Play theme.tune` on the machine.
+1 -1
View File
@@ -31,7 +31,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -21,7 +21,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -38,7 +38,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -28,7 +28,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -28,7 +28,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -114,7 +114,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -33,7 +33,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -21,7 +21,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -19,7 +19,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+1 -1
View File
@@ -28,7 +28,7 @@ Crash.sbx 632
vars.script 50 vars.script 50
blocks.script 343 blocks.script 343
loops.script 272 loops.script 272
splash.tune 218 splash.tune 189
tune.sbx 318 tune.sbx 318
Play.sbx 2526 Play.sbx 2526
notes.txt 21 notes.txt 21
+2 -2
View File
@@ -744,12 +744,12 @@ def blob(octave):
open(sys.argv[1], "wb").write(blob(128)) open(sys.argv[1], "wb").write(blob(128))
open(sys.argv[2], "wb").write(blob(129)) open(sys.argv[2], "wb").write(blob(129))
FIXTURE FIXTURE
"$ROOT/TuneC" -I "$WORK" "$ROOT/Programs/Tunes/two.score" "$WORK/compiled.tune" >/dev/null "$ROOT/TuneC" -I "$WORK" "$ROOT/Tests/two.score" "$WORK/compiled.tune" >/dev/null
# The same tune at half the speed. A TICK BELONGS TO THE TUNE, and the only reason nothing # The same tune at half the speed. A TICK BELONGS TO THE TUNE, and the only reason nothing
# noticed that Play was ignoring it was that every fixture asked for the tick Play happened to # noticed that Play was ignoring it was that every fixture asked for the tick Play happened to
# have written into itself. One that asks for something else is the whole check. # have written into itself. One that asks for something else is the whole check.
sed 's/#Tick 0d125000/#Tick 0d250000/' "$ROOT/Programs/Tunes/two.score" > "$WORK/slow.score" sed 's/#Tick 0d125000/#Tick 0d250000/' "$ROOT/Tests/two.score" > "$WORK/slow.score"
"$ROOT/TuneC" -I "$WORK" "$WORK/slow.score" "$WORK/slow.tune" >/dev/null "$ROOT/TuneC" -I "$WORK" "$WORK/slow.score" "$WORK/slow.tune" >/dev/null
"$TOOL" put "$DISKS/quiet.img" "$WORK/slow.tune" slow.tune >/dev/null "$TOOL" put "$DISKS/quiet.img" "$WORK/slow.tune" slow.tune >/dev/null
"$ROOT/Assembler" -I "$ROOT/Programs/Sounds" -I "$ROOT/Programs/Libraries" \ "$ROOT/Assembler" -I "$ROOT/Programs/Sounds" -I "$ROOT/Programs/Libraries" \
+1 -1
View File
@@ -1,4 +1,4 @@
; two.score ; Tests/two.score
; The smallest thing that is a tune: one voice, two sequences, and an instrument change. ; The smallest thing that is a tune: one voice, two sequences, and an instrument change.
; Written by Anachronaut ; Written by Anachronaut
; ;
+18 -4
View File
@@ -639,11 +639,25 @@ $(COSMOS_DISK): $(APPS) $(NATIVE_ASM) $(COSMOS) $(STAGE2) \
@# written and a .sbx is what it loads. The patches come from SoundPatch, which stays the @# written and a .sbx is what it loads. The patches come from SoundPatch, which stays the
@# only thing that knows what a soundThing patch means; TuneC embeds the bytes and knows @# only thing that knows what a soundThing patch means; TuneC embeds the bytes and knows
@# nothing about them. @# nothing about them.
@# EVERY SCORE, NOT A NAMED ONE. A list here goes stale the moment somebody writes a
@# second piece of music, and what they forgot is invisible until they go looking for
@# it on the machine - which is the same argument the mirror above is made of, and the
@# same way it went wrong the first time: splash.score was named and intro.score sat
@# beside it compiling into nothing.
@#
@# The patches every score can name are converted first. They come from SoundPatch,
@# which stays the only thing that knows what a soundThing patch means.
@mkdir -p $(PROG_BUILD)/tunes @mkdir -p $(PROG_BUILD)/tunes
$(PATCH_RUN) --blob $(PROG_DIR)/Sounds/Oboe.json Oboe $(PROG_BUILD)/tunes/oboe.patch @for json in $(PROG_DIR)/Sounds/*.json; do \
$(TUNE_RUN) -I $(PROG_BUILD)/tunes $(PROG_DIR)/Tunes/splash.score \ $(PATCH_RUN) --blob $$json `basename $$json .json` \
$(PROG_BUILD)/tunes/splash.tune $(PROG_BUILD)/tunes/`basename $$json .json | tr 'A-Z' 'a-z'`.patch \
$(DISKTOOL) put $@ $(PROG_BUILD)/tunes/splash.tune splash.tune >/dev/null || exit 1; done
@for score in $(PROG_DIR)/Tunes/*.score; do \
name=`basename $$score .score`; \
$(TUNE_RUN) -I $(PROG_BUILD)/tunes $$score $(PROG_BUILD)/tunes/$$name.tune \
>/dev/null || exit 1; \
$(DISKTOOL) put $@ $(PROG_BUILD)/tunes/$$name.tune $$name.tune >/dev/null \
|| exit 1; done
@# ---- What you assemble: all of it ---- @# ---- What you assemble: all of it ----
@# @#
@# MIRRORED RATHER THAN LISTED. A list in a makefile goes stale the moment somebody @# MIRRORED RATHER THAN LISTED. A list in a makefile goes stale the moment somebody