1 .export _Mym_MusicStart
2 .importzp sp,tmp2,tmp3,tmp1,ptr1
4 .include "telemon30.inc"
7 ; http://cpcwiki.eu/index.php/AYC
12 _DecodedByte :=$D0 ; Byte being currently decoded from the MYM stream
13 _DecodeBitCounter :=$D2 ; Number of bits we can read in the current byte
14 _DecodedResult :=$D3 ; What is returned by the 'read bits' function
15 _CurrentAYRegister :=$D4 ; Contains the number of the register being decoded
16 _RegisterBufferHigh :=$D5 ; Points to the high byte of the decoded register buffer, increment to move to the next register
17 _BufferFrameOffset :=$D6 ; From 0 to 127, used when filling the decoded register buffer
18 _MusicResetCounter :=$D7 ; 2 bytes Contains the number of rows to play before reseting
19 _CurrentFrame :=$D9 ; From 0 to 255 and then cycles... the index of the frame to play this vbl
21 _FrameLoadBalancer :=$DB ; We depack a new frame every 9 VBLs, this way the 14 registers are evenly depacked over 128 frames
35 ; Current PSG values during unpacking
41 ; The two first bytes of the MYM music is the number of rows in the music
42 ; We decrement that at each frame, and when we reach zero, time to start again.
48 sta _MusicResetCounter+0
53 stx _MusicResetCounter+1
56 ;stx _MusicResetCounter+0
59 ;stx _MusicResetCounter+1
62 ; Initialize the read bit counter
63 ldy #2 ; should be useless because we can do iny which earn 1 byte
71 sta __auto_music_ptr+2
74 sta __auto_music_ptr+1
79 ;sta __auto_music_ptr+1
81 ;sta __auto_music_ptr+2
91 sta _PlayerRegCurrentValue
92 sta _BufferFrameOffset
94 sta _CurrentAYRegister
100 sta _PlayerRegValues,x
105 ; Unpack the 128 first register frames
109 sta _RegisterBufferHigh
113 stx _CurrentAYRegister
115 ; Unpack that register
116 jsr _PlayerUnpackRegister2
119 ldx _CurrentAYRegister
122 bne unpack_block_loop
130 sta _CurrentAYRegister
134 sta _FrameLoadBalancer
145 sta _InterruptCallBack_3+1
147 sta _InterruptCallBack_3+2
155 ; Indicate the main code that the music is finished
159 ; Disable the IRQ so it does not conflict or cause weird things
163 sta _InterruptCallBack_3+1
165 sta _InterruptCallBack_3+2
168 ; Cut the sound so it does not sounds like a dying cat
172 ldy #7 ; Control register
193 ; Check for end of music
195 dec _MusicResetCounter+0
197 dec _MusicResetCounter+1
206 ; Play a frame of 14 registers
210 sta _auto_psg_play_read+1
212 sta _auto_psg_play_read+2
224 inc _auto_psg_play_read+2
234 lda _CurrentAYRegister
239 dec _FrameLoadBalancer
242 jsr _PlayerUnpackRegister
243 inc _CurrentAYRegister
245 sta _FrameLoadBalancer
257 sta _CurrentAYRegister
260 sta _FrameLoadBalancer
282 ora #$EE ; $EE 238 11101110
285 and #$11 ; $11 17 00010001
286 ora #$CC ; $CC 204 11001100
293 ora #$EC ; $EC 236 11101100
296 and #$11 ; $11 17 00010001
297 ora #$CC ; $CC 204 11001100
306 ; Initialise X with the number of bits to read
314 ; Will iterate X times (number of bits to read)
317 dec _DecodeBitCounter
331 sta _DecodeBitCounter
333 ; fetch a new byte, and increment the adress.
338 inc __auto_music_ptr+1
340 inc __auto_music_ptr+2
347 _PlayerUnpackRegister:
350 adc _CurrentAYRegister
351 sta _RegisterBufferHigh
352 _PlayerUnpackRegister2:
354 ; Init register bit count and current value
356 ldx _CurrentAYRegister
357 lda _PlayerRegValues,x
358 sta _PlayerRegCurrentValue
362 ; Check if it's packed or not
363 ; and call adequate routine...
368 bne DecompressFragment
374 ; No change at all, just repeat '_PlayerRegCurrentValue' 128 times
376 lda _RegisterBufferHigh ; highpart of buffer adress + register number
377 sta __auto_copy_unchanged_write+2
379 ldx #128 ; 128 iterations
380 lda _PlayerRegCurrentValue ; Value to write
385 __auto_copy_unchanged_write:
392 jmp player_main_return
396 ; Write back register current value
397 ldx _CurrentAYRegister
398 lda _PlayerRegCurrentValue
399 sta _PlayerRegValues,x
401 ; Move to the next register buffer
402 inc _RegisterBufferHigh
409 lda _PlayerVbl ; Either 0 or 128 at this point else we have a problem...
410 sta _BufferFrameOffset
412 decompressFragmentLoop:
414 player_copy_packed_loop:
415 ; Check packing method
420 bne PlayerNotCopyLast
424 ; We just copy the current value 128 times
425 lda _RegisterBufferHigh ; highpart of buffer adress + register number
426 sta __auto_player_copy_last+2
428 ldx _BufferFrameOffset ; Value between 00 and 7f
429 lda _PlayerRegCurrentValue ; Value to copy
430 __auto_player_copy_last:
433 inc _BufferFrameOffset
440 lda _BufferFrameOffset
442 bne decompressFragmentLoop
444 jmp player_main_return
448 ; Check packing method
453 beq DecompressWithOffset
455 ReadNewRegisterValue:
456 ; Read new register value (variable bit count)
457 ldx _CurrentAYRegister
462 stx _PlayerRegCurrentValue
465 lda _RegisterBufferHigh ; highpart of buffer adress + register number
466 sta __auto_player_read_new+2
468 ldx _BufferFrameOffset ; Value between 00 and 7f
469 lda _PlayerRegCurrentValue ; New value to write
470 __auto_player_read_new:
473 inc _BufferFrameOffset
479 DecompressWithOffset:
481 ; Read Offset (0 to 127)
485 lda _RegisterBufferHigh ; highpart of buffer adress + register number
486 sta __auto_write+2 ; Write adress
487 sta __auto_read+2 ; Read adress
489 ; Compute wrap around offset...
490 lda _BufferFrameOffset ; between 0 and 255
492 adc _DecodedResult ; + Offset Between 00 and 7f
497 ; Read count (7 bits)
501 inc _DecodedResult ; 1 to 129
504 ldx _BufferFrameOffset
506 player_copy_offset_loop:
509 lda _PlayerBuffer,y ; Y for reading
513 sta _PlayerBuffer,x ; X for writing
517 bne player_copy_offset_loop
519 stx _BufferFrameOffset
520 sta _PlayerRegCurrentValue
528 ; Size in bits of each PSG register
543 ; Chanel sound generator
562 .res 1,0 ; must be equal to 0
564 .res 1,0 ; must be equal to 0
568 _RegisterChanAFrequency:
573 _RegisterChanBFrequency:
578 _RegisterChanCFrequency:
583 _RegisterChanNoiseFrequency:
584 ; Chanel sound generator
591 _RegisterChanAVolume:
593 _RegisterChanBVolume:
595 _RegisterChanCVolume:
605 _PlayerRegCurrentValue:
610 _InterruptCallBack_3: ; Used by the music player
611 jsr _DoNothing ; Transformed to "jsr _Mym_PlayFrame" -> 12 cycles
613 ; jsr MiniScrollLoading ; -> 338 cycles
623 .res 256*14 ; About 3.5 kilobytes somewhere in memory, we put the music file in overlay memory