mirror of
https://github.com/polpo/picogus.git
synced 2026-10-25 21:40:16 +00:00
Config OPL wait; allow WT volume; inline in sbdsp
This commit is contained in:
1 parent
92cb2408a4
commit
4e6017b36e
3 files changed
+58
-35
No files matched your search
+19
-8
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user