renamed the digital part
This commit is contained in:
parent
5db88ca4ea
commit
ca65162e3f
@ -11,7 +11,7 @@ NAME = chassis
|
||||
|
||||
FILES_DSP = \
|
||||
parameters.cpp \
|
||||
digital.cpp \
|
||||
voicecpu.cpp \
|
||||
chassis.cpp \
|
||||
voice.cpp
|
||||
|
||||
|
@ -18,7 +18,12 @@
|
||||
|
||||
// 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 <cstdio>
|
||||
@ -31,6 +36,136 @@ bool Voice::isFree() {
|
||||
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) {
|
||||
uint32_t bc, ea, a;
|
||||
|
||||
@ -145,11 +280,6 @@ h04d5:
|
||||
}
|
||||
|
||||
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
|
||||
(void)reset;
|
||||
|
||||
@ -248,139 +378,6 @@ h0590:
|
||||
// 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() {
|
||||
// compute a loop's worth of LFO
|
||||
|
Loading…
Reference in New Issue
Block a user