Merge branch 'master' of https://github.com/86Box/86Box into qt
This commit is contained in:
@@ -9,9 +9,11 @@
|
|||||||
#include <86box/dma.h>
|
#include <86box/dma.h>
|
||||||
#include <86box/pic.h>
|
#include <86box/pic.h>
|
||||||
#include <86box/device.h>
|
#include <86box/device.h>
|
||||||
|
#include <86box/gameport.h>
|
||||||
#include <86box/nvr.h>
|
#include <86box/nvr.h>
|
||||||
#include <86box/sound.h>
|
#include <86box/sound.h>
|
||||||
#include <86box/filters.h>
|
#include <86box/filters.h>
|
||||||
|
#include <86box/midi.h>
|
||||||
#include <86box/snd_opl.h>
|
#include <86box/snd_opl.h>
|
||||||
#include <86box/snd_ym7128.h>
|
#include <86box/snd_ym7128.h>
|
||||||
|
|
||||||
@@ -38,6 +40,10 @@ typedef struct adgold_t
|
|||||||
int adgold_mma_intpos[2];
|
int adgold_mma_intpos[2];
|
||||||
|
|
||||||
pc_timer_t adgold_mma_timer_count;
|
pc_timer_t adgold_mma_timer_count;
|
||||||
|
|
||||||
|
uint8_t adgold_midi_ctrl, midi_queue[16];
|
||||||
|
int midi_r, midi_w;
|
||||||
|
int uart_in, uart_out, sysex;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -61,7 +67,9 @@ typedef struct adgold_t
|
|||||||
int16_t mma_buffer[2][SOUNDBUFLEN];
|
int16_t mma_buffer[2][SOUNDBUFLEN];
|
||||||
|
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
|
int gameport_enabled;
|
||||||
|
|
||||||
int surround_enabled;
|
int surround_enabled;
|
||||||
} adgold_t;
|
} adgold_t;
|
||||||
|
|
||||||
@@ -134,12 +142,15 @@ void adgold_update_irq_status(adgold_t *adgold)
|
|||||||
uint8_t temp = 0xf;
|
uint8_t temp = 0xf;
|
||||||
|
|
||||||
if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/
|
if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/
|
||||||
temp &= ~2;
|
temp &= ~2;
|
||||||
if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/
|
if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/
|
||||||
temp &= ~2;
|
temp &= ~2;
|
||||||
if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/
|
if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/
|
||||||
temp &= ~2;
|
temp &= ~2;
|
||||||
|
if (!(adgold->adgold_mma_regs[0][0xd] & 0x01) && (adgold->adgold_mma_status & 0x04))
|
||||||
|
temp &= ~2;
|
||||||
|
if (!(adgold->adgold_mma_regs[0][0xd] & 0x04) && (adgold->adgold_mma_status & 0x08))
|
||||||
|
temp &= ~2;
|
||||||
if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2))
|
if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2))
|
||||||
temp &= ~2;
|
temp &= ~2;
|
||||||
if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2))
|
if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2))
|
||||||
@@ -253,7 +264,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
case 0x18: /*Surround*/
|
case 0x18: /*Surround*/
|
||||||
adgold->adgold_38x_regs[0x18] = val;
|
adgold->adgold_38x_regs[0x18] = val;
|
||||||
ym7128_write(&adgold->ym7128, val);
|
ym7128_write(&adgold->ym7128, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val;
|
adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val;
|
||||||
@@ -380,6 +391,26 @@ void adgold_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
case 0xc:
|
case 0xc:
|
||||||
adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8;
|
adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xd:
|
||||||
|
adgold->adgold_midi_ctrl = val & 0x3f;
|
||||||
|
|
||||||
|
if ((val & 0x0f) == 0x0f) {
|
||||||
|
adgold->uart_in = 0;
|
||||||
|
adgold->midi_w = 0;
|
||||||
|
adgold->midi_r = 0;
|
||||||
|
adgold->adgold_mma_status &= ~0x0c;
|
||||||
|
} else if (adgold->adgold_midi_ctrl & 0x05) {
|
||||||
|
adgold->uart_in = 1;
|
||||||
|
} else
|
||||||
|
adgold->uart_in = 0;
|
||||||
|
|
||||||
|
adgold_update_irq_status(adgold);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xe:
|
||||||
|
midi_raw_out_byte(val);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val;
|
adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val;
|
||||||
break;
|
break;
|
||||||
@@ -482,7 +513,7 @@ uint8_t adgold_read(uint16_t addr, void *p)
|
|||||||
|
|
||||||
case 4: case 6:
|
case 4: case 6:
|
||||||
temp = adgold->adgold_mma_status;
|
temp = adgold->adgold_mma_status;
|
||||||
adgold->adgold_mma_status = 0; /*JUKEGOLD expects timer status flags to auto-clear*/
|
adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/
|
||||||
adgold_update_irq_status(adgold);
|
adgold_update_irq_status(adgold);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
@@ -491,12 +522,26 @@ uint8_t adgold_read(uint16_t addr, void *p)
|
|||||||
{
|
{
|
||||||
case 6: /*Timer 2 low*/
|
case 6: /*Timer 2 low*/
|
||||||
adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count;
|
adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count;
|
||||||
|
adgold->adgold_mma_status |= 0x40;
|
||||||
temp = adgold->adgold_mma.timer2_read & 0xff;
|
temp = adgold->adgold_mma.timer2_read & 0xff;
|
||||||
break;
|
break;
|
||||||
case 7: /*Timer 2 high*/
|
case 7: /*Timer 2 high*/
|
||||||
temp = adgold->adgold_mma.timer2_read >> 8;
|
temp = adgold->adgold_mma.timer2_read >> 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xe:
|
||||||
|
temp = 0;
|
||||||
|
if (adgold->uart_in) {
|
||||||
|
temp = adgold->midi_queue[adgold->midi_r];
|
||||||
|
if (adgold->midi_r != adgold->midi_w) {
|
||||||
|
adgold->midi_r++;
|
||||||
|
adgold->midi_r &= 0x0f;
|
||||||
|
}
|
||||||
|
adgold->adgold_mma_status &= ~0x04;
|
||||||
|
adgold_update_irq_status(adgold);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr];
|
temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr];
|
||||||
break;
|
break;
|
||||||
@@ -579,6 +624,19 @@ void adgold_timer_poll(void *p)
|
|||||||
adgold_t *adgold = (adgold_t *)p;
|
adgold_t *adgold = (adgold_t *)p;
|
||||||
|
|
||||||
timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t)((double)TIMER_USEC * 1.88964));
|
timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t)((double)TIMER_USEC * 1.88964));
|
||||||
|
|
||||||
|
if (adgold->adgold_midi_ctrl & 0x0f) {
|
||||||
|
if ((adgold->adgold_midi_ctrl & 0x0f) == 0x05) {
|
||||||
|
adgold->adgold_mma_status |= 0x08;
|
||||||
|
} else {
|
||||||
|
if ((adgold->adgold_midi_ctrl & 0x0f) == 0x02)
|
||||||
|
adgold->adgold_mma_status &= ~0x04;
|
||||||
|
else if ((adgold->adgold_midi_ctrl & 0x0f) == 0x08)
|
||||||
|
adgold->adgold_mma_status &= ~0x08;
|
||||||
|
}
|
||||||
|
adgold_update_irq_status(adgold);
|
||||||
|
}
|
||||||
|
|
||||||
if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/
|
if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/
|
||||||
{
|
{
|
||||||
adgold->adgold_mma.timer0_count--;
|
adgold->adgold_mma.timer0_count--;
|
||||||
@@ -753,6 +811,47 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len)
|
||||||
|
{
|
||||||
|
adgold_t *adgold = (adgold_t *)p;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if (adgold->sysex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (adgold->uart_in) {
|
||||||
|
adgold->adgold_mma_status |= 0x04;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++) {
|
||||||
|
adgold->midi_queue[adgold->midi_w++] = msg[i];
|
||||||
|
adgold->midi_w &= 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
adgold_update_irq_status(adgold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||||
|
{
|
||||||
|
adgold_t *adgold = (adgold_t *)p;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (abort) {
|
||||||
|
adgold->sysex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
adgold->sysex = 1;
|
||||||
|
for (i=0;i<len;i++) {
|
||||||
|
if (adgold->midi_r == adgold->midi_w)
|
||||||
|
return (len-i);
|
||||||
|
adgold->midi_queue[adgold->midi_w++] = buffer[i];
|
||||||
|
adgold->midi_w &= 0x0f;
|
||||||
|
}
|
||||||
|
adgold->sysex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *adgold_init(const device_t *info)
|
void *adgold_init(const device_t *info)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -762,6 +861,8 @@ void *adgold_init(const device_t *info)
|
|||||||
memset(adgold, 0, sizeof(adgold_t));
|
memset(adgold, 0, sizeof(adgold_t));
|
||||||
|
|
||||||
adgold->surround_enabled = device_get_config_int("surround");
|
adgold->surround_enabled = device_get_config_int("surround");
|
||||||
|
|
||||||
|
adgold->gameport_enabled = device_get_config_int("gameport");
|
||||||
|
|
||||||
opl3_init(&adgold->opl);
|
opl3_init(&adgold->opl);
|
||||||
if (adgold->surround_enabled)
|
if (adgold->surround_enabled)
|
||||||
@@ -805,10 +906,16 @@ void *adgold_init(const device_t *info)
|
|||||||
/*388/389 are handled by adlib_init*/
|
/*388/389 are handled by adlib_init*/
|
||||||
io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold);
|
io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold);
|
||||||
|
|
||||||
|
if (adgold->gameport_enabled)
|
||||||
|
gameport_remap(gameport_add(&gameport_201_device), 0x201);
|
||||||
|
|
||||||
timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1);
|
timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1);
|
||||||
|
|
||||||
sound_add_handler(adgold_get_buffer, adgold);
|
sound_add_handler(adgold_get_buffer, adgold);
|
||||||
|
|
||||||
|
if (device_get_config_int("receive_input"))
|
||||||
|
midi_in_handler(1, adgold_input_msg, adgold_input_sysex, adgold);
|
||||||
|
|
||||||
return adgold;
|
return adgold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,9 +936,15 @@ void adgold_close(void *p)
|
|||||||
|
|
||||||
static const device_config_t adgold_config[] =
|
static const device_config_t adgold_config[] =
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
"gameport", "Enable Game port", CONFIG_BINARY, "", 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"surround", "Surround module", CONFIG_BINARY, "", 1
|
"surround", "Surround module", CONFIG_BINARY, "", 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"", "", -1
|
"", "", -1
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,10 @@ typedef struct {
|
|||||||
uint8_t uart_ctrl, uart_status,
|
uint8_t uart_ctrl, uart_status,
|
||||||
uart_res;
|
uart_res;
|
||||||
uint32_t uart_fifo;
|
uint32_t uart_fifo;
|
||||||
|
|
||||||
|
uint8_t midi_queue[64], midi_data;
|
||||||
|
int midi_r, midi_w;
|
||||||
|
int uart_in, sysex, valid;
|
||||||
|
|
||||||
ac97_codec_t * codec;
|
ac97_codec_t * codec;
|
||||||
uint32_t codec_ctrl;
|
uint32_t codec_ctrl;
|
||||||
@@ -174,7 +178,6 @@ typedef struct {
|
|||||||
static void es1371_fetch(es1371_t *dev, int dac_nr);
|
static void es1371_fetch(es1371_t *dev, int dac_nr);
|
||||||
static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl);
|
static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_AUDIOPCI_LOG
|
#ifdef ENABLE_AUDIOPCI_LOG
|
||||||
int audiopci_do_log = ENABLE_AUDIOPCI_LOG;
|
int audiopci_do_log = ENABLE_AUDIOPCI_LOG;
|
||||||
|
|
||||||
@@ -201,14 +204,19 @@ es1371_update_irqs(es1371_t *dev)
|
|||||||
int irq = 0;
|
int irq = 0;
|
||||||
|
|
||||||
if ((dev->int_status & INT_STATUS_DAC1) && (dev->si_cr & SI_P1_INTR_EN))
|
if ((dev->int_status & INT_STATUS_DAC1) && (dev->si_cr & SI_P1_INTR_EN))
|
||||||
irq = 1;
|
irq = 1;
|
||||||
if ((dev->int_status & INT_STATUS_DAC2) && (dev->si_cr & SI_P2_INTR_EN))
|
if ((dev->int_status & INT_STATUS_DAC2) && (dev->si_cr & SI_P2_INTR_EN))
|
||||||
irq = 1;
|
irq = 1;
|
||||||
|
|
||||||
/* MIDI input is unsupported for now */
|
if (dev->int_status & INT_STATUS_UART) {
|
||||||
if ((dev->int_status & INT_STATUS_UART) && (dev->uart_status & UART_STATUS_TXINT) &&
|
if (((dev->uart_ctrl & UART_CTRL_TXINTEN) != 0x20) && (dev->uart_status & UART_STATUS_TXINT) && !dev->uart_in) {
|
||||||
((dev->uart_ctrl & UART_CTRL_TXINTEN) != 0x20))
|
audiopci_log("TXINT\n");
|
||||||
irq = 1;
|
irq = 1;
|
||||||
|
} else if ((dev->uart_ctrl & UART_CTRL_RXINTEN) && (dev->uart_status & UART_STATUS_RXINT) && (dev->uart_in)) {
|
||||||
|
audiopci_log("RXINT\n");
|
||||||
|
irq = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (irq)
|
if (irq)
|
||||||
dev->int_status |= INT_STATUS_INTR;
|
dev->int_status |= INT_STATUS_INTR;
|
||||||
@@ -230,6 +238,11 @@ es1371_reset(void *p)
|
|||||||
{
|
{
|
||||||
es1371_t *dev = (es1371_t *) p;
|
es1371_t *dev = (es1371_t *) p;
|
||||||
|
|
||||||
|
dev->uart_in = 0;
|
||||||
|
dev->midi_r = 0;
|
||||||
|
dev->midi_w = 0;
|
||||||
|
dev->valid = 0;
|
||||||
|
|
||||||
nmi = 0;
|
nmi = 0;
|
||||||
|
|
||||||
/* Interrupt/Chip Select Control Register, Address 00H
|
/* Interrupt/Chip Select Control Register, Address 00H
|
||||||
@@ -344,7 +357,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page)
|
|||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe: case 0xf:
|
||||||
ret = dev->uart_fifo;
|
ret = dev->midi_data;
|
||||||
|
if (dev->valid) {
|
||||||
|
ret |= 0x100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -363,7 +379,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page)
|
|||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe: case 0xf:
|
||||||
ret = dev->uart_fifo;
|
ret = dev->midi_data;
|
||||||
|
if (dev->valid) {
|
||||||
|
ret |= 0x100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -377,7 +396,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page)
|
|||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe: case 0xf:
|
||||||
ret = dev->uart_fifo;
|
ret = dev->midi_data;
|
||||||
|
if (dev->valid) {
|
||||||
|
ret |= 0x100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -391,12 +413,19 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page)
|
|||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe: case 0xf:
|
||||||
ret = dev->uart_fifo;
|
ret = dev->midi_data;
|
||||||
|
if (dev->valid) {
|
||||||
|
ret |= 0x100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (page == 0x0e || page == 0x0f) {
|
||||||
|
audiopci_log("Read frame = %02x, page = %02x, uart fifo valid = %02x, temp = %03x\n", frame, page, dev->valid, ret);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +448,8 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val)
|
|||||||
break;
|
break;
|
||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe:
|
||||||
|
case 0xf:
|
||||||
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -440,7 +470,8 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val)
|
|||||||
break;
|
break;
|
||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe:
|
||||||
|
case 0xf:
|
||||||
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -454,7 +485,8 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val)
|
|||||||
break;
|
break;
|
||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe:
|
||||||
|
case 0xf:
|
||||||
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -469,12 +501,18 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val)
|
|||||||
break;
|
break;
|
||||||
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
/* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b
|
||||||
Addressable as longword only */
|
Addressable as longword only */
|
||||||
case 0xe: case 0xf:
|
case 0xe:
|
||||||
|
case 0xf:
|
||||||
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (page == 0x0e || page == 0x0f) {
|
||||||
|
audiopci_log("Write frame = %02x, page = %02x, uart fifo = %08x, val = %02x\n", frame, page, dev->uart_fifo, val);
|
||||||
|
dev->valid = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -520,6 +558,19 @@ es1371_inb(uint16_t port, void *p)
|
|||||||
Addressable as byte only */
|
Addressable as byte only */
|
||||||
case 0x08:
|
case 0x08:
|
||||||
ret = 0x00;
|
ret = 0x00;
|
||||||
|
if (dev->uart_in) {
|
||||||
|
ret = dev->midi_queue[dev->midi_r];
|
||||||
|
if (dev->midi_r != dev->midi_w) {
|
||||||
|
dev->midi_r++;
|
||||||
|
dev->midi_r &= 0x3f;
|
||||||
|
}
|
||||||
|
dev->midi_data = ret;
|
||||||
|
audiopci_log("MIDI input ret = %02x, pos = %i, valid = %i\n", ret, dev->midi_r, dev->valid);
|
||||||
|
if (!dev->valid)
|
||||||
|
dev->int_status &= ~INT_STATUS_UART;
|
||||||
|
dev->uart_status &= ~(UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
es1371_update_irqs(dev);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* UART Status Register, Address 09H
|
/* UART Status Register, Address 09H
|
||||||
@@ -661,6 +712,8 @@ es1371_inw(uint16_t port, void *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,6 +836,7 @@ es1371_outb(uint16_t port, uint8_t val, void *p)
|
|||||||
/* UART Data Register, Address 08H
|
/* UART Data Register, Address 08H
|
||||||
Addressable as byte only */
|
Addressable as byte only */
|
||||||
case 0x08:
|
case 0x08:
|
||||||
|
audiopci_log("MIDI data = %02x\n", dev->midi_data);
|
||||||
midi_raw_out_byte(val);
|
midi_raw_out_byte(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -790,10 +844,22 @@ es1371_outb(uint16_t port, uint8_t val, void *p)
|
|||||||
Addressable as byte only */
|
Addressable as byte only */
|
||||||
case 0x09:
|
case 0x09:
|
||||||
dev->uart_ctrl = val & 0xe3;
|
dev->uart_ctrl = val & 0xe3;
|
||||||
if ((dev->uart_ctrl & UART_CTRL_TXINTEN) != 0x20)
|
|
||||||
|
if ((val & 0x03) == 0x03) { /*Software reset*/
|
||||||
|
dev->uart_in = 0;
|
||||||
|
dev->uart_status = 0x00;
|
||||||
|
dev->midi_r = 0;
|
||||||
|
dev->midi_w = 0;
|
||||||
|
dev->valid = 0;
|
||||||
|
} else if (dev->uart_ctrl & UART_CTRL_RXINTEN) {
|
||||||
|
dev->uart_in = 1;
|
||||||
|
audiopci_log("ES1371 UART RX Cntrl = %02x\n", dev->uart_ctrl);
|
||||||
|
} else if ((dev->uart_ctrl & UART_CTRL_TXINTEN) != 0x20) {
|
||||||
dev->int_status &= ~INT_STATUS_UART;
|
dev->int_status &= ~INT_STATUS_UART;
|
||||||
|
dev->uart_in = 0;
|
||||||
|
}
|
||||||
|
|
||||||
es1371_update_irqs(dev);
|
es1371_update_irqs(dev);
|
||||||
audiopci_log("ES1371 UART Cntrl = %02x\n", dev->uart_ctrl);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* UART Reserved Register, Address 0AH
|
/* UART Reserved Register, Address 0AH
|
||||||
@@ -1708,19 +1774,32 @@ es1371_poll(void *p)
|
|||||||
|
|
||||||
if (dev->int_ctrl & INT_UART_EN) {
|
if (dev->int_ctrl & INT_UART_EN) {
|
||||||
//audiopci_log("UART INT Enabled\n");
|
//audiopci_log("UART INT Enabled\n");
|
||||||
if (dev->uart_ctrl & UART_CTRL_RXINTEN) {
|
if (((dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN)) == UART_CTRL_RXINTEN) && dev->uart_in) {
|
||||||
/* We currently don't implement MIDI Input.
|
audiopci_log("RX irq\n");
|
||||||
But if anything sets MIDI Input and Output together we'd have to take account
|
|
||||||
of the MIDI Output case, and disable IRQ's and RX bits when MIDI Input is
|
|
||||||
enabled as well but not in the MIDI Output portion */
|
|
||||||
dev->int_status &= ~INT_STATUS_UART;
|
|
||||||
dev->uart_status |= (UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
|
||||||
} else if (!(dev->uart_ctrl & UART_CTRL_RXINTEN) && ((dev->uart_ctrl & UART_CTRL_TXINTEN))) {
|
|
||||||
/* Or enable the UART IRQ and the respective TX bits only when the MIDI Output is
|
|
||||||
enabled */
|
|
||||||
dev->int_status |= INT_STATUS_UART;
|
dev->int_status |= INT_STATUS_UART;
|
||||||
|
} else if (((dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN)) == UART_CTRL_TXINTEN) && !dev->uart_in) {
|
||||||
|
audiopci_log("TX irq\n");
|
||||||
|
dev->int_status |= INT_STATUS_UART;
|
||||||
|
} else if ((dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN)) == (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN)) {
|
||||||
|
dev->int_status &= ~INT_STATUS_UART;
|
||||||
|
if (dev->uart_in) {
|
||||||
|
audiopci_log("No Status UART RX\n");
|
||||||
|
dev->uart_status |= (UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
dev->uart_status &= ~(UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
||||||
|
} else {
|
||||||
|
audiopci_log("No Status UART TX\n");
|
||||||
|
dev->uart_status &= ~(UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
dev->uart_status |= (UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dev->uart_status |= (UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
audiopci_log("STAT UART IN = %i\n", dev->uart_in);
|
||||||
|
if (dev->uart_in) {
|
||||||
|
dev->uart_status |= (UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
dev->uart_status &= ~(UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
||||||
|
} else {
|
||||||
|
dev->uart_status &= ~(UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
dev->uart_status |= (UART_STATUS_TXINT | UART_STATUS_TXRDY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//audiopci_log("UART control = %02x\n", dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN));
|
//audiopci_log("UART control = %02x\n", dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN));
|
||||||
@@ -1846,12 +1925,63 @@ generate_es1371_filter(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
es1371_input_msg(void *p, uint8_t *msg, uint32_t len)
|
||||||
|
{
|
||||||
|
es1371_t *dev = (es1371_t *)p;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
audiopci_log("SYSEX on MSG = %i, len = %i, midiw = %i\n", dev->sysex, len, dev->midi_w);
|
||||||
|
|
||||||
|
if (dev->sysex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dev->uart_in) {
|
||||||
|
audiopci_log("RX midi data\n");
|
||||||
|
dev->uart_status |= (UART_STATUS_RXINT | UART_STATUS_RXRDY);
|
||||||
|
dev->valid = 1;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++) {
|
||||||
|
dev->midi_queue[dev->midi_w++] = msg[i];
|
||||||
|
dev->midi_w &= 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
es1371_update_irqs(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
es1371_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||||
|
{
|
||||||
|
es1371_t *dev = (es1371_t *)p;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
audiopci_log("SYSEX = %i, Abort = %i\n", dev->sysex, abort);
|
||||||
|
|
||||||
|
if (abort) {
|
||||||
|
dev->sysex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dev->sysex = 1;
|
||||||
|
for (i=0;i<len;i++) {
|
||||||
|
if (dev->midi_r == dev->midi_w)
|
||||||
|
return (len-i);
|
||||||
|
dev->midi_queue[dev->midi_w++] = buffer[i];
|
||||||
|
dev->midi_w &= 0x3f;
|
||||||
|
}
|
||||||
|
dev->sysex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
es1371_init(const device_t *info)
|
es1371_init(const device_t *info)
|
||||||
{
|
{
|
||||||
es1371_t *dev = malloc(sizeof(es1371_t));
|
es1371_t *dev = malloc(sizeof(es1371_t));
|
||||||
memset(dev, 0x00, sizeof(es1371_t));
|
memset(dev, 0x00, sizeof(es1371_t));
|
||||||
|
|
||||||
|
if (device_get_config_int("receive_input"))
|
||||||
|
midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev);
|
||||||
|
|
||||||
sound_add_handler(es1371_get_buffer, dev);
|
sound_add_handler(es1371_get_buffer, dev);
|
||||||
sound_set_cd_audio_filter(es1371_filter_cd_audio, dev);
|
sound_set_cd_audio_filter(es1371_filter_cd_audio, dev);
|
||||||
|
|
||||||
@@ -1920,7 +2050,11 @@ static const device_config_t es1371_config[] =
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.default_int = AC97_CODEC_CS4297A
|
.default_int = AC97_CODEC_CS4297A
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
|
"receive_input", "Receive input (MIDI)", CONFIG_BINARY, "", 1
|
||||||
|
},
|
||||||
|
{
|
||||||
"", "", -1
|
"", "", -1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -872,6 +872,8 @@ static void opengl_main(void* param)
|
|||||||
|
|
||||||
static void opengl_blit(int x, int y, int w, int h)
|
static void opengl_blit(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
|
int row;
|
||||||
|
|
||||||
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (thread == NULL) ||
|
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (thread == NULL) ||
|
||||||
atomic_flag_test_and_set(&blit_info[write_pos].in_use))
|
atomic_flag_test_and_set(&blit_info[write_pos].in_use))
|
||||||
{
|
{
|
||||||
@@ -879,7 +881,8 @@ static void opengl_blit(int x, int y, int w, int h)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_copy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t));
|
for (row = 0; row < h; ++row)
|
||||||
|
video_copy(&(((uint8_t *) blit_info[write_pos].buffer)[row * ROW_LENGTH * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t));
|
||||||
|
|
||||||
if (screenshots)
|
if (screenshots)
|
||||||
video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH);
|
video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH);
|
||||||
|
@@ -274,6 +274,7 @@ sdl_blit_ex(int x, int y, int w, int h)
|
|||||||
SDL_Rect r_src;
|
SDL_Rect r_src;
|
||||||
void *pixeldata;
|
void *pixeldata;
|
||||||
int pitch, ret;
|
int pitch, ret;
|
||||||
|
int row;
|
||||||
|
|
||||||
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
|
if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) {
|
||||||
video_blit_complete();
|
video_blit_complete();
|
||||||
@@ -284,7 +285,8 @@ sdl_blit_ex(int x, int y, int w, int h)
|
|||||||
|
|
||||||
SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
|
SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch);
|
||||||
|
|
||||||
video_copy(pixeldata, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t));
|
for (row = 0; row < h; ++row)
|
||||||
|
video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t));
|
||||||
|
|
||||||
if (screenshots)
|
if (screenshots)
|
||||||
video_screenshot((uint32_t *) pixeldata, 0, 0, 2048);
|
video_screenshot((uint32_t *) pixeldata, 0, 0, 2048);
|
||||||
|
Reference in New Issue
Block a user