diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 8abbe50c1..2f6afa940 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -518,12 +518,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0b); + regs[0x52] = (regs[0x52] & 0x04) | (val & 0xfb); cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; case INTEL_430HX: - regs[0x52] = (regs[0x52] & 0xf0) | (val & 0x0f); + regs[0x52] = val; cpu_cache_ext_enabled = ((val & 0x03) == 0x01); cpu_update_waitstates(); break; diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index cf4ff42d7..f80ecf99e 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -174,9 +174,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x23: if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) { valxor = val ^ dev->regs[rel_reg]; - if (rel_reg == 0x19) - dev->regs[rel_reg] &= ~val; - else if (rel_reg == 0x00) + if (rel_reg == 0x00) dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0); else dev->regs[rel_reg] = val; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 8ec0498ff..137ddb5cf 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -39,6 +39,7 @@ #include <86box/spd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/keyboard.h> #include <86box/chipset.h> #ifdef ENABLE_SIS_85C50X_LOG @@ -257,6 +258,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) break; case 0x5b: dev->pci_conf[addr] = val; + kbc_at_set_fast_reset(!!(val & 0x40)); break; case 0x60: /* SMI */ if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) { diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d8b308d6b..7a720f948 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -133,9 +133,9 @@ typedef struct atkbc_t { uint8_t stat_hi; uint8_t pending; uint8_t irq_state; + uint8_t suppress_cmd_intr; uint8_t pad; uint8_t pad0; - uint8_t pad1; uint8_t mem[0x100]; @@ -164,6 +164,8 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL }; static uint8_t kbc_ami_revision = '8'; static uint8_t kbc_award_revision = 0x42; +static uint8_t kbc_handler_set = 0; + static void (*kbc_at_do_poll)(atkbc_t *dev); /* Non-translated to translated scan codes. */ @@ -202,6 +204,19 @@ static const uint8_t nont_to_t[256] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; +static const uint8_t multikey_vars[0x0b] = { + 0x0a, + 0x03, 0x1e, 0x27, 0x28, 0x29, 0x38, 0x39, 0x18, 0x19, 0x35 +}; + +static uint8_t fast_reset = 0x00; + +void +kbc_at_set_fast_reset(const uint8_t new_fast_reset) +{ + fast_reset = new_fast_reset; +} + #ifdef ENABLE_KBC_AT_LOG int kbc_at_do_log = ENABLE_KBC_AT_LOG; @@ -359,7 +374,7 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) picint_common(1 << 12, 0, 1, NULL); picint_common(1 << 1, 0, 0, NULL); } else { - if (dev->mem[0x20] & 0x01) + if ((!dev->suppress_cmd_intr || (dev->channel == 1)) && (dev->mem[0x20] & 0x01)) picint_common(1 << 1, 0, 1, NULL); picint_common(1 << 12, 0, 0, NULL); } @@ -748,7 +763,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* AT, PS/2: Handle reset. */ /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if (!cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + /* TODO: The fast reset flag's condition should be reversed - the BCM SQ-588 + enables the flag and the CPURST on soft reset flag but expects this + to still soft reset instead. */ + if ((fast_reset || !cpu_cpurst_on_sr) && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); @@ -765,11 +783,12 @@ write_p2(atkbc_t *dev, uint8_t val) flushmmucache(); if (kbc_ven == KBC_VEN_ALI) smbase = 0x00030000; + /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L and can find out what they actually did to make it boot from FFFFF0 correctly despite A20 being gated when the CPU is reset, this will have to do. */ - else if (kbc_ven == KBC_VEN_SIEMENS) + if (kbc_ven == KBC_VEN_SIEMENS) is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } @@ -778,10 +797,10 @@ write_p2(atkbc_t *dev, uint8_t val) /* Do this here to avoid an infinite reset loop. */ dev->p2 = val; - if (cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ + if (!fast_reset && cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/ if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ - pclog("write_p2(): Pulse reset!\n"); + kbc_at_log("write_p2(): Pulse reset!\n"); dma_reset(); dma_set_at(1); @@ -1336,6 +1355,206 @@ write64_ami(void *priv, uint8_t val) return write64_generic(dev, val); } +static uint8_t +write60_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (dev->command) { + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + if (val == 0x00) + dev->command_phase = 0; + else { + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + } + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->mem[0x3a] = val; + dev->command_phase = 0; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->mem_addr = val; + dev->command_phase = 0; + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->mem[dev->mem_addr] = val; + dev->command_phase = 0; + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) + dev->mem[multikey_vars[dev->mem_addr]] = val; + else if (dev->mem_addr == 0x29) + dev->suppress_cmd_intr = !val; + dev->command_phase = 0; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->p1 |= val; + dev->command_phase = 0; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->p1 &= ~val; + dev->command_phase = 0; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + write_p2(dev, dev->p2 | val); + dev->command_phase = 0; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + write_p2(dev, dev->p2 & ~val); + dev->command_phase = 0; + return 0; + + default: + break; + } + + return 1; +} + +static uint8_t +write64_phoenix(void *priv, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + + switch (val) { + case 0x00 ... 0x1f: + kbc_at_log("ATkbc: Phoenix - alias read from %08X\n", val); + kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00); + return 0; + + case 0x40 ... 0x5f: + kbc_at_log("ATkbc: Phoenix - alias write to %08X\n", dev->command); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xa2: /* Test Extended Password */ + kbc_at_log("ATkbc: Phoenix - Test Extended Password\n"); + kbc_at_queue_add(dev, 0xf1); /* Extended Password not loaded */ + return 0; + + /* TODO: Make this actually load the password. */ + case 0xa3: /* Load Extended Password */ + kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xaf: /* Set Inactivity Timer */ + kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb8: /* Set Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xb9: /* Get Extended Memory Access Index */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory Access Index\n"); + kbc_at_queue_add(dev, dev->mem_addr); + return 0; + + case 0xba: /* Get Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Get Extended Memory\n"); + kbc_at_queue_add(dev, dev->mem[dev->mem_addr]); + return 0; + + case 0xbb: /* Set Extended Memory */ + kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xbc: /* Get MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Get MultiKey Variable\n"); + if (dev->mem_addr == 0) + kbc_at_queue_add(dev, multikey_vars[dev->mem_addr]); + else if (dev->mem_addr <= multikey_vars[dev->mem_addr]) + kbc_at_queue_add(dev, dev->mem[multikey_vars[dev->mem_addr]]); + else + kbc_at_queue_add(dev, 0xff); + return 0; + + case 0xbd: /* Set MultiKey Variable */ + kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc7: /* Set Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc8: /* Clear Port1 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xc9: /* Set Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + case 0xca: /* Clear Port2 bits */ + kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + return 0; + + /* TODO: Handle these three commands properly - configurable + revision level and proper CPU bits. */ + case 0xd5: /* Read MultiKey code revision level */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey code revision level\n"); + kbc_at_queue_add(dev, 0x04); + kbc_at_queue_add(dev, 0x16); + return 0; + + case 0xd6: /* Read Version Information */ + kbc_at_log("ATkbc: Phoenix - Read Version Information\n"); + kbc_at_queue_add(dev, 0x81); + kbc_at_queue_add(dev, 0xac); + return 0; + + case 0xd7: /* Read MultiKey model numbers */ + kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n"); + kbc_at_queue_add(dev, 0x02); + kbc_at_queue_add(dev, 0x87); + kbc_at_queue_add(dev, 0x02); + return 0; + + default: + break; + } + + return write64_generic(dev, val); +} + static uint8_t write64_siemens(void *priv, uint8_t val) { @@ -1833,24 +2052,8 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { kbc_at_log("ATkbc: write P2\n"); -#if 0 - /* Fast A20 - ignore all other bits. */ - val = (val & 0x02) | (dev->p2 & 0xfd); - - /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), - discovered by reverse-engineering the AOpeN Vi15G BIOS. */ - if (dev->ami_flags & 0x04) { - /* If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged. */ - val &= ~0x0c; - val |= (dev->p2 & 0x0c); - } - - write_p2_fast_a20(dev, val | 0x01); -#else /* Fast A20 - ignore all other bits. */ write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); -#endif dev->wantdata = 0; dev->state = STATE_MAIN_IBF; @@ -1866,6 +2069,11 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) dev->state = STATE_KBC_PARAM; dev->command = 0xd1; return; + } else if (fast_reset && ((val & 0xf0) == 0xf0)) { + pulse_output(dev, val & 0x0f); + + dev->state = STATE_MAIN_IBF; + return; } break; @@ -1894,6 +2102,11 @@ kbc_at_read(uint16_t port, void *priv) This also means that in AT mode, the IRQ is level-triggered. */ if (!(dev->misc_flags & FLAG_PS2)) picintclevel(1 << 1, &dev->irq_state); + /* I"m not even sure if this is correct but the PB450 absolutely requires this. */ + if (dev->suppress_cmd_intr) { + picint_common(1 << 1, 0, 1, NULL); + dev->suppress_cmd_intr = 0; + } if ((strstr(machine_get_internal_name(), "pb") != NULL) && (cpu_override_dynarec == 1)) cpu_override_dynarec = 0; break; @@ -1936,6 +2149,8 @@ kbc_at_reset(void *priv) kbc_at_queue_reset(dev); + dev->suppress_cmd_intr = 0; + dev->sc_or = 0; dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 0x01 : 0x00; @@ -1989,10 +2204,14 @@ kbc_at_close(void *priv) void kbc_at_handler(int set, void *priv) { - io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + if (kbc_handler_set) { + io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + } - if (set) { + kbc_handler_set = set; + + if (kbc_handler_set) { io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); } @@ -2015,6 +2234,7 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; + kbc_handler_set = 0; kbc_at_handler(1, dev); timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1); @@ -2085,6 +2305,11 @@ kbc_at_init(const device_t *info) dev->write64_ven = write64_ami; break; + case KBC_VEN_PHOENIX: + dev->write60_ven = write60_phoenix; + dev->write64_ven = write64_phoenix; + break; + case KBC_VEN_QUADTEL: dev->write60_ven = write60_quadtel; dev->write64_ven = write64_quadtel; @@ -2113,6 +2338,8 @@ kbc_at_init(const device_t *info) /* The actual keyboard. */ device_add(&keyboard_at_generic_device); + fast_reset = 0x00; + return dev; } @@ -2298,6 +2525,20 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; +const device_t keyboard_ps2_phoenix_device = { + .name = "PS/2 Keyboard (Phoenix)", + .internal_name = "keyboard_ps2_phoenix", + .flags = DEVICE_KBC, + .local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_tg_ami_device = { .name = "PS/2 Keyboard (TriGem AMI)", .internal_name = "keyboard_ps2_tg_ami", diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d203a52e8..3793f778b 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -516,24 +516,29 @@ ide_hd_identify(const ide_t *ide) { char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; const ide_bm_t *bm = ide_boards[ide->board]->bm; - const uint32_t d_spt = ide->spt; uint64_t full_size = (((uint64_t) hdd[ide->hdd_num].tracks) * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - uint32_t d_hpc; - uint32_t d_tracks; device_identify[6] = (ide->hdd_num / 10) + 0x30; device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); - if (ide->hpc <= 16) { + uint32_t d_hpc = ide->hpc; + uint32_t d_spt = ide->spt; + uint32_t d_tracks; + + if ((ide->hpc <= 16) && (ide->spt <= 63)) { /* HPC <= 16, report as needed. */ d_tracks = ide->tracks; - d_hpc = ide->hpc; } else { /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; + if (ide->hpc > 16) + d_hpc = 16; + if (ide->spt > 63) + d_spt = 63; + d_tracks = (ide->tracks * ide->hpc * ide->spt) / (16 * 63); + if (d_tracks > 16383) + d_tracks = 16383; } /* Specify default CHS translation */ @@ -579,7 +584,7 @@ ide_hd_identify(const ide_t *ide) */ ide->buffer[53] = 1; - if (ide->cfg_spt != 0) { + if (ide->params_specified) { ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; ide->buffer[55] = ide->cfg_hpc; ide->buffer[56] = ide->cfg_spt; @@ -2427,10 +2432,12 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) err = ABRT_ERR; else { - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ + /* Only accept after RESET or DIAG. */ + if (ide->params_specified) { ide->cfg_spt = ide->tf->secount; ide->cfg_hpc = ide->tf->head + 1; + + ide->params_specified = 1; } ide->command = 0x00; ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2744,8 +2751,26 @@ ide_board_setup(const int board) dev->tf->error = 1; if (dev->type != IDE_HDD) dev->cfg_spt = dev->cfg_hpc = 0; - if (dev->type == IDE_HDD) + if (dev->type == IDE_HDD) { dev->blocksize = hdd[dev->hdd_num].max_multiple_block; + + /* Calculate the default heads and sectors. */ + uint32_t d_hpc = dev->hpc; + uint32_t d_spt = dev->spt; + + if ((dev->hpc > 16) || (dev->spt > 63)) { + /* HPC > 16, convert to 16 HPC. */ + if (dev->hpc > 16) + d_hpc = 16; + if (dev->spt > 63) + d_spt = 63; + } + + dev->cfg_spt = d_spt; + dev->cfg_hpc = d_hpc; + } + + dev->params_specified = 0; } } diff --git a/src/disk/mo.c b/src/disk/mo.c index c93f4b055..e90267b95 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -1677,8 +1677,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x07; /*Optical disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/disk/zip.c b/src/disk/zip.c index 08d3baee3..d4cbd0b41 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -1865,8 +1865,8 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->buffer, 0, 8); - if (cdb[1] & 0xe0) - dev->buffer[0] = 0x60; /*No physical device on this LUN*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ else dev->buffer[0] = 0x00; /*Hard disk*/ dev->buffer[1] = 0x80; /*Removable*/ diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 4ee808d69..9094f7f00 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -82,7 +82,7 @@ typedef struct ide_s { uint8_t selected; uint8_t command; uint8_t head; - uint8_t pad; + uint8_t params_specified; int type; int board; int irqstat; diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0d8b2e745..79665c9a9 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -245,6 +245,7 @@ extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_tg_ami_device; extern const device_t keyboard_ps2_tg_ami_green_device; extern const device_t keyboard_ps2_olivetti_device; +extern const device_t keyboard_ps2_phoenix_device; extern const device_t keyboard_ps2_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; @@ -276,7 +277,9 @@ extern int keyboard_isfsexit_up(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); +extern void kbc_at_set_fast_reset(uint8_t new_fast_reset); extern void kbc_at_handler(int set, void *priv); + extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 216fdb2ad..64d3bc853 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -308,7 +308,7 @@ #define BUS_REQ 0x20 #define BUS_BSY 0x40 #define BUS_RST 0x80 -#define BUS_ACK 0x200 +#define BUS_ACK 0x100 #define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t) val << 16) diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 55c3bf3c5..8baa4f9d8 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -109,14 +109,10 @@ typedef struct ncr_t { int data_pos; int irq; - int simple_pseudo_dma; - - uint32_t block_count; double period; void *priv; - void (*dma_init_ext)(void *priv, void *ext_priv, int send); void (*dma_mode_ext)(void *priv, void *ext_priv); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); @@ -131,11 +127,11 @@ extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); extern void ncr5380_bus_read(ncr_t *ncr); extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); -extern uint8_t ncr5380_drq(ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); #ifdef EMU_DEVICE_H extern const device_t scsi_lcs6821n_device; +extern const device_t scsi_pas_device; extern const device_t scsi_rt1000b_device; extern const device_t scsi_rt1000mc_device; extern const device_t scsi_t128_device; @@ -145,7 +141,6 @@ extern const device_t scsi_ls2000_device; #if defined(DEV_BRANCH) && defined(USE_SUMO) extern const device_t scsi_scsiat_device; #endif -extern const device_t scsi_pas_device; #endif #endif /*SCSI_NCR5380_H*/ diff --git a/src/include/86box/scsi_ncr53c400.h b/src/include/86box/scsi_t128.h similarity index 55% rename from src/include/86box/scsi_ncr53c400.h rename to src/include/86box/scsi_t128.h index 9a5315990..65148a5d1 100644 --- a/src/include/86box/scsi_ncr53c400.h +++ b/src/include/86box/scsi_t128.h @@ -18,45 +18,34 @@ * Copyright 2017-2024 TheCollector1995. */ -#ifndef SCSI_NCR53C400_H -#define SCSI_NCR53C400_H +#ifndef SCSI_T128_H +#define SCSI_T128_H -typedef struct ncr53c400_t { - rom_t bios_rom; - mem_mapping_t mapping; +typedef struct t128_t { ncr_t ncr; + rom_t bios_rom; + mem_mapping_t mapping; + + uint8_t ctrl; + uint8_t status; uint8_t buffer[512]; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; + uint8_t ext_ram[0x80]; + uint8_t block_count; + + int block_loaded; + int pos, host_pos; uint32_t rom_addr; - uint16_t base; - int8_t type; - uint8_t block_count; - uint8_t status_ctrl; - - int simple_ctrl; - - int block_count_loaded; - - int buffer_pos; - int buffer_host_pos; - - int busy; + int bios_enabled; uint8_t pos_regs[8]; pc_timer_t timer; -} ncr53c400_t; +} t128_t; -#define CTRL_DATA_DIR 0x40 -#define STATUS_BUFFER_NOT_READY 0x04 -#define STATUS_5380_ACCESSIBLE 0x80 +extern void t128_write(uint32_t addr, uint8_t val, void *priv); +extern uint8_t t128_read(uint32_t addr, void *priv); -extern void ncr53c400_simple_write(uint8_t val, void *priv); -extern void ncr53c400_write(uint32_t addr, uint8_t val, void *priv); -extern uint8_t ncr53c400_simple_read(void *priv); -extern uint8_t ncr53c400_read(uint32_t addr, void *priv); -extern void ncr53c400_callback(void *priv); +extern void t128_callback(void *priv); -#endif /*SCSI_NCR53C400_H*/ +#endif /*SCSI_T128_H*/ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index c7098cfdb..d5fc88fb4 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -43,6 +43,7 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37c935_370_device; extern const device_t fdc37c935_no_nvr_device; extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d4cd5fe16..1a6a6db67 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -702,13 +702,13 @@ machine_at_pb450_init(const machine_t *model) pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5428_vlb_onboard_device); + device_add(machine_get_vid_device(machine)); - device_add(&opti602_device); device_add(&opti895_device); + device_add(&opti602_device); device_add(&opti822_device); - device_add(&keyboard_ps2_ami_device); - device_add(&fdc37c661_ide_device); + device_add(&keyboard_ps2_phoenix_device); + device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_sec_device); device_add(&intel_flash_bxt_device); device_add(&phoenix_486_jumper_pci_device); @@ -2223,10 +2223,10 @@ machine_at_dvent4xx_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_cmd640_vlb_pri_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_ps2_device); + device_add(&keyboard_ps2_phoenix_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_phoenix_trio32_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); return ret; } diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7bbf49edf..9e2ed9a26 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -657,7 +657,7 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&sst_flash_29ee020_device); return ret; @@ -726,7 +726,7 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add(&fdc37c935_370_device); device_add(&intel_flash_bxt_device); return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7fbae3a32..dd3d58625 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -6522,10 +6522,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &gd5428_vlb_onboard_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, .snd_device = NULL, .net_device = NULL }, @@ -6804,10 +6804,10 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = &s3_phoenix_trio32_onboard_vlb_device, + .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &s3_phoenix_trio32_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, diff --git a/src/mem/spd.c b/src/mem/spd.c index a3bcba46d..a0896a05a 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -136,7 +136,7 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m /* Look for a module to split. */ split = 0; for (row = 0; row < slot_count; row++) { - if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) + if ((rows[row] <= (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row])))) continue; /* no module here, module is too small to be split, or asymmetric module */ /* Find next empty row. */ diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 9f5421ee9..ee6d77849 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -391,13 +391,13 @@ msgid "Video:" msgstr "Video:" msgid "Voodoo Graphics" -msgstr "Voodoo đồ họa" +msgstr "Đồ họa Voodoo" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A đồ họa" +msgstr "Đồ họa IBM 8514/A" msgid "XGA Graphics" -msgstr "XGA đồ họa" +msgstr "Đồ họa XGA" msgid "Mouse:" msgstr "Chuột:" @@ -442,7 +442,7 @@ msgid "Use FLOAT32 sound" msgstr "Dùng âm FLOAT32" msgid "FM synth driver" -msgstr "Driver bộ tổng hợp (synth) FM" +msgstr "Driver bộ tổng hợp âm FM" msgid "Nuked (more accurate)" msgstr "Nuked (chính xác hơn)" @@ -508,10 +508,10 @@ msgid "Parallel port 4" msgstr "Cổng parallel 4" msgid "HD Controller:" -msgstr "Bộ điều khiển HD:" +msgstr "Bộ điều khiển ổ cứng:" msgid "FD Controller:" -msgstr "Bộ điều khiển FD:" +msgstr "Bộ điều khiển ổ mềm:" msgid "Tertiary IDE Controller" msgstr "Bộ điều khiển IDE thứ ba" @@ -841,7 +841,7 @@ msgid "86Box v" msgstr "86Box v" msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." +msgstr "Trình giả lập các dòng máy tính cổ.\n\nTác giả: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, cùng những người khác.\n\nCùng với những đóng góp cốt cán từ Sarah Walker, leilei, JohnElliott, greatpsycho, và một số người khác.\n\nPhát hành dưới giấy phép GNU General Public License version 2 trở đi. Đọc LICENSE để biết thêm thông tin." msgid "Hardware not available" msgstr "Phần cứng không có sẵn" @@ -889,7 +889,7 @@ msgid "You are loading an unsupported configuration" msgstr "Bạn đang load tinh chỉnh không được hỗ trợ." msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị closed as invalid (đóng vì phạm quy)." +msgstr "Phần chọn loại CPU dựa trên mẫu máy đã chọn bị vô hiệu hóa.\n\nỞ đây bạn có thể chọn loại CPU có thể không tương thích với mẫu máy hiện tại. Tuy nhiên bạn có thể gặp vấn đề tương khắc với BIOS hay phần mềm khác.\n\nViệc bật tùy chọn này lên không được khuyến cáo chính thức và các bản bug report (báo lỗi) với nội dung tương tự sẽ bị coi là phạm quy và đóng." msgid "Continue" msgstr "Tiếp tục" @@ -916,7 +916,7 @@ msgid "Resume execution" msgstr "Tiếp tục chạy thực thi" msgid "Pause execution" -msgstr "Dừng chạy thực thi" +msgstr "Tạm dừng thực thi" msgid "Press Ctrl+Alt+Del" msgstr "Nhấn Ctrl+Alt+Del" diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index def3a4385..b031e6544 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -134,7 +134,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; int value = 0; - auto selected = static_cast(blank.toStdString().c_str()); + auto selected = blank; switch (config_major_type) { default: @@ -246,7 +246,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) p += !!rom_present(const_cast(bios->files[d])); if (p == bios->files_no) { const int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) + if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) currentIndex = row; } q++; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 8a9f72946..47ba0535e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2794,6 +2794,15 @@ begin: return; } + if (max_len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + scsi_cdrom_buf_free(dev); + return; + } + if (!(cdb[2] & 0x40)) alloc_length = 4; else @@ -3189,7 +3198,10 @@ begin: size_idx = 4; memset(dev->buffer, 0, 8); - dev->buffer[0] = 5; /*CD-ROM*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->buffer[0] = 5; /*CD-ROM*/ dev->buffer[1] = 0x80; /*Removable*/ if (dev->drv->bus_type == CDROM_BUS_SCSI) { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 39a69ea32..f29e85431 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1328,7 +1328,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) size_idx = 4; memset(dev->temp_buffer, 0, 8); - dev->temp_buffer[0] = 0; /*SCSI HD*/ + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->temp_buffer[0] = 0x7f; /*No physical device on this LUN*/ + else + dev->temp_buffer[0] = 0; /*SCSI HD*/ dev->temp_buffer[1] = 0; /*Fixed*/ dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d256de764..527ff373f 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -326,19 +326,6 @@ ncr5380_bus_update(ncr_t *ncr, int bus) ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); } } - - if (ncr->simple_pseudo_dma) { - if (dev->phase == SCSI_PHASE_DATA_IN) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 1); - } else if (dev->phase == SCSI_PHASE_DATA_OUT) { - ncr->block_count = dev->buffer_length / 512; - - ncr->dma_init_ext(ncr, ncr->priv, 0); - } - } - ncr->new_phase = dev->phase; } } @@ -358,10 +345,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle in\n"); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 1); - else - ncr->timer(ncr->priv, ncr->period); + ncr->timer(ncr->priv, ncr->period); } else { ncr5380_log("DMA mode IN.\n"); ncr->clear_req = 3; @@ -388,10 +372,7 @@ ncr5380_bus_update(ncr_t *ncr, int bus) if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; ncr5380_log("DMA mode idle out\n"); - if (!ncr->simple_pseudo_dma) - ncr->timer(ncr->priv, ncr->period); - if (ncr->simple_pseudo_dma) - ncr->dma_init_ext(ncr, ncr->priv, 0); + ncr->timer(ncr->priv, ncr->period); } else ncr->clear_req = 3; @@ -517,21 +498,6 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr5380_bus_update(ncr, bus_host); } -uint8_t -ncr5380_drq(ncr_t *ncr) -{ - uint8_t ret = 0; - int bus; - - ncr5380_bus_read(ncr); - bus = ncr->cur_bus; - - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - ret = 1; - - return ret; -} - uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { @@ -579,6 +545,8 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ret |= BUS_SEL; if (ncr->icr & ICR_BSY) ret |= BUS_BSY; + // if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN) + // ret &= ~BUS_REQ; break; case 5: /* Bus and Status register */ diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index f4bd9de59..1ed8e520e 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -41,7 +41,6 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> #define LCS6821N_ROM "roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin" #define COREL_LS2000_ROM "roms/scsi/ncr5380/Corel LS2000 - BIOS ROM - Ver 1.65.bin" @@ -49,14 +48,43 @@ #define RT1000B_820R_ROM "roms/scsi/ncr5380/RTBIOS82.ROM" #define T130B_ROM "roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin" +#define CTRL_DATA_DIR 0x40 +#define STATUS_BUFFER_NOT_READY 0x04 +#define STATUS_5380_ACCESSIBLE 0x80 + enum { ROM_LCS6821N = 0, ROM_LS2000, ROM_RT1000B, - ROM_T130B, - ROM_PAS + ROM_T130B }; +typedef struct ncr53c400_t { + rom_t bios_rom; + mem_mapping_t mapping; + ncr_t ncr; + uint8_t buffer[128]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + uint32_t rom_addr; + uint16_t base; + + int8_t type; + uint8_t block_count; + uint8_t status_ctrl; + + int block_count_loaded; + + int buffer_pos; + int buffer_host_pos; + + int busy; + uint8_t pos_regs[8]; + + pc_timer_t timer; +} ncr53c400_t; + #ifdef ENABLE_NCR53C400_LOG int ncr53c400_do_log = ENABLE_NCR53C400_LOG; @@ -75,29 +103,8 @@ ncr53c400_log(const char *fmt, ...) # define ncr53c400_log(fmt, ...) #endif -void -ncr53c400_simple_write(uint8_t val, void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ncr400->buffer[ncr400->buffer_host_pos++] = val; - - ncr53c400_log("Write host pos = %i, val = %02x\n", ncr400->buffer_host_pos, val); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr400->busy = 1; - - ncr53c400_callback(priv); - } - } -} - /* Memory-mapped I/O WRITE handler. */ -void +static void ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -185,30 +192,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } } -uint8_t -ncr53c400_simple_read(void *priv) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) priv; - ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t ret = 0xff; - - if (ncr400->buffer_host_pos < MIN(512, dev->buffer_length)) { - ret = ncr400->buffer[ncr400->buffer_host_pos++]; - ncr53c400_log("Read host pos = %i, ret = %02x\n", ncr400->buffer_host_pos, ret); - - if (ncr400->buffer_host_pos == MIN(512, dev->buffer_length)) { - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x\n", ncr400->status_ctrl); - ncr53c400_callback(priv); - } - } - - return ret; -} - /* Memory-mapped I/O READ handler. */ -uint8_t +static uint8_t ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; @@ -400,34 +385,6 @@ t130b_in(uint16_t port, void *priv) return ret; } -static void -ncr53c400_dma_init_ext(void *priv, void *ext_priv, int send) -{ - ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; - ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - uint8_t val = send ? CTRL_DATA_DIR : 0x00; - - ncr53c400_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode); - ncr400->status_ctrl = (ncr400->status_ctrl & 0x87) | (val & 0x78); - - ncr400->block_count_loaded = 1; - - if (ncr400->status_ctrl & CTRL_DATA_DIR) { - ncr400->buffer_host_pos = MIN(512, dev->buffer_length); - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - } else { - ncr400->buffer_host_pos = 0; - ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - } - if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { - memset(ncr400->buffer, 0, MIN(512, dev->buffer_length)); - ncr53c400_log("DMA buffer init\n"); - ncr->timer(ncr->priv, ncr->period); - } - ncr53c400_log("NCR DMA init\n"); -} - static void ncr53c400_dma_mode_ext(void *priv, void *ext_priv) { @@ -455,21 +412,17 @@ ncr53c400_timer_on_auto(void *ext_priv, double period) timer_on_auto(&ncr400->timer, period); } -void +static void ncr53c400_callback(void *priv) { ncr53c400_t *ncr400 = (void *) priv; ncr_t *ncr = &ncr400->ncr; scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; int bus; - int blocks_left; uint8_t c; uint8_t temp; - const int buf_len = ncr400->simple_ctrl ? 512 : 128; - ncr53c400_log("DMA mode = %i\n", ncr->dma_mode); - - if (!ncr400->simple_ctrl && (ncr->dma_mode != DMA_IDLE)) + if (ncr->dma_mode != DMA_IDLE) timer_on_auto(&ncr400->timer, 1.0); if (ncr->data_wait & 1) { @@ -488,7 +441,7 @@ ncr53c400_callback(void *priv) switch (ncr->dma_mode) { case DMA_SEND: - if (!ncr400->simple_ctrl && (ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (ncr400->status_ctrl & CTRL_DATA_DIR) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; } @@ -522,20 +475,14 @@ ncr53c400_callback(void *priv) ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; ncr400->busy = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -552,7 +499,7 @@ ncr53c400_callback(void *priv) break; case DMA_INITIATOR_RECEIVE: - if (!ncr400->simple_ctrl && !(ncr400->status_ctrl & CTRL_DATA_DIR)) { + if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; } @@ -568,10 +515,8 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) { - ncr53c400_log("ncr->cur_bus & BUS_REQ\n"); + if (ncr->cur_bus & BUS_REQ) break; - } } /* Data ready. */ @@ -586,19 +531,13 @@ ncr53c400_callback(void *priv) ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); - if (ncr400->buffer_pos == MIN(buf_len, dev->buffer_length)) { + if (ncr400->buffer_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl &= ~STATUS_BUFFER_NOT_READY; ncr400->buffer_pos = 0; ncr400->buffer_host_pos = 0; - if (ncr400->simple_ctrl) { - ncr->block_count = (ncr->block_count - 1) & 0xffffffff; - blocks_left = ncr->block_count; - } else { - ncr400->block_count = (ncr400->block_count - 1) & 0xff; - blocks_left = ncr400->block_count; - } - ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", blocks_left); - if (blocks_left == 0) { + ncr400->block_count = (ncr400->block_count - 1) & 0xff; + ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); + if (!ncr400->block_count) { ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -623,8 +562,6 @@ ncr53c400_callback(void *priv) ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - if (ncr400->simple_ctrl) - ncr400->block_count_loaded = 0; } } @@ -719,6 +656,7 @@ ncr53c400_init(const device_t *info) ncr400->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr400); break; + case ROM_LS2000: /* Corel LS2000 */ ncr400->rom_addr = device_get_config_hex20("bios_addr"); ncr->irq = device_get_config_int("irq"); @@ -777,13 +715,6 @@ ncr53c400_init(const device_t *info) t130b_in, NULL, NULL, t130b_out, NULL, NULL, ncr400); break; - case ROM_PAS: /* Pro Audio Spectrum Plus/16 SCSI controller */ - ncr400->simple_ctrl = 1; - ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr->simple_pseudo_dma = 1; - ncr->dma_init_ext = ncr53c400_dma_init_ext; - break; - default: break; } @@ -1076,17 +1007,3 @@ const device_t scsi_ls2000_device = { .force_redraw = NULL, .config = ncr53c400_mmio_config }; - -const device_t scsi_pas_device = { - .name = "Pro Audio Spectrum Plus/16 SCSI", - .internal_name = "scsi_pas", - .flags = DEVICE_ISA, - .local = ROM_PAS, - .init = ncr53c400_init, - .close = ncr53c400_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index b13511eac..7e42a089d 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -41,31 +41,10 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> +#include <86box/scsi_t128.h> #define T128_ROM "roms/scsi/ncr5380/trantor_t128_bios_v1.12.bin" -typedef struct t128_t { - ncr_t ncr; - rom_t bios_rom; - mem_mapping_t mapping; - - uint8_t ctrl; - uint8_t status; - uint8_t buffer[512]; - uint8_t ext_ram[0x80]; - uint8_t block_count; - - int block_loaded; - int pos, host_pos; - - uint32_t rom_addr; - - int bios_enabled; - uint8_t pos_regs[8]; - - pc_timer_t timer; -} t128_t; - #ifdef ENABLE_T128_LOG int t128_do_log = ENABLE_T128_LOG; @@ -85,7 +64,7 @@ t128_log(const char *fmt, ...) #endif /* Memory-mapped I/O WRITE handler. */ -static void +void t128_write(uint32_t addr, uint8_t val, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -122,7 +101,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv) } /* Memory-mapped I/O READ handler. */ -static uint8_t +uint8_t t128_read(uint32_t addr, void *priv) { t128_t *t128 = (t128_t *) priv; @@ -243,7 +222,7 @@ t128_timer_on_auto(void *ext_priv, double period) timer_on_auto(&t128->timer, period); } -static void +void t128_callback(void *priv) { t128_t *t128 = (void *) priv; @@ -506,7 +485,7 @@ t128_init(const device_t *info) t128->pos_regs[0] = 0x8c; t128->pos_regs[1] = 0x50; mca_add(t228_read, t228_write, t228_feedb, NULL, t128); - } else { + } else if (info->local == 0) { ncr->irq = device_get_config_int("irq"); t128->rom_addr = device_get_config_hex20("bios_addr"); t128->bios_enabled = device_get_config_int("boot"); @@ -525,12 +504,13 @@ t128_init(const device_t *info) ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->timer = t128_timer_on_auto; - t128->status = 0x04; + t128->status = 0x00 /*0x04*/; t128->host_pos = 512; if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; - timer_add(&t128->timer, t128_callback, t128, 0); + if (info->local == 0) + timer_add(&t128->timer, t128_callback, t128, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); @@ -616,6 +596,7 @@ const device_t scsi_t128_device = { .config = t128_config }; + const device_t scsi_t228_device = { .name = "Trantor T228", .internal_name = "t228", @@ -629,3 +610,17 @@ const device_t scsi_t228_device = { .force_redraw = NULL, .config = NULL }; + +const device_t scsi_pas_device = { + .name = "Pro Audio Spectrum Plus/16 SCSI", + .internal_name = "scsi_pas", + .flags = DEVICE_ISA, + .local = 1, + .init = t128_init, + .close = t128_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 7d8e12795..97fcb3fbd 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -54,6 +54,7 @@ typedef struct fdc37c93x_t { uint8_t is_apm; uint8_t has_nvr; uint8_t tries; + uint8_t port_370; uint8_t gpio_regs[2]; uint8_t auxio_reg; uint8_t regs[48]; @@ -785,7 +786,7 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = 0xF0; + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xF0; dev->regs[0x27] = 0x03; for (uint8_t i = 0; i < 11; i++) @@ -940,13 +941,14 @@ fdc37c93x_init(const device_t *info) dev->fdc = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; - dev->is_apm = (info->local >> 8) & 0x01; - is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); + dev->chip_id = info->local & 0xff; + dev->is_apm = (info->local >> 8) & 0x01; + is_compaq = (info->local >> 8) & 0x02; + dev->has_nvr = !((info->local >> 8) & 0x04); + dev->port_370 = ((info->local >> 8) & 0x08); dev->gpio_regs[0] = 0xff; #if 0 @@ -1053,6 +1055,20 @@ const device_t fdc37c935_device = { .config = NULL }; +const device_t fdc37c935_370_device = { + .name = "SMC FDC37C935 Super I/O (Port 370h)", + .internal_name = "fdc37c935_370", + .flags = 0, + .local = 0x802, + .init = fdc37c93x_init, + .close = fdc37c93x_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc37c935_no_nvr_device = { .name = "SMC FDC37C935 Super I/O", .internal_name = "fdc37c935", diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index cc01ff6dd..5f13d2f8e 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2124,21 +2124,6 @@ emu8k_update(emu8k_t *emu8k) emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, wavetable_pos_global - emu8k->pos); emu8k_work_eq(buf, wavetable_pos_global - emu8k->pos); - // Clip signal - for (pos = emu8k->pos; pos < wavetable_pos_global; pos++) { - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } - /* Update EMU clock. */ emu8k->wc += (wavetable_pos_global - emu8k->pos); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 859a1fd17..243332257 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -108,8 +108,9 @@ #include <86box/pit.h> #include <86box/pit_fast.h> #include <86box/rom.h> +#include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -#include <86box/scsi_ncr53c400.h> +#include <86box/scsi_t128.h> #include <86box/snd_mpu401.h> #include <86box/sound.h> #include <86box/snd_opl.h> @@ -247,7 +248,7 @@ typedef struct pas16_t { pitf_t * pit; - ncr53c400_t *scsi; + t128_t * scsi; pc_timer_t scsi_timer; } pas16_t; @@ -705,7 +706,6 @@ pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; uint8_t ret = 0xff; - ncr53c400_t *dev = (ncr53c400_t *) pas16->scsi; port -= pas16->base; @@ -763,10 +763,8 @@ pas16_in(uint16_t port, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ret = ncr5380_read(port, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ret = ncr5380_read((port & 0x0003) | ((port & 0x2000) >> 11), &pas16->scsi->ncr); break; case 0x2401: /* Board revision */ @@ -782,20 +780,12 @@ pas16_in(uint16_t port, void *priv) case 0x5c00: if (pas16->has_scsi) - ret = ncr53c400_simple_read(pas16->scsi); + ret = t128_read(0x1e00, pas16->scsi); break; case 0x5c01: - if (pas16->has_scsi) { - ret = ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) << 7; - if (!(ret & 0x80)) { - ncr53c400_callback(pas16->scsi); - if ((dev->ncr.dma_mode != DMA_IDLE) && !(dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - timer_stop(&pas16->scsi_timer); - pas16->timeout_status &= 0x7f; - } - - } - } + if (pas16->has_scsi) + /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */ + ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; break; case 0x5c03: if (pas16->has_scsi) @@ -1187,6 +1177,20 @@ lmc835_update_reg(nsc_mixer_t *mixer) lmc835_recalc(mixer); } +static void +pas16_scsi_callback(void *priv) +{ + pas16_t * pas16 = (pas16_t *) priv; + t128_t * dev = pas16->scsi; + + t128_callback(pas16->scsi); + + if ((dev->ncr.dma_mode != DMA_IDLE) && (dev->status & 0x04)) { + timer_stop(&pas16->scsi_timer); + pas16->timeout_status &= 0x7f; + } +} + static void pas16_timeout_callback(void *priv) { @@ -1491,10 +1495,8 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x1c00 ... 0x1c03: /* NCR5380 ports 0 to 3. */ case 0x3c00 ... 0x3c03: /* NCR5380 ports 4 to 7. */ - if (pas16->has_scsi) { - port = (port & 0x0003) | ((port & 0x2000) >> 11); - ncr5380_write(port, val, &pas16->scsi->ncr); - } + if (pas16->has_scsi) + ncr5380_write((port & 0x0003) | ((port & 0x2000) >> 11), val, &pas16->scsi->ncr); break; case 0x4000: @@ -1516,7 +1518,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) case 0x5c00: if (pas16->has_scsi) - ncr53c400_simple_write(val, pas16->scsi); + t128_write(0x1e00, val, pas16->scsi); break; case 0x5c03: if (pas16->has_scsi) { @@ -2324,6 +2326,7 @@ pas16_init(const device_t *info) if (pas16->has_scsi) { pas16->scsi = device_add(&scsi_pas_device); + timer_add(&pas16->scsi->timer, pas16_scsi_callback, pas16, 0); timer_add(&pas16->scsi_timer, pas16_timeout_callback, pas16, 0); other_scsi_present++; } diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index bbd14a4a0..5b6dbb434 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3103,6 +3103,61 @@ static const device_config_t banshee_sgram_config[] = { } }; +static const device_config_t banshee_sgram_16mbonly_config[] = { + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "4", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 2 + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, +#endif + { + .type = CONFIG_END + } +}; + static const device_config_t banshee_sdram_config[] = { { .name = "bilinear", @@ -3181,7 +3236,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int #endif mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */ else if (has_sgram) { - if (banshee->type == TYPE_VELOCITY100) + if ((banshee->type == TYPE_V3_1000) || (banshee->type == TYPE_VELOCITY200)) + mem_size = 16; /* Our Voodoo 3 1000 and Velocity 200 bios'es are hardcoded to 16 MB. */ + else if (banshee->type == TYPE_VELOCITY100) mem_size = 8; /* Velocity 100 only supports 8 MB */ else mem_size = device_get_config_int("memory"); @@ -3600,7 +3657,7 @@ const device_t voodoo_3_1000_agp_device = { { .available = v3_1000_agp_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config }; const device_t voodoo_3_2000_device = { @@ -3768,5 +3825,5 @@ const device_t velocity_200_agp_device = { { .available = velocity_200_available }, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, - .config = banshee_sgram_config + .config = banshee_sgram_16mbonly_config };