diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h
index 75d056ea1..f0dd948ae 100644
--- a/src/include/86box/resource.h
+++ b/src/include/86box/resource.h
@@ -207,6 +207,9 @@
#define IDC_COMBO_MIDI_IN 1050
#define IDC_CONFIGURE_CMS 1051
#define IDC_CONFIGURE_SSI 1052
+#define IDC_FM_DRIVER 1053
+#define IDC_RADIO_FM_DRV_NUKED 1054
+#define IDC_RADIO_FM_DRV_YMFM 1055
#define IDC_COMBO_NET_TYPE 1060 /* network config */
#define IDC_COMBO_PCAP 1061
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index 1216257bc..fd402186a 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -329,6 +329,7 @@ extern const device_t gd5428_isa_device;
extern const device_t gd5428_vlb_device;
extern const device_t gd5428_diamond_speedstar_pro_b1_vlb_device;
extern const device_t gd5428_mca_device;
+extern const device_t gd5426_mca_device;
extern const device_t gd5428_onboard_device;
extern const device_t gd5429_isa_device;
extern const device_t gd5429_vlb_device;
@@ -441,6 +442,7 @@ extern const device_t s3_metheus_86c928_isa_device;
extern const device_t s3_metheus_86c928_vlb_device;
extern const device_t s3_spea_mercury_lite_86c928_pci_device;
extern const device_t s3_spea_mirage_86c801_isa_device;
+extern const device_t s3_86c805_onboard_vlb_device;
extern const device_t s3_spea_mirage_86c805_vlb_device;
extern const device_t s3_mirocrystal_8s_805_vlb_device;
extern const device_t s3_mirocrystal_10sd_805_vlb_device;
diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c
index 72e8eaa6a..7baa85ed3 100644
--- a/src/machine/m_at_386dx_486.c
+++ b/src/machine/m_at_386dx_486.c
@@ -441,11 +441,14 @@ machine_at_decpclpv_init(const machine_t *model)
machine_at_common_init(model);
device_add(&sis_85c461_device);
+
+ if (gfxcard == VID_INTERNAL)
+ device_add(&s3_86c805_onboard_vlb_device);
+
/* TODO: Phoenix MultiKey KBC */
device_add(&keyboard_ps2_ami_pci_device);
device_add(&ide_isa_2ch_device);
- device_add(&fdc37c663_device);
- /* TODO: On-board S3 805 with AT&T 490 RAM DAC. */
+ device_add(&fdc37c663_ide_device);
return ret;
}
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index ac04fa413..fe4f618c3 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -4723,7 +4723,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_PS2,
- .flags = MACHINE_IDE_DUAL, /* No MACHINE_VIDEO yet, because on-board video is not yet implemented. */
+ .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO,
.ram = {
.min = 1024,
.max = 32768,
@@ -4733,7 +4733,7 @@ const machine_t machines[] = {
.kbc = KBC_UNKNOWN,
.kbc_p1 = 0,
.gpio = 0,
- .device = NULL,
+ .device = &s3_86c805_onboard_vlb_device,
.vid_device = NULL
},
/* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */
diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c
index 047624dad..b4c56af53 100644
--- a/src/network/net_pcnet.c
+++ b/src/network/net_pcnet.c
@@ -258,7 +258,7 @@ typedef struct {
uint32_t cMsLinkUpDelay;
int transfer_size;
uint8_t maclocal[6]; /* configured MAC (local) address */
- pc_timer_t timer_soft_int, timer_restore;
+ pc_timer_t timer, timer_soft_int, timer_restore;
} nic_t;
/** @todo All structs: big endian? */
@@ -386,7 +386,6 @@ static uint8_t pcnet_pci_regs[PCI_REGSIZE];
static void pcnetAsyncTransmit(nic_t *dev);
static void pcnetPollRxTx(nic_t *dev);
-static void pcnetPollTimer(nic_t *dev);
static void pcnetUpdateIrq(nic_t *dev);
static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap);
static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val);
@@ -1038,7 +1037,7 @@ pcnetStart(nic_t *dev)
dev->aCSR[0] |= 0x0020; /* set RXON */
dev->aCSR[0] &= ~0x0004; /* clear STOP bit */
dev->aCSR[0] |= 0x0002; /* STRT */
- pcnetPollTimer(dev);
+ timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
}
@@ -1052,7 +1051,7 @@ pcnetStop(nic_t *dev)
dev->aCSR[0] = 0x0004;
dev->aCSR[4] &= ~0x02c2;
dev->aCSR[5] &= ~0x0011;
- pcnetPollTimer(dev);
+ timer_disable(&dev->timer);
}
@@ -1699,8 +1698,12 @@ pcnetPollRxTx(nic_t *dev)
static void
-pcnetPollTimer(nic_t *dev)
+pcnetPollTimer(void *p)
{
+ nic_t *dev = (nic_t *)p;
+
+ timer_advance_u64(&dev->timer, 2000 * TIMER_USEC);
+
if (CSR_TDMD(dev))
pcnetAsyncTransmit(dev);
@@ -2226,7 +2229,7 @@ pcnet_word_write(nic_t *dev, uint32_t addr, uint16_t val)
if (!BCR_DWIO(dev)) {
switch (addr & 0x0f) {
case 0x00: /* RDP */
- pcnetPollTimer(dev);
+ timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
pcnet_csr_writew(dev, dev->u32RAP, val);
pcnetUpdateIrq(dev);
break;
@@ -2272,7 +2275,7 @@ pcnet_word_read(nic_t *dev, uint32_t addr)
/** @note if we're not polling, then the guest will tell us when to poll by setting TDMD in CSR0 */
/** Polling is then useless here and possibly expensive. */
if (!CSR_DPOLL(dev))
- pcnetPollTimer(dev);
+ timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
val = pcnet_csr_readw(dev, dev->u32RAP);
if (dev->u32RAP == 0)
@@ -2306,7 +2309,7 @@ pcnet_dword_write(nic_t *dev, uint32_t addr, uint32_t val)
if (BCR_DWIO(dev)) {
switch (addr & 0x0f) {
case 0x00: /* RDP */
- pcnetPollTimer(dev);
+ timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
pcnet_csr_writew(dev, dev->u32RAP, val & 0xffff);
pcnetUpdateIrq(dev);
break;
@@ -2334,7 +2337,7 @@ pcnet_dword_read(nic_t *dev, uint32_t addr)
switch (addr & 0x0f) {
case 0x00: /* RDP */
if (!CSR_DPOLL(dev))
- pcnetPollTimer(dev);
+ timer_set_delay_u64(&dev->timer, 2000 * TIMER_USEC);
val = pcnet_csr_readw(dev, dev->u32RAP);
if (dev->u32RAP == 0)
goto skip_update_irq;
@@ -3050,6 +3053,8 @@ pcnet_init(const device_t *info)
/* Attach ourselves to the network module. */
network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail, pcnetSetLinkState);
+ timer_add(&dev->timer, pcnetPollTimer, dev, 0);
+
if (dev->board == DEV_AM79C973)
timer_add(&dev->timer_soft_int, pcnetTimerSoftInt, dev, 0);
diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp
index 89ead7acd..d1f5318ba 100644
--- a/src/qt/qt_platform.cpp
+++ b/src/qt/qt_platform.cpp
@@ -571,7 +571,7 @@ void ProgSettings::reloadStrings()
gssynthstr.replace("libgs", LIB_NAME_GS);
}
else gssynthstr.prepend(LIB_NAME_GS);
- translatedstrings[IDS_2132] = flsynthstr.toStdWString();
+ translatedstrings[IDS_2132] = gssynthstr.toStdWString();
auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation.");
if (ftsynthstr.contains("libfreetype"))
{
diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp
index 56391569a..1c441b8ef 100644
--- a/src/qt/qt_settingssound.cpp
+++ b/src/qt/qt_settingssound.cpp
@@ -25,6 +25,7 @@ extern "C" {
#include <86box/sound.h>
#include <86box/midi.h>
#include <86box/snd_mpu401.h>
+#include <86box/snd_opl.h>
}
#include "qt_deviceconfig.hpp"
@@ -52,6 +53,10 @@ void SettingsSound::save() {
GAMEBLASTER = ui->checkBoxCMS->isChecked() ? 1 : 0;
GUS = ui->checkBoxGUS->isChecked() ? 1 : 0;;
sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0;;
+ if (ui->radioButtonYMFM->isChecked())
+ fm_driver = FM_DRV_YMFM;
+ else
+ fm_driver = FM_DRV_NUKED;
}
void SettingsSound::onCurrentMachineChanged(int machineId) {
@@ -151,6 +156,15 @@ void SettingsSound::onCurrentMachineChanged(int machineId) {
ui->pushButtonConfigureGUS->setEnabled((GUS > 0) && hasIsa16);
ui->checkBoxSSI2001->setEnabled(hasIsa);
ui->pushButtonConfigureSSI2001->setEnabled((SSI2001 > 0) && hasIsa);
+ switch (fm_driver) {
+ case FM_DRV_YMFM:
+ ui->radioButtonYMFM->setChecked(true);
+ break;
+ case FM_DRV_NUKED:
+ default:
+ ui->radioButtonNuked->setChecked(true);
+ break;
+ }
}
static bool allowMpu401(Ui::SettingsSound *ui) {
diff --git a/src/qt/qt_settingssound.ui b/src/qt/qt_settingssound.ui
index 65f5d7fd6..9ae91dcd2 100644
--- a/src/qt/qt_settingssound.ui
+++ b/src/qt/qt_settingssound.ui
@@ -152,6 +152,35 @@
-
+
+
+
+ 0
+ 0
+
+
+
+ FM synth driver
+
+
+
-
+
+
+ Nuked (more accurate)
+
+
+
+ -
+
+
+ YMFM (faster)
+
+
+
+
+
+
+ -
Qt::Vertical
diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c
index 57fcc2469..3266dc802 100644
--- a/src/scsi/scsi_pcscsi.c
+++ b/src/scsi/scsi_pcscsi.c
@@ -372,11 +372,13 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen)
if (dmalen == 0)
return 0;
if (dev->mca) {
+ dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < dmalen) {
int val = dma_channel_read(dev->DmaChannel);
buf[dev->dma_86c01.pos++] = val & 0xff;
}
dev->dma_86c01.pos = 0;
+ dma_set_drq(dev->DmaChannel, 0);
} else {
esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE);
dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen);
@@ -677,11 +679,13 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
esp_log("ESP Command on DMA\n");
count = MIN(count, fifo8_num_free(&dev->cmdfifo));
if (dev->mca) {
+ dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
dma_channel_write(dev->DmaChannel, buf[dev->dma_86c01.pos]);
dev->dma_86c01.pos++;
}
dev->dma_86c01.pos = 0;
+ dma_set_drq(dev->DmaChannel, 0);
} else
esp_pci_dma_memory_rw(dev, buf, count, READ_FROM_DEVICE);
fifo8_push_all(&dev->cmdfifo, buf, count);
@@ -719,24 +723,28 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
if (sd->phase == SCSI_PHASE_DATA_IN) {
esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", esp_get_tc(dev), dev->ti_size, count);
if (dev->mca) {
+ dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]);
esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]);
dev->dma_86c01.pos++;
}
dev->dma_86c01.pos = 0;
+ dma_set_drq(dev->DmaChannel, 0);
} else {
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, READ_FROM_DEVICE);
}
} else if (sd->phase == SCSI_PHASE_DATA_OUT) {
esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, esp_get_tc(dev));
if (dev->mca) {
+ dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < count) {
int val = dma_channel_read(dev->DmaChannel);
esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff);
sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff;
dev->dma_86c01.pos++;
}
+ dma_set_drq(dev->DmaChannel, 0);
dev->dma_86c01.pos = 0;
} else
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, WRITE_TO_DEVICE);
@@ -922,11 +930,13 @@ esp_write_response(esp_t *dev)
if (dev->dma) {
if (dev->mca) {
+ dma_set_drq(dev->DmaChannel, 1);
while (dev->dma_86c01.pos < 2) {
int val = dma_channel_read(dev->DmaChannel);
buf[dev->dma_86c01.pos++] = val & 0xff;
}
dev->dma_86c01.pos = 0;
+ dma_set_drq(dev->DmaChannel, 0);
} else
esp_pci_dma_memory_rw(dev, buf, 2, WRITE_TO_DEVICE);
dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c
index 8b5bde94a..cfcf8e816 100644
--- a/src/scsi/scsi_spock.c
+++ b/src/scsi/scsi_spock.c
@@ -438,74 +438,67 @@ spock_process_imm_cmd(spock_t *scsi)
int i;
int adapter_id, phys_id, lun_id;
- switch (scsi->command & CMD_MASK) {
- case CMD_ASSIGN:
- adapter_id = (scsi->command >> 16) & 15;
- phys_id = (scsi->command >> 20) & 7;
- lun_id = (scsi->command >> 24) & 7;
-
+ switch (scsi->command & CMD_MASK) {
+ case CMD_ASSIGN:
+ adapter_id = (scsi->command >> 16) & 15;
+ phys_id = (scsi->command >> 20) & 7;
+ lun_id = (scsi->command >> 24) & 7;
if (adapter_id == 15) {
- if (phys_id == 7) /*Device 15 always adapter*/
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- else /*Can not re-assign device 15 (always adapter)*/
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
- } else {
- if (scsi->command & (1 << 23)) {
- spock_log("Assign: adapter id=%d\n", adapter_id);
- scsi->dev_id[adapter_id].phys_id = -1;
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- } else {
- if (phys_id != scsi->adapter_id) {
- scsi->dev_id[adapter_id].phys_id = phys_id;
- scsi->dev_id[adapter_id].lun_id = lun_id;
- spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- } else { /*Can not assign adapter*/
- spock_log("Assign: PUN=%d, cannot assign adapter\n", phys_id);
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
- }
- }
- }
+ if (phys_id == 7) /*Device 15 always adapter*/
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ else /*Can not re-assign device 15 (always adapter)*/
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
+ } else {
+ if (scsi->command & (1 << 23)) {
+ spock_log("Assign: adapter id=%d\n", adapter_id);
+ scsi->dev_id[adapter_id].phys_id = -1;
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ } else {
+ if (phys_id != scsi->adapter_id) {
+ scsi->dev_id[adapter_id].phys_id = phys_id;
+ scsi->dev_id[adapter_id].lun_id = lun_id;
+ spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ } else { /*Can not assign adapter*/
+ spock_log("Assign: PUN=%d, cannot assign adapter\n", phys_id);
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
+ }
+ }
+ }
break;
-
case CMD_DMA_PACING_CONTROL:
- scsi->pacing = scsi->cir[2];
- spock_log("Pacing control: %i\n", scsi->pacing);
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- break;
+ scsi->pacing = scsi->cir[2];
+ spock_log("Pacing control: %i\n", scsi->pacing);
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ break;
+ case CMD_FEATURE_CONTROL:
+ spock_log("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29);
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ break;
+ case CMD_INVALID_412:
+ spock_log("Invalid 412\n");
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ break;
+ case CMD_RESET:
+ spock_log("Reset Command\n");
+ if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
+ for (i = 0; i < 8; i++)
+ scsi_device_reset(&scsi_devices[scsi->bus][i]);
+ spock_log("Adapter Reset\n");
- case CMD_FEATURE_CONTROL:
- spock_log("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29);
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- break;
+ if (!scsi->adapter_reset) /*The early 1990 bios must have its boot drive
+ set to ID 6 according https://www.ardent-tool.com/IBM_SCSI/SCSI-A.html */
+ scsi->adapter_reset = 1;
- case CMD_INVALID_412:
- spock_log("Invalid 412\n");
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- break;
-
- case CMD_RESET:
- spock_log("Reset Command\n");
- if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
- for (i = 0; i < 8; i++)
- scsi_device_reset(&scsi_devices[scsi->bus][i]);
- spock_log("Adapter Reset\n");
-
- if (!scsi->adapter_reset && scsi->bios_ver) /*The early 1990 bios must have its boot drive
- set to ID 6 according https://www.ardent-tool.com/IBM_SCSI/SCSI-A.html */
- scsi->adapter_reset = 1;
- else
- scsi->adapter_reset = 0;
-
- scsi->scb_state = 0;
+ scsi->scb_state = 0;
}
- spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
- break;
+ spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
+ break;
- default:
- fatal("scsi_callback: Bad command %02x\n", scsi->command);
- break;
- }
+ default:
+ fatal("scsi_callback: Bad command %02x\n", scsi->command);
+ break;
+ }
}
static void
@@ -523,11 +516,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
for (c = 0; c < SCSI_ID_MAX; c++)
spock_clear_irq(scsi, c);
- if (scsi->in_reset == 1) {
- scsi->basic_ctrl |= CTRL_IRQ_ENA;
- spock_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE);
- } else
- spock_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE);
+ if (scsi->in_reset == 1) {
+ scsi->basic_ctrl |= CTRL_IRQ_ENA;
+ spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
+ } else
+ spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
/*Reset device mappings*/
for (c = 0; c < 7; c++) {
@@ -559,17 +552,17 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 1: /* Select */
- if (scsi->dev_id[scsi->scb_id].phys_id == -1) {
- uint16_t term_stat_block_addr7 = (0xe << 8) | 0;
- uint16_t term_stat_block_addr8 = (0xa << 8) | 0;
+ if (scsi->dev_id[scsi->scb_id].phys_id == -1) {
+ uint16_t term_stat_block_addr7 = (0xe << 8) | 0;
+ uint16_t term_stat_block_addr8 = (0xa << 8) | 0;
- spock_log("Start failed, SCB ID = %d\n", scsi->scb_id);
- spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
- scsi->scb_state = 0;
- dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
- dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
- break;
- }
+ spock_log("Start failed, SCB ID = %d\n", scsi->scb_id);
+ spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
+ scsi->scb_state = 0;
+ dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
+ dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
+ break;
+ }
dma_bm_read(scsi->scb_addr, (uint8_t *)&scb->command, 2, 2);
dma_bm_read(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2, 2);
@@ -591,11 +584,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
" SCB chain address = %08x\n"
" Block count = %04x\n"
" Block length = %04x\n"
- " SCB id = %d\n",
+ " SCB id = %d, Phys id = %d\n",
scb->command, scb->enable, scb->lba_addr,
scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count,
scb->term_status_block_addr, scb->scb_chain_addr,
- scb->block_count, scb->block_length, scsi->scb_id);
+ scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
switch (scb->command & CMD_MASK) {
case CMD_GET_COMPLETE_STATUS:
@@ -669,11 +662,10 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case CMD_DEVICE_INQUIRY:
- if (scsi->adapter_reset) {
- scsi->cdb_id = scsi->scb_id;
- } else {
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
- }
+ if (scb->command != CMD_DEVICE_INQUIRY)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id);
scsi->cdb[0] = GPCMD_INQUIRY;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -689,12 +681,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_SEND_OTHER_SCSI:
- if (scsi->adapter_reset) {
- scsi->cdb_id = scsi->scb_id;
- } else {
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
- }
- spock_log("Send Other SCSI, ID=%d\n", scsi->cdb_id);
+ if (scb->command != CMD_SEND_OTHER_SCSI)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
+ spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2);
scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/
scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6;
@@ -703,11 +694,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DEVICE_CAPACITY:
- if (scsi->adapter_reset)
- scsi->cdb_id = scsi->scb_id;
- else
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
- spock_log("Device Capacity, ID=%d\n", scsi->cdb_id);
+ if (scb->command != CMD_READ_DEVICE_CAPACITY)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
+ spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = 0; /*LBA*/
@@ -724,7 +715,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DATA:
- spock_log("Device Read Data\n");
+ if (scb->command != CMD_READ_DATA)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
+ spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
scsi->cdb[0] = GPCMD_READ_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/
@@ -736,12 +731,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_WRITE_DATA:
+ if (scb->command != CMD_WRITE_DATA)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Write Data\n");
scsi->cdb[0] = GPCMD_WRITE_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -754,12 +752,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_VERIFY:
+ if (scb->command != CMD_VERIFY)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Verify\n");
scsi->cdb[0] = GPCMD_VERIFY_10;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -772,17 +773,16 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->cdb[8] = scb->block_count & 0xff;
scsi->cdb[9] = 0; /*Control*/
scsi->cdb_len = 10;
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
scsi->data_len = 0;
scsi->scsi_state = SCSI_STATE_SELECT;
scsi->scb_state = 2;
return;
case CMD_REQUEST_SENSE:
- if (scsi->adapter_reset)
- scsi->cdb_id = scsi->scb_id;
- else
- scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
+ if (scb->command != CMD_REQUEST_SENSE)
+ scsi->cdb_id = scsi->scb_id;
+ else
+ scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id);
scsi->cdb[0] = GPCMD_REQUEST_SENSE;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
@@ -798,32 +798,35 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case 2: /* Wait */
- if (scsi->scsi_state == SCSI_STATE_IDLE && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
- if (scsi->last_status == SCSI_STATUS_OK) {
- scsi->scb_state = 3;
- spock_log("Status is Good on device ID %d, timer = %i\n", scsi->cdb_id, scsi->cmd_timer);
- } else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
- uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
- uint16_t term_stat_block_addr8 = 0x20;
- uint16_t term_stat_block_addrb = scsi->scb_addr & 0xffff;
- uint16_t term_stat_block_addrc = scsi->scb_addr >> 16;
+ if (scsi->scsi_state == SCSI_STATE_IDLE) {
+ if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
+ if (scsi->last_status == SCSI_STATUS_OK) {
+ scsi->scb_state = 3;
+ spock_log("Status is Good on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
+ } else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
+ uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
+ uint16_t term_stat_block_addr8 = 0x20;
+ uint16_t term_stat_block_addrb = scsi->scb_addr & 0xffff;
+ uint16_t term_stat_block_addrc = scsi->scb_addr >> 16;
- spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
- scsi->scb_state = 0;
- spock_log("Status Check Condition on device ID %d\n", scsi->cdb_id);
- dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
- dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
- dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
- dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
- }
- } else if (scsi->scsi_state == SCSI_STATE_IDLE && !scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
- uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
- uint16_t term_stat_block_addr8 = 0x10;
- spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
- scsi->scb_state = 0;
- dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
- dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
- }
+ spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
+ scsi->scb_state = 0;
+ spock_log("Status Check Condition on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
+ dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
+ dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
+ dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
+ dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
+ }
+ } else {
+ uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
+ uint16_t term_stat_block_addr8 = 0x10;
+ spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
+ scsi->scb_state = 0;
+ spock_log("Status Check Condition on device ID %d on no device, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
+ dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
+ dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
+ }
+ }
break;
case 3: /* Complete */
@@ -1104,30 +1107,29 @@ spock_init(const device_t *info)
scsi->bios_ver = device_get_config_int("bios_ver");
- switch (scsi->bios_ver) {
+ switch (scsi->bios_ver) {
case 1:
- rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
- 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
- break;
+ rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
+ 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
+ break;
case 0:
- rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM,
- 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
- break;
- }
+ rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM,
+ 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
+ break;
+ }
+ mem_mapping_disable(&scsi->bios_rom.mapping);
- mem_mapping_disable(&scsi->bios_rom.mapping);
-
- scsi->pos_regs[0] = 0xff;
- scsi->pos_regs[1] = 0x8e;
+ scsi->pos_regs[0] = 0xff;
+ scsi->pos_regs[1] = 0x8e;
mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi);
scsi->in_reset = 2;
scsi->cmd_timer = SPOCK_TIME * 50;
scsi->status = STATUS_BUSY;
- for (c = 0; c < (SCSI_ID_MAX-1); c++) {
- scsi->dev_id[c].phys_id = -1;
- }
+ for (c = 0; c < (SCSI_ID_MAX-1); c++) {
+ scsi->dev_id[c].phys_id = -1;
+ }
scsi->dev_id[SCSI_ID_MAX-1].phys_id = scsi->adapter_id;
@@ -1141,7 +1143,7 @@ spock_init(const device_t *info)
static void
spock_close(void *p)
{
- spock_t *scsi = (spock_t *)p;
+ spock_t *scsi = (spock_t *)p;
if (scsi) {
free(scsi);
diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp
index 6acbf79f3..28ea7a621 100644
--- a/src/sound/snd_opl_ymfm.cpp
+++ b/src/sound/snd_opl_ymfm.cpp
@@ -21,6 +21,7 @@
#include "ymfm/ymfm_opl.h"
extern "C" {
+#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/sound.h>
@@ -81,6 +82,9 @@ public:
memset(m_oldsamples, 0, sizeof(m_oldsamples));
m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock);
m_clock_us = 1000000 / (double) m_clock;
+ m_subtract[0] = 80.0;
+ m_subtract[1] = 320.0;
+ m_type = type;
timer_add(&m_timers[0], YMFMChip::timer1, this, 0);
timer_add(&m_timers[1], YMFMChip::timer2, this, 0);
@@ -97,11 +101,14 @@ public:
return;
pc_timer_t *timer = &m_timers[tnum];
- if (duration_in_clocks < 0) {
+ if (duration_in_clocks < 0)
timer_stop(timer);
- } else {
+ else {
double period = m_clock_us * duration_in_clocks;
- timer_on_auto(timer, period);
+ if (period < m_subtract[tnum])
+ m_engine->engine_timer_expired(tnum);
+ else
+ timer_on_auto(timer, period);
}
}
@@ -172,6 +179,11 @@ virtual void generate_resampled(int32_t *data, uint32_t num_samples) override
return m_chip.read(addr);
}
+ virtual uint32_t get_special_flags(void) override
+ {
+ return ((m_type == FM_YMF262) || (m_type == FM_YMF289B)) ? 0x8000 : 0x0000;
+ }
+
static void timer1(void *priv)
{
YMFMChip *drv = (YMFMChip *) priv;
@@ -187,7 +199,7 @@ virtual void generate_resampled(int32_t *data, uint32_t num_samples) override
private:
ChipType m_chip;
uint32_t m_clock;
- double m_clock_us;
+ double m_clock_us, m_subtract[2];
typename ChipType::output_data m_output;
pc_timer_t m_timers[2];
diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c
index 16fcfe9d3..609786d0d 100644
--- a/src/sound/snd_sb.c
+++ b/src/sound/snd_sb.c
@@ -314,7 +314,7 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *p)
if (sb->opl_enabled) {
sb->opl.reset_buffer(sb->opl.priv);
- if (sb->dsp.sb_type != SBPRO)
+ if (sb->dsp.sb_type == SBPRO)
sb->opl2.reset_buffer(sb->opl2.priv);
}
@@ -2749,6 +2749,17 @@ static const device_config_t sb_pro_config[] = {
{ .name = "", .description = "", .type = CONFIG_END }
};
+static const device_config_t sb_pro_mcv_config[] = {
+ {
+ .name = "receive_input",
+ .description = "Receive input (SB MIDI)",
+ .type = CONFIG_BINARY,
+ .default_string = "",
+ .default_int = 1
+ },
+ { .name = "", .description = "", .type = CONFIG_END }
+};
+
static const device_config_t sb_16_config[] = {
{
.name = "base",
@@ -3523,7 +3534,7 @@ const device_t sb_pro_mcv_device = {
{ .available = NULL },
.speed_changed = sb_speed_changed,
.force_redraw = NULL,
- .config = NULL
+ .config = sb_pro_mcv_config
};
const device_t sb_pro_compat_device = {
diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h
index d9c3bca3b..ae13faedd 100644
--- a/src/sound/ymfm/ymfm.h
+++ b/src/sound/ymfm/ymfm.h
@@ -543,6 +543,8 @@ public:
// noted busy end time and return true if we haven't yet passed it
virtual bool ymfm_is_busy() { return false; }
+ virtual uint32_t get_special_flags(void) { return 0x0000; }
+
//
// I/O functions
//
diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp
index 17bbc9150..7e5109d59 100644
--- a/src/sound/ymfm/ymfm_fm.ipp
+++ b/src/sound/ymfm/ymfm_fm.ipp
@@ -1472,11 +1472,14 @@ void fm_engine_base::assign_operators()
template
void fm_engine_base::update_timer(uint32_t tnum, uint32_t enable, int32_t delta_clocks)
{
+ uint32_t subtract = !!(tnum >> 15);
+ tnum &= 0x7fff;
+
// if the timer is live, but not currently enabled, set the timer
if (enable && !m_timer_running[tnum])
{
// period comes from the registers, and is different for each
- uint32_t period = (tnum == 0) ? (1024 - m_regs.timer_a_value()) : 16 * (256 - m_regs.timer_b_value());
+ uint32_t period = (tnum == 0) ? (1024 - subtract - m_regs.timer_a_value()) : 16 * (256 - subtract - m_regs.timer_b_value());
// caller can also specify a delta to account for other effects
period += delta_clocks;
@@ -1581,8 +1584,11 @@ void fm_engine_base::engine_mode_write(uint8_t data)
// load timers; note that timer B gets a small negative adjustment because
// the *16 multiplier is free-running, so the first tick of the clock
// is a bit shorter
- update_timer(1, m_regs.load_timer_b(), -(m_total_clocks & 15));
- update_timer(0, m_regs.load_timer_a(), 0);
+ // OPL3 begins counting immediately instead of after the first period is over.
+ // We use bit 15 of the timer number on those chips to inform that this was a
+ // control register write, and to therefore, subtract 1 counting cycle.
+ update_timer(1 | m_intf.get_special_flags(), m_regs.load_timer_b(), -(m_total_clocks & 15));
+ update_timer(0 | m_intf.get_special_flags(), m_regs.load_timer_a(), 0);
}
}
diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c
index 174dc5037..709e2a972 100644
--- a/src/video/vid_cl54xx.c
+++ b/src/video/vid_cl54xx.c
@@ -46,6 +46,7 @@
#define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi"
#define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin"
#define BIOS_GD5426_DIAMOND_A1_ISA_PATH "roms/video/cirruslogic/diamond5426.vbi"
+#define BIOS_GD5426_MCA_PATH "roms/video/cirruslogic/Reply.BIN"
#define BIOS_GD5428_DIAMOND_B1_VLB_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"
#define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin"
#define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM"
@@ -3902,6 +3903,8 @@ static void
else {
if (gd54xx->vlb)
romfn = BIOS_GD5428_PATH;
+ else if (gd54xx->mca)
+ romfn = BIOS_GD5426_MCA_PATH;
else
romfn = BIOS_GD5428_ISA_PATH;
}
@@ -4115,8 +4118,8 @@ static void
gd54xx->unlocked = 1;
if (gd54xx->mca) {
- gd54xx->pos_regs[0] = 0x7b;
- gd54xx->pos_regs[1] = 0x91;
+ gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b;
+ gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91;
mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx);
io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
}
@@ -4184,6 +4187,12 @@ gd5428_isa_available(void)
return rom_present(BIOS_GD5428_ISA_PATH);
}
+static int
+gd5426_mca_available(void)
+{
+ return rom_present(BIOS_GD5426_MCA_PATH);
+}
+
static int
gd5428_mca_available(void)
{
@@ -4699,6 +4708,20 @@ const device_t gd5428_mca_device = {
.config = NULL
};
+const device_t gd5426_mca_device = {
+ .name = "Cirrus Logic GD5426 (MCA) (Reply Video Adapter)",
+ .internal_name = "replymcasvga",
+ .flags = DEVICE_MCA,
+ .local = CIRRUS_ID_CLGD5426,
+ .init = gd54xx_init,
+ .close = gd54xx_close,
+ .reset = gd54xx_reset,
+ { .available = gd5426_mca_available },
+ .speed_changed = gd54xx_speed_changed,
+ .force_redraw = gd54xx_force_redraw,
+ .config = gd5426_config
+};
+
const device_t gd5428_onboard_device = {
.name = "Cirrus Logic GD5428 (ISA) (On-Board)",
.internal_name = "cl_gd5428_onboard",
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index 6887c0b51..b6a1af232 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -107,7 +107,8 @@ enum
S3_MIROCRYSTAL8S_805,
S3_NUMBER9_9FX_531,
S3_NUMBER9_9FX_771,
- S3_SPEA_MERCURY_LITE_PCI
+ S3_SPEA_MERCURY_LITE_PCI,
+ S3_86C805_ONBOARD
};
@@ -6803,6 +6804,11 @@ static void *s3_init(const device_t *info)
chip = S3_86C801;
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801);
break;
+ case S3_86C805_ONBOARD:
+ bios_fn = NULL;
+ chip = S3_86C805;
+ video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805);
+ break;
case S3_SPEA_MIRAGE_86C805:
bios_fn = ROM_SPEA_MIRAGE_86C805;
chip = S3_86C805;
@@ -7213,6 +7219,20 @@ static void *s3_init(const device_t *info)
svga->getclock = av9194_getclock;
break;
+ case S3_86C805_ONBOARD:
+ svga->decode_mask = (2 << 20) - 1;
+ stepping = 0xa0; /*86C801/86C805*/
+ s3->id = stepping;
+ s3->id_ext = stepping;
+ s3->id_ext_pci = 0;
+ s3->packed_mmio = 0;
+ svga->crtc[0x5a] = 0x0a;
+
+ svga->ramdac = device_add(&att490_ramdac_device);
+ svga->clock_gen = device_add(&av9194_device);
+ svga->getclock = av9194_getclock;
+ break;
+
case S3_PHOENIX_86C801:
case S3_PHOENIX_86C805:
svga->decode_mask = (2 << 20) - 1;
@@ -7818,6 +7838,20 @@ const device_t s3_spea_mirage_86c801_isa_device = {
.config = s3_9fx_config
};
+const device_t s3_86c805_onboard_vlb_device = {
+ .name = "S3 86c805 VLB On-Board",
+ .internal_name = "px_s3_805_onboard_vlb",
+ .flags = DEVICE_VLB,
+ .local = S3_86C805_ONBOARD,
+ .init = s3_init,
+ .close = s3_close,
+ .reset = s3_reset,
+ { .available = NULL },
+ .speed_changed = s3_speed_changed,
+ .force_redraw = s3_force_redraw,
+ .config = s3_9fx_config
+};
+
const device_t s3_spea_mirage_86c805_vlb_device = {
.name = "S3 86c805 VLB (SPEA Mirage VL)",
.internal_name = "px_s3_v7_805_vlb",
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index fdad852fe..94d4601a8 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -148,6 +148,7 @@ video_cards[] = {
{ &vga_device },
{ &v7_vga_1024i_device },
{ &wy700_device },
+ { &gd5426_mca_device },
{ &gd5428_mca_device },
{ &et4000_mca_device },
{ &radius_svga_multiview_mca_device },
diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc
index a28b99a84..c7bdb3cb1 100644
--- a/src/win/languages/cs-CZ.rc
+++ b/src/win/languages/cs-CZ.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Použít zvuk FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Druh sítě:"
#define STR_PCAP "PCap zařízení:"
diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc
index 27644e4a7..d99095d56 100644
--- a/src/win/languages/de-DE.rc
+++ b/src/win/languages/de-DE.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32-Wiedergabe benutzen"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Netzwerktyp:"
#define STR_PCAP "PCap-Gerät:"
diff --git a/src/win/languages/dialogs.rc b/src/win/languages/dialogs.rc
index 45a767ea3..bd1eb87bd 100644
--- a/src/win/languages/dialogs.rc
+++ b/src/win/languages/dialogs.rc
@@ -364,6 +364,17 @@ BEGIN
CONTROL STR_FLOAT, IDC_CHECK_FLOAT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
CFG_HMARGIN, 138, 104, CFG_CHECKBOX_HEIGHT
+
+ GROUPBOX STR_FM_DRIVER, IDC_FM_DRIVER,
+ CFG_HMARGIN, 154, 110, 42
+
+ CONTROL STR_FM_DRV_NUKED, IDC_RADIO_FM_DRV_NUKED,
+ "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,
+ 14, 166, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT
+
+ CONTROL STR_FM_DRV_YMFM, IDC_RADIO_FM_DRV_YMFM,
+ "Button", BS_AUTORADIOBUTTON | WS_TABSTOP,
+ 14, 180, CFG_CHECKBOX_PRI_WIDTH, CFG_CHECKBOX_HEIGHT
END
DLG_CFG_NETWORK DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT
@@ -924,6 +935,8 @@ END
#undef STR_VIDEO
#undef STR_VOODOO
+#undef STR_IBM8514
+#undef STR_XGA
#undef STR_MOUSE
#undef STR_JOYSTICK
@@ -940,6 +953,9 @@ END
#undef STR_CMS
#undef STR_GUS
#undef STR_FLOAT
+#undef STR_FM_DRIVER
+#undef STR_FM_DRV_NUKED
+#undef STR_FM_DRV_YMFM
#undef STR_NET_TYPE
#undef STR_PCAP
diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc
index fbbb982cf..9c1e8acd7 100644
--- a/src/win/languages/en-GB.rc
+++ b/src/win/languages/en-GB.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Use FLOAT32 sound"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Network type:"
#define STR_PCAP "PCap device:"
diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc
index 5a5839686..5a5fa4fd2 100644
--- a/src/win/languages/en-US.rc
+++ b/src/win/languages/en-US.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Use FLOAT32 sound"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Network type:"
#define STR_PCAP "PCap device:"
diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc
index b7eb61d24..3dc9757ea 100644
--- a/src/win/languages/es-ES.rc
+++ b/src/win/languages/es-ES.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Usar sonido FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Tipo de red:"
#define STR_PCAP "Dispositivo PCap:"
diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc
index a8dc55b72..d1b390bcd 100644
--- a/src/win/languages/fi-FI.rc
+++ b/src/win/languages/fi-FI.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Käytä FLOAT32-ääntä"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Verkon tyyppi:"
#define STR_PCAP "PCap-laite:"
diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc
index 11fc3360e..eab96bf05 100644
--- a/src/win/languages/fr-FR.rc
+++ b/src/win/languages/fr-FR.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Utiliser le son FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Type de réseau:"
#define STR_PCAP "Dispositif PCap:"
diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc
index 60e6e28c4..3cb8eb6d3 100644
--- a/src/win/languages/hr-HR.rc
+++ b/src/win/languages/hr-HR.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Koristi FLOAT32 za zvuk"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Tip mreže:"
#define STR_PCAP "Uređaj PCap:"
diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc
index 6b4dae959..7c2e1cf5e 100644
--- a/src/win/languages/hu-HU.rc
+++ b/src/win/languages/hu-HU.rc
@@ -294,6 +294,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32 használata"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Hálózati típusa:"
#define STR_PCAP "PCap eszköz:"
diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc
index 20d301f47..ca24daed4 100644
--- a/src/win/languages/it-IT.rc
+++ b/src/win/languages/it-IT.rc
@@ -290,6 +290,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Usa suono FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Tipo di rete:"
#define STR_PCAP "Dispositivo PCap:"
diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc
index 151e13e65..18017bfb4 100644
--- a/src/win/languages/ja-JP.rc
+++ b/src/win/languages/ja-JP.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32サウンドを使用する"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "ネットワークタイプ:"
#define STR_PCAP "PCapデバイス:"
diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc
index 831ca74bb..961b00748 100644
--- a/src/win/languages/ko-KR.rc
+++ b/src/win/languages/ko-KR.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32 사운드 사용"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "네트워크 종류:"
#define STR_PCAP "PCap 장치:"
diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc
index 211eb3ed8..5405778d3 100644
--- a/src/win/languages/pl-PL.rc
+++ b/src/win/languages/pl-PL.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Użyj dźwięku FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Rodzaj sieci:"
#define STR_PCAP "Urządzenie PCap:"
diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc
index 5e23a9d71..538472293 100644
--- a/src/win/languages/pt-BR.rc
+++ b/src/win/languages/pt-BR.rc
@@ -292,6 +292,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Usar som FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Tipo de rede:"
#define STR_PCAP "Dispositivo PCap:"
diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc
index fafc21df4..314f7ed56 100644
--- a/src/win/languages/pt-PT.rc
+++ b/src/win/languages/pt-PT.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Utilizar som FLOAT32"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Tipo de rede:"
#define STR_PCAP "Dispositivo PCap:"
diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc
index 15bd1752d..e88d9668e 100644
--- a/src/win/languages/ru-RU.rc
+++ b/src/win/languages/ru-RU.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32 звук"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Тип сети:"
#define STR_PCAP "Устройство PCap:"
diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc
index 7d715c5ca..e8672235f 100644
--- a/src/win/languages/sl-SI.rc
+++ b/src/win/languages/sl-SI.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "Uporabi FLOAT32 za zvok"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Vrsta omrežja:"
#define STR_PCAP "Naprava PCap:"
diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc
index cc3a98406..3d1cffc97 100644
--- a/src/win/languages/tr-TR.rc
+++ b/src/win/languages/tr-TR.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32 ses kullan"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Ağ tipi:"
#define STR_PCAP "PCap cihazı:"
diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc
index dfb86cc8b..5a741a5c9 100644
--- a/src/win/languages/uk-UA.rc
+++ b/src/win/languages/uk-UA.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "FLOAT32 звук"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "Тип мережі:"
#define STR_PCAP "Пристрій PCap:"
diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc
index a3c324c6c..3151b7143 100644
--- a/src/win/languages/zh-CN.rc
+++ b/src/win/languages/zh-CN.rc
@@ -289,6 +289,9 @@ END
#define STR_CMS "CMS / Game Blaster"
#define STR_GUS "Gravis Ultrasound"
#define STR_FLOAT "使用单精度浮点 (FLOAT32)"
+#define STR_FM_DRIVER "FM synth driver"
+#define STR_FM_DRV_NUKED "Nuked (more accurate)"
+#define STR_FM_DRV_YMFM "YMFM (faster)"
#define STR_NET_TYPE "网络类型:"
#define STR_PCAP "PCap 设备:"
diff --git a/src/win/win_settings.c b/src/win/win_settings.c
index 84ad26754..227c007b1 100644
--- a/src/win/win_settings.c
+++ b/src/win/win_settings.c
@@ -63,6 +63,7 @@
#include <86box/sound.h>
#include <86box/midi.h>
#include <86box/snd_mpu401.h>
+#include <86box/snd_opl.h>
#include <86box/video.h>
#include <86box/vid_xga_device.h>
#include <86box/plat.h>
@@ -94,7 +95,7 @@ static int temp_mouse, temp_joystick;
/* Sound category */
static int temp_sound_card, temp_midi_output_device, temp_midi_input_device, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS;
-static int temp_float;
+static int temp_float, temp_fm_driver;
/* Network category */
static int temp_net_type, temp_net_card;
@@ -350,6 +351,7 @@ win_settings_init(void)
temp_GAMEBLASTER = GAMEBLASTER;
temp_GUS = GUS;
temp_float = sound_is_float;
+ temp_fm_driver = fm_driver;
/* Network category */
temp_net_type = network_type;
@@ -476,6 +478,7 @@ win_settings_changed(void)
i = i || (GAMEBLASTER != temp_GAMEBLASTER);
i = i || (GUS != temp_GUS);
i = i || (sound_is_float != temp_float);
+ i = i || (fm_driver != temp_fm_driver);
/* Network category */
i = i || (network_type != temp_net_type);
@@ -568,6 +571,7 @@ win_settings_save(void)
GAMEBLASTER = temp_GAMEBLASTER;
GUS = temp_GUS;
sound_is_float = temp_float;
+ fm_driver = temp_fm_driver;
/* Network category */
network_type = temp_net_type;
@@ -1421,6 +1425,11 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
settings_enable_window(hdlg, IDC_CONFIGURE_SSI, machine_has_bus(temp_machine, MACHINE_BUS_ISA) && temp_SSI2001);
settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float);
+ if (temp_fm_driver == FM_DRV_YMFM)
+ settings_set_check(hdlg, IDC_RADIO_FM_DRV_YMFM, BST_CHECKED);
+ else
+ settings_set_check(hdlg, IDC_RADIO_FM_DRV_NUKED, BST_CHECKED);
+
free(lptsTemp);
return TRUE;
@@ -1517,7 +1526,10 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
temp_GUS = settings_get_check(hdlg, IDC_CHECK_GUS);
temp_SSI2001 = settings_get_check(hdlg, IDC_CHECK_SSI);
temp_float = settings_get_check(hdlg, IDC_CHECK_FLOAT);
-
+ if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_NUKED))
+ temp_fm_driver = FM_DRV_NUKED;
+ if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_YMFM))
+ temp_fm_driver = FM_DRV_YMFM;
default:
return FALSE;
}