chassis/plugin/cpuboard.cpp
Gordon JC Pearce 36aa2de0db key detection
2024-09-17 10:21:02 +01:00

116 lines
2.7 KiB
C++

#include "cpuboard.hpp"
#include <cstdio>
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;
}