-
Notifications
You must be signed in to change notification settings - Fork 2
/
MidiJoy2.asm
2075 lines (1925 loc) · 47.2 KB
/
MidiJoy2.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; MidiJoy (c) 2014 by Frederik Holst
run start
DOSVEC = $0a
ATTRACT = $4d
SDMCTL = $22f
SDLSTL = $230
CH = $2fc
TRIG0 = $d010
TRIG1 = $d011
CONSOL = $d01F
AUDF1 = $d200
AUDC1 = $d201
AUDCTL = $d208
KBCODE = $d209
PMCFG = $d20c
SKCTL = $d20f
PMCAP = $d211
PSGMODE = $d215
FREQ1 = $d240
SQPW1 = $d243
WAVE1 = $d244
ATTDEC1 = $d245
SUSTREL1 = $d246
SIDVOLUME = $d258
PSGFREQ = $d2a0
PSGNFREQ = $d2a6
PSGMIXER = $d2a7
PSGVOL = $d2a8
PSGEFREQ = $d2ab
PSGESHP = $d2ad
PORTA = $d300
PACTL = $d302
ADSRStart = $5f00
ADSRTable = ADSRStart+17
; ADSRTable = ADSRMax+4
org $80
VOICE .byte 0
CHANNEL .byte 0
NOTE .byte 0, 0
NOTETIMER .word 0
NOTEPTR .word $6000
TEMPPTR .word 0
PLAYPTR .word $6000
PLAYAUDC .byte 0
PLAYNOTE .byte 0
PLAYTIMER .word 0
TIME .byte 0
TEMP .byte 0
TEMP2 .byte 0
MINUS
ACTL .byte 0, 0, 0, 0
AC1 .byte $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0, $a0
SIDWAVE .byte 32, 32, 32, 32, 32, 32
SIDAttack .byte 0, 0, 0, 0, 0, 0
SIDDecay .byte 0, 0, 0, 0, 0, 0
SIDRelease .byte 0, 0, 0, 0, 0, 0
SIDSqPw .byte 8, 8, 8, 8, 8, 8
PSGMix .byte $38, $38
PSGEnvAct .byte 0, 0, 0, 0, 0, 0
PSGEnvShape .byte 0, 0
PSGEnvFqLo .byte 0, 0
PSGEnvFqHi .byte 0, 0
PSGNoise .byte 0, 0
MSGSAVE .byte $ff
PITCH .byte 0
VELOCITY .byte 0
PITCHBEND .byte 0
D12FLAG .byte 0
SXBITFLAG .byte 0
RECFLAG .byte 0
PLAYFLAG .byte 0
PORTASAVE .byte 128
VOICESAVE .byte 255
ADSRVol .byte 0
ADSRDist .byte 0
ADSRTemp .byte 0
POKEYOffset .byte 0, 2, 4, 6, 16, 18, 20, 22, 32, 34, 36, 38, 48, 50, 52, 54
AUDCOffset .byte 106, 117, 146, 157
;RelOffset .byte Rel1-ADS1, Rel2-ADS2, Rel3-ADS3, Rel4-ADS4 ; these can be adjusted if you need a longer release phase at the cost of shorter ADS phase
;RelMax .byte ADS2-ADS1, ADS3-ADS2, ADS4-ADS3, ENDADSR-ADS4
EnvSrc .word 0
EnvSelect .byte 0
CHTemp .byte 0
EquOffset .word 0
PMDevice .byte 0
PMConfig .byte 0
ChipCount .byte 1
ChipFlag .byte 0
org $3c00
DLIST .byte $70, $70, $70, $42
ScreenMem .word INTRO
.byte 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
.byte $41
.word DLIST
start
lda PMCFG
cmp #1
bne setupDL
lda #$3f
sta PMCFG
lda #101
sta PSGMODE
lda PMCAP
sta PMConfig
and #3 ; number of POKEYs
asl
bne store
lda #1
store sta ChipCount
lda #0
sta PMCFG
setupDL lda #<DLIST ; set up display list
sta SDLSTL
lda #>DLIST
sta SDLSTL+1
lda #%00100010
sta SDMCTL
lda #56
sta PACTL
lda #%10000000 ; set all lines for input except Player 2 Right (port 2 pin 4)
sta PORTA
lda #60
sta PACTL
lda #0
sta AUDCTL
sta AUDCTL+$10
sta AUDCTL+$20
sta AUDCTL+$30
lda #3
sta SKCTL
sta SKCTL+$10
sta SKCTL+$20
sta SKCTL+$30
lda #15
sta SIDVOLUME
sta SIDVOLUME+$20
ldy #<VBI ; set up VBI
ldx #>VBI
lda #6
jsr $e45c
MainLoop lda 20
cmp TIME
beq novbi
sta TIME
jsr playadsr
novbi lda CONSOL ; test for OPTION and SELECT key
cmp #3
beq changeID
cmp #5
beq changeCore
checkkeys lda CH
sta CHTemp
cmp #255
bne jmpcheck
jmp nokey
jmpcheck jmp checkinput
changeId lda CONSOL
and #4
beq changeId ; wait for OPTION key to be released
lda PMDevice
clc
adc #1
cmp ChipCount ; rollover?
bcc setId
lda #0
setId sta PMDevice
clc
adc #$11
ldy #6 ; Device number position for POKEY, will be different for other soundchips
sta Device,y
bne checkkeys ; always greater than 0, jump to checkkeys
changeCore lda CONSOL ; wait for SELECT to be releasesd
and #2
beq changeCore
lda #0
sta PMDevice
lda ChipFlag
beq writeSID
cmp #1
beq writePSG
cmp #2
beq writePOKEY
; bne checkkeys
writeSID lda PMConfig
and #4
clc
ror
sta ChipCount
ldy #6
nextchar1 lda SIDText,y
sta Device,y
dey
bpl nextchar1
ldy #119
SIDlines lda SIDStats,y
sta ConfigLines,y
dey
bpl SIDLines
lda #1
sta ChipFlag
bne checkkeys
lda #0
ldy #39
CleanSID sta ConfigLines+120,y
dey
bpl cleanSID
writePSG lda PMConfig
and #8
clc
ror
ror
sta ChipCount
ldy #6
nextchar3 lda PSGText,y
sta Device,y
dey
bpl nextchar3
ldy #0
PSGlines lda PSGStats,y
sta ConfigLines,y
iny
cpy #132
bne PSGlines
lda #2
sta ChipFlag
bne jmpchkkeys
writePOKEY lda PMConfig
and #3
asl
sta ChipCount
ldy #6
nextchar2 lda POKEYText,y
sta Device,y
dey
bpl nextchar2
ldy #79
Pokeylines lda PokeyStats,y
sta ConfigLines,y
dey
bpl PokeyLines
lda #0
sta ChipFlag
lda #0
ldy #79
CleanPOKEY sta ConfigLines+80,y
dey
bpl cleanPOKEY
jmpchkkeys jmp checkkeys
checkinput lda #255
sta CH
; Functions applicable to all soundchips go here...
exitdos lda CHTemp
cmp #$1C
bne enter
lda #255
sta CHTemp
jmp (DOSVEC)
enter lda CHTemp
cmp #$0C
bne TestKeys
lda #255
sta CHTemp
lda #0
sta RECFLAG
sta 712
ldx #15
resetsound lda POKEYoffset,x
tay
lda #0
sta AUDC1,y
dex
bpl resetsound
; lda #0
sta NOTETIMER
sta NOTETIMER+1
sta NOTEPTR
sta PLAYPTR
lda #$60
sta NOTEPTR+1
sta PLAYPTR+1
lda #"5"
sta COUNTER
lda #"F"
sta COUNTER+1
sta COUNTER+2
sta COUNTER+3
lda #0
sta PITCHBEND
lda #8 ; unblock potential noise generator lockups on SID
sta WAVE1
sta WAVE1+$07
sta WAVE1+$0E
sta WAVE1+$20
sta WAVE1+$27
sta WAVE1+$2E
lda #0
sta WAVE1
sta WAVE1+$07
sta WAVE1+$0E
sta WAVE1+$20
sta WAVE1+$27
sta WAVE1+$2E
sta PSGVOL
sta PSGVOL+1
sta PSGVOL+2
sta PSGVOL+16
sta PSGVOL+17
sta PSGVOL+18
TestKeys lda ChipFlag
beq PokeyKeys
cmp #1
beq jmpSIDKeys
jmp PSGKeys
jmpSIDKeys jmp SIDKeys
; Keys for POKEY functions go here...
PokeyKeys ldx #7
nb1 lda AUDCTLKeys,x ; read AUDCTL-Keys (Q-Y)
cmp CHTemp
beq sb
dex
bpl nb1
bmi audckey
sb lda #255
sta CHTemp
lda AUDCTLVals,x
ldy PMDevice
eor ACTL,y
sta ACTL,y
audckey ldx #11 ; read AUDC1-4 keys (A-H, Z-N)
nb2 lda ACKeys,x
cmp CHTemp
beq sb2
dex
bpl nb2
bmi envkey
sb2 lda #255
sta CHTemp
lda PMDevice ; read device id
asl ; multiply by four
asl
clc
adc ACIndex,x ; add the index
tay ; transfer to Y as final index to AC1
lda ACVals,x
eor AC1,y ; invert previous bit status
sta AC1,y ; and store back
envkey ldx #0 ; read envelope keys (1-8)
nb3 lda EnvKeys,x
cmp CHTemp
beq sb3
inx
cpx #9
bne nb3
beq spacekey
sb3 lda #255
sta CHTemp
txa
sta EnvSelect
clc
adc #$34
sta EnvSrc+1
nextenv lda (EnvSrc),y
sta $5f00,y
dey
bne nextenv
ldy #15
ClearADSR lda #1
sta ADSRC,y
lda #0
sta ADSRActive,y
dey
bpl ClearADSR
ldy #0
nextbank tya
cmp EnvSelect
clc
bne contenv
adc #128
contenv adc #"1"
sta EnvBank,y
iny
cpy #8
bne nextbank
spacekey lda CHTemp
cmp #$21
bne pauserec
lda #255
sta CHTemp
lda D12FLAG
eor #1
sta D12FLAG
pauserec lda CHTemp
cmp #$2c
bne playkey
lda #255
sta CHTemp
lda RECFLAG
eor #1
sta RECFLAG
asl
asl
asl
asl
asl
sta 712
playkey lda CHTemp
cmp #$0a
bne jmpnokey
jmp playram
jmpnokey jmp nokey
SIDKeys ldx #11
readSIDWave lda SIDWaveKeys,x
cmp CHTemp
beq SetSIDWave
dex
bpl readSIDWave
bmi SIDAtt
SetSIDWave jsr getSIDindex
lda SIDWaveVals,x ; SIDWaveVals' index is 0 to 11
eor SIDWAVE,y
sta SIDWAVE,y
dex
bpl readSIDWave
SIDAtt ldx #2
readSIDAtt lda CHTemp
cmp SIDAttKeys,x
beq SetSIDAtt
sec
sbc #64
cmp SIDAttKeys,x
beq AttMinus
dex
bpl readSIDAtt
bmi SIDDec
AttMinus lda #0
SetSIDAtt sta MINUS
jsr getregindex ; index is in Y
lda SIDAttack,y
jsr storereg
sta SIDAttack,y
dex
bpl readSIDAtt
SIDDec ldx #2
readSIDDec lda CHTemp
cmp SIDDecKeys,x
beq SetSIDDec
sec
sbc #64
cmp SIDDecKeys,x
beq DecMinus
dex
bpl readSIDDec
bmi SIDRel
DecMinus lda #0
SetSIDDec sta MINUS
jsr getregindex ; index is in Y
lda SIDDecay,y
jsr storereg
sta SIDDecay,y
dex
bpl readSIDDec
SIDRel ldx #2
readSIDRel lda CHTemp
cmp SIDRelKeys,x
beq SetSIDRel
sec
sbc #64
cmp SIDRelKeys,x
beq RelMinus
dex
bpl readSIDRel
bmi SIDPW
RelMinus lda #0
SetSIDRel sta MINUS
jsr getregindex ; index is in Y
lda SIDRelease,y
jsr storereg
sta SIDRelease,y
dex
bpl readSIDRel
SIDPW ldx #2
readSIDPw lda CHTemp
cmp SIDPwKeys,x
beq SetSIDPw
sec
sbc #64
cmp SIDPwKeys,x
beq PwMinus
dex
bpl readSIDPw
bmi noSIDkeys
PwMinus lda #0
SetSIDPw sta MINUS
jsr getregindex ; index is in Y
lda SIDSqPw,y
jsr storereg
sta SIDSqPw,y
dex
bpl readSIDPw
noSIDkeys jmp nokey
PSGKeys ldx #5
readPSGMix lda PSGMixKeys,x
cmp CHTemp
beq SetPSGMix
dex
bpl readPSGMix
bmi Noise
SetPSGMix lda #255
sta CHTemp
ldy PMDevice
lda PSGMixVals,x
eor PSGMix,y
sta PSGMix,y
dex
bpl readPSGMix
Noise lda CHTemp
cmp #$0b
beq SetNoise
sec
sbc #64
cmp #$0b
beq NoiseMinus
bne EnvFreqLo
NoiseMinus lda #0
SetNoise sta MINUS
lda #255
sta CHTemp
ldy PMDevice
lda PSGNoise,y
jsr storereg
sta PSGNoise,y
EnvFreqLo lda CHTemp
cmp #$3d
beq SetEnvFqLo
sec
sbc #64
cmp #$3d
beq FqLoMinus
bne EnvFreqHi
FqLoMinus lda #0
SetEnvFqLo sta MINUS
lda #255
sta CHTemp
ldy PMDevice
lda PSGEnvFqLo,y
jsr storereg
sta PSGEnvFqLo,y
EnvFreqHi lda CHTemp
cmp #$39
beq SetEnvFqHi
sec
sbc #64
cmp #$39
beq FqHiMinus
bne ActEnv
FqHiMinus lda #0
SetEnvFqHi sta MINUS
lda #255
sta CHTemp
ldy PMDevice
lda PSGEnvFqHi,y
jsr storereg
sta PSGEnvFqHi,y
ActEnv ldx #2
readActEnv lda PSGEnvKeys,x
cmp CHTemp
beq SetActEnv
dex
bpl readActEnv
bmi EnvShape
SetActEnv lda #255
sta CHTemp
jsr getregindex
lda PSGEnvAct,y
eor #128
sta PSGEnvAct,y
dex
bpl readActEnv
EnvShape ldx #3
readEnvKeys lda EnvShpKeys,x
cmp CHTemp
beq SetEnvShape
dex
bpl readEnvKeys
bmi nokey
SetEnvShape lda #255
sta CHTemp
ldy PMDevice
lda EnvShpVals,x
eor PSGEnvShape,y
sta PSGEnvShape,y
dex
bpl readEnvKeys
nokey lda ChipFlag
beq PokeyWorks
cmp #1
beq jmpSIDWorks
jmp PSGWorks
jmpSIDWorks jmp SIDWorks
PokeyWorks lda PMDevice ; POKEY number 1-4 (0-3)
tay
asl
asl ; multiply by four to get PokeyOffset index
pha ; save
lda ACTL,y ; to get AUDCTL value of respective POKEY
sta TEMP ; store temporarily
pla ; get back PokeyOffset index
tay
lda PokeyOffset,y ; and get the actual PokeyOffset
tay ; use as index
lda TEMP ; get back AUDCTL value
sta AUDCTL,y ; and store in the respective AUDCTL
ldy #95 ; display AUDCTL bits on screen
ldx #8
jsr showbits
ldy #3 ; display AUDC1-4 bits 5-7 on screen
nextaudc tya
pha
sta TEMP
lda PMDevice
asl
asl
clc
adc TEMP
tay
lda AC1,y
clc
ror
ror
ror
ror
ror
sta TEMP
pla
pha
tay
lda AUDCOffset,y
tay
ldx #3
jsr showbits
pla
tay
dey
; cpy #0
bpl nextaudc
jmp receiveMIDI
SIDWorks ldy #2
nextwave lda PMDevice
cmp #1
beq sid2wave
lda SIDWAVE,y
jmp gowave
sid2wave lda SIDWAVE+3,y
gowave sta TEMP
ldx #3
nextwavebit tya ; save Y and X...
pha
txa
pha
tya
clc ; calculate position for SIDWavePos
asl
asl
sta TEMP2
txa
ora TEMP2
tax
lda SIDWavePos,x
tay
pla
tax
lda TEMP
and #128
bne waveset
beq wavenotset
waveset lda WaveTxt,x
ora #128
bne writewave
wavenotset lda WaveTxt,x
writewave sta INTRO+120,y
pla
tay
lda TEMP
asl
sta TEMP
dex
bpl nextwavebit
dey
bpl nextwave
; SID envelope data
ldx #2
ldy #100
nextatt lda PMDevice
cmp #1
beq sid2att
lda SIDAttack,x
bcc goatt
sid2att lda SIDAttack+3,x
goatt jsr dispEnv
tya
sec
sbc #40
tay
dex
bpl nextatt
ldx #2
ldy #106
nextdec lda PMDevice
cmp #1
beq sid2dec
lda SIDDecay,x
bcc godec
sid2dec lda SIDDecay+3,x
godec jsr dispEnv
tya
sec
sbc #40
tay
dex
bpl nextdec
ldx #2
ldy #112
nextrel lda PMDevice
cmp #1
beq sid2rel
lda SIDRelease,x
bcc gorel
sid2rel lda SIDRelease+3,x
gorel jsr dispEnv
tya
sec
sbc #40
tay
dex
bpl nextrel
ldx #2
ldy #118
nextpw lda PMDevice
cmp #1
beq sid2pw
lda SIDSqPw,x
bcc gopw
sid2pw lda SIDSqPw+3,x
gopw jsr dispEnv
tya
sec
sbc #40
tay
dex
bpl nextpw
jmp receiveMIDI
PSGWorks ldy PMDevice ; Mixer
lda PSGMix,y
sta TEMP
ldx #5
nextMixBit lda TEMP
and #1
bne MixNotSet
beq MixSet
MixSet lda MixerTxt,x
ora #128
bne writemix
MixNotSet lda MixerTxt,x
writemix sta INTRO+126,x
lda TEMP
clc
ror
sta TEMP
dex
bpl nextMixBit
ldx #2 ; Active Envelopes
ldy #35
nextactenv lda PMDevice
cmp #1
beq psg2ae
lda PSGEnvACt,x
bcc goactenv
psg2ae lda PSGEnvAct+3,x
goactenv sta TEMP
lda EnvActTxt,x
ora TEMP
sta INTRO+120,y
dey
dex
bpl nextactenv
ldy PMDevice ; Envelope Shape
lda PSGEnvShape,y
sta TEMP
ldx #3
ldy #76
nextshpbit lda TEMP
and #1
bne shapeset
beq shapenotset
shapeset lda EnvShpTxt,x
ora #128
bne writeshape
shapenotset lda EnvShpTxt,x
writeshape sta INTRO+120,y
lda TEMP
clc
ror
sta TEMP
dey
dex
bpl nextshpbit
ldy #134 ; Noise Frequency
ldx PMDevice
lda PSGNoise,x
jsr dispEnv
ldy #94 ; Envelope Frequency Lo
ldx PMDevice
lda PSGEnvFqLo,x
jsr dispEnv
ldy #113 ; Envelope Frequency Hi
ldx PMDevice
lda PSGEnvFqHi,x
jsr dispEnv
receiveMIDI lda #$80 ; set control line to "ready"
sta PORTA
jsr wait ; Give the Teensy a little bit time to interpret the "ready" signal and get all lines set up...
lda TRIG0 ; Trigger Port 1 contains Bit 1 of message number
asl
clc
adc TRIG1 ; Trigger Port 2 contains Bit 0 of message number
sta TEMP
ldy #0
sty PORTA ; Set control line to "not ready" while we do other stuff...
sty ATTRACT
cmp MSGSAVE ; do we have the same message number as last time?
bne parseMsg ; if no, then parse message
cmp #3 ; special case: msg type 03 (pitch bend) can occur repeatedly during a note is played
bne jmain
lda TEMP
and #$7f
cmp PITCHBEND
bne parseMsg
jmain jmp MainLoop ; otherwise back to square one
wait ldy #8 ; a few dozen cycles shall do...
w1 dey
bne w1
rts
parseMsg sta MSGSAVE
cmp #0
beq setVoice
cmp #1
beq setVelocity
cmp #2
beq setPitch
cmp #3
beq setAux
contparse lda #255
sta CHTemp
lda VOICE
cmp #22
bcs jmpPSG
cmp #16
bcs jmpSID
bne playPOKEY
jmpSID jmp playSID
jmpPSG jmp playPSG
setVoice lda PORTA
and #31
sta VOICE
lda PORTA
and #96
clc
ror
ror
ror
sta CHANNEL
lda MSGSAVE ; restore accumulator
jmp contparse
setVelocity lda PORTA
and #15
sta VELOCITY
lda PORTA
and #48
clc
ror
ror
ror
ror
ora CHANNEL
sta CHANNEL
lda MSGSAVE
jmp contparse
setPitch lda PORTA
and #$7f
sta PITCH
lda MSGSAVE
jmp contparse
setAux lda PORTA
and #$7f
clc
rol
sta PITCHBEND
lda MSGSAVE
jmp contparse
playPOKEY
/*
stx VOICESAVE
sta MIDI ; and store in variable
sta TEMP
*/
ldy PMDevice
lda VOICE ; Check for 16-bit voices (Midi-Channel 1 and 3)
and #3
cmp #2
beq checkv3
cmp #0
bne nosxbit
lda ACTL,y ; Voice 1 16-bit?
and #%00010000 ; Compare with AUDCTL-Bit 4
bne sxbit
beq nosxbit
checkv3 lda ACTL,y ; Voice 3 16-bit?
and #%00001000 ; Compare with AUDCTL-Bit 3