diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index bcdca3283..9fce3cde9 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -60,6 +60,7 @@ typedef struct adgold_t int fm_vol_l, fm_vol_r; int samp_vol_l, samp_vol_r; + int aux_vol_l, aux_vol_r; int vol_l, vol_r; int aux_vol_l, aux_vol_r; int treble, bass; @@ -528,9 +529,9 @@ uint8_t adgold_read(uint16_t addr, void *p) { case 0x00: /*Control/ID*/ if (adgold->surround_enabled) - temp = 0x51; /*16-bit ISA, surround module, no telephone/CDROM*/ + temp = 0x51; /*8-bit ISA, surround module, no telephone/CD-ROM*/ else - temp = 0x71; /*16-bit ISA, no telephone/surround/CD-ROM*/ + temp = 0x71; /*8-bit ISA, no telephone/surround/CD-ROM*/ break; default: @@ -838,6 +839,18 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p) free(adgold_buffer); } +static void +adgold_filter_cd_audio(int channel, double *buffer, void *p) +{ + adgold_t *adgold = (adgold_t *)p; + double c; + int aux = channel ? adgold->aux_vol_r : adgold->aux_vol_l; + int vol = channel ? adgold->vol_r : adgold->vol_l; + + c = ((((*buffer) * aux) / 4096.0) * vol) / 4096.0; + *buffer = c; +} + static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len) { @@ -937,8 +950,8 @@ void *adgold_init(const device_t *info) adgold->fm_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0a] - 128); adgold->samp_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0b] - 128); adgold->samp_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0c] - 128); - adgold->aux_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0d] - 128); - adgold->aux_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0e] - 128); + adgold->aux_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0d] - 128); + adgold->aux_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0e] - 128); adgold->adgold_mma_enable[0] = 0; adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; @@ -954,6 +967,8 @@ void *adgold_init(const device_t *info) sound_add_handler(adgold_get_buffer, adgold); sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); + sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); + if (device_get_config_int("receive_input")) midi_in_handler(1, adgold_input_msg, adgold_input_sysex, adgold); diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 444108a25..91d04a311 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -67,13 +67,10 @@ typedef struct { uint32_t sr_cir; uint16_t sr_ram[128]; - uint8_t uart_ctrl, uart_status, - uart_res; - uint32_t uart_fifo; - - uint8_t midi_queue[64], midi_data; - int midi_r, midi_w; - int uart_in, sysex, valid; + uint8_t uart_data, uart_ctrl, + uart_status, uart_res; + uint32_t uart_fifo[8]; + uint8_t read_fifo_pos, write_fifo_pos; ac97_codec_t * codec; uint32_t codec_ctrl; @@ -169,6 +166,8 @@ typedef struct { #define UART_STATUS_TXRDY (1<<1) #define UART_STATUS_RXRDY (1<<0) +#define UART_FIFO_BYTE_VALID 0x00000100 + #define FORMAT_MONO_8 0 #define FORMAT_STEREO_8 1 #define FORMAT_MONO_16 2 @@ -204,19 +203,16 @@ es1371_update_irqs(es1371_t *dev) int irq = 0; 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)) - irq = 1; + irq = 1; - if (dev->int_status & INT_STATUS_UART) { - if (((dev->uart_ctrl & UART_CTRL_TXINTEN) != 0x20) && (dev->uart_status & UART_STATUS_TXINT) && !dev->uart_in) { - audiopci_log("TXINT\n"); - 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; - } - } + dev->int_status &= ~INT_STATUS_UART; + + if ((dev->uart_status & UART_STATUS_TXINT) || (dev->uart_status & UART_STATUS_RXINT)) { + dev->int_status |= INT_STATUS_UART; + irq = 1; + } if (irq) dev->int_status |= INT_STATUS_INTR; @@ -233,15 +229,96 @@ es1371_update_irqs(es1371_t *dev) } +static void +es1371_update_tx_irq(es1371_t *dev) +{ + dev->uart_status &= ~UART_STATUS_TXINT; + + if (((dev->uart_ctrl & UART_CTRL_TXINTEN) == 0x20) && (dev->uart_status & UART_STATUS_TXRDY)) + dev->uart_status |= UART_STATUS_TXINT; + + es1371_update_irqs(dev); +} + + +static void +es1371_set_tx_irq(es1371_t *dev, int set) +{ + dev->uart_status &= ~UART_STATUS_TXRDY; + + if (set) + dev->uart_status |= UART_STATUS_TXRDY; + + es1371_update_tx_irq(dev); +} + + +static void +es1371_update_rx_irq(es1371_t *dev) +{ + dev->uart_status &= ~UART_STATUS_RXINT; + + if ((dev->uart_ctrl & UART_CTRL_RXINTEN) && (dev->uart_status & UART_STATUS_RXRDY)) + dev->uart_status |= UART_STATUS_RXINT; + + es1371_update_irqs(dev); +} + + +static void +es1371_set_rx_irq(es1371_t *dev, int set) +{ + dev->uart_status &= ~UART_STATUS_RXRDY; + + if (set) + dev->uart_status |= UART_STATUS_RXRDY; + + es1371_update_rx_irq(dev); +} + + +static void +es1371_scan_fifo(es1371_t *dev) +{ + if (dev->read_fifo_pos != dev->write_fifo_pos) { + dev->uart_data = dev->uart_fifo[dev->read_fifo_pos]; + dev->read_fifo_pos = (dev->read_fifo_pos + 1) & 7; + + es1371_set_rx_irq(dev, 1); + } else + es1371_set_rx_irq(dev, 0); +} + + +static void +es1371_write_fifo(es1371_t *dev, uint8_t val) +{ + if (dev->write_fifo_pos < 8) { + dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; + dev->write_fifo_pos = (dev->write_fifo_pos + 1) & 7; + } +} + + +static void +es1371_reset_fifo(es1371_t *dev) +{ + int i; + + for (i = 0; i < 8; i++) + dev->uart_fifo[i] = 0x00000000; + + dev->read_fifo_pos = dev->write_fifo_pos = 0; + + es1371_set_rx_irq(dev, 0); +} + + static void es1371_reset(void *p) { es1371_t *dev = (es1371_t *) p; - - dev->uart_in = 0; - dev->midi_r = 0; - dev->midi_w = 0; - dev->valid = 0; + int i; nmi = 0; @@ -329,7 +406,14 @@ es1371_reset(void *p) /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ - dev->uart_fifo = 0xfffffe00; + for (i = 0; i < 8; i++) + dev->uart_fifo[i] = 0xffff0000; + + /* Reset the UART TX. */ + es1371_set_tx_irq(dev, 0); + + /* Reset the UART (RX) FIFO. */ + es1371_reset_fifo(dev); /* Update interrupts to ensure they're all correctly cleared. */ es1371_update_irqs(dev); @@ -357,10 +441,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ case 0xe: case 0xf: - ret = dev->midi_data; - if (dev->valid) { - ret |= 0x100; - } + audiopci_log("[30:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; } break; @@ -379,10 +463,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ case 0xe: case 0xf: - ret = dev->midi_data; - if (dev->valid) { - ret |= 0x100; - } + audiopci_log("[34:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; } break; @@ -396,10 +480,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ case 0xe: case 0xf: - ret = dev->midi_data; - if (dev->valid) { - ret |= 0x100; - } + audiopci_log("[38:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; } break; @@ -413,10 +497,10 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ case 0xe: case 0xf: - ret = dev->midi_data; - if (dev->valid) { - ret |= 0x100; - } + audiopci_log("[3C:%02X] ret = dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]); + ret = dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)]; break; } break; @@ -448,9 +532,10 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) break; /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ - case 0xe: - case 0xf: - dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff); + case 0xe: case 0xf: + audiopci_log("[30:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; } break; @@ -470,9 +555,10 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) break; /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ - case 0xe: - case 0xf: - dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff); + case 0xe: case 0xf: + audiopci_log("[34:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; } break; @@ -485,9 +571,10 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) break; /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ - case 0xe: - case 0xf: - dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff); + case 0xe: case 0xf: + audiopci_log("[38:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; break; } break; @@ -501,18 +588,18 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) break; /* UART FIFO Register, Address 30H, 34H, 38H, 3CH, Memory Page 1110b, 1111b Addressable as longword only */ - case 0xe: - case 0xf: - dev->uart_fifo = (dev->uart_fifo & 0xfffffe00) | (val & 0x000001ff); + case 0xe: case 0xf: + audiopci_log("[3C:%02X] dev->uart_fifo[%02X] = %08X\n", page, + ((page & 0x01) << 2) + ((frame >> 2) & 0x03), val); + dev->uart_fifo[((page & 0x01) << 2) + ((frame >> 2) & 0x03)] = val; 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; - } + + if (page == 0x0e || page == 0x0f) { + audiopci_log("Write frame = %02x, page = %02x, uart fifo = %08x, val = %02x\n", frame, page, dev->uart_fifo, val); + } } @@ -543,34 +630,27 @@ es1371_inb(uint16_t port, void *p) must be for a reason */ case 0x04: ret = dev->int_status & 0xff; + audiopci_log("[R] STATUS 0- 7 = %02X\n", ret); break; case 0x05: ret = (dev->int_status >> 8) & 0xff; + audiopci_log("[R] STATUS 8-15 = %02X\n", ret); break; case 0x06: ret = (dev->int_status >> 16) & 0x0f; + audiopci_log("[R] STATUS 16-23 = %02X\n", ret); break; case 0x07: ret = ((dev->int_status >> 24) & 0x03) | 0xfc; + audiopci_log("[R] STATUS 24-31 = %02X\n", ret); break; /* UART Data Register, Address 08H Addressable as byte only */ case 0x08: - 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); - } + ret = dev->uart_data; + es1371_set_rx_irq(dev, 0); + audiopci_log("[R] UART DATA = %02X\n", ret); break; /* UART Status Register, Address 09H @@ -584,6 +664,7 @@ es1371_inb(uint16_t port, void *p) Addressable as byte only */ case 0x0a: ret = dev->uart_res & 0x01; + audiopci_log("[R] UART RES = %02X\n", ret); break; /* Memory Page Register, Address 0CH @@ -735,6 +816,7 @@ es1371_inl(uint16_t port, void *p) Addressable as longword only */ case 0x04: ret = dev->int_status; + audiopci_log("[R] STATUS = %08X\n", ret); break; /* Memory Page Register, Address 0CH @@ -836,35 +918,36 @@ es1371_outb(uint16_t port, uint8_t val, void *p) /* UART Data Register, Address 08H Addressable as byte only */ case 0x08: - audiopci_log("MIDI data = %02x\n", dev->midi_data); + audiopci_log("MIDI data = %02x\n", val); + /* TX does not use FIFO. */ midi_raw_out_byte(val); + es1371_set_tx_irq(dev, 1); break; /* UART Control Register, Address 09H Addressable as byte only */ case 0x09: + audiopci_log("[W] UART CTRL = %02X\n", val); dev->uart_ctrl = val & 0xe3; - 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->uart_in = 0; + if ((val & 0x03) == 0x03) { + /* Reset TX */ + es1371_set_tx_irq(dev, 1); + + /* Software reset */ + es1371_reset_fifo(dev); + } else { + es1371_set_tx_irq(dev, 1); + + es1371_update_tx_irq(dev); + es1371_update_rx_irq(dev); } - - es1371_update_irqs(dev); break; /* UART Reserved Register, Address 0AH Addressable as byte only */ case 0x0a: + audiopci_log("[W] UART RES = %02X\n", val); dev->uart_res = val & 0x01; break; @@ -1031,6 +1114,7 @@ es1371_outl(uint16_t port, uint32_t val, void *p) /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ case 0x04: + audiopci_log("[W] STATUS = %08X\n", val); break; /* Memory Page Register, Address 0CH @@ -1770,42 +1854,10 @@ es1371_poll(void *p) timer_advance_u64(&dev->dac[1].timer, dev->dac[1].latch); + es1371_scan_fifo(dev); + es1371_update(dev); - if (dev->int_ctrl & INT_UART_EN) { - //audiopci_log("UART INT Enabled\n"); - if (((dev->uart_ctrl & (UART_CTRL_RXINTEN | UART_CTRL_TXINTEN)) == UART_CTRL_RXINTEN) && dev->uart_in) { - audiopci_log("RX irq\n"); - 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 { - 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)); - es1371_update_irqs(dev); - } - if (dev->int_ctrl & INT_DAC1_EN) { frac = dev->dac[0].ac & 0x7fff; idx = dev->dac[0].ac >> 15; @@ -1928,59 +1980,47 @@ 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); + es1371_t *dev = (es1371_t *)p; + uint8_t i; - 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); - } + for (i = 0; i < len; i++) + es1371_write_fifo(dev, msg[i]); } + 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; + es1371_t *dev = (es1371_t *)p; + uint32_t i = -1; + + audiopci_log("Abort = %i\n", abort); + + if (dev->uart_status & UART_STATUS_RXRDY) + abort = 1; + + if (!abort) { + for (i = 0; i < len; i++) { + es1371_write_fifo(dev, buffer[i]); + if (dev->uart_status & UART_STATUS_RXRDY) + break; } - dev->sysex = 1; - for (i=0;imidi_r == dev->midi_w) - return (len-i); - dev->midi_queue[dev->midi_w++] = buffer[i]; - dev->midi_w &= 0x3f; - } - dev->sysex = 0; - return 0; + } + + /* The last sent position is in i. Return 7 - i. */ + + return 7 - i; } + static void * es1371_init(const device_t *info) { es1371_t *dev = malloc(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); + 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_set_cd_audio_filter(es1371_filter_cd_audio, dev);