Changes to logging - nothing (other than some parts of pc.c) uses the global pclog anymore (and logs will be almost empty (until the base set logging flags is agreed upon);
Fixes to various hard disk controllers; Added the Packard Bell PB640; Fixed the InPort mouse emulation - now it works correctly on Windows NT 3.1; Removed the status window and the associated variables; Completely removed the Green B 486 machine; Fixed the MDSI Genius; Fixed the single-sided 5.25" floppy drive; Ported a CPU-related commit from VARCem.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Common code to handle all sorts of disk controllers.
|
||||
*
|
||||
* Version: @(#)hdc.c 1.0.14 2018/04/26
|
||||
* Version: @(#)hdc.c 1.0.15 2018/04/29
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -16,10 +16,12 @@
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../device.h"
|
||||
@@ -32,6 +34,26 @@ char *hdc_name; /* configured HDC name */
|
||||
int hdc_current;
|
||||
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
int hdc_do_log = ENABLE_HDC_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
hdc_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
va_list ap;
|
||||
|
||||
if (hdc_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
null_init(const device_t *info)
|
||||
{
|
||||
@@ -142,7 +164,7 @@ hdc_init(char *name)
|
||||
{
|
||||
int c;
|
||||
|
||||
pclog("HDC: initializing..\n");
|
||||
hdc_log("HDC: initializing..\n");
|
||||
|
||||
for (c = 0; controllers[c].device; c++) {
|
||||
if (! strcmp(name, (char *) controllers[c].internal_name)) {
|
||||
@@ -160,7 +182,7 @@ hdc_init(char *name)
|
||||
void
|
||||
hdc_reset(void)
|
||||
{
|
||||
pclog("HDC: reset(current=%d, internal=%d)\n",
|
||||
hdc_log("HDC: reset(current=%d, internal=%d)\n",
|
||||
hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
|
||||
|
||||
/* If we have a valid controller, add its device. */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Driver for the ESDI controller (WD1007-vse1) for PC/AT.
|
||||
*
|
||||
* Version: @(#)hdc_esdi_at.c 1.0.11 2018/04/26
|
||||
* Version: @(#)hdc_esdi_at.c 1.0.13 2018/05/02
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -21,11 +21,13 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../io.h"
|
||||
@@ -104,28 +106,45 @@ typedef struct {
|
||||
} esdi_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ESDI_AT_LOG
|
||||
int esdi_at_do_log = ENABLE_ESDI_AT_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
esdi_at_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_ESDI_AT_LOG
|
||||
va_list ap;
|
||||
|
||||
if (esdi_at_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
irq_raise(esdi_t *esdi)
|
||||
{
|
||||
if (!(esdi->fdisk&2))
|
||||
if (!(esdi->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
|
||||
esdi->irqstat=1;
|
||||
esdi->irqstat = 1;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
irq_lower(esdi_t *esdi)
|
||||
{
|
||||
picintc(1 << 14);
|
||||
}
|
||||
if (esdi->irqstat) {
|
||||
if (!(esdi->fdisk & 2))
|
||||
picintc(1 << 14);
|
||||
|
||||
|
||||
static void
|
||||
irq_update(esdi_t *esdi)
|
||||
{
|
||||
if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
esdi->irqstat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,12 +158,12 @@ get_sector(esdi_t *esdi, off64_t *addr)
|
||||
int c, h, s;
|
||||
|
||||
if (esdi->head > heads) {
|
||||
pclog("esdi_get_sector: past end of configured heads\n");
|
||||
esdi_at_log("esdi_get_sector: past end of configured heads\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (esdi->sector >= sectors+1) {
|
||||
pclog("esdi_get_sector: past end of configured sectors\n");
|
||||
esdi_at_log("esdi_get_sector: past end of configured sectors\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -202,7 +221,8 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 6LL*HDC_TIME;
|
||||
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
||||
esdi->callback = (3125LL * TIMER_USEC) / 8LL;
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
@@ -213,9 +233,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
pclog("WD1007 write(%04x, %02x)\n", port, val);
|
||||
#endif
|
||||
esdi_at_log("WD1007 write(%04x, %02x)\n", port, val);
|
||||
|
||||
switch (port) {
|
||||
case 0x1f0: /* data */
|
||||
@@ -257,9 +275,8 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
esdi->command = val;
|
||||
esdi->error = 0;
|
||||
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
pclog("WD1007: command %02x\n", val & 0xf0);
|
||||
#endif
|
||||
esdi_at_log("WD1007: command %02x\n", val & 0xf0);
|
||||
|
||||
switch (val & 0xf0) {
|
||||
case CMD_RESTORE:
|
||||
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||
@@ -349,7 +366,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("WD1007: bad command %02X\n", val);
|
||||
esdi_at_log("WD1007: bad command %02X\n", val);
|
||||
case 0xe8: /*???*/
|
||||
esdi->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
@@ -377,7 +394,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
esdi->status = STAT_BUSY;
|
||||
}
|
||||
esdi->fdisk = val;
|
||||
irq_update(esdi);
|
||||
/* Lower IRQ on IRQ disable. */
|
||||
if ((val & 2) && !(esdi->fdisk & 0x02))
|
||||
picintc(1 << 14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -401,7 +420,8 @@ esdi_readw(uint16_t port, void *priv)
|
||||
next_sector(esdi);
|
||||
esdi->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 6LL*HDC_TIME;
|
||||
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
|
||||
esdi->callback = (3125LL * TIMER_USEC) / 8LL;
|
||||
timer_update_outstanding();
|
||||
} else {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||
@@ -454,9 +474,7 @@ esdi_read(uint16_t port, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
pclog("WD1007 read(%04x) = %02x\n", port, temp);
|
||||
#endif
|
||||
esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp);
|
||||
|
||||
return(temp);
|
||||
}
|
||||
@@ -484,9 +502,7 @@ esdi_callback(void *priv)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
pclog("WD1007: command %02x\n", esdi->command);
|
||||
#endif
|
||||
esdi_at_log("WD1007: command %02x\n", esdi->command);
|
||||
|
||||
switch (esdi->command) {
|
||||
case CMD_RESTORE:
|
||||
@@ -632,9 +648,9 @@ esdi_callback(void *priv)
|
||||
|
||||
drive->cfg_spt = esdi->secount;
|
||||
drive->cfg_hpc = esdi->head+1;
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
pclog("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
||||
#endif
|
||||
|
||||
esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
||||
|
||||
if (! esdi->secount)
|
||||
fatal("WD1007: secount=0\n");
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
@@ -673,7 +689,7 @@ esdi_callback(void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("WD1007: bad read config %02x\n",
|
||||
esdi_at_log("WD1007: bad read config %02x\n",
|
||||
esdi->cylinder >> 8);
|
||||
}
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
@@ -730,7 +746,7 @@ esdi_callback(void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("WD1007: callback on unknown command %02x\n", esdi->command);
|
||||
esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command);
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
case 0xe8:
|
||||
@@ -750,7 +766,7 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
|
||||
drive_t *drive = &esdi->drives[hdd_num];
|
||||
|
||||
if (! hdd_image_load(d)) {
|
||||
pclog("WD1007: drive %d not present!\n", d);
|
||||
esdi_at_log("WD1007: drive %d not present!\n", d);
|
||||
drive->present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
* however, are auto-configured by the system software as
|
||||
* shown above.
|
||||
*
|
||||
* Version: @(#)hdc_esdi_mca.c 1.0.12 2018/04/26
|
||||
* Version: @(#)hdc_esdi_mca.c 1.0.13 2018/04/29
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -60,11 +60,13 @@
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../dma.h"
|
||||
@@ -192,6 +194,26 @@ typedef struct esdi {
|
||||
#define STATUS_DEVICE_HOST_ADAPTER (7 << 5)
|
||||
|
||||
|
||||
#ifdef ENABLE_ESDI_MCA_LOG
|
||||
int esdi_mca_do_log = ENABLE_ESDI_MCA_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
esdi_mca_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_ESDI_MCA_LOG
|
||||
va_list ap;
|
||||
|
||||
if (esdi_mca_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static __inline void
|
||||
set_irq(esdi_t *dev)
|
||||
{
|
||||
@@ -561,13 +583,12 @@ esdi_callback(void *priv)
|
||||
dev->status_data[4] = drive->tracks;
|
||||
dev->status_data[5] = drive->hpc | (drive->spt << 16);
|
||||
|
||||
#if 0
|
||||
pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n",
|
||||
esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n",
|
||||
drive->sectors,
|
||||
dev->status_data[0], dev->status_data[1],
|
||||
dev->status_data[2], dev->status_data[3],
|
||||
dev->status_data[4], dev->status_data[5]);
|
||||
#endif
|
||||
|
||||
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
|
||||
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
|
||||
dev->irq_in_progress = 1;
|
||||
@@ -754,9 +775,8 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
|
||||
#if 0
|
||||
pclog("ESDI: wr(%04x, %02x)\n", port & 7, val);
|
||||
#endif
|
||||
esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val);
|
||||
|
||||
switch (port & 7) {
|
||||
case 2: /*Basic control register*/
|
||||
if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) {
|
||||
@@ -887,9 +907,8 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
|
||||
#if 0
|
||||
pclog("ESDI: wrw(%04x, %04x)\n", port & 7, val);
|
||||
#endif
|
||||
esdi_mca_log("ESDI: wrw(%04x, %04x)\n", port & 7, val);
|
||||
|
||||
switch (port & 7) {
|
||||
case 0: /*Command Interface Register*/
|
||||
if (dev->cmd_pos >= 4)
|
||||
@@ -921,9 +940,8 @@ esdi_mca_read(int port, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
|
||||
#if 0
|
||||
pclog("ESDI: mcard(%04x)\n", port);
|
||||
#endif
|
||||
esdi_mca_log("ESDI: mcard(%04x)\n", port);
|
||||
|
||||
return(dev->pos_regs[port & 7]);
|
||||
}
|
||||
|
||||
@@ -933,10 +951,9 @@ esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
|
||||
#if 0
|
||||
pclog("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
|
||||
esdi_mca_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
|
||||
port, val, dev->pos_regs[2], dev->pos_regs[3]);
|
||||
#endif
|
||||
|
||||
if (port < 0x102)
|
||||
return;
|
||||
|
||||
@@ -984,7 +1001,7 @@ esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
/* Say hello. */
|
||||
pclog("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n",
|
||||
esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n",
|
||||
dev->dma, dev->bios);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||
* CD-ROM devices.
|
||||
*
|
||||
* Version: @(#)hdc_ide.c 1.0.45 2018/04/26
|
||||
* Version: @(#)hdc_ide.c 1.0.46 2018/05/02
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../pic.h"
|
||||
#include "../pci.h"
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../scsi/scsi.h"
|
||||
@@ -72,9 +74,9 @@
|
||||
#define WIN_SRST 0x08 /* ATAPI Device Reset */
|
||||
#define WIN_RECAL 0x10
|
||||
#define WIN_READ 0x20 /* 28-Bit Read */
|
||||
#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry*/
|
||||
#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry */
|
||||
#define WIN_WRITE 0x30 /* 28-Bit Write */
|
||||
#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write */
|
||||
#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write - no retry */
|
||||
#define WIN_VERIFY 0x40 /* 28-Bit Verify */
|
||||
#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */
|
||||
#define WIN_FORMAT 0x50
|
||||
@@ -127,9 +129,11 @@ enum
|
||||
};
|
||||
#endif
|
||||
|
||||
#define IDE_PCI (PCI && (romset != ROM_PB640))
|
||||
|
||||
|
||||
typedef struct {
|
||||
int enable, cur_dev,
|
||||
int bit32, cur_dev,
|
||||
irq;
|
||||
int64_t callback;
|
||||
} ide_board_t;
|
||||
@@ -150,6 +154,9 @@ static uint16_t ide_side_main[4] = { 0x3f6, 0x376, 0x36e, 0x3ee };
|
||||
static void ide_callback(void *priv);
|
||||
|
||||
|
||||
#define IDE_TIME (20LL * TIMER_USEC) / 3LL
|
||||
|
||||
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
int ide_do_log = ENABLE_IDE_LOG;
|
||||
#endif
|
||||
@@ -259,6 +266,34 @@ ide_get_period(ide_t *ide, int size)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int64_t
|
||||
ide_get_seek_time(ide_t *ide, uint32_t new_pos)
|
||||
{
|
||||
double dusec, time;
|
||||
uint32_t pos = hdd_image_get_pos(ide->hdd_num);
|
||||
uint32_t t, nt;
|
||||
t = pos / ide->spt;
|
||||
nt = new_pos / ide->spt;
|
||||
|
||||
dusec = (double) TIMER_USEC;
|
||||
time = (1000000.0 / 2800.0) * dusec; /* Revolution (1/2800 s). */
|
||||
|
||||
if ((t % ide->hpc) != (pos % ide->hpc)) /* Head change. */
|
||||
time += (dusec / 250.0); /* 4ns */
|
||||
|
||||
t /= ide->hpc;
|
||||
nt /= ide->hpc;
|
||||
|
||||
if (t != nt) {
|
||||
t = ABS(t - nt);
|
||||
time += ((40000.0 * dusec) / ((double) ide->tracks)) * ((double) t);
|
||||
}
|
||||
return (int64_t) time;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
ide_drive_is_cdrom(ide_t *ide)
|
||||
{
|
||||
@@ -305,14 +340,7 @@ ide_irq_raise(ide_t *ide)
|
||||
|
||||
/* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */
|
||||
|
||||
if ((ide_boards[ide->board]->irq == -1) || ide->irqstat) {
|
||||
ide->irqstat=1;
|
||||
ide->service=1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(ide->fdisk&2)) {
|
||||
if (!(ide->fdisk & 2) && (ide_boards[ide->board]->irq != -1)) {
|
||||
if ((ide->board < 2) && ide_bus_master_set_irq)
|
||||
ide_bus_master_set_irq(ide->board | 0x40, ide_bus_master_priv[ide->board]);
|
||||
else
|
||||
@@ -332,16 +360,13 @@ ide_irq_lower(ide_t *ide)
|
||||
|
||||
/* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */
|
||||
|
||||
if ((ide_boards[ide->board]->irq == -1) || !(ide->irqstat)) {
|
||||
ide->irqstat=0;
|
||||
return;
|
||||
if ((ide_boards[ide->board]->irq != -1) && ide->irqstat) {
|
||||
if ((ide->board < 2) && ide_bus_master_set_irq)
|
||||
ide_bus_master_set_irq(ide->board, ide_bus_master_priv[ide->board]);
|
||||
else
|
||||
picintc(1 << ide_boards[ide->board]->irq);
|
||||
}
|
||||
|
||||
if ((ide->board < 2) && ide_bus_master_set_irq)
|
||||
ide_bus_master_set_irq(ide->board, ide_bus_master_priv[ide->board]);
|
||||
else
|
||||
picintc(1 << ide_boards[ide->board]->irq);
|
||||
|
||||
ide->irqstat=0;
|
||||
}
|
||||
|
||||
@@ -414,7 +439,7 @@ ide_get_max(ide_t *ide, int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TYPE_PIO: /* PIO */
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return 0; /* Maximum PIO 0 for legacy PIO-only drive. */
|
||||
else {
|
||||
if (ide_drive_is_zip(ide))
|
||||
@@ -424,12 +449,12 @@ ide_get_max(ide_t *ide, int type)
|
||||
}
|
||||
break;
|
||||
case TYPE_SDMA: /* SDMA */
|
||||
if (!PCI || (ide->board >= 2) || ide_drive_is_zip(ide))
|
||||
if (!IDE_PCI || (ide->board >= 2) || ide_drive_is_zip(ide))
|
||||
return -1;
|
||||
else
|
||||
return 2;
|
||||
case TYPE_MDMA: /* MDMA */
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return -1;
|
||||
else {
|
||||
if (ide_drive_is_zip(ide))
|
||||
@@ -438,7 +463,7 @@ ide_get_max(ide_t *ide, int type)
|
||||
return 2;
|
||||
}
|
||||
case TYPE_UDMA: /* UDMA */
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return -1;
|
||||
else
|
||||
return 2;
|
||||
@@ -465,7 +490,7 @@ ide_get_timings(ide_t *ide, int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TIMINGS_DMA:
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return 0;
|
||||
else {
|
||||
if (ide_drive_is_zip(ide))
|
||||
@@ -475,7 +500,7 @@ ide_get_timings(ide_t *ide, int type)
|
||||
}
|
||||
break;
|
||||
case TIMINGS_PIO:
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return 0;
|
||||
else {
|
||||
if (ide_drive_is_zip(ide))
|
||||
@@ -485,7 +510,7 @@ ide_get_timings(ide_t *ide, int type)
|
||||
}
|
||||
break;
|
||||
case TIMINGS_PIO_FC:
|
||||
if (!PCI || (ide->board >= 2))
|
||||
if (!IDE_PCI || (ide->board >= 2))
|
||||
return 0;
|
||||
else {
|
||||
if (ide_drive_is_zip(ide))
|
||||
@@ -560,10 +585,10 @@ static void ide_hd_identify(ide_t *ide)
|
||||
Bit 2 = The fields reported in word 88 are valid. */
|
||||
ide->buffer[53] = 1;
|
||||
|
||||
if (ide->specify_success) {
|
||||
ide->buffer[54] = (full_size / ide->t_hpc) / ide->t_spt;
|
||||
ide->buffer[55] = ide->t_hpc;
|
||||
ide->buffer[56] = ide->t_spt;
|
||||
if (ide->cfg_spt != 0) {
|
||||
ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt;
|
||||
ide->buffer[55] = ide->cfg_hpc;
|
||||
ide->buffer[56] = ide->cfg_spt;
|
||||
} else {
|
||||
if (full_size <= 16514064) {
|
||||
ide->buffer[54] = d_tracks;
|
||||
@@ -584,7 +609,7 @@ static void ide_hd_identify(ide_t *ide)
|
||||
ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]);
|
||||
}
|
||||
|
||||
if (PCI && (ide->board < 2)) {
|
||||
if (IDE_PCI && (ide->board < 2)) {
|
||||
ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||
ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/
|
||||
ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/
|
||||
@@ -612,12 +637,17 @@ ide_atapi_cdrom_identify(ide_t *ide)
|
||||
|
||||
ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */
|
||||
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
||||
#if 0
|
||||
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
||||
#else
|
||||
ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */
|
||||
#endif
|
||||
ide->buffer[49] = 0x200; /* LBA supported */
|
||||
ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */
|
||||
|
||||
if (PCI && (ide->board < 2)) {
|
||||
if (IDE_PCI && (ide->board < 2)) {
|
||||
ide->buffer[71] = 30;
|
||||
ide->buffer[72] = 30;
|
||||
}
|
||||
@@ -638,7 +668,7 @@ ide_atapi_zip_250_identify(ide_t *ide)
|
||||
ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */
|
||||
|
||||
if (PCI && (ide->board < 2)) {
|
||||
if (IDE_PCI && (ide->board < 2)) {
|
||||
ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/
|
||||
ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/
|
||||
}
|
||||
@@ -690,7 +720,8 @@ ide_identify(ide_t *ide)
|
||||
max_mdma = ide_get_max(ide, TYPE_MDMA);
|
||||
max_udma = ide_get_max(ide, TYPE_UDMA);
|
||||
|
||||
ide->buffer[48] |= 1; /*Dword transfers supported*/
|
||||
if (ide_boards[ide->board]->bit32)
|
||||
ide->buffer[48] |= 1; /*Dword transfers supported*/
|
||||
ide->buffer[51] = ide_get_timings(ide, TIMINGS_PIO);
|
||||
ide->buffer[53] &= 0x0006;
|
||||
ide->buffer[52] = ide->buffer[62] = ide->buffer[63] = ide->buffer[64] = 0x0000;
|
||||
@@ -756,8 +787,8 @@ ide_get_sector(ide_t *ide)
|
||||
if (ide->lba)
|
||||
return (off64_t)ide->lba_addr + ide->skip512;
|
||||
else {
|
||||
heads = ide->t_hpc;
|
||||
sectors = ide->t_spt;
|
||||
heads = ide->cfg_hpc;
|
||||
sectors = ide->cfg_spt;
|
||||
|
||||
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
||||
sectors) + (ide->sector - 1) + ide->skip512;
|
||||
@@ -775,10 +806,10 @@ ide_next_sector(ide_t *ide)
|
||||
ide->lba_addr++;
|
||||
else {
|
||||
ide->sector++;
|
||||
if (ide->sector == (ide->t_spt + 1)) {
|
||||
if (ide->sector == (ide->cfg_spt + 1)) {
|
||||
ide->sector = 1;
|
||||
ide->head++;
|
||||
if (ide->head == ide->t_hpc) {
|
||||
if (ide->head == ide->cfg_hpc) {
|
||||
ide->head = 0;
|
||||
ide->cylinder++;
|
||||
}
|
||||
@@ -1043,6 +1074,7 @@ ide_board_init(int board)
|
||||
max = ide_get_max(dev, TYPE_PIO);
|
||||
dev->mdma_mode = (1 << max);
|
||||
dev->error = 1;
|
||||
dev->cfg_spt = dev->cfg_hpc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1870,7 +1902,8 @@ ide_read_alt_status(uint16_t addr, void *priv)
|
||||
ch = dev->cur_dev;
|
||||
ide = ide_drives[ch];
|
||||
|
||||
ide_irq_lower(ide);
|
||||
/* Per the Seagate ATA-3 specification:
|
||||
Reading the alternate status does *NOT* clear the IRQ. */
|
||||
temp = ide_status(ide, ch);
|
||||
|
||||
ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, temp);
|
||||
@@ -1895,10 +1928,6 @@ ide_readw(uint16_t addr, void *priv)
|
||||
case 0x0: /* Data */
|
||||
temp = ide_read_data(ide, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
/* ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); */
|
||||
@@ -1939,7 +1968,6 @@ ide_callback(void *priv)
|
||||
int snum, ret, ch;
|
||||
int cdrom_id, cdrom_id_other;
|
||||
int zip_id, zip_id_other;
|
||||
uint64_t full_size = 0;
|
||||
|
||||
ide_board_t *dev = (ide_board_t *) priv;
|
||||
ch = dev->cur_dev;
|
||||
@@ -1949,9 +1977,6 @@ ide_callback(void *priv)
|
||||
|
||||
ide_set_callback(ide->board, 0LL);
|
||||
|
||||
if (ide->type == IDE_HDD)
|
||||
full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt);
|
||||
|
||||
if (ide->reset) {
|
||||
ide_log("CALLBACK RESET %i %i\n", ide->reset,ch);
|
||||
|
||||
@@ -1961,6 +1986,10 @@ ide_callback(void *priv)
|
||||
ide->sector = ide_other->sector = 1;
|
||||
ide->head = ide_other->head = 0;
|
||||
ide->cylinder = ide_other->cylinder = 0;
|
||||
|
||||
// ide->cfg_spt = ide->cfg_hpc = 0; /* need new parameters (drive 0) */
|
||||
// ide_other->cfg_spt = ide_other->cfg_hpc = 0; /* need new parameters (drive 1) */
|
||||
|
||||
ide->reset = ide_other->reset = 0;
|
||||
|
||||
ide_set_signature(ide);
|
||||
@@ -2018,9 +2047,11 @@ ide_callback(void *priv)
|
||||
/* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h,
|
||||
Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */
|
||||
case WIN_SRST: /*ATAPI Device Reset */
|
||||
|
||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||
ide->error=1; /*Device passed*/
|
||||
ide->secount = ide->sector = 1;
|
||||
ide->error = 1; /*Device passed*/
|
||||
ide->secount = 1;
|
||||
ide->sector = 1;
|
||||
|
||||
ide_set_signature(ide);
|
||||
|
||||
@@ -2071,7 +2102,7 @@ ide_callback(void *priv)
|
||||
ide_set_signature(ide);
|
||||
goto abort_cmd;
|
||||
}
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
|
||||
if (ide->do_initial_read) {
|
||||
@@ -2101,7 +2132,7 @@ ide_callback(void *priv)
|
||||
ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel);
|
||||
goto abort_cmd;
|
||||
}
|
||||
if (!ide->specify_success) {
|
||||
if (ide->cfg_spt == 0) {
|
||||
ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel);
|
||||
goto id_not_found;
|
||||
}
|
||||
@@ -2153,7 +2184,7 @@ ide_callback(void *priv)
|
||||
mand error. */
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || !ide->blocksize)
|
||||
goto abort_cmd;
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
|
||||
if (ide->do_initial_read) {
|
||||
@@ -2182,7 +2213,7 @@ ide_callback(void *priv)
|
||||
case WIN_WRITE_NORETRY:
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide))
|
||||
goto abort_cmd;
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide_irq_raise(ide);
|
||||
@@ -2204,7 +2235,7 @@ ide_callback(void *priv)
|
||||
ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel);
|
||||
goto abort_cmd;
|
||||
}
|
||||
if (!ide->specify_success) {
|
||||
if (ide->cfg_spt == 0) {
|
||||
ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel);
|
||||
goto id_not_found;
|
||||
}
|
||||
@@ -2249,7 +2280,7 @@ ide_callback(void *priv)
|
||||
case WIN_WRITE_MULTIPLE:
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide))
|
||||
goto abort_cmd;
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->blockcount++;
|
||||
@@ -2272,7 +2303,7 @@ ide_callback(void *priv)
|
||||
case WIN_VERIFY_ONCE:
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide))
|
||||
goto abort_cmd;
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
ide->pos=0;
|
||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||
@@ -2283,7 +2314,7 @@ ide_callback(void *priv)
|
||||
case WIN_FORMAT:
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide))
|
||||
goto abort_cmd;
|
||||
if (!ide->specify_success)
|
||||
if (ide->cfg_spt == 0)
|
||||
goto id_not_found;
|
||||
hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount);
|
||||
|
||||
@@ -2332,14 +2363,14 @@ ide_callback(void *priv)
|
||||
case WIN_SPECIFY: /* Initialize Drive Parameters */
|
||||
if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide))
|
||||
goto abort_cmd;
|
||||
full_size /= (ide->head+1);
|
||||
full_size /= ide->secount;
|
||||
ide->specify_success = 1;
|
||||
hdd_image_specify(ide->hdd_num, ide->head + 1, ide->secount);
|
||||
ide->t_spt=ide->secount;
|
||||
ide->t_hpc=ide->head;
|
||||
ide->t_hpc++;
|
||||
if (ide->cfg_spt == 0) {
|
||||
/* Only accept after RESET or DIAG. */
|
||||
ide->cfg_spt = ide->secount;
|
||||
ide->cfg_hpc = ide->head + 1;
|
||||
}
|
||||
ide->command = 0x00;
|
||||
ide->atastat = DRDY_STAT | DSC_STAT;
|
||||
ide->error = 1;
|
||||
ide_irq_raise(ide);
|
||||
return;
|
||||
|
||||
@@ -2449,7 +2480,7 @@ abort_cmd:
|
||||
|
||||
id_not_found:
|
||||
ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT;
|
||||
ide->error = ABRT_ERR | 0x10;
|
||||
ide->error = IDNF_ERR;
|
||||
ide->pos = 0;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
@@ -2459,15 +2490,26 @@ static void
|
||||
ide_set_handlers(uint8_t board)
|
||||
{
|
||||
if (ide_base_main[board] & 0x300) {
|
||||
io_sethandler(ide_base_main[board], 8,
|
||||
ide_readb, ide_readw, ide_readl,
|
||||
ide_writeb, ide_writew, ide_writel,
|
||||
if (ide_boards[board]->bit32) {
|
||||
io_sethandler(ide_base_main[board], 1,
|
||||
ide_readb, ide_readw, ide_readl,
|
||||
ide_writeb, ide_writew, ide_writel,
|
||||
ide_boards[board]);
|
||||
} else {
|
||||
io_sethandler(ide_base_main[board], 1,
|
||||
ide_readb, ide_readw, NULL,
|
||||
ide_writeb, ide_writew, NULL,
|
||||
ide_boards[board]);
|
||||
}
|
||||
io_sethandler(ide_base_main[board] + 1, 7,
|
||||
ide_readb, NULL, NULL,
|
||||
ide_writeb, NULL, NULL,
|
||||
ide_boards[board]);
|
||||
}
|
||||
if (ide_side_main[board] & 0x300) {
|
||||
io_sethandler(ide_side_main[board], 1,
|
||||
ide_read_alt_status, NULL, NULL,
|
||||
ide_write_devctl, NULL, NULL,
|
||||
ide_read_alt_status, NULL, NULL,
|
||||
ide_write_devctl, NULL, NULL,
|
||||
ide_boards[board]);
|
||||
}
|
||||
}
|
||||
@@ -2476,13 +2518,24 @@ ide_set_handlers(uint8_t board)
|
||||
static void
|
||||
ide_remove_handlers(uint8_t board)
|
||||
{
|
||||
io_removehandler(ide_base_main[board], 8,
|
||||
ide_readb, ide_readw, ide_readl,
|
||||
ide_writeb, ide_writew, ide_writel,
|
||||
if (ide_boards[board]->bit32) {
|
||||
io_removehandler(ide_base_main[board], 1,
|
||||
ide_readb, ide_readw, ide_readl,
|
||||
ide_writeb, ide_writew, ide_writel,
|
||||
ide_boards[board]);
|
||||
} else {
|
||||
io_removehandler(ide_base_main[board], 1,
|
||||
ide_readb, ide_readw, NULL,
|
||||
ide_writeb, ide_writew, NULL,
|
||||
ide_boards[board]);
|
||||
}
|
||||
io_removehandler(ide_base_main[board] + 1, 7,
|
||||
ide_readb, NULL, NULL,
|
||||
ide_writeb, NULL, NULL,
|
||||
ide_boards[board]);
|
||||
io_removehandler(ide_side_main[board], 1,
|
||||
ide_read_alt_status, NULL, NULL,
|
||||
ide_write_devctl, NULL, NULL,
|
||||
ide_read_alt_status, NULL, NULL,
|
||||
ide_write_devctl, NULL, NULL,
|
||||
ide_boards[board]);
|
||||
}
|
||||
|
||||
@@ -2702,6 +2755,8 @@ ide_sainit(const device_t *info)
|
||||
memset(ide_boards[0], 0, sizeof(ide_board_t));
|
||||
ide_boards[0]->irq = 14;
|
||||
ide_boards[0]->cur_dev = 0;
|
||||
if (info->local & 8)
|
||||
ide_boards[0]->bit32 = 1;
|
||||
ide_base_main[0] = 0x1f0;
|
||||
ide_side_main[0] = 0x3f6;
|
||||
ide_set_handlers(0);
|
||||
@@ -2719,6 +2774,8 @@ ide_sainit(const device_t *info)
|
||||
memset(ide_boards[1], 0, sizeof(ide_board_t));
|
||||
ide_boards[1]->irq = 15;
|
||||
ide_boards[1]->cur_dev = 2;
|
||||
if (info->local & 8)
|
||||
ide_boards[1]->bit32 = 1;
|
||||
ide_base_main[1] = 0x170;
|
||||
ide_side_main[1] = 0x376;
|
||||
ide_set_handlers(1);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||
* CD-ROM devices.
|
||||
*
|
||||
* Version: @(#)hdd_ide.h 1.0.9 2018/03/26
|
||||
* Version: @(#)hdd_ide.h 1.0.10 2018/05/02
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -29,14 +29,13 @@ typedef struct {
|
||||
hdd_num, channel,
|
||||
pos, sector_pos,
|
||||
lba, skip512,
|
||||
reset, specify_success,
|
||||
mdma_mode, do_initial_read,
|
||||
reset, tracks,
|
||||
spt, hpc,
|
||||
tracks;
|
||||
mdma_mode, do_initial_read;
|
||||
uint32_t secount, sector,
|
||||
cylinder, head,
|
||||
drive, cylprecomp,
|
||||
t_spt, t_hpc,
|
||||
cfg_spt, cfg_hpc,
|
||||
lba_addr;
|
||||
|
||||
uint16_t *buffer;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* based design. Most cards were WD1003-WA2 or -WAH, where the
|
||||
* -WA2 cards had a floppy controller as well (to save space.)
|
||||
*
|
||||
* Version: @(#)hdc_mfm_at.c 1.0.15 2018/04/26
|
||||
* Version: @(#)hdc_mfm_at.c 1.0.17 2018/05/02
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -23,11 +23,13 @@
|
||||
#define __USE_LARGEFILE64
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../io.h"
|
||||
@@ -110,28 +112,45 @@ typedef struct {
|
||||
} mfm_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_MFM_AT_LOG
|
||||
int mfm_at_do_log = ENABLE_MFM_AT_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
mfm_at_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_MFM_AT_LOG
|
||||
va_list ap;
|
||||
|
||||
if (mfm_at_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
irq_raise(mfm_t *mfm)
|
||||
{
|
||||
if (!(mfm->fdisk&2))
|
||||
if (!(mfm->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
|
||||
mfm->irqstat=1;
|
||||
mfm->irqstat = 1;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
irq_lower(mfm_t *mfm)
|
||||
{
|
||||
picintc(1 << 14);
|
||||
}
|
||||
if (mfm->irqstat) {
|
||||
if (!(mfm->fdisk & 2))
|
||||
picintc(1 << 14);
|
||||
|
||||
|
||||
static void
|
||||
irq_update(mfm_t *mfm)
|
||||
{
|
||||
if (mfm->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(mfm->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
mfm->irqstat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,18 +172,18 @@ get_sector(mfm_t *mfm, off64_t *addr)
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
|
||||
if (drive->curcyl != mfm->cylinder) {
|
||||
pclog("WD1003(%d) sector: wrong cylinder\n");
|
||||
mfm_at_log("WD1003(%d) sector: wrong cylinder\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->head > drive->cfg_hpc) {
|
||||
pclog("WD1003(%d) get_sector: past end of configured heads\n",
|
||||
mfm_at_log("WD1003(%d) get_sector: past end of configured heads\n",
|
||||
mfm->drvsel);
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->sector >= drive->cfg_spt+1) {
|
||||
pclog("WD1003(%d) get_sector: past end of configured sectors\n",
|
||||
mfm_at_log("WD1003(%d) get_sector: past end of configured sectors\n",
|
||||
mfm->drvsel);
|
||||
return(1);
|
||||
}
|
||||
@@ -172,12 +191,12 @@ get_sector(mfm_t *mfm, off64_t *addr)
|
||||
#if 1
|
||||
/* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */
|
||||
if (mfm->head > drive->hpc) {
|
||||
pclog("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
|
||||
mfm_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->sector >= drive->spt+1) {
|
||||
pclog("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
|
||||
mfm_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
@@ -214,7 +233,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
|
||||
if (! drive->present) {
|
||||
/* This happens if sofware polls all drives. */
|
||||
pclog("WD1003(%d) command %02x on non-present drive\n",
|
||||
mfm_at_log("WD1003(%d) command %02x on non-present drive\n",
|
||||
mfm->drvsel, val);
|
||||
mfm->command = 0xff;
|
||||
mfm->status = STAT_BUSY;
|
||||
@@ -232,10 +251,8 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
switch (val & 0xf0) {
|
||||
case CMD_RESTORE:
|
||||
drive->steprate = (val & 0x0f);
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) restore, step=%d\n",
|
||||
mfm_at_log("WD1003(%d) restore, step=%d\n",
|
||||
mfm->drvsel, drive->steprate);
|
||||
#endif
|
||||
drive->curcyl = 0;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->command &= 0xf0;
|
||||
@@ -258,10 +275,8 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
case CMD_READ+1:
|
||||
case CMD_READ+2:
|
||||
case CMD_READ+3:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) read, opt=%d\n",
|
||||
mfm_at_log("WD1003(%d) read, opt=%d\n",
|
||||
mfm->drvsel, val&0x03);
|
||||
#endif
|
||||
mfm->command &= 0xfc;
|
||||
if (val & 2)
|
||||
fatal("WD1003: READ with ECC\n");
|
||||
@@ -275,10 +290,8 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
case CMD_WRITE+1:
|
||||
case CMD_WRITE+2:
|
||||
case CMD_WRITE+3:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) write, opt=%d\n",
|
||||
mfm_at_log("WD1003(%d) write, opt=%d\n",
|
||||
mfm->drvsel, val & 0x03);
|
||||
#endif
|
||||
mfm->command &= 0xfc;
|
||||
if (val & 2)
|
||||
fatal("WD1003: WRITE with ECC\n");
|
||||
@@ -328,11 +341,11 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
/* Only accept after RESET or DIAG. */
|
||||
drive->cfg_spt = mfm->secount;
|
||||
drive->cfg_hpc = mfm->head+1;
|
||||
pclog("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
|
||||
mfm_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
|
||||
mfm->drvsel, drive->tracks,
|
||||
drive->cfg_spt, drive->cfg_hpc);
|
||||
} else {
|
||||
pclog("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n",
|
||||
mfm_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n",
|
||||
mfm->drvsel, drive->tracks,
|
||||
drive->cfg_spt, drive->cfg_hpc);
|
||||
}
|
||||
@@ -343,7 +356,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("WD1003: bad command %02X\n", val);
|
||||
mfm_at_log("WD1003: bad command %02X\n", val);
|
||||
mfm->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
@@ -366,7 +379,9 @@ mfm_writew(uint16_t port, uint16_t val, void *priv)
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 6LL*MFM_TIME;
|
||||
/* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */
|
||||
mfm->callback = ((3125LL * TIMER_USEC) / 4LL);
|
||||
/* mfm->callback = 10LL * MFM_TIME; */
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
@@ -377,9 +392,8 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
|
||||
#if ENABLE_HDC_LOG > 1
|
||||
pclog("WD1003 write(%04x, %02x)\n", port, val);
|
||||
#endif
|
||||
mfm_at_log("WD1003 write(%04x, %02x)\n", port, val);
|
||||
|
||||
switch (port) {
|
||||
case 0x01f0: /* data */
|
||||
mfm_writew(port, val | (val << 8), priv);
|
||||
@@ -436,7 +450,9 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
mfm->status = STAT_BUSY;
|
||||
}
|
||||
mfm->fdisk = val;
|
||||
irq_update(mfm);
|
||||
/* Lower IRQ on IRQ disable. */
|
||||
if ((val & 2) && !(mfm->fdisk & 0x02))
|
||||
picintc(1 << 14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -459,7 +475,9 @@ mfm_readw(uint16_t port, void *priv)
|
||||
next_sector(mfm);
|
||||
mfm->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 6LL*MFM_TIME;
|
||||
/* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */
|
||||
mfm->callback = ((3125LL * TIMER_USEC) / 4LL);
|
||||
/* mfm->callback = 10LL * MFM_TIME; */
|
||||
timer_update_outstanding();
|
||||
} else {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
@@ -514,9 +532,8 @@ mfm_read(uint16_t port, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if ENABLE_HDC_LOG > 1
|
||||
pclog("WD1003 read(%04x) = %02x\n", port, ret);
|
||||
#endif
|
||||
|
||||
mfm_at_log("WD1003 read(%04x) = %02x\n", port, ret);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@@ -527,10 +544,9 @@ do_seek(mfm_t *mfm)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) seek(%d) max=%d\n",
|
||||
mfm_at_log("WD1003(%d) seek(%d) max=%d\n",
|
||||
mfm->drvsel,mfm->cylinder,drive->tracks);
|
||||
#endif
|
||||
|
||||
if (mfm->cylinder < drive->tracks)
|
||||
drive->curcyl = mfm->cylinder;
|
||||
else
|
||||
@@ -547,9 +563,8 @@ do_callback(void *priv)
|
||||
|
||||
mfm->callback = 0LL;
|
||||
if (mfm->reset) {
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) reset\n", mfm->drvsel);
|
||||
#endif
|
||||
mfm_at_log("WD1003(%d) reset\n", mfm->drvsel);
|
||||
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->error = 1;
|
||||
mfm->secount = 1;
|
||||
@@ -569,20 +584,16 @@ do_callback(void *priv)
|
||||
|
||||
switch (mfm->command) {
|
||||
case CMD_SEEK:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) seek, step=%d\n",
|
||||
mfm_at_log("WD1003(%d) seek, step=%d\n",
|
||||
mfm->drvsel, drive->steprate);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
break;
|
||||
|
||||
case CMD_READ:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) read(%d,%d,%d)\n",
|
||||
mfm_at_log("WD1003(%d) read(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
@@ -600,10 +611,8 @@ do_callback(void *priv)
|
||||
break;
|
||||
|
||||
case CMD_WRITE:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) write(%d,%d,%d)\n",
|
||||
mfm_at_log("WD1003(%d) write(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
@@ -628,10 +637,8 @@ do_callback(void *priv)
|
||||
break;
|
||||
|
||||
case CMD_VERIFY:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) verify(%d,%d,%d)\n",
|
||||
mfm_at_log("WD1003(%d) verify(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
@@ -640,10 +647,8 @@ do_callback(void *priv)
|
||||
break;
|
||||
|
||||
case CMD_FORMAT:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) format(%d,%d)\n",
|
||||
mfm_at_log("WD1003(%d) format(%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
@@ -660,9 +665,7 @@ do_callback(void *priv)
|
||||
break;
|
||||
|
||||
case CMD_DIAGNOSE:
|
||||
#if ENABLE_HDC_LOG
|
||||
pclog("WD1003(%d) diag\n", mfm->drvsel);
|
||||
#endif
|
||||
mfm_at_log("WD1003(%d) diag\n", mfm->drvsel);
|
||||
drive->steprate = 0x0f;
|
||||
mfm->error = 1;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
@@ -670,7 +673,7 @@ do_callback(void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("WD1003(%d) callback on unknown command %02x\n",
|
||||
mfm_at_log("WD1003(%d) callback on unknown command %02x\n",
|
||||
mfm->drvsel, mfm->command);
|
||||
mfm->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
mfm->error = ERR_ABRT;
|
||||
@@ -705,7 +708,7 @@ mfm_init(const device_t *info)
|
||||
mfm_t *mfm;
|
||||
int c, d;
|
||||
|
||||
pclog("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n");
|
||||
mfm_at_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n");
|
||||
mfm = malloc(sizeof(mfm_t));
|
||||
memset(mfm, 0x00, sizeof(mfm_t));
|
||||
|
||||
@@ -714,7 +717,7 @@ mfm_init(const device_t *info)
|
||||
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
|
||||
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
|
||||
|
||||
pclog("WD1003(%d): (%ls) geometry %d/%d/%d\n", c, hdd[d].fn,
|
||||
mfm_at_log("WD1003(%d): (%ls) geometry %d/%d/%d\n", c, hdd[d].fn,
|
||||
(int)hdd[d].tracks, (int)hdd[d].hpc, (int)hdd[d].spt);
|
||||
|
||||
if (++c >= MFM_NUM) break;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
* Since all controllers (including the ones made by DTC) use
|
||||
* (mostly) the same API, we keep them all in this module.
|
||||
*
|
||||
* Version: @(#)hdc_mfm_xt.c 1.0.16 2018/04/26
|
||||
* Version: @(#)hdc_mfm_xt.c 1.0.17 2018/04/29
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -52,11 +52,13 @@
|
||||
#define __USE_LARGEFILE64
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../dma.h"
|
||||
@@ -153,6 +155,26 @@ typedef struct {
|
||||
#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21
|
||||
|
||||
|
||||
#ifdef ENABLE_MFM_XT_LOG
|
||||
int mfm_xt_do_log = ENABLE_MFM_XT_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
mfm_xt_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_MFM_XT_LOG
|
||||
va_list ap;
|
||||
|
||||
if (mfm_xt_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mfm_read(uint16_t port, void *priv)
|
||||
{
|
||||
@@ -279,7 +301,7 @@ mfm_error(mfm_t *mfm, uint8_t error)
|
||||
mfm->completion_byte |= 0x02;
|
||||
mfm->error = error;
|
||||
|
||||
pclog("mfm_error - %02x\n", mfm->error);
|
||||
mfm_xt_log("mfm_error - %02x\n", mfm->error);
|
||||
}
|
||||
|
||||
|
||||
@@ -290,22 +312,22 @@ get_sector(mfm_t *mfm, off64_t *addr)
|
||||
int heads = drive->cfg_hpc;
|
||||
|
||||
if (drive->current_cylinder != mfm->cylinder) {
|
||||
pclog("mfm_get_sector: wrong cylinder\n");
|
||||
mfm_xt_log("mfm_get_sector: wrong cylinder\n");
|
||||
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (mfm->head > heads) {
|
||||
pclog("mfm_get_sector: past end of configured heads\n");
|
||||
mfm_xt_log("mfm_get_sector: past end of configured heads\n");
|
||||
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (mfm->head > drive->hpc) {
|
||||
pclog("mfm_get_sector: past end of heads\n");
|
||||
mfm_xt_log("mfm_get_sector: past end of heads\n");
|
||||
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (mfm->sector >= 17) {
|
||||
pclog("mfm_get_sector: past end of sectors\n");
|
||||
mfm_xt_log("mfm_get_sector: past end of sectors\n");
|
||||
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
@@ -396,7 +418,7 @@ mfm_callback(void *priv)
|
||||
mfm->sector_count = mfm->command[4];
|
||||
do {
|
||||
if (get_sector(mfm, &addr)) {
|
||||
pclog("get_sector failed\n");
|
||||
mfm_xt_log("get_sector failed\n");
|
||||
mfm_error(mfm, mfm->error);
|
||||
mfm_complete(mfm);
|
||||
return;
|
||||
@@ -423,7 +445,7 @@ mfm_callback(void *priv)
|
||||
mfm->head = mfm->command[1] & 0x1f;
|
||||
|
||||
if (get_sector(mfm, &addr)) {
|
||||
pclog("get_sector failed\n");
|
||||
mfm_xt_log("get_sector failed\n");
|
||||
mfm_error(mfm, mfm->error);
|
||||
mfm_complete(mfm);
|
||||
return;
|
||||
@@ -471,7 +493,7 @@ mfm_callback(void *priv)
|
||||
int val = dma_channel_write(3, mfm->sector_buf[mfm->data_pos]);
|
||||
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_READ_SECTORS out of data!\n");
|
||||
mfm_xt_log("CMD_READ_SECTORS out of data!\n");
|
||||
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
mfm->callback = MFM_TIME;
|
||||
return;
|
||||
@@ -544,7 +566,7 @@ mfm_callback(void *priv)
|
||||
int val = dma_channel_read(3);
|
||||
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_WRITE_SECTORS out of data!\n");
|
||||
mfm_xt_log("CMD_WRITE_SECTORS out of data!\n");
|
||||
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
mfm->callback = MFM_TIME;
|
||||
return;
|
||||
@@ -619,7 +641,7 @@ mfm_callback(void *priv)
|
||||
case STATE_RECEIVED_DATA:
|
||||
drive->cfg_cyl = mfm->data[1] | (mfm->data[0] << 8);
|
||||
drive->cfg_hpc = mfm->data[2];
|
||||
pclog("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
|
||||
mfm_xt_log("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
|
||||
mfm_complete(mfm);
|
||||
break;
|
||||
|
||||
@@ -648,7 +670,7 @@ mfm_callback(void *priv)
|
||||
int val = dma_channel_read(3);
|
||||
|
||||
if (val == DMA_NODATA) {
|
||||
pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n");
|
||||
mfm_xt_log("CMD_WRITE_SECTOR_BUFFER out of data!\n");
|
||||
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
mfm->callback = MFM_TIME;
|
||||
return;
|
||||
@@ -697,7 +719,7 @@ mfm_callback(void *priv)
|
||||
mfm->data[0] = drive->tracks & 0xff;
|
||||
mfm->data[1] = 17 | ((drive->tracks >> 2) & 0xc0);
|
||||
mfm->data[2] = drive->hpc-1;
|
||||
pclog("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks);
|
||||
mfm_xt_log("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks);
|
||||
break;
|
||||
|
||||
case STATE_SENT_DATA:
|
||||
@@ -803,7 +825,7 @@ mfm_set_switches(mfm_t *mfm)
|
||||
}
|
||||
|
||||
if (c == 4)
|
||||
pclog("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C');
|
||||
mfm_xt_log("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,16 +838,16 @@ xebec_init(const device_t *info)
|
||||
mfm_t *xebec = malloc(sizeof(mfm_t));
|
||||
memset(xebec, 0x00, sizeof(mfm_t));
|
||||
|
||||
pclog("MFM: looking for disks..\n");
|
||||
mfm_xt_log("MFM: looking for disks..\n");
|
||||
for (i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||
pclog("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
|
||||
mfm_xt_log("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
|
||||
loadhd(xebec, i, hdd[i].mfm_channel, hdd[i].fn);
|
||||
|
||||
if (++c > MFM_NUM) break;
|
||||
}
|
||||
}
|
||||
pclog("MFM: %d disks loaded.\n", c);
|
||||
mfm_xt_log("MFM: %d disks loaded.\n", c);
|
||||
|
||||
mfm_set_switches(xebec);
|
||||
|
||||
@@ -881,16 +903,16 @@ dtc5150x_init(const device_t *info)
|
||||
mfm_t *dtc = malloc(sizeof(mfm_t));
|
||||
memset(dtc, 0x00, sizeof(mfm_t));
|
||||
|
||||
pclog("MFM: looking for disks..\n");
|
||||
mfm_xt_log("MFM: looking for disks..\n");
|
||||
for (i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||
pclog("Found MFM hard disk on channel %i (%ls)\n", hdd[i].mfm_channel, hdd[i].fn);
|
||||
mfm_xt_log("Found MFM hard disk on channel %i (%ls)\n", hdd[i].mfm_channel, hdd[i].fn);
|
||||
loadhd(dtc, i, hdd[i].mfm_channel, hdd[i].fn);
|
||||
|
||||
if (++c > MFM_NUM) break;
|
||||
}
|
||||
}
|
||||
pclog("MFM: %d disks loaded.\n", c);
|
||||
mfm_xt_log("MFM: %d disks loaded.\n", c);
|
||||
|
||||
dtc->switches = 0xff;
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
*
|
||||
* NOTE: The XTA interface is 0-based for sector numbers !!
|
||||
*
|
||||
* Version: @(#)hdc_ide_xta.c 1.0.7 2018/04/26
|
||||
* Version: @(#)hdc_ide_xta.c 1.0.8 2018/04/29
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -87,11 +87,13 @@
|
||||
#define __USE_LARGEFILE64
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../io.h"
|
||||
#include "../dma.h"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the hard disk image handler.
|
||||
*
|
||||
* Version: @(#)hdd.h 1.0.4 2018/03/29
|
||||
* Version: @(#)hdd.h 1.0.5 2018/04/30
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -119,6 +119,7 @@ extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8
|
||||
extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern uint32_t hdd_image_get_last_sector(uint8_t id);
|
||||
extern uint32_t hdd_image_get_pos(uint8_t id);
|
||||
extern uint8_t hdd_image_get_type(uint8_t id);
|
||||
extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt);
|
||||
extern void hdd_image_unload(uint8_t id, int fn_preserve);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of hard disk image files.
|
||||
*
|
||||
* Version: @(#)hdd_image.c 1.0.14 2018/03/28
|
||||
* Version: @(#)hdd_image.c 1.0.15 2018/04/29
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -19,11 +19,11 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#define HAVE_STDARG_H
|
||||
@@ -36,9 +36,9 @@ typedef struct
|
||||
{
|
||||
FILE *file;
|
||||
uint32_t base;
|
||||
uint32_t last_sector;
|
||||
uint32_t pos, last_sector;
|
||||
uint8_t type;
|
||||
uint8_t loaded;
|
||||
uint8_t loaded;
|
||||
} hdd_image_t;
|
||||
|
||||
|
||||
@@ -48,23 +48,22 @@ static char empty_sector[512];
|
||||
static char *empty_sector_1mb;
|
||||
|
||||
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
int hdd_image_do_log = ENABLE_HDD_LOG;
|
||||
#ifdef ENABLE_HDD_IMAGE_LOG
|
||||
int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
hdd_image_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_HDD_LOG
|
||||
va_list ap;
|
||||
#ifdef ENABLE_HDD_IMAGE_LOG
|
||||
va_list ap;
|
||||
|
||||
if (hdd_image_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
if (hdd_image_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -203,6 +202,8 @@ hdd_image_load(int id)
|
||||
is_hdx[0] = image_is_hdx(fn, 0);
|
||||
is_hdx[1] = image_is_hdx(fn, 1);
|
||||
|
||||
hdd_images[id].pos = 0;
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.') {
|
||||
hdd_image_log("File name starts with .\n");
|
||||
@@ -345,8 +346,9 @@ void
|
||||
hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
off64_t addr = sector;
|
||||
addr = (uint64_t)sector * 512;
|
||||
addr = (uint64_t)sector << 9LL;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET);
|
||||
}
|
||||
|
||||
@@ -354,6 +356,7 @@ hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
void
|
||||
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, count << 9, hdd_images[id].file);
|
||||
}
|
||||
@@ -376,6 +379,7 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, transfer_sectors << 9, hdd_images[id].file);
|
||||
|
||||
@@ -388,6 +392,7 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
void
|
||||
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, count << 9, 1, hdd_images[id].file);
|
||||
}
|
||||
@@ -402,6 +407,7 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, transfer_sectors << 9, 1, hdd_images[id].file);
|
||||
|
||||
@@ -416,6 +422,7 @@ hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < count; i++)
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
@@ -433,6 +440,7 @@ hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < transfer_sectors; i++)
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
@@ -450,6 +458,13 @@ hdd_image_get_last_sector(uint8_t id)
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
hdd_image_get_pos(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].pos;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
hdd_image_get_type(uint8_t id)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the Iomega ZIP drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)zip.h 1.0.5 2018/03/26
|
||||
* Version: @(#)zip.h 1.0.6 2018/04/30
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
|
||||
#define IDE_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
#define ZIP_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
|
||||
#define ZIP_SECTORS (96*2048)
|
||||
|
||||
Reference in New Issue
Block a user