Config OPL wait; allow WT volume; inline in sbdsp

This commit is contained in:
Ian Scott committed 2024-03-27 09:12:16 -06:00
1 parent 92cb2408a4
commit 4e6017b36e
3 files changed
+58 -35

No files matched your search

+19 -8
View File
@@ -41,7 +41,7 @@ const char* usage_by_card[] = {
"[/p x] [/v x] [/s] [/n]", // MPU_MODE
"[/p x]", // TANDY_MODE
"[/p x]", // CMS_MODE
"[/p x] [/o x]", // SB_MODE
"[/p x] [/o x] [/w]", // SB_MODE
"", "", "", "", "", "", "", "", "", // future expansion
"", // JOYSTICK_ONLY_MODE
};
@@ -66,6 +66,7 @@ void usage(char *argv0, card_mode_t mode) {
}
if (mode == SB_MODE) {
fprintf(stderr, " /o x - set the base address of the OPL2/AdLib on the SB. Default: 388\n");
fprintf(stderr, " /w - wait on OPL2 data write. Can fix speed-sensitive early AdLib games\n");
// "................................................................................\n"
}
if (mode == MPU_MODE) {
@@ -285,12 +286,13 @@ int main(int argc, char* argv[]) {
uint8_t force_44k = 0;
uint16_t port_override = 0;
uint16_t opl_port_override = 0;
uint8_t wt_volume = 100;
uint8_t wt_volume;
char fw_filename[256] = {0};
card_mode_t mode;
uint8_t mpu_delaysysex = 0;
uint8_t mpu_fakeallnotesoff = 0;
uint8_t enable_joystick = 0;
uint8_t adlib_wait = 0;
banner();
// Get magic value from port on PicoGUS that is not on real GUS
@@ -306,6 +308,9 @@ int main(int argc, char* argv[]) {
outp(CONTROL_PORT, 0x03); // Select mode register
mode = inp(DATA_PORT_HIGH);
// Default wavetable volume to 100 in MPU mode, 0 otherwise
wt_volume = (mode == MPU_MODE) ? 100 : 0;
int i = 1;
while (i < argc) {
if (stricmp(argv[i], "/?") == 0) {
@@ -355,6 +360,8 @@ int main(int argc, char* argv[]) {
usage(argv[0], mode);
return 4;
}
} else if (stricmp(argv[i], "/w") == 0) {
adlib_wait = 1;
} else if (stricmp(argv[i], "/v") == 0) {
if (i + 1 >= argc) {
usage(argv[0], mode);
@@ -433,6 +440,12 @@ int main(int argc, char* argv[]) {
outp(DATA_PORT_HIGH, enable_joystick);
printf("USB joystick support %s\n", enable_joystick ? "enabled" : "disabled (use /j to enable)");
if (board_type == PICOGUS_2) {
outp(CONTROL_PORT, 0x20); // Select wavetable volume register
outp(DATA_PORT_HIGH, wt_volume); // Write volume
printf("Wavetable volume set to %u\n", wt_volume);
}
switch(mode) {
case GUS_MODE:
init_gus(argv[0]);
@@ -465,11 +478,6 @@ int main(int argc, char* argv[]) {
printf("Running in AdLib/OPL2 mode on port %x\n", port);
break;
case MPU_MODE:
if (board_type == PICOGUS_2) {
outp(CONTROL_PORT, 0x20); // Select wavetable volume register
outp(DATA_PORT_HIGH, wt_volume); // Write volume
printf("Wavetable volume set to %u\n", wt_volume);
}
printf("MPU-401 sysex delay: %s, fake all notes off: %s\n", mpu_delaysysex ? "on" : "off", mpu_fakeallnotesoff ? "on" : "off");
outp(CONTROL_PORT, 0x21); // Select MPU settings register
outp(DATA_PORT_HIGH, mpu_delaysysex | (mpu_fakeallnotesoff << 1)); // Write sysex delay and fake all notes off settings
@@ -482,7 +490,10 @@ int main(int argc, char* argv[]) {
printf("Running in CMS/Game Blaster mode on port %x\n", port);
break;
case SB_MODE:
printf("Running in Sound Blaster 2.0 mode on port %x (AdLib port %x)\n", port, opl_port);
outp(CONTROL_PORT, 0x30); // Select Adlib wait register
outp(DATA_PORT_HIGH, adlib_wait); // Write sysex delay and fake all notes off settings
printf("Running in Sound Blaster 2.0 mode on port %x (AdLib port %x%s)\n",
port, opl_port, adlib_wait ? ", wait on" : "");
break;
case JOYSTICK_ONLY_MODE:
printf("Running in Joystick exclusive mode on port 201\n");
+16 -5
View File
@@ -58,6 +58,7 @@ extern uint8_t sbdsp_read(uint8_t address);
extern void sbdsp_init();
extern void sbdsp_process();
static uint16_t adlib_basePort = 0x388u;
static bool adlib_wait = false;
#endif
#ifdef SOUND_GUS
@@ -148,10 +149,15 @@ __force_inline void select_picogus(uint8_t value) {
case 0x12: // Force 44k
break;
#endif
#ifdef SOUND_MPU
case 0x20: // Wavetable mixer volume
break;
#ifdef SOUND_MPU
case 0x21: // MPU init
break;
#endif
#ifdef SOUND_SB
case 0x30: // Adlib speed sensitive fix
break;
#endif
case 0xF0: // Hardware version
break;
@@ -209,15 +215,20 @@ __force_inline void write_picogus_high(uint8_t value) {
GUS_SetFixed44k(value);
break;
#endif
#ifdef SOUND_MPU
case 0x20: // Wavetable mixer volume
if (BOARD_TYPE == PICOGUS_2) {
m62429->setVolume(M62429_BOTH, value);
}
break;
#ifdef SOUND_MPU
case 0x21: // MIDI emulation flags
MPU401_Init(value & 0x1 /* delaysysex */, value & 0x2 /* fakeallnotesoff */);
break;
#endif
#ifdef SOUND_SB
case 0x30: // Adlib speed sensitive fix
adlib_wait = value;
break;
#endif
case 0xff: // Firmware write
pico_firmware_write(value);
@@ -298,7 +309,6 @@ __force_inline uint8_t read_picogus_high(void) {
#else
return 0;
#endif
#ifdef SOUND_MPU
case 0x20: // Wavetable mixer volume
if (BOARD_TYPE == PICOGUS_2) {
return m62429->getVolume(0);
@@ -306,7 +316,6 @@ __force_inline uint8_t read_picogus_high(void) {
return 0;
}
break;
#endif
case 0xF0: // Hardware version
return BOARD_TYPE;
case 0xff:
@@ -396,7 +405,9 @@ __force_inline void handle_iow(void) {
return;
} else if (port == adlib_basePort + 1) {
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
busy_wait_us(1); // busy wait for speed sensitive games :(
if (adlib_wait) {
busy_wait_us(1); // busy wait for speed sensitive games
}
opl_buffer.cmds[opl_buffer.head++] = {
OPL_DATA_PORT,
(uint8_t)(iow_read & 0xFF)
+23 -22
View File
@@ -14,8 +14,8 @@ Author : Kevin Moonlight <me@yyzkevin.com>
#include "isa_dma.h"
irq_handler_t SBDSP_DMA_isr_pt;
dma_inst_t dma_config;
static irq_handler_t SBDSP_DMA_isr_pt;
static dma_inst_t dma_config;
#define DMA_PIO_SM 2
#define DSP_VERSION_MAJOR 2
@@ -66,7 +66,7 @@ typedef struct sbdsp_t {
uint8_t current_command_index;
uint16_t dma_interval;
int16_t dma_interval_trim;
// int16_t dma_interval_trim;
uint8_t dma_transfer_size;
uint8_t dma_buffer[DSP_DMA_FIFO_SIZE];
volatile uint16_t dma_buffer_tail;
@@ -80,12 +80,12 @@ typedef struct sbdsp_t {
uint32_t dma_sample_count_rx;
uint8_t time_constant;
uint16_t sample_rate;
uint32_t sample_step;
uint64_t cycle_us;
// uint16_t sample_rate;
// uint32_t sample_step;
// uint64_t cycle_us;
uint64_t sample_offset;
uint8_t sample_factor;
// uint64_t sample_offset;
// uint8_t sample_factor;
bool autoinit;
bool dma_enabled;
@@ -95,15 +95,17 @@ typedef struct sbdsp_t {
volatile bool dsp_busy;
uint8_t reset_state;
volatile uint8_t cur_sample;
} sbdsp_t;
sbdsp_t sbdsp;
static sbdsp_t sbdsp;
void sbdsp_process(void);
uint32_t DSP_DMA_Event(Bitu val);
#if 0
uint16_t sbdsp_fifo_level() {
if(sbdsp.dma_buffer_tail < sbdsp.dma_buffer_head) return DSP_DMA_FIFO_SIZE - (sbdsp.dma_buffer_head - sbdsp.dma_buffer_tail);
return sbdsp.dma_buffer_tail - sbdsp.dma_buffer_head;
@@ -140,15 +142,16 @@ uint16_t sbdsp_fifo_tx(char *buffer,uint16_t len) {
}
return 0;
}
#endif
void sbdsp_dma_disable() {
static __force_inline void sbdsp_dma_disable() {
sbdsp.dma_enabled=false;
PIC_RemoveEvents(DSP_DMA_Event);
}
void sbdsp_dma_enable() {
static __force_inline void sbdsp_dma_enable() {
if(!sbdsp.dma_enabled) {
sbdsp_fifo_clear();
// sbdsp_fifo_clear();
sbdsp.dma_enabled=true;
if(sbdsp.dma_pause_duration) {
PIC_AddEvent(DSP_DMA_Event,sbdsp.dma_interval * sbdsp.dma_pause_duration,1);
@@ -192,16 +195,14 @@ uint32_t DSP_DMA_Event(Bitu val) {
return 0;
}
static volatile uint8_t cur_sample; // TODO move to sbdsp struct
void sbdsp_dma_isr(void) {
static void sbdsp_dma_isr(void) {
const uint32_t dma_data = DMA_Complete_Write(&dma_config);
uint16_t current_interval;
cur_sample = dma_data & 0xFF;
sbdsp.cur_sample = dma_data & 0xFF;
}
int16_t sbdsp_sample() {
return (sbdsp.dma_enabled || sbdsp.current_command == DSP_DIRECT_DAC) ? (int16_t)(cur_sample)-0x80 << 4 : 0;
return (sbdsp.dma_enabled || sbdsp.current_command == DSP_DIRECT_DAC) ? (int16_t)(sbdsp.cur_sample)-0x80 << 5 : 0;
}
void sbdsp_init() {
@@ -215,7 +216,7 @@ void sbdsp_init() {
}
void sbdsp_output(uint8_t value) {
static __force_inline void sbdsp_output(uint8_t value) {
sbdsp.outbox=value;
sbdsp.dav_pc=1;
}
@@ -370,7 +371,7 @@ void sbdsp_process(void) {
case DSP_DIRECT_DAC:
if(sbdsp.dav_dsp) {
if(sbdsp.current_command_index==1) {
cur_sample=sbdsp.inbox;
sbdsp.cur_sample=sbdsp.inbox;
sbdsp.dav_dsp=0;
sbdsp.current_command=0;
}
@@ -428,13 +429,13 @@ void sbdsp_process(void) {
}
sbdsp.dsp_busy=0;
}
void sbdsp_reset(uint8_t value) {
static __force_inline void sbdsp_reset(uint8_t value) {
//TODO: COLDBOOT ? WARMBOOT ?
value &= 1; // Some games may write unknown data for bits other than the LSB.
switch(value) {
case 1:
sbdsp.autoinit=0;
sbdsp.dma_enabled=false;
sbdsp_dma_disable();
sbdsp.reset_state=1;
break;
case 0: