From 168742261957c43930309ca65487273d71f5744a Mon Sep 17 00:00:00 2001 From: Anachronaut Date: Sat, 5 Sep 2026 15:24:02 -0400 Subject: [PATCH] A voice starts pointed at its track, without code to point it There is no assembler bug. I reported one and was wrong. A label written in the Data Segment does come out as its address, two bytes, most significant first - implemented in populateOutputBuffers, documented in the Assembler Manual, and correct. What misled me was the test I checked it with: the label was the first thing in an unbased Data Segment, so its address really was 0x0000, and I read the right answer as an unfilled placeholder. So Play was doing at run time what the assembler had already offered to do at assembly time. The voice records now carry their track labels directly, which is exactly the shape LDD reads, and nothing relocates on this machine so the address written is the address it will have. That takes out startVoice, its four call sites, and the eight SETDs that fed them: 450 bytes to 379, and the initial state of a voice is now something you can read rather than something you have to follow the code to work out. The comment claiming otherwise is gone from Play.asm, and the same change is made in fourVoiceTest. The music is unchanged - bar by bar the render matches to within one per cent, which is the program loading a shade sooner because it is smaller. Ten recordings moved for the same reason: 446 to 379, and nothing else. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW --- Programs/CosmOS/Apps/Play.asm | 55 +++++++------------------ Programs/testPrograms/fourVoiceTest.asm | 22 +++------- Tests/expected/cosmosCrossDisk.out | 2 +- Tests/expected/cosmosDrives.out | 2 +- Tests/expected/cosmosFault.out | 2 +- Tests/expected/cosmosFlip.out | 2 +- Tests/expected/cosmosGrid.out | 2 +- Tests/expected/cosmosMonitor.out | 2 +- Tests/expected/cosmosMonitorRun.out | 2 +- Tests/expected/cosmosRun.out | 2 +- Tests/expected/cosmosSlowDisk.out | 2 +- Tests/expected/cosmosSprite.out | 2 +- 12 files changed, 29 insertions(+), 68 deletions(-) diff --git a/Programs/CosmOS/Apps/Play.asm b/Programs/CosmOS/Apps/Play.asm index 81373b8..f4c6477 100644 --- a/Programs/CosmOS/Apps/Play.asm +++ b/Programs/CosmOS/Apps/Play.asm @@ -37,10 +37,6 @@ ; first because that is what LDD and STD move - a pointer through a pointer, which is the ; whole reason this can be a loop over four voices instead of the same code written out four ; times. -; -; The counts start at one rather than zero, so the first pass through the loop runs every -; voice's count out and fetches its first event. Nothing has to be special-cased for the -; beginning, and the piece starts on the tick rather than one after it. #Include services.asm @@ -81,27 +77,6 @@ start: OUTA 0x51 ; Run, repeat, interrupt. SIF - ; ---- The voices, pointed at their tracks ---- - ; - ; The cursors are written here rather than assembled into the table, because a label used - ; as data does not come out as its address. - SETD.1 Voice0 - SETD.0 Track0 - CALL startVoice - SETD.1 Voice1 - SETD.0 Track1 - CALL startVoice - SETD.1 Voice2 - SETD.0 Track2 - CALL startVoice - SETD.1 Voice3 - SETD.0 Track3 - CALL startVoice - - INIA 0d4 - SETD.1 Playing - STA.1 ; Four tracks still running. - ; ---- The loop ---- ; ; Step every voice, see whether any of them is still going, and then sleep. Stepping before @@ -200,17 +175,6 @@ stepEnded: STA.3 RET -; DP1 is a voice and DP0 its track. Sets the cursor, and a count of one so that the first -; pass through the loop fetches the first event. -startVoice: - STD.0.1 - DPUP.1 0d2 - INIA 0d1 - STA.1 ; Count: one tick, which runs out immediately. - INCD.1 - STA.1 ; Live. - RET - ; A plucked sound, on the channel named by A. setUpChannel: OUTA 0x41 @@ -258,17 +222,26 @@ tick: #Base 0x3000 ; Four bytes a voice: cursor high, cursor low, count, live. +; +; A LABEL WRITTEN HERE COMES OUT AS ITS ADDRESS, two bytes, most significant first - which is +; exactly the shape LDD reads. So a voice starts pointed at its track without a line of code: +; nothing relocates on this machine, so the address the assembler wrote is the address it +; will have. +; +; The count starts at one rather than zero so that the first pass through the loop runs it out +; and fetches the first event. Nothing has to be special-cased for the beginning, and the +; piece starts on the tick rather than one after it. Voice0: - 0x00 0x00 0x00 0x00 + Track0 0d1 0d1 Voice1: - 0x00 0x00 0x00 0x00 + Track1 0d1 0d1 Voice2: - 0x00 0x00 0x00 0x00 + Track2 0d1 0d1 Voice3: - 0x00 0x00 0x00 0x00 + Track3 0d1 0d1 Playing: - 0x00 + 0d4 ThisChannel: 0x00 diff --git a/Programs/testPrograms/fourVoiceTest.asm b/Programs/testPrograms/fourVoiceTest.asm index 5ace985..9f6ce83 100644 --- a/Programs/testPrograms/fourVoiceTest.asm +++ b/Programs/testPrograms/fourVoiceTest.asm @@ -43,13 +43,6 @@ start: OUTA 0x51 SIF - SETD.1 Voice0 - SETD.0 Track0 - CALL startVoice - SETD.1 Voice1 - SETD.0 Track1 - CALL startVoice - ; Twelve ticks. B survives the calls below, because a CALL saves it. INIB 0d12 tickLoop: @@ -110,14 +103,6 @@ stepVoice: stepDone: RET -; DP1 a voice, DP0 its track. A count of one, so the first pass fetches the first event. -startVoice: - STD.0.1 - DPUP.1 0d2 - INIA 0d1 - STA.1 - RET - ; Held at full and released quickly, so a note lasts exactly its ticks and the boundary ; between two of them is something a counter can find. setUpChannel: @@ -157,10 +142,13 @@ tick: #Data +; Cursor high, cursor low, count, spare. A label written here comes out as its address, most +; significant first, which is the shape LDD reads - so a voice starts pointed at its track +; with no code at all. The count starts at one so the first pass runs it out and fetches. Voice0: - 0x00 0x00 0x00 0x00 + Track0 0d1 0d0 Voice1: - 0x00 0x00 0x00 0x00 + Track1 0d1 0d0 ThisChannel: 0x00 diff --git a/Tests/expected/cosmosCrossDisk.out b/Tests/expected/cosmosCrossDisk.out index 5ef2823..cb5cda6 100644 --- a/Tests/expected/cosmosCrossDisk.out +++ b/Tests/expected/cosmosCrossDisk.out @@ -32,7 +32,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosDrives.out b/Tests/expected/cosmosDrives.out index 8ad51bd..a929347 100644 --- a/Tests/expected/cosmosDrives.out +++ b/Tests/expected/cosmosDrives.out @@ -22,7 +22,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosFault.out b/Tests/expected/cosmosFault.out index 7efee63..22b6fff 100644 --- a/Tests/expected/cosmosFault.out +++ b/Tests/expected/cosmosFault.out @@ -39,7 +39,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosFlip.out b/Tests/expected/cosmosFlip.out index 3adb8d2..6fc0759 100644 --- a/Tests/expected/cosmosFlip.out +++ b/Tests/expected/cosmosFlip.out @@ -29,7 +29,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosGrid.out b/Tests/expected/cosmosGrid.out index 947663b..ca43d02 100644 --- a/Tests/expected/cosmosGrid.out +++ b/Tests/expected/cosmosGrid.out @@ -29,7 +29,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosMonitor.out b/Tests/expected/cosmosMonitor.out index e686361..ed96a1d 100644 --- a/Tests/expected/cosmosMonitor.out +++ b/Tests/expected/cosmosMonitor.out @@ -115,7 +115,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosMonitorRun.out b/Tests/expected/cosmosMonitorRun.out index fc66a93..0fcd724 100644 --- a/Tests/expected/cosmosMonitorRun.out +++ b/Tests/expected/cosmosMonitorRun.out @@ -34,7 +34,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosRun.out b/Tests/expected/cosmosRun.out index 0240ec9..2f413bf 100644 --- a/Tests/expected/cosmosRun.out +++ b/Tests/expected/cosmosRun.out @@ -22,7 +22,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosSlowDisk.out b/Tests/expected/cosmosSlowDisk.out index be9f8b1..7f3f7e3 100644 --- a/Tests/expected/cosmosSlowDisk.out +++ b/Tests/expected/cosmosSlowDisk.out @@ -20,7 +20,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121 diff --git a/Tests/expected/cosmosSprite.out b/Tests/expected/cosmosSprite.out index a44fac9..447fc21 100644 --- a/Tests/expected/cosmosSprite.out +++ b/Tests/expected/cosmosSprite.out @@ -29,7 +29,7 @@ vars.script 50 blocks.script 343 loops.script 272 tune.sbx 318 -Play.sbx 446 +Play.sbx 379 notes.txt 21 Apps hi.script 121