try another way

This commit is contained in:
Gordon JC Pearce 2024-09-17 20:28:50 +01:00
parent 36aa2de0db
commit 72fa8a2aab
6 changed files with 3055 additions and 120 deletions

View File

@ -12,7 +12,7 @@ NAME = chassis
FILES_DSP = \ FILES_DSP = \
parameters.cpp \ parameters.cpp \
voicecpu.cpp \ voicecpu.cpp \
cpuboard.cpp \ assigner.cpp \
chassis.cpp \ chassis.cpp \
voice.cpp voice.cpp

2632
plugin/assigner.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,10 @@ void Chassis::activate() {
for (uint8_t i = 0; i < 104; i++) { for (uint8_t i = 0; i < 104; i++) {
s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate; 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() { void Chassis::deactivate() {

View File

@ -1,116 +0,0 @@
#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;
}

View File

@ -5,12 +5,13 @@
class Assigner { class Assigner {
public: public:
uint8_t ram[256]; 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; uint32_t bc, de, hl, ea = 0;
void noteOn(); void noteOn();
void voiceOn(); void voiceOn();
void resetVoices(); void resetVoices();
void clearNotes(); // void clearNotes();
//void assignNote();
}; };

414
plugin/cpuboard.off Normal file
View File

@ -0,0 +1,414 @@
#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;
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;
}