Merge branch 'master' of https://github.com/86Box/86Box into 86Box-master
This commit is contained in:
@@ -9,13 +9,29 @@
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2024 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_monster.c fdc_pii15xb.c
|
||||
fdi2raw.c fdd_common.c fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_pcjs.c
|
||||
fdd_mfm.c fdd_td0.c)
|
||||
add_library(fdd OBJECT
|
||||
fdd.c
|
||||
fdc.c
|
||||
fdc_compaticard.c
|
||||
fdc_magitronic.c
|
||||
fdc_monster.c
|
||||
fdc_pii15xb.c
|
||||
fdi2raw.c
|
||||
fdd_common.c
|
||||
fdd_86f.c
|
||||
fdd_fdi.c
|
||||
fdd_imd.c
|
||||
fdd_img.c
|
||||
fdd_pcjs.c
|
||||
fdd_mfm.c
|
||||
fdd_td0.c
|
||||
)
|
||||
|
||||
add_subdirectory(lzw)
|
||||
target_link_libraries(86Box lzw)
|
||||
|
||||
322
src/floppy/fdc.c
322
src/floppy/fdc.c
@@ -103,15 +103,18 @@ typedef const struct {
|
||||
|
||||
static fdc_cards_t fdc_cards[] = {
|
||||
// clang-format off
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
{ &fdc_xt_device },
|
||||
{ &fdc_at_device },
|
||||
{ &fdc_b215_device },
|
||||
{ &fdc_pii151b_device },
|
||||
{ &fdc_pii158b_device },
|
||||
{ &fdc_monster_device },
|
||||
{ NULL }
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
{ &fdc_b215_device },
|
||||
{ &fdc_pii151b_device },
|
||||
{ &fdc_pii158b_device },
|
||||
{ &fdc_compaticard_i_device },
|
||||
{ &fdc_compaticard_ii_device },
|
||||
#if 0
|
||||
{ &fdc_compaticard_iv_device },
|
||||
#endif
|
||||
{ &fdc_monster_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -177,15 +180,13 @@ fdc_ctrl_reset(void *priv)
|
||||
{
|
||||
fdc_t *fdc = (fdc_t *) priv;
|
||||
|
||||
fdc->stat = 0x80;
|
||||
fdc->stat = 0x80;
|
||||
fdc->pnum = fdc->ptot = 0;
|
||||
fdc->st0 = 0;
|
||||
fdc->lock = 0;
|
||||
fdc->head = 0;
|
||||
fdc->step = 0;
|
||||
fdc->power_down = 0;
|
||||
if (!(fdc->flags & FDC_FLAG_AT))
|
||||
fdc->rate = 2;
|
||||
}
|
||||
|
||||
sector_id_t
|
||||
@@ -612,9 +613,11 @@ fdc_io_command_phase1(fdc_t *fdc, int out)
|
||||
|
||||
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
|
||||
fdc->stat = out ? 0x10 : 0x50;
|
||||
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma)
|
||||
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) {
|
||||
fdc->stat |= 0x20;
|
||||
else
|
||||
if (out)
|
||||
fdc->stat |= 0x80;
|
||||
} else
|
||||
dma_set_drq(fdc->dma_ch, 1);
|
||||
}
|
||||
|
||||
@@ -652,13 +655,31 @@ fdc_sis(fdc_t *fdc)
|
||||
fdc->paramstogo = 2;
|
||||
}
|
||||
|
||||
static void
|
||||
fdc_soft_reset(fdc_t *fdc)
|
||||
{
|
||||
if (fdc->power_down) {
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
fdc->interrupt = -5;
|
||||
} else {
|
||||
timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC);
|
||||
fdc->interrupt = -1;
|
||||
|
||||
fdc->perp &= 0xfc;
|
||||
|
||||
for (int i = 0; i < FDD_NUM; i++)
|
||||
ui_sb_update_icon(SB_FLOPPY | i, 0);
|
||||
|
||||
fdc_ctrl_reset(fdc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
fdc_t *fdc = (fdc_t *) priv;
|
||||
|
||||
int drive;
|
||||
int i;
|
||||
int drive_num;
|
||||
|
||||
fdc_log("Write FDC %04X %02X\n", addr, val);
|
||||
@@ -682,7 +703,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc->interrupt = -1;
|
||||
ui_sb_update_icon(SB_FLOPPY | 0, 0);
|
||||
fdc_ctrl_reset(fdc);
|
||||
fdd_changed[0] = 1;
|
||||
}
|
||||
if (!fdd_get_flags(0))
|
||||
val &= 0xfe;
|
||||
@@ -699,24 +719,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc->stat = 0x00;
|
||||
fdc->pnum = fdc->ptot = 0;
|
||||
}
|
||||
if ((val & 4) && !(fdc->dor & 4)) {
|
||||
if (fdc->power_down) {
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
fdc->interrupt = -5;
|
||||
} else {
|
||||
timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC);
|
||||
fdc->interrupt = -1;
|
||||
|
||||
fdc->perp &= 0xfc;
|
||||
|
||||
for (i = 0; i < FDD_NUM; i++)
|
||||
ui_sb_update_icon(SB_FLOPPY | i, 0);
|
||||
|
||||
fdc_ctrl_reset(fdc);
|
||||
}
|
||||
}
|
||||
if ((val & 4) && !(fdc->dor & 4))
|
||||
fdc_soft_reset(fdc);
|
||||
/* We can now simplify this since each motor now spins separately. */
|
||||
for (i = 0; i < FDD_NUM; i++) {
|
||||
for (int i = 0; i < FDD_NUM; i++) {
|
||||
drive_num = real_drive(fdc, i);
|
||||
if ((!fdd_get_flags(drive_num)) || (drive_num >= FDD_NUM))
|
||||
val &= ~(0x10 << drive_num);
|
||||
@@ -749,28 +755,14 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
case 4: /* DSR */
|
||||
if (!(fdc->flags & FDC_FLAG_NO_DSR_RESET)) {
|
||||
if (!(val & 0x80)) {
|
||||
timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC);
|
||||
fdc->interrupt = -6;
|
||||
}
|
||||
if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) {
|
||||
if (fdc->power_down) {
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
fdc->interrupt = -5;
|
||||
} else {
|
||||
timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC);
|
||||
fdc->interrupt = -1;
|
||||
|
||||
fdc->perp &= 0xfc;
|
||||
|
||||
for (i = 0; i < FDD_NUM; i++)
|
||||
ui_sb_update_icon(SB_FLOPPY | i, 0);
|
||||
|
||||
fdc_ctrl_reset(fdc);
|
||||
}
|
||||
}
|
||||
if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80)))
|
||||
fdc_soft_reset(fdc);
|
||||
}
|
||||
fdc->dsr = val;
|
||||
return;
|
||||
@@ -1231,7 +1223,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_UMC))
|
||||
return;
|
||||
fdc->rate = val & 0x03;
|
||||
if (fdc->flags & FDC_FLAG_PS1)
|
||||
if (fdc->flags & FDC_FLAG_PS2)
|
||||
fdc->noprec = !!(val & 0x04);
|
||||
return;
|
||||
|
||||
@@ -1251,23 +1243,43 @@ fdc_read(uint16_t addr, void *priv)
|
||||
|
||||
if (!fdc->power_down || ((addr & 7) == 2)) switch (addr & 7) {
|
||||
case 0: /* STA */
|
||||
if (fdc->flags & FDC_FLAG_PS1) {
|
||||
if (fdc->flags & FDC_FLAG_PS2) {
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
ret = 0x00;
|
||||
/* TODO:
|
||||
Bit 2: INDEX (best return always 0 as it goes by very fast)
|
||||
*/
|
||||
if (fdc->seek_dir) /* nDIRECTION */
|
||||
if (fdc->seek_dir) /* nDIRECTION */
|
||||
ret |= 0x01;
|
||||
if (writeprot[drive]) /* WRITEPROT */
|
||||
if (writeprot[drive]) /* WRITEPROT */
|
||||
ret |= 0x02;
|
||||
if (!fdd_get_head(drive)) /* nHDSEL */
|
||||
if (!fdd_get_head(drive)) /* nHDSEL */
|
||||
ret |= 0x08;
|
||||
if (fdd_track0(drive)) /* TRK0 */
|
||||
if (fdd_track0(drive)) /* TRK0 */
|
||||
ret |= 0x10;
|
||||
if (fdc->step) /* STEP */
|
||||
if (fdc->step) /* STEP */
|
||||
ret |= 0x20;
|
||||
if (dma_get_drq(fdc->dma_ch)) /* DRQ */
|
||||
if (dma_get_drq(fdc->dma_ch)) /* DRQ */
|
||||
ret |= 0x40;
|
||||
if (fdc->fintr || fdc->reset_stat) /* INTR */
|
||||
ret |= 0x80;
|
||||
} else if (fdc->flags & FDC_FLAG_PS2_MCA) {
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
ret = 0x04;
|
||||
/* TODO:
|
||||
Bit 2: nINDEX (best return always 1 as it goes by very fast)
|
||||
*/
|
||||
if (!fdc->seek_dir) /* DIRECTION */
|
||||
ret |= 0x01;
|
||||
if (!writeprot[drive]) /* nWRITEPROT */
|
||||
ret |= 0x02;
|
||||
if (fdd_get_head(drive)) /* HDSEL */
|
||||
ret |= 0x08;
|
||||
if (!fdd_track0(drive)) /* nTRK0 */
|
||||
ret |= 0x10;
|
||||
if (fdc->step) /* STEP */
|
||||
ret |= 0x20;
|
||||
if (!fdd_get_type(1)) /* -Drive 2 Installed */
|
||||
ret |= 0x40;
|
||||
if (fdc->fintr || fdc->reset_stat) /* INTR */
|
||||
ret |= 0x80;
|
||||
@@ -1295,14 +1307,12 @@ fdc_read(uint16_t addr, void *priv)
|
||||
ret = 0xff;
|
||||
break;
|
||||
case 1: /* STB */
|
||||
if (fdc->flags & FDC_FLAG_PS1) {
|
||||
if (fdc->flags & FDC_FLAG_PS2) {
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
ret = 0x00;
|
||||
/* -Drive 2 Installed */
|
||||
if (!fdd_get_type(1))
|
||||
if (!fdd_get_type(1)) /* -Drive 2 Installed */
|
||||
ret |= 0x80;
|
||||
/* -Drive Select 1,0 */
|
||||
switch (drive) {
|
||||
switch (drive) { /* -Drive Select 1,0 */
|
||||
case 0:
|
||||
ret |= 0x43;
|
||||
break;
|
||||
@@ -1319,19 +1329,12 @@ fdc_read(uint16_t addr, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fdc->flags & FDC_FLAG_PS2) {
|
||||
/* Status Register B (PS/2, PS/55) */
|
||||
/* | 1 | 1 | DS0 | WD TOGGLE | RD TOGGLE | WE | MOT EN1 | MOT EN0 | */
|
||||
ret = 0xc0;
|
||||
if (motoron[0]) /* Bit 0: MOT EN0 */
|
||||
ret |= 1;
|
||||
if (motoron[1]) /* Bit 1: MOT EN1 */
|
||||
ret |= 2;
|
||||
if(real_drive(fdc, fdc->dor & 3) == 0) /* Bit 5: Drive Select 0 */
|
||||
ret |= 0x20;
|
||||
}
|
||||
else {
|
||||
} else if (fdc->flags & FDC_FLAG_PS2_MCA) {
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
ret = 0xc0;
|
||||
ret |= (fdc->dor & 0x01) << 5; /* Drive Select 0 */
|
||||
ret |= (fdc->dor & 0x30) >> 4; /* Motor Select 1, 0 */
|
||||
} else {
|
||||
if (is486 || !fdc->enable_3f1)
|
||||
ret = 0xff;
|
||||
else {
|
||||
@@ -1339,19 +1342,12 @@ fdc_read(uint16_t addr, void *priv)
|
||||
drive = real_drive(fdc, fdc->dor & 1);
|
||||
ret = !fdd_is_dd(drive) ? ((fdc->dor & 1) ? 2 : 1) : 0;
|
||||
} else {
|
||||
ret = 0x70;
|
||||
|
||||
/* TODO: What is this and what is it used for?
|
||||
It's almost identical to the PS/2 MCA mode. */
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
|
||||
if (drive)
|
||||
ret &= ~0x40;
|
||||
else
|
||||
ret &= ~0x20;
|
||||
|
||||
if (fdc->dor & 0x10)
|
||||
ret |= 1;
|
||||
if (fdc->dor & 0x20)
|
||||
ret |= 2;
|
||||
ret = 0x70;
|
||||
ret &= ~(drive ? 0x40 : 0x20);
|
||||
ret |= (fdc->dor & 0x30) >> 4; /* Motor Select 1, 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1361,7 +1357,8 @@ fdc_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
case 3:
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
if (fdc->flags & FDC_FLAG_PS1) {
|
||||
/* TODO: FDC_FLAG_PS2_TDR? */
|
||||
if ((fdc->flags & FDC_FLAG_PS2) || (fdc->flags & FDC_FLAG_PS2_MCA)) {
|
||||
/* PS/1 Model 2121 seems return drive type in port
|
||||
* 0x3f3, despite the 82077AA fdc_t not implementing
|
||||
* this. This is presumably implemented outside the
|
||||
@@ -1433,7 +1430,7 @@ fdc_read(uint16_t addr, void *priv)
|
||||
case 7: /*Disk change*/
|
||||
drive = real_drive(fdc, fdc->dor & 3);
|
||||
|
||||
if (fdc->flags & FDC_FLAG_PS1) {
|
||||
if (fdc->flags & FDC_FLAG_PS2) {
|
||||
if (fdc->dor & (0x10 << drive)) {
|
||||
ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x00 : 0x80;
|
||||
ret |= (fdc->dor & 0x08);
|
||||
@@ -1441,18 +1438,15 @@ fdc_read(uint16_t addr, void *priv)
|
||||
ret |= (fdc->rate & 0x03);
|
||||
} else
|
||||
ret = 0x00;
|
||||
}
|
||||
else if (fdc->flags & FDC_FLAG_PS2) {
|
||||
/* Digital Input Register (PS/2, PS/55) */
|
||||
/* | DSKCHG | 1 | 1 | 1 | 1 | DRATE1 | DRATE0 | nHDEN | */
|
||||
ret = 0x78;
|
||||
ret |= (fdc->rate & 0x03) << 1;
|
||||
if (fdc->rate == 1 || fdc->rate == 2)
|
||||
ret |= 0x01;
|
||||
if (fdc->dor & (0x10 << drive))
|
||||
ret |= (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00;
|
||||
}
|
||||
else {
|
||||
} else if (fdc->flags & FDC_FLAG_PS2_MCA) {
|
||||
if (fdc->dor & (0x10 << drive)) {
|
||||
ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00;
|
||||
ret |= ((fdc->rate & 0x03) << 1);
|
||||
ret |= fdc_get_densel(fdc, drive);
|
||||
ret |= 0x78;
|
||||
} else
|
||||
ret = 0xf9;
|
||||
} else {
|
||||
if (fdc->dor & (0x10 << drive)) {
|
||||
if ((drive == 1) && (fdc->flags & FDC_FLAG_TOSHIBA))
|
||||
ret = 0x00;
|
||||
@@ -1484,7 +1478,7 @@ static void
|
||||
fdc_poll_common_finish(fdc_t *fdc, int compare, int st5)
|
||||
{
|
||||
fdc_int(fdc, 1);
|
||||
if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2)))
|
||||
if (!(fdc->flags & FDC_FLAG_FINTR))
|
||||
fdc->fintr = 0;
|
||||
fdc->stat = 0xD0;
|
||||
fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive;
|
||||
@@ -1786,7 +1780,7 @@ fdc_callback(void *priv)
|
||||
} else {
|
||||
fdc->interrupt = -2;
|
||||
fdc_int(fdc, 1);
|
||||
if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2)))
|
||||
if (!(fdc->flags & FDC_FLAG_FINTR))
|
||||
fdc->fintr = 0;
|
||||
fdc->stat = 0xD0;
|
||||
fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->drive;
|
||||
@@ -1878,7 +1872,7 @@ fdc_error(fdc_t *fdc, int st5, int st6)
|
||||
timer_disable(&fdc->timer);
|
||||
|
||||
fdc_int(fdc, 1);
|
||||
if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2)))
|
||||
if (!(fdc->flags & FDC_FLAG_FINTR))
|
||||
fdc->fintr = 0;
|
||||
fdc->stat = 0xD0;
|
||||
fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive;
|
||||
@@ -2287,7 +2281,7 @@ fdc_reset(void *priv)
|
||||
fdc->enable_3f1 = 1;
|
||||
|
||||
fdc_update_enh_mode(fdc, 0);
|
||||
if (fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2))
|
||||
if (fdc->flags & FDC_FLAG_DENSEL_INVERT)
|
||||
fdc_update_densel_polarity(fdc, 0);
|
||||
else
|
||||
fdc_update_densel_polarity(fdc, 1);
|
||||
@@ -2334,6 +2328,9 @@ fdc_reset(void *priv)
|
||||
|
||||
fdc_ctrl_reset(fdc);
|
||||
|
||||
if (!(fdc->flags & FDC_FLAG_AT))
|
||||
fdc->rate = 2;
|
||||
|
||||
fdc->max_track = (fdc->flags & FDC_FLAG_MORE_TRACKS) ? 85 : 79;
|
||||
|
||||
fdc_remove(fdc);
|
||||
@@ -2371,8 +2368,7 @@ fdc_close(void *priv)
|
||||
static void *
|
||||
fdc_init(const device_t *info)
|
||||
{
|
||||
fdc_t *fdc = (fdc_t *) malloc(sizeof(fdc_t));
|
||||
memset(fdc, 0, sizeof(fdc_t));
|
||||
fdc_t *fdc = (fdc_t *) calloc(1, sizeof(fdc_t));
|
||||
|
||||
fdc->flags = info->local;
|
||||
|
||||
@@ -2428,7 +2424,7 @@ const device_t fdc_xt_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2442,7 +2438,7 @@ const device_t fdc_xt_sec_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2456,7 +2452,7 @@ const device_t fdc_xt_ter_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2470,7 +2466,7 @@ const device_t fdc_xt_qua_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2484,7 +2480,7 @@ const device_t fdc_xt_t1x00_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2498,7 +2494,7 @@ const device_t fdc_xt_amstrad_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2512,7 +2508,21 @@ const device_t fdc_xt_tandy_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_xt_umc_um8398_device = {
|
||||
.name = "PC/XT Floppy Drive Controller (UMC UM8398)",
|
||||
.internal_name = "fdc_xt_umc_um8398",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_UMC,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2526,7 +2536,7 @@ const device_t fdc_pcjr_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2540,7 +2550,7 @@ const device_t fdc_at_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2554,7 +2564,7 @@ const device_t fdc_at_sec_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2568,7 +2578,7 @@ const device_t fdc_at_ter_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2582,7 +2592,7 @@ const device_t fdc_at_qua_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2596,35 +2606,7 @@ const device_t fdc_at_actlow_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_at_ps1_device = {
|
||||
.name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)",
|
||||
.internal_name = "fdc_at_ps1",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_at_ps1_2121_device = {
|
||||
.name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)",
|
||||
.internal_name = "fdc_at_ps1",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2652,7 +2634,7 @@ const device_t fdc_at_smc_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2666,7 +2648,7 @@ const device_t fdc_at_ali_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2680,7 +2662,7 @@ const device_t fdc_at_winbond_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2694,35 +2676,51 @@ const device_t fdc_at_nsc_device = {
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_dp8473_device = {
|
||||
.name = "NS DP8473 Floppy Drive Controller",
|
||||
.internal_name = "fdc_dp8473",
|
||||
const device_t fdc_at_nsc_dp8473_device = {
|
||||
.name = "PC/AT Floppy Drive Controller (NSC DP8473)",
|
||||
.internal_name = "fdc_at_nsc_dp8473",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_AT | FDC_FLAG_NEC | FDC_FLAG_NO_DSR_RESET,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_um8398_device = {
|
||||
.name = "UMC UM8398 Floppy Drive Controller",
|
||||
.internal_name = "fdc_um8398",
|
||||
const device_t fdc_ps2_device = {
|
||||
.name = "PS/2 Model 25/30 Floppy Drive Controller",
|
||||
.internal_name = "fdc_ps2",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_UMC,
|
||||
.local = FDC_FLAG_FINTR | FDC_FLAG_DENSEL_INVERT | FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW |
|
||||
FDC_FLAG_AT | FDC_FLAG_PS2,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t fdc_ps2_mca_device = {
|
||||
.name = "PS/2 MCA Floppy Drive Controller",
|
||||
.internal_name = "fdc_ps2_mca",
|
||||
.flags = 0,
|
||||
.local = FDC_FLAG_FINTR | FDC_FLAG_DENSEL_INVERT | FDC_FLAG_NO_DSR_RESET | FDC_FLAG_AT |
|
||||
FDC_FLAG_PS2_MCA,
|
||||
.init = fdc_init,
|
||||
.close = fdc_close,
|
||||
.reset = fdc_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
368
src/floppy/fdc_compaticard.c
Normal file
368
src/floppy/fdc_compaticard.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of Micro Solutions CompatiCard I/II/IV.
|
||||
*
|
||||
* Authors: Jasmine Iwanek, <jasmine@iwanek.co.uk>
|
||||
*
|
||||
* Copyright 2022-2025 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define DEVICE_COMPATICARD_I 0
|
||||
#define DEVICE_COMPATICARD_II 1
|
||||
#define DEVICE_COMPATICARD_IV 2
|
||||
|
||||
#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
|
||||
#define ROM_COMPATICARD_IV "roms/floppy/compaticard/ccivbios1.05.bin"
|
||||
|
||||
#define CR_2_MASK 0x2f /* 00101111b */
|
||||
|
||||
typedef struct compaticard_s {
|
||||
rom_t bios_rom;
|
||||
fdc_t *fdc;
|
||||
/*
|
||||
* 7 - Reserved - Set to 0
|
||||
* 6 - Reserved - Set to 0
|
||||
* 5 - Programmable Pin 2 Logic I sets Pin 2 low (TODO)
|
||||
* 4 - Reserved - Set to 0
|
||||
* 3-0 - Data Transfer Rate Select (TODO)
|
||||
* 0000---250 Kbps
|
||||
* 0001-300 Kbps
|
||||
* 1111-500 Kbps
|
||||
*/
|
||||
uint8_t cr_2;
|
||||
} compaticard_t;
|
||||
|
||||
static void
|
||||
compaticard_out(UNUSED(uint16_t port), uint8_t val, void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
|
||||
dev->cr_2 = (val & CR_2_MASK);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaticard_in(UNUSED(uint16_t port), void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
uint8_t ret = (dev->cr_2 &CR_2_MASK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaticard_close(void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
compaticard_init(const device_t *info)
|
||||
{
|
||||
compaticard_t *dev = calloc(1, sizeof(compaticard_t));
|
||||
uint16_t base_addr = device_get_config_hex16("base");
|
||||
uint8_t irq = 6;
|
||||
uint8_t dma = 2;
|
||||
uint16_t cr2_addr = 0x7f2; // Control Register 2
|
||||
|
||||
// CompatiCard II & IV have configurable IRQ and DMA
|
||||
if (info->local >= DEVICE_COMPATICARD_II) {
|
||||
irq = device_get_config_int("irq");
|
||||
dma = device_get_config_int("dma");
|
||||
}
|
||||
|
||||
// Only on CompatiCard IV
|
||||
if ((info->local == DEVICE_COMPATICARD_IV) && (BIOS_ADDR != 0))
|
||||
rom_init(&dev->bios_rom, ROM_COMPATICARD_IV, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
// TODO: Make this neater
|
||||
switch (base_addr) {
|
||||
case FDC_SECONDARY_ADDR:
|
||||
cr2_addr = 0x772;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_sec_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_sec_device);
|
||||
break;
|
||||
|
||||
case FDC_TERTIARY_ADDR:
|
||||
cr2_addr = 0x762;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_ter_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_ter_device);
|
||||
break;
|
||||
|
||||
case FDC_QUATERNARY_ADDR:
|
||||
cr2_addr = 0x7e2;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_qua_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_qua_device);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_device);
|
||||
break;
|
||||
}
|
||||
|
||||
fdc_set_irq(dev->fdc, irq);
|
||||
fdc_set_dma_ch(dev->fdc, dma);
|
||||
|
||||
io_sethandler(cr2_addr, 0x0001,
|
||||
compaticard_in, NULL, NULL,
|
||||
compaticard_out, NULL, NULL,
|
||||
dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int compaticard_iv_available(void)
|
||||
{
|
||||
return rom_present(ROM_COMPATICARD_IV);
|
||||
}
|
||||
|
||||
static const device_config_t compaticard_i_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t compaticard_ii_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 6,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 2", .value = 2 },
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 6", .value = 6 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 2,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 1", .value = 1 },
|
||||
{ .description = "DMA 2", .value = 2 },
|
||||
{ .description = "DMA 3", .value = 3 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t compaticard_iv_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 6,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 2", .value = 2 },
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 6", .value = 6 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 2,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 1", .value = 1 },
|
||||
{ .description = "DMA 2", .value = 2 },
|
||||
{ .description = "DMA 3", .value = 3 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0xce000,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "CE00H", .value = 0xce000 },
|
||||
{ .description = "D000H", .value = 0xd0000 },
|
||||
{ .description = "D800H", .value = 0xd8000 },
|
||||
{ .description = "DE00H", .value = 0xde000 },
|
||||
{ .description = "E000H", .value = 0xe0000 },
|
||||
{ .description = "E800H", .value = 0xe8000 },
|
||||
{ .description = "EE00H", .value = 0xee000 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "autoboot_enabled",
|
||||
.description = "Enable Autoboot",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#endif
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_i_device = {
|
||||
.name = "Micro Solutions CompatiCard I",
|
||||
.internal_name = "compaticard_i",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_i_config
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_ii_device = {
|
||||
.name = "Micro Solutions CompatiCard II",
|
||||
.internal_name = "compaticard_ii",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_ii_config
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_iv_device = {
|
||||
.name = "Micro Solutions CompatiCard IV",
|
||||
.internal_name = "compaticard_iv",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 2,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = compaticard_iv_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_iv_config
|
||||
};
|
||||
@@ -90,12 +90,11 @@ b215_close(void *priv)
|
||||
static void *
|
||||
b215_init(UNUSED(const device_t *info))
|
||||
{
|
||||
b215_t *dev = (b215_t *) malloc(sizeof(b215_t));
|
||||
memset(dev, 0, sizeof(b215_t));
|
||||
b215_t *dev = (b215_t *) calloc(1, sizeof(b215_t));
|
||||
|
||||
rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
dev->fdc_controller = device_add(&fdc_um8398_device);
|
||||
dev->fdc_controller = device_add(&fdc_xt_umc_um8398_device);
|
||||
io_sethandler(FDC_PRIMARY_ADDR, 1, b215_read, NULL, NULL, NULL, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
@@ -110,18 +109,19 @@ b215_available(void)
|
||||
static const device_config_t b215_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = "",
|
||||
.default_int = 0xca000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0xca000,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "CA00H", .value = 0xca000 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
@@ -135,7 +135,7 @@ const device_t fdc_b215_device = {
|
||||
.init = b215_init,
|
||||
.close = b215_close,
|
||||
.reset = NULL,
|
||||
{ .available = b215_available },
|
||||
.available = b215_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = b215_config
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Authors: Jasmine Iwanek, <jasmine@iwanek.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2022-2024 Jasmine Iwanek.
|
||||
* Copyright 2022-2025 Jasmine Iwanek.
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
@@ -165,82 +165,61 @@ static const device_config_t monster_fdc_config[] = {
|
||||
// clang-format off
|
||||
#if 0
|
||||
{
|
||||
.name = "sec_enabled",
|
||||
.description = "Enable Secondary Controller",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = "",
|
||||
.default_int = 0
|
||||
.name = "sec_enabled",
|
||||
.description = "Enable Secondary Controller",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "sec_irq",
|
||||
.description = "Secondary Controller IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 6,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{
|
||||
.description = "IRQ 2",
|
||||
.value = 2
|
||||
},
|
||||
{
|
||||
.description = "IRQ 3",
|
||||
.value = 3
|
||||
},
|
||||
{
|
||||
.description = "IRQ 4",
|
||||
.value = 4
|
||||
},
|
||||
{
|
||||
.description = "IRQ 5",
|
||||
.value = 5
|
||||
},
|
||||
{
|
||||
.description = "IRQ 6",
|
||||
.value = 6
|
||||
},
|
||||
{
|
||||
.description = "IRQ 7",
|
||||
.value = 7
|
||||
},
|
||||
{ .description = "" }
|
||||
}
|
||||
.name = "sec_irq",
|
||||
.description = "Secondary Controller IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 6,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 2", .value = 2 },
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 6", .value = 6 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "sec_dma",
|
||||
.description = "Secondary Controller DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 2,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{
|
||||
.description = "DMA 1",
|
||||
.value = 1
|
||||
},
|
||||
{
|
||||
.description = "DMA 2",
|
||||
.value = 2
|
||||
},
|
||||
{
|
||||
.description = "DMA 3",
|
||||
.value = 3
|
||||
},
|
||||
{ .description = "" }
|
||||
}
|
||||
.name = "sec_dma",
|
||||
.description = "Secondary Controller DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 2,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 1", .value = 1 },
|
||||
{ .description = "DMA 2", .value = 2 },
|
||||
{ .description = "DMA 3", .value = 3 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = "",
|
||||
.default_int = 0xc8000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0xc8000,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "C000H", .value = 0xc0000 },
|
||||
{ .description = "C800H", .value = 0xc8000 },
|
||||
@@ -249,30 +228,36 @@ static const device_config_t monster_fdc_config[] = {
|
||||
{ .description = "E000H", .value = 0xe0000 },
|
||||
{ .description = "E800H", .value = 0xe8000 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = "32",
|
||||
.default_int = 0xc8000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
.name = "bios_size",
|
||||
.description = "BIOS Size:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 32,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "8K", .value = 8 },
|
||||
{ .description = "32K", .value = 32 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "rom_writes_enabled",
|
||||
.description = "Enable BIOS extension ROM Writes",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = "",
|
||||
.default_int = 0
|
||||
.name = "rom_writes_enabled",
|
||||
.description = "Enable BIOS extension ROM Writes",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
@@ -286,7 +271,7 @@ const device_t fdc_monster_device = {
|
||||
.init = monster_fdc_init,
|
||||
.close = monster_fdc_close,
|
||||
.reset = NULL,
|
||||
{ .available = monster_fdc_available },
|
||||
.available = monster_fdc_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = monster_fdc_config
|
||||
|
||||
@@ -75,7 +75,7 @@ MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be.
|
||||
#include <86box/fdc_ext.h>
|
||||
|
||||
#define DTK_VARIANT ((info->local == 158) ? ROM_PII_158B : ROM_PII_151B)
|
||||
#define DTK_CHIP ((info->local == 158) ? &fdc_xt_device : &fdc_dp8473_device)
|
||||
#define DTK_CHIP ((info->local == 158) ? &fdc_xt_device : &fdc_at_nsc_dp8473_device)
|
||||
#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
|
||||
#define ROM_PII_151B "roms/floppy/dtk/pii-151b.rom"
|
||||
#define ROM_PII_158B "roms/floppy/dtk/pii-158b.rom"
|
||||
@@ -97,8 +97,7 @@ pii_init(const device_t *info)
|
||||
{
|
||||
pii_t *dev;
|
||||
|
||||
dev = (pii_t *) malloc(sizeof(pii_t));
|
||||
memset(dev, 0, sizeof(pii_t));
|
||||
dev = (pii_t *) calloc(1, sizeof(pii_t));
|
||||
|
||||
if (BIOS_ADDR != 0)
|
||||
rom_init(&dev->bios_rom, DTK_VARIANT, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
@@ -123,20 +122,21 @@ pii_158_available(void)
|
||||
static const device_config_t pii_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = "",
|
||||
.default_int = 0xce000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = NULL,
|
||||
.default_int = 0xce000,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "CA00H", .value = 0xca000 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "CE00H", .value = 0xce000 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
@@ -150,7 +150,7 @@ const device_t fdc_pii151b_device = {
|
||||
.init = pii_init,
|
||||
.close = pii_close,
|
||||
.reset = NULL,
|
||||
{ .available = pii_151b_available },
|
||||
.available = pii_151b_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = pii_config
|
||||
@@ -164,7 +164,7 @@ const device_t fdc_pii158b_device = {
|
||||
.init = pii_init,
|
||||
.close = pii_close,
|
||||
.reset = NULL,
|
||||
{ .available = pii_158_available },
|
||||
.available = pii_158_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = pii_config
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/path.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
@@ -99,10 +100,10 @@ d86f_handler_t d86f_handler[FDD_NUM];
|
||||
|
||||
static const struct
|
||||
{
|
||||
char *ext;
|
||||
void (*load)(int drive, char *fn);
|
||||
void (*close)(int drive);
|
||||
int size;
|
||||
const char *ext;
|
||||
void (*load)(int drive, char *fn);
|
||||
void (*close)(int drive);
|
||||
int size;
|
||||
} loaders[] = {
|
||||
{ "001", img_load, img_close, -1},
|
||||
{ "002", img_load, img_close, -1},
|
||||
@@ -153,20 +154,16 @@ static const struct {
|
||||
{ 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" },
|
||||
/* 5.25" QD */
|
||||
{ 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" },
|
||||
/* 5.25" HD PS/2 */
|
||||
{ 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" },
|
||||
/* 5.25" HD */
|
||||
{ 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" },
|
||||
{ 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_PS2, "5.25\" 1.2M", "525_2hd" },
|
||||
/* 5.25" HD Dual RPM */
|
||||
{ 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" },
|
||||
/* 3.5" 1DD */
|
||||
{ 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" },
|
||||
/* 3.5" DD, Equivalent to TEAC FD-235F */
|
||||
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" },
|
||||
/* 3.5" HD PS/2 */
|
||||
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" },
|
||||
/* 3.5" HD, Equivalent to TEAC FD-235HF */
|
||||
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" },
|
||||
{ 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_PS2, "3.5\" 1.44M", "35_2hd" },
|
||||
/* TODO: 3.5" DD, Equivalent to TEAC FD-235GF */
|
||||
// { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.25M", "35_2hd_2mode" },
|
||||
/* 3.5" HD PC-98 */
|
||||
@@ -214,10 +211,19 @@ fdd_get_internal_name(int type)
|
||||
int
|
||||
fdd_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
int c = 0;
|
||||
char *n;
|
||||
|
||||
/* TODO: Remove this once the migration period is over. */
|
||||
if (!strcmp(s, "525_2hd_ps2"))
|
||||
n = "525_2hd";
|
||||
else if (!strcmp(s, "35_2hd_ps2"))
|
||||
n = "35_2hd";
|
||||
else
|
||||
n = s;
|
||||
|
||||
while (strlen(drive_types[c].internal_name)) {
|
||||
if (!strcmp((char *) drive_types[c].internal_name, s))
|
||||
if (!strcmp((char *) drive_types[c].internal_name, n))
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
@@ -282,11 +288,32 @@ fdd_current_track(int drive)
|
||||
return fdd[drive].track;
|
||||
}
|
||||
|
||||
static int
|
||||
fdd_type_invert_densel(int type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (drive_types[type].flags & FLAG_PS2)
|
||||
ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2"));
|
||||
else
|
||||
ret = drive_types[type].flags & FLAG_INVERT_DENSEL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
fdd_invert_densel(int drive)
|
||||
{
|
||||
int ret = fdd_type_invert_densel(fdd[drive].type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
fdd_set_densel(int densel)
|
||||
{
|
||||
for (uint8_t i = 0; i < FDD_NUM; i++) {
|
||||
if (drive_types[fdd[i].type].flags & FLAG_INVERT_DENSEL)
|
||||
if (fdd_invert_densel(i))
|
||||
fdd[i].densel = densel ^ 1;
|
||||
else
|
||||
fdd[i].densel = densel;
|
||||
@@ -302,7 +329,7 @@ fdd_getrpm(int drive)
|
||||
hole = fdd_hole(drive);
|
||||
densel = fdd[drive].densel;
|
||||
|
||||
if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL)
|
||||
if (fdd_invert_densel(drive))
|
||||
densel ^= 1;
|
||||
|
||||
if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360))
|
||||
@@ -340,10 +367,9 @@ fdd_doublestep_40(int drive)
|
||||
void
|
||||
fdd_set_type(int drive, int type)
|
||||
{
|
||||
int old_type = fdd[drive].type;
|
||||
fdd[drive].type = type;
|
||||
if ((drive_types[old_type].flags ^ drive_types[type].flags) & FLAG_INVERT_DENSEL)
|
||||
if (fdd_type_invert_densel(fdd[drive].type) != fdd_type_invert_densel(type))
|
||||
fdd[drive].densel ^= 1;
|
||||
fdd[drive].type = type;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -628,10 +628,12 @@ d86f_get_array_size(int drive, int side, int words)
|
||||
int hole;
|
||||
int rm;
|
||||
int ssd;
|
||||
int mpc;
|
||||
|
||||
rm = d86f_get_rpm_mode(drive);
|
||||
ssd = d86f_get_speed_shift_dir(drive);
|
||||
hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1;
|
||||
hole = (d86f_handler[drive].disk_flags(drive) >> 1) & 3;
|
||||
mpc = (d86f_handler[drive].disk_flags(drive) >> 13) & 1;
|
||||
|
||||
if (!rm && ssd) /* Special case - extra bit cells size specifies entire array size. */
|
||||
array_size = 0;
|
||||
@@ -703,13 +705,20 @@ d86f_get_array_size(int drive, int side, int words)
|
||||
array_size <<= 4;
|
||||
array_size += d86f_handler[drive].extra_bit_cells(drive, side);
|
||||
|
||||
if (array_size & 15)
|
||||
array_size = (array_size >> 4) + 1;
|
||||
else
|
||||
array_size = (array_size >> 4);
|
||||
if (mpc && !words) {
|
||||
if (array_size & 7)
|
||||
array_size = (array_size >> 3) + 1;
|
||||
else
|
||||
array_size = (array_size >> 3);
|
||||
} else {
|
||||
if (array_size & 15)
|
||||
array_size = (array_size >> 4) + 1;
|
||||
else
|
||||
array_size = (array_size >> 4);
|
||||
|
||||
if (!words)
|
||||
array_size <<= 1;
|
||||
if (!words)
|
||||
array_size <<= 1;
|
||||
}
|
||||
|
||||
return array_size;
|
||||
}
|
||||
@@ -1098,9 +1107,9 @@ d86f_get_bit(int drive, int side)
|
||||
/* In some cases, misindentification occurs so we need to make sure the surface data array is not
|
||||
not NULL. */
|
||||
if (d86f_has_surface_desc(drive) && dev->track_surface_data[side]) {
|
||||
if (d86f_reverse_bytes(drive)) {
|
||||
if (d86f_reverse_bytes(drive))
|
||||
surface_data = dev->track_surface_data[side][track_word] & 0xFF;
|
||||
} else {
|
||||
else {
|
||||
surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8;
|
||||
surface_data |= (dev->track_surface_data[side][track_word] >> 8);
|
||||
}
|
||||
@@ -1150,9 +1159,9 @@ d86f_put_bit(int drive, int side, int bit)
|
||||
}
|
||||
|
||||
if (d86f_has_surface_desc(drive)) {
|
||||
if (d86f_reverse_bytes(drive)) {
|
||||
if (d86f_reverse_bytes(drive))
|
||||
surface_data = dev->track_surface_data[side][track_word] & 0xFF;
|
||||
} else {
|
||||
else {
|
||||
surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8;
|
||||
surface_data |= (dev->track_surface_data[side][track_word] >> 8);
|
||||
}
|
||||
@@ -1177,9 +1186,9 @@ d86f_put_bit(int drive, int side, int bit)
|
||||
|
||||
surface_data &= ~(1 << track_bit);
|
||||
surface_data |= (surface_bit << track_bit);
|
||||
if (d86f_reverse_bytes(drive)) {
|
||||
if (d86f_reverse_bytes(drive))
|
||||
dev->track_surface_data[side][track_word] = surface_data;
|
||||
} else {
|
||||
else {
|
||||
dev->track_surface_data[side][track_word] = (surface_data & 0xFF) << 8;
|
||||
dev->track_surface_data[side][track_word] |= (surface_data >> 8);
|
||||
}
|
||||
@@ -1191,9 +1200,9 @@ d86f_put_bit(int drive, int side, int bit)
|
||||
encoded_data &= ~(1 << track_bit);
|
||||
encoded_data |= (current_bit << track_bit);
|
||||
|
||||
if (d86f_reverse_bytes(drive)) {
|
||||
if (d86f_reverse_bytes(drive))
|
||||
d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data;
|
||||
} else {
|
||||
else {
|
||||
d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8;
|
||||
d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8);
|
||||
}
|
||||
@@ -1833,7 +1842,6 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3
|
||||
uint16_t mask_data;
|
||||
uint16_t mask_surface;
|
||||
uint16_t mask_hole;
|
||||
uint16_t mask_fuzzy;
|
||||
decoded_t dbyte;
|
||||
decoded_t dpbyte;
|
||||
|
||||
@@ -1846,6 +1854,7 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3
|
||||
if (type == 0) {
|
||||
/* Byte write. */
|
||||
encoded_byte = d86f_encode_byte(drive, 0, dbyte, dpbyte);
|
||||
dev->preceding_bit[side] = encoded_byte & 1;
|
||||
if (!d86f_reverse_bytes(drive)) {
|
||||
mask_data = encoded_byte >> 8;
|
||||
encoded_byte &= 0xFF;
|
||||
@@ -1855,6 +1864,7 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3
|
||||
} else {
|
||||
/* Word write. */
|
||||
encoded_byte = byte;
|
||||
dev->preceding_bit[side] = (encoded_byte >> 8) & 1;
|
||||
if (d86f_reverse_bytes(drive)) {
|
||||
mask_data = encoded_byte >> 8;
|
||||
encoded_byte &= 0xFF;
|
||||
@@ -1863,16 +1873,19 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3
|
||||
}
|
||||
}
|
||||
|
||||
dev->preceding_bit[side] = encoded_byte & 1;
|
||||
|
||||
if (d86f_has_surface_desc(drive)) {
|
||||
mask_data = dev->track_encoded_data[side][pos] ^= 0xFFFF;
|
||||
/* Inverted track data, clear bits are now set. */
|
||||
mask_data = ~dev->track_encoded_data[side][pos];
|
||||
/* Surface data. */
|
||||
mask_surface = dev->track_surface_data[side][pos];
|
||||
mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */
|
||||
encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */
|
||||
mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */
|
||||
mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */
|
||||
dev->track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */
|
||||
|
||||
/* Hole = surface & ~data, so holes are one. */
|
||||
mask_hole = mask_surface & mask_data;
|
||||
/* Hole bits are ones again, set the surface data to that. */
|
||||
dev->track_surface_data[side][pos] = mask_hole;
|
||||
|
||||
/* Force the data of any hole to zero. */
|
||||
encoded_byte &= ~mask_hole;
|
||||
}
|
||||
|
||||
dev->track_encoded_data[side][pos] = encoded_byte;
|
||||
@@ -2718,8 +2731,7 @@ d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t
|
||||
uint16_t datadam_mfm = 0x4A55;
|
||||
|
||||
if (fdd_get_turbo(drive) && (dev->version == 0x0063)) {
|
||||
s = (sector_t *) malloc(sizeof(sector_t));
|
||||
memset(s, 0, sizeof(sector_t));
|
||||
s = (sector_t *) calloc(1, sizeof(sector_t));
|
||||
s->c = id_buf[0];
|
||||
s->h = id_buf[1];
|
||||
s->r = id_buf[2];
|
||||
@@ -2865,22 +2877,22 @@ d86f_construct_encoded_buffer(int drive, int side)
|
||||
/* Source image has surface description data, so we have some more handling to do. */
|
||||
src1_fuzm = src1[i] & src1_s[i];
|
||||
src2_fuzm = src2[i] & src2_s[i];
|
||||
dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or
|
||||
the other or both. */
|
||||
src1_holm = src1[i] | (src1_s[i] ^ 0xffff);
|
||||
src2_holm = src2[i] | (src2_s[i] ^ 0xffff);
|
||||
dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */
|
||||
dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither
|
||||
fuzzy nor are holes in both. */
|
||||
dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or
|
||||
the other or both. */
|
||||
src1_holm = ~src1[i] & src1_s[i];
|
||||
src2_holm = ~src2[i] & src2_s[i];
|
||||
dst_holm = src1_holm & src2_holm; /* The bits that remain set are holes in both. */
|
||||
dst_neim = ~(dst_fuzm | dst_holm); /* The bits that remain set are those that are neither
|
||||
fuzzy nor are holes in both. */
|
||||
src1_d = src1[i] & dst_neim;
|
||||
src2_d = src2[i] & dst_neim;
|
||||
|
||||
dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are
|
||||
holes in both. */
|
||||
dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and
|
||||
Source 2. */
|
||||
dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set
|
||||
but data bit clear). */
|
||||
dst_s[i] = ~dst_neim; /* The set bits are those that are either fuzzy or are
|
||||
holes in both. */
|
||||
dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and
|
||||
Source 2. */
|
||||
dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set
|
||||
but data bit clear). */
|
||||
} else {
|
||||
/* No surface data, the handling is much simpler - a simple OR. */
|
||||
dst[i] = src1[i] | src2[i];
|
||||
@@ -2898,6 +2910,7 @@ d86f_decompose_encoded_buffer(int drive, int side)
|
||||
uint16_t temp2;
|
||||
uint32_t len;
|
||||
const uint16_t *dst = dev->track_encoded_data[side];
|
||||
const uint16_t *dst_s = dev->track_surface_data[side];
|
||||
uint16_t *src1 = dev->thin_track_encoded_data[0][side];
|
||||
uint16_t *src1_s = dev->thin_track_surface_data[0][side];
|
||||
uint16_t *src2 = dev->thin_track_encoded_data[1][side];
|
||||
@@ -2909,15 +2922,15 @@ d86f_decompose_encoded_buffer(int drive, int side)
|
||||
if (d86f_has_surface_desc(drive)) {
|
||||
/* Source image has surface description data, so we have some more handling to do.
|
||||
We need hole masks for both buffers. Holes have data bit clear and surface bit set. */
|
||||
temp = src1[i] & (src1_s[i] ^ 0xffff);
|
||||
temp2 = src2[i] & (src2_s[i] ^ 0xffff);
|
||||
src1[i] = dst[i] & temp;
|
||||
src1_s[i] = temp ^ 0xffff;
|
||||
src2[i] = dst[i] & temp2;
|
||||
src2_s[i] = temp2 ^ 0xffff;
|
||||
} else {
|
||||
src1_s[i] = src2_s[i] = dst_s[i]; /* Write the new holes and weak bits. */
|
||||
temp = ~src1[i] & src1_s[i]; /* Bits that are clear in data and set in surface are holes. */
|
||||
temp2 = ~src2[i] & src2_s[i]; /* Bits that are clear in data and set in surface are holes. */
|
||||
src1[i] = dst[i] & ~temp; /* Make sure the holes' bits are cleared in the decomposed buffer. */
|
||||
src1_s[i] |= temp; /* Make sure the holes' bits are set in the decomposed surface. */
|
||||
src2[i] = dst[i] & ~temp2; /* Make sure the holes' bits are cleared in the decomposed buffer. */
|
||||
src2_s[i] |= temp2; /* Make sure the holes' bits are set in the decomposed surface. */
|
||||
} else
|
||||
src1[i] = src2[i] = dst[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3213,6 +3226,8 @@ d86f_writeback(int drive)
|
||||
free(dev->filebuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
fflush(dev->fp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3544,9 +3559,9 @@ d86f_load(int drive, char *fn)
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
|
||||
if (ui_writeprot[drive]) {
|
||||
if (ui_writeprot[drive])
|
||||
writeprot[drive] = 1;
|
||||
}
|
||||
|
||||
fwriteprot[drive] = writeprot[drive];
|
||||
|
||||
fseek(dev->fp, 0, SEEK_END);
|
||||
@@ -3905,8 +3920,7 @@ d86f_setup(int drive)
|
||||
d86f_t *dev;
|
||||
|
||||
/* Allocate a drive structure. */
|
||||
dev = (d86f_t *) malloc(sizeof(d86f_t));
|
||||
memset(dev, 0x00, sizeof(d86f_t));
|
||||
dev = (d86f_t *) calloc(1, sizeof(d86f_t));
|
||||
dev->state = STATE_IDLE;
|
||||
|
||||
dev->last_side_sector[0] = NULL;
|
||||
|
||||
@@ -316,15 +316,13 @@ fdi_load(int drive, char *fn)
|
||||
writeprot[drive] = fwriteprot[drive] = 1;
|
||||
|
||||
/* Allocate a drive block. */
|
||||
dev = (fdi_t *) malloc(sizeof(fdi_t));
|
||||
dev = (fdi_t *) calloc(1, sizeof(fdi_t));
|
||||
|
||||
if (dev == NULL) {
|
||||
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(dev, 0x00, sizeof(fdi_t));
|
||||
|
||||
d86f_unregister(drive);
|
||||
|
||||
dev->fp = plat_fopen(fn, "rb");
|
||||
|
||||
@@ -549,6 +549,8 @@ imd_writeback(int drive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fflush(dev->fp);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -633,8 +635,7 @@ imd_load(int drive, char *fn)
|
||||
writeprot[drive] = 0;
|
||||
|
||||
/* Allocate a drive block. */
|
||||
dev = (imd_t *) malloc(sizeof(imd_t));
|
||||
memset(dev, 0x00, sizeof(imd_t));
|
||||
dev = (imd_t *) calloc(1, sizeof(imd_t));
|
||||
|
||||
dev->fp = plat_fopen(fn, "rb+");
|
||||
if (dev->fp == NULL) {
|
||||
|
||||
@@ -431,6 +431,8 @@ write_back(int drive)
|
||||
if (fwrite(dev->track_data[side], 1, size, dev->fp) != size)
|
||||
fatal("IMG write_back(): Error writing data\n");
|
||||
}
|
||||
|
||||
fflush(dev->fp);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
@@ -679,8 +681,7 @@ img_load(int drive, char *fn)
|
||||
writeprot[drive] = 0;
|
||||
|
||||
/* Allocate a drive block. */
|
||||
dev = (img_t *) malloc(sizeof(img_t));
|
||||
memset(dev, 0x00, sizeof(img_t));
|
||||
dev = (img_t *) calloc(1, sizeof(img_t));
|
||||
|
||||
dev->fp = plat_fopen(fn, "rb+");
|
||||
if (dev->fp == NULL) {
|
||||
@@ -1073,9 +1074,14 @@ jump_if_fdf:
|
||||
dev->sectors = 19;
|
||||
dev->tracks = 80;
|
||||
} else if (size <= 1638400) { /*HD 1024 sector*/
|
||||
#ifdef SYNTH_FORMAT
|
||||
dev->sectors = 10;
|
||||
dev->tracks = 80;
|
||||
dev->sector_size = 3;
|
||||
#else
|
||||
/* Prefer 20 512-byte sectors per track, used by the OpenStep 4.0 Pre-Release 1 boot disk. */
|
||||
dev->sectors = 20;
|
||||
#endif
|
||||
dev->tracks = 80;
|
||||
} else if (size <= 1720320) { /*DMF (Windows 95) */
|
||||
dev->sectors = 21;
|
||||
dev->tracks = 80;
|
||||
@@ -1086,9 +1092,14 @@ jump_if_fdf:
|
||||
dev->sectors = 21;
|
||||
dev->tracks = 82;
|
||||
} else if (size <= 1802240) { /*HD 1024 sector*/
|
||||
dev->sectors = 22;
|
||||
dev->tracks = 80;
|
||||
#ifdef SYNTH_FORMAT
|
||||
dev->sectors = 11;
|
||||
dev->sector_size = 3;
|
||||
#else
|
||||
/* Prefer 22 512-byte sectors per track. */
|
||||
dev->sectors = 22;
|
||||
#endif
|
||||
dev->tracks = 80;
|
||||
} else if (size == 1884160) { /*XDF (OS/2 Warp)*/
|
||||
dev->sectors = 23;
|
||||
dev->tracks = 80;
|
||||
@@ -1108,12 +1119,12 @@ jump_if_fdf:
|
||||
dev->sectors = 42;
|
||||
dev->tracks = 80;
|
||||
#if 0
|
||||
} else if (size <= 3440640) { /*HD 1024 sector*/
|
||||
} else if (size <= 3440640) { /*ED 1024 sector*/
|
||||
dev->sectors = 21;
|
||||
dev->tracks = 80;
|
||||
dev->sector_size = 3;
|
||||
#endif
|
||||
} else if (size <= 3604480) { /*HD 1024 sector*/
|
||||
} else if (size <= 3604480) { /*ED 1024 sector*/
|
||||
dev->sectors = 22;
|
||||
dev->tracks = 80;
|
||||
dev->sector_size = 3;
|
||||
|
||||
@@ -396,8 +396,7 @@ mfm_load(int drive, char *fn)
|
||||
writeprot[drive] = fwriteprot[drive] = 1;
|
||||
|
||||
/* Allocate a drive block. */
|
||||
dev = (mfm_t *) malloc(sizeof(mfm_t));
|
||||
memset(dev, 0x00, sizeof(mfm_t));
|
||||
dev = (mfm_t *) calloc(1, sizeof(mfm_t));
|
||||
|
||||
dev->fp = plat_fopen(fn, "rb");
|
||||
if (dev->fp == NULL) {
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
@@ -465,7 +469,7 @@ track_flags(int drive)
|
||||
}
|
||||
|
||||
static void
|
||||
set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n)
|
||||
set_sector(int drive, int side, uint8_t c, UNUSED(uint8_t h), uint8_t r, UNUSED(uint8_t n))
|
||||
{
|
||||
pcjs_t *dev = images[drive];
|
||||
|
||||
@@ -613,8 +617,7 @@ pcjs_load(int drive, char *fn)
|
||||
d86f_unregister(drive);
|
||||
|
||||
/* Allocate a drive block */
|
||||
dev = (pcjs_t *) malloc(sizeof(pcjs_t));
|
||||
memset(dev, 0x00, sizeof(pcjs_t));
|
||||
dev = (pcjs_t *) calloc(1, sizeof(pcjs_t));
|
||||
|
||||
/* Open the image file, read-only */
|
||||
dev->fp = plat_fopen(fn, "rb");
|
||||
|
||||
@@ -1214,8 +1214,7 @@ td0_load(int drive, char *fn)
|
||||
|
||||
writeprot[drive] = 1;
|
||||
|
||||
dev = (td0_t *) malloc(sizeof(td0_t));
|
||||
memset(dev, 0x00, sizeof(td0_t));
|
||||
dev = (td0_t *) calloc(1, sizeof(td0_t));
|
||||
td0[drive] = dev;
|
||||
|
||||
dev->fp = plat_fopen(fn, "rb");
|
||||
|
||||
Reference in New Issue
Block a user