Open Kyuchumimo opened 1 month ago
Registers here don't mean the emulated chip's register, but a specially assigned register to realize a library specific function, i.e. reading the library version.
https://github.com/toyoshim/SoundCortex/blob/master/src/SCC.c#L108 https://github.com/toyoshim/SoundCortex/blob/master/src/SCC.c#L108
Implementation is here.
I want to implement that the mixers of both sound chips are readable as they are registers / memory adresses that need to be bit modified. Is this the right way to do it?
PSG.c
bool PSGRead(uint8_t reg, uint8_t* value) {
switch (reg) {
case 0x07: // mixer
for (int i = 0; i < 3; ++i) {
*value |= PSGWork.synth[i].tone << i;
*value |= PSGWork.synth[i].noise << i + 3;
}
break;
case 0xfe: // minor version
*value = 1;
break;
case 0xff: // major version
*value = 1;
break;
default:
return false;
}
return true;
}
SCC.c
bool SCCRead(uint8_t reg, uint8_t* value) {
switch (reg) {
case 0xaf: // mixer
for (int i = 0; i < 5; ++i) {
*value |= SCCWork.synth[i].tone << i;
}
break;
case 0xfe: // minor version
*value = 1;
break;
case 0xff: // major version
*value = 1;
break;
default:
return false;
}
return true;
}
Do you really need to implement this in the SoundCortex side? I think your code should know what was written last time as your code was the single writer in your system? Adding a local cache in your code would work effectively as a query via i2c costs. Also I would like to keep the code for the SoundCortex as small as possible.
Not really.
I had already thought about the other way you mention, but since the original sound chips can be read, it seemed like a good idea to have it implemented.
I took the trouble to fill in all the remaining registers and memory addresses. I could make a pull request, but since you say that you are not interested in making the microcontroller readable due to memory space issues, it doesn't make much sense, but I'll leave it anyway in case someone else is interested in the future.
PSG.c
// PSG.c
bool PSGRead(uint8_t reg, uint8_t* value) {
switch (reg) {
case 0x00: // TP[7:0] for Ch.A
*value = PSGWork.channel[0].tp & 0xff;
break;
case 0x01: // TP[11:8] for Ch.A
*value = PSGWork.channel[0].tp >> 8;
break;
case 0x02: // TP[7:0] for Ch.B
*value = PSGWork.channel[1].tp & 0xff;
break;
case 0x03: // TP[11:8] for Ch.B
*value = PSGWork.channel[1].tp >> 8;
break;
case 0x04: // TP[7:0] for Ch.C
*value = PSGWork.channel[2].tp & 0xff;
break;
case 0x05: // TP[11:8] for Ch.C
*value = PSGWork.channel[2].tp >> 8;
break;
case 0x06: // NP[4:0]
*value = PSGWork.noise.np;
break;
case 0x07: // mixer
for (int i = 0; i < 3; ++i) {
*value |= PSGWork.synth[i].tone << i;
*value |= PSGWork.synth[i].noise << i + 3;
}
break;
case 0x08: // M/L[3:0] for Ch.A
*value = PSGWork.channel[0].ml;
break;
case 0x09: // M/L[3:0] for Ch.B
*value = PSGWork.channel[1].ml;
break;
case 0x0a: // M/L[3:0] for Ch.C
*value = PSGWork.channel[2].ml;
break;
case 0x0b: // EP[7:0]
case 0x0c: // EP[15:8]
case 0x0d: // CONT/ATT/ALT/HOLD
// TODO: support envelope.
break;
case 0x0e:
case 0x0f:
break;
case 0xfe: // minor version
*value = 1;
break;
case 0xff: // major version
*value = 1;
break;
default:
return false;
}
return true;
}
SCC.c
// SCC.c
bool SCCRead(uint8_t reg, uint8_t* value) {
// Register map is compatible with SCC+.
if (reg <= 0x9f) {
int ch = reg >> 5;
int offset = reg & 0x1f;
*value = SCCWork.synth[ch].wt[offset];
} else if (reg <= 0xa9) {
int ch = (reg - 0xa0) >> 1;
if (reg & 1)
*value = SCCWork.channel[ch].tp >> 8;
else
*value = SCCWork.channel[ch].tp & 0xff;
} else if (reg <= 0xae) {
int ch = reg - 0xaa;
*value = SCCWork.channel[ch].ml;
} else if (reg == 0xaf) {
for (int i = 0; i < 5; ++i) {
*value |= SCCWork.synth[i].tone << i;
}
} else if (reg == 0xfe) {
// minor version
*value = 1;
} else if (reg == 0xff) {
// major version
*value = 1;
} else {
return false;
}
return true;
}
I am using SoundCortexLPC and I can write data perfectly well to it via I2C, but I can't seem to read data.
With PSG registers I always get 0xA1 as answer. With SCC addresses I almost always get 0xA3 as answer. This seems to match the addresses of the IOEXT protocol.
I use MicroPython, and the code I use for testing is as follows:
For PSG
Which returns the following:
For SCC
Which returns the following: