/
yamaha_dx7_rom_v1.8.asm
16789 lines (13991 loc) · 459 KB
/
yamaha_dx7_rom_v1.8.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
; ==============================================================================
; YAMAHA DX7 V1.8 ROM DISASSEMBLY
; Annotated by AJXS: https://ajxs.me/ https://github.com/ajxs
; ==============================================================================
; ==============================================================================
; Hitachi 6303 IO Port Registers.
; The addresses of the Hitachi 6303 CPU's internal IO port registers.
; ==============================================================================
IO_PORT_1_DIR: equ 0
IO_PORT_2_DIR: equ 1
IO_PORT_1_DATA: equ 2
IO_PORT_2_DATA: equ 3
IO_PORT_3_DIR: equ 4
IO_PORT_4_DIR: equ 5
IO_PORT_3_DATA: equ 6
IO_PORT_4_DATA: equ 7
TIMER_CTRL_STATUS: equ 8
FREE_RUNNING_COUNTER: equ 9
OUTPUT_COMPARE: equ $B
RATE_MODE_CTRL: equ $10
SCI_CTRL_STATUS: equ $11
SCI_RECEIVE: equ $12
SCI_TRANSMIT: equ $13
; ==============================================================================
; Peripheral Addresses.
; These constants are the addresses of the synth's various peripherals.
; These are mapped into the CPU's address space via the use of an Intel 8255
; Peripheral Interface Controller.
; ==============================================================================
P_LCD_DATA: equ $2800
P_LCD_CTRL: equ $2801
; This peripheral is the 8255's 'IO Port C'. It is used to read the
; cartridge's state, as well as the portamento, and sustain pedal state.
; The 8255's C7 line is multiplexed with Port A's A7. This is used to read
; the LCD's ready state.
P_CRT_PEDALS_LCD: equ $2802
; The control register for the 8255 Programmable Peripheral Interface chip
; used to interface with the various peripherals on the address bus.
P_8255_CTRL: equ $2803
; The OPS 'Mode' register.
; Bit 7 = Mute. Bit 6 = Clear OSC Key Sync. Bit 5 = Set OSC Key Sync.
P_OPS_MODE: equ $2804
; The Ops Algorithm/Feedback register.
; Bits 0-2 = Feedback, Bits 3-7 = Algorithm Select.
P_OPS_ALG_FDBK: equ $2805
; Used to send the 3-bit analog volume value to the DAC.
P_DAC: equ $280A
P_ACEPT: equ $280C
P_LED1: equ $280E
P_LED2: equ $280F
; The EGS Voice Pitch register. Length: 32.
P_EGS_VOICE_PITCH: equ $3000
; The EGS Operator Pitch register. Length: 16.
P_EGS_OP_PITCH: equ $3020
P_EGS_OP_DETUNE: equ $3030
P_EGS_OP_EG_RATES: equ $3040
P_EGS_OP_EG_LEVELS: equ $3060
; Length: 6.
P_EGS_OP_LEVELS: equ $3080
P_EGS_OP_SENS_SCALING: equ $30E0
P_EGS_AMP_MOD: equ $30F0
; The 'Voice Events' register.
; This is not a buffer, it is the input to a shift register. Writing to this
; register triggers a key event on the EGS chip.
; Bit 0 = Key On, Bit 1 = Key Off, Bit 2-5 = Voice # 0-15.
P_EGS_VOICE_EVENTS: equ $30F1
P_EGS_PITCH_MOD_HIGH: equ $30F2
P_EGS_PITCH_MOD_LOW: equ $30F3
P_CRT_START: equ $4000
P_CRT_START_IC2: equ $4800
P_CRT_END: equ $5000
; ==============================================================================
; Intel 8255 'Control Words'.
; These constants are the 'Control Words' for the Intel 8255 Peripheral
; Interface Controller chip. This chip is used in the DX7 to interface with
; its various peripherals over the CPU's address bus.
; When sent to the control register, these constants control the chip's
; functionality, such as the 'direction' of the PIC's IO ports.
; ==============================================================================
I8255_CONTROL_WORD_5: equ %10001001
I8255_CONTROL_WORD_13: equ %10011001
; ==============================================================================
; LCD Controller Constants.
; The DX7 uses a KS0066U-compatible LCD module. These bitmasks are used to
; interface with the LCD controller.
; ==============================================================================
LCD_CTRL_RS: equ 1
LCD_CTRL_RW: equ 2
LCD_CTRL_RW_RS: equ 3
; RS=Low, RW=Low := Instruction Write.
LCD_CTRL_E: equ 4
LCD_CTRL_E_RS: equ 5
LCD_CTRL_E_RW: equ 6
LCD_BUSY_FLAG: equ $80
; ==============================================================================
; LCD Instruction Constants.
; The DX7 uses a KS0066U-compatible LCD module. These constants are instruction
; masks to be written to the LCD controller's instruction register.
; ==============================================================================
LCD_INSTR_CLEAR: equ 1
LCD_INSTR_SET_DIR: equ 6
LCD_INSTR_SET_BLINK_OFF: equ $C
LCD_INSTR_SET_BLINK_ON: equ $D
LCD_INSTR_SHIFT_CURSOR_LEFT: equ $10
LCD_INSTR_SHIFT_CURSOR_RIGHT: equ $14
LCD_INSTR_FUNC_SET_8BIT_2_LINE: equ $38
LCD_INSTR_SET_CURSOR_POSITION: equ $80
LCD_INSTR_SET_CURSOR_TO_LINE_2: equ $C0
; ==============================================================================
; Cartridge Status.
; These bitmasked flags indicate the physical status of the synth's cartridge
; interface. They are read from the 8255 peripheral controller's IO port C.
; ==============================================================================
CRT_FLAG_INSERTED: equ %100000
CRT_FLAG_PROTECTED: equ %1000000
; ==============================================================================
; Memory Protect Status.
; These bitmasked flags are used to store the status of the synth's
; firmware level memory protection.
; ==============================================================================
MEM_PROTECT_INT: equ %1000000
MEM_PROTECT_CRT: equ %10000000
; ==============================================================================
; Modulation Pedal Input Status.
; These bitmasked flags are used to determine the status of the synth's
; modulation pedal inputs. These are read from the 8255 peripheral
; controller's IO port C.
; ==============================================================================
PEDAL_STATUS_SUSTAIN_ACTIVE: equ 1
PEDAL_STATUS_PORTAMENTO_ACTIVE: equ %10
; Used to mask both pedal inputs, when reading both is necessary.
PEDAL_STATUS_MASK: equ %11
; ==============================================================================
; Patch Edit Buffer Status Flags.
; These flags determine the status of the synth's 'Patch Edit Buffer'.
; They determine whether the currently held patch has been edited, or whether
; it has been moved to the compare buffer.
; ==============================================================================
EDITED_PATCH_IN_WORKING: equ 1
EDITED_PATCH_IN_COMPARE: equ 2
; ==============================================================================
; MIDI Error Status.
; These constants are used to track the status of the MIDI buffers. If an error
; condition occurs, these constants will be written to the appropriate memory
; location. They are referenced in printing error messages.
; ==============================================================================
MIDI_STATUS_ERROR: equ 1
MIDI_STATUS_BUFFER_FULL: equ 2
; ==============================================================================
; Firmware Variables.
; These are the synth's firmware variables located in its internal memory.
; Locations from 0x80 to 0xFF are located in the CPU's internal memory. These
; memory locations are initialised by the synth's reset handler, and should be
; considered volatile. The remaining memory locations are persistent. This
; includes the internal patch memory.
; ==============================================================================
; The last key pressed on the synth's keyboard.
M_NOTE_KEY: equ $81
; The velocity of the last keyboard keypress.
M_NOTE_VEL: equ $82
; The status of the portamento, and sustain modulation pedals.
; Bit 0 = Sustain, Bit 1 = Portamento.
M_PEDAL_INPUT_STATUS: equ $83
; The incoming analog data read from the synth's various analog inputs.
; This variable is set in the main IRQ handler.
M_ANALOG_DATA: equ $84
; The source of the last read analog input event.
; The source will be one of the synth's analog inputs, such as the modulation
; wheel, keyboard, aftertouch, etc.
; This variable is set in the main IRQ handler.
M_ANALOG_DATA_SRC: equ $85
M_INPUT_ANALOG_UPDATE_MOD_TOGGLE: equ $86
; This variable stores the synth's up/down increment/decrement value.
; These values are set by either the up/down buttons, or the slider input.
; These value are to be considered a signed 8-bit value, and are used
; for arithmetic purposes. e.g: A numeric value with the 'No/Down'
; value added will be decremented by one.
M_UP_DOWN_INCREMENT: equ $87
; Bit 7 = CRT mem protect. Bit 6 = INT mem protect.
M_MEM_PROTECT_FLAGS: equ $88
; This flag states whether the last input event originated from the slider.
M_SLIDER_INPUT_EVENT: equ $89
; This variable holds which memory (Internal/Cartridge) is currently being
; changed when selecting memory protection ON/OFF.
M_MEM_PROTECT_MODE: equ $8A
; This flag variable is used suring cartridge saving and loading.
; It stores a 'Confirm' bit, which is used to indicate whether the user has
; 'confirmed' the current operation.
; Bit 7 = Read(0)/Write(1). Bit 0 = Confirm.
M_CRT_SAVE_LOAD_FLAGS: equ $8B
; This flag holds whether the 'Function' button is currently being held down.
M_BTN_FUNC_STATE: equ $8C
; When this flag is set the next keypress event will be used to set the
; synth's key transpose.
M_EDIT_KEY_TRANSPOSE_ACTIVE: equ $8D
M_MONO_ACTIVE_VOICE_COUNT: equ $8E
; The direction of legato, when the synth is in monophonic mode.
; 1 = Up, 0 = Down.
M_LEGATO_DIRECTION: equ $8F
M_NOTE_KEY_LAST: equ $90
M_MONO_SUSTAIN_PEDAL_ACTIVE: equ $91
M_SUB_CPU_READ_KEY: equ $92
; This flag stores whether the patch serialise/deserialise operation in the
; 'PATCH_READ_WRITE' subroutine is reading from memory, or writing to it.
; This is set by pressing the 'STORE' button.
M_PATCH_READ_OR_WRITE: equ $93
; 'Toggle' variable used to determine whether the keyboard scaling
; 'depth', or 'curve' values are currently being edited.
; This value is either 0x0, or 0xFF.
M_EDIT_KBD_SCALE_TOGGLE: equ $94
M_EDIT_EG_RATE_LVL_SUB_FN: equ $95
; Osc Mode/Sync Flag.
; This flag is used to determine whether the synth UI is currently editing
; the Oscillator Mode, or Oscillator Sync, based on cycling through these
; values using Button 17.
M_EDIT_OSC_MODE_SYNC_FLAG: equ $96
M_TEST_MODE_BUTTON_CHECK: equ $97
; This variable seems to hold the source of the last analog input event.
M_LAST_ANALOG_INPUT_EVENT: equ $98
; This flag is set when the 'Edit/Char' button is held down during
; editing a patch name. It causes the front panel buttons to input
; characters when pressed.
; Refer to page 46 of the DX7 manual.
M_EDIT_ASCII_MODE: equ $99
; This flag controls whether the synth checks for incoming 'Active Sensing'
; MIDI messages.
M_MIDI_ACTV_SENS_RX_ENABLE: equ $9A
; The incoming 'Active Sensing' check counter.
M_MIDI_ACTV_SENS_RX_CTR: equ $9B
; The computed frequency value of the last-pressed key.
; This is used when adding new voice events.
; All of the frequency values passed to the EGS' internal registers are stored
; in logarithmic format, with 1024 units per octave. The key transpose,
; and pitch EG values are stored in the same format.
M_KEY_PITCH: equ $9D
M_KEY_PITCH_LOW: equ $9E
M_KEY_EVENT_CURRENT: equ $AA
M_VOICE_NOTE_CURRENT: equ $AE
M_PITCH_BEND_INPUT_SIGNED: equ $B8
M_PITCH_BEND_STEP_VALUE: equ $B9
M_EG_BIAS_TOTAL_RANGE: equ $BA
M_VOICE_PITCH_GLISS_CURRENT: equ $BB
M_PORTA_PROCESS_LOOP_IDX: equ $BD
M_VOICE_PORTA_PITCH_FINAL: equ $BE
M_VOICE_PITCH_TARGET_PTR: equ $C0
M_VOICE_PITCH_PORTA_PTR: equ $C2
M_VOICE_PITCH_EG_CURR_LVL_PTR: equ $C4
M_PORTA_PITCH_INCREMENT: equ $C6
M_GLISSANDO_PITCH_LSB: equ $C7
M_EGS_PITCH_PTR: equ $C8
M_VOICE_PITCH_GLISS_PTR: equ $CA
; This variable is used as a loop counter when processing the pitch EG.
M_PITCH_EG_VOICE_INDEX: equ $CC
M_PITCH_EG_VOICE_LEVELS_PTR: equ $CD
M_PITCH_EG_VOICE_STEP_PTR: equ $CF
M_PITCH_EG_INCREMENT: equ $D1
M_PITCH_EG_NEXT_LVL: equ $D3
M_MOD_AMP_EG_BIAS_TOTAL: equ $D5
M_MOD_AMP_FACTOR: equ $D6
; The phase accumulator for the synth's LFO.
; This is set to its maximum value of 0x7FFF during the handling of a
; keypress if 'LFO Sync' is enabled.
M_LFO_PHASE_ACCUMULATOR: equ $D7
; The current amplitude of the synth's LFO wave.
M_LFO_CURR_AMPLITUDE: equ $D9
M_LFO_SAMPLE_HOLD_ACCUMULATOR: equ $DA
; The amount that LFO modulation should be scaled by during 'fade in'
; after the LFO delay elapses.
M_LFO_FADE_IN_SCALE_FACTOR: equ $DB
M_LFO_TRI_ACCUMULATOR: equ $DC
M_LFO_DELAY_COUNTER: equ $DD
; This flag variable is used to track whether the 'Sample+Hold' LFO needs to
; be 'resampled'. Each time the LFO counter overflows, the MSB is set/cleared.
M_LFO_SAMPLE_HOLD_RESET_FLAG: equ $DF
; The portamento rate increment.
; This is used when transitioning a voice's pitch during portamento
; processing. It is the increment/decrement calculated from the portamento
; 'rate' variable.
M_PORTA_RATE_INCREMENT: equ $E0
; The last read MIDI data byte.
M_MIDI_INCOMING_DATA: equ $E1
M_MIDI_SYSEX_CHECKSUM: equ $E2
; The number of MIDI data bytes processed during an incoming MIDI message.
; Specifically this is used to store the number of bytes that have been
; processed so far in the subroutine to handle incoming buffered MIDI data.
M_MIDI_PROCESSED_DATA_COUNT: equ $E7
M_MIDI_BUFFER_ERROR_CODE: equ $E8
; The MIDI transmit ring buffer's read, and write pointers.
M_MIDI_TX_BFR_WRITE_PTR: equ $EA
M_MIDI_TX_BFR_READ_PTR: equ $EC
; The MIDI receive ring buffer's read, and write pointers.
M_MIDI_RX_BFR_WRITE_PTR: equ $EE
M_MIDI_RX_BFR_READ_PTR: equ $F0
M_MIDI_SUBSTATUS: equ $F2
M_MIDI_SYSEX_PARAM_GRP: equ $F3
M_MIDI_SYSEX_RX_COUNT: equ $F4
M_MIDI_SYSEX_RX_DATA_COUNT: equ $F5
; This flag indicates whether there is pending received MIDI to be processed.
M_MIDI_RX_BUFFER_PENDING: equ $F6
; The last received MIDI status byte.
M_MIDI_STATUS_BYTE: equ $F7
; Whether 'SYS INFO AVAIL' is enabled on the synth.
M_MIDI_SYS_INFO_AVAIL: equ $F8
; These variables are used as pointers for the block copy subroutine.
; They point to the source, and destination addresses to copy from/to.
M_COPY_SRC_PTR: equ $F9
M_COPY_DEST_PTR: equ $FB
M_TEST_AD_STAGE_FLAGS: equ $FF
; The start address of the synth's external RAM chips.
M_EXTERNAL_RAM_START: equ $1000
; The address of the synth's 'Patch Edit Buffer'.
; This is where the currently loaded patch is stored in memory.
M_PATCH_CURRENT_BUFFER: equ $2000
M_PATCH_CURRENT_ALG: equ $2086
M_PATCH_CURRENT_LFO_DELAY: equ $208A
M_PATCH_CURRENT_LFO_SYNC: equ $208D
M_PATCH_CURRENT_TRANSPOSE: equ $2090
M_PATCH_CURRENT_NAME: equ $2091
M_PATCH_CURRENT_NAME_LAST_CHAR: equ $209A
M_PATCH_CURRENT_OPS_ON_OFF: equ $209B
; When the synth is placed in 'Compare Mode' the status of the operators for
; the current patch are stored here.
M_PATCH_COMPARE_OPS_ON_OFF: equ $209C
M_PATCH_CURRENT_NUMBER: equ $209D
; When the synth is placed in 'Compare Mode' the currently edited patch number
; will be stored in this variable.
M_PATCH_COMPARE_NUMBER: equ $209E
M_SELECTED_OPERATOR: equ $209F
; This variable holds the last input event source.
; In contrast to the last button variable, this variable also tracks input
; events from the front-panel slider.
M_LAST_INPUT_EVENT: equ $20A0
; The 'Input Mode' the synth is currently in.
; This is either, 'Play Mode', 'Edit Mode', or 'Function Mode'.
M_INPUT_MODE: equ $20A1
; The 0 indexed number of the last pressed button.
M_LAST_PRESSED_BTN: equ $20A2
; The parameter currently selected to be edited while in 'EDIT' mode.
M_EDIT_PARAM_CURRENT: equ $20A3
; This variable holds both whether Internal, or cartridge memory is selected,
; and the current 'UI Mode'. A value of 0 selects internal memory, a value of
; 1 selects cartridge. The other 'UI Mode' values are used to determine
; what specific function is being performed by the UI.
M_MEM_SELECT_UI_MODE: equ $20A4
; This variable holds the current patch's 'modified' state.
; A non-zero value here indicates that this patch has been edited.
; 0x2 = Edited patch in compare buffer. 0x1 = Currently editing patch.
M_PATCH_CURRENT_MODIFIED_FLAG: equ $20A5
M_PATCH_COMPARE_MODIFIED_FLAG: equ $20A6
M_PEDAL_INPUT_STATUS_PREVIOUS: equ $20A7
; The parameter currently selected to be edited while the synth is in
; 'Function' mode.
M_FN_PARAM_CURRENT: equ $20A8
; Whether the synth is configured to be polyphonic, or monophonic.
; 0 = Poly, 1 = Mono.
M_MONO_POLY: equ $20A9
; The synth's 'portamento mode'.
; Poly: 0 = Retain, 1 = Follow.
; Mono: 0 = Fingered, 1 = Full.
M_PORTA_MODE: equ $20AA
; This variable holds whether Glissando is ON/OFF.
M_PORTA_GLISS_ENABLED: equ $20AB
; The purpose of this variable is unknown, however it is set once to
; 0x7F on reset, and set to 0x7F on MIDI error.
M_ERR_HANDLING_FLAG: equ $20AC
; This variable holds the which 'sub-function' of button 8 in
; 'Function Mode' is currently selected.
; *0 = Edit MIDI RX ch.
; *1 = SYS INFO AVAIL?
; *2 = Transmit MIDI.
M_EDIT_BTN_8_SUB_FN: equ $20AD
M_PATCH_NAME_EDIT_ACTIVE: equ $20AE
; Whether the currently loaded patch is from internal, or cartridge memory.
; A non-zero value indicates the patch is loaded from the cartridge.
M_PATCH_CURRENT_CRT_OR_INT: equ $20AF
; Voice 'Status' buffer.
; This buffer stores the current status for each of the synth's voices.
; There are 2 byte entries for each of the 16 voices.
; The first byte stores the MIDI note that this voice is currently playing,
; the second byte stores the status of the note.
; The entry is cleared when a voice is removed in monophonic mode.
; Bit 0 = Sustain Active, Bit 1 = Note currently being held.
M_VOICE_STATUS: equ $20B0
; This section of RAM is used to store incoming MIDI performance data
; received over SYSEX.
; While this area normally holds the current voice event data, since this
; cannot be used while receiving a bulk SYSEX transfer, this area in memory
; doubles as a buffer to store incoming SYSEX data.
M_MIDI_PERF_DATA_BUFFER: equ $20B0
; This buffer holds the 'target' pitch of each of the synth's 16 voices.
; During the portamento/glissando processing subroutine, the individual
; voices transition from their 'current' pitch towards this pitch.
; This pitch is set by the main 'Voice add' subroutines.
M_VOICE_PITCH_TARGET: equ $20D0
; This buffer holds the 'portamento' pitch of each of the synth's 16 voices.
; During the portamento/glissando processing subroutine, if portamento is
; currently active the individual voices transition from this pitch towards
; their target pitch value. This pitch is set by the main
; 'Voice add' subroutines.
M_VOICE_PITCH_PORTAMENTO: equ $20F0
; This buffer holds the 'glissando' pitch of each of the synth's 16 voices.
; During the portamento/glissando processing subroutine, if glissando is
; currently active the individual voices transition from this pitch towards
; their target pitch value. This pitch is set by the main 'Voice add'
; subroutines.
M_VOICE_PITCH_GLISSANDO: equ $2110
; The current Pitch EG step for each of the synth's voices.
M_VOICE_PITCH_EG_CURR_STEP: equ $2130
; The current Pitch EG level for each of the synth's voices.
M_VOICE_PITCH_EG_CURR_LEVEL: equ $2140
; This array contains the quantised pitch EG rate and level values.
; Entries 0-3 contain the RATE values, 4-7 contain the LEVEL values.
; Length: 8.
M_PATCH_PITCH_EG_VALUES: equ $2160
; The final pitch EG level for the current patch.
; This doubles as the INITIAL pitch EG level.
M_PATCH_PITCH_EG_VALUES_FINAL_LEVEL: equ $2167
; This buffer holds the active 'Key Events'. Each of the 16 entries are a
; single byte storing the note in bits 0..6, with bit 7 holding the key
; state, whether it is active or not.
; Length: 16.
M_KEY_EVENT_BUFFER: equ $2168
; Options Flag Variable for CRT Read/Write Functions.
; Bit 7 is used to store whether the operation is read, or write.
; Refer to the 'CRT_READ_WRITE_ALL' subroutine for more information.
M_CRT_RW_FLAGS: equ $2178
M_CRT_WRITE_PATCH_COUNTER: equ $2179
M_CRT_FORMAT_PATCH_INDEX: equ $217A
; These variables are used during the conversion of a stored integer into its
; ASCII representation. They are used to hold the powers-of-ten of an integer.
; For more specific information, refer to the 'CONVERT_INT_TO_STR' function.
M_PARSED_INT_DIGITS: equ $217C
M_PARSED_INT_TENS: equ $217D
M_PARSED_INT_HNDRDS: equ $217E
M_PARSED_INT_THSNDS: equ $217F
; During the patch loading process, this variable is used as a pointer to
; hold a function address, which is called once for each of the synth's six
; operators. Refer to the patch loading subroutine for more information.
M_PATCH_LOAD_FUNC_PTR: equ $2183
; The operator keyboard scaling curve data.
; When the keyboard scaling for an operator is parsed from the patch data,
; this curve data is created with the amplitude scaling factor for the full
; keyboard range.
; The MSB of the note pitch word is used as an index into this curve data
; when looking up the scaling factor for a particular note.
; Length: 6 * 43.
M_OPERATOR_KEYBOARD_SCALING: equ $2187
M_OPERATOR_KEYBOARD_SCALING_2: equ $21B2
; Parsed Individual Operator Volume. Length: 6.
M_OP_VOLUME: equ $228B
; This buffer is temporary storage for a serialised patch, prior to being
; written to memory. Length: 128.
M_PATCH_SERIALISED_TEMP: equ $2291
; The synth's 'Master Tune' setting.
M_MASTER_TUNE: equ $2311
M_MASTER_TUNE_LOW: equ $2312
M_KBD_SCALE_CURVE_INDEX: equ $2313
M_PATCH_OP_SENS: equ $2314
; This 16-bit variable is the LFO's phase increment.
M_LFO_PHASE_INCREMENT: equ $2320
M_LFO_DELAY_INCREMENT: equ $2322
M_LFO_WAVEFORM: equ $2324
M_LFO_PITCH_MOD_DEPTH: equ $2325
M_LFO_AMP_MOD_DEPTH: equ $2326
M_LFO_PITCH_MOD_SENS: equ $2327
M_PITCH_BND_RANGE: equ $2328
M_PITCH_BND_STEP: equ $2329
M_PITCH_BEND_INPUT: equ $232A
; This flag acts as a 'toggle' switch to control which voices are processed
; in the portamento update function.
; If this flag is set, then voices 8-15 are processed, otherwise voices 0-7
; are processed.
M_PORTA_UPDATE_VOICE_SWITCH: equ $232B
; This flag is used to determine whether pitch modulation should be updated
; in the interrupt cycle. The effect is that pitch-mod is processed once
; every two periodic timer interrupts.
M_PITCH_UPDATE_TOGGLE: equ $232C
; The counter used to 'blink' the LED dot.
M_COMPARE_PATCH_LED_BLINK_COUNTER: equ $232D
; Modulation-source control flags variable.
; Bit 0 = Pitch, Bit 1 = Amplitude, Bit 2 = EG Bias.
M_MOD_WHEEL_ASSIGN_FLAGS: equ $232E
; These 'scaled input' variables refer to the raw analog input 'scaled' by
; this particular modulation-source's 'range' parameter.
M_MOD_WHEEL_SCALED_INPUT: equ $232F
M_FT_CTRL_ASSIGN_FLAGS: equ $2330
M_FT_CTRL_SCALED_INPUT: equ $2331
M_BRTH_CTRL_ASSIGN_FLAGS: equ $2332
M_BRTH_CTRL_SCALED_INPUT: equ $2333
M_AFTERTOUCH_ASSIGN_FLAGS: equ $2334
M_AFTERTOUCH_SCALED_INPUT: equ $2335
M_MOD_WHEEL_RANGE: equ $2336
; These 'Analog Input' variables are used to store the raw analog input for
; each of these analog modulation sources. These will be scaled according
; to the 'range' of each input source, and stored in the associated
; 'scaled input' variables.
M_MOD_WHEEL_ANALOG_INPUT: equ $2337
M_FOOT_CTRL_RANGE: equ $2338
M_FOOT_CTRL_ANALOG_INPUT: equ $2339
M_BRTH_CTRL_RANGE: equ $233A
M_BRTH_CTRL_ANALOG_INPUT: equ $233B
M_AFTERTOUCH_RANGE: equ $233C
M_AFTERTOUCH_ANALOG_INPUT: equ $233D
M_PITCH_BEND_VALUE: equ $233E
; The outgoing MIDI transmit ring buffer.
M_MIDI_TX_BUFFER: equ $2340
; The incoming MIDI received ring buffer.
M_MIDI_RX_BUFFER: equ $23F4
M_MIDI_TX_DATA_PRESENT: equ $2570
; The 'format' of incoming SYSEX MIDI data.
; 1 = Receive perf data, 0 = Receive patch, 9 = Receive bulk.
M_MIDI_SYSEX_FORMAT: equ $2571
; This flag determines whether an 'Active Sensing' signal is due to be sent.
M_MIDI_ACTV_SENS_TX_TRIGGER: equ $2572
M_MIDI_RX_CH: equ $2573
M_MIDI_TX_CH: equ $2574
M_EDIT_PARAM_MAX_VALUE: equ $2576
M_EDIT_RATIO_FREQ_PRINT_VALUE: equ $2577
M_EDIT_PARAM_MAX_AND_OFFSET: equ $2579
M_OP_CURRENT: equ $257B
M_BATTERY_VOLTAGE: equ $257C
M_PORTA_TIME: equ $257D
M_EDIT_PARAM_STR_INDEX: equ $257E
; The currently active diagnostic test stage.
; This is only used when the synth is in diagnostic test mode.
M_TEST_STAGE: equ $257F
M_TEST_STAGE_SUB: equ $2580
M_TEST_STAGE_2: equ $2581
; This variable is a timer for triggering the 'Active Sensing' MIDI message.
M_MIDI_ACTV_SENS_TX_CNTR: equ $2582
M_TEST_LAST_ANALOG_INPUT: equ $2582
; The synth's 'Compare Patch' buffer.
; When an edited patch is 'compared' with the original, stored patch, this is
; the memory location where the edited patch is copied to.
M_PATCH_COMPARE_BUFFER: equ $2584
; The first line buffer for the synth's LCD screen. Length: 16.
M_LCD_BUFFER_LN_1: equ $261F
M_LCD_BUFFER_LN_2: equ $262F
; This buffer stores the LCD screen's current contents.
; During writing the string buffer to the LCD, if the current char to be
; written matches the one in there, the copy process is skipped.
; Length: 32.
M_LCD_BUFFER_CONTENTS: equ $263F
M_STACK_TOP: equ $27FF
; ==============================================================================
; MIDI Error Status.
; These constants are used to track the status of the MIDI buffers. If an error
; condition occurs, these constants will be written to the appropriate memory
; location. They are referenced in printing error messages.
; ==============================================================================
MIDI_SYSEX_FMT_PATCH: equ 0
MIDI_SYSEX_FMT_PERF: equ 1
MIDI_SUBSTATUS_BULK: equ 1
MIDI_SYSEX_PARAM_GRP_VOICE: equ 1
MIDI_SYSEX_PARAM_GRP_FUNCTION: equ 2
MIDI_SYSEX_FMT_BULK: equ 9
MIDI_SYSEX_SUB_PARAM_CHG: equ $10
MIDI_SUBSTATUS_PARAM: equ $11
MIDI_SYSEX_MANUFACTURER_ID: equ $43
MIDI_STATUS_NOTE_OFF: equ $80
MIDI_STATUS_NOTE_ON: equ $90
MIDI_STATUS_MODE_CHANGE: equ $B0
MIDI_STATUS_PROG_CHANGE: equ $C0
MIDI_STATUS_AFTERTOUCH: equ $D0
MIDI_STATUS_PITCH_BEND: equ $E0
MIDI_STATUS_SYSEX_START: equ $F0
MIDI_STATUS_SYSEX_END: equ $F7
MIDI_STATUS_STOP: equ $FC
MIDI_STATUS_ACTIVE_SENSING: equ $FE
MIDI_STATUS_RESET: equ $FF
; ==============================================================================
; Front Panel Buttons.
; These constants are used when referencing front-panel button input.
; ==============================================================================
BUTTON_1: equ 0
BUTTON_2: equ 1
BUTTON_3: equ 2
BUTTON_4: equ 3
BUTTON_5: equ 4
BUTTON_6: equ 5
BUTTON_7: equ 6
BUTTON_8: equ 7
BUTTON_9: equ 8
BUTTON_10: equ 9
BUTTON_11: equ $A
BUTTON_12: equ $B
BUTTON_13: equ $C
BUTTON_14: equ $D
BUTTON_15: equ $E
BUTTON_16: equ $F
BUTTON_17: equ $10
BUTTON_18: equ $11
BUTTON_19: equ $12
BUTTON_20: equ $13
BUTTON_21: equ $14
BUTTON_22: equ $15
BUTTON_23: equ $16
BUTTON_24: equ $17
BUTTON_25: equ $18
BUTTON_26: equ $19
BUTTON_27: equ $1A
BUTTON_28: equ $1B
BUTTON_29: equ $1C
BUTTON_30: equ $1D
BUTTON_31: equ $1E
BUTTON_32: equ $1F
BUTTON_STORE: equ $20
BUTTON_MEM_PROTECT_INT: equ $21
BUTTON_MEM_PROTECT_CRT: equ $22
BUTTON_OP_SELECT: equ $23
BUTTON_EDIT_CHAR: equ $24
BUTTON_MEM_SELECT_INT: equ $25
BUTTON_MEM_SELECT_CRT: equ $26
BUTTON_FUNCTION: equ $27
BUTTON_NO_DOWN: equ $28
BUTTON_YES_UP: equ $29
; ==============================================================================
; User-Interface 'Sub-Modes'.
; These user-interface 'sub-modes' are used by various user-interface
; subroutines. In addition to controlling the current mode of the UI, the
; associated 'M_MEM_SELECT_UI_MODE' memory variable also controls which patch
; memory is selected: Internal, or Cartridge. Refer to the documentation of
; the 'M_MEM_SELECT_UI_MODE' variable for more information.
; ==============================================================================
UI_MODE_CRT_INSERTED: equ 1
UI_MODE_EDIT: equ 2
UI_MODE_EDIT_PATCH_NAME: equ 3
UI_MODE_CRT_LOAD_SAVE: equ 4
UI_MODE_FUNCTION: equ 5
UI_MODE_SET_MEM_PROTECT: equ 6
; ==============================================================================
; Synth 'Input Mode'.
; This is the main 'Input Mode' for the synthesiser. This controls the main
; functionality of the synth's front-panel buttons. These constant values are
; stored in the 'M_INPUT_MODE' memory variable. Refer to the documentation for
; this variable for more information.
; ==============================================================================
INPUT_MODE_PLAY: equ 0
INPUT_MODE_EDIT: equ 1
INPUT_MODE_FN: equ 2
; ==============================================================================
; 'VOICE_REMOVE' Specific Variables.
; The memory locations in 0xAx, to 0xBx are typically scratch registers, which
; serve multiple uses between the different periodic functions, such as the
; synth's voice subroutines. These are the variable definitions specific to
; the 'VOICE_REMOVE' function.
; ==============================================================================
VR_REMOVE_VOICE_CMD: equ $9F
VR_VOICE_PITCH_EG_CURR_STEP_PTR: equ $A6
VR_VOICE_STATUS_PTR: equ $A8
; ==============================================================================
; 'VOICE_ADD' Specific Variables.
; The memory locations in 0xAx, to 0xBx are typically scratch registers, which
; serve multiple uses between the different periodic functions, such as the
; synth's voice subroutines. These are the variable definitions specific to
; the 'VOICE_ADD' function.
; ==============================================================================
VA_VOICE_INDEX: equ $9F
VA_FIND_VOICE_LOOP_INDEX: equ $A0
VA_CURR_VOICE_INDEX: equ $A1
VA_BUFFER_OFFSET: equ $A3
VA_VOICE_PITCH_LAST: equ $A4
VA_VOICE_PITCH_TARGET_PTR: equ $A6
VA_VOICE_STATUS_PTR: equ $A8
VA_VOICE_PITCH_NEW: equ $AB
VA_OPERATOR_ON_OFF: equ $AD
VA_VOICE_CURRENT: equ $AE
VA_LOOP_INDEX: equ $AF
VA_OP_SENS_PTR: equ $B0
VA_OP_VOLUME_PTR: equ $B2
; ==============================================================================
; 'LFO Waves.
; These constants are the values corresponding to the various LFO Waves.
; ==============================================================================
LFO_WAVE_TRIANGLE: equ 0
LFO_WAVE_SAW_DOWN: equ 1
LFO_WAVE_SAW_UP: equ 2
LFO_WAVE_SQUARE: equ 3
LFO_WAVE_SINE: equ 4
LFO_WAVE_S_H: equ 5
; ==============================================================================
; 'PATCH_LOAD_OPERATOR_KBD_SCALING' Specific Variables.
; The memory locations in 0xAx, to 0xBx are typically scratch registers, which
; serve multiple uses between the different periodic functions, such as the
; synth's voice subroutines. These are the variable definitions specific to
; the 'PATCH_LOAD_OPERATOR_KBD_SCALING' function.
; ==============================================================================
K_BREAKPOINT: equ $AB
K_DEPTH_LEFT: equ $AC
K_DEPTH_RIGHT: equ $AD
K_CURVE_TABLE_LEFT_PTR: equ $AE
K_CURVE_TABLE_RIGHT_PTR: equ $B0
K_KBD_SCALING_POLARITY: equ $B2
K_OPERATOR_OUTPUT_LVL: equ $B3
K_OPERATOR_CURRENT_PTR: equ $F9
; ==============================================================================
; ROM Disassembly.
; This is the beginning of the ROM's code section, starting at 0xC000.
; ==============================================================================
ORG $C000
; ==============================================================================
; TEST_ENTRY
; ==============================================================================
; LOCATION: 0xC000
;
; DESCRIPTION:
; Entry point to the synth's diagnostic test mode.
; Interrupts are disabled by the 'sei' instruction during this subroutine,
; and restored by 'cli'.
;
; ==============================================================================
TEST_ENTRY:
SEI
CLR TIMER_CTRL_STATUS
CLR M_PATCH_CURRENT_MODIFIED_FLAG
.RESET_TEST_STAGE:
LDD #0
STD M_TEST_STAGE
.RESET_INPUT_VARIABLES:
CLR P_EGS_PITCH_MOD_HIGH
CLR P_EGS_PITCH_MOD_LOW
CLR P_EGS_AMP_MOD
CLR M_LAST_INPUT_EVENT
CLR M_TEST_AD_STAGE_FLAGS
CLR M_TEST_STAGE_2
LDAA #7
STAA M_TEST_LAST_ANALOG_INPUT
STAA <M_TEST_MODE_BUTTON_CHECK
LDS #M_STACK_TOP
BSR TEST_RESET_VOICE_PARAMS
CLI
BRA .BEGIN_TESTS
; ==============================================================================
; TEST_RESET_VOICE_PARAMS
; ==============================================================================
; LOCATION: 0xC02E
;
; DESCRIPTION:
; This function is called in-between tests in the synth's diagnostic mode. It
; resets various synth parameters to their default value, such as polyphony,
; pitch EG levels, and portamento rate.
;
; ==============================================================================
TEST_RESET_VOICE_PARAMS:
LDAA #$FF
; Reset portamento increment to instantaneous.
STAA <M_PORTA_RATE_INCREMENT
LDD #$100
STD M_MASTER_TUNE ; Reset master tune.
CLR M_MONO_POLY ; Reset synth to polyphonic.
LDAA #%11000000
STAA M_PEDAL_INPUT_STATUS
; The following loop resets the current pitch EG levels for all 16 voices.
; It sets each of the pitch EG levels to 0x4000.
.RESET_PITCH_EG_LEVELS:
LDAB #16
LDX #M_VOICE_PITCH_EG_CURR_LEVEL
.RESET_PITCH_EG_LOOP:
LDAA #64
STAA 0,x
INX
CLR 0,x
INX
DECB
BNE .RESET_PITCH_EG_LOOP ; if ACCB > 0, loop.
RTS
.BEGIN_TESTS:
JSR TEST_RAM
JSR TEST_PRINT_STAGE_NAME
; Falls-through to begin the full diagnostic test run.
JSR TEST_STAGE_1_TONE
; ==============================================================================
; TEST_MAIN_LOOP
; ==============================================================================
; LOCATION: 0xC05A
;
; DESCRIPTION:
; This is the synth's diagnostic test mode's main loop.
; This subroutine will loop continuously, running the currently selected
; diagnostic test stage.
; The series of two 'main' test functions will check the current test function.
; This loop is exited by the 'Test Stage Increment' function, called by the
; first main test function. If the test stage is incremented beyond 8, control
; will jump to the reset handler.
;
; ==============================================================================
TEST_MAIN_LOOP:
BSR TEST_MAIN_FUNCTIONS_1
BSR TEST_MAIN_FUNCTIONS_2
BRA TEST_MAIN_LOOP
; ==============================================================================
; TEST_MAIN_FUNCTIONS_1
; ==============================================================================
; LOCATION: 0xC060
;
; DESCRIPTION:
; The first of the two main diagnostic test functions.
; This subroutine initialises the currently selected diagnotic test function.
;
; ==============================================================================
TEST_MAIN_FUNCTIONS_1:
TST M_LAST_ANALOG_INPUT_EVENT
BNE .IS_LAST_BTN_NO?
RTS
; If the last button was 'DOWN' decrement the test stage.
.IS_LAST_BTN_NO?:
LDAB M_LAST_INPUT_EVENT
CMPB #BUTTON_NO_DOWN
BNE .IS_LAST_BTN_YES?
JSR TEST_STAGE_DECREMENT
BRA .END
; If the last button was 'UP' increment the test stage.
.IS_LAST_BTN_YES?:
CMPB #BUTTON_YES_UP
BNE .IS_TEST_STG_7?
.ADVANCE_STAGE:
JSR TEST_STAGE_INCREMENT
BRA .END
.IS_TEST_STG_7?:
LDAB M_TEST_STAGE
CMPB #7
BNE .IS_TEST_STG_2?
LDAB <M_LAST_ANALOG_INPUT_EVENT
CMPB #1
BNE .IS_BUTTON_16_PRESSED?
JSR TEST_STAGE_8_CRT_EEPROM
BRA .END
.IS_BUTTON_16_PRESSED?:
CMPB #16
BNE .END
JSR TEST_STAGE_8_COPY_CRT_TO_RAM
BRA .END
.IS_TEST_STG_2?:
CMPB #2
BNE .IS_TEST_STG_3?