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:
OBattler
2018-05-21 19:04:05 +02:00
parent 534ed6ea32
commit 5d8deea63b
130 changed files with 5062 additions and 3262 deletions

View File

@@ -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. */

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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)