diff --git a/plugin/chassis.cpp b/plugin/chassis.cpp index 3b9c4ae..7112499 100644 --- a/plugin/chassis.cpp +++ b/plugin/chassis.cpp @@ -69,11 +69,12 @@ void Chassis::noteOn(uint8_t note) { ic1.ram[0x3e] = note; ic1.noteOn(); +/* for (uint8_t i = 0x40; i < 0x4f; i++) { printf("%02x ", ic1.ram[i]); } printf("\n"); - +*/ s.keyon = true; for (i = 0; i < NUM_VOICES; i++) { vPtr++; @@ -97,11 +98,12 @@ void Chassis::noteOff(uint8_t note) { ic1.ram[0x3e] = note; ic1.noteOn(); +/* for (uint8_t i = 0x40; i < 0x4f; i++) { printf("%02x ", ic1.ram[i]); } printf("\n"); - +*/ s.keyon = false; for (uint32_t i = 0; i < NUM_VOICES; i++) { if (s.voice[i].note == note && !s.voice[i].isFree()) { @@ -126,6 +128,8 @@ void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) { } } lastEvent = i; + + ic1.voiceOn(); } void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) { diff --git a/plugin/cpuboard.cpp b/plugin/cpuboard.cpp index ccd712f..c6e355a 100644 --- a/plugin/cpuboard.cpp +++ b/plugin/cpuboard.cpp @@ -2,16 +2,77 @@ #include -void Assigner::noteOn() { +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 + c = 0x40; // fake velocity // bring note into range // 06cc @@ -34,23 +95,22 @@ void Assigner::noteOn() { // 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 - + 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 +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 + 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 f5746f7..0a6d6dc 100644 --- a/plugin/cpuboard.hpp +++ b/plugin/cpuboard.hpp @@ -9,5 +9,8 @@ class Assigner { uint32_t bc, de, hl, ea = 0; void noteOn(); + void voiceOn(); + void resetVoices(); + void clearNotes(); }; \ No newline at end of file