From 72fa8a2aab3411dc5e14f8a64791aa659d0f17fb Mon Sep 17 00:00:00 2001 From: Gordon JC Pearce Date: Tue, 17 Sep 2024 20:28:50 +0100 Subject: [PATCH] try another way --- plugin/Makefile | 2 +- plugin/assigner.cpp | 2632 +++++++++++++++++++++++++++++++++++++++++++ plugin/chassis.cpp | 4 + plugin/cpuboard.cpp | 116 -- plugin/cpuboard.hpp | 7 +- plugin/cpuboard.off | 414 +++++++ 6 files changed, 3055 insertions(+), 120 deletions(-) create mode 100644 plugin/assigner.cpp delete mode 100644 plugin/cpuboard.cpp create mode 100644 plugin/cpuboard.off diff --git a/plugin/Makefile b/plugin/Makefile index 08e43d9..d67df3d 100644 --- a/plugin/Makefile +++ b/plugin/Makefile @@ -12,7 +12,7 @@ NAME = chassis FILES_DSP = \ parameters.cpp \ voicecpu.cpp \ - cpuboard.cpp \ + assigner.cpp \ chassis.cpp \ voice.cpp diff --git a/plugin/assigner.cpp b/plugin/assigner.cpp new file mode 100644 index 0000000..3b8daf1 --- /dev/null +++ b/plugin/assigner.cpp @@ -0,0 +1,2632 @@ +#include + +#include "cpuboard.hpp" + +// Disassembly of assigner.bin, 8192 bytes [0x0 to 0x1fff] +// ; start +// 0000: 4e 9a JRE $009C +// 0002: 00 NOP +// 0003: 00 NOP +// +// ; nmi +// 0004: aa EI +// 0005: 62 RETI +// 0006: 00 NOP +// 0007: 00 NOP +// +// ; bit patterns used for Note On +// ; ORed with a flag byte for each byte of key flags +// 0008: 01 02 LDAW $0002 +// 000a: 04 08 10 LXI SP,$1008 +// 000d: 20 40 INRW $0040 +// 000f: 80 CALT ($0080) +// +// ; bit patterns used for Note Off +// ; ANDed with a flag byte to mask it off +// 0010: fe JR $000F +// 0011: fd JR $000F +// 0012: fb JR $000E +// 0013: f7 JR $000B +// 0014: ef JR $0004 +// 0015: df JR $0035 +// 0016: bf 7f STAX (HL+$7F) +// +// ; timer/event +// 0018: 00 NOP +// 0019: 00 NOP +// 001a: 00 NOP +// 001b: 00 NOP +// 001c: 00 NOP +// 001d: 00 NOP +// 001e: 00 NOP +// 001f: 00 NOP +// +// ; timer/ AD +// 0020: 20 cb INRW $00CB +// 0022: c3 JR $0026 ; hasn't rolled over +// 0023: 54 4b 05 JMP $054B ; timer ISR handler +// 0026: aa EI +// 0027: 62 RETI +// +// ; serial +// 0028: 54 95 05 JMP $0595 +// 002b: 00 NOP +// 002c: 00 NOP +// 002d: 00 NOP +// 002e: 00 NOP +// 002f: 00 NOP +// +// ; lookup table of some sort, not sure what for +// ; referenced at 088c +// ; where it's used as the low byte of an address in DE +// ; and a byte in C is stored +// ; also a routine at 08a7h where the value is read +// ; also something up around 0c6eh +// 0030: 9c CALT ($00B8) +// 0031: 97 CALT ($00AE) +// 0032: 94 CALT ($00A8) +// 0033: 90 CALT ($00A0) +// 0034: 9d CALT ($00BA) +// 0035: 9a CALT ($00B4) +// 0036: 95 CALT ($00AA) +// 0037: 93 CALT ($00A6) +// 0038: 9e CALT ($00BC) +// 0039: 98 CALT ($00B0) +// 003a: 96 CALT ($00AC) +// 003b: 91 CALT ($00A2) +// 003c: 9b CALT ($00B6) +// 003d: 99 CALT ($00B2) +// 003e: 9f CALT ($00BE) +// 003f: 92 CALT ($00A4) +// +// ; " 1" to "16" +// 0040: f1 JR $0032 +// 0041: f2 JR $0034 +// 0042: f3 JR $0036 +// 0043: f4 JR $0038 +// 0044: f5 JR $003A +// 0045: f6 JR $003C +// 0046: f7 JR $003E +// 0047: f8 JR $0040 +// 0048: f9 JR $0042 +// 0049: 1a MOV B,A +// 004a: 11 EXX +// 004b: 12 INX BC +// 004c: 13 DCX BC +// 004d: 14 15 16 LXI BC,$1615 +// +// ; digit lookup table 1 2 3 4 5 6 7 8 9 0 c E P r +// 0050: 01 60 LDAW $0060 +// 0052: c7 JR $005A +// 0053: e5 JR $0039 +// 0054: 6c ad MVI D,$AD +// 0056: af e8 LDAX (HL+$E8) +// 0058: ef JR $0048 +// 0059: ed JR $0047 +// 005a: eb JR $0046 +// 005b: 07 8f ANI A,$8F +// 005d: ce JR $006C +// 005e: 06 illegal +// 005f: 00 NOP +// +// ; digit lookup table for transpose, C C. d d. E F F. and so on +// 0060: 8b CALT ($0096) +// 0061: 9b CALT ($00B6) +// 0062: 67 77 NEI A,$77 +// 0064: 8f CALT ($009E) +// 0065: 8e CALT ($009C) +// 0066: 9e CALT ($00BC) +// 0067: ab bb LDAX (DE+$BB) +// 0069: ee JR $0058 +// 006a: fe JR $0069 +// 006b: 2f LDAX (HL-) +// 006c: 8b CALT ($0096) +// 006d: 9b CALT ($00B6) +// 006e: 67 77 NEI A,$77 +// 0070: 8f CALT ($009E) +// 0071: 8e CALT ($009C) +// 0072: 9e CALT ($00BC) +// 0073: ab bb LDAX (DE+$BB) +// 0075: ee JR $0064 +// 0076: fe JR $0075 +// 0077: 2f LDAX (HL-) +// 0078: 8b CALT ($0096) +// +// ; +// 0079: 69 00 MVI A,$00 +// 007b: 4d c1 MOV PB,A ; turn off digit lines +// 007d: 4d c5 MOV PF,A ; turn off select lines +// 007f: 63 cc STAW $00CC ; zero out some variable +// 0081: 63 cd STAW $00CD ; zero out some variable +// 0083: 63 c0 STAW $00C0 ; running status +// 0085: 63 b7 STAW $00B7 ; zero out some variable +// 0087: 64 02 fd MVI PC,$FD ; set all output pins high (2 is midi in) +// 008a: aa EI +// 008b: 75 cd 08 EQIW $00CD,$08 +// 008e: fc JR $008B ; wait until this is set +// 008f: 71 b8 2a MVIW $00B8,$2A ; default is 42 +// 0092: 7c 54 CALF $0C54 +// 0094: 75 cd 10 EQIW $00CD,$10 +// 0097: fc JR $0094 +// 0098: 7b 81 CALF $0B81 ; set up voice allocation table +// 009a: 4e 71 JRE $010D +// +// ; cold start +// 009c: 69 0e MVI A,$0E ; enable RAM, PF into port mode +// ; upper two bits of PF select ADC external MUX +// ; 5 = low for ROM high for RAM enable +// ; 4-0 upper address bits +// 009e: 4d d0 MOV MM,A +// 00a0: 69 0e MVI A,$0E ; serial mode clock x24 tx on rx on +// 00a2: 4d c9 MOV SMH,A +// 00a4: 69 4e MVI A,$4E ; 8n1 x16 clock +// 00a6: 4d ca MOV SML,A +// 00a8: 64 80 08 MVI ANM,$08 ; select DAC 4-7 +// 00ab: 68 ff MVI V,$FF ; set vector register +// 00ad: 10 EXA +// 00ae: 68 ff MVI V,$FF +// 00b0: 04 ff ff LXI SP,$FFFF +// 00b3: 69 00 MVI A,$00 +// 00b5: 34 00 ff LXI HL,$FF00 ; clear RAM +// 00b8: 3d STAX (HL+) +// 00b9: 74 7f 00 EQI L,$00 +// 00bc: fb JR $00B8 +// 00bd: 69 03 MVI A,$03 ; mode control port C serial on +// 00bf: 4d d1 MOV MCC,A +// 00c1: 69 3a MVI A,$3A ; mode C 0, 2, 6, 7 output +// ; 7-6 cassette out +// ; 5 cassette in +// ; 4 memory protect +// ; 3 pedal hold +// ; 2 UART out - MIDI/Module +// ; 1 UART in - MIDI +// ; 0 MIDI / Module select +// 00c3: 4d d4 MOV MC,A +// 00c5: 69 00 MVI A,$00 +// 00c7: 4d d3 MOV MB,A ; port B outputs for LED rows +// 00c9: 4d d7 MOV MF,A ; port F outputs column drive, panel mux select +// 00cb: 4d c5 MOV PF,A ; turn outputs off +// 00cd: 4d c1 MOV PB,A +// 00cf: 69 ff MVI A,$FF ; port A input keypad/keyboard rows +// 00d1: 4d d2 MOV MA,A +// 00d3: 71 bc 08 MVIW $00BC,$08 +// 00d6: 7b 81 CALF $0B81 ; set up voice allocation table +// 00d8: 71 c8 42 MVIW $00C8,$42 ; bit 1 is "Poly 1", bit 6 is ? +// 00db: 24 ff 1f LXI DE,$1FFF ; keypad demux +// 00de: 4a de MVIX DE,$DE ; IC9 enabled Col 6, trans, poly, midi +// ; notes +// ; IC7 latches bits D0-D5, D3 is not used +// ; D0-D2 go to IC8/IC9 select pins +// ; D4 goes to IC8 G2A active low +// ; D5 goes to IC9 G2A active low +// ; IC8/9 all outputs active low +// ; IC9 col 0 and 1 not used +// ; IC9 col 2 Bank buttons +// ; IC9 col 3 Patch buttons +// ; IC9 col 4 footage, chorus, and waveform buttons +// ; IC9 col 5 slide switches (PWM LFO, ENV invert, ENV/GATE, HPF) +// ; IC9 col 6 transpose, poly 1, poly 2, midi ch, midi func 2, midi func 1, N/U, group +// ; IC9 col 7 N/U, manual, write, save, verify, load +// +// ; MIDI panel +// ; 1 = bit 4, 2=bit 5, 3 = bit 6 (marked NC), 4 = "MIDI COM") +// +// ; active low outputs from IC8/9 are inverted by IC11/12 +// +// 00e0: 4c c0 MOV A,PA ; read port A +// 00e2: 63 a8 STAW $00A8 ; save +// 00e4: 07 01 ANI A,$01 ; bit 0, key transpose (rows are inverted) +// 00e6: 63 b6 STAW $00B6 ; store +// 00e8: 4a dd MVIX DE,$DD ; read "fixed" switches? +// 00ea: 4c c0 MOV A,PA ; read port A +// 00ec: 63 a7 STAW $00A7 ; store +// 00ee: 4a e8 MVIX DE,$E8 ; keyboard? +// 00f0: 64 06 00 MVI MKH,$00 ; unmask AD, TX, RX interrupts +// 00f3: aa EI +// 00f4: 75 cd 10 EQIW $00CD,$10 +// 00f7: fc JR $00F4 +// 00f8: 71 b8 2a MVIW $00B8,$2A ; default is 42 +// 00fb: 7c 47 CALF $0C47 ; set manual mode? +// 00fd: 78 43 CALF $0843 ; omni off poly +// 00ff: 71 ba 20 MVIW $00BA,$20 +// 0102: 71 bb 01 MVIW $00BB,$01 +// 0105: 58 b6 BIT 0,$00B6 ; test mode? +// 0107: 71 ba 10 MVIW $00BA,$10 +// 010a: 71 be 0c MVIW $00BE,$0C ; transpose is 12 +// 010d: 7b 9a CALF $0B9A ; zero out RAM at FF40 (key bitmap) +// 010f: 78 28 CALF $0828 ; reset modwheel +// 0111: 58 a8 BIT 0,$00A8 ; key trans was/wasn't pressed at startup? +// 0113: c7 JR $011B +// 0114: 55 87 40 OFFIW $0087,$40 ; "all notes off" has previously been sent? +// 0117: c3 JR $011B +// 0118: 55 a8 08 OFFIW $00A8,$08 ; MIDI CH? +// 011b: 4e 75 JRE $0192 +// 011d: 7b 70 CALF $0B70 ; stop all notes +// 011f: 7b 9e CALF $0B9E ; clear played notes +// 0121: 7b 81 CALF $0B81 ; set up voice allocation table +// 0123: 7d 33 CALF $0D33 ; save LCD bitpattern +// 0125: 78 00 CALF $0800 ; show transpose value +// +// ; scan the keyboard +// ; this might be where it does the Transpose setting +// 0127: 24 ff 1f LXI DE,$1FFF ; keypad mux address +// 012a: 34 50 ff LXI HL,$FF50 +// 012d: 6a e8 MVI B,$E8 ; keyboard, col 0 +// 012f: 0a MOV A,B +// 0130: 3a STAX (DE) ; select latch +// 0131: 00 NOP +// 0132: 00 NOP +// 0133: 4c c0 MOV A,PA ; read rows +// 0135: 3b STAX (HL) ; store +// 0136: 0a MOV A,B +// 0137: 17 10 ORI A,$10 ; turn off mux +// 0139: 3a STAX (DE) +// 013a: 32 INX HL ; next byte +// 013b: 42 INR B ; next col +// 013c: 48 0b SK HC ; skip if halfcarry, all $ef rolled over +// 013e: f0 JR $012F ; loop +// 013f: 34 50 ff LXI HL,$FF50 ; start of keyboard state +// 0142: 6a 07 MVI B,$07 ; eight bytes +// 0144: 24 00 00 LXI DE,$0000 ; key note +// 0147: 2d LDAX (HL+) ; fetch byte; +// 0148: 67 00 NEI A,$00 ; zero? +// 014a: ca JR $0155 ; skip ahead +// 014b: 6b 07 MVI C,$07 ; 8 bits +// 014d: 48 01 SLRC A ; shift found byte +// 014f: c1 JR $0151 ; not this bit, jump over +// 0150: cb JR $015C ; bit is set +// 0151: 22 INX DE ; next note +// 0152: 53 DCR C ; next bit +// 0153: f9 JR $014D ; loop around +// 0154: c3 JR $0158 +// 0155: 74 45 08 ADI E,$08 ; next eight notes +// 0158: 52 DCR B ; next byte, or skip +// 0159: ed JR $0147 ; loop back and try the next byte +// 015a: 4e 21 JRE $017D ; all bytes considered +// 015c: 0d MOV A,E ; save note +// 015d: 36 0c SUINB A,$0C ; subtract 12, skip if greater than 12 +// 015f: 46 0c ADI A,$0C ; add 12 +// 0161: 37 25 LTI A,$25 ; less than 37? +// 0163: 66 0c SUI A,$0C ; no, subtract +// 0165: 37 19 LTI A,$19 ; less than 25? +// 0167: 66 0c SUI A,$0C ; no, subtract +// 0169: 63 be STAW $00BE ; save in Transpose +// 016b: 77 0c EQI A,$0C ; default is 12, is it this? +// 016d: c7 JR $0175 +// 016e: 01 c8 LDAW $00C8 ; status flags +// 0170: 07 fe ANI A,$FE ; mask off bit 0 +// 0172: 63 c8 STAW $00C8 ; save +// 0174: c6 JR $017B +// 0175: 01 c8 LDAW $00C8 +// 0177: 17 01 ORI A,$01 ; set bit 0 +// 0179: 63 c8 STAW $00C8 ; save +// 017b: 78 00 CALF $0800 ; show transpose value +// 017d: 24 ff 1f LXI DE,$1FFF +// 0180: 69 de MVI A,$DE ; Keypad, IC9 select 6 +// 0182: 3a STAX (DE) +// 0183: 00 NOP +// 0184: 00 NOP +// 0185: 4c c0 MOV A,PA +// 0187: 47 01 ONI A,$01 ; looks like this checks for KEY TRANS pressed? +// 0189: c2 JR $018C +// 018a: 4f 9b JRE $0127 +// 018c: 7d 3c CALF $0D3C +// 018e: 78 28 CALF $0828 ; reset modwheel +// 0190: 7b 9a CALF $0B9A ; zero out at FF40 (key bitmap) +// +// +// // key scanning loop? +// 0192: 01 cd LDAW $00CD +// 0194: 07 10 ANI A,$10 +// 0196: 74 f8 bf EQAW $00BF +// 0199: 71 c0 00 MVIW $00C0,$00 +// 019c: 63 bf STAW $00BF +// 019e: 24 ff 1f LXI DE,$1FFF ; scan keyboard +// 01a1: 34 50 ff LXI HL,$FF50 ; key pressed map +// 01a4: 6a e8 MVI B,$E8 ; IC8 select 0 +// 01a6: 0a MOV A,B +// 01a7: 3a STAX (DE) ; write to MUX selector +// 01a8: 00 NOP +// 01a9: 00 NOP ; settle +// 01aa: 4c c0 MOV A,PA ; read port +// 01ac: 1b MOV C,A ; save +// 01ad: 77 00 EQI A,$00 ; no keys pressed? all keys pressed? investigate +// 01af: 15 87 80 ORIW $0087,$80 ; no keys pressed, set no keys flag +// 01b2: 0a MOV A,B +// 01b3: 17 10 ORI A,$10 +// 01b5: 3a STAX (DE) ; turn MUX off +// 01b6: 0b MOV A,C +// 01b7: 70 93 XRAX (HL) ; XOR bits with key pressed map +// 01b9: 48 0c SK Z ; skip if zero (no change) +// 01bb: 79 96 CALF $0996 ; handle something do with keys +// 01bd: 0b MOV A,C ; +// 01be: 3d STAX (HL+) ; save in keymap +// 01bf: 42 INR B ; next column +// 01c0: 48 0b SK HC ; skip if halfcarry +// 01c2: e3 JR $01A6 ; loop if not done +// 01c3: 55 87 80 OFFIW $0087,$80 ; skip if no keys were pressed +// 01c6: d3 JR $01DA ; jump ahead +// 01c7: 5e 87 BIT 6,$0087 ; skip if no keys were pressed previously +// ; but we've already sent All Notes Off +// 01c9: d0 JR $01DA +// +// ; if no keys were pressed +// ; send all notes off +// 01ca: 69 f9 MVI A,$F9 ; select MIDI output +// 01cc: 79 e8 CALF $09E8 +// 01ce: 69 b0 MVI A,$B0 +// 01d0: 79 d5 CALF $09D5 ; send, wiping running status +// 01d2: 69 7b MVI A,$7B ; all notes off +// 01d4: 79 e8 CALF $09E8 ; send byte to TX +// 01d6: 69 00 MVI A,$00 ; value +// 01d8: 79 e8 CALF $09E8 ; send byte to TX +// 01da: 01 87 LDAW $0087 +// 01dc: 48 21 SLR A +// 01de: 63 87 STAW $0087 ; mark the flag that we have sent all notes off +// +// ; assign notes here? +// 01e0: 6a 0d MVI B,$0D +// 01e2: 34 3d ff LXI HL,$FF3D ; probably copies keymap to notemap +// 01e5: 24 57 ff LXI DE,$FF57 +// 01e8: 71 d0 00 MVIW $00D0,$00 +// 01eb: af 10 LDAX (HL+$10) ; ff40 table +// 01ed: 74 3a 03 LTI B,$03 ; skip if value is greater than 3 +// 01f0: 74 3a 0b LTI B,$0B ; skip if value is greater than 0x0b +// +// ; okay what +// ; 01ed b<03h so skip to 01f7h +// ; 01f0 b<0bh so do not jump to 1f7 +// ; there are only so many bits available for keys off the physical keyboard +// ; I think this takes care of mapping the keyboard correctly +// +// 01f3: c3 JR $01F7 +// 01f4: 70 9a ORAX (DE) ; or the bitfield at ff40+ with the one at ff50+ (physical keys pressed) +// 01f6: 23 DCX DE ; count down DE +// 01f7: 1b MOV C,A ; save A +// 01f8: 70 93 XRAX (HL) ; compare with ff30+ +// 01fa: 48 0c SK Z ; zero, no change +// 01fc: 7a 18 CALF $0A18 ; there was a change, do stuff +// 01fe: 0b MOV A,C ; restore A +// 01ff: 3b STAX (HL) ; store at ff30+ +// 0200: 33 DCX HL ; count down hl +// 0201: 52 DCR B ; count down bytes +// 0202: e8 JR $01EB ; loop for next one +// 0203: 65 d0 ff NEIW $00D0,$FF ; skip if ffd0 != ff +// 0206: 7b 9e CALF $0B9E ; clear played notes +// +// +// 0208: 24 ff 1f LXI DE,$1FFF ; keypad mux +// 020b: 34 a4 ff LXI HL,$FFA4 ; raw switch values +// 020e: 6a da MVI B,$DA ; IC9 select 2 (Bank buttons) +// 0210: 0a MOV A,B +// 0211: 3a STAX (DE) ; select MUX +// 0212: 00 NOP +// 0213: 00 NOP +// 0214: 4c c0 MOV A,PA ; read keypad +// 0216: 1b MOV C,A ; save +// 0217: 0a MOV A,B +// 0218: 17 20 ORI A,$20 +// 021a: 3a STAX (DE) ; turn off mux +// 021b: 0b MOV A,C ; restore +// 021c: 70 93 XRAX (HL) ; xor with previous? Debounce? +// 021e: bf 06 STAX (HL+$06) ; store result +// 0220: 60 8b ANA A,C ; mask +// 0222: bf 0c STAX (HL+$0C) ; store result +// 0224: 0b MOV A,C +// 0225: 3d STAX (HL+) ; store raw value, increment HL +// 0226: 42 INR B ; next column +// 0227: 48 0b SK HC ; halfcarry? +// 0229: e6 JR $0210 ; no, loop +// 022a: 58 b6 BIT 0,$00B6 ; test mode? +// 022c: c2 JR $022F +// 022d: 4e 3f JRE $026E +// 022f: 5b ae BIT 3,$00AE +// 0231: d6 JR $0248 +// 0232: 5b a8 BIT 3,$00A8 ; MIDI Ch +// 0234: d1 JR $0246 +// 0235: 78 43 CALF $0843 ; omni off poly +// 0237: 7b 9a CALF $0B9A ; zero out RAM at FF40 (key bitmap) +// 0239: 78 28 CALF $0828 ; reset modwheel +// 023b: 7d 33 CALF $0D33 ; save LED bitpattern +// 023d: 01 bd LDAW $00BD ; MIDI channel? +// 023f: 34 40 00 LXI HL,$0040 ; lookup table, turn it into 1 to 16 with leading space +// 0242: ac LDAX (HL+A) +// 0243: 7d 45 CALF $0D45 ; digit lookup +// 0245: c2 JR $0248 +// 0246: 7d 3c CALF $0D3C +// 0248: 5b a8 BIT 3,$00A8 ; MIDI Ch +// 024a: 4e 4f JRE $029B +// 024c: 55 87 40 OFFIW $0087,$40 +// 024f: db JR $026B +// 0250: 64 4a 08 ONI PC,$08 ; pedal hold +// 0253: d7 JR $026B +// 0254: 25 b0 00 GTIW $00B0,$00 +// 0257: c7 JR $025F +// 0258: 01 b0 LDAW $00B0 +// 025a: 7c 9d CALF $0C9D +// 025c: 51 DCR A +// 025d: 78 13 CALF $0813 +// 025f: 25 b1 00 GTIW $00B1,$00 +// 0262: c8 JR $026B +// 0263: 01 b1 LDAW $00B1 +// 0265: 7c 9d CALF $0C9D +// 0267: 46 07 ADI A,$07 +// 0269: 78 13 CALF $0813 +// 026b: 54 5d 04 JMP $045D +// +// ; test mode? +// 026e: 5b b4 BIT 3,$00B4 +// 0270: c2 JR $0273 +// 0271: 78 5c CALF $085C ; send command to module board +// 0273: 01 a8 LDAW $00A8 ; MIDI/Transpose/etc +// 0275: 48 21 SLR A +// 0277: 07 38 ANI A,$38 +// 0279: 1b MOV C,A +// 027a: 01 c8 LDAW $00C8 ; status bits +// 027c: 07 c7 ANI A,$C7 +// 027e: 60 9b ORA A,C +// 0280: 63 c8 STAW $00C8 +// 0282: 75 ba 10 EQIW $00BA,$10 +// 0285: cf JR $0295 +// 0286: 59 cd BIT 1,$00CD +// 0288: c7 JR $0290 +// 0289: 5f b6 BIT 7,$00B6 +// 028b: 69 30 MVI A,$30 +// 028d: 7b 55 CALF $0B55 voiceOnUnison +// 028f: c5 JR $0295 +// 0290: 5f b6 BIT 7,$00B6 +// 0292: c2 JR $0295 +// 0293: 7b 70 CALF $0B70 ; stop all notes? +// 0295: 25 aa 00 GTIW $00AA,$00 +// 0298: c2 JR $029B +// 0299: 7b 70 CALF $0B70 ; stop all notes? +// 029b: 55 b5 38 OFFIW $00B5,$38 +// 029e: 54 62 0d JMP $0D62 +// 02a1: 59 b5 BIT 1,$00B5 +// 02a3: c4 JR $02A8 +// 02a4: 5c a9 BIT 4,$00A9 +// 02a6: 7c 47 CALF $0C47 ; set manual mode? +// 02a8: 5a af BIT 2,$00AF +// 02aa: 4e 20 JRE $02CC +// 02ac: 5a a9 BIT 2,$00A9 +// 02ae: d0 JR $02BF +// 02af: 7d 33 CALF $0D33 ; save LED bitpattern +// 02b1: 05 b6 fb ANIW $00B6,$FB +// 02b4: 64 4a 10 ONI PC,$10 ; Port C bit 4 = memory protect +// 02b7: cf JR $02C7 +// 02b8: 69 00 MVI A,$00 +// 02ba: 63 b9 STAW $00B9 +// 02bc: 7d 45 CALF $0D45 ; digit lookup +// 02be: cd JR $02CC +// 02bf: 5a b6 BIT 2,$00B6 +// 02c1: 7d 3c CALF $0D3C +// 02c3: 05 b6 fb ANIW $00B6,$FB +// 02c6: c5 JR $02CC +// 02c7: 69 de MVI A,$DE +// 02c9: 40 45 0d CALL $0D45 ; digit lookup +// 02cc: 5f b4 BIT 7,$00B4 +// 02ce: 4e 2f JRE $02FF +// 02d0: 01 c8 LDAW $00C8 +// 02d2: 16 c0 XRI A,$C0 +// 02d4: 63 c8 STAW $00C8 +// 02d6: 58 b6 BIT 0,$00B6 ; test mode +// 02d8: cc JR $02E5 +// 02d9: 69 fd MVI A,$FD ; select module board +// 02db: 79 e8 CALF $09E8 ; send byte to TX +// 02dd: 5e c8 BIT 6,$00C8 ; something to do with sustain on/off +// 02df: 69 86 MVI A,$86 ; sustain on +// 02e1: 69 87 MVI A,$87 ; sustain off +// 02e3: 79 e8 CALF $09E8 ; send byte to TX +// 02e5: 59 b6 BIT 1,$00B6 +// 02e7: 55 a9 04 OFFIW $00A9,$04 +// 02ea: d4 JR $02FF +// 02eb: 01 bb LDAW $00BB +// 02ed: 74 98 ba ORAW $00BA +// 02f0: 1b MOV C,A +// 02f1: 7c d0 CALF $0CD0 +// 02f3: 7c 93 CALF $0C93 +// 02f5: 55 a8 10 OFFIW $00A8,$10 ; "MIDI 2" +// 02f8: 79 29 CALF $0929 ; send program change +// 02fa: 45 a8 30 ONIW $00A8,$30 ; "MIDI 3" +// 02fd: 78 f0 CALF $08F0 ; sendSysexPatch +// 02ff: 45 b4 06 ONIW $00B4,$06 +// 0302: d3 JR $0316 +// 0303: 7b 70 CALF $0B70 ; stop all notes +// 0305: 7b 9e CALF $0B9E ; clear played notes +// 0307: 7b 81 CALF $0B81 ; set up voice allocation table +// 0309: 01 a8 LDAW $00A8 ; saved button column 6 +// 030b: 07 06 ANI A,$06 ; poly 1 or poly 2 pressed +// 030d: 1b MOV C,A +// 030e: 01 c8 LDAW $00C8 ; some flags? +// 0310: 07 f9 ANI A,$F9 +// 0312: 60 9b ORA A,C ; OR the new value in +// 0314: 63 c8 STAW $00C8 ; save it +// 0316: 25 b1 00 GTIW $00B1,$00 +// 0319: 4e 41 JRE $035C +// 031b: 01 b1 LDAW $00B1 +// 031d: 7c 9d CALF $0C9D +// 031f: 07 0f ANI A,$0F +// 0321: 63 bb STAW $00BB +// 0323: 5a a9 BIT 2,$00A9 +// 0325: 4e 20 JRE $0347 +// 0327: 64 4a 10 ONI PC,$10 +// 032a: 4e 7a JRE $03A6 +// 032c: 5a b6 BIT 2,$00B6 +// 032e: c2 JR $0331 +// 032f: 4e 75 JRE $03A6 +// 0331: 01 b9 LDAW $00B9 +// 0333: 07 f0 ANI A,$F0 +// 0335: 1a MOV B,A +// 0336: 74 98 bb ORAW $00BB +// 0339: 7d 45 CALF $0D45 ; digit lookup +// 033b: 01 bb LDAW $00BB +// 033d: 63 b9 STAW $00B9 +// 033f: 74 2a 00 GTI B,$00 +// 0342: d9 JR $035C +// 0343: 7d 06 CALF $0D06 +// 0345: 4e 5f JRE $03A6 +// 0347: 74 98 ba ORAW $00BA +// 034a: 7d 45 CALF $0D45 +// 034c: 7c 3c CALF $0C3C +// 034e: 7c d0 CALF $0CD0 +// 0350: 7c 93 CALF $0C93 +// 0352: 55 a8 10 OFFIW $00A8,$10 ; "function" +// 0355: 79 29 CALF $0929 ; send program change +// 0357: 45 a8 30 ONIW $00A8,$30 ; "both function" +// 035a: 78 f0 CALF $08F0 ; sendSysexPatch +// 035c: 25 b0 00 GTIW $00B0,$00 +// 035f: 4e 45 JRE $03A6 +// 0361: 01 b0 LDAW $00B0 +// 0363: 7c 9d CALF $0C9D +// 0365: 48 25 SLL A +// 0367: 48 25 SLL A +// 0369: 48 25 SLL A +// 036b: 48 25 SLL A +// 036d: 63 ba STAW $00BA +// 036f: 5a a9 BIT 2,$00A9 +// 0371: df JR $0391 +// 0372: 64 4a 10 ONI PC,$10 +// 0375: 4e 2f JRE $03A6 +// 0377: 5a b6 BIT 2,$00B6 +// 0379: c2 JR $037C +// 037a: 4e 2a JRE $03A6 +// 037c: 01 b9 LDAW $00B9 +// 037e: 07 0f ANI A,$0F +// 0380: 1a MOV B,A +// 0381: 74 98 ba ORAW $00BA +// 0384: 7d 45 CALF $0D45 +// 0386: 01 ba LDAW $00BA +// 0388: 63 b9 STAW $00B9 +// 038a: 74 2a 00 GTI B,$00 +// 038d: d8 JR $03A6 +// 038e: 7d 06 CALF $0D06 +// 0390: d5 JR $03A6 +// 0391: 74 98 bb ORAW $00BB +// 0394: 7d 45 CALF $0D45 +// 0396: 7c 3c CALF $0C3C +// 0398: 7c d0 CALF $0CD0 +// 039a: 7c 93 CALF $0C93 +// 039c: 55 a8 10 OFFIW $00A8,$10 ; function +// 039f: 79 29 CALF $0929 ; send program change +// 03a1: 45 a8 30 ONIW $00A8,$30 ; both function +// 03a4: 78 f0 CALF $08F0 ; sendSysexPatch +// 03a6: 5a a9 BIT 2,$00A9 +// 03a8: 58 b5 BIT 0,$00B5 +// 03aa: 4e 28 JRE $03D4 +// 03ac: 59 b6 BIT 1,$00B6 +// 03ae: c6 JR $03B5 +// 03af: 7c 3c CALF $0C3C +// 03b1: 01 bb LDAW $00BB +// 03b3: 1b MOV C,A +// 03b4: cb JR $03C0 +// 03b5: 01 bb LDAW $00BB +// 03b7: 37 08 LTI A,$08 +// 03b9: 69 00 MVI A,$00 +// 03bb: 46 01 ADI A,$01 +// 03bd: 63 bb STAW $00BB +// 03bf: 1b MOV C,A +// 03c0: 01 ba LDAW $00BA +// 03c2: 60 9b ORA A,C +// 03c4: 7d 45 CALF $0D45 +// 03c6: 7c d0 CALF $0CD0 +// 03c8: 7c 93 CALF $0C93 +// 03ca: 55 a8 10 OFFIW $00A8,$10 ; function +// 03cd: 79 29 CALF $0929 ; send program change +// 03cf: 45 a8 30 ONIW $00A8,$30 ; both function +// 03d2: 78 f0 CALF $08F0 ; sendSysexPatch +// 03d4: 5f a3 BIT 7,$00A3 +// 03d6: 4e 32 JRE $040A +// 03d8: 05 a3 7f ANIW $00A3,$7F +// 03db: 01 c8 LDAW $00C8 +// 03dd: 07 3f ANI A,$3F +// 03df: 5e a3 BIT 6,$00A3 +// 03e1: c3 JR $03E5 +// 03e2: 17 80 ORI A,$80 +// 03e4: c2 JR $03E7 +// 03e5: 17 40 ORI A,$40 +// 03e7: 63 c8 STAW $00C8 +// 03e9: 01 a3 LDAW $00A3 +// 03eb: 1b MOV C,A +// 03ec: 07 07 ANI A,$07 +// 03ee: 41 INR A +// 03ef: 63 bb STAW $00BB +// 03f1: 0b MOV A,C +// 03f2: 07 38 ANI A,$38 +// 03f4: 48 25 SLL A +// 03f6: 46 10 ADI A,$10 +// 03f8: 63 ba STAW $00BA +// 03fa: 74 98 bb ORAW $00BB +// 03fd: 7d 45 CALF $0D45 +// 03ff: 7c 3c CALF $0C3C +// 0401: 7c d0 CALF $0CD0 +// 0403: 7c 93 CALF $0C93 +// 0405: 55 a3 80 OFFIW $00A3,$80 +// 0408: 4f ce JRE $03D8 +// 040a: 4c c2 MOV A,PC +// 040c: 1b MOV C,A +// 040d: 74 90 bc XRAW $00BC +// 0410: 07 08 ANI A,$08 +// 0412: 48 0c SK Z +// 0414: 7b a9 CALF $0BA9 ; send sustain message +// 0416: 0b MOV A,C +// 0417: 63 bc STAW $00BC +// 0419: 5b b6 BIT 3,$00B6 +// 041b: cb JR $0427 +// 041c: 05 b6 f7 ANIW $00B6,$F7 +// 041f: 69 fd MVI A,$FD ; module board +// 0421: 79 e8 CALF $09E8 ; send byte to TX +// 0423: 69 87 MVI A,$87 ; sustain on +// 0425: 79 e8 CALF $09E8 ; send byte to TX +// 0427: 5c b6 BIT 4,$00B6 ; sustain pressed +// 0429: cb JR $0435 +// 042a: 05 b6 ef ANIW $00B6,$EF ; sustain released bit +// 042d: 69 fd MVI A,$FD ; module board +// 042f: 79 e8 CALF $09E8 ; send byte to TX +// 0431: 69 86 MVI A,$86 ; sustain off +// 0433: 79 e8 CALF $09E8 ; send byte to TX +// 0435: 5f a1 BIT 7,$00A1 +// 0437: cb JR $0443 +// 0438: 01 a1 LDAW $00A1 +// 043a: 07 7f ANI A,$7F +// 043c: 63 a1 STAW $00A1 +// 043e: 6a a0 MVI B,$A0 ; negative bend value to module +// 0440: 78 37 CALF $0837 ; send BC to module board +// 0442: cd JR $0450 +// 0443: 5f a0 BIT 7,$00A0 +// 0445: ca JR $0450 +// 0446: 01 a0 LDAW $00A0 +// 0448: 07 7f ANI A,$7F +// 044a: 63 a0 STAW $00A0 +// 044c: 6a a1 MVI B,$A1 ; positive bend value to module +// 044e: 78 37 CALF $0837 ; send BC to module board +// 0450: 5f a2 BIT 7,$00A2 +// 0452: ca JR $045D +// 0453: 01 a2 LDAW $00A2 +// 0455: 07 7f ANI A,$7F +// 0457: 63 a2 STAW $00A2 +// 0459: 6a a2 MVI B,$A2 +// 045b: 78 37 CALF $0837 ; send BC to module board +// 045d: 25 b2 00 GTIW $00B2,$00 +// 0460: 4e 22 JRE $0484 +// 0462: 59 b6 BIT 1,$00B6 +// 0464: 7d 5b CALF $0D5B ; set both DP on +// 0466: 55 b2 07 OFFIW $00B2,$07 +// 0469: 7b cc CALF $0BCC +// 046b: 55 b2 18 OFFIW $00B2,$18 +// 046e: 7b da CALF $0BDA +// 0470: 55 b2 e0 OFFIW $00B2,$E0 +// 0473: 7b eb CALF $0BEB +// 0475: 7b f9 CALF $0BF9 +// 0477: 55 a8 30 OFFIW $00A8,$30 ; both funtion +// 047a: c9 JR $0484 +// 047b: 01 c7 LDAW $00C7 +// 047d: 07 7f ANI A,$7F +// 047f: 1b MOV C,A +// 0480: 6d a0 MVI E,$A0 +// 0482: 78 d6 CALF $08D6 +// 0484: 25 ad 00 GTIW $00AD,$00 +// 0487: d5 JR $049D +// 0488: 01 a7 LDAW $00A7 +// 048a: 59 b6 BIT 1,$00B6 +// 048c: 7c 0c CALF $0C0C +// 048e: 7c 29 CALF $0C29 +// 0490: 55 a8 30 OFFIW $00A8,$30 ; both function +// 0493: c9 JR $049D +// 0494: 01 8f LDAW $008F +// 0496: 07 1f ANI A,$1F +// 0498: 1b MOV C,A +// 0499: 6d a1 MVI E,$A1 +// 049b: 78 d6 CALF $08D6 +// 049d: 6a 00 MVI B,$00 +// 049f: 24 58 ff LXI DE,$FF58 +// 04a2: 34 6c ff LXI HL,$FF6C +// 04a5: 2a LDAX (DE) +// 04a6: 70 b3 SUBNBX (HL) +// 04a8: 48 3a NEGA +// 04aa: 19 MOV EAL,A +// 04ab: 37 02 LTI A,$02 +// 04ad: 78 7e CALF $087E +// 04af: 22 INX DE +// 04b0: 32 INX HL +// 04b1: 42 INR B +// 04b2: 74 7a 10 EQI B,$10 +// 04b5: ef JR $04A5 +// 04b6: 2a LDAX (DE) +// 04b7: 70 b3 SUBNBX (HL) +// 04b9: 48 3a NEGA +// 04bb: 37 02 LTI A,$02 +// 04bd: 79 55 CALF $0955 +// 04bf: 22 INX DE +// 04c0: 32 INX HL +// 04c1: 01 6b LDAW $006B +// 04c3: 27 80 GTI A,$80 +// 04c5: 69 7f MVI A,$7F +// 04c7: 69 00 MVI A,$00 +// 04c9: 1b MOV C,A +// 04ca: 74 f8 7f EQAW $007F +// 04cd: 79 7e CALF $097E ; modwheel to midi +// 04cf: 55 4f 04 OFFIW $004F,$04 +// 04d2: 54 11 01 JMP $0111 +// 04d5: 25 ce 00 GTIW $00CE,$00 +// 04d8: d7 JR $04F0 +// 04d9: 7d 5b CALF $0D5B ; set both DP on +// 04db: 24 90 ff LXI DE,$FF90 ; patch? +// 04de: 6a 07 MVI B,$07 ; eight bytes +// 04e0: 01 ce LDAW $00CE ; +// 04e2: 1b MOV C,A ; save +// 04e3: 48 2a CLC +// 04e5: 48 03 SLRC C ; test if bit 0 is set +// 04e7: c2 JR $04EA ; it is +// 04e8: 79 47 CALF $0947 ; send E followed by (DE) to module board +// 04ea: 22 INX DE +// 04eb: 52 DCR B +// 04ec: f8 JR $04E5 +// 04ed: 71 ce 00 MVIW $00CE,$00 +// 04f0: 25 cf 00 GTIW $00CF,$00 +// 04f3: d7 JR $050B +// 04f4: 7d 5b CALF $0D5B ; set both DP on +// 04f6: 24 98 ff LXI DE,$FF98 +// 04f9: 6a 07 MVI B,$07 +// 04fb: 01 cf LDAW $00CF +// 04fd: 1b MOV C,A +// 04fe: 48 2a CLC +// 0500: 48 03 SLRC C +// 0502: c2 JR $0505 +// 0503: 79 47 CALF $0947 ; send E followed by (DE) to module board) +// 0505: 22 INX DE +// 0506: 52 DCR B +// 0507: f8 JR $0500 +// 0508: 71 cf 00 MVIW $00CF,$00 +// 050b: 5d b6 BIT 5,$00B6 +// 050d: d0 JR $051E +// 050e: 05 b6 df ANIW $00B6,$DF +// 0511: 7d 5b CALF $0D5B ; set both DP on +// 0513: 01 8e LDAW $008E +// 0515: 57 60 OFFI A,$60 +// 0517: c4 JR $051C +// 0518: 17 80 ORI A,$80 +// 051a: 63 8e STAW $008E +// 051c: 7b f9 CALF $0BF9 +// 051e: 5e b6 BIT 6,$00B6 +// 0520: cc JR $052D +// 0521: 05 b6 bf ANIW $00B6,$BF +// 0524: 7d 5b CALF $0D5B ; set both DP on +// 0526: 71 b7 00 MVIW $00B7,$00 +// 0529: 01 8f LDAW $008F +// 052b: 7c 29 CALF $0C29 +// 052d: 58 b6 BIT 0,$00B6 +// 052f: 54 11 01 JMP $0111 +// 0532: 6a 05 MVI B,$05 +// 0534: 34 8d ff LXI HL,$FF8D +// 0537: 2f LDAX (HL-) +// 0538: 47 80 ONI A,$80 +// 053a: c5 JR $0540 +// 053b: 52 DCR B +// 053c: fa JR $0537 +// 053d: 69 00 MVI A,$00 +// 053f: c2 JR $0542 +// 0540: 0a MOV A,B +// 0541: 41 INR A +// 0542: 34 50 00 LXI HL,$0050 ; lookup digit table +// 0545: ac LDAX (HL+A) +// 0546: 63 c6 STAW $00C6 ; store into right digit +// 0548: 54 11 01 JMP $0111 +// +// ; AD/timer handler +// 054b: 10 EXA +// 054c: 11 EXX +// 054d: 64 c8 08 ONI ANM,$08 ; test which set of AD inputs are selected +// 0550: d1 JR $0562 +// 0551: 34 68 ff LXI HL,$FF68 ; AD values +// 0554: 78 71 CALF $0871 ; fetch AD registers +// 0556: 01 c5 LDAW $00C5 ; left digit +// 0558: 4d c1 MOV PB,A ; write to buffer +// 055a: 64 05 00 MVI PF,$00 ; select BANK digit +// 055d: 64 80 00 MVI ANM,$00 ; +// 0560: 4e 2b JRE $058D +// 0562: 6e ff MVI H,$FF ; +// 0564: 01 cc LDAW $00CC ; variable +// 0566: 46 58 ADI A,$58 ; offset +// 0568: 1f MOV L,A +// 0569: 78 71 CALF $0871 ; fetch AD registers +// 056b: 01 cc LDAW $00CC +// 056d: 46 04 ADI A,$04 +// 056f: 48 0b SK HC +// 0571: cc JR $057E +// 0572: 71 cc 00 MVIW $00CC,$00 +// 0575: 20 cd INRW $00CD +// 0577: 00 NOP +// 0578: 64 80 08 MVI ANM,$08 +// 057b: 69 fc MVI A,$FC +// 057d: d1 JR $058F +// 057e: 63 cc STAW $00CC +// 0580: 48 01 SLRC A +// 0582: 48 01 SLRC A +// 0584: 46 c5 ADI A,$C5 +// 0586: 1f MOV L,A +// 0587: 2b LDAX (HL) +// 0588: 4d c1 MOV PB,A +// 058a: 64 45 40 ADI PF,$40 +// 058d: 69 f7 MVI A,$F7 +// 058f: 63 cb STAW $00CB +// 0591: 10 EXA +// 0592: 11 EXX +// 0593: aa EI +// 0594: 62 RETI +// +// ; serial interrupt handler +// 0595: 10 EXA +// 0596: 11 EXX +// 0597: 64 5e 04 OFFI MKH,$04 ; tx int masked +// 059a: c5 JR $05A0 +// 059b: 48 49 SKIT FSR ; receive interrupt +// 059d: 54 af 07 JMP $07AF ; handle TX interrupt +// 05a0: 48 6b SKNIT ER ; error +// 05a2: 4e 6f JRE $0613 ; handle error and return +// 05a4: 4c d9 MOV A,RXB ; receive byte +// 05a6: 47 80 ONI A,$80 ; skip bit 7 set? +// 05a8: 4e 70 JRE $061A ; not a status byte +// 05aa: 37 f0 LTI A,$F0 ; less than $f0 +// 05ac: 4e 50 JRE $05FE ; handle sysex etc +// 05ae: 1a MOV B,A ; save byte +// 05af: 05 4f 33 ANIW $004F,$33 ; mask bits in variable +// 05b2: 5d 4f BIT 5,$004F ; test bit in variable, maybe omni? +// 05b4: c4 JR $05B9 +// 05b5: 74 e0 bd SUBW $00BD +// 05b8: c2 JR $05BB +// 05b9: 07 f0 ANI A,$F0 ; mask off status, ignore channel +// 05bb: 67 90 NEI A,$90 ; note on? +// 05bd: c2 JR $05C0 ; +// 05be: 67 80 NEI A,$80 ; note off +// 05c0: 4e 25 JRE $05E7 ; handle note on/off +// 05c2: 67 b0 NEI A,$B0 ; control change +// 05c4: d7 JR $05DC ; +// 05c5: 5d a8 BIT 5,$00A8 ; function pin 49/2 +// 05c7: 4e 2a JRE $05F3 +// 05c9: 75 a2 00 EQIW $00A2,$00 +// 05cc: 71 a2 80 MVIW $00A2,$80 +// 05cf: 75 a1 00 EQIW $00A1,$00 +// 05d2: 71 a1 80 MVIW $00A1,$80 +// 05d5: 75 a0 00 EQIW $00A0,$00 +// 05d8: 71 a0 80 MVIW $00A0,$80 +// 05db: d3 JR $05EF ; return from interrupt +// +// ; handle control change +// 05dc: 1b MOV C,A +// 05dd: 0a MOV A,B +// 05de: 07 0f ANI A,$0F ; channel? +// 05e0: 74 e8 bd NEAW $00BD ; variable might be MIDI channel selected +// 05e3: 15 4f 40 ORIW $004F,$40 +// 05e6: 0b MOV A,C +// +// ; handling note on/off +// 05e7: 71 3f 01 MVIW $003F,$01 ; two bytes +// 05ea: 63 4e STAW $004E ; variable, store status +// 05ec: 15 4f 80 ORIW $004F,$80 ; set flag byte +// 05ef: 10 EXA +// 05f0: 11 EXX +// 05f1: aa EI +// 05f2: 62 RETI +// +// ; wasn't control or note +// 05f3: 67 c0 NEI A,$C0 ; program change? +// 05f5: c4 JR $05FA +// 05f6: 77 e0 EQI A,$E0 ; bender +// 05f8: f6 JR $05EF ; no, return +// 05f9: ed JR $05E7 ; handle two byte message +// 05fa: 71 3f 00 MVIW $003F,$00 ; one byte +// 05fd: ec JR $05EA ; store the variable, set the flag, return +// ; statuses > $f0 +// 05fe: 37 f8 LTI A,$F8 ; +// 0600: ee JR $05EF ; return if it's system realtime +// 0601: 77 f0 EQI A,$F0 ; actually sysex? +// 0603: d1 JR $0615 ; no +// 0604: 55 a8 30 OFFIW $00A8,$30 ; variable, function switch? +// 0607: cd JR $0615 +// 0608: 05 4f f3 ANIW $004F,$F3 +// 060b: 15 4f 04 ORIW $004F,$04 +// 060e: 71 3f 00 MVIW $003F,$00 ; expect one byte +// 0611: 4f d7 JRE $05EA ; store status and return +// 0613: 4c d9 MOV A,RXB ; handle error condition +// 0615: 05 4f 33 ANIW $004F,$33 ; +// 0618: 4f d5 JRE $05EF ; return +// ; not status byte +// 061a: 5f 4f BIT 7,$004F ; test if we're looking for a value not status? +// 061c: fb JR $0618 ; return +// 061d: 1b MOV C,A +// 061e: 5a 4f BIT 2,$004F ; flag variable +// 0620: 4e 8f JRE $06B1 ; handle double byte +// 0622: 5b 4f BIT 3,$004F ; flag variable +// 0624: 4e 53 JRE $0679 ; +// 0626: 5c 4f BIT 4,$004F ; flag variable +// 0628: 4e 41 JRE $066B +// 062a: 01 3f LDAW $003F +// 062c: 37 10 LTI A,$10 ; less than 16-byte message? +// 062e: 4e 20 JRE $0650 +// 0630: 1a MOV B,A +// 0631: 0b MOV A,C +// 0632: 34 90 ff LXI HL,$FF90 ; incoming patch data from sysex? +// 0635: bd STAX (HL+B) +// 0636: 34 08 00 LXI HL,$0008 +// 0639: 0a MOV A,B +// 063a: 07 07 ANI A,$07 +// 063c: ac LDAX (HL+A) +// 063d: 34 cf ff LXI HL,$FFCF +// 0640: 74 4a 08 ONI B,$08 +// 0643: 34 ce ff LXI HL,$FFCE +// 0646: 70 9b ORAX (HL) +// 0648: 3b STAX (HL) +// 0649: 20 3f INRW $003F +// 064b: 00 NOP +// ; return from interrupt +// 064c: 10 EXA +// 064d: 11 EXX +// 064e: aa EI +// 064f: 62 RETI +// 0650: 67 10 NEI A,$10 +// 0652: ca JR $065D +// 0653: 67 11 NEI A,$11 +// 0655: ce JR $0664 +// 0656: 05 4f 33 ANIW $004F,$33 +// 0659: 71 3f 00 MVIW $003F,$00 ; expect single byte +// 065c: ef JR $064C ; return +// 065d: 0b MOV A,C +// 065e: 63 8e STAW $008E +// 0660: 15 b6 20 ORIW $00B6,$20 +// 0663: e5 JR $0649 +// 0664: 0b MOV A,C +// 0665: 63 8f STAW $008F +// 0667: 15 b6 40 ORIW $00B6,$40 +// 066a: f8 JR $0663 +// 066b: 55 3f 01 OFFIW $003F,$01 +// 066e: c3 JR $0672 +// 066f: 63 3e STAW $003E +// 0671: f1 JR $0663 +// 0672: 01 3e LDAW $003E +// 0674: 27 11 GTI A,$11 +// 0676: 4f b4 JRE $062C +// 0678: ea JR $0663 +// +// ; +// 0679: 75 3f 00 EQIW $003F,$00 ; only one byte to get? +// 067c: c6 JR $0683 ; no +// 067d: 77 41 EQI A,$41 ; sysex manufacturer ID? +// 067f: 4f d5 JRE $0656 ; no +// 0681: 4f c6 JRE $0649 ; get sysex? +// 0683: 75 3f 01 EQIW $003F,$01 ; two bytes to get? +// 0686: d4 JR $069B ; no +// 0687: 77 30 EQI A,$30 ; receive patch change? +// 0689: c5 JR $068F ; no +// 068a: 15 4f 10 ORIW $004F,$10 ; flag variable +// 068d: 4f ba JRE $0649 ; increment ff3f and return +// 068f: 67 31 NEI A,$31 ; pressed manual? +// 0691: f8 JR $068A ; no +// 0692: 77 32 EQI A,$32 ; single controller +// 0694: 4f c0 JRE $0656 ; no +// 0696: 05 4f ef ANIW $004F,$EF ; flag variable +// 0699: 4f ae JRE $0649 ; increment counter and return +// 069b: 75 3f 02 EQIW $003F,$02 ; three bytes +// 069e: ca JR $06A9 +// 069f: 74 f8 bd EQAW $00BD +// 06a2: 4f b2 JRE $0656 +// 06a4: 55 4f 10 OFFIW $004F,$10 +// 06a7: 4f a0 JRE $0649 ; increment counter and return +// 06a9: 15 4f 08 ORIW $004F,$08 +// 06ac: 71 3f 00 MVIW $003F,$00 ; expect a single byte +// 06af: 4f 9b JRE $064C ; return +// +// ; handle incoming values +// 06b1: 30 3f DCRW $003F ; count down variable, skip if we roll over +// 06b3: 4e 59 JRE $070E ; store it in ff3e +// 06b5: 25 4e 91 GTIW $004E,$91 ; status byte? not note on +// 06b8: d1 JR $06CA +// 06b9: 65 4e b0 NEIW $004E,$B0 ; control change +// 06bc: 4e 54 JRE $0712 +// 06be: 65 4e c0 NEIW $004E,$C0 ; program change +// 06c1: 4e bd JRE $0780 +// 06c3: 65 4e e0 NEIW $004E,$E0 ; bend +// 06c6: 4e c7 JRE $078F +// 06c8: 4f 8c JRE $0656 +// +// ; handle note on/off? +// ; called with status in $ff4e, value in $ff3e and velocity in C +// 06ca: 01 3e LDAW $003E ; first byte +// 06cc: 27 17 GTI A,$17 ; greater than 23 +// 06ce: 4e 36 JRE $0706 ; no, add an octave +// 06d0: 37 6d LTI A,$6D ; less than 108 +// 06d2: 4e 36 JRE $070A ; no, subtract an octave +// 06d4: 74 e0 be SUBW $00BE ; subtract a value - transpose? +// 06d7: 1a MOV B,A ; save in b +// 06d8: 48 22 SLR B +// 06da: 48 22 SLR B +// 06dc: 48 22 SLR B ; divide by 8 +// 06de: 07 07 ANI A,$07 ; lower three bits +// 06e0: 75 4e 90 EQIW $004E,$90 ; note on? +// 06e3: d5 JR $06F9 ; no, jump ahead +// 06e4: 74 6b 00 NEI C,$00 ; velocity 0 +// 06e7: d1 JR $06F9 ; no, jump ahead +// ; otherwise fall through and handle Note On +// 06e8: 34 08 00 LXI HL,$0008 ; lookup table runs 01, 02, 04, 08, 10, 20, 40, 80 +// ; inverse of the one at 0x0010 +// 06eb: ac LDAX (HL+A) ; look up table based on note +// 06ec: 1b MOV C,A ; save +// 06ed: 34 40 ff LXI HL,$FF40 ; bit flags +// 06f0: ad LDAX (HL+B) ; byte pointed to by upper part +// 06f1: 60 9b ORA A,C ; or in whichever note is flagged +// 06f3: bd STAX (HL+B) ; save in flag +// +// ; +// 06f4: 71 3f 01 MVIW $003F,$01 ; expect two bytes +// 06f7: 4f 53 JRE $064C ; return +// +// ; note off? +// ; A contains lower three bits of note, B contains upper 4 bits +// 06f9: 34 10 00 LXI HL,$0010 ; lookup table runs fe, fd, fb, f7, ef, df, bf, 7f +// ; inverse of 0x0008 +// 06fc: ac LDAX (HL+A) ; look up the table based on the note +// 06fd: 1b MOV C,A ; fetch value, store in C +// 06fe: 34 40 ff LXI HL,$FF40 ; table in RAM +// 0701: ad LDAX (HL+B) ; $FF40 + upper four bits as offset +// 0702: 60 8b ANA A,C ; mask off the bit for the note +// 0704: bd STAX (HL+B) ; store at $FF40 + offset +// 0705: ee JR $06F4 +// +// ; add or subtract an octave to bring out-of-range notes in +// 0706: 46 0c ADI A,$0C ; add 12 to note value in A +// 0708: 4f c2 JRE $06CC ; jump back and test if it's in range yet +// 070a: 66 0c SUI A,$0C ; subtract 12 from note value in A +// 070c: 4f c2 JRE $06D0 ; jump back and test if it's in range yet +// +// ; store first value +// 070e: 63 3e STAW $003E +// 0710: 4f 3a JRE $064C ; return from interrupt +// +// ; control change? +// 0712: 01 3e LDAW $003E ; parameter? +// 0714: 27 7a GTI A,$7A ; all notes off, or higher? +// 0716: 4e 35 JRE $074D +// 0718: 45 4f 40 ONIW $004F,$40 ; flag variable +// 071b: 4f d7 JRE $06F4 +// 071d: 67 7b NEI A,$7B ; all notes off? +// 071f: 4e 51 JRE $0772 +// 0721: 47 02 ONI A,$02 ; mono/poly (but ignored according to the manual) +// 0723: c8 JR $072C +// 0724: 05 4f fd ANIW $004F,$FD ; flag variable +// 0727: 47 01 ONI A,$01 ; omni on +// 0729: 4e 4d JRE $0778 ; set omni off +// 072b: c8 JR $0734 +// 072c: 05 4f fe ANIW $004F,$FE ; clear flag variable bit 0 +// 072f: 47 01 ONI A,$01 ; if mono on? +// 0731: 15 4f 01 ORIW $004F,$01 ; set flag variable? +// 0734: 69 03 MVI A,$03 +// 0736: 74 88 4f ANAW $004F +// 0739: 15 4f 20 ORIW $004F,$20 +// 073c: 77 01 EQI A,$01 +// 073e: 05 4f df ANIW $004F,$DF +// 0741: 6a 0d MVI B,$0D ; 14 values +// 0743: 69 00 MVI A,$00 ; zero out note flags +// 0745: 34 40 ff LXI HL,$FF40 ; table in RAM for note flags +// 0748: 3d STAX (HL+) ; store +// 0749: 52 DCR B +// 074a: fd JR $0748 ; loop +// 074b: 4f a7 JRE $06F4 ; expect two bytes +// 074d: 77 40 EQI A,$40 ; sustain +// 074f: ce JR $075E +// 0750: 74 6b 00 NEI C,$00 ; value is zero +// 0753: c5 JR $0759 +// 0754: 15 b6 10 ORIW $00B6,$10 ; sustain on +// 0757: 4f 9b JRE $06F4 +// 0759: 15 b6 08 ORIW $00B6,$08 ; sustain off +// 075c: 4f 96 JRE $06F4 +// 075e: 77 01 EQI A,$01 ; mod wheel +// 0760: 4f 92 JRE $06F4 ; expect two bytes and return (running status) +// 0762: 55 a8 20 OFFIW $00A8,$20 ; midi mode 0 +// 0765: c7 JR $076D ; continue +// 0766: 0b MOV A,C ; get byte +// 0767: 17 80 ORI A,$80 ; set bit? +// 0769: 63 a2 STAW $00A2 ; mod wheel value? +// 076b: 4f 87 JRE $06F4 ; expect two bytes and return (running status) +// 076d: 71 a2 80 MVIW $00A2,$80 ; mod wheel off? +// 0770: 4f 82 JRE $06F4 ; expect two bytes and return +// +// ; handle all notes off +// 0772: 5d 4f BIT 5,$004F ; all notes off? +// 0774: 4f 7e JRE $06F4 ; expect two bytes and return +// 0776: 4f c9 JRE $0741 ; wipe a table +// 0778: 74 7b 01 EQI C,$01 +// 077b: 15 4f 02 ORIW $004F,$02 +// 077e: 4f b4 JRE $0734 +// +// ; program change +// 0780: 55 a8 20 OFFIW $00A8,$20 ; Midi mode 0? +// 0783: c5 JR $0789 ; skip ahead and do nothing +// 0784: 0b MOV A,C ; get prog +// 0785: 17 80 ORI A,$80 ; bit 7 +// 0787: 63 a3 STAW $00A3 ; store +// 0789: 71 3f 00 MVIW $003F,$00 ; expect one byte (running status) +// 078c: 54 4c 06 JMP $064C ; return +// +// ; bend +// 078f: 55 a8 20 OFFIW $00A8,$20 ; midi mode 0? +// 0792: d7 JR $07AA ; clear and end +// 0793: 0b MOV A,C +// 0794: 18 MOV EAH,A ; EAH gets msb +// 0795: 01 3e LDAW $003E ; lsb +// 0797: 48 25 SLL A ; multiply by two +// 0799: 19 MOV EAL,A ; EA contains 14-bit bend multiplied by 2 +// 079a: 48 a4 DSLL EA ; left aligned +// 079c: 08 MOV A,EAH +// 079d: 47 80 ONI A,$80 ; negative? +// 079f: c4 JR $07A4 +// 07a0: 63 a1 STAW $00A1 ; save in ffa1 +// 07a2: 4f 50 JRE $06F4 ; return, two byte running status +// 07a4: 16 ff XRI A,$FF ; invert +// 07a6: 63 a0 STAW $00A0 ; save in ffa0 +// 07a8: 4f 4a JRE $06F4 ; return, two byte running status +// 07aa: 71 a1 80 MVIW $00A1,$80 ; reset bend? +// 07ad: 4f 45 JRE $06F4 ; return, two byte running status +// +// ; handle TX interrupt +// 07af: 01 c1 LDAW $00C1 ; buffer pointers? +// 07b1: 74 f8 c2 EQAW $00C2 +// 07b4: 4e 25 JRE $07DB ; not equal, send byte +// 07b6: 64 1e 04 ORI MKH,$04 ; disable tx interrupt +// 07b9: 11 EXX ; return +// 07ba: 10 EXA +// 07bb: aa EI +// 07bc: 62 RETI +// +// ; handle command byte to assigner board +// 07bd: 1b MOV C,A ; save A +// 07be: 4c c2 MOV A,PC ; fetch port C +// 07c0: 60 93 XRA A,C ; XOR with "command" byte +// 07c2: 47 04 ONI A,$04 ; MIDI out / Serial Out +// 07c4: ca JR $07CF ; +// 07c5: 69 d0 MVI A,$D0 +// 07c7: 48 49 SKIT FSR ; receive buffer full? +// 07c9: c3 JR $07CD ; no +// 07ca: 54 a0 05 JMP $05A0 ; error handler +// 07cd: 41 INR A ; inc a, skip if it rolls over +// 07ce: f8 JR $07C7 ; loop around 32 times +// 07cf: 0f MOV A,L +// 07d0: 37 30 LTI A,$30 ; wrapped +// 07d2: 69 00 MVI A,$00 ; +// 07d4: 63 c1 STAW $00C1 ; set buffer pointer +// 07d6: 0b MOV A,C +// 07d7: 4d c2 MOV PC,A ; set port C +// 07d9: 4f d4 JRE $07AF ; handle TX interrupt +// +// ; fetch byte to send +// 07db: 6e ff MVI H,$FF +// 07dd: 1f MOV L,A ; contains pointer +// 07de: 2d LDAX (HL+) ; fetch byte +// 07df: 67 fd NEI A,$FD ; is it a module board command? +// 07e1: 4f da JRE $07BD ; yes +// 07e3: 67 f9 NEI A,$F9 ; is this "send midi?" +// 07e5: 4f d6 JRE $07BD ; yes +// 07e7: 48 4a SKIT FST ; wait for TX ready +// 07e9: cd JR $07F7 +// 07ea: 4d d8 MOV TXB,A ; transmit +// 07ec: 0f MOV A,L +// 07ed: 37 30 LTI A,$30 ; end of buffer +// 07ef: 69 00 MVI A,$00 ; wrap +// 07f1: 63 c1 STAW $00C1 ; TX pointer +// 07f3: 11 EXX +// 07f4: 10 EXA +// 07f5: aa EI +// 07f6: 62 RETI +// +// ; +// 07f7: 33 DCX HL +// 07f8: fa JR $07F3 +// 07f9: 00 NOP +// 07fa: 00 NOP +// 07fb: 00 NOP +// 07fc: 00 NOP +// 07fd: 00 NOP +// 07fe: 00 NOP +// 07ff: 00 NOP +// +// ; show transpose value +// 0800: 01 be LDAW $00BE ; transpose value +// 0802: 37 0c LTI A,$0C ; is it 12 +// 0804: c4 JR $0809 ; yes, don't show decimal point in left digit +// 0805: 71 c5 04 MVIW $00C5,$04 ; decimal point into left digit? +// 0808: c3 JR $080C ; show transpose +// 0809: 71 c5 00 MVIW $00C5,$00 ; blank left digit +// 080c: 34 60 00 LXI HL,$0060 ; lookup table - letters to segments +// 080f: ac LDAX (HL+A) +// 0810: 63 c6 STAW $00C6 ; right digit +// 0812: b8 RET +// +// ; look up bit patterns " 1" to "16" +// 0813: 05 4f dc ANIW $004F,$DC +// 0816: 15 4f 21 ORIW $004F,$21 +// 0819: 63 bd STAW $00BD +// 081b: 34 40 00 LXI HL,$0040 ; 1-16 with leading space +// 081e: ac LDAX (HL+A) +// 081f: 7d 45 CALF $0D45 ; look up bit patterns +// 0821: 78 43 CALF $0843 ; omni off poly +// 0823: 7b 9a CALF $0B9A ; zero out RAM at FF40 (key bitmap) +// 0825: 78 28 CALF $0828 ; reset modwheel +// 0827: b8 RET +// +// ; reset modwheel +// 0828: 69 80 MVI A,$80 +// 082a: 63 a1 STAW $00A1 ; centre modwheel +// 082c: 63 a2 STAW $00A2 ; centre pitchwheel +// 082e: 69 fd MVI A,$FD ; to module board +// 0830: 79 e8 CALF $09E8 ; send byte to TX +// 0832: 69 87 MVI A,$87 ; command $87 ; sustain on +// 0834: 79 e8 CALF $09E8 ; send byte to TX +// 0836: b8 RET +// +// ; send command in BC to module board +// 0837: 1b MOV C,A +// 0838: 69 fd MVI A,$FD +// 083a: 79 e8 CALF $09E8 ; send byte to TX +// 083c: 0a MOV A,B +// 083d: 79 e8 CALF $09E8 ; send byte to TX +// 083f: 0b MOV A,C +// 0840: 79 e8 CALF $09E8 ; send byte to TX +// 0842: b8 RET +// +// ; Omni Off Poly +// 0843: 69 f9 MVI A,$F9 ; send to MIDI +// 0845: 79 e8 CALF $09E8 ; send byte to TX +// 0847: 69 b0 MVI A,$B0 ; Continuous Controller +// 0849: 79 d5 CALF $09D5 ; send wiping running status +// 084b: 69 7c MVI A,$7C ; Omni Off +// 084d: 79 e8 CALF $09E8 ; send byte to TX +// 084f: 69 00 MVI A,$00 ; dummy +// 0851: 79 e8 CALF $09E8 ; send byte to TX +// 0853: 69 7f MVI A,$7F ; Poly on +// 0855: 79 e8 CALF $09E8 ; send byte to TX +// 0857: 69 00 MVI A,$00 ; dummy +// 0859: 79 e8 CALF $09E8 ; send byte to TX +// 085b: b8 RET +// +// ; Send "zero DAC" command to board +// 085c: 69 fd MVI A,$FD ; module board +// 085e: 79 e8 CALF $09E8 ; send byte to TX +// 0860: 69 8f MVI A,$8F ; switch register 2 +// 0862: 79 e8 CALF $09E8 ; send byte to TX +// 0864: 69 5f MVI A,$5F ; manual, gate, -, HPF 2, mystery bit 6? +// 0866: 79 e8 CALF $09E8 ; send byte to TX +// 0868: 69 a3 MVI A,$A3 ; +// 086a: 79 e8 CALF $09E8 ; send byte to TX +// 086c: 69 00 MVI A,$00 +// 086e: 79 e8 CALF $09E8 ; send byte to TX +// 0870: b8 RET +// +// ; fetch AD registers +// 0871: 4c e0 MOV A,CR0 +// 0873: 3d STAX (HL+) +// 0874: 4c e1 MOV A,CR1 +// 0876: 3d STAX (HL+) +// 0877: 4c e2 MOV A,CR2 +// 0879: 3d STAX (HL+) +// 087a: 4c e3 MOV A,CR3 +// 087c: 3b STAX (HL) +// 087d: b8 RET +// +// ; +// 087e: 78 c3 CALF $08C3 +// 0880: 59 b6 BIT 1,$00B6 +// 0882: 4e 23 JRE $08A7 +// 0884: 55 c5 10 OFFIW $00C5,$10 ; is left digit decimal point set? +// ; poss. is edited +// 0887: df JR $08A7 +// 0888: b3 PUSH HL +// 0889: b2 PUSH DE +// 088a: 6c ff MVI D,$FF +// 088c: 34 30 00 LXI HL,$0030 ; lookup table +// 088f: ad LDAX (HL+B) +// 0890: 1d MOV E,A +// 0891: 0b MOV A,C +// 0892: 3a STAX (DE) +// 0893: 69 fd MVI A,$FD +// 0895: 79 e8 CALF $09E8 ; send byte to TX +// 0897: 0d MOV A,E +// 0898: 79 e8 CALF $09E8 ; send byte to TX +// 089a: 0b MOV A,C +// 089b: 79 e8 CALF $09E8 ; send byte to TX +// 089d: 45 a8 30 ONIW $00A8,$30 +// 08a0: 78 d6 CALF $08D6 +// 08a2: a2 POP DE +// 08a3: a3 POP HL +// 08a4: 2a LDAX (DE) +// 08a5: 3b STAX (HL) +// 08a6: b8 RET +// +// 08a7: b3 PUSH HL +// 08a8: b2 PUSH DE +// 08a9: 6c ff MVI D,$FF +// 08ab: 34 30 00 LXI HL,$0030 +// 08ae: ad LDAX (HL+B) +// 08af: 1d MOV E,A +// 08b0: 2a LDAX (DE) +// 08b1: 57 80 OFFI A,$80 +// 08b3: c9 JR $08BD +// 08b4: 09 MOV A,EAL +// 08b5: 37 10 LTI A,$10 +// 08b7: c3 JR $08BB +// 08b8: a2 POP DE +// 08b9: a3 POP HL +// 08ba: b8 RET +// +// 08bb: 7d 5b CALF $0D5B ; set both DP on +// 08bd: 0b MOV A,C +// 08be: 17 80 ORI A,$80 +// 08c0: 3a STAX (DE) +// 08c1: 4f d0 JRE $0893 +// +// ; subroutine +// 08c3: 2a LDAX (DE) +// 08c4: 36 04 SUINB A,$04 +// 08c6: 69 00 MVI A,$00 +// 08c8: 27 f2 GTI A,$F2 +// 08ca: c7 JR $08D2 +// 08cb: 1b MOV C,A +// 08cc: 66 f2 SUI A,$F2 +// 08ce: 60 a3 ADDNC A,C +// 08d0: 69 ff MVI A,$FF +// 08d2: 48 21 SLR A +// 08d4: 1b MOV C,A +// 08d5: b8 RET +// +// ; subroutine +// 08d6: 6c 32 MVI D,$32 +// 08d8: 79 15 CALF sendSysexHeader +// 08da: 0d MOV A,E +// 08db: 66 90 SUI A,$90 +// 08dd: 07 7f ANI A,$7F +// 08df: 79 e8 CALF $09E8 ; send byte to TX +// 08e1: 0b MOV A,C +// 08e2: 79 e8 CALF $09E8 ; send byte to TX +// 08e4: 69 f7 MVI A,$F7 ; sysex end +// 08e6: 79 e6 CALF $09E6 ; save running status +// 08e8: b8 RET +// +// 08e9: 6c 31 MVI D,$31 +// 08eb: 79 15 CALF sendSysexHeader +// 08ed: 69 00 MVI A,$00 +// 08ef: c6 JR $08F6 +// +// ; send sysex patch change +// sendSysexPatch: +// 08f0: 6c 30 MVI D,$30 +// 08f2: 79 15 CALF sendSysexHeader ; send sysex header +// 08f4: 79 36 CALF $0936 +// 08f6: 79 e8 CALF $09E8 ; send byte to TX +// 08f8: 6a 0f MVI B,$0F +// 08fa: 34 90 ff LXI HL,$FF90 ; start of working patch RAM +// 08fd: 2d LDAX (HL+) +// 08fe: 07 7f ANI A,$7F +// 0900: 79 e8 CALF $09E8 ; send byte to TX +// 0902: 52 DCR B +// 0903: f9 JR $08FD ; loop around +// 0904: 01 8e LDAW $008E ; switches 1 +// 0906: 07 7f ANI A,$7F +// 0908: 79 e8 CALF $09E8 ; send byte to TX +// 090a: 01 8f LDAW $008F ; switches 2 +// 090c: 07 1f ANI A,$1F +// 090e: 79 e8 CALF $09E8 ; send byte to TX +// 0910: 69 f7 MVI A,$F7 ; terminate sysex +// 0912: 79 e8 CALF $09E8 ; send byte to TX +// 0914: b8 RET +// +// ; send sysex header +// sendSysexHeader: +// 0915: 69 f9 MVI A,$F9 ; MIDI on +// 0917: 79 e8 CALF $09E8 ; send byte to TX +// 0919: 69 f0 MVI A,$F0 ; sysex +// 091b: 79 e6 CALF $09E6 ; set running status +// 091d: 69 41 MVI A,$41 ; Roland +// 091f: 79 e8 CALF $09E8 ; send byte to TX +// 0921: 0c MOV A,D ; command +// 0922: 79 e8 CALF $09E8 ; send byte to TX +// 0924: 01 bd LDAW $00BD ; MIDI channel +// 0926: 79 e8 CALF $09E8 ; send byte to TX +// 0928: b8 RET +// +// ; send program change +// 0929: 69 f9 MVI A,$F9 +// 092b: 79 e8 CALF $09E8 ; send byte to TX +// 092d: 69 c0 MVI A,$C0 ; program change +// 092f: 79 d5 CALF $09D5 ; test and set running status +// 0931: 79 36 CALF $0936 +// 0933: 79 e8 CALF $09E8 ; send byte to TX +// 0935: b8 RET +// +// ; turn internal program into MIDI value +// 0936: 01 bb LDAW $00BB ; value +// 0938: 51 DCR A ; +// 0939: 1b MOV C,A +// 093a: 01 ba LDAW $00BA +// 093c: 66 10 SUI A,$10 +// 093e: 48 21 SLR A +// 0940: 60 9b ORA A,C +// 0942: 5e c8 BIT 6,$00C8 +// 0944: 17 40 ORI A,$40 +// 0946: b8 RET +// +// ; +// 0947: 69 fd MVI A,$FD ; module +// 0949: 79 e8 CALF $09E8 ; send byte to TX +// 094b: 0d MOV A,E +// 094c: 79 e8 CALF $09E8 ; send byte to TX +// 094e: 2a LDAX (DE) +// 094f: 07 7f ANI A,$7F ; does setting its upper bit mean it needs sent? +// 0951: 3a STAX (DE) +// 0952: 79 e8 CALF $09E8 ; send byte to TX +// 0954: b8 RET +// +// ; send pitchbend to MIDI +// 0955: 55 a8 20 OFFIW $00A8,$20 ; Midi mode 0? +// 0958: b8 RET +// 0959: 2a LDAX (DE) +// 095a: 3b STAX (HL) +// 095b: 44 00 00 LXI EA,$0000 +// 095e: 35 6a 80 LTIW $006A,$80 +// 0961: 16 ff XRI A,$FF +// 0963: 18 MOV EAH,A +// 0964: 48 a0 DSLR EA +// 0966: 48 a0 DSLR EA +// 0968: 69 f9 MVI A,$F9 +// 096a: 79 e8 CALF $09E8 ; send byte to TX +// 096c: 69 e0 MVI A,$E0 ; pitch wheel +// 096e: 79 dc CALF $09DC ; send status byte, setting running status +// 0970: 09 MOV A,EAL +// 0971: 48 21 SLR A +// 0973: 79 e8 CALF $09E8 ; send pitch wheel low byte to TX +// 0975: 08 MOV A,EAH +// 0976: 25 6a 80 GTIW $006A,$80 ; bend or down? +// 0979: 17 40 ORI A,$40 +// 097b: 79 e8 CALF $09E8 ; send signed high byte to TX +// 097d: b8 RET +// +// ; send modwheel to MIDI +// 097e: 0b MOV A,C +// 097f: 63 7f STAW $007F +// 0981: 55 a8 20 OFFIW $00A8,$20 ; midi mode 0? +// 0984: b8 RET +// 0985: 1b MOV C,A +// 0986: 69 f9 MVI A,$F9 +// 0988: 79 e8 CALF $09E8 ; send byte to TX +// 098a: 69 b0 MVI A,$B0 ; control change +// 098c: 79 d5 CALF $09D5 ; send status byte and set running status +// 098e: 69 01 MVI A,$01 ; modwheel +// 0990: 79 e8 CALF $09E8 ; send byte to TX +// 0992: 0b MOV A,C +// 0993: 79 e8 CALF $09E8 ; send byte to TX +// 0995: b8 RET +// +// ; determine if we need to send Note On or Note Off +// 0996: 19 MOV EAL,A ; save key bit +// 0997: 0a MOV A,B ; key column number +// 0998: 07 07 ANI A,$07 ; not sure why this would be more than 0-7 +// 099a: 7a 0d CALF $0A0D ; multiply A by 8 and put it in EAH, store C in ffc3 +// 099c: b3 PUSH HL +// 099d: b1 PUSH BC +// 099e: 6a 00 MVI B,$00 ; +// 09a0: 09 MOV A,EAL ; key bitpattern +// 09a1: 1b MOV C,A ; +// 09a2: 48 03 SLRC C ; skip if bit 0 was set (skip if carry) +// 09a4: d5 JR $09BA +// 09a5: 34 08 00 LXI HL,$0008 ; +// 09a8: ad LDAX (HL+B) ; convert count to bit +// 09a9: 74 c8 c3 ONAW $00C3 ; is it set in C3 +// 09ac: c7 JR $09B4 ; no +// 09ad: 79 c2 CALF $09C2 ; yes +// 09af: 69 40 MVI A,$40 ; velocity = 64 +// 09b1: 79 e8 CALF $09E8 ; send byte to TX +// 09b3: c6 JR $09BA +// 09b4: 79 c2 CALF $09C2 ; +// 09b6: 69 00 MVI A,$00 ; velocity = 0 +// 09b8: 79 e8 CALF $09E8 ; send byte to TX +// 09ba: 42 INR B ; next +// 09bb: 74 7a 08 EQI B,$08 +// 09be: e3 JR $09A2 ; loop around +// 09bf: a1 POP BC +// 09c0: a3 POP HL +// 09c1: b8 RET +// +// ; Note On +// ; doesn't send velocity, that's dealt with by the routine at 0996 +// 09c2: 69 f9 MVI A,$F9 +// 09c4: 79 e8 CALF $09E8 ; select MIDI out +// 09c6: 69 90 MVI A,$90 +// 09c8: 79 dc CALF $09DC ; note on +// 09ca: 08 MOV A,EAH ; upper bits of note from routine at 0a0d +// 09cb: 60 9a ORA A,B ; lower bits of note (bit count) +// 09cd: 46 18 ADI A,$18 ; offset 24 +// 09cf: 74 c0 be ADDW $00BE ; transpose +// 09d2: 79 e8 CALF $09E8 ; send byte to TX +// 09d4: b8 RET +// +// +// 09d5: 74 c0 bd ADDW $00BD ; add in MIDI channel +// 09d8: 71 c0 00 MVIW $00C0,$00 ; zero out running status? +// 09db: cc JR $09E8 ; send byte to TX +// +// ; send status byte? +// 09dc: 47 80 ONI A,$80 ; is it a status byte? +// 09de: c9 JR $09E8 ; send byte to TX if not +// 09df: 74 c0 bd ADDW $00BD ; add in MIDI channel +// 09e2: 74 e8 c0 NEAW $00C0 ; if running status hasn't changed +// 09e5: b8 RET ; go back +// 09e6: 63 c0 STAW $00C0 ; save running status byte +// +// ; send command to serial +// 09e8: b3 PUSH HL +// 09e9: b1 PUSH BC +// 09ea: b2 PUSH DE +// 09eb: 1b MOV C,A ; save A +// 09ec: 01 c2 LDAW $00C2 ; TX buffer queue pointer +// 09ee: 41 INR A ; inc +// 09ef: 67 30 NEI A,$30 ; if it's 30 +// 09f1: 69 00 MVI A,$00 ; reset to 0 +// 09f3: 74 e8 c1 NEAW $00C1 ; wait until all bytes are sent +// 09f6: fc JR $09F3 +// 09f7: 1d MOV E,A ; save +// 09f8: 01 c2 LDAW $00C2 ; fetch second one again +// 09fa: 34 00 ff LXI HL,$FF00 +// 09fd: 1a MOV B,A ; pointer +// 09fe: 0b MOV A,C ; restore A +// 09ff: bd STAX (HL+B) ; save into buffer +// 0a00: 0d MOV A,E ; other pointer +// 0a01: 64 1e 07 ORI MKH,$07 ; mask AD, TX, RX interrupt flags +// 0a04: 63 c2 STAW $00C2 ; update pointer +// 0a06: 64 0e f8 ANI MKH,$F8 ; unmask AD, TX, RX +// 0a09: a2 POP DE ; restore registers +// 0a0a: a1 POP BC +// 0a0b: a3 POP HL +// 0a0c: b8 RET ; return +// +// ; +// 0a0d: 48 25 SLL A +// 0a0f: 48 25 SLL A +// 0a11: 48 25 SLL A +// 0a13: 18 MOV EAH,A +// 0a14: 0b MOV A,C +// 0a15: 63 c3 STAW $00C3 +// 0a17: b8 RET +// +// ; +// ; called if a keypress changed +// 0a18: 19 MOV EAL,A ; save note bitmap +// 0a19: 0a MOV A,B ; save bitcolumn +// 0a1a: 7a 0d CALF $0A0D ; multiply bits by 8, store C in FFC3 +// 0a1c: b3 PUSH HL +// 0a1d: b1 PUSH BC +// 0a1e: 6a 07 MVI B,$07 ; count bits +// 0a20: 09 MOV A,EAL ; bitmap +// 0a21: 1b MOV C,A ; save +// 0a22: 34 08 00 LXI HL,$0008 ; lookup table +// 0a25: 48 07 SLLC C ; shift left until it fall off the end +// 0a27: 4e 37 JRE $0A60 ; +// 0a29: ad LDAX (HL+B) ; look up bitfield in B +// 0a2a: 74 c8 c3 ONAW $00C3 ; was this already set +// 0a2d: 4e 23 JRE $0A52 ; +// 0a2f: 08 MOV A,EAH ; +// 0a30: 60 9a ORA A,B ; +// 0a32: 59 c8 BIT 1,$00C8 ; Poly 1? +// 0a34: da JR $0A4F ; no, skip ahead +// 0a35: 5a c8 BIT 2,$00C8 ; Poly 2? +// 0a37: c7 JR $0A3F ; no, skip ahead +// 0a38: 58 b6 BIT 0,$00B6 ; test mode flag? +// 0a3a: c7 JR $0A42 ; jump on ahead +// 0a3b: 7a 88 CALF $0A88 ; ? +// 0a3d: 4e 21 JRE $0A60 ; jump ahead to try next voice +// 0a3f: 58 b6 BIT 0,$00B6 +// 0a41: ca JR $0A4C +// 0a42: 75 d0 00 EQIW $00D0,$00 ; if ffd0=0 skip +// 0a45: da JR $0A60 ; ahead to loop around voices +// 0a46: 7b 55 CALF $0B55 voiceOnUnison +// 0a48: 71 d0 80 MVIW $00D0,$80 ; +// 0a4b: d4 JR $0A60 ; loop around +// 0a4c: 7a af CALF $0AAF +// 0a4e: d1 JR $0A60 +// 0a4f: 7a 76 CALF $0A76 +// 0a51: ce JR $0A60 +// 0a52: 08 MOV A,EAH +// 0a53: 60 9a ORA A,B +// 0a55: 59 c8 BIT 1,$00C8 +// 0a57: c6 JR $0A5E +// 0a58: 5a c8 BIT 2,$00C8 +// 0a5a: cb JR $0A66 +// 0a5b: 58 b6 BIT 0,$00B6 +// 0a5d: cb JR $0A69 +// 0a5e: 7b 30 CALF $0B30 +// 0a60: 52 DCR B +// 0a61: 4f c2 JRE $0A25 +// 0a63: a1 POP BC +// 0a64: a3 POP HL +// 0a65: b8 RET +// +// 0a66: 58 b6 BIT 0,$00B6 +// 0a68: ca JR $0A73 +// 0a69: 75 d0 00 EQIW $00D0,$00 +// 0a6c: f3 JR $0A60 +// 0a6d: 7b 70 CALF $0B70 ; stop all notes? +// 0a6f: 71 d0 ff MVIW $00D0,$FF +// 0a72: ed JR $0A60 +// 0a73: 7a f8 CALF $0AF8 +// 0a75: ea JR $0A60 +// +// 0a76: b3 PUSH HL +// 0a77: b1 PUSH BC +// 0a78: 1b MOV C,A +// 0a79: 6a 05 MVI B,$05 +// 0a7b: 34 88 ff LXI HL,$FF88 +// 0a7e: 2b LDAX (HL) +// 0a7f: 57 80 OFFI A,$80 +// 0a81: dc JR $0A9E +// 0a82: 32 INX HL +// 0a83: 52 DCR B +// 0a84: f9 JR $0A7E +// 0a85: a1 POP BC +// 0a86: a3 POP HL +// 0a87: b8 RET +// +// ; send note to module board? +// 0a88: b3 PUSH HL +// 0a89: b1 PUSH BC +// 0a8a: 6e ff MVI H,$FF +// 0a8c: 1b MOV C,A +// 0a8d: 01 86 LDAW $0086 ; note number +// 0a8f: 41 INR A ; increment, skip if carry +// 0a90: 77 8e EQI A,$8E ; 88-8d, 8e is seventh? +// 0a92: c2 JR $0A95 +// 0a93: 69 88 MVI A,$88 ; rotate back to first +// 0a95: 63 86 STAW $0086 ; voice under consideration +// 0a97: 1f MOV L,A ; HL contains voice? +// 0a98: 2b LDAX (HL) ; fetch value +// 0a99: 57 80 OFFI A,$80 +// 0a9b: c2 JR $0A9E +// 0a9c: 52 DCR B +// 0a9d: ef JR $0A8D +// +// 0a9e: 69 fd MVI A,$FD ; module board +// 0aa0: 79 e8 CALF $09E8 ; send select module command to TX +// 0aa2: 0f MOV A,L +// 0aa3: 79 e8 CALF $09E8 ; send note on command to TX +// 0aa5: 0b MOV A,C +// 0aa6: 3b STAX (HL) +// 0aa7: 74 c0 be ADDW $00BE ; transpose +// 0aaa: 79 e8 CALF $09E8 ; send note value to TX +// 0aac: a1 POP BC +// 0aad: a3 POP HL +// 0aae: b8 RET +// +// ; maybe voice stealing +// 0aaf: b3 PUSH HL +// 0ab0: b1 PUSH BC +// 0ab1: b2 PUSH DE +// 0ab2: 1b MOV C,A ; save HL, BC, DE, A +// 0ab3: 6a 05 MVI B,$05 ; six voices +// 0ab5: 6c ff MVI D,$FF ; set up DE to point to RAM +// 0ab7: 34 85 ff LXI HL,$FF85 ; voice number of last voice +// 0aba: 2b LDAX (HL) ; into A +// 0abb: 1d MOV E,A ; DE now points to voice number +// 0abc: 2a LDAX (DE) ; A now contains voice +// 0abd: 57 80 OFFI A,$80 ; upper bit not set +// 0abf: ca JR $0ACA ; it was set +// 0ac0: a2 POP DE ; it was not set, end +// 0ac1: a1 POP BC +// 0ac2: a3 POP HL +// 0ac3: b8 RET +// ; looped if c=a +// 0ac4: 2b LDAX (HL) ; fetch next voce +// 0ac5: 1d MOV E,A +// 0ac6: 2a LDAX (DE) ; value +// 0ac7: 47 80 ONI A,$80 ; top bit set yet? +// 0ac9: c8 JR $0AD2 ; yes +// ; top bit was set +// 0aca: 07 7f ANI A,$7F ; strip top bit +// 0acc: 60 eb NEA A,C ; c=a? +// 0ace: d1 JR $0AE0 ; no +// 0acf: 33 DCX HL ; move down one note +// 0ad0: 52 DCR B ; count down +// 0ad1: f2 JR $0AC4 ; loop around voices +// 0ad2: 32 INX HL ; back up a voice +// 0ad3: 2b LDAX (HL) ; get its voice number +// 0ad4: 1d MOV E,A ; into DE +// 0ad5: 0b MOV A,C ; restore C into A +// 0ad6: ce JR $0AE5 +// 0ad7: 33 DCX HL ; count down +// 0ad8: af 01 LDAX (HL+$01) ; fetch next one up +// 0ada: 1b MOV C,A ; save +// 0adb: 2b LDAX (HL) ; fetch this +// 0adc: bf 01 STAX (HL+$01) ; save +// 0ade: 0b MOV A,C ; restore +// 0adf: 3b STAX (HL) ; save +// 0ae0: 52 DCR B ; count down +// 0ae1: f5 JR $0AD7 ; loop +// 0ae2: 2a LDAX (DE) ; voice +// 0ae3: 07 7f ANI A,$7F ; mask top bit +// 0ae5: 3a STAX (DE) ; save back +// 0ae6: 74 c0 be ADDW $00BE ; transpose +// 0ae9: 1b MOV C,A +// 0aea: 69 fd MVI A,$FD ; select module board +// 0aec: 79 e8 CALF $09E8 ; send byte to TX +// 0aee: 0d MOV A,E ; voice number +// 0aef: 79 e8 CALF $09E8 ; send byte to TX +// 0af1: 0b MOV A,C ; note number +// 0af2: 79 e8 CALF $09E8 ; send byte to TX +// 0af4: a2 POP DE +// 0af5: a1 POP BC +// 0af6: a3 POP HL +// 0af7: b8 RET +// +// ; +// 0af8: b3 PUSH HL +// 0af9: b1 PUSH BC +// 0afa: b2 PUSH DE +// 0afb: 1b MOV C,A +// 0afc: 6a 05 MVI B,$05 +// 0afe: 6c ff MVI D,$FF +// 0b00: 34 80 ff LXI HL,$FF80 +// 0b03: 2b LDAX (HL) +// 0b04: 1d MOV E,A +// 0b05: 2a LDAX (DE) +// 0b06: 07 7f ANI A,$7F +// 0b08: 60 eb NEA A,C +// 0b0a: d0 JR $0B1B +// 0b0b: 32 INX HL +// 0b0c: 52 DCR B +// 0b0d: f5 JR $0B03 +// 0b0e: a2 POP DE +// 0b0f: a1 POP BC +// 0b10: a3 POP HL +// 0b11: b8 RET +// +// ; +// 0b12: 2b LDAX (HL) +// 0b13: 1b MOV C,A +// 0b14: af 01 LDAX (HL+$01) +// 0b16: 3b STAX (HL) +// 0b17: 0b MOV A,C +// 0b18: bf 01 STAX (HL+$01) +// 0b1a: 32 INX HL +// 0b1b: 52 DCR B +// 0b1c: f5 JR $0B12 +// 0b1d: 2a LDAX (DE) +// 0b1e: 17 80 ORI A,$80 +// 0b20: 3a STAX (DE) +// 0b21: 0d MOV A,E +// 0b22: 66 08 SUI A,$08 +// 0b24: 1b MOV C,A +// 0b25: 69 fd MVI A,$FD +// 0b27: 79 e8 CALF $09E8 ; send byte to TX +// 0b29: 0b MOV A,C +// 0b2a: 79 e8 CALF $09E8 ; send byte to TX +// 0b2c: a2 POP DE +// 0b2d: a1 POP BC +// 0b2e: a3 POP HL +// 0b2f: b8 RET +// +// ; find voice to switch off +// 0b30: b3 PUSH HL +// 0b31: b1 PUSH BC +// 0b32: 1b MOV C,A ; save HL, BC, A +// 0b33: 6a 05 MVI B,$05 ; six voices +// 0b35: 34 88 ff LXI HL,$FF88 ; other voice table +// 0b38: 2b LDAX (HL) ; fetch +// 0b39: 47 80 ONI A,$80 ; top bit set +// 0b3b: c6 JR $0B42 ; no +// 0b3c: 32 INX HL ; yes, next voice +// 0b3d: 52 DCR B ; one less voice to consider +// 0b3e: f9 JR $0B38 ; loop back around +// 0b3f: a1 POP BC ; restore BC and HL +// 0b40: a3 POP HL ; but not A? +// 0b41: b8 RET ; return to 0a60 +// 0b42: 60 eb NEA A,C ; skip if a != c +// 0b44: c1 JR $0B46 ; a=c +// 0b45: f6 JR $0B3C ; a!=c +// 0b46: 17 80 ORI A,$80 ; a!=c, set A's upper bit +// 0b48: 3b STAX (HL) ; store +// 0b49: 69 fd MVI A,$FD ; select module board +// 0b4b: 79 e8 CALF $09E8 ; +// 0b4d: 0f MOV A,L ; L is 88 to 8d +// 0b4e: 66 08 SUI A,$08 ; L is now 80 to 85, voice off message +// 0b50: 79 e8 CALF $09E8 ; send byte to TX +// 0b52: a1 POP BC +// 0b53: a3 POP HL +// 0b54: b8 RET +// +// ; called with note value in A +// voiceOnUnison: +// 0b55: b3 PUSH HL +// 0b56: b1 PUSH BC +// 0b57: 74 c0 be ADDW $00BE ; transpose +// 0b5a: 1b MOV C,A ; save +// 0b5b: 6a 05 MVI B,$05 ; six voices +// 0b5d: 34 88 ff LXI HL,$FF88 ; voice table +// 0b60: 69 fd MVI A,$FD ; send to module board +// 0b62: 79 e8 CALF $09E8 +// 0b64: 0f MOV A,L ; voice number +// 0b65: 79 e8 CALF $09E8 ; to module board +// 0b67: 0b MOV A,C ; note +// 0b68: 79 e8 CALF $09E8 ; to module board +// 0b6a: 32 INX HL ; next note +// 0b6b: 52 DCR B ; count down +// 0b6c: f7 JR $0B64 ; loop +// 0b6d: a1 POP BC ; return +// 0b6e: a3 POP HL +// 0b6f: b8 RET +// +// ; stop all notes? +// ; sends $FD $80 $81 $82 $83 $84 $85 +// 0b70: b1 PUSH BC +// 0b71: 6b 80 MVI C,$80 +// 0b73: 6a 05 MVI B,$05 +// 0b75: 69 fd MVI A,$FD ; select module board +// 0b77: 79 e8 CALF $09E8 ; send byte to TX +// 0b79: 0b MOV A,C ; send each voice off message +// 0b7a: 79 e8 CALF $09E8 ; send byte to TX +// 0b7c: 43 INR C +// 0b7d: 52 DCR B +// 0b7e: fa JR $0B79 +// 0b7f: a1 POP BC +// 0b80: b8 RET +// + +void Assigner::resetVoices() { + // ; subroutine called at start + // 0b81: 34 88 ff LXI HL,$FF88 ; fill six bytes of ram with $80 + hl = 0x88; + // 0b84: 6a 05 MVI B,$05 + b = 5; // five voices + // 0b86: 69 80 MVI A,$80 + a = 0x80; + // 0b88: 3d STAX (HL+) + h0b88: + ram[hl++] = a; + // 0b89: 52 DCR B + // 0b8a: fd JR $0B88 + if (b>0) { + b--; + goto h0b88; + } + // 0b8b: 34 80 ff LXI HL,$FF80 ; fill six bytes of RAM with $88-$8d + hl = 0x80; + // 0b8e: 6a 05 MVI B,$05 + b = 0x05; + // 0b90: 69 88 MVI A,$88 + a = 0x88; + // 0b92: 3d STAX (HL+) + h0b92: + ram[hl++] = a; + // 0b93: 41 INR A + a++; + // 0b94: 52 DCR B + // 0b95: fc JR $0B92 + if (b>0) { + b--; + goto h0b92; + } + // 0b96: 71 86 88 MVIW $0086,$88 ; set voice number to $88 (first voice) + ram[0x86] = 0x88; + // 0b99: b8 RET + // +} + +// ; zero out 14 bytes at ff40 +// ; something to do with storing note flags +// 0b9a: 34 40 ff LXI HL,$FF40 +// 0b9d: c3 JR $0BA1 +// +// ; +// 0b9e: 34 30 ff LXI HL,$FF30 ; zero out 14 bytes at ff30 +// 0ba1: 6a 0d MVI B,$0D +// 0ba3: 69 00 MVI A,$00 +// 0ba5: 3d STAX (HL+) +// 0ba6: 52 DCR B +// 0ba7: fd JR $0BA5 +// 0ba8: b8 RET +// +// ; +// 0ba9: 69 fd MVI A,$FD ; select module board +// 0bab: 79 e8 CALF $09E8 ; send byte to TX +// 0bad: 0b MOV A,C +// 0bae: 47 08 ONI A,$08 +// 0bb0: 69 86 MVI A,$86 ; +// 0bb2: 69 87 MVI A,$87 ; ignored if previous instruction ran +// 0bb4: 79 e8 CALF $09E8 ; send byte to TX +// 0bb6: 69 f9 MVI A,$F9 ; MIDI +// 0bb8: 79 e8 CALF $09E8 ; send byte to TX +// 0bba: 69 b0 MVI A,$B0 ; MIDI CC +// 0bbc: 79 d5 CALF $09D5 ; send and set running status +// 0bbe: 69 40 MVI A,$40 ; sustain +// 0bc0: 79 e8 CALF $09E8 ; send byte to TX +// 0bc2: 0b MOV A,C +// 0bc3: 47 08 ONI A,$08 ; if the bit is set +// 0bc5: 69 7f MVI A,$7F ; skip +// 0bc7: 69 00 MVI A,$00 ; ignored if previous instruction was run +// 0bc9: 79 e8 CALF $09E8 ; send byte to TX +// 0bcb: b8 RET +// +// ; +// 0bcc: 01 b2 LDAW $00B2 +// 0bce: 07 07 ANI A,$07 +// 0bd0: 1a MOV B,A +// 0bd1: 01 8e LDAW $008E +// 0bd3: 07 f8 ANI A,$F8 +// 0bd5: 60 9a ORA A,B +// 0bd7: 63 8e STAW $008E +// 0bd9: b8 RET +// +// ; +// 0bda: 01 b2 LDAW $00B2 +// 0bdc: 74 90 8e XRAW $008E +// 0bdf: 07 18 ANI A,$18 +// 0be1: 1a MOV B,A +// 0be2: 01 8e LDAW $008E +// 0be4: 07 e7 ANI A,$E7 +// 0be6: 60 9a ORA A,B +// 0be8: 63 8e STAW $008E +// 0bea: b8 RET +// +// ; +// 0beb: 01 b2 LDAW $00B2 +// 0bed: 07 e0 ANI A,$E0 +// 0bef: 1a MOV B,A +// 0bf0: 01 8e LDAW $008E +// 0bf2: 07 1f ANI A,$1F +// 0bf4: 60 9a ORA A,B +// 0bf6: 63 8e STAW $008E +// 0bf8: b8 RET +// +// ; sends switches 1 to the voice board +// 0bf9: 63 c7 STAW $00C7 +// 0bfb: 16 ff XRI A,$FF +// 0bfd: 07 7f ANI A,$7F ; invert and mask off bit 7 +// 0bff: 1b MOV C,A ; save +// 0c00: 69 fd MVI A,$FD +// 0c02: 79 e8 CALF $09E8 ; module board +// 0c04: 69 8e MVI A,$8E ; switches 1 +// 0c06: 79 e8 CALF $09E8 ; send byte to TX +// 0c08: 0b MOV A,C +// 0c09: 79 e8 CALF $09E8 ; send byte to TX +// 0c0b: b8 RET +// +// ; +// 0c0c: 7d 5b CALF $0D5B ; set both DP on +// 0c0e: 55 ad 18 OFFIW $00AD,$18 +// 0c11: 15 ad 18 ORIW $00AD,$18 +// 0c14: 01 b7 LDAW $00B7 +// 0c16: 74 98 ad ORAW $00AD +// 0c19: 63 b7 STAW $00B7 +// 0c1b: 16 ff XRI A,$FF +// 0c1d: 74 88 8f ANAW $008F +// 0c20: 1a MOV B,A +// 0c21: 01 a7 LDAW $00A7 +// 0c23: 74 88 b7 ANAW $00B7 +// 0c26: 60 9a ORA A,B +// 0c28: b8 RET +// +// ; send switches 2 +// 0c29: 63 8f STAW $008F +// 0c2b: 16 ff XRI A,$FF +// 0c2d: 07 1f ANI A,$1F +// 0c2f: 1b MOV C,A +// 0c30: 69 fd MVI A,$FD ; module board +// 0c32: 79 e8 CALF $09E8 ; send byte to TX +// 0c34: 69 8f MVI A,$8F ; switches 2 +// 0c36: 79 e8 CALF $09E8 ; send byte to TX +// 0c38: 0b MOV A,C +// 0c39: 79 e8 CALF $09E8 ; send byte to TX +// 0c3b: b8 RET +// +// ; +// 0c3c: 59 b6 BIT 1,$00B6 +// 0c3e: c7 JR $0C46 +// +// ; +// 0c3f: 01 8e LDAW $008E +// 0c41: 63 b8 STAW $00B8 +// 0c43: 05 b6 fd ANIW $00B6,$FD +// 0c46: b8 RET +// +// ; manual mode? +// 0c47: 71 b7 00 MVIW $00B7,$00 +// 0c4a: 71 c5 04 MVIW $00C5,$04 ; middle bar of left digit +// 0c4d: 71 c6 04 MVIW $00C6,$04 ; middle bar of right digit +// 0c50: 01 c7 LDAW $00C7 +// 0c52: 59 b6 BIT 1,$00B6 +// +// ; +// 0c54: 01 b8 LDAW $00B8 +// 0c56: 63 8e STAW $008E +// 0c58: 7b f9 CALF $0BF9 ; send switches 1 to module board +// 0c5a: 01 a7 LDAW $00A7 +// 0c5c: 63 8f STAW $008F +// 0c5e: 7c 29 CALF $0C29 ; send switches 2 to module board +// 0c60: 6a 00 MVI B,$00 +// 0c62: 24 58 ff LXI DE,$FF58 +// 0c65: 34 6c ff LXI HL,$FF6C +// 0c68: 78 c3 CALF $08C3 +// 0c6a: b3 PUSH HL +// 0c6b: b2 PUSH DE +// 0c6c: 6c ff MVI D,$FF +// 0c6e: 34 30 00 LXI HL,$0030 +// 0c71: ad LDAX (HL+B) +// 0c72: 1d MOV E,A +// 0c73: 0b MOV A,C +// 0c74: 3a STAX (DE) +// 0c75: a2 POP DE +// 0c76: a3 POP HL +// 0c77: 2a LDAX (DE) +// 0c78: 3b STAX (HL) +// 0c79: 22 INX DE +// 0c7a: 32 INX HL +// 0c7b: 42 INR B +// 0c7c: 74 7a 10 EQI B,$10 +// 0c7f: e8 JR $0C68 +// 0c80: 34 90 ff LXI HL,$FF90 +// 0c83: 6a 0f MVI B,$0F +// 0c85: 2d LDAX (HL+) +// 0c86: 79 e8 CALF $09E8 ; send byte to TX +// 0c88: 52 DCR B +// 0c89: fb JR $0C85 +// 0c8a: 45 a8 30 ONIW $00A8,$30 ; MIDI mode 3? +// 0c8d: 78 e9 CALF $08E9 +// 0c8f: 15 b6 02 ORIW $00B6,$02 +// 0c92: b8 RET +// 0c93: 71 b7 00 MVIW $00B7,$00 +// 0c96: 05 c5 ef ANIW $00C5,$EF ; left digit mask dp off +// 0c99: 05 c6 ef ANIW $00C6,$EF ; right digit mask dp off +// 0c9c: b8 RET +// 0c9d: 6a 01 MVI B,$01 +// 0c9f: 48 01 SLRC A +// 0ca1: c2 JR $0CA4 +// 0ca2: 0a MOV A,B +// 0ca3: b8 RET +// 0ca4: 42 INR B +// 0ca5: f9 JR $0C9F +// 0ca6: b8 RET +// +// ; calculate address of patch data to send +// ; check first if we send test mode data +// 0ca7: 58 b6 BIT 0,$00B6 ; set to true if test mode +// 0ca9: c8 JR $0CB2 ; calculate address of program +// 0caa: 6e 0f MVI H,$0F ; upper byte of address +// 0cac: 07 f0 ANI A,$F0 ; mask off uppp nybble of address +// 0cae: 46 70 ADI A,$70 ; $F70 -> ? +// 0cb0: 1f MOV L,A ; A contains bank maybe? +// 0cb1: dd JR $0CCF ; return +// +// ; calculate address of program +// 0cb2: 01 bb LDAW $00BB ; current program +// 0cb4: 51 DCR A ; 0-based, so 0-7? +// 0cb5: 1b MOV C,A ; save in C +// 0cb6: 01 ba LDAW $00BA ; program? bank? +// 0cb8: 66 10 SUI A,$10 ; left digit? would now be 00-70 +// 0cba: 48 21 SLR A ; +// 0cbc: 60 9b ORA A,C ; 11-88 to $00-$3f +// 0cbe: 5e c8 BIT 6,$00C8 ; bank flag +// 0cc0: 17 40 ORI A,$40 ; or $40-$7f +// 0cc2: 44 00 02 LXI EA,$0200 ; address in RAM +// 0cc5: 19 MOV EAL,A ; program number into low byte +// 0cc6: 48 a4 DSLL EA ; +// 0cc8: 48 a4 DSLL EA +// 0cca: 48 a4 DSLL EA +// 0ccc: 48 a4 DSLL EA ; RAM is at $2000, 16 bytes per program +// 0cce: b7 DMOV HL,EA ; return address of patch in HL +// 0ccf: b8 RET +// +// ; send patch to voice board +// 0cd0: 69 fd MVI A,$FD ; voice +// 0cd2: 79 e8 CALF $09E8 ; send byte to TX +// 0cd4: 69 90 MVI A,$90 ; LFO rate, first half of sliders +// 0cd6: 79 e8 CALF $09E8 ; send byte to TX +// 0cd8: 0b MOV A,C +// 0cd9: 7c a7 CALF $0CA7 ; find address of patch +// 0cdb: 24 90 ff LXI DE,$FF90 ; +// 0cde: 7c f1 CALF $0CF1 ; send eight bytes and assemble switch register +// 0ce0: 0b MOV A,C ; switch register to A +// 0ce1: 63 8e STAW $008E ; save +// 0ce3: 7b f9 CALF $0BF9 ; send switches 1 to voice board +// 0ce5: 69 98 MVI A,$98 ; VCF LFO, second half of sliders +// 0ce7: 79 e8 CALF $09E8 ; send byte to TX +// 0ce9: 7c f1 CALF $0CF1 ; send next eight bytes +// 0ceb: 0b MOV A,C ; switch register to A +// 0cec: 63 8f STAW $008F ; save it +// 0cee: 7c 29 CALF $0C29 ; send switches 2 to voice board +// 0cf0: b8 RET +// +// ; send 8 bytes pointed to by HL +// 0cf1: 6a 07 MVI B,$07 ; eight bytes +// 0cf3: 6b 00 MVI C,$00 ; +// 0cf5: 2d LDAX (HL+) ; byte from address in patch data +// 0cf6: 48 2a CLC ; clear carry +// 0cf8: 57 80 OFFI A,$80 ; top bit set? +// 0cfa: 48 2b STC ; no, set carry +// 0cfc: 48 33 RLR C ; rotate C right, carry into top bit +// 0cfe: 07 7f ANI A,$7F ; mask top bit off +// 0d00: 3c STAX (DE+) ; store in buffer at DE, inc +// 0d01: 79 e8 CALF $09E8 ; send byte to TX +// 0d03: 52 DCR B ; count down +// 0d04: f0 JR $0CF5 ; back around +// 0d05: b8 RET +// +// ; +// 0d06: 0b MOV A,C +// 0d07: 63 b9 STAW $00B9 +// 0d09: 7c a7 CALF $0CA7 +// 0d0b: 24 90 ff LXI DE,$FF90 +// 0d0e: 01 8e LDAW $008E +// 0d10: 1b MOV C,A +// 0d11: 7d 25 CALF $0D25 +// 0d13: 01 8f LDAW $008F +// 0d15: 1b MOV C,A +// 0d16: 7d 25 CALF $0D25 +// 0d18: 15 b6 04 ORIW $00B6,$04 +// 0d1b: 7c 3c CALF $0C3C +// 0d1d: 01 b9 LDAW $00B9 +// 0d1f: 1b MOV C,A +// 0d20: 7c d0 CALF $0CD0 +// 0d22: 7c 93 CALF $0C93 +// 0d24: b8 RET +// +// ; copies from DE to HL, rotating bits right +// 0d25: 6a 07 MVI B,$07 +// 0d27: 2c LDAX (DE+) +// 0d28: 07 7f ANI A,$7F +// 0d2a: 48 03 SLRC C +// 0d2c: c2 JR $0D2F +// 0d2d: 17 80 ORI A,$80 +// 0d2f: 3d STAX (HL+) +// 0d30: 52 DCR B +// 0d31: f5 JR $0D27 +// 0d32: b8 RET +// +// ; save digit values +// 0d33: 01 c5 LDAW $00C5 ; left digit value +// 0d35: 63 c9 STAW $00C9 ; save in ffc9 +// 0d37: 01 c6 LDAW $00C6 ; right digit value +// 0d39: 63 ca STAW $00CA ; save in ffca +// 0d3b: b8 RET +// +// ; restore digit values +// 0d3c: 01 c9 LDAW $00C9 ; +// 0d3e: 63 c5 STAW $00C5 +// 0d40: 01 ca LDAW $00CA +// 0d42: 63 c6 STAW $00C6 +// 0d44: b8 RET +// +// ; digit lookup +// ; lookup table is 0 = _1234567890cEPR +// 0d45: 34 50 00 LXI HL,$0050 ; lookup table - 7 segment +// 0d48: 1b MOV C,A +// 0d49: 48 21 SLR A +// 0d4b: 48 21 SLR A +// 0d4d: 48 21 SLR A +// 0d4f: 48 21 SLR A +// 0d51: ac LDAX (HL+A) ; bit pattern for left digit +// 0d52: 63 c5 STAW $00C5 ; store +// 0d54: 0b MOV A,C ; restore +// 0d55: 07 0f ANI A,$0F ; right digit +// 0d57: ac LDAX (HL+A) ; lookup +// 0d58: 63 c6 STAW $00C6 ; store +// 0d5a: b8 RET +// +// ; set both DPs on +// 0d5b: 15 c5 10 ORIW $00C5,$10 +// 0d5e: 15 c6 10 ORIW $00C6,$10 +// 0d61: b8 RET +// +// ; +// 0d62: 07 38 ANI A,$38 +// 0d64: 5f c8 BIT 7,$00C8 +// 0d66: 17 04 ORI A,$04 +// 0d68: 63 d1 STAW $00D1 +// 0d6a: 64 05 ff MVI PF,$FF +// 0d6d: 4d c1 MOV PB,A +// 0d6f: 24 ff 1f LXI DE,$1FFF +// 0d72: 4a df MVIX DE,$DF ; IC9 "Manual" col +// 0d74: 7b 70 CALF $0B70 ; stop all notes? +// 0d76: 69 87 MVI A,$87 +// 0d78: 79 e8 CALF $09E8 ; send byte to TX +// 0d7a: 6a ff MVI B,$FF +// 0d7c: 48 2d MUL A +// 0d7e: 52 DCR B +// 0d7f: fc JR $0D7C +// 0d80: ba DI +// 0d81: 64 01 00 MVI PB,$00 +// 0d84: 64 05 c0 MVI PF,$C0 +// 0d87: 05 d1 3c ANIW $00D1,$3C +// 0d8a: 55 d1 20 OFFIW $00D1,$20 +// 0d8d: 4e 69 JRE $0DF8 +// 0d8f: 55 d1 10 OFFIW $00D1,$10 +// 0d92: 4e 6d JRE $0E01 +// 0d94: 45 d1 08 ONIW $00D1,$08 +// 0d97: 4e f7 JRE $0E90 +// 0d99: 64 85 bf MVI TMM,$BF ; disable and reset timer 0, reset timer 1 and set to /384 +// 0d9c: 48 42 SKIT FT1 +// 0d9e: 00 NOP +// 0d9f: 64 01 08 MVI PB,$08 +// 0da2: 44 00 24 LXI EA,$2400 +// 0da5: 5a d1 BIT 2,$00D1 +// 0da7: 44 00 28 LXI EA,$2800 +// 0daa: 34 00 20 LXI HL,$2000 +// 0dad: 5a d1 BIT 2,$00D1 +// 0daf: 34 00 24 LXI HL,$2400 +// 0db2: 24 c0 00 LXI DE,$00C0 +// 0db5: 15 d1 01 ORIW $00D1,$01 +// 0db8: 69 01 MVI A,$01 +// 0dba: 4d db MOV TM1,A ; set timer +// 0dbc: 64 8d 7f ANI TMM,$7F ; timer 1 count-up mode +// 0dbf: 7e b4 CALF $0EB4 +// 0dc1: 69 4a MVI A,$4A +// 0dc3: 1a MOV B,A +// 0dc4: 60 44 ADD D,A +// 0dc6: 7f 07 CALF $0F07 +// 0dc8: 7e f0 CALF $0EF0 +// 0dca: 69 55 MVI A,$55 +// 0dcc: 1a MOV B,A +// 0dcd: 60 44 ADD D,A +// 0dcf: 7f 07 CALF $0F07 +// 0dd1: 7e f0 CALF $0EF0 +// 0dd3: 7f 01 CALF $0F01 +// 0dd5: 2d LDAX (HL+) +// 0dd6: 1a MOV B,A +// 0dd7: 60 44 ADD D,A +// 0dd9: 7f 07 CALF $0F07 +// 0ddb: 7e f0 CALF $0EF0 +// 0ddd: 74 ff DEQ EA,HL +// 0ddf: f3 JR $0DD3 +// 0de0: 0c MOV A,D +// 0de1: 1a MOV B,A +// 0de2: 7f 07 CALF $0F07 +// 0de4: 6a aa MVI B,$AA +// 0de6: 7f 07 CALF $0F07 +// 0de8: 6a aa MVI B,$AA +// 0dea: 7f 07 CALF $0F07 +// 0dec: 5e d1 BIT 6,$00D1 +// 0dee: c4 JR $0DF3 +// 0def: 7e b4 CALF $0EB4 +// 0df1: 4e 9d JRE $0E90 +// 0df3: 15 d1 40 ORIW $00D1,$40 +// 0df6: 4f a1 JRE $0D99 +// 0df8: 64 4a 10 ONI PC,$10 +// 0dfb: 4e 9f JRE $0E9C +// 0dfd: 64 01 20 MVI PB,$20 +// 0e00: c3 JR $0E04 +// 0e01: 64 01 10 MVI PB,$10 +// 0e04: 5a d1 BIT 2,$00D1 +// 0e06: ca JR $0E11 +// 0e07: 64 11 40 XRI PB,$40 +// 0e0a: 34 00 20 LXI HL,$2000 +// 0e0d: 44 00 24 LXI EA,$2400 +// 0e10: c9 JR $0E1A +// 0e11: 64 11 80 XRI PB,$80 +// 0e14: 34 00 24 LXI HL,$2400 +// 0e17: 44 00 28 LXI EA,$2800 +// 0e1a: 64 85 b7 MVI TMM,$B7 ; reset timer 0 and set to internal /384, reset timer 1 and set to internal /384 +// 0e1d: 69 0d MVI A,$0D +// 0e1f: 4d da MOV TM0,A ; set timer 0 +// 0e21: 69 1e MVI A,$1E +// 0e23: 4d db MOV TM1,A ; set timer 1 +// 0e25: 15 d1 01 ORIW $00D1,$01 +// 0e28: 64 4a 20 ONI PC,$20 +// 0e2b: 05 d1 fe ANIW $00D1,$FE +// 0e2e: 48 41 SKIT FT0 +// 0e30: 00 NOP +// 0e31: 48 42 SKIT FT1 +// 0e33: 00 NOP +// 0e34: 6b ff MVI C,$FF +// 0e36: 64 8d 6f ANI TMM,$6F +// 0e39: 7f 38 CALF $0F38 +// 0e3b: 48 0a SK CY +// 0e3d: f6 JR $0E34 +// 0e3e: 7e f0 CALF $0EF0 +// 0e40: 53 DCR C +// 0e41: f7 JR $0E39 +// 0e42: 15 d1 02 ORIW $00D1,$02 +// 0e45: 14 00 80 LXI BC,$8000 +// 0e48: 7f 38 CALF $0F38 +// 0e4a: 48 1a SKN CY +// 0e4c: 4e 30 JRE $0E7E +// 0e4e: 6b 00 MVI C,$00 +// 0e50: 7f 27 CALF $0F27 +// 0e52: 77 4a EQI A,$4A +// 0e54: d3 JR $0E68 +// 0e55: 60 43 ADD C,A +// 0e57: 7f 18 CALF $0F18 +// 0e59: 77 55 EQI A,$55 +// 0e5b: cc JR $0E68 +// 0e5c: 60 43 ADD C,A +// 0e5e: 7f 18 CALF $0F18 +// 0e60: 60 43 ADD C,A +// 0e62: 45 d1 10 ONIW $00D1,$10 +// 0e65: c5 JR $0E6B +// 0e66: 70 fd EQAX (HL+) +// 0e68: 4e 22 JRE $0E8C +// 0e6a: c5 JR $0E70 +// 0e6b: 64 4a 10 ONI PC,$10 +// 0e6e: dd JR $0E8C +// 0e6f: 3d STAX (HL+) +// 0e70: 74 ff DEQ EA,HL +// 0e72: eb JR $0E5E +// 0e73: 7f 18 CALF $0F18 +// 0e75: 60 fb EQA A,C +// 0e77: d4 JR $0E8C +// 0e78: 7f 18 CALF $0F18 +// 0e7a: 77 aa EQI A,$AA +// 0e7c: cf JR $0E8C +// 0e7d: d2 JR $0E90 +// 0e7e: 5c d1 BIT 4,$00D1 +// 0e80: 7e fb CALF $0EFB +// 0e82: 7e f0 CALF $0EF0 +// 0e84: 13 DCX BC +// 0e85: 0b MOV A,C +// 0e86: 60 9a ORA A,B +// 0e88: 77 00 EQI A,$00 +// 0e8a: 4f bc JRE $0E48 +// 0e8c: 15 d1 80 ORIW $00D1,$80 +// 0e8f: c3 JR $0E93 +// 0e90: 05 d1 7f ANIW $00D1,$7F +// 0e93: 64 01 00 MVI PB,$00 +// 0e96: 64 85 bf MVI TMM,$BF +// 0e99: 5f d1 BIT 7,$00D1 +// 0e9b: d1 JR $0EAD +// 0e9c: 69 ce MVI A,$CE +// 0e9e: 5f d1 BIT 7,$00D1 +// 0ea0: 69 de MVI A,$DE +// 0ea2: 7d 45 CALF $0D45 ; digit lookup +// 0ea4: 04 ff ff LXI SP,$FFFF +// 0ea7: 64 80 08 MVI ANM,$08 +// 0eaa: 54 79 00 JMP $0079 ; appears to be real code! +// 0ead: 71 c5 04 MVIW $00C5,$04 ; left digit middle bar +// 0eb0: 71 c6 04 MVIW $00C6,$04 ; right digit middle bar +// 0eb3: f0 JR $0EA4 +// 0eb4: 6a 18 MVI B,$18 +// 0eb6: 6b ff MVI C,$FF +// 0eb8: 7e d5 CALF $0ED5 +// 0eba: 7e f0 CALF $0EF0 +// 0ebc: 53 DCR C +// 0ebd: fa JR $0EB8 +// 0ebe: 7f 01 CALF $0F01 +// 0ec0: 52 DCR B +// 0ec1: f4 JR $0EB6 +// 0ec2: b8 RET +// 0ec3: 0d MOV A,E +// 0ec4: 58 d1 BIT 0,$00D1 +// 0ec6: c8 JR $0ECF +// 0ec7: 16 c0 XRI A,$C0 +// 0ec9: 1d MOV E,A +// 0eca: 69 05 MVI A,$05 +// 0ecc: 7e e7 CALF $0EE7 +// 0ece: b8 RET +// 0ecf: 15 d1 01 ORIW $00D1,$01 +// 0ed2: 16 80 XRI A,$80 +// 0ed4: f4 JR $0EC9 +// 0ed5: 0d MOV A,E +// 0ed6: 58 d1 BIT 0,$00D1 +// 0ed8: cb JR $0EE4 +// 0ed9: 05 d1 fe ANIW $00D1,$FE +// 0edc: 16 80 XRI A,$80 ; top bit of PC, tape output +// 0ede: 1d MOV E,A +// 0edf: 69 14 MVI A,$14 +// 0ee1: 7e e7 CALF $0EE7 +// 0ee3: b8 RET +// +// ; top two bits of PC, tape output +// 0ee4: 16 c0 XRI A,$C0 +// 0ee6: f7 JR $0EDE +// +// ; +// 0ee7: 48 42 SKIT FT1 ; wait for timer 1 to match +// 0ee9: fd JR $0EE7 +// 0eea: 4d db MOV TM1,A ; load with new value +// 0eec: 0d MOV A,E +// 0eed: 4d c2 MOV PC,A ; value in A to port C (only output lines are MIDI select and tape) +// 0eef: b8 RET +// +// ; +// 0ef0: 5a d1 BIT 2,$00D1 +// 0ef2: c4 JR $0EF7 +// 0ef3: 64 11 40 XRI PB,$40 ; group A / Chorus I / segment B +// 0ef6: b8 RET +// 0ef7: 64 11 80 XRI PB,$80 ; group B / Chorus II / segment A +// 0efa: b8 RET +// 0efb: 64 4a 10 ONI PC,$10 +// 0efe: 4f 8c JRE $0E8C +// 0f00: b8 RET +// 0f01: 64 48 06 ONI PA,$06 ; poly I + poly II? +// 0f04: b8 RET +// 0f05: 4f 89 JRE $0E90 +// 0f07: 6b 07 MVI C,$07 +// 0f09: 7e c3 CALF $0EC3 +// 0f0b: 48 02 SLRC B +// 0f0d: c3 JR $0F11 +// 0f0e: 7e d5 CALF $0ED5 +// 0f10: c2 JR $0F13 +// 0f11: 7e c3 CALF $0EC3 +// 0f13: 53 DCR C +// 0f14: f6 JR $0F0B +// 0f15: 7e d5 CALF $0ED5 +// 0f17: b8 RET +// 0f18: 5a d1 BIT 2,$00D1 +// 0f1a: c4 JR $0F1F +// 0f1b: 64 11 40 XRI PB,$40 +// 0f1e: c3 JR $0F22 +// 0f1f: 64 11 80 XRI PB,$80 +// 0f22: 7f 38 CALF $0F38 +// 0f24: 48 1a SKN CY +// 0f26: ce JR $0F35 +// 0f27: 69 00 MVI A,$00 +// 0f29: 6a 07 MVI B,$07 +// 0f2b: 7f 38 CALF $0F38 +// 0f2d: 48 31 RLR A +// 0f2f: 52 DCR B +// 0f30: fa JR $0F2B +// 0f31: 7f 38 CALF $0F38 +// 0f33: 48 0a SK CY +// 0f35: 4f 55 JRE $0E8C +// 0f37: b8 RET +// 0f38: 7f 01 CALF $0F01 +// 0f3a: 58 d1 BIT 0,$00D1 +// 0f3c: cc JR $0F49 +// 0f3d: 05 d1 fe ANIW $00D1,$FE +// 0f40: 64 4a 20 ONI PC,$20 +// 0f43: d1 JR $0F55 +// 0f44: 48 62 SKNIT FT1 +// 0f46: 7f 64 CALF $0F64 +// 0f48: f7 JR $0F40 +// 0f49: 15 d1 01 ORIW $00D1,$01 +// 0f4c: 64 5a 20 OFFI PC,$20 +// 0f4f: c5 JR $0F55 +// 0f50: 48 62 SKNIT FT1 +// 0f52: 7f 64 CALF $0F64 +// 0f54: f7 JR $0F4C +// 0f55: 48 41 SKIT FT0 +// 0f57: c9 JR $0F61 +// 0f58: 48 2b STC +// 0f5a: 64 95 90 XRI TMM,$90 +// 0f5d: 64 95 90 XRI TMM,$90 +// 0f60: b8 RET +// 0f61: 48 2a CLC +// 0f63: f6 JR $0F5A +// 0f64: 55 d1 02 OFFIW $00D1,$02 +// 0f67: 4f 23 JRE $0E8C +// 0f69: 64 95 90 XRI TMM,$90 +// 0f6c: 64 95 90 XRI TMM,$90 +// 0f6f: 48 41 SKIT FT0 +// 0f71: 00 NOP +// 0f72: 6b ff MVI C,$FF +// 0f74: 5c d1 BIT 4,$00D1 +// 0f76: 7e fb CALF $0EFB +// 0f78: 7f 01 CALF $0F01 +// 0f7a: 7e f0 CALF $0EF0 +// 0f7c: b8 RET +// 0f7d: 00 NOP +// 0f7e: 00 NOP +// 0f7f: 00 NOP +// +// ; test mode patches +// ; 0f80 40 80 00 00 00 ff 00 00 00 7f 40 00 80 00 00 00 +// ; 0f90 40 80 00 00 00 ff 00 00 00 7f 40 00 80 7f 00 7f +// ; 0fa0 40 80 00 00 00 b1 7f 00 00 7f 40 00 80 7f 00 00 +// +// ; and so on +// +// 0f80: 40 80 00 CALL $0080 +// 0f83: 00 NOP +// 0f84: 00 NOP +// 0f85: ff JR $0F85 +// 0f86: 00 NOP +// 0f87: 00 NOP +// 0f88: 00 NOP +// 0f89: 7f 40 CALF $0F40 +// 0f8b: 00 NOP +// 0f8c: 80 CALT ($0080) +// 0f8d: 00 NOP +// 0f8e: 00 NOP +// 0f8f: 00 NOP +// 0f90: 40 80 00 CALL $0080 +// 0f93: 00 NOP +// 0f94: 00 NOP +// 0f95: ff JR $0F95 +// 0f96: 00 NOP +// 0f97: 00 NOP +// 0f98: 00 NOP +// 0f99: 7f 40 CALF $0F40 +// 0f9b: 00 NOP +// 0f9c: 80 CALT ($0080) +// 0f9d: 7f 00 CALF $0F00 +// 0f9f: 7f 40 CALF $0F40 +// 0fa1: 80 CALT ($0080) +// 0fa2: 00 NOP +// 0fa3: 00 NOP +// 0fa4: 00 NOP +// 0fa5: b1 PUSH BC +// 0fa6: 7f 00 CALF $0F00 +// 0fa8: 00 NOP +// 0fa9: 7f 40 CALF $0F40 +// 0fab: 00 NOP +// 0fac: 80 CALT ($0080) +// 0fad: 7f 00 CALF $0F00 +// 0faf: 00 NOP +// 0fb0: 40 80 00 CALL $0080 +// 0fb3: 00 NOP +// 0fb4: 80 CALT ($0080) +// 0fb5: ff JR $0FB5 +// 0fb6: 00 NOP +// 0fb7: 00 NOP +// 0fb8: 00 NOP +// 0fb9: 7f 40 CALF $0F40 +// 0fbb: 00 NOP +// 0fbc: 80 CALT ($0080) +// 0fbd: 7f 00 CALF $0F00 +// 0fbf: 00 NOP +// 0fc0: 40 80 00 CALL $0080 +// 0fc3: 80 CALT ($0080) +// 0fc4: 00 NOP +// 0fc5: ff JR $0FC5 +// 0fc6: 00 NOP +// 0fc7: 00 NOP +// 0fc8: 80 CALT ($0080) +// 0fc9: 7f 40 CALF $0F40 +// 0fcb: 00 NOP +// 0fcc: 80 CALT ($0080) +// 0fcd: 7f 00 CALF $0F00 +// 0fcf: 00 NOP +// 0fd0: 40 80 00 CALL $0080 +// 0fd3: 00 NOP +// 0fd4: 7f ff CALF $0FFF +// 0fd6: 00 NOP +// 0fd7: 00 NOP +// 0fd8: 00 NOP +// 0fd9: 7f 40 CALF $0F40 +// 0fdb: 00 NOP +// 0fdc: 80 CALT ($0080) +// 0fdd: 7f 00 CALF $0F00 +// 0fdf: 00 NOP +// 0fe0: 40 80 00 CALL $0080 +// 0fe3: 00 NOP +// 0fe4: 00 NOP +// 0fe5: ff JR $0FE5 +// 0fe6: 7f 00 CALF $0F00 +// 0fe8: 00 NOP +// 0fe9: 7f 40 CALF $0F40 +// 0feb: 00 NOP +// 0fec: 80 CALT ($0080) +// 0fed: 7f 00 CALF $0F00 +// 0fef: 00 NOP +// 0ff0: 40 80 00 CALL $0080 +// 0ff3: 80 CALT ($0080) +// 0ff4: 00 NOP +// 0ff5: ff JR $0FF5 +// 0ff6: 00 NOP +// 0ff7: 00 NOP +// 0ff8: 00 NOP +// 0ff9: 7f 40 CALF $0F40 +// 0ffb: 00 NOP +// 0ffc: 8a CALT ($0094) +// 0ffd: 00 NOP +// 0ffe: 0a MOV A,B +// 0fff: 00 NOP diff --git a/plugin/chassis.cpp b/plugin/chassis.cpp index 7112499..44bb4ad 100644 --- a/plugin/chassis.cpp +++ b/plugin/chassis.cpp @@ -55,6 +55,10 @@ void Chassis::activate() { for (uint8_t i = 0; i < 104; i++) { s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate; } + + ic1.ram[0xc6] = 0x42; + ic1.ram[0xb6] = 0; + ic1.resetVoices(); } void Chassis::deactivate() { diff --git a/plugin/cpuboard.cpp b/plugin/cpuboard.cpp deleted file mode 100644 index c6e355a..0000000 --- a/plugin/cpuboard.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "cpuboard.hpp" - -#include - -void Assigner::resetVoices() { - // 0b81 - for (uint16_t i = 0x80; i < 0x85; i++) { - ram[i + 8] = 0x80; // 0b81 loop - ram[i] = i + 0x88; // 0b8b loop - } - ram[0x86] = 0x88; // 0b96 -} - -void Assigner::clearNotes() { - // 0b9e - // loop over ff30 to ff3d zeroing out the "played notes" bits - for (uint16_t hl = 0x30; hl < 0x3d; hl++) { - ram[hl] = 0; - } -} - -void Assigner::voiceOn() { - // 01e0 which we fall through to after scanning the key matrix - - b = 0x0d; // bytes in scan table - hl = 0x3d; // ff3d, top of "enabled" notes - de = 0x57; // the key matrix is stored here - ram[0xd0] = 0; // unsure - -h01eb: - a = ram[hl + 0x10]; // read MIDI bitmap - // 01ed - // LTI B, $03; LTI B, $0B - // I believe this selects only the key bitmap addresses from DE - // 1f3 jr 01f7 - // 1f4 orax (DE) ; or in the bitmap at (DE) (keys pressed) - - // 1f7 - c = a; - a ^= ram[hl]; // XRAX (HL), compare with already pressed - - if (a == 0) { - // 01fa SK Z - } else { - // 01fc CALF $0A18; - printf("new note change detected\n"); - } - - a = c; // restore A - ram[hl] = a; // store bitfield at $ff30 - - hl--; - if (b > 0) { - b--; - goto h01eb; - } - - // 0203 - if (ram[0xd0] != 0xff) { - // skip - } else { - // 0206 CALF $0b9e - clearNotes(); - } -} - -void Assigner::noteOn() { - // called from serial interrupt handler - // sets or clears a bit in the "MIDI Key pressed" bitfield - - // note that RAM addresses normally set to 0xff40 are reduced to 0x0040 - - // 06ca - a = ram[0x3e]; // first byte is note value - c = 0x40; // fake velocity - - // bring note into range - // 06cc - if (a <= 0x17) a += 12; - // 06d0 - if (a >= 0x6d) a -= 12; - - // 06d4 subtract transpose from ffbe - - // 06d7 mov b,a; slr b; slr b; slr b - b = a >> 3; - a &= 0x07; - - // 06e0 note on? - if (ram[0x4e] != 0x90) goto h06f9; // no, skip to note off - // 06e4 velocity zero? - if (c == 0) goto h06f9; // yes, skip to note off - - // otherwise handle note on - // 06e8 lxi hl,$0008; ldax (a+hl) for table of bits - a = 1 << a; - c = a; - hl = 0x0040; // note bit flags - a = ram[hl + b]; // byte pointed to by upper part - a |= c; // or in the bit value - ram[hl + b] = a; // save it in RAM - - // 06f4 mviw $003f, $01 expect two bytes; jre $064c return from interrupt - return; - -h06f9: // note off - - a = 0xff ^ (1 << a); - c = a; - hl = 0x0040; // note bit flags - a = ram[hl + b]; // byte pointed to by upper part - a &= c; // mask off the bit - ram[hl + b] = a; // save it in RAM - - return; -} \ No newline at end of file diff --git a/plugin/cpuboard.hpp b/plugin/cpuboard.hpp index 0a6d6dc..51c16ba 100644 --- a/plugin/cpuboard.hpp +++ b/plugin/cpuboard.hpp @@ -3,14 +3,15 @@ #include class Assigner { - public: + public: uint8_t ram[256]; - uint16_t a = 0, b=0, c=0; + uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0; uint32_t bc, de, hl, ea = 0; void noteOn(); void voiceOn(); void resetVoices(); - void clearNotes(); + // void clearNotes(); + //void assignNote(); }; \ No newline at end of file diff --git a/plugin/cpuboard.off b/plugin/cpuboard.off new file mode 100644 index 0000000..63fa868 --- /dev/null +++ b/plugin/cpuboard.off @@ -0,0 +1,414 @@ +#include "cpuboard.hpp" + +#include + +void Assigner::resetVoices() { + // 0b81 + for (uint16_t i = 0x80; i < 0x85; i++) { + ram[i + 8] = 0x80; // 0b81 loop + ram[i] = i + 0x88; // 0b8b loop + } + ram[0x86] = 0x88; // 0b96 +} + +void Assigner::clearNotes() { + // 0b9e + // loop over ff30 to ff3d zeroing out the "played notes" bits + for (uint16_t hl = 0x30; hl < 0x3d; hl++) { + ram[hl] = 0; + } +} + +void Assigner::voiceOn() { + // 01e0 which we fall through to after scanning the key matrix + b = 0x0d; // bytes in scan table + hl = 0x3d; // ff3d, top of "enabled" notes + de = 0x57; // the key matrix is stored here + ram[0xd0] = 0; // unsure + +h01eb: + a = ram[hl + 0x10]; // read MIDI bitmap + // 01ed + // LTI B, $03; LTI B, $0B + // I believe this selects only the key bitmap addresses from DE + // 1f3 jr 01f7 + // 1f4 orax (DE) ; or in the bitmap at (DE) (keys pressed) + + // 1f7 + c = a; + a ^= ram[hl]; // XRAX (HL), compare with already pressed + + if (a == 0) { + // 01fa SK Z + } else { + // 01fc CALF $0A18; + assignNote(); + } + + a = c; // restore A + ram[hl] = a; // store bitfield at $ff30 + + hl--; + if (b > 0) { + b--; + goto h01eb; + } + + // 0203 + if (ram[0xd0] != 0xff) { + // skip + } else { + // 0206 CALF $0b9e + clearNotes(); + } +} + +void Assigner::f_0b30() { + // identify routine here + + // 0b30 + uint32_t toshl = hl, tosbc = (b << 8) | c; // used to save hl and bc + + c = a; + + b = 5; // six voices + + hl = 0x88; // table that's set to 0x80 at startup +h0b38: + a = ram[hl]; + if (a & 0x80) { + // skip + } else { + goto h0b42; + } + +// 0b3c +h0b3c: + hl++; + if (b > 0) { + b--; + goto h0b38; + } + hl = toshl; + bc = tosbc; + b = tosbc >> 8; + c = tosbc & 0xff; + return; + +h0b42: + if (a == c) { + goto h0b46; + } + goto h0b3c; +h0b46: + a |= 0x80; + ram[hl] = a; + + a = hl & 0xff; + a -= 8; + + printf("in 0x0b30 send %02x to module board\n", a); + hl = toshl; + bc = tosbc; + b = tosbc >> 8; + c = tosbc & 0xff; + return; +} + +void Assigner::f_0a88() { +h0a88: + printf("called 0a88, send to module?\n"); + + uint32_t tosbc = (b << 8) | c; + uint32_t toshl = hl; + + // 08a8 mvi h,$ff + hl = 0x00; // + c = a; + +h0a8d: + a = ram[0x86]; // note number + a++; + // 0a90 + if (a == 0x8e) { + // skip + } else { + goto h0a95; + } + a = 0x88; +h0a95: + ram[0x86] = a; + hl = a; // 0a97 mov l,a but H is ignored because we only consider the 256 bytes of RAM + a = ram[hl]; + if ((a & 0x80) == 0) { + // skip + } else { + goto h0a9e; + } + if (b > 0) { + b--; + goto h0a8d; + } + +h0a9e: // mvi a, $fd; calf $09e8 to select module board + + a = hl; // mov a, l + // calf $09e8 + + a = c; // aa5 mov a,c + ram[hl] = a; // aa6 stax(hl) + + // 0aa7 addw $00be, transpose + // 0aaa calf 09e8 send to tx + + printf("0a9e sending to module board %02x %02x\n", hl, c); + bc = tosbc; + b = bc >> 8; + c = bc & 0xff; + hl = toshl; + return; +} + +void Assigner::assignNote() { + uint32_t toshl, tosbc, temphl, tempbc; // used to save hl and bc + // 0a18 + + // printf("in assignNote, a=%02x b=%02x\n", a, b); + + eal = a; // note bitmap + a = b; // bitmap column + + // 0a1a calf $0a0d but inline + + // a0d + a >>= 3; // 0a0d sll a; sll a; sll a; + eah = a; // 0a13 mov EAH,a + a = c; // mov a,c + ram[0xc3] = a; // staw $ffc3; + // a17 ret + + // 0a1c + toshl = hl; + tosbc = (b << 8) | c; + + b = 7; + a = eal; + c = a; + + // hl = 0x08; // lookup table + + // 0a25 sllc c + // printf("h0a25 %02x %02x\n", b, c); + +h0a25: + c <<= 1; + if (c & 0x100) { + // it carried, skip + } else { + c &= 0xff; + goto h0a60; + } + c &= 0xff; + + // 0a29 + // a = ram[hl + b]; // byte containing this column bitfield + + a = 1 << b; + + // printf("column bitfield %02x %02x\n", b, a); + + if (a == ram[0xc3]) { // 0a2a onaw $ffc3 + // skip + } else { + goto h0a52; + } + + // 0a2f + a = eah; // upper bits of note + a |= b; // 0a30 ora a,b + + // 0a32 bit 1,$ffc8; jr 0a4f + if ((ram[0xc8] & 0x02) == 0) goto h0a4f; // poly1? + + // 0a35 bit 2,$ffc8; jr 0a3f + if ((ram[0xc8] & 0x04) == 0) goto h0a3f; // poly2? + + // 0a38 bit 0,$ffb6; jr 0a42 + if ((ram[0xb6] & 0x01) == 0) goto h0a42; // test mode? + + // 0a3b calf 0a88 + // 0a3d jre 0a60; + +h0a3b: + f_0a88(); +h0a3d: + + goto h0a60; + +h0a3f: + printf("at h0a3f\n"); + // 0a3f bit 0,$ffb6; jr 0a42 + if ((ram[0xb6] & 0x01) == 0) goto h0a4c; + // 0a42 eqiw $ffd0,00; jr 0a60 + +h0a42: + printf("h0a42"); + if (ram[0xd0] == 0) { + // skip + } else { + goto h0a60; // loop around + } + // 0a46 calf 0b55 voice on unison + printf("voice on Unison for %02x\n", eal); + ram[0xd0] = 0x80; + goto h0a60; + +// 0a4c calf 0aaf +h0a4c: + printf("calling 0aaf\n"); + goto h0a60; + +h0a4f: + printf("h0a4f\n"); + printf("calling 0a76\n"); + goto h0a60; + +h0a52: + a = eah; + a |= b; + + // 0a55 bit 1,$ffc8; jr 0a5e + if ((ram[0xc8] & 0x02) == 0) goto h0a5e; + + // 0a58 bit 2,$ffc8; jr 0a66 + if ((ram[0xc8] & 0x04) == 0) goto h0a66; + + // 0a5b bit 0,$ffb6; jr 0a69 something to do with test mode + if ((ram[0xb6] & 0x01) == 0) goto h0a69; + + // 0a5e calf 0b30 + +h0a5e: + printf("called 0x0b30\n"); + f_0b30(); + +h0a60: + // 0a60 dcr b; jre 0a25 + if (b > 0) { + b--; + goto h0a25; + } + + bc = tosbc; + b = tosbc >> 8; + c = tosbc & 0xff; + hl = toshl; + return; + +h0a66: + printf("called 0a66\n"); + goto h0a60; + +h0a69: + printf("called 0a69"); + goto h0a69; + +h0a76: + tempbc = (b << 8) | c; + temphl = hl; + + c = a; + b = 5; + + hl = 0x88; +h0a7e: + a = ram[hl]; + if ((a & 0x80) == 0) { + // skip + } else { + goto h0a9e; + } + hl++; + if (b > 0) { + b--; + goto h0a7e; + } + + hl = toshl; + b = tosbc >> 8; + c = tosbc & 0xff; + + goto h0a60; + +h0aaf: + printf("got to 0aaf\n"); + return; +h0a9e: // mvi a, $fd; calf $09e8 to select module board + + a = hl; // mov a, l + // calf $09e8 + + a = c; // aa5 mov a,c + ram[hl] = a; // aa6 stax(hl) + + // 0aa7 addw $00be, transpose + // 0aaa calf 09e8 send to tx + + printf("from a7e 0a9e sending to module board %02x %02x\n", hl, c); + bc = tosbc; + b = bc >> 8; + c = bc & 0xff; + hl = toshl; + return; +} + +void Assigner::noteOn() { + // called from serial interrupt handler + // sets or clears a bit in the "MIDI Key pressed" bitfield + + // note that RAM addresses normally set to 0xff40 are reduced to 0x0040 + + // 06ca + a = ram[0x3e]; // first byte is note value + c = 0x40; // fake velocity + + // bring note into range + // 06cc + if (a <= 0x17) a += 12; + // 06d0 + if (a >= 0x6d) a -= 12; + + // 06d4 subtract transpose from ffbe + + // 06d7 mov b,a; slr b; slr b; slr b + b = a >> 3; + a &= 0x07; + + // 06e0 note on? + if (ram[0x4e] != 0x90) goto h06f9; // no, skip to note off + // 06e4 velocity zero? + if (c == 0) goto h06f9; // yes, skip to note off + + // otherwise handle note on + // 06e8 lxi hl,$0008; ldax (a+hl) for table of bits + a = 1 << a; + c = a; + hl = 0x0040; // note bit flags + a = ram[hl + b]; // byte pointed to by upper part + a |= c; // or in the bit value + ram[hl + b] = a; // save it in RAM + + // 06f4 mviw $003f, $01 expect two bytes; jre $064c return from interrupt + return; + +h06f9: // note off + + a = 0xff ^ (1 << a); + c = a; + hl = 0x0040; // note bit flags + a = ram[hl + b]; // byte pointed to by upper part + a &= c; // mask off the bit + ram[hl + b] = a; // save it in RAM + + return; +} \ No newline at end of file