| ← D566 | Map | D5A5 → |
D568: Play the next note of the active tune
|
Advances the tune pointer past the next byte of the active tune. Plays that byte as a square-wave note or a silent rest, or returns it when it is the terminator.
|
|||||||
|
|||||||
|
A caller points the tune pointer at a tune and calls this once per byte until the terminator comes back. A tune is a byte stream with three byte classes. $0D ends the tune, $FE is a rest, and any other value is a note.
A note byte is a byte offset into the period/duration table, so it is always even, at twice the note index. A rest borrows the table's first entry for its length and plays it silently.
|
|||||||
| play_tune_note | D568 | LD HL,(tune_ptr) | Fetch the next tune byte through the tune pointer and advance it by 1. | ||||
| D56B | LD A,(HL) | ||||||
| D56C | INC HL | ||||||
| D56D | LD (tune_ptr),HL | ||||||
| D570 | CP $0D | The terminator: return it in A for the caller's end test. | |||||
| D572 | RET Z | ||||||
| D573 | CP $FE | A rest falls through to the rest path; any other value is a note. | |||||
| D575 | JP NZ,play_tune_note_0 | ||||||
| D578 | LD HL,$0000 | Rest: patch the speaker write to two NOPs to silence it, and select table entry 0 in A for the rest's duration. | |||||
| D57B | LD (tone_out_patch),HL | ||||||
| D57E | XOR A | ||||||
| D57F | JP play_tune_note_1 | ||||||
| play_tune_note_0 | D582 | LD HL,SPEAKER_OUT_OPCODE | Note: patch the speaker write to OUT ($FE),A so the tone sounds. | ||||
| D585 | LD (tone_out_patch),HL | ||||||
| play_tune_note_1 | D588 | LD HL,note_table | Index the period/duration table by the raw byte value. | ||||
| D58B | LD E,A | ||||||
| D58C | LD D,$00 | ||||||
| D58E | ADD HL,DE | ||||||
| D58F | LD E,(HL) | Read the period, which sets the pitch, into E and the duration in speaker half-cycles into B. | |||||
| D590 | INC HL | ||||||
| D591 | LD B,(HL) | ||||||
| D592 | LD HL,$0000 | Point HL at the start of ROM so the delay loop's store hits ROM harmlessly. Start A at the first speaker level, with the border bits clear for black. | |||||
| D595 | XOR A | ||||||
|
Square-wave generator. Each half-cycle flips the speaker and holds it for a delay set by the note's period. The border bits are never touched, so the border stays black for the whole note. The speaker write is patched at run time, so the disassembly from the speaker write onward is mis-aligned with the run-time code. At run time the speaker write takes two bytes, followed by the time-burn store. The disassembly re-syncs with the run-time path at the delay loop below.
|
|||||||
| play_tune_note_2 | D596 | PUSH DE | Save the period so it can be reloaded each half-cycle. | ||||
| D597 | XOR $10 | Flip the speaker bit (ULA bit 4). | |||||
| tone_out_patch | D599 | DEFB $D3 | |||||
| D59A | CP $36 | ||||||
| D59C | NOP | ||||||
| D59D | DEC E | Inner delay: spin E times to set the half-period. A lower E gives a higher pitch. | |||||
| D59E | JR NZ,tone_out_patch+$2 | ||||||
| D5A0 | POP DE | Reload the period for the next half-cycle. | |||||
| D5A1 | NOP | ||||||
| D5A2 | DJNZ play_tune_note_2 | Repeat for B half-cycles, the note's duration. | |||||
| D5A4 | RET | ||||||
| ← D566 | Map | D5A5 → |
