| Chase H.Q. | Routines |
| Prev: EFAF | Up: Map | Next: F225 |
|
Reached via the computed jump at ED33 (pattern command byte $87). Traced mechanically below (explicit instruction lengths, to avoid the auto-disassembler misreading the DD-prefixed IX-offset forms). Confirmed against a working build (see compute_channel_ay_registers's C translation, advance_channel_phrase). The phrase-pointer table read from $F1D5 onward is a sequence of little-endian words, each either a literal marker or a raw address: marker $0000 means the table is exhausted (restart from this channel's own header word); marker $0001 is followed by a 1-byte transpose override then another table word; marker $0002 is followed by a 1-byte repeat count and a 2-byte pointer (a "repeating" phrase); anything else is a plain phrase-pointer word, used directly.
Used by the routine at ts_music_service.
|
||||
| advance_channel_phrase | F1AE | LD C,(IX+$05) | BC = (IX+$05)/(IX+$06), this channel's byte offset into its own phrase-pointer table | |
| F1B1 | LD B,(IX+$06) | |||
| acph_repeat_loop | F1B4 | LD L,(IX+$03) | HL = (IX+$03)/(IX+$04) | |
| F1B7 | LD H,(IX+$04) | |||
| F1BA | ADD HL,BC | HL = HL + BC (-> this table position) | ||
| F1BB | LD A,(IX+$21) | A = (IX+$21) (the repeat count for the phrase in (IX+$22)/(IX+$23)); A -= 1 | ||
| F1BE | DEC A | |||
| F1BF | JP M,acph_new_word | if A < 0, jump to $F1D1 (repeats exhausted -- read a new table word) | ||
| F1C2 | LD (IX+$21),A | else (IX+$21) = A (store the decremented repeat count) | ||
| F1C5 | LD E,(IX+$22) | DE = (IX+$22)/(IX+$23) (the phrase pointer this repeat count belongs to) | ||
| F1C8 | LD D,(IX+$23) | |||
| F1CB | JR NZ,acph_finalize | if A (the value decremented at $F1BE, tested via the Z flag it left behind -- $F1C2-$F1C8 are LD (IX+d),reg/LD reg,(IX+d) and do not affect flags) != 0, jump to $F1E8 (repeats remain -- resume this phrase) | ||
| F1CD | INC BC | else BC += 2 (repeat count reached exactly 0 -- this slot is done; advance to the next table word) | ||
| F1CE | INC BC | |||
| F1CF | JR acph_repeat_loop | and loop back to $F1B4 (re-add BC to HL) | ||
| acph_new_word | F1D1 | LD (IX+$20),$00 | (IX+$20) = 0 (clear this phrase's transpose override) | |
| acph_read_word | F1D5 | LD A,(HL) | A = (HL); HL += 1 | |
| F1D6 | INC HL | |||
| F1D7 | LD D,(HL) | D = (HL); E = A (DE = the table word just read) | ||
| F1D8 | LD E,A | |||
| F1D9 | OR D | if DE != $0000 (not the table-exhausted marker), jump to $F1F3 | ||
| F1DA | JR NZ,acph_check_transpose | |||
| F1DC | LD L,(IX+$03) | else HL = (IX+$03)/(IX+$04) (table exhausted -- re-read this channel's own header word) | ||
| F1DF | LD H,(IX+$04) | |||
| F1E2 | LD BC,$0002 | BC = 2 (table offset resets to just past the header) | ||
| F1E5 | LD E,(HL) | E = (HL); HL += 1; D = (HL) (DE = the header word, used as the resume pointer) | ||
| F1E6 | INC HL | |||
| F1E7 | LD D,(HL) | |||
| acph_finalize | F1E8 | LD (IX+$05),C | (IX+$05) = C; (IX+$06) = B (persist the table offset cursor) | |
| F1EB | LD (IX+$06),B | |||
| F1EE | LD B,$00 | B = 0 | ||
| F1F0 | JP acp_read_pattern_byte | jump to $EDE4 (acp_read_pattern_byte), resuming the pattern stream from DE | ||
| acph_check_transpose | F1F3 | DEC DE | DE -= 1 (test for the transpose-prefix marker, value $0001) | |
| F1F4 | LD A,D | if DE != 0 (word was not $0001), jump to $F204 | ||
| F1F5 | OR E | |||
| F1F6 | JR NZ,acph_check_repeat | |||
| F1F8 | INC HL | else HL += 1; A = (HL) (read the inline transpose override byte) | ||
| F1F9 | LD A,(HL) | |||
| F1FA | LD (IX+$20),A | (IX+$20) = A | ||
| F1FD | INC HL | HL += 1; BC += 3; DE += 1 | ||
| F1FE | INC BC | |||
| F1FF | INC BC | |||
| F200 | INC BC | |||
| F201 | INC DE | |||
| F202 | JR acph_read_word | and loop back to $F1D5 to read the next table word | ||
| acph_check_repeat | F204 | DEC DE | DE -= 1 (test for the repeating-entry marker, value $0002; DE already holds word-1 from $F1F3) | |
| F205 | LD A,D | if DE != 0 (word was not $0002), jump to $F21F | ||
| F206 | OR E | |||
| F207 | INC DE | |||
| F208 | INC DE | |||
| F209 | JR NZ,acph_plain_pointer | |||
| F20B | INC HL | else HL += 1; A = (HL); (IX+$21) = A (repeat count operand) | ||
| F20C | LD A,(HL) | |||
| F20D | LD (IX+$21),A | |||
| F210 | INC HL | HL += 1; E = (HL); (IX+$22) = E (phrase pointer operand, low byte) | ||
| F211 | LD E,(HL) | |||
| F212 | LD (IX+$22),E | |||
| F215 | INC HL | HL += 1; D = (HL); (IX+$23) = D (phrase pointer operand, high byte) | ||
| F216 | LD D,(HL) | |||
| F217 | LD (IX+$23),D | |||
| F21A | INC BC | BC += 3 | ||
| F21B | INC BC | |||
| F21C | INC BC | |||
| F21D | JR acph_finalize | and jump to $F1E8 (DE = the new phrase pointer, used as the resume cursor) | ||
| acph_plain_pointer | F21F | INC BC | BC += 2 (word was a plain phrase-pointer, not a marker) | |
| F220 | INC BC | |||
| F221 | JR acph_finalize | and jump to $F1E8 (DE = the table word itself, used as the resume cursor) | ||
| F223 | NOP | padding (unreachable) | ||
| F224 | NOP | |||
| Prev: EFAF | Up: Map | Next: F225 |