mirror of
https://github.com/polpo/picogus.git
synced 2026-10-25 21:40:16 +00:00
SB: finalize IRQ/DMA/options settings
This commit is contained in:
1 parent
f54d9a5840
commit
4bf5631472
11 files changed
+284
-108
No files matched your search
+2
-2
@@ -68,10 +68,10 @@ static const char *modenames[8] = {
|
||||
#define CMD_MPUFAKE 0x22 // MPU fake all notes off
|
||||
|
||||
#define CMD_OPLWAIT 0x30 // Adlib speed sensitive fix
|
||||
#define CMD_SBOPTS 0x30 // SB options (mixer lock, time constant fix, etc.) - aliased to CMD_OPLWAIT
|
||||
#define CMD_SBDSPVER 0x31 // SB DSP version
|
||||
#define CMD_SBTYPE 0x31 // SB type
|
||||
#define CMD_SBIRQ 0x32 // SB IRQ
|
||||
#define CMD_SBDMA 0x33 // SB DMA
|
||||
#define CMD_SBOPTS 0x34 // SB options (mixer lock, time constant fix, etc.)
|
||||
|
||||
#define CMD_MOUSEPORT 0x40 // Mouse Base port
|
||||
#define CMD_MOUSEPROTO 0x41 // Mouse protocol
|
||||
|
||||
@@ -86,11 +86,30 @@ https://github.com/polpo/picogus/wiki/Compatibility-list
|
||||
|
||||
### Sound Blaster/AdLib options
|
||||
|
||||
Sound Blaster emulation requires the BLASTER variable to be set, in the format:
|
||||
|
||||
`set BLASTER=A220 I5 D1 H1 T6`, where 220 is the PicoGUS's SB emulation port,
|
||||
5 is the IRQ, 1 is the DMA, 6 is the emulated SB type (see `/sbtype` option)
|
||||
|
||||
* `/sbport x` - sets the base port of the Sound Blaster. Defaults to 220.
|
||||
* `/sbirq x` - sets the IRQ of the Sound Blaster. Must match jumper settings.
|
||||
* `/sbdma x` - sets the DMA of the Sound Blaster. Must match jumper settings.
|
||||
* `/sbtype x` - sets the Sound Blaster type: Allowed values are:
|
||||
1 - SB 1.x, 2 - SB Pro 1 (dual OPL2), 3 - SB 2.0
|
||||
4 - SB Pro 2 (OPL3), 6 - SB 16
|
||||
* `/oplport x` - sets the base port of the OPL/AdLib. Defaults to 388.
|
||||
* `/oplwait` - wait on OPL2 data write. Can fix speed-sensitive early AdLib
|
||||
games on fast systems (example: 688 Attack Sub).
|
||||
* `/sbvol x` - sets the volume of the SB PCM output to x percent.
|
||||
* `/oplvol x` - sets the volume of the OPL2 output to x percent.
|
||||
* `/sbfixtc 1|0 ` - fix SB time constant for 11/22/44 kHz sample rate. Can fix
|
||||
PCM audio slightly pitched up or down in pre-SB16 games and applications.
|
||||
Note than certain programs are already aware of SB time constant inaccuracy
|
||||
and will sound wrong if this option is enabled. Default = 0 (disabled)
|
||||
* `/sblockmixer n` - lock writes to SB mixer settings. Choices:
|
||||
0 - write lock disabled (default)
|
||||
1 - lock all but Voice Volume registers (for panning effects e.g. in Wolf3D)
|
||||
2 - lock all registers
|
||||
|
||||
### MPU-401 options
|
||||
|
||||
|
||||
+171
-38
@@ -107,8 +107,16 @@ static void usage(card_mode_t mode, bool print_all)
|
||||
if (mode == SB_MODE || print_all) {
|
||||
// "...............................................................................\n"
|
||||
pageprintf("Sound Blaster settings:\n");
|
||||
pageprintf(" /sbport x - set the base port of the Sound Blaster. Default: 220\n");
|
||||
pageprintf(" /sbvol x - set the Sound Blaster audio volume: 0 - 100%\n");
|
||||
pageprintf(" /sbport x - set the base port of the Sound Blaster. Default: 220\n");
|
||||
pageprintf(" /sbirq x - set the SB IRQ (must match jumper settings!). Default: 5\n");
|
||||
pageprintf(" /sbdma x - set the SB DMA (must match jumper settings!). Default: 1\n");
|
||||
pageprintf(" /sbtype x - set the Sound Blaster type. Default: 6 (SB 16)\n");
|
||||
pageprintf(" 1 - SB 1.x, 2 - SB Pro 1 (dual OPL2), 3 - SB 2.0,\n");
|
||||
pageprintf(" 4 - SB Pro 2 (OPL3), 6 - SB 16\n");
|
||||
pageprintf(" /sbvol x - set the Sound Blaster audio volume: 0 - 100%\n");
|
||||
pageprintf(" /sbfixtc 1|0 - fix SB time constant to match common rates. Default: 0\n");
|
||||
pageprintf(" /sblockmixer n - lock SB mixer settings. Default: 0 (no lock)\n");
|
||||
pageprintf(" 0 - no lock, 1 - lock all but Voice Volume, 2 - lock all\n");
|
||||
}
|
||||
if (mode == SB_MODE || mode == ADLIB_MODE || print_all) {
|
||||
pageprintf("AdLib settings:\n");
|
||||
@@ -176,11 +184,19 @@ static void err_blaster(void)
|
||||
// "................................................................................\n"
|
||||
fprintf(stderr, "ERROR: In SB mode but no BLASTER variable set or is malformed!\n");
|
||||
fprintf(stderr, "The BLASTER environment variable must be set in the following format:\n");
|
||||
fprintf(stderr, "\tset BLASTER=Axxx Iy Dz T3\n");
|
||||
fprintf(stderr, "Where xxx = port, y = IRQ, z = DMA. T3 indicates an SB 2.0 compatible card.\n");
|
||||
fprintf(stderr, "Port is set via /sbport xxx option; DMA and IRQ configued via jumper.\n");
|
||||
fprintf(stderr, "\tset BLASTER=Axxx Iy Dz Hz Tw\n");
|
||||
fprintf(stderr, "Where xxx = port, y = IRQ, z = DMA. w = SB type:\n");
|
||||
fprintf(stderr, " 1 - SB 1.x, 2 - SB Pro 1 (dual OPL2), 3 - SB 2.0,\n");
|
||||
fprintf(stderr, " 4 - SB Pro 2 (OPL3), 6 - SB 16\n");
|
||||
fprintf(stderr, "Port is set via /sbport xxx option; DMA and IRQ configued via jumper then also\n");
|
||||
fprintf(stderr, "set via /sbirq y and /sbdma y options.\n");
|
||||
}
|
||||
|
||||
static void err_blaster16_dma_mismatch(void)
|
||||
{
|
||||
// "................................................................................\n"
|
||||
fprintf(stderr, "ERROR: In SB 16 mode, low (Dx) and high (Hx) DMA in BLASTER variable must match!\n");
|
||||
}
|
||||
|
||||
static void err_pigus(void)
|
||||
{
|
||||
@@ -247,17 +263,33 @@ static int init_gus(void)
|
||||
|
||||
static int init_sb(void)
|
||||
{
|
||||
// SB DSP version table
|
||||
const uint16_t dspver[] = {0, 0x105, 0x300, 0x201, 0x301, 0, 0x405};
|
||||
|
||||
char* blaster = getenv("BLASTER");
|
||||
if (blaster == NULL) {
|
||||
err_blaster();
|
||||
return 1;
|
||||
}
|
||||
char blasterTemp[256];
|
||||
strncpy(blasterTemp, blaster, sizeof(blasterTemp));
|
||||
|
||||
// Parse BLASTER
|
||||
uint16_t port;
|
||||
int e;
|
||||
e = sscanf(blaster, "A%hx I%*hhu D%*hhu T3", &port);
|
||||
if (e != 1) {
|
||||
char* p = strtok(blasterTemp, " ");
|
||||
uint16_t port = -1, irq = -1, dma8 = -1, dma16 = -1, sbtype = 0;
|
||||
while (p != NULL) {
|
||||
switch (*p) {
|
||||
case 'a': case 'A': port = strtol(p + 1, NULL, 16); break;
|
||||
case 'i': case 'I': irq = strtol(p + 1, NULL, 10); break;
|
||||
case 'd': case 'D': dma8 = strtol(p + 1, NULL, 10); break;
|
||||
case 'h': case 'H': dma16 = strtol(p + 1, NULL, 10); break;
|
||||
case 't': case 'T': sbtype = strtol(p + 1, NULL, 10); break;
|
||||
default: break;
|
||||
}
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
if ((port == -1) || (irq == -1) || (dma8 == -1) || (sbtype > 6) || (dspver[sbtype] == 0) || ((sbtype == 6) && (dma8 != dma16))) {
|
||||
err_blaster();
|
||||
return 2;
|
||||
}
|
||||
@@ -268,6 +300,28 @@ static int init_sb(void)
|
||||
err_blaster();
|
||||
return 2;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, CMD_SBIRQ); // Select IRQ register
|
||||
uint8_t tmp_irq = inp(DATA_PORT_HIGH);
|
||||
if (irq != tmp_irq) {
|
||||
err_blaster();
|
||||
return 2;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, CMD_SBDMA); // Select DMA register
|
||||
uint8_t tmp_dma = inp(DATA_PORT_HIGH);
|
||||
if (dma8 != tmp_dma) {
|
||||
err_blaster();
|
||||
return 2;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, CMD_SBTYPE); // Select SB type register
|
||||
uint8_t tmp_type = inp(DATA_PORT_HIGH);
|
||||
if (sbtype != tmp_type) {
|
||||
err_blaster();
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -630,13 +684,13 @@ static void send_string(const uint8_t cmd, const char* str, const int16_t max_le
|
||||
outp(DATA_PORT_HIGH, 0);
|
||||
}
|
||||
|
||||
static bool cmdDisplayUsage(const char* arg, const int print_all)
|
||||
static bool cmdDisplayUsage(const char* arg, const int print_all, const int cmd2, const int cmd3)
|
||||
{
|
||||
usage(gMode, print_all);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendBool(const char* arg, const int cmd)
|
||||
static bool cmdSendBool(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
uint8_t value;
|
||||
|
||||
@@ -654,7 +708,27 @@ static bool cmdSendBool(const char* arg, const int cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSetMode(const char* arg, const int cmd)
|
||||
static bool cmdSendBoolMasked(const char* arg, const int cmd, const int mask, const int shift)
|
||||
{
|
||||
uint8_t value, oldvalue;
|
||||
|
||||
if (!strcmp(arg, "1") || !stricmp(arg, "true") || !stricmp(arg, "on")) {
|
||||
value = 1;
|
||||
} else if (!strcmp(arg, "0") || !stricmp(arg, "false") || !stricmp(arg, "off")) {
|
||||
value = 0;
|
||||
} else {
|
||||
usage(gMode, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, cmd);
|
||||
oldvalue = inp(DATA_PORT_HIGH);
|
||||
outp(DATA_PORT_HIGH, (uint8_t)(oldvalue & ~mask) | ((value << shift) & mask));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool cmdSetMode(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
if (!stricmp(arg, "TANDY") || !stricmp(arg, "CMS")) {
|
||||
// Backwards compatibility for old tandy and cms modes
|
||||
@@ -687,11 +761,47 @@ static bool ctrlSendUint8(const char *arg, int cmd, int min, int max)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendUint8(const char* arg, const int cmd)
|
||||
static bool ctrlSendUint8Masked(const char *arg, int cmd, int min, int max, int mask, int shift) {
|
||||
char* endptr;
|
||||
uint8_t val = (uint8_t)strtoul(arg, &endptr, 10);
|
||||
uint8_t oldval = 0;
|
||||
|
||||
if (*endptr != '\0' || val < min || val > max) {
|
||||
usage(gMode, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, cmd);
|
||||
oldval = inp(DATA_PORT_HIGH);
|
||||
outp(DATA_PORT_HIGH, (uint8_t)(oldval & ~mask) | ((val << shift) & mask));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendUint8(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint8(arg, cmd, 0, 255);
|
||||
}
|
||||
|
||||
static bool cmdSendSBType(const char* arg, const int cmd, const int cmd2, const int cmd3) {
|
||||
char* endptr;
|
||||
uint8_t val = (uint8_t)strtoul(arg, &endptr, 10);
|
||||
|
||||
if (*endptr != '\0' || val < 1 || val > 6 || val == 5) {
|
||||
usage(gMode, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, cmd);
|
||||
outp(DATA_PORT_HIGH, (uint8_t)val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendUint8Masked(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
// cmd2 - mask, cmd3 - shift
|
||||
return ctrlSendUint8Masked(arg, cmd, 0, 255, cmd2, cmd3);
|
||||
}
|
||||
|
||||
static bool ctrlSendUint16(const char *arg, int cmd, long min, long max, int base)
|
||||
{
|
||||
char *endptr;
|
||||
@@ -707,27 +817,27 @@ static bool ctrlSendUint16(const char *arg, int cmd, long min, long max, int bas
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendUint16(const char* arg, const int cmd)
|
||||
static bool cmdSendUint16(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint16(arg, cmd, 0, 65535, 10);
|
||||
}
|
||||
|
||||
static bool cmdSendPort(const char* arg, const int cmd)
|
||||
static bool cmdSendPort(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint16(arg, cmd, 0, 0x3FF, 16);
|
||||
}
|
||||
|
||||
static bool cmdDefaults(const char* arg, const int cmd)
|
||||
static bool cmdDefaults(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return cmdSendUint8(CMD_DEFAULTS, 0xff);
|
||||
return cmdSendUint8(CMD_DEFAULTS, 0xff, 0, 0);
|
||||
}
|
||||
|
||||
static bool cmdSetVol(const char* arg, const int cmd)
|
||||
static bool cmdSetVol(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint8(arg, cmd, 0, 100);
|
||||
}
|
||||
|
||||
static bool cmdSendMousePort(const char *arg, const int cmd)
|
||||
static bool cmdSendMousePort(const char *arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
char* endptr;
|
||||
uint8_t val = (uint8_t)strtoul(arg, &endptr, 10);
|
||||
@@ -753,66 +863,71 @@ static bool cmdSendMousePort(const char *arg, const int cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSendMouseSen(const char* arg, const int cmd)
|
||||
static bool cmdSendMouseSen(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint16(arg, cmd, 0, 1024, 10);
|
||||
}
|
||||
|
||||
static bool cmdSendMouseProto(const char* arg, const int cmd)
|
||||
static bool cmdSendMouseProto(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint8(arg, cmd, 0, 3);
|
||||
}
|
||||
|
||||
static bool cmdSendMouseRate(const char* arg, const int cmd)
|
||||
static bool cmdSendMouseRate(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint8(arg, cmd, 20, 200);
|
||||
}
|
||||
|
||||
static bool cmdWifiStatus(const char* arg, const int cmd)
|
||||
static bool cmdSendSBLockMixer(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
return ctrlSendUint8Masked(arg, cmd, 0, 2, (2 << 1), 1);
|
||||
}
|
||||
|
||||
static bool cmdWifiStatus(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
wifi_printStatus();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static bool cmdWifiSSID(const char* arg, const int cmd)
|
||||
static bool cmdWifiSSID(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
wifichg = true;
|
||||
send_string(cmd, arg, 32);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdWifiPass(const char* arg, const int cmd)
|
||||
static bool cmdWifiPass(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
wifichg = true;
|
||||
send_string(cmd, arg, 63);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdWifiNoPass(const char* arg, const int cmd)
|
||||
static bool cmdWifiNoPass(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
wifichg = true;
|
||||
send_string(cmd, "", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdCDLoadName(const char* arg, const int cmd)
|
||||
static bool cmdCDLoadName(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
send_string(cmd, arg, 127);
|
||||
exit(wait_for_cd_load());
|
||||
}
|
||||
|
||||
static bool cmdCDList(const char* arg, const int cmd)
|
||||
static bool cmdCDList(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
exit(print_cdimage_list());
|
||||
}
|
||||
|
||||
static bool cmdCDLoad(const char* arg, const int cmd)
|
||||
static bool cmdCDLoad(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
ctrlSendUint8(arg, cmd, 0, 255);
|
||||
exit(wait_for_cd_load());
|
||||
}
|
||||
|
||||
static bool cmdGUSBuffer(const char* arg, const int cmd)
|
||||
static bool cmdGUSBuffer(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
uint8_t tmp_uint8;
|
||||
uint8_t e = sscanf(arg, "%hhu", &tmp_uint8);
|
||||
@@ -826,7 +941,7 @@ static bool cmdGUSBuffer(const char* arg, const int cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdFlashPico(const char* arg, const int cmd)
|
||||
static bool cmdFlashPico(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
if (strlen(arg) > 255)
|
||||
{
|
||||
@@ -837,7 +952,7 @@ static bool cmdFlashPico(const char* arg, const int cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cmdSave(const char* arg, const int cmd)
|
||||
static bool cmdSave(const char* arg, const int cmd, const int cmd2, const int cmd3)
|
||||
{
|
||||
permanent = true;
|
||||
return true;
|
||||
@@ -868,6 +983,11 @@ ParseCommand parseCommands[] = {
|
||||
{"/gusdma", cmdSendUint8, CMD_GUSDMA, ARG_REQUIRE, "0"},
|
||||
{"/gusport", cmdSendPort, CMD_GUSPORT, ARG_REQUIRE, "240"},
|
||||
{"/sbport", cmdSendPort, CMD_SBPORT, ARG_REQUIRE, "220"},
|
||||
{"/sbirq", cmdSendUint8, CMD_SBIRQ, ARG_REQUIRE, "5"},
|
||||
{"/sbdma", cmdSendUint8, CMD_SBDMA, ARG_REQUIRE, "1"},
|
||||
{"/sbtype", cmdSendSBType, CMD_SBTYPE, ARG_REQUIRE, "6"},
|
||||
{"/sbfixtc", cmdSendBoolMasked, CMD_SBOPTS, ARG_REQUIRE, "0", (1 << 0), 0},
|
||||
{"/sblockmixer", cmdSendSBLockMixer, CMD_SBOPTS, ARG_REQUIRE, "0"},
|
||||
{"/oplport", cmdSendPort, CMD_OPLPORT, ARG_REQUIRE, "388"},
|
||||
{"/oplwait", cmdSendBool, CMD_OPLWAIT, ARG_REQUIRE, "false"},
|
||||
{"/mpuport", cmdSendPort, CMD_MPUPORT, ARG_REQUIRE, "330"},
|
||||
@@ -941,7 +1061,7 @@ int parseCommand(int argc, char* argv[], int* i, ParseCommand commands[])
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
return command->routine(arg, command->cmd);
|
||||
return command->routine(arg, command->cmd, command->cmd2, command->cmd3);
|
||||
} else {
|
||||
printf("Invalid command %s. Run pgusinit /? for usage help", argv[idx]);
|
||||
}
|
||||
@@ -1006,7 +1126,7 @@ static void printGUSMode()
|
||||
static void printAdlibMode()
|
||||
{
|
||||
printf("Running in AdLib/OPL2 mode on port %x", ctrlGetUint16(CMD_OPLPORT));
|
||||
printf("%s\n", ctrlGetUint8(CMD_OPLWAIT) ? ", wait on" : "");
|
||||
printf("%s\n", ctrlGetUint8(CMD_OPLWAIT) & 1 ? ", wait on" : "");
|
||||
}
|
||||
|
||||
static void printUSBMode()
|
||||
@@ -1023,16 +1143,29 @@ static void printPSGMode()
|
||||
|
||||
static void printSBMode()
|
||||
{
|
||||
static char *strMode[] = {"(invalid)", "1.x", "Pro 1", "2.0", "Pro 2", "(invalid)", "16"};
|
||||
static char *strLockMixerMode[] = {"unlocked", "locked except Voice Volume", "locked", "(invalid)"};
|
||||
|
||||
if (init_sb()) {
|
||||
return;
|
||||
}
|
||||
printf("Running in Sound Blaster 2.0 mode on port %x ", ctrlGetUint16(CMD_SBPORT));
|
||||
printf("Running in Sound Blaster %s mode on port %x, IRQ %d, DMA %d\n",
|
||||
ctrlGetUint8(CMD_SBTYPE) > 6 ? "(invalid)" : strMode[ctrlGetUint8(CMD_SBTYPE)],
|
||||
ctrlGetUint16(CMD_SBPORT),
|
||||
ctrlGetUint8(CMD_SBIRQ),
|
||||
ctrlGetUint8(CMD_SBDMA)
|
||||
);
|
||||
uint8_t tmp_uint8 = ctrlGetUint8(CMD_SBOPTS);
|
||||
printf("SB Time Constant fix: %s, SB mixer: %s\n",
|
||||
(tmp_uint8 >> 0) & 1 ? "enabled" : "disabled",
|
||||
strLockMixerMode[(tmp_uint8 >> 1) & 3]
|
||||
);
|
||||
uint16_t tmp_uint16 = ctrlGetUint16(CMD_OPLPORT);
|
||||
if (tmp_uint16) {
|
||||
printf("(AdLib port %x", tmp_uint16);
|
||||
printf("%s)\n", ctrlGetUint8(CMD_OPLWAIT) ? ", wait on" : "");
|
||||
printf("AdLib port %x", tmp_uint16);
|
||||
printf("%s\n", ctrlGetUint8(CMD_OPLWAIT) & 1 ? ", wait on" : "");
|
||||
} else {
|
||||
printf("(AdLib port disabled)\n");
|
||||
printf("AdLib port disabled\n");
|
||||
}
|
||||
print_cdemu_status();
|
||||
}
|
||||
|
||||
+3
-1
@@ -34,9 +34,11 @@ enum CommandType
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
bool (*routine)(const char*, const int);
|
||||
bool (*routine)(const char*, const int, const int, const int);
|
||||
int cmd;
|
||||
int type;
|
||||
char *def;
|
||||
int cmd2;
|
||||
int cmd3;
|
||||
} ParseCommand;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ set(PICO_COPY_TO_RAM 1)
|
||||
include(pico_sdk_import.cmake)
|
||||
|
||||
project(picogus
|
||||
VERSION "3.2.1"
|
||||
VERSION "3.2.2"
|
||||
LANGUAGES C CXX ASM
|
||||
)
|
||||
|
||||
|
||||
+22
-18
@@ -244,13 +244,10 @@ __force_inline void select_picogus(uint8_t value) {
|
||||
cur_read_idx = 0;
|
||||
#endif
|
||||
break;
|
||||
#ifdef SOUND_SB
|
||||
case CMD_SBDSPVER:
|
||||
picogus_dataLatch_low = 0;
|
||||
case CMD_SBTYPE:
|
||||
case CMD_SBIRQ:
|
||||
case CMD_SBDMA:
|
||||
break;
|
||||
#endif
|
||||
case CMD_SBOPTS:
|
||||
case CMD_CDSTATUS:
|
||||
case CMD_CDLOAD:
|
||||
case CMD_CDAUTOADV:
|
||||
@@ -296,12 +293,6 @@ __force_inline void write_picogus_low(uint8_t value) {
|
||||
case CMD_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
mouseSensitivity_low = value;
|
||||
break;
|
||||
#ifdef SOUND_SB
|
||||
case CMD_SBDSPVER:
|
||||
picogus_dataLatch_low = value;
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,25 +363,30 @@ __force_inline void write_picogus_high(uint8_t value) {
|
||||
#endif
|
||||
break;
|
||||
case CMD_OPLWAIT: // Adlib speed sensitive fix
|
||||
//case CMD_SBOPTS: // ... and SB emulation options
|
||||
settings.SB.oplSpeedSensitive = value & 1; // HACK until settings struct resolved
|
||||
#ifdef SOUND_SB
|
||||
sbdsp_set_options(value);
|
||||
#endif
|
||||
settings.SB.oplSpeedSensitive = value;
|
||||
break;
|
||||
case CMD_SBDSPVER:
|
||||
|
||||
case CMD_SBTYPE:
|
||||
settings.SB16.sbType = value;
|
||||
#ifdef SOUND_SB
|
||||
sbdsp_set_dsp_version((value << 8) | picogus_dataLatch_low);
|
||||
sbdsp_set_type(value);
|
||||
#endif
|
||||
break;
|
||||
case CMD_SBIRQ:
|
||||
settings.SB16.irq = value;
|
||||
#ifdef SOUND_SB
|
||||
sbdsp_set_irq(value);
|
||||
#endif
|
||||
break;
|
||||
case CMD_SBDMA:
|
||||
settings.SB16.dma = value;
|
||||
#ifdef SOUND_SB
|
||||
sbdsp_set_dma(value);
|
||||
#endif
|
||||
case CMD_SBOPTS:
|
||||
settings.SB16.options = value;
|
||||
#ifdef SOUND_SB
|
||||
sbdsp_set_options(value);
|
||||
#endif
|
||||
break;
|
||||
case CMD_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
@@ -606,6 +602,14 @@ __force_inline uint8_t read_picogus_high(void) {
|
||||
return settings.Mouse.sensitivity >> 8;
|
||||
case CMD_NE2KPORT: // NE2000 Base port
|
||||
return settings.NE2K.basePort == 0xFFFF ? 0 : (settings.NE2K.basePort >> 8);
|
||||
case CMD_SBTYPE: // SB type
|
||||
return settings.SB16.sbType;
|
||||
case CMD_SBIRQ: // SB IRQ
|
||||
return settings.SB16.irq;
|
||||
case CMD_SBDMA: // SB DMA
|
||||
return settings.SB16.dma;
|
||||
case CMD_SBOPTS: // SB Options
|
||||
return settings.SB16.options;
|
||||
/*
|
||||
case CMD_WIFISSID:
|
||||
break;
|
||||
|
||||
+32
-19
@@ -13,6 +13,7 @@ Author : Kevin Moonlight <me@yyzkevin.com>
|
||||
|
||||
Copyright (C) 2023 Kevin Moonlight
|
||||
Copyright (C) 2024 Ian Scott
|
||||
Copyright (C) 2026 Artem Vasilev
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
@@ -49,8 +50,12 @@ static irq_handler_t SBDSP_DMA_isr_pt;
|
||||
static dma_inst_t dma_config;
|
||||
#define DMA_PIO_SM 2
|
||||
|
||||
#define DSP_VERSION_MAJOR 4
|
||||
#define DSP_VERSION_MINOR 5
|
||||
#define SB_TYPE_SB1 0x1
|
||||
#define SB_TYPE_SBPRO1 0x2
|
||||
#define SB_TYPE_SB2 0x3
|
||||
#define SB_TYPE_SBPRO2 0x4
|
||||
#define SB_TYPE_SB2MCV 0x5
|
||||
#define SB_TYPE_SB16 0x6
|
||||
|
||||
// Sound Blaster DSP I/O port offsets
|
||||
#define DSP_RESET 0x6
|
||||
@@ -138,8 +143,8 @@ static dma_inst_t dma_config;
|
||||
|
||||
// mixer locking settings
|
||||
#define MIXER_LOCK_NONE 0 // none, all registers writeable
|
||||
#define MIXER_LOCK_ALL_BUT_SBP_VOICE 14 // lock all but SBPro Voice (for stereo FX like in Wolf3D)
|
||||
#define MIXER_LOCK_ALL 15 // lock all registers
|
||||
#define MIXER_LOCK_ALL_BUT_SBP_VOICE 1 // lock all but SBPro Voice (for stereo FX like in Wolf3D)
|
||||
#define MIXER_LOCK_ALL 2 // lock all registers
|
||||
|
||||
static char const copyright_string[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
|
||||
|
||||
@@ -222,7 +227,7 @@ uint32_t sbdsp_generate_sample() {
|
||||
}
|
||||
|
||||
static void sbdsp_handle_time_constant(uint8_t tc) {
|
||||
if (sbdsp.options.fix_tc) {
|
||||
if (sbdsp.options.fixTC) {
|
||||
// round time constants to 11/22/44 KHz sample rates
|
||||
switch (tc) {
|
||||
case (256 - 62): // 16129 Hz
|
||||
@@ -320,11 +325,31 @@ uint16_t sbdsp_sample_rate() {
|
||||
return sbdsp.sample_rate;
|
||||
}
|
||||
|
||||
void sbdsp_set_options(uint8_t options) {
|
||||
sbdsp.options.b = options;
|
||||
// TODO if any to apply
|
||||
}
|
||||
|
||||
void sbdsp_set_type(uint8_t type) {
|
||||
if ((type == 0) && (type > SB_TYPE_SB16)) type = SB_TYPE_SB16;
|
||||
switch (type) {
|
||||
default:
|
||||
case SB_TYPE_SB1: sbdsp.dsp_version.major = 1; sbdsp.dsp_version.minor = 5; break;
|
||||
case SB_TYPE_SB2:
|
||||
case SB_TYPE_SB2MCV: sbdsp.dsp_version.major = 2; sbdsp.dsp_version.minor = 1; break;
|
||||
case SB_TYPE_SBPRO1: sbdsp.dsp_version.major = 3; sbdsp.dsp_version.minor = 0; break;
|
||||
case SB_TYPE_SBPRO2: sbdsp.dsp_version.major = 3; sbdsp.dsp_version.minor = 1; break;
|
||||
case SB_TYPE_SB16: sbdsp.dsp_version.major = 4; sbdsp.dsp_version.minor = 5; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sbdsp_set_irq(uint8_t irq) {
|
||||
sbdsp.resources.irq = irq;
|
||||
int mixer_irq;
|
||||
switch (irq) {
|
||||
case 2: mixer_irq = 1; break;
|
||||
case 2:
|
||||
case 9: mixer_irq = 1; break;
|
||||
case 7: mixer_irq = 4; break;
|
||||
case 10: mixer_irq = 8; break;
|
||||
case 5:
|
||||
@@ -338,23 +363,11 @@ void sbdsp_set_dma(uint8_t dma) {
|
||||
mixer_state[MIXER_DMA] = dma < 4 ? (1 << dma) : 0; // 8-bit DMA channel only
|
||||
}
|
||||
|
||||
void sbdsp_set_options(uint8_t opts) {
|
||||
sbdsp.options.b = opts;
|
||||
// TODO apply them in runtime where applicable
|
||||
}
|
||||
|
||||
static void sbmixer_reset(void);
|
||||
void sbdsp_init() {
|
||||
puts("Initing ISA DMA PIO...");
|
||||
SBDSP_DMA_isr_pt = sbdsp_dma_isr;
|
||||
|
||||
sbdsp.options.mixer_lock = MIXER_LOCK_NONE;
|
||||
sbdsp.options.fix_tc = 0;
|
||||
sbdsp.dsp_version.major = DSP_VERSION_MAJOR;
|
||||
sbdsp.dsp_version.minor = DSP_VERSION_MINOR;
|
||||
sbdsp_set_irq(5);
|
||||
sbdsp_set_dma(1);
|
||||
|
||||
sbdsp.outbox = 0xAA;
|
||||
dma_config = DMA_multi_init(pio0, DMA_PIO_SM, SBDSP_DMA_isr_pt);
|
||||
|
||||
@@ -882,7 +895,7 @@ static __force_inline uint8_t sbmixer_read(void) {
|
||||
|
||||
static __force_inline void sbmixer_write(uint8_t value) {
|
||||
// mixer locking
|
||||
switch(sbdsp.options.mixer_lock) {
|
||||
switch(sbdsp.options.lockMixer) {
|
||||
case MIXER_LOCK_ALL_BUT_SBP_VOICE:
|
||||
if (sbdsp.mixer_command != MIXER_VOL_VOICE)
|
||||
// fallthrough
|
||||
|
||||
+4
-27
@@ -84,12 +84,10 @@ typedef struct sbdsp_t {
|
||||
uint8_t dma;
|
||||
} resources;
|
||||
|
||||
// additional options
|
||||
union {
|
||||
struct {
|
||||
uint8_t reserved : 3; // reserved for OPL speed sensitivity fix and future settings
|
||||
uint8_t fix_tc : 1; // fix time constant for exact 11/22/44k Hz
|
||||
uint8_t mixer_lock : 4; // mixer lock
|
||||
uint8_t fixTC : 1;
|
||||
uint8_t lockMixer : 2;
|
||||
};
|
||||
uint8_t b;
|
||||
} options;
|
||||
@@ -140,30 +138,9 @@ static inline uint32_t sbdsp_sample_stereo() {
|
||||
// -------------------------
|
||||
// PicoGUS configuration interface helpers
|
||||
|
||||
static inline uint16_t sbdsp_get_dsp_version() {
|
||||
extern sbdsp_t sbdsp;
|
||||
return sbdsp.dsp_version.w;
|
||||
}
|
||||
static inline void sbdsp_set_dsp_version(uint16_t dspver) {
|
||||
extern sbdsp_t sbdsp;
|
||||
sbdsp.dsp_version.w = dspver;
|
||||
}
|
||||
|
||||
static inline uint8_t sbdsp_get_irq() {
|
||||
extern sbdsp_t sbdsp;
|
||||
return sbdsp.resources.irq;
|
||||
}
|
||||
static inline uint8_t sbdsp_get_dma() {
|
||||
extern sbdsp_t sbdsp;
|
||||
return sbdsp.resources.dma;
|
||||
}
|
||||
void sbdsp_set_type(uint8_t type);
|
||||
void sbdsp_set_irq(uint8_t irq);
|
||||
void sbdsp_set_dma(uint8_t dma);
|
||||
|
||||
static inline uint8_t sbdsp_get_options() {
|
||||
extern sbdsp_t sbdsp;
|
||||
return sbdsp.options.b;
|
||||
}
|
||||
void sbdsp_set_options(uint8_t opts);
|
||||
void sbdsp_set_options(uint8_t options);
|
||||
|
||||
#endif // SBDSP_H
|
||||
+5
-1
@@ -66,7 +66,7 @@ extern cms_buffer_t opl_cmd_buffer;
|
||||
#include "mouse/sermouse.h"
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_MPU
|
||||
#if (defined(SOUND_MPU) || defined(SOUND_SB))
|
||||
#include "system/flash_settings.h"
|
||||
extern Settings settings;
|
||||
#include "mpu401/export.h"
|
||||
@@ -201,6 +201,10 @@ void play_adlib() {
|
||||
ad1848_init();
|
||||
#else
|
||||
sbdsp_init();
|
||||
sbdsp_set_type(settings.SB16.sbType);
|
||||
sbdsp_set_irq(settings.SB16.irq);
|
||||
sbdsp_set_dma(settings.SB16.dma);
|
||||
sbdsp_set_options(settings.SB16.options);
|
||||
#endif
|
||||
#endif
|
||||
init_audio();
|
||||
|
||||
@@ -85,6 +85,13 @@ static const Settings defaultSettings = {
|
||||
.cdVol = 100,
|
||||
.gusVol = 100,
|
||||
.psgVol = 80
|
||||
},
|
||||
.SB16 = {
|
||||
.irq = 5,
|
||||
.dma = 1,
|
||||
.sbType = 6,
|
||||
.fixTC = 0,
|
||||
.lockMixer = 0
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,6 +133,11 @@ static const VersionFields versionFieldsTable[] = {
|
||||
{(const FieldInfo[]){
|
||||
FIELD(Volume),
|
||||
}, 1},
|
||||
|
||||
// version 5 - added SB16 settings
|
||||
{(const FieldInfo[]){
|
||||
FIELD(SB16),
|
||||
}, 1},
|
||||
};
|
||||
|
||||
// Apply default values only to fields introduced after the given version
|
||||
|
||||
@@ -25,7 +25,7 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SETTINGS_MAGIC 0x70677573 // "pgus" in ascii
|
||||
#define SETTINGS_VERSION 4
|
||||
#define SETTINGS_VERSION 5
|
||||
|
||||
// When adding new fields to Settings struct:
|
||||
// 1. Increment SETTINGS_VERSION
|
||||
@@ -95,6 +95,18 @@ typedef struct Settings {
|
||||
uint8_t gusVol;
|
||||
uint8_t psgVol;
|
||||
} Volume;
|
||||
struct {
|
||||
uint8_t irq;
|
||||
uint8_t dma;
|
||||
uint8_t sbType;
|
||||
union {
|
||||
struct {
|
||||
uint8_t fixTC : 1;
|
||||
uint8_t lockMixer : 2;
|
||||
};
|
||||
uint8_t options;
|
||||
};
|
||||
} SB16; // TEMPORARY - may be changed!
|
||||
} Settings;
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user