CODE_K% = P% LOAD_K% = LOAD% + P% - CODE%ELITE K FILE Produces the binary file ELTK.bin that gets loaded by elite-checksum.py..value0 EQUB 0 ; An unused counter that increments every time we ; process music command <#6> ; ; [Show more]Name: Music variables [Show more] Type: Workspace Address: $B4CB to $B4D1 Category: Sound Summary: Variables that are used by the music playerContext: See this workspace on its own page References: No direct references to this workspace in this source file; ; This variable is used by the following: ; ; * BDRO6 ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned above.value1 EQUB 0 ; Stores the voice control register for voice 1 ; ; [Show more]; ; This variable is used by the following: ; ; * BDlab21 ; * BDlab4 ; * BDRO13 ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned above.value2 EQUB 0 ; Stores the voice control register for voice 2 ; ; [Show more]; ; This variable is used by the following: ; ; * BDlab21 ; * BDlab6 ; * BDRO13 ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned above.value3 EQUB 0 ; Stores the voice control register for voice 3 ; ; [Show more]; ; This variable is used by the following: ; ; * BDlab21 ; * BDlab8 ; * BDRO13 ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned above.value4 EQUB 0 ; Stores the rest length for commands #8 and #15 ; ; [Show more]; ; This variable is used by the following: ; ; * BDRO12 ; * BDRO8 ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned aboveIF _GMA_RELEASE .value5 EQUW $8888 ; The address before the start of the music data for the ; tune that is configured to play for docking, so this ; can be changed to alter the docking music ; ; [Show more]; ; This variable is used by the following: ; ; * BDENTRY ; * startbd ; ; This list only includes code that refers to the ; variable by name; there may be other references to ; this memory location that don't use this label, and ; these will not be mentioned aboveENDIF.BDirqhere LDY #0 ; If the music counter is zero then we are not currently CPY counter ; processing a wait command, so jump to BDskip1 to BEQ BDskip1 ; process the current byte of music data in BDBUFF DEC counter ; Otherwise we are processing a rest command, so ; decrement the music counter while we continue to pause ; the music JMP BDlab1 ; And jump to BDlab1 to update the vibrato and control ; registers before returning from the subroutine .BDskip1 ; When we get here, Y is set to 0 ; ; This value is retained throughout the entire music ; interrupt routine, so whenever you see Y in these ; routines, it has a value of 0 LDA BDBUFF ; Set A to the current byte of music data in BDBUFF CMP #$10 ; If A >= $10 then the high nibble of A is non-zero, so BCS BDLABEL2 ; jump to BDLABEL2 to extract and process the command in ; the low nibble first, leaving the command in the high ; nibble until later TAX ; Set X to the low nibble of music data in A, so X is ; in the range 1 to 15 and contains the number of the ; music command we now need to process BNE BDLABEL ; If A > 0 then this is a valid command number in the ; range 1 to 15, so jump to BDLABEL to process the ; command ; If we get here then the nibble of music data in A is ; zero, which means "do nothing", so we just move on to ; the next data byte JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA BDBUFF ; Store the next music data byte in BDBUFF .BDLABEL2 AND #$0F ; Extract the low nibble of the music data into A TAX ; Set X to the low nibble of music data in A, so X is ; in the range 1 to 15 and contains the number of the ; music command we now need to process .BDLABEL LDA BDBUFF ; Shift the high nibble of BDBUFF into the low nibble, LSR A ; so it is available as the next nibble of music data LSR A ; to be processed, once we have finished processing the LSR A ; command in X LSR A STA BDBUFF ; We now process the current music command, which is in ; the low nibble of X, and in the range 1 to 15 LDA BDJMPTBL-1,X ; Modify the JMP command at BDJMP to jump to the X-th STA BDJMP+1 ; address in the BDJMPTBL table, to process the music LDA BDJMPTBH-1,X ; command in X STA BDJMP+2 ; ; This means that command <#1> jumps to BDRO1, command ; <#2> jumps to BDRO2, and so on up to command <#15>, ; which jumps to BDR15 .BDJMP JMP BDskip1 ; Jump to the correct routine for processing the music ; command in X (as this instruction gets modified)Name: BDirqhere [Show more] Type: Subroutine Category: Sound Summary: The interrupt routine for playing background musicContext: See this subroutine on its own page References: This subroutine is called as follows: * BDRO8 calls BDirqhere * COMIRQ1 calls BDirqhere * BDRO1 calls via BDskip1 * BDRO10 calls via BDskip1 * BDRO12 calls via BDskip1 * BDRO13 calls via BDskip1 * BDRO14 calls via BDskip1 * BDRO2 calls via BDskip1 * BDRO3 calls via BDskip1 * BDRO4 calls via BDskip1 * BDRO5 calls via BDskip1 * BDRO6 calls via BDskip1 * BDRO7 calls via BDskip1 * BDRO9 calls via BDskip1
The label "BD" is used as a prefix throughout the music routines. This is a reference to the Blue Danube, which is the only bit of music that was included in the first release of Commodore 64 Elite (where it was used for the docking computer). The Elite theme tune on the title screen was added in a later release. The following comments appear in the original source: Music driver by Dave Dunn. BBC source code converted from Commodore disassembly extremely badly Jez. 13/4/85. Music system (c)1985 D.Dunn. Modified by IB,DB
Other entry points: BDskip1 Process the next nibble of music data in BDBUFF.BDRO1 JSR BDlab3 ; Fetch the next two music data bytes and set the ; frequency of voice 1 (high byte then low byte) JSR BDlab4 ; Set the voice control register for voice 1 to value1 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO1 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#1 fh1 fl1> to set the frequency for voice 1 to (fh1 fl1) and the control register for voice 1 to value1Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO1 * BDJMPTBL calls BDRO1.BDRO2 JSR BDlab5 ; Fetch the next two music data bytes and set the ; frequency of voice 2 (high byte then low byte) and the ; vibrato variables for voice 2 JSR BDlab6 ; Set the voice control register for voice 2 to value2 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO2 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#2 fh1 fl1> to set the frequency for voice 2 to (fh2 fl2) and the control register for voice 2 to value2Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO2 * BDJMPTBL calls BDRO2.BDRO3 JSR BDlab7 ; Fetch the next two music data bytes and set the ; frequency of voice 3 (high byte then low byte) and the ; vibrato variables for voice 3 JSR BDlab8 ; Set the voice control register for voice 3 to value3 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO3 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#3 fh1 fl1> to set the frequency for voice 3 to (fh3 fl3) and the control register for voice 3 to value3Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO3 * BDJMPTBL calls BDRO3.BDRO4 JSR BDlab3 ; Fetch the next two music data bytes and set the ; frequency of voice 1 (high byte then low byte) JSR BDlab5 ; Fetch the next two music data bytes and set the ; frequency of voice 2 (high byte then low byte) and the ; vibrato variables for voice 2 JSR BDlab4 ; Set the voice control register for voice 1 to value1 JSR BDlab6 ; Set the voice control register for voice 2 to value2 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO4 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#4 fh1 fl1 fh2 fl2> to set the frequencies and voice control registers for voices 1 and 2Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO4 * BDJMPTBL calls BDRO4.BDRO5 JSR BDlab3 ; Fetch the next two music data bytes and set the ; frequency of voice 1 (high byte then low byte) JSR BDlab5 ; Fetch the next two music data bytes and set the ; frequency of voice 2 (high byte then low byte) and the ; vibrato variables for voice 2 JSR BDlab7 ; Fetch the next two music data bytes and set the ; frequency of voice 3 (high byte then low byte) and the ; vibrato variables for voice 3 JSR BDlab4 ; Set the voice control register for voice 1 to value1 JSR BDlab6 ; Set the voice control register for voice 2 to value2 JSR BDlab8 ; Set the voice control register for voice 3 to value3 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO5 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#5 fh1 fl1 fh2 fl2 fh3 fl3> to set the frequencies and voice control registers for voices 1, 2 and 3Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO5 * BDJMPTBL calls BDRO5.BDRO6 INC value0 ; Increment the counter in value0 ; ; This value is never read, so it could be a debugging ; command of some kind, or a counter that is not used ; by the music in Elite JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; data.BDRO15 LDA BDBUFF ; Slide the value %1000 (8) into the low nibble of SEC ; BDBUFF while shifting the original low nibble into ROL A ; the high nibble ASL A ; ASL A ; Because we process the low nibble first in each music ASL A ; data byte, this inserts command <#8> into the queue as STA BDBUFF ; the next command to be processed, after we fall ; through into BDRO8 to process another command <#8> ; first ; ; In other words, this processes two command <#8>s in a ; row, which implements a double-length rest ; Fall into BDRO8 to rest for value4 interrupts.BDRO8 LDA value4 ; Set the music counter to value4, so we introduce a STA counter ; rest of value4 interrupts (i.e. a pause where we play ; no music) JMP BDirqhere ; Jump back to the start of the interrupt routine so the ; counter starts to count down.BDRO7 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$5 ; Set SID register $5 to the music data byte we just ; fetched, which sets the attack and decay length for ; voice 1 as follows: ; ; * Bits 0-3 = decay length ; ; * Bits 4-7 = attack length JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$C ; Set SID register $C to the music data byte we just ; fetched, which sets the attack and decay length for ; voice 2 as follows: ; ; * Bits 0-3 = decay length ; ; * Bits 4-7 = attack length JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$13 ; Set SID register $12 to the music data byte we just ; fetched, which sets the attack and decay length for ; voice 3 as follows: ; ; * Bits 0-3 = decay length ; ; * Bits 4-7 = attack length JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$6 ; Set SID register $6 to the music data byte we just ; fetched, which sets the release length and sustain ; volume for voice 1 as follows: ; ; * Bits 0-3 = release length ; ; * Bits 4-7 = sustain volume JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$D ; Set SID register $D to the music data byte we just ; fetched, which sets the release length and sustain ; volume for voice 2 as follows: ; ; * Bits 0-3 = release length ; ; * Bits 4-7 = sustain volume JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$14 ; Set SID register $14 to the music data byte we just ; fetched, which sets the release length and sustain ; volume for voice 4 as follows: ; ; * Bits 0-3 = release length ; ; * Bits 4-7 = sustain volume JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO7 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#7 ad1 ad2 ad3 sr1 sr2 sr3> to set three voices' attack and decay length, sustain volume and release lengthContext: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO7 * BDJMPTBL calls BDRO7.BDRO9 LDA #0 ; Clear the current music data byte, which discards the STA BDBUFF ; next nibble if there is one (so this flushes any data ; from the current pipeline) LDA BDdataptr3 ; Set BDdataptr1(1 0) = BDdataptr3(1 0) STA BDdataptr1 ; LDA BDdataptr4 ; So this sets the data pointer in BDdataptr1(1 0) back STA BDdataptr2 ; to the original value that we gave it at the start of ; the BDENTRY routine when we started playing this tune, ; which we stored in BDdataptr3(1 0) ; ; In other words, this restarts the current tune JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; data.BDRO10 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$2 ; Set SID register $2 to the music data byte we just ; fetched, which sets the high byte of the pulse width ; for voice 1 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$3 ; Set SID register $3 to the music data byte we just ; fetched, which sets the low byte of the pulse width ; for voice 1 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$9 ; Set SID register $9 to the music data byte we just ; fetched, which sets the high byte of the pulse width ; for voice 2 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$A ; Set SID register $A to the music data byte we just ; fetched, which sets the low byte of the pulse width ; for voice 2 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$10 ; Set SID register $10 to the music data byte we just ; fetched, which sets the high byte of the pulse width ; for voice 3 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$11 ; Set SID register $11 to the music data byte we just ; fetched, which sets the low byte of the pulse width ; for voice 3 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; data.BDRO11 JMP BDRO9 ; Jump to BDRO9 to process command <#9> (so command ; <#11> is the same as command <#9> and restarts the ; current tune)Name: BDRO11 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#11>, which does the same as command <#9> and restarts the current tuneContext: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO11 * BDJMPTBL calls BDRO11.BDRO12 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA value4 ; Set value4 to the value of the byte we just fetched, ; which sets the rest length used in commands #8 and #15 JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO12 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#12 n> to set value4 = n, which sets the rest length for commands #8 and #15Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO12 * BDJMPTBL calls BDRO12.BDRO13 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA value1 ; Set value1 to the value of the byte we just fetched, ; which is used to set the voice control register for ; voice 1 in command <#1> JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA value2 ; Set value2 to the value of the byte we just fetched, ; which is used to set the voice control register for ; voice 2 in command <#2> JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA value3 ; Set value3 to the value of the byte we just fetched, ; which is used to set the voice control register for ; voice 3 in command <#3> JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO13 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#13 v1 v2 v3> to set value1, value2, value3 to the voice control register values for commands <#1> to <#3>Context: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO13 * BDJMPTBL calls BDRO13.BDRO14 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$18 ; Set SID register $18 to the music data byte we just ; fetched, which sets the volume and filter modes as ; follows: ; ; * Bits 0-3: volume (0 to 15) ; ; * Bit 4 set: enable the low-pass filter ; ; * Bit 5 set: enable the bandpass filter ; ; * Bit 6 set: enable the high-pass filter ; ; * Bit 7 set: disable voice 1 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$17 ; Set SID register $17 to the music data byte we just ; fetched, which sets the filter control as follows: ; ; * Bit 0 set: voice 1 filtered ; ; * Bit 1 set: voice 2 filtered ; ; * Bit 2 set: voice 3 filtered ; ; * Bit 3 set: external voice filtered ; ; * Bits 4-7: filter resonance JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$16 ; Set SID register $16 to the music data byte we just ; fetched, which sets bits 3 to 10 of the filter cut-off ; frequency JMP BDskip1 ; Jump to BDskip1 to process the next nibble of music ; dataName: BDRO14 [Show more] Type: Subroutine Category: Sound Summary: Process music command <#14 vf fc cf> to set the volume and filter modes, filter control and filter cut-off frequencyContext: See this subroutine on its own page References: This subroutine is called as follows: * BDJMPTBH calls BDRO14 * BDJMPTBL calls BDRO14.BDlab4 LDA value1 ; Set A to value1, to use as the new value of the voice ; control register for voice 1 STY SID+$4 ; Zero SID register $4 (the voice control register for ; voice 1), to reset the voice control STA SID+$4 ; Set SID register $4 (the voice control register for ; voice 1) to the music data byte that we just fetched ; in A, so control the voice as follows: ; ; * Bit 0: 0 = voice off, release cycle ; 1 = voice on, attack-decay-sustain cycle ; ; * Bit 1 set = synchronization enabled ; ; * Bit 2 set = ring modulation enabled ; ; * Bit 3 set = disable voice, reset noise generator ; ; * Bit 4 set = triangle waveform enabled ; ; * Bit 5 set = saw waveform enabled ; ; * Bit 6 set = square waveform enabled ; ; * Bit 7 set = noise waveform enabled RTS ; Return from the subroutine.BDlab6 LDA value2 ; Set A to value2, to use as the new value of the voice ; control register for voice 2 STY SID+$B ; Zero SID register $B (the voice control register for ; voice 2), to reset the voice control STA SID+$B ; Set SID register $B (the voice control register for ; voice 2) to the music data byte that we just fetched ; in A, so control the voice as follows: ; ; * Bit 0: 0 = voice off, release cycle ; 1 = voice on, attack-decay-sustain cycle ; ; * Bit 1 set = synchronization enabled ; ; * Bit 2 set = ring modulation enabled ; ; * Bit 3 set = disable voice, reset noise generator ; ; * Bit 4 set = triangle waveform enabled ; ; * Bit 5 set = saw waveform enabled ; ; * Bit 6 set = square waveform enabled ; ; * Bit 7 set = noise waveform enabled RTS ; Return from the subroutine.BDlab8 LDA value3 ; Set A to value3, to use as the new value of the voice ; control register for voice 3 STY SID+$12 ; Zero SID register $12 (the voice control register for ; voice 3), to reset the voice control STA SID+$12 ; Set SID register $12 (the voice control register for ; voice 3) to the music data byte that we just fetched ; in A, so control the voice as follows: ; ; * Bit 0: 0 = voice off, release cycle ; 1 = voice on, attack-decay-sustain cycle ; ; * Bit 1 set = synchronization enabled ; ; * Bit 2 set = ring modulation enabled ; ; * Bit 3 set = disable voice, reset noise generator ; ; * Bit 4 set = triangle waveform enabled ; ; * Bit 5 set = saw waveform enabled ; ; * Bit 6 set = square waveform enabled ; ; * Bit 7 set = noise waveform enabled RTS ; Return from the subroutine.BDlab19 INC BDdataptr1 ; Increment the data pointer in BDdataptr1(1 0) BNE BDskipme1 INC BDdataptr1+1 .BDskipme1 LDA (BDdataptr1),Y ; Y is zero, so this sets A to the next byte of music ; data from BDdataptr1(1 0) ; ; We have to include an index of Y as the 6502 doesn't ; have an instruction of the form LDA (BDdataptr1) RTS ; Return from the subroutineName: BDlab19 [Show more] Type: Subroutine Category: Sound Summary: Increment the music data pointer in BDdataptr1(1 0) and fetch the next data byte into AContext: See this subroutine on its own page References: This subroutine is called as follows: * BDirqhere calls BDlab19 * BDlab3 calls BDlab19 * BDlab5 calls BDlab19 * BDlab7 calls BDlab19 * BDRO10 calls BDlab19 * BDRO12 calls BDlab19 * BDRO13 calls BDlab19 * BDRO14 calls BDlab19 * BDRO7 calls BDlab19
Arguments: Y Y is always 0
Returns: BDdataptr1(1 0) Incremented to point to the next music data byte A The next music data byte.BDlab3 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$1 ; Set SID register $1 to the music data byte we just ; fetched, which sets the high byte of the frequency ; for voice 1 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$0 ; Set SID register $0 to the music data byte we just ; fetched, which sets the low byte of the frequency ; for voice 1 RTS ; Return from the subroutineName: BDlab3 [Show more] Type: Subroutine Category: Sound Summary: Fetch the next two music data bytes and set the frequency of voice 1 (high byte then low byte).BDlab5 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$8 ; Set SID register $8 to the music data byte we just ; fetched, which sets the high byte of the frequency ; for voice 2 STA voice2lo1 ; Store the high byte in the voice2lo variables STA voice2lo2 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$7 ; Set SID register $7 to the music data byte we just ; fetched, which sets the low byte of the frequency ; for voice 2 STA voice2hi1 ; Store the low byte in the voice2hi variables STA voice2hi2 ; So by this point we have the following: ; ; (voice2lo1 voice2hi1) = frequency ; ; (voice2lo2 voice2hi2) = frequency ; ; Note that the variable naming here is a bit odd, as ; the high bytes are in the voice2lo variables, and the ; low bytes are in the voice2hi variables ; ; These are the names from the original source code, so ; let's roll with it CLC ; Clear the C flag for the addition below CLD ; Clear the D flag to make sure we are in binary mode, ; as we are in an interrupt handler and can't be sure of ; the flag state on entry LDA #32 ; Set (voice2lo2 voice2hi2) = (voice2lo2 voice2hi2) + 32 ADC voice2hi2 ; STA voice2hi2 ; So the second frequency in (voice2lo2 voice2hi2) is BCC BDruts1 ; now a bit higher than the first frequency, which we INC voice2lo2 ; can use to add vibrato to voice 2 .BDruts1 RTS ; Return from the subroutineName: BDlab5 [Show more] Type: Subroutine Category: Sound Summary: Fetch the next two music data bytes and set the frequency of voice 2 (high byte then low byte) and the vibrato variables.BDlab7 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$F ; Set SID register $F to the music data byte we just ; fetched, which sets the high byte of the frequency ; for voice 3 STA voice3lo1 ; Store the high byte in the voice3lo variables STA voice3lo2 JSR BDlab19 ; Increment the music data pointer in BDdataptr1(1 0) ; and fetch the next music data byte into A STA SID+$E ; Set SID register $E to the music data byte we just ; fetched, which sets the low byte of the frequency ; for voice 3 STA voice3hi1 ; Store the low byte in the voice3hi variables STA voice3hi2 ; So by this point we have the following: ; ; (voice3lo1 voice3hi1) = frequency ; ; (voice3lo2 voice3hi2) = frequency ; ; Note that the variable naming here is a bit odd, as ; the high bytes are in the voice3lo variables, and the ; low bytes are in the voice3hi variables ; ; These are the names from the original source code, so ; let's roll with it CLC ; Clear the C flag for the addition below CLD ; Clear the D flag to make sure we are in binary mode, ; as we are in an interrupt handler and can't be sure of ; the flag state on entry IF _GMA_RELEASE LDA #37 ; Set A to the frequency change used when applying ; vibrato to voice 3 (voice 2 applies a vibrato of 32, ; so this sets a bigger vibrato frequency change for ; voice 3) ELIF _SOURCE_DISK LDA #32 ; Set A to the frequency change used when applying ; vibrato to voice 3 (this is the same value as for ; voice 2) ENDIF ADC voice3hi2 ; Set (voice3lo2 voice3hi2) = (voice3lo2 voice3hi2) + A STA voice3hi2 ; BCC BDruts2 ; So the second frequency in (voice3lo2 voice3hi2) is INC voice3lo2 ; now a bit higher than the first frequency, which we ; can use to add vibrato to voice 3 .BDruts2 RTS ; Return from the subroutineName: BDlab7 [Show more] Type: Subroutine Category: Sound Summary: Fetch the next two music data bytes and set the frequency of voice 3 (high byte then low byte) and the vibrato variablesContext: See this subroutine on its own page References: This subroutine is called as follows: * BDRO3 calls BDlab7 * BDRO5 calls BDlab7.BDENTRY LDA #0 ; Set BDBUFF = 0 to reset the current music data byte in STA BDBUFF ; BDBUFF STA counter ; Set counter = 0 to reset the rest counter STA vibrato2 ; Set vibrato2 = 0 to reset the vibrato counter for ; voice 2 STA vibrato3 ; Set vibrato3 = 0 to reset the vibrato counter for ; voice 3 ; We now zero all the SID registers from $01 to $18 to ; reset the sound chip (though it doesn't zero the first ; byte at $00, for some reason) LDX #$18 ; Set a byte counter in X .BDloop2 STA SID,X ; Zero the X-th byte of the SID registers DEX ; Decrement the counter in X BNE BDloop2 ; Loop back until we have zeroed all the registers from ; $01 to $18 IF _GMA_RELEASE LDA value5 ; Set A to the low byte of value5, which is set to the ; address before the start of the tune that is ; configured to play for docking ELIF _SOURCE_DISK LDA #LO(musicstart) ; Set A to the low byte of musicstart, which is the ; address before the start of the docking music ENDIF STA BDdataptr1 ; Set BDdataptr1 to the low byte of the music to play STA BDdataptr3 ; Set BDdataptr3 to the low byte of the music to play IF _GMA_RELEASE LDA value5+1 ; Set A to the high byte of value5, which is set to the ; address before the start of the tune that is ; configured to play for docking ELIF _SOURCE_DISK LDA #HI(musicstart) ; Set A to the high byte of musicstart, which is the ; address before the start of the docking music ENDIF STA BDdataptr2 ; Set BDdataptr2 to the high byte of the music to play, ; so BDdataptr1(1 0) is the address of the music to play ; (as BDdataptr2 = BDdataptr1 + 1) STA BDdataptr4 ; Set BDdataptr4 to the high byte of the music to play, ; so BDdataptr3(1 0) is the address of the music to play ; (as BDdataptr4 = BDdataptr3 + 1) LDA #%00001111 ; Set SID register $18 to control the sound as follows: STA SID+$18 ; ; * Bits 0-3: set the volume to 15 (maximum) ; ; * Bit 4 clear: disable the low-pass filter ; ; * Bit 5 clear: disable the bandpass filter ; ; * Bit 6 clear: disable the high-pass filter ; ; * Bit 7 clear: enable voice 3 ;SEI ; This instruction is commented out in the original ; source RTS ; Return from the subroutine ;point IRQ to start ; These instructions are commented out in the original ;LDA #LO(BDirqhere) ; source ;STA $0314 ;LDA #HI(BDirqhere) ;STA $0315 ;CLI ;BRK ;re enter monitor!Name: BDENTRY [Show more] Type: Subroutine Category: Sound Summary: Start playing a new tune as background musicContext: See this subroutine on its own page References: This subroutine is called as follows: * startbd calls BDENTRYLDA #0 ; Reset the vibrato counter for voice 2 so it starts to STA vibrato2 ; count up towards the next vibrato change once again LDA #$AE ; Modify the BEQ instruction at BDbeqmod1 so next time STA BDbeqmod1+1 ; it jumps to the second half of this routine LDA voice2lo2 ; Set SID registers $7 and $8 to the vibrato frequency STA SID+$8 ; in (voice2lo2 voice2hi2), which sets the frequency LDA voice2hi2 ; for voice 2 to the second (i.e. the higher) frequency STA SID+$7 ; that we set up for vibrato in BDlab5 JMP BDlab21 ; Jump to BDlab21 to clean up and return from the ; interrupt routine .BDlab24 LDA #0 ; Reset the vibrato counter for voice 2 so it starts to STA vibrato2 ; count up towards the next vibrato change once again LDA #$98 ; Modify the BEQ instruction at BDbeqmod1 so next time STA BDbeqmod1+1 ; it jumps to the first half of this routine LDA voice2lo1 ; Set SID registers $7 and $8 to the vibrato frequency STA SID+$8 ; in (voice2lo1 voice2hi1), which sets the frequency LDA voice2hi1 ; for voice 2 to the first (i.e. the lower) frequency STA SID+$7 ; that we set up for vibrato in BDlab5 JMP BDlab21 ; Jump to BDlab21 to clean up and return from the ; interrupt routineName: BDlab24 [Show more] Type: Subroutine Category: Sound Summary: Apply a vibrato frequency change to voice 2Context: See this subroutine on its own page References: This subroutine is called as follows: * BDlab1 calls BDlab24LDA #0 ; Reset the vibrato counter for voice 3 so it starts to STA vibrato3 ; count up towards the next vibrato change once again LDA #$E2 ; Modify the BEQ instruction at BDbeqmod2 so next time STA BDbeqmod2+1 ; it jumps to the second half of this routine LDA voice3lo2 ; Set SID registers $E and $F to the vibrato frequency STA SID+$F ; in (voice3lo2 voice3hi2), which sets the frequency LDA voice3hi2 ; for voice 3 to the second (i.e. the higher) frequency STA SID+$E ; that we set up for vibrato in BDlab7 JMP BDlab21 ; Jump to BDlab21 to clean up and return from the ; interrupt routine .BDlab23 LDA #0 ; Reset the vibrato counter for voice 3 so it starts to STA vibrato3 ; count up towards the next vibrato change once again LDA #$CC ; Modify the BEQ instruction at BDbeqmod2 so next time STA BDbeqmod2+1 ; it jumps to the first half of this routine LDA voice3lo1 ; Set SID registers $E and $F to the vibrato frequency STA SID+$F ; in (voice3lo1 voice3hi1), which sets the frequency LDA voice3hi1 ; for voice 3 to the second (i.e. the higher) frequency STA SID+$E ; that we set up for vibrato in BDlab7 JMP BDlab21 ; Jump to BDlab21 to clean up and return from the ; interrupt routineName: BDlab23 [Show more] Type: Subroutine Category: Sound Summary: Apply a vibrato frequency change to voice 3Context: See this subroutine on its own page References: This subroutine is called as follows: * BDlab1 calls BDlab23.BDlab1 INC vibrato3 ; Increment the vibrato counter for voice 3 IF _GMA_RELEASE LDA #5 ; Set A = 5 so the period of the vibrato for voice 3 is ; five interrupts ELIF _SOURCE_DISK LDA #6 ; Set A = 6 so the period of the vibrato for voice 3 is ; six interrupts ENDIF CMP vibrato3 ; If the vibrato counter for voice 3 has reached the ; the value in A, then it is time to change the voice 3 ; frequency to implement vibrato, so jump to the address ; in the following BEQ instruction, which gets modified ; by the BDlab23 routine to oscillate between the two ; halves of the BDlab23 routine ; ; One half applies the lower vibrato frequency, and the ; other applies the higher vibrato frequency, so the ; effect is to flip between the two frequencies every A ; interrupts .BDbeqmod2 BEQ BDlab23 ; Jump to the BDlab23 routine to switch to the correct ; vibrato frequency and jump back to BDlab21 to clean up ; and return from the interrupt routine INC vibrato2 ; Increment the vibrato counter for voice 2 IF _GMA_RELEASE LDA #4 ; Set A = 5 so the period of the vibrato for voice 2 is ; four interrupts ELIF _SOURCE_DISK LDA #5 ; Set A = 5 so the period of the vibrato for voice 2 is ; five interrupts ENDIF CMP vibrato2 ; If the vibrato counter for voice 2 has reached the ; the value in A, then it is time to change the voice 2 ; frequency to implement vibrato, so jump to the address ; in the following BEQ instruction, which gets modified ; by the BDlab24 routine to oscillate between the two ; halves of the BDlab24 routine ; ; One half applies the lower vibrato frequency, and the ; other applies the higher vibrato frequency, so the ; effect is to flip between the two frequencies every A ; interrupts .BDbeqmod1 BEQ BDlab24 ; Jump to the BDlab24 routine to switch to the correct ; vibrato frequency and jump back to BDlab21 to clean up ; and return from the interrupt routineName: BDlab1 [Show more] Type: Subroutine Category: Sound Summary: Apply vibrato before cleaning up and returning from the interrupt routineContext: See this subroutine on its own page References: This subroutine is called as follows: * BDirqhere calls BDlab1.BDlab21 IF _GMA_RELEASE LDX counter ; If the rest counter is non-zero, jump to BDexitirq to CPX #0 ; return from the interrupt routine BNE BDexitirq ELIF _SOURCE_DISK LDX counter ; If the rest counter is not 2, jump to BDexitirq to CPX #2 ; return from the interrupt routine BNE BDexitirq ENDIF ; The rest counter is ticking down, which means no new ; notes are being played for the time being, so we need ; to silence all three voices LDX value1 ; Set SID register $4 (the voice control register for DEX ; voice 1) to value1 - 1 STX SID+$4 ; ; This changes bit 0 from a 1 to a 0, which turns off ; voice 1 and starts the release cycle (so this ; effectively terminates any music on voice 1) LDX value2 ; Set SID register $B (the voice control register for DEX ; voice 1) to value2 - 1 STX SID+$B ; ; This changes bit 0 from a 1 to a 0, which turns off ; voice 2 and starts the release cycle (so this ; effectively terminates any music on voice 2) LDX value3 ; Set SID register $12 (the voice control register for DEX ; voice 1) to value3 - 1 STX SID+$12 ; ; This changes bit 0 from a 1 to a 0, which turns off ; voice 3 and starts the release cycle (so this ; effectively terminates any music on voice 3) .BDexitirq RTS ; Return from the subroutine RTS ; This instruction has no effect as we have already ; returned from the subroutine.BDJMPTBL EQUB LO(BDRO1) EQUB LO(BDRO2) EQUB LO(BDRO3) EQUB LO(BDRO4) EQUB LO(BDRO5) EQUB LO(BDRO6) EQUB LO(BDRO7) EQUB LO(BDRO8) EQUB LO(BDRO9) EQUB LO(BDRO10) EQUB LO(BDRO11) EQUB LO(BDRO12) EQUB LO(BDRO13) EQUB LO(BDRO14) EQUB LO(BDRO15)Name: BDJMPTBL [Show more] Type: Variable Category: Sound Summary: A jump table containing addresses for processing music commands 1 through 15 (low bytes)Context: See this variable on its own page References: This variable is used as follows: * BDirqhere uses BDJMPTBL.BDJMPTBH EQUB HI(BDRO1) EQUB HI(BDRO2) EQUB HI(BDRO3) EQUB HI(BDRO4) EQUB HI(BDRO5) EQUB HI(BDRO6) EQUB HI(BDRO7) EQUB HI(BDRO8) EQUB HI(BDRO9) EQUB HI(BDRO10) EQUB HI(BDRO11) EQUB HI(BDRO12) EQUB HI(BDRO13) EQUB HI(BDRO14) .musicstart EQUB HI(BDRO15)Name: BDJMPTBH [Show more] Type: Variable Category: Sound Summary: A jump table containing addresses for processing music commands 1 through 15 (high bytes)Context: See this variable on its own page References: This variable is used as follows: * BDirqhere uses BDJMPTBHIF _GMA_RELEASE INCBIN "1-source-files/music/gma/C.COMUDAT.bin" ELIF _SOURCE_DISK INCBIN "1-source-files/music/source-disk/C.COMUDAT.bin" ENDIF .THEME IF _SOURCE_DISK EQUB $28 ; C.THEME is not included in the encrypted HICODE binary ; in the source disk variant, unlike the GMA85 variant ELIF _GMA_RELEASE INCBIN "1-source-files/music/gma/C.THEME.bin" ENDIFName: COMUDAT [Show more] Type: Variable Category: Sound Summary: Music data from the C.COMUDAT fileContext: See this variable on its own page References: No direct references to this variable in this source file.F% SKIP 0Name: F% [Show more] Type: Variable Category: Utility routines Summary: Denotes the end of the main game code, from ELITE A to ELITE KContext: See this variable on its own page References: This variable is used as follows: * DEEOR uses F%PRINT "ELITE K" PRINT "Assembled at ", ~CODE_K% PRINT "Ends at ", ~P% PRINT "Code size is ", ~(P% - CODE_K%) PRINT "Execute at ", ~LOAD% PRINT "Reload at ", ~LOAD_K% PRINT "S.ELTK ", ~CODE_K%, " ", ~P%, " ", ~LOAD%, " ", ~LOAD_J% SAVE "3-assembled-output/ELTK.bin", CODE_K%, P%, LOAD% PRINT "Addresses for the scramble routines in elite-checksum.py" PRINT "B% = ", ~CODE% PRINT "G% = ", ~G% PRINT "NA2% = ", ~NA2%Save ELTK.bin
[X]
Variable BDJMPTBH (category: Sound)
A jump table containing addresses for processing music commands 1 through 15 (high bytes)
[X]
Variable BDJMPTBL (category: Sound)
A jump table containing addresses for processing music commands 1 through 15 (low bytes)
[X]
Subroutine BDRO1 (category: Sound)
Process music command <#1 fh1 fl1> to set the frequency for voice 1 to (fh1 fl1) and the control register for voice 1 to value1
[X]
Subroutine BDRO10 (category: Sound)
Process music command <#10 h1 l1 h2 l2 h3 l3> to set the pulse width to all three voices
[X]
Subroutine BDRO11 (category: Sound)
Process music command <#11>, which does the same as command <#9> and restarts the current tune
[X]
Subroutine BDRO12 (category: Sound)
Process music command <#12 n> to set value4 = n, which sets the rest length for commands #8 and #15
[X]
Subroutine BDRO13 (category: Sound)
Process music command <#13 v1 v2 v3> to set value1, value2, value3 to the voice control register values for commands <#1> to <#3>
[X]
Subroutine BDRO14 (category: Sound)
Process music command <#14 vf fc cf> to set the volume and filter modes, filter control and filter cut-off frequency
[X]
Subroutine BDRO15 (category: Sound)
Process music command <#15> to rest for 2 * value4 interrupts
[X]
Subroutine BDRO2 (category: Sound)
Process music command <#2 fh1 fl1> to set the frequency for voice 2 to (fh2 fl2) and the control register for voice 2 to value2
[X]
Subroutine BDRO3 (category: Sound)
Process music command <#3 fh1 fl1> to set the frequency for voice 3 to (fh3 fl3) and the control register for voice 3 to value3
[X]
Subroutine BDRO4 (category: Sound)
Process music command <#4 fh1 fl1 fh2 fl2> to set the frequencies and voice control registers for voices 1 and 2
[X]
Subroutine BDRO5 (category: Sound)
Process music command <#5 fh1 fl1 fh2 fl2 fh3 fl3> to set the frequencies and voice control registers for voices 1, 2 and 3
[X]
Subroutine BDRO6 (category: Sound)
Process music command <#6> to increment value0 and move on to the next nibble of music data
[X]
Subroutine BDRO7 (category: Sound)
Process music command <#7 ad1 ad2 ad3 sr1 sr2 sr3> to set three voices' attack and decay length, sustain volume and release length
[X]
Subroutine BDRO8 (category: Sound)
Process music command <#8> to rest for value4 interrupts
[X]
Subroutine BDRO9 (category: Sound)
Process music command <#9> to restart the current tune
[X]
Variable BDdataptr1 in workspace ZP
The low byte of the address of the music data pointer in BDdataptr1(1 0), which points to the end of the music data currently being processed
[X]
Variable BDdataptr2 in workspace ZP
The high byte of the address of the music data pointer in BDdataptr1(1 0), which points to the end of the music data currently being processed
[X]
Variable BDdataptr3 in workspace ZP
The low byte of the address of the music data pointer in BDdataptr3(1 0), which is a backup of the initial value of the BDdataptr1(1 0) pointer, so music can be repeated
[X]
Variable BDdataptr4 in workspace ZP
The high byte of the address of the music data pointer in BDdataptr3(1 0), which is a backup of the initial value of the BDdataptr1(1 0) pointer, so music can be repeated
[X]
Subroutine BDirqhere (category: Sound)
The interrupt routine for playing background music
[X]
Subroutine BDlab1 (category: Sound)
Apply vibrato before cleaning up and returning from the interrupt routine
[X]
Subroutine BDlab19 (category: Sound)
Increment the music data pointer in BDdataptr1(1 0) and fetch the next data byte into A
[X]
Subroutine BDlab21 (category: Sound)
Clean up and return from the interrupt routine
[X]
Subroutine BDlab23 (category: Sound)
Apply a vibrato frequency change to voice 3
[X]
Subroutine BDlab24 (category: Sound)
Apply a vibrato frequency change to voice 2
[X]
Subroutine BDlab3 (category: Sound)
Fetch the next two music data bytes and set the frequency of voice 1 (high byte then low byte)
[X]
Subroutine BDlab4 (category: Sound)
Set the voice control register for voice 1 to value1
[X]
Subroutine BDlab5 (category: Sound)
Fetch the next two music data bytes and set the frequency of voice 2 (high byte then low byte) and the vibrato variables
[X]
Subroutine BDlab6 (category: Sound)
Set the voice control register for voice 2 to value2
[X]
Subroutine BDlab7 (category: Sound)
Fetch the next two music data bytes and set the frequency of voice 3 (high byte then low byte) and the vibrato variables
[X]
Subroutine BDlab8 (category: Sound)
Set the voice control register for voice 3 to value3
[X]
Configuration variable SID
Registers for the SID sound synthesis chip, which are memory-mapped to the 29 bytes from $D400 to $D41C (see page 461 of the Programmer's Reference Guide)
[X]
Label musicstart in variable BDJMPTBH
[X]
Variable value0 in workspace Music variables
An unused counter that increments every time we process music command <#6>
[X]
Variable value1 in workspace Music variables
Stores the voice control register for voice 1
[X]
Variable value2 in workspace Music variables
Stores the voice control register for voice 2
[X]
Variable value3 in workspace Music variables
Stores the voice control register for voice 3
[X]
Variable value4 in workspace Music variables
Stores the rest length for commands #8 and #15
[X]
Variable value5 in workspace Music variables
The address before the start of the music data for the tune that is configured to play for docking, so this can be changed to alter the docking music