revised disassembly file

This commit is contained in:
Gordon JC Pearce 2024-09-17 22:25:28 +01:00
parent 3e16f5314f
commit 77acf5e800
7 changed files with 6471 additions and 465 deletions

View File

@ -10,9 +10,9 @@
NAME = chassis NAME = chassis
FILES_DSP = \ FILES_DSP = \
ic1.cpp \
parameters.cpp \ parameters.cpp \
voicecpu.cpp \ voicecpu.cpp \
assigner.cpp \
chassis.cpp \ chassis.cpp \
voice.cpp voice.cpp

View File

@ -1,12 +1,12 @@
#include <cstdio> #include <cstdio>
#include "cpuboard.hpp"
// startup needs to clear RAM etc // startup needs to clear RAM etc
// 0xffbe = 0x0c; transpose = 12; // 0xffbe = 0x0c; transpose = 12;
// Disassembly of assigner.bin, 8192 bytes [0x0 to 0x1fff] // Disassembly of assigner.bin, 8192 bytes [0x0 to 0x1fff]
// ; start // ; start
// 0000: 4e 9a JRE $009C // 0000: 4e 9a JRE $009C
// 0002: 00 NOP // 0002: 00 NOP
// 0003: 00 NOP // 0003: 00 NOP
// //
@ -17,21 +17,9 @@
// 0007: 00 NOP // 0007: 00 NOP
// //
// ; bit patterns used for Note On // ; bit patterns used for Note On
// ; ORed with a flag byte for each byte of key flags // 0008: 01 02 04 08 10 20 40 80
// 0008: 01 02 LDAW $0002
// 000a: 04 08 10 LXI SP,$1008
// 000d: 20 40 INRW $0040
// 000f: 80 CALT ($0080)
// ; bit patterns used for Note Off // ; bit patterns used for Note Off
// ; ANDed with a flag byte to mask it off // 0010: fe fd fb f7 ef df bf 7f
// 0010: fe JR $000F
// 0011: fd JR $000F
// 0012: fb JR $000E
// 0013: f7 JR $000B
// 0014: ef JR $0004
// 0015: df JR $0035
// 0016: bf 7f STAX (HL+$7F)
// ; timer/event // ; timer/event
// 0018: 00 NOP // 0018: 00 NOP
@ -1054,6 +1042,10 @@
// ; called with status in $ff4e, value in $ff3e and velocity in C // ; called with status in $ff4e, value in $ff3e and velocity in C
void Assigner::noteOn(uint8_t c) { void Assigner::noteOn(uint8_t c) {
// this routine is called with the status byte in RAM at
// 0xff4e, the MIDI note at 0xff3e, and the Transpose value
// at 0xffbe
// 06ca: 01 3e LDAW $003E ; first byte // 06ca: 01 3e LDAW $003E ; first byte
a = ram[0x3e]; a = ram[0x3e];
h06cc: h06cc:
@ -1157,7 +1149,8 @@ h070a:
a -= 12; // semitones a -= 12; // semitones
goto h06d0; goto h06d0;
// ; store first value // called from $06b3
// stores the first byte after the status byte
// 070e: 63 3e STAW $003E // 070e: 63 3e STAW $003E
// 0710: 4f 3a JRE $064C ; return from interrupt // 0710: 4f 3a JRE $064C ; return from interrupt
// //

View File

@ -18,7 +18,7 @@
#include "chassis.hpp" #include "chassis.hpp"
#include "cpuboard.hpp" #include "ic1.hpp"
#include "patches.hpp" #include "patches.hpp"
Assigner ic1; Assigner ic1;
@ -56,9 +56,9 @@ void Chassis::activate() {
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[0xc6] = 0x42;
ic1.ram[0xb6] = 0; //ic1.ram[0xb6] = 0;
ic1.resetVoices(); //ic1.resetVoices();
} }
void Chassis::deactivate() { void Chassis::deactivate() {
@ -69,9 +69,9 @@ void Chassis::deactivate() {
void Chassis::noteOn(uint8_t note) { void Chassis::noteOn(uint8_t note) {
uint32_t i; uint32_t i;
ic1.ram[0x4e] = 0x90; //ic1.ram[0x4e] = 0x90;
ic1.ram[0x3e] = note; //ic1.ram[0x3e] = note;
ic1.noteOn(0x40); // ic1.noteOn(0x40);
#ifdef D_MIDIBITMAP #ifdef D_MIDIBITMAP
printf("note on -> "); printf("note on -> ");
@ -100,9 +100,9 @@ void Chassis::noteOn(uint8_t note) {
} }
void Chassis::noteOff(uint8_t note) { void Chassis::noteOff(uint8_t note) {
ic1.ram[0x4e] = 0x90; //ic1.ram[0x4e] = 0x90;
ic1.ram[0x3e] = note; //ic1.ram[0x3e] = note;
ic1.noteOn(0); //ic1.noteOn(0);
#ifdef D_MIDIBITMAP #ifdef D_MIDIBITMAP
printf("note off -> "); printf("note off -> ");

View File

@ -1,24 +0,0 @@
#pragma once
#include <cstdint>
#define D_MIDIBITMAP
class Assigner {
public:
uint8_t ram[256];
uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0;
uint32_t bc, de, hl, ea = 0;
void noteOn(uint8_t c);
void voiceOn();
void resetVoices();
// void clearNotes();
// void assignNote();
private:
uint8_t bitMask[24] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
};

View File

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

6407
plugin/ic1.cpp Normal file

File diff suppressed because it is too large Load Diff

44
plugin/ic1.hpp Normal file
View File

@ -0,0 +1,44 @@
/*
Chassis polysynth framework
Copyright 2024 Gordon JC Pearce <gordonjcp@gjcp.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <cstdint>
class Assigner {
public:
void noteOn(uint8_t c);
private:
// 256 bytes of RAM from $ff00 to $ffff
uint8_t ram[256];
// bitmask data is at $0008 and $0010
// eight padding bytes at the start
uint8_t bitMask[24] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0;
uint32_t bc, de, hl, ea = 0;
};