Use command buffer for OPL

This commit is contained in:
Ian Scott committed 2024-03-25 23:53:07 -06:00
1 parent f3b9edae57
commit 3e3017169e
3 files changed
+57 -19

No files matched your search

+4 -4
View File
@@ -7,12 +7,12 @@ typedef struct cms_buffer_t {
uint16_t addr;
uint8_t data;
} cmds[256];
uint8_t head;
uint8_t tail;
volatile uint8_t head;
volatile uint8_t tail;
} cms_buffer_t;
typedef struct tandy_buffer_t {
uint8_t cmds[256];
uint8_t head;
uint8_t tail;
volatile uint8_t head;
volatile uint8_t tail;
} tandy_buffer_t;
+34 -15
View File
@@ -49,8 +49,9 @@ static uint16_t sb_port_test = basePort >> 4;
void play_adlib(void);
extern "C" int OPL_Pico_Init(unsigned int);
extern "C" void OPL_Pico_PortWrite(opl_port_t, unsigned int);
extern "C" unsigned int OPL_Pico_PortRead(opl_port_t);
#include "cmd_buffers.h"
cms_buffer_t opl_buffer = { {0}, 0, 0 };
extern void sbdsp_write(uint8_t address, uint8_t value);
extern uint8_t sbdsp_read(uint8_t address);
@@ -249,8 +250,6 @@ __force_inline uint8_t read_picogus_high(void) {
case 0x03: // Mode (GUS, OPL, MPU, etc...)
#if defined(SOUND_GUS)
return GUS_MODE;
#elif defined(SOUND_OPL)
return ADLIB_MODE;
#elif defined(SOUND_MPU)
return MPU_MODE;
#elif defined(SOUND_TANDY)
@@ -343,13 +342,22 @@ __force_inline void handle_iow(void) {
case 0x8:
// Fast write
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
OPL_Pico_PortWrite(OPL_REGISTER_PORT, iow_read & 0xFF);
opl_buffer.cmds[opl_buffer.head++] = {
OPL_REGISTER_PORT,
(uint8_t)(iow_read & 0xFF)
};
// Fast write - return early as we've already written 0x0u to the PIO
return;
break;
case 0x9:
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
OPL_Pico_PortWrite(OPL_DATA_PORT, iow_read & 0xFF);
// Fast write
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
opl_buffer.cmds[opl_buffer.head++] = {
OPL_DATA_PORT,
(uint8_t)(iow_read & 0xFF)
};
// Fast write - return early as we've already written 0x0u to the PIO
return;
break;
// DSP ports
default:
@@ -359,21 +367,24 @@ __force_inline void handle_iow(void) {
sbdsp_process();
break;
}
#ifndef PICOW
gpio_xor_mask(LED_PIN);
#endif
} else if (port == adlib_basePort) {
// Fast write
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
OPL_Pico_PortWrite(OPL_REGISTER_PORT, iow_read & 0xFF);
opl_buffer.cmds[opl_buffer.head++] = {
OPL_REGISTER_PORT,
(uint8_t)(iow_read & 0xFF)
};
// Fast write - return early as we've already written 0x0u to the PIO
return;
} else if (port == adlib_basePort + 1) {
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
OPL_Pico_PortWrite(OPL_DATA_PORT, iow_read & 0xFF);
#ifndef PICOW
gpio_xor_mask(LED_PIN);
#endif
// Fast write
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
opl_buffer.cmds[opl_buffer.head++] = {
OPL_DATA_PORT,
(uint8_t)(iow_read & 0xFF)
};
// Fast write - return early as we've already written 0x0u to the PIO
return;
} else // if follows down below
#endif // SOUND_SB
#ifdef SOUND_MPU
@@ -493,6 +504,10 @@ __force_inline void handle_ior(void) {
if ((port >> 4) == sb_port_test) {
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
if (port - basePort == 0x8) {
// wait for OPL buffer to process
while (opl_buffer.tail != opl_buffer.head) {
tight_loop_contents();
}
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | OPL_Pico_PortRead(OPL_REGISTER_PORT));
} else {
sbdsp_process();
@@ -502,6 +517,10 @@ __force_inline void handle_ior(void) {
} else if (port == adlib_basePort) {
// Tell PIO to wait for data
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
// wait for OPL buffer to process
while (opl_buffer.tail != opl_buffer.head) {
tight_loop_contents();
}
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | OPL_Pico_PortRead(OPL_REGISTER_PORT));
} else // if follows down below
#elif defined(SOUND_MPU)
+19
View File
@@ -20,15 +20,21 @@
#include "opl.h"
extern "C" void OPL_Pico_simple(int16_t *buffer, uint32_t nsamples);
extern "C" void OPL_Pico_PortWrite(opl_port_t, unsigned int);
extern int16_t sbdsp_sample();
#include "clamp.h"
#include "cmd_buffers.h"
extern cms_buffer_t opl_buffer;
#ifdef USB_JOYSTICK
#include "tusb.h"
#endif
extern uint LED_PIN;
#ifdef USE_ALARM
#include "pico_pic.h"
#endif
@@ -101,6 +107,19 @@ void play_adlib() {
struct audio_buffer_pool *ap = init_audio();
for (;;) {
bool notfirst = false;
while (opl_buffer.tail != opl_buffer.head) {
if (!notfirst) {
#ifndef PICOW
gpio_xor_mask(LED_PIN);
#endif
notfirst = true;
}
auto cmd = opl_buffer.cmds[opl_buffer.tail];
OPL_Pico_PortWrite((opl_port_t)cmd.addr, cmd.data);
// putchar('.');
++opl_buffer.tail;
}
struct audio_buffer *buffer = take_audio_buffer(ap, true);
int16_t *samples = (int16_t *) buffer->buffer->bytes;
int16_t opl_sample;