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