/[projet1]/public/oric/mym_player/mymplayer.s
Defence Force logotype

Contents of /public/oric/mym_player/mymplayer.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1073 - (show annotations)
Sun Jan 12 19:46:23 2014 UTC (5 years, 10 months ago) by dbug
File size: 12186 byte(s)
First version of the revamped mym player tool chain.
1
2 .zero
3
4 *=$50
5
6 _DecodedByte .dsb 1 ; Byte being currently decoded from the MYM stream
7 _DecodeBitCounter .dsb 1 ; Number of bits we can read in the current byte
8 _DecodedResult .dsb 1 ; What is returned by the 'read bits' function
9
10 _CurrentAYRegister .dsb 1 ; Contains the number of the register being decoded
11
12 _RegisterBufferHigh .dsb 1 ; Points to the high byte of the decoded register buffer, increment to move to the next register
13 _BufferFrameOffset .dsb 1 ; From 0 to 127, used when filling the decoded register buffer
14
15 _MusicResetCounter .dsb 2 ; Contains the number of rows to play before reseting
16
17 _CurrentFrame .dsb 1 ; From 0 to 255 and then cycles... the index of the frame to play this vbl
18
19 _PlayerVbl .dsb 1
20 _MusicLooped .dsb 1
21
22 _FrameLoadBalancer .dsb 1 ; We depack a new frame every 9 VBLs, this way the 14 registers are evenly depacked over 128 frames
23
24
25 .text
26
27 #define VIA_1 $30f
28 #define VIA_2 $30c
29
30 *=$6500 ; Actual start address of the player
31
32 #define _PlayerBuffer $6800 ; .dsb 256*14 (About 3.5 kilobytes)
33 #define _PlayerBufferEnd $7600
34
35 #define _MusicData $7600 ; Musics are loaded in $7600, between the player buffer and the redefined character sets
36
37 MymPlayerStart
38 jmp StartMusic ; Call #6500 to start the music
39 jmp EndMusic ; Call #6503 to stop the music
40
41 StartMusic
42 php
43 pha
44 sei
45
46 clc
47 lda $fffe
48 adc #1
49 sta __auto_1+1
50 sta __auto_3+1
51 sta __auto_5+1
52 lda $ffff
53 adc #0
54 sta __auto_1+2
55 sta __auto_3+2
56 sta __auto_5+2
57
58 clc
59 lda $fffe
60 adc #2
61 sta __auto_2+1
62 sta __auto_4+1
63 sta __auto_6+1
64 lda $ffff
65 adc #0
66 sta __auto_2+2
67 sta __auto_4+2
68 sta __auto_6+2
69
70 ; Save the old handler value
71 __auto_1
72 lda $245
73 sta jmp_old_handler+1
74 __auto_2
75 lda $246
76 sta jmp_old_handler+2
77
78 ; Install our own handler
79 lda #<irq_handler
80 __auto_3
81 sta $245
82 lda #>irq_handler
83 __auto_4
84 sta $246
85
86 jsr _Mym_Initialize
87
88 pla
89 plp
90 rts
91
92
93 EndMusic
94 php
95 pha
96 sei
97
98 ; Restore the old handler value
99 lda jmp_old_handler+1
100 __auto_5
101 sta $245
102 lda jmp_old_handler+2
103 __auto_6
104 sta $246
105
106 ; Stop the sound
107 lda #8
108 ldx #0
109 jsr WriteRegister
110
111 lda #9
112 ldx #0
113 jsr WriteRegister
114
115 lda #10
116 ldx #0
117 jsr WriteRegister
118
119 pla
120 plp
121 rts
122
123
124 _50hzFlipFlop .byt 0
125
126 irq_handler
127 pha
128 txa
129 pha
130 tya
131 pha
132
133 ; This handler runs at 100hz if comming from the BASIC,
134 ; but the music should play at 50hz, so we need to call the playing code
135 ; only every second frame
136 lda _50hzFlipFlop
137 eor #1
138 sta _50hzFlipFlop
139 beq skipFrame
140
141 jsr _Mym_PlayFrame
142
143 skipFrame
144
145 pla
146 tay
147 pla
148 tax
149 pla
150
151 jmp_old_handler
152 jmp 0000
153
154 ; http://www.defence-force.org/ftp/oric/documentation/v1.1_rom_disassembly.pdf
155 ;
156 ; Oric Atmos ROM function W8912
157 ; Originally called with JSR F590
158 ; F590 08 PHP WRITE X TO REGISTER A 0F 8912.
159 ; F591 78 SEI
160 ; F592 8D 0F 03 STA $030F Send A to port A of 6522.
161 ; F595 A8 TAY
162 ; F596 8A TXA
163 ; F597 C0 07 CPY #$07 If writing to register 7, set
164 ; F599 D0 02 BNE $F59D 1/0 port to output.
165 ; F59B 09 40 ORA #$40
166 ; F59D 48 PHA
167 ; F59E AD 0C 03 LDA $030C Set CA2 (BC1 of 8912) to 1,
168 ; F5A1 09 EE ORA #$EE set CB2 (BDIR of 8912) to 1.
169 ; F5A3 8D 0C 03 STA $030C 8912 latches the address.
170 ; F5A6 29 11 AND #$11 Set CA2 and CB2 to 0, BC1 and
171 ; F5A8 09 CC ORA #$CC BDIR in inactive state.
172 ; F5AA 8D 0C 03 STA $030C
173 ; F5AD AA TAX
174 ; F5AE 68 PLA
175 ; F5AF 8D 0F 03 STA $030F Send data to 8912 register.
176 ; F5B2 8A TXA
177 ; F5B3 09 EC ORA #$EC Set CA2 to 0 and CB2 to 1,
178 ; F5B5 8D 0C 03 STA $030C 8912 latches data.
179 ; F5B8 29 11 AND #$11 Set CA2 and CB2 to 0, BC1 and
180 ; F5BA 09 CC ORA #$CC BDIR in inactive state.
181 ; F5BC 8D 0C 03 STA $030C
182 ; F5BF 28 PLP
183 ; F5C0 60 RTS
184
185 WriteRegister
186 .(
187 PHP ; WRITE X TO REGISTER A 0F 8912.
188 SEI
189 STA $030F ; Send A to port A of 6522.
190 TAY
191 TXA
192 CPY #$07 ; If writing to register 7, set
193 BNE skip ; 1/0 port to output.
194 ORA #$40
195 skip
196 PHA
197 LDA $030C ; Set CA2 (BC1 of 8912) to 1,
198 ORA #$EE ; set CB2 (BDIR of 8912) to 1.
199 STA $030C ; 8912 latches the address.
200 AND #$11 ; Set CA2 and CB2 to 0, BC1 and
201 ORA #$CC ; BDIR in inactive state.
202 STA $030C
203 TAX
204 PLA
205 STA $030F ; Send data to 8912 register.
206 TXA
207 ORA #$EC ; Set CA2 to 0 and CB2 to 1,
208 STA $030C ; 8912 latches data.
209 AND #$11 ; Set CA2 and CB2 to 0, BC1 and
210 ORA #$CC ; BDIR in inactive state.
211 STA $030C
212 PLP
213 RTS
214 .)
215
216
217
218 _PlayerCount .byt 0
219
220
221 ;
222 ; Current PSG values during unpacking
223 ;
224 _PlayerRegValues
225 _RegisterChanAFrequency
226 ; Chanel A Frequency
227 .byt 8
228 .byt 4
229
230 _RegisterChanBFrequency
231 ; Chanel B Frequency
232 .byt 8
233 .byt 4
234
235 _RegisterChanCFrequency
236 ; Chanel C Frequency
237 .byt 8
238 .byt 4
239
240 _RegisterChanNoiseFrequency
241 ; Chanel sound generator
242 .byt 5
243
244 ; select
245 .byt 8
246
247 ; Volume A,B,C
248 _RegisterChanAVolume
249 .byt 5
250 _RegisterChanBVolume
251 .byt 5
252 _RegisterChanCVolume
253 .byt 5
254
255 ; Wave period
256 .byt 8
257 .byt 8
258
259 ; Wave form
260 .byt 8
261
262 _PlayerRegCurrentValue .byt 0
263
264
265 _Mym_ReInitialize
266 .(
267 sei
268 lda #0
269 sta _MusicLooped
270 jsr _Mym_Initialize
271 cli
272 rts
273 .)
274
275 _Mym_Initialize
276 .(
277 ; The two first bytes of the MYM music is the number of rows in the music
278 ; We decrement that at each frame, and when we reach zero, time to start again.
279 ldx _MusicData+0
280 stx _MusicResetCounter+0
281 ldx _MusicData+1
282 inx
283 stx _MusicResetCounter+1
284
285 .(
286 ; Initialize the read bit counter
287 lda #<(_MusicData+2)
288 sta __auto_music_ptr+1
289 lda #>(_MusicData+2)
290 sta __auto_music_ptr+2
291
292 lda #1
293 sta _DecodeBitCounter
294
295 ; Clear all data
296 lda #0
297 sta _DecodedResult
298 sta _DecodedByte
299 sta _PlayerVbl
300 sta _PlayerRegCurrentValue
301 sta _BufferFrameOffset
302 sta _PlayerCount
303 sta _CurrentAYRegister
304 sta _CurrentFrame
305
306 ldx #14
307 loop_init
308 dex
309 sta _PlayerRegValues,x
310 bne loop_init
311 .)
312
313 ;
314 ; Unpack the 128 first register frames
315 ;
316 .(
317 lda #>_PlayerBuffer
318 sta _RegisterBufferHigh
319
320 ldx #0
321 unpack_block_loop
322 stx _CurrentAYRegister
323
324 ; Unpack that register
325 jsr _PlayerUnpackRegister2
326
327 ; Next register
328 ldx _CurrentAYRegister
329 inx
330 cpx #14
331 bne unpack_block_loop
332 .)
333
334 lda #128
335 sta _PlayerVbl+0
336
337 lda #0
338 sta _PlayerCount
339 sta _CurrentAYRegister
340 sta _CurrentFrame
341
342 lda #9
343 sta _FrameLoadBalancer
344 rts
345 .)
346
347
348
349 _Mym_PlayFrame
350 .(
351 ;
352 ; Check for end of music
353 ; CountZero: $81,$0d
354 dec _MusicResetCounter+0
355 bne music_contines
356 dec _MusicResetCounter+1
357 bne music_contines
358 music_resets
359 lda #1
360 sta _MusicLooped
361 jsr _Mym_Initialize
362
363 music_contines
364
365 ;
366 ; Play a frame of 14 registers
367 ;
368 .(
369 lda _CurrentFrame
370 sta _auto_psg_play_read+1
371 lda #>_PlayerBuffer
372 sta _auto_psg_play_read+2
373
374 ldy #0
375 register_loop
376
377 _auto_psg_play_read
378 ldx _PlayerBuffer
379
380 ; W8912
381 ; jsr $f590
382 ; a=register
383 ; x=value
384 pha
385 tya
386 pha
387 jsr WriteRegister
388 pla
389 tay
390 pla
391
392 /*
393 sty VIA_1
394 txa
395
396 pha
397 lda VIA_2
398 ora #$EE ; $EE 238 11101110
399 sta VIA_2
400
401 and #$11 ; $11 17 00010001
402 ora #$CC ; $CC 204 11001100
403 sta VIA_2
404
405 tax
406 pla
407 sta VIA_1
408 txa
409 ora #$EC ; $EC 236 11101100
410 sta VIA_2
411
412 and #$11 ; $11 17 00010001
413 ora #$CC ; $CC 204 11001100
414 sta VIA_2
415 */
416
417 inc _auto_psg_play_read+2
418 iny
419 cpy #14
420 bne register_loop
421 .)
422
423
424 inc _CurrentFrame
425 inc _PlayerCount
426
427 lda _CurrentAYRegister
428 cmp #14
429 bcs end_reg
430
431 .(
432 dec _FrameLoadBalancer
433 bne end
434
435 jsr _PlayerUnpackRegister
436 inc _CurrentAYRegister
437 lda #9
438 sta _FrameLoadBalancer
439 end
440 rts
441 .)
442
443 end_reg
444 .(
445 lda _PlayerCount
446 cmp #128
447 bcc skip
448
449 lda #0
450 sta _CurrentAYRegister
451 sta _PlayerCount
452 lda #9
453 sta _FrameLoadBalancer
454
455 clc
456 lda _PlayerVbl+0
457 adc #128
458 sta _PlayerVbl+0
459 skip
460 .)
461
462 rts
463 .)
464
465
466
467
468 ;
469 ; Initialise X with the number of bits to read
470 ; Y is not modifier
471 ; A is saved and restored..
472 ;
473 _ReadBits
474 pha
475
476 lda #0
477 sta _DecodedResult
478
479 ; Will iterate X times (number of bits to read)
480 loop_read_bits
481
482 dec _DecodeBitCounter
483 bne end_reload
484
485 ; reset mask
486 lda #8
487 sta _DecodeBitCounter
488
489 ; fetch a new byte, and increment the adress.
490 __auto_music_ptr
491 lda _MusicData+2
492 sta _DecodedByte
493
494 inc __auto_music_ptr+1
495 bne end_reload
496 inc __auto_music_ptr+2
497 end_reload
498
499 asl _DecodedByte
500 rol _DecodedResult
501
502 dex
503 bne loop_read_bits
504
505 pla
506 rts
507
508
509
510
511
512 _PlayerUnpackRegister
513 lda #>_PlayerBuffer
514 clc
515 adc _CurrentAYRegister
516 sta _RegisterBufferHigh
517 _PlayerUnpackRegister2
518 ;
519 ; Init register bit count and current value
520 ;
521 ldx _CurrentAYRegister
522 lda _PlayerRegValues,x
523 sta _PlayerRegCurrentValue
524
525
526 ;
527 ; Check if it's packed or not
528 ; and call adequate routine...
529 ;
530 ldx #1
531 jsr _ReadBits
532 ldx _DecodedResult
533 bne DecompressFragment
534
535
536 UnchangedFragment
537 .(
538 ;
539 ; No change at all, just repeat '_PlayerRegCurrentValue' 128 times
540 ;
541 lda _RegisterBufferHigh ; highpart of buffer adress + register number
542 sta __auto_copy_unchanged_write+2
543
544 ldx #128 ; 128 iterations
545 lda _PlayerRegCurrentValue ; Value to write
546
547 ldy _PlayerVbl
548
549 repeat_loop
550 __auto_copy_unchanged_write
551 sta _PlayerBuffer,y
552 iny
553 dex
554 bne repeat_loop
555 .)
556
557 jmp player_main_return
558
559
560 player_main_return
561 ; Write back register current value
562 ldx _CurrentAYRegister
563 lda _PlayerRegCurrentValue
564 sta _PlayerRegValues,x
565
566 ; Move to the next register buffer
567 inc _RegisterBufferHigh
568 rts
569
570
571
572
573 DecompressFragment
574 lda _PlayerVbl ; Either 0 or 128 at this point else we have a problem...
575 sta _BufferFrameOffset
576
577 decompressFragmentLoop
578
579 player_copy_packed_loop
580 ; Check packing method
581 ldx #1
582 jsr _ReadBits
583
584 ldx _DecodedResult
585 bne PlayerNotCopyLast
586
587 UnchangedRegister
588 .(
589 ; We just copy the current value 128 times
590 lda _RegisterBufferHigh ; highpart of buffer adress + register number
591 sta player_copy_last+2
592
593 ldx _BufferFrameOffset ; Value between 00 and 7f
594 lda _PlayerRegCurrentValue ; Value to copy
595 player_copy_last
596 sta _PlayerBuffer,x
597
598 inc _BufferFrameOffset
599 .)
600
601
602 player_return
603
604 ; Check end of loop
605 lda _BufferFrameOffset
606 and #127
607 bne decompressFragmentLoop
608
609 jmp player_main_return
610
611
612 PlayerNotCopyLast
613 ; Check packing method
614 ldx #1
615 jsr _ReadBits
616
617 ldx _DecodedResult
618 beq DecompressWithOffset
619
620 ReadNewRegisterValue
621 ; Read new register value (variable bit count)
622 ldx _CurrentAYRegister
623 lda _PlayerRegBits,x
624 tax
625 jsr _ReadBits
626 ldx _DecodedResult
627 stx _PlayerRegCurrentValue
628
629 ; Copy to stream
630 lda _RegisterBufferHigh ; highpart of buffer adress + register number
631 sta player_read_new+2
632
633 ldx _BufferFrameOffset ; Value between 00 and 7f
634 lda _PlayerRegCurrentValue ; New value to write
635 player_read_new
636 sta _PlayerBuffer,x
637
638 inc _BufferFrameOffset
639 jmp player_return
640
641
642
643
644 DecompressWithOffset
645 .(
646 ; Read Offset (0 to 127)
647 ldx #7
648 jsr _ReadBits
649
650 lda _RegisterBufferHigh ; highpart of buffer adress + register number
651 sta __auto_write+2 ; Write adress
652 sta __auto_read+2 ; Read adress
653
654 ; Compute wrap around offset...
655 lda _BufferFrameOffset ; between 0 and 255
656 clc
657 adc _DecodedResult ; + Offset Between 00 and 7f
658 sec
659 sbc #128 ; -128
660 tay
661
662 ; Read count (7 bits)
663 ldx #7
664 jsr _ReadBits
665
666 inc _DecodedResult ; 1 to 129
667
668
669 ldx _BufferFrameOffset
670
671 player_copy_offset_loop
672
673 __auto_read
674 lda _PlayerBuffer,y ; Y for reading
675 iny
676
677 __auto_write
678 sta _PlayerBuffer,x ; X for writing
679
680 inc _BufferFrameOffset
681
682 inx
683 dec _DecodedResult
684 bne player_copy_offset_loop
685
686 sta _PlayerRegCurrentValue
687
688 jmp player_return
689 .)
690
691
692
693 ;
694 ; Size in bits of each PSG register
695 ;
696 _PlayerRegBits
697 ; Chanel A Frequency
698 .byt 8
699 .byt 4
700
701 ; Chanel B Frequency
702 .byt 8
703 .byt 4
704
705 ; Chanel C Frequency
706 .byt 8
707 .byt 4
708
709 ; Chanel sound generator
710 .byt 5
711
712 ; select
713 .byt 8
714
715 ; Volume A,B,C
716 .byt 5
717 .byt 5
718 .byt 5
719
720 ; Wave period
721 .byt 8
722 .byt 8
723
724 ; Wave form
725 .byt 8
726

  ViewVC Help
Powered by ViewVC 1.1.26