renamed the digital part

This commit is contained in:
Gordon JC Pearce 2024-09-09 20:58:14 +01:00
parent 5db88ca4ea
commit ca65162e3f
3 changed files with 137 additions and 140 deletions

View File

@ -11,7 +11,7 @@ NAME = chassis
FILES_DSP = \ FILES_DSP = \
parameters.cpp \ parameters.cpp \
digital.cpp \ voicecpu.cpp \
chassis.cpp \ chassis.cpp \
voice.cpp voice.cpp

View File

@ -18,7 +18,12 @@
// contains the emulation of the digital bits // contains the emulation of the digital bits
#include "digital.hpp" // what's with the crazy private variables and all the gotos with crazy labels?
// this code emulates the uPD7811 code directly (probably inefficiently)
// to allow for documenting what the variables actually do
// they're really bitfields holding a bit for each voice
#include "voicecpu.hpp"
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
@ -31,6 +36,136 @@ bool Voice::isFree() {
return ff10 == false; return ff10 == false;
} }
void Synth::lfoDelay() {
// compute LFO delay
uint16_t a, bc, d, ea, tos;
// 030d: 45 11 3f ONIW $0011,$3F ; are any notes enabled
// 0310: 4e 59 JRE $036B ; no, just run LFO
if (!keyon /* ff11 */) goto h036b; // skip ahead if no notes are pressed
// 0312
if (!(ff1e & 0x08)) goto h0323; // a note is running, don't reset
// 0315 no note is running, reset it all
bc = 0;
ff56 = 0; // delay envelope
ff5a = 0; // holdoff timer
ff1e &= 0xf1; // mask bits in flag byte
h0323:
if (!(ff1e & 0x02)) goto h0370; // compute delay envelope
if (!(ff1e & 0x04)) goto h0388; // compute holdoff timer
// 032b
bc |= 0xff00; // initial scaling value?
h032d:
tos = bc; // push bc
// 032e
a = lfoDepthTable[patchRam.vcoLfo];
// MUL B; MOV A, EAH
a = (a * (bc >> 8)) >> 8;
// 0333 ADDNCW $0064; MVI A, $FF
a += ff64;
if (a > 0xff) a = 0xff;
// 0338 sets up HL to store computed pitch LFO output
// 33b
bc = ff4d; // current LFO output
// 033f
ea = (bc & 0xff) * a; // MUL C
d = a; // MOV D,A
a = (ea >> 8); // MOV A,EAH
bc &= 0xff00;
bc |= a; // MOV C,A
a = d; // MOV A,D
// 0345
ea = (bc >> 8) * a; // MUL B
ea += (bc & 0xff); // EADD EA, C
// 0349
ea >>= 3; // divide by eight
// 034f
ff51 = ea; // save scaled pitch LFO
bc = tos; // pop BC, contains scaling amount
a = patchRam.vcfLfo << 1; // amount is doubled and stored at ff48
// 0354
ea = (bc >> 8) * a; // MUL B
a = ea >> 8; // MOV A, EAH
bc = ff4d; // current LFO output
// 035b
ea = (bc & 0xff) * a; // MUL C
d = a; // MOV D,A
a = ea >> 8; // MOV A, EAH
bc &= 0xff00;
bc |= a; // MOV C,A
a = d; // MOV A,D
ea = (bc >> 8) * a; // MUL B
ea += (bc & 0xff); // EADD EA,C
ea >>= 1; // DSLR A
ff53 = ea; // save scaled VCF LFO
goto h03a1;
h036b:
ff1e |= 0x08; // set LFO flag
goto h0323;
h0370: // calculate holdoff time
// printf("0370 ");
ea = ff56; // holdoff time
bc = attackTable[patchRam.lfoDelay]; // stored at ff58
// 0379
ea += bc; // DADD EA,BC
ff56 = ea; // STEAX (DE) which still holds ff56 from 0x370
a = ea >> 8; // MOV A, EAH
if (a & 0xc0) goto h0385; // OFFI A, $C0
bc &= 0xff; // MOV B, 0
goto h032d;
h0385:
ff1e |= 0x02; // stop predelay flag
h0388:
// printf("0388 ");
ea = ff5a; // envelope speed
// 038d
bc = lfoDelayTable[patchRam.lfoDelay >> 4]; // delay setting divided by 8 and saved at ff6c
// printf("---------------------------------------- %04x %04x\n", ea, bc);
// 0391 DADDNC EA, BC
if ((ea + bc) > 0xffff) goto h039a;
ea += bc;
// 394
ff5a = ea; // STEAX (HL) hl still contains ff5a
bc |= (ea & 0xff00); // MOV A, EAH; MOV B, A
goto h032d;
h039a:
ff1e |= 0x04;
bc |= 0xff; // MVI B, $ff
goto h032d;
h03a1:
// printf("LFO=%04x VCF=%04x flags=%02x holdoff=%04x envelope=%04x\n", ff51, ff53, ff1e, ff56, ff5a);
return;
}
void Voice::calcPitch(Synth &s) { void Voice::calcPitch(Synth &s) {
uint32_t bc, ea, a; uint32_t bc, ea, a;
@ -145,11 +280,6 @@ h04d5:
} }
void Voice::on(uint32_t key, bool reset = 0) { void Voice::on(uint32_t key, bool reset = 0) {
// what's with the crazy private variables and all the gotos with crazy labels?
// this code emulates the 78C11 code directly (probably inefficiently)
// to allow for documenting what the variables actually do
// they're really bitfields holding a bit for each voice
// this current implementation doesn't reset the voice // this current implementation doesn't reset the voice
(void)reset; (void)reset;
@ -248,139 +378,6 @@ h0590:
// printf("%04x %d %d %d %d %d \n", ea, ff07, ff08, ff10, ff11, ff33); // printf("%04x %d %d %d %d %d \n", ea, ff07, ff08, ff10, ff11, ff33);
} }
void Synth::lfoDelay() {
// compute LFO delay
uint16_t a, bc, d, ea, tos;
// 030d
if (!keyon /* ff11 */) goto h036b; // skip ahead if no notes are pressed
// 0312
if (!(ff1e & 0x08)) goto h0323; // a note is running, don't reset
// 0315 no note is running, reset it all
bc = 0;
ff56 = 0; // delay envelope
ff5a = 0; // holdoff timer
ff1e &= 0xf1; // mask bits in flag byte
h0323:
if (!(ff1e & 0x02)) goto h0370; // compute delay envelope
if (!(ff1e & 0x04)) goto h0388; // compute holdoff timer
// 032b
bc |= 0xff00; // initial scaling value?
// printf("0323 ");
h032d:
tos = bc; // push bc
// 032e
a = lfoDepthTable[patchRam.vcoLfo];
// MUL B; MOV A, EAH
a = (a * (bc >> 8)) >> 8;
// 0333 ADDNCW $0064; MVI A, $FF
a += ff64;
if (a > 0xff) a = 0xff;
// 0338 sets up HL to store computed pitch LFO output
// 33b
bc = ff4d; // current LFO output
// printf("-----------------------%02x %04x\n", a, bc);
// 033f
ea = (bc & 0xff) * a; // MUL C
d = a; // MOV D,A
a = (ea >> 8); // MOV A,EAH
bc &= 0xff00;
bc |= a; // MOV C,A
a = d; // MOV A,D
// 0345
ea = (bc >> 8) * a; // MUL B
ea += (bc & 0xff); // EADD EA, C
// 0349
ea >>= 3; // divide by eight
// 034f
ff51 = ea; // save scaled pitch LFO
bc = tos; // pop BC, contains scaling amount
a = patchRam.vcfLfo << 1; // amount is doubled and stored at ff48
// 0354
ea = (bc >> 8) * a; // MUL B
a = ea >> 8; // MOV A, EAH
bc = ff4d; // current LFO output
// 035b
ea = (bc & 0xff) * a; // MUL C
d = a; // MOV D,A
a = ea >> 8; // MOV A, EAH
bc &= 0xff00;
bc |= a; // MOV C,A
a = d; // MOV A,D
ea = (bc >> 8) * a; // MUL B
ea += (bc & 0xff); // EADD EA,C
ea >>= 1; // DSLR A
ff53 = ea; // save scaled VCF LFO
goto h03a1;
h036b:
ff1e |= 0x08; // set LFO flag
goto h0323;
h0370: // calculate holdoff time
// printf("0370 ");
ea = ff56; // holdoff time
bc = attackTable[patchRam.lfoDelay]; // stored at ff58
// 0379
ea += bc; // DADD EA,BC
ff56 = ea; // STEAX (DE) which still holds ff56 from 0x370
a = ea >> 8; // MOV A, EAH
if (a & 0xc0) goto h0385; // OFFI A, $C0
bc &= 0xff; // MOV B, 0
goto h032d;
h0385:
ff1e |= 0x02; // stop predelay flag
h0388:
// printf("0388 ");
ea = ff5a; // envelope speed
// 038d
bc = lfoDelayTable[patchRam.lfoDelay >> 4]; // delay setting divided by 8 and saved at ff6c
// printf("---------------------------------------- %04x %04x\n", ea, bc);
// 0391 DADDNC EA, BC
if ((ea + bc) > 0xffff) goto h039a;
ea += bc;
// 394
ff5a = ea; // STEAX (HL) hl still contains ff5a
bc |= (ea & 0xff00); // MOV A, EAH; MOV B, A
goto h032d;
h039a:
ff1e |= 0x04;
bc |= 0xff; // MVI B, $ff
goto h032d;
h03a1:
// printf("LFO=%04x VCF=%04x flags=%02x holdoff=%04x envelope=%04x\n", ff51, ff53, ff1e, ff56, ff5a);
return;
}
void Synth::runLFO() { void Synth::runLFO() {
// compute a loop's worth of LFO // compute a loop's worth of LFO