![]() |
Routines |
| Prev: C041 | Up: Map | Next: C0B0 |
|
Used by the routine at LOADING_TUNE.
Both voices' next notes are taken and their pitches looked up. Unless both are resting, the note is played for 18 passes of 256 turns of a loop that sends a byte to the speaker's port twice a turn, one for each voice. Each voice keeps its own copy of the port byte (voice one's in A', voice two's in A) and its own countdown (E, and L), and toggles the speaker bit in its copy when the countdown runs out; so each is a square wave at its own pitch, and the two sound together. The two ways round the loop take the same time, 96 T-states (the JR Z that never jumps and the NOPs pad the shorter), so neither voice's pitch depends on the other's.
Once both voices rest, it returns at once. That never ran in the sessions (the sounds page's runs reach it), and nor did the end of a note by way of the first DJNZ: which of the two ends a note depends only on voice two's countdown in the note's last turn.
|
||||
| TUNE_PLAY_NOTE | C049 | LD HL,VOICE_ONE_AT | Voice one's next note. | |
| C04C | CALL TUNE_NEXT_NOTE | |||
| C04F | LD (VOICE_ONE_NOTE),A | |||
| C052 | LD HL,VOICE_TWO_AT | Voice two's. | ||
| C055 | CALL TUNE_NEXT_NOTE | |||
| C058 | LD (VOICE_TWO_NOTE),A | |||
| C05B | LD HL,VOICE_ONE_NOTE | Voice one's pitch, on the stack. | ||
| C05E | CALL TUNE_PITCH | |||
| C061 | PUSH HL | |||
| C062 | LD HL,VOICE_TWO_NOTE | Voice two's: H its pitch, L its countdown; D and E voice one's. | ||
| C065 | CALL TUNE_PITCH | |||
| C068 | POP DE | |||
| C069 | LD A,H | Both resting: nothing to play. | ||
| C06A | CP $01 | |||
| C06C | JR NZ,TUNE_PLAY_NOTE_0 | |||
| C06E | LD A,D | |||
| C06F | CP $01 | |||
| C071 | RET Z | |||
| TUNE_PLAY_NOTE_0 | C072 | LD A,(NOTE_LENGTH) | BC counts the note's turns: B 256 at a time, C up from $EE to 0. | |
| C075 | LD C,A | |||
| C076 | LD B,$00 | |||
| C078 | LD A,(TUNE_PORT) | Both voices start from the same port byte: voice one's copy in A', voice two's in A. | ||
| C07B | EX AF,AF' | |||
| C07C | LD A,(TUNE_PORT) | |||
| C07F | LD IXh,D | Voice one's pitch in IXh, to reload its countdown from. | ||
| C081 | LD D,$10 | D: the speaker bit (bit 4 of port $FE). | ||
| TUNE_PLAY_NOTE_1 | C083 | NOP | Padding. | |
| C084 | NOP | |||
| TUNE_PLAY_NOTE_2 | C085 | EX AF,AF' | Voice one: its port byte out, and its countdown down; not run out, the other way round. | |
| C086 | DEC E | |||
| C087 | OUT ($FE),A | |||
| C089 | JR NZ,TUNE_PLAY_NOTE_4 | |||
| C08B | LD E,IXh | Run out: reload it, and toggle voice one's speaker bit. | ||
| C08D | XOR D | |||
| C08E | EX AF,AF' | Voice two: its countdown down; not run out, out with its port byte as it is. | ||
| C08F | DEC L | |||
| C090 | JP NZ,TUNE_PLAY_NOTE_5 | |||
| TUNE_PLAY_NOTE_3 | C093 | OUT ($FE),A | Run out: out with voice two's port byte; reload its countdown and toggle its speaker bit. | |
| C095 | LD L,H | |||
| C096 | XOR D | |||
| C097 | DJNZ TUNE_PLAY_NOTE_1 | Next turn; next 256; the note is over. | ||
| C099 | INC C | |||
| C09A | JP NZ,TUNE_PLAY_NOTE_2 | |||
| C09D | RET | |||
| TUNE_PLAY_NOTE_4 | C09E | JR Z,TUNE_PLAY_NOTE_4 | As long as the reload above, and never jumps: Z is clear here. | |
| C0A0 | EX AF,AF' | Voice two: its countdown down; run out, go and toggle it. | ||
| C0A1 | DEC L | |||
| C0A2 | JP Z,TUNE_PLAY_NOTE_3 | |||
| TUNE_PLAY_NOTE_5 | C0A5 | OUT ($FE),A | Out with voice two's port byte, and padding. | |
| C0A7 | NOP | |||
| C0A8 | NOP | |||
| C0A9 | DJNZ TUNE_PLAY_NOTE_1 | Next turn; next 256; the note is over. | ||
| C0AB | INC C | |||
| C0AC | JP NZ,TUNE_PLAY_NOTE_2 | |||
| C0AF | RET | |||
| Prev: C041 | Up: Map | Next: C0B0 |