#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; }