renamed the digital part
This commit is contained in:
parent
5db88ca4ea
commit
ca65162e3f
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user