try another way
This commit is contained in:
parent
36aa2de0db
commit
72fa8a2aab
@ -12,7 +12,7 @@ NAME = chassis
|
||||
FILES_DSP = \
|
||||
parameters.cpp \
|
||||
voicecpu.cpp \
|
||||
cpuboard.cpp \
|
||||
assigner.cpp \
|
||||
chassis.cpp \
|
||||
voice.cpp
|
||||
|
||||
|
2632
plugin/assigner.cpp
Normal file
2632
plugin/assigner.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -55,6 +55,10 @@ void Chassis::activate() {
|
||||
for (uint8_t i = 0; i < 104; i++) {
|
||||
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() {
|
||||
|
@ -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;
|
||||
}
|
@ -5,12 +5,13 @@
|
||||
class Assigner {
|
||||
public:
|
||||
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;
|
||||
|
||||
void noteOn();
|
||||
void voiceOn();
|
||||
void resetVoices();
|
||||
void clearNotes();
|
||||
// void clearNotes();
|
||||
//void assignNote();
|
||||
|
||||
};
|
414
plugin/cpuboard.off
Normal file
414
plugin/cpuboard.off
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user