Some FDC, SM(S)C FDC37C66x, and VLSI VL82C480 changes.

This commit is contained in:
OBattler
2025-05-18 08:14:46 +02:00
parent 3f93bde031
commit 7b9b2bc10d
4 changed files with 71 additions and 31 deletions

View File

@@ -132,7 +132,8 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x02: case 0x03:
dev->regs[dev->idx] = val;
if (!strcmp(machine_get_internal_name(), "martin"))
if (!strcmp(machine_get_internal_name(), "martin") ||
!strcmp(machine_get_internal_name(), "prolineamt"))
vl82c480_recalc_banks(dev);
break;
case 0x04:
@@ -140,8 +141,6 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
else
dev->regs[dev->idx] = val;
if (!strcmp(machine_get_internal_name(), "martin"))
dev->regs[dev->idx] &= 0x1f;
break;
case 0x05:
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
@@ -221,6 +220,9 @@ vl82c480_init(const device_t *info)
vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t));
uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 };
uint32_t ms = mem_size;
uint8_t min_i = !strcmp(machine_get_internal_name(), "prolineamt") ? 1 : 0;
uint8_t min_j = !strcmp(machine_get_internal_name(), "prolineamt") ? 4 : 2;
uint8_t max_j = !strcmp(machine_get_internal_name(), "prolineamt") ? 8 : 7;
dev->regs[0x00] = info->local;
dev->regs[0x01] = 0xff;
@@ -231,8 +233,16 @@ vl82c480_init(const device_t *info)
dev->regs[0x07] = 0x21;
dev->regs[0x08] = 0x38;
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 2; j < 7; j++) {
if (!strcmp(machine_get_internal_name(), "prolineamt")) {
dev->banks[0] = 4096;
/* Bank 0 is ignored if 64 MB is installed. */
if (ms != 65536)
ms -= 4096;
}
if (ms > 0) for (uint8_t i = min_i; i < 4; i++) {
for (uint8_t j = min_j; j < max_j; j++) {
if (ms >= sizes[j])
dev->banks[i] = sizes[j];
else

View File

@@ -469,9 +469,11 @@ fdc_update_drv2en(fdc_t *fdc, int drv2en)
void
fdc_update_rate(fdc_t *fdc, int drive)
{
if (((fdc->rwc[drive] == 1) || (fdc->rwc[drive] == 2)) && fdc->enh_mode)
if (((fdc->rwc[drive] == 1) || (fdc->rwc[drive] == 2)) &&
fdc->enh_mode && !(fdc->flags & FDC_FLAG_SMC661))
fdc->bit_rate = 500;
else if ((fdc->rwc[drive] == 3) && fdc->enh_mode)
else if ((fdc->rwc[drive] == 3) && fdc->enh_mode &&
!(fdc->flags & FDC_FLAG_SMC661))
fdc->bit_rate = 250;
else switch (fdc->rate) {
default:
@@ -535,7 +537,7 @@ fdc_get_bitcell_period(fdc_t *fdc)
static int
fdc_get_densel(fdc_t *fdc, int drive)
{
if (fdc->enh_mode) {
if (fdc->enh_mode && !(fdc->flags & FDC_FLAG_SMC661)) {
switch (fdc->rwc[drive]) {
case 1:
case 3:
@@ -770,8 +772,13 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
return;
case 3: /* TDR */
if (fdc->enh_mode) {
drive = real_drive(fdc, fdc->dor & 3);
fdc_update_rwc(fdc, drive, (val & 0x30) >> 4);
if (fdc->flags & FDC_FLAG_SMC661) {
fdc_set_swap(fdc, !!(val & 0x20));
fdc_update_densel_force(fdc, (val & 0x18) >> 3);
} else {
drive = real_drive(fdc, fdc->dor & 3);
fdc_update_rwc(fdc, drive, (val & 0x30) >> 4);
}
}
/* Bit 2: FIFO test mode (PS/55 5550-S,T only. Undocumented)
The Power-on Self Test of PS/55 writes and verifies 8 bytes of FIFO buffer through I/O 3F5h.
@@ -1391,6 +1398,8 @@ fdc_read(uint16_t addr, void *priv)
/* PS/55 POST throws an error and halt if ret = 1 or 2, somehow. */
} else if (!fdc->enh_mode)
ret = 0x20;
else if (fdc->flags & FDC_FLAG_SMC661)
ret = (fdc->densel_force << 3) | ((!!fdc->swap) << 5) | (fdc->media_id << 6);
else
ret = (fdc->rwc[drive] << 4) | (fdc->media_id << 6);
break;
@@ -2401,6 +2410,8 @@ fdc_init(const device_t *info)
fdc_t *fdc = (fdc_t *) calloc(1, sizeof(fdc_t));
fdc->flags = info->local;
if (fdc->flags & FDC_FLAG_SMC661)
pclog("661!\n");
if (fdc->flags & FDC_FLAG_SEC)
fdc->irq = FDC_SECONDARY_IRQ;
@@ -2644,6 +2655,20 @@ const device_t fdc_at_actlow_device = {
.config = NULL
};
const device_t fdc_at_smc_661_device = {
.name = "PC/AT Floppy Drive Controller (SM(s)C FDC37C661/2)",
.internal_name = "fdc_at_smc",
.flags = 0,
.local = FDC_FLAG_AT | FDC_FLAG_SUPERIO | FDC_FLAG_SMC661,
.init = fdc_init,
.close = fdc_close,
.reset = fdc_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t fdc_at_smc_device = {
.name = "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)",
.internal_name = "fdc_at_smc",

View File

@@ -38,26 +38,27 @@
#define FDC_QUATERNARY_IRQ 6
#define FDC_QUATERNARY_DMA 2
#define FDC_FLAG_PCJR 0x01 /* PCjr */
#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */
#define FDC_FLAG_AT 0x04 /* AT+, PS/x */
#define FDC_FLAG_PS2 0x08 /* PS/1, PS/2 ISA */
#define FDC_FLAG_PS2_MCA 0x10 /* PS/2 MCA */
#define FDC_FLAG_SUPERIO 0x20 /* Super I/O chips */
#define FDC_FLAG_START_RWC_1 0x40 /* W83877F, W83977F */
#define FDC_FLAG_MORE_TRACKS 0x80 /* W83877F, W83977F, PC87306, PC87309 */
#define FDC_FLAG_NSC 0x100 /* PC87306, PC87309 */
#define FDC_FLAG_TOSHIBA 0x200 /* T1000, T1200 */
#define FDC_FLAG_AMSTRAD 0x400 /* Non-AT Amstrad machines */
#define FDC_FLAG_UMC 0x800 /* UMC UM8398 */
#define FDC_FLAG_ALI 0x1000 /* ALi M512x / M1543C */
#define FDC_FLAG_NO_DSR_RESET 0x2000 /* Has no DSR reset */
#define FDC_FLAG_DENSEL_INVERT 0x4000 /* Invert DENSEL polarity */
#define FDC_FLAG_FINTR 0x8000 /* Raise FINTR on data command finish */
#define FDC_FLAG_NEC 0x10000 /* Is NEC upd765-compatible */
#define FDC_FLAG_SEC 0x20000 /* Is Secondary */
#define FDC_FLAG_TER 0x40000 /* Is Tertiary */
#define FDC_FLAG_QUA 0x80000 /* Is Quaternary */
#define FDC_FLAG_PCJR 0x01 /* PCjr */
#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */
#define FDC_FLAG_AT 0x04 /* AT+, PS/x */
#define FDC_FLAG_PS2 0x08 /* PS/1, PS/2 ISA */
#define FDC_FLAG_PS2_MCA 0x10 /* PS/2 MCA */
#define FDC_FLAG_SUPERIO 0x20 /* Super I/O chips */
#define FDC_FLAG_START_RWC_1 0x40 /* W83877F, W83977F */
#define FDC_FLAG_MORE_TRACKS 0x80 /* W83877F, W83977F, PC87306, PC87309 */
#define FDC_FLAG_NSC 0x100 /* PC87306, PC87309 */
#define FDC_FLAG_TOSHIBA 0x200 /* T1000, T1200 */
#define FDC_FLAG_AMSTRAD 0x400 /* Non-AT Amstrad machines */
#define FDC_FLAG_UMC 0x800 /* UMC UM8398 */
#define FDC_FLAG_ALI 0x1000 /* ALi M512x / M1543C */
#define FDC_FLAG_NO_DSR_RESET 0x2000 /* Has no DSR reset */
#define FDC_FLAG_DENSEL_INVERT 0x4000 /* Invert DENSEL polarity */
#define FDC_FLAG_FINTR 0x8000 /* Raise FINTR on data command finish */
#define FDC_FLAG_NEC 0x10000 /* Is NEC upd765-compatible */
#define FDC_FLAG_SEC 0x20000 /* Is Secondary */
#define FDC_FLAG_TER 0x40000 /* Is Tertiary */
#define FDC_FLAG_QUA 0x80000 /* Is Quaternary */
#define FDC_FLAG_SMC661 0x100000 /* SM(s)C FDC37C661 - different TDR enhanced mode */
typedef struct fdc_t {
uint8_t dor;
@@ -260,6 +261,7 @@ extern const device_t fdc_at_sec_device;
extern const device_t fdc_at_ter_device;
extern const device_t fdc_at_qua_device;
extern const device_t fdc_at_actlow_device;
extern const device_t fdc_at_smc_661_device;
extern const device_t fdc_at_smc_device;
extern const device_t fdc_at_ali_device;
extern const device_t fdc_at_winbond_device;

View File

@@ -314,7 +314,10 @@ fdc37c6xx_init(const device_t *info)
{
fdc37c6xx_t *dev = (fdc37c6xx_t *) calloc(1, sizeof(fdc37c6xx_t));
dev->fdc = device_add(&fdc_at_smc_device);
if (dev->chip_id >= 0x63)
dev->fdc = device_add(&fdc_at_smc_device);
else
dev->fdc = device_add(&fdc_at_smc_661_device);
dev->chip_id = info->local & 0xff;
dev->has_ide = (info->local >> 8) & 0xff;