Hard disk image handling is now unified in hdd_image.c/h;
Fixed some bugs regarding the Winbond W83877F Super I/O Chip and serial ports; Added the President Award 430FX PCI machine, thank you ashenone for the BIOS.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Modified Makefile for Win32 (MinGW32) environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.28 2017/06/14
|
||||
# Version: @(#)Makefile.mingw 1.0.29 2017/06/16
|
||||
#
|
||||
# Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -143,6 +143,7 @@ SYSOBJ = model.o \
|
||||
olivetti_m24.o ps1.o ps2.o ps2_mca.o \
|
||||
tandy_eeprom.o tandy_rom.o
|
||||
DEVOBJ = bugger.o lpt.o serial.o \
|
||||
fdc37c665.o fdc37c669.o fdc37c932fr.o \
|
||||
pc87306.o sis85c471.o w83877f.o \
|
||||
keyboard.o \
|
||||
keyboard_xt.o keyboard_at.o keyboard_pcjr.o \
|
||||
@@ -151,9 +152,8 @@ DEVOBJ = bugger.o lpt.o serial.o \
|
||||
joystick_standard.o joystick_ch_flightstick_pro.o \
|
||||
joystick_sw_pad.o joystick_tm_fcs.o \
|
||||
mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \
|
||||
fdd.o fdc.o \
|
||||
fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \
|
||||
hdd.o \
|
||||
fdd.o fdc.o fdi2raw.o \
|
||||
hdd.o hdd_image.o \
|
||||
mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \
|
||||
disc.o \
|
||||
disc_86f.o disc_fdi.o disc_imd.o disc_img.o \
|
||||
@@ -338,8 +338,10 @@ gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \
|
||||
hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \
|
||||
mfm_at.h mfm_xebec.h xtide.h
|
||||
|
||||
hdd_esdi.o: ibm.h device.h dma.h io.h mca.h mem.h pic.h rom.h \
|
||||
timer.h hdd_esdi.h
|
||||
hdd_image.o: ibm.h ide.h hdd_image.h
|
||||
|
||||
hdd_esdi.o: ibm.h device.h dma.h hdd_image.h io.h mca.h mem.h \
|
||||
pic.h rom.h timer.h hdd_esdi.h
|
||||
|
||||
headland.o: ibm.h cpu/cpu.h io.h mem.h headland.h
|
||||
|
||||
@@ -357,7 +359,7 @@ i440fx.o: ibm.h io.h mem.h pci.h i440fx.h
|
||||
|
||||
i82335.o: ibm.h io.h mem.h
|
||||
|
||||
ide.o: 86box.h cdrom.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h
|
||||
ide.o: 86box.h cdrom.h hdd_image.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h
|
||||
|
||||
intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h
|
||||
|
||||
@@ -410,9 +412,9 @@ mem.o: ibm.h cpu/cpu.h cpu/x86_ops.h cpu/x86.h config.h \
|
||||
|
||||
memregs.o: ibm.h io.h memregs.h
|
||||
|
||||
mfm_at.o: ibm.h device.h io.h pic.h timer.h mfm_at.h
|
||||
mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h
|
||||
|
||||
mfm_xebec.o: ibm.h device.h dma.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h
|
||||
mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h
|
||||
|
||||
model.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h mouse.h \
|
||||
mouse_ps2.h cdrom.h acerm3a.h ali1429.h amstrad.h compaq.h \
|
||||
@@ -497,8 +499,8 @@ scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \
|
||||
scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \
|
||||
device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h
|
||||
|
||||
scsi_disk.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h scsi_disk.h \
|
||||
timer.h win/plat_iodev.h
|
||||
scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \
|
||||
scsi_disk.h timer.h win/plat_iodev.h
|
||||
|
||||
serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ static void write_lock(uint8_t val)
|
||||
|
||||
static void ide_handler()
|
||||
{
|
||||
#if 0
|
||||
uint16_t or_value = 0;
|
||||
if ((romset == ROM_440FX) || (romset == ROM_R418) || (romset == ROM_MB500N))
|
||||
{
|
||||
@@ -65,6 +66,7 @@ static void ide_handler()
|
||||
ide_set_side(0, 0x376 | or_value);
|
||||
ide_pri_enable_ex();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_com34_addr()
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <malloc.h>
|
||||
#include "ibm.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "dma.h"
|
||||
#include "hdd_image.h"
|
||||
#include "io.h"
|
||||
#include "mca.h"
|
||||
#include "mem.h"
|
||||
@@ -30,7 +22,8 @@ typedef struct esdi_drive_t
|
||||
int spt, hpc;
|
||||
int tracks;
|
||||
int sectors;
|
||||
FILE *hdfile;
|
||||
int present;
|
||||
int hdc_num;
|
||||
} esdi_drive_t;
|
||||
|
||||
typedef struct esdi_t
|
||||
@@ -395,7 +388,7 @@ static void esdi_callback(void *p)
|
||||
case CMD_READ:
|
||||
ESDI_DRIVE_ONLY();
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
{
|
||||
device_not_present(esdi);
|
||||
return;
|
||||
@@ -431,8 +424,7 @@ static void esdi_callback(void *p)
|
||||
{
|
||||
if (esdi->rba >= drive->sectors)
|
||||
fatal("Read past end of drive\n");
|
||||
fseek(drive->hdfile, esdi->rba * 512, SEEK_SET);
|
||||
fread(esdi->data, 512, 1, drive->hdfile);
|
||||
hdd_image_read(drive->hdc_num, esdi->rba, 1, (uint8_t *) esdi->data);
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1);
|
||||
}
|
||||
while (esdi->data_pos < 256)
|
||||
@@ -471,7 +463,7 @@ static void esdi_callback(void *p)
|
||||
case CMD_WRITE_VERIFY:
|
||||
ESDI_DRIVE_ONLY();
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
{
|
||||
device_not_present(esdi);
|
||||
return;
|
||||
@@ -518,8 +510,7 @@ static void esdi_callback(void *p)
|
||||
|
||||
if (esdi->rba >= drive->sectors)
|
||||
fatal("Write past end of drive\n");
|
||||
fseek(drive->hdfile, esdi->rba * 512, SEEK_SET);
|
||||
fwrite(esdi->data, 512, 1, drive->hdfile);
|
||||
hdd_image_write(drive->hdc_num, esdi->rba, 1, (uint8_t *) esdi->data);
|
||||
esdi->rba++;
|
||||
esdi->sector_pos++;
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1);
|
||||
@@ -545,7 +536,7 @@ static void esdi_callback(void *p)
|
||||
case CMD_READ_VERIFY:
|
||||
ESDI_DRIVE_ONLY();
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
{
|
||||
device_not_present(esdi);
|
||||
return;
|
||||
@@ -560,7 +551,7 @@ static void esdi_callback(void *p)
|
||||
case CMD_SEEK:
|
||||
ESDI_DRIVE_ONLY();
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
{
|
||||
device_not_present(esdi);
|
||||
return;
|
||||
@@ -575,7 +566,7 @@ static void esdi_callback(void *p)
|
||||
case CMD_GET_DEV_CONFIG:
|
||||
ESDI_DRIVE_ONLY();
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
{
|
||||
device_not_present(esdi);
|
||||
return;
|
||||
@@ -799,40 +790,22 @@ static void esdi_mca_write(int port, uint8_t val, void *p)
|
||||
static void loadhd(esdi_t *esdi, int hdc_num, int d, const wchar_t *fn)
|
||||
{
|
||||
esdi_drive_t *drive = &esdi->drives[d];
|
||||
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Try to open existing hard disk image */
|
||||
drive->hdfile = _wfopen(fn, L"rb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
drive->hdfile = _wfopen(fn, L"wb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
pclog("Cannot create file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
pclog("Cannot open file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
ret = hdd_image_load(hdc_num);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
drive->present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
drive->spt = hdc[hdc_num].spt;
|
||||
drive->hpc = hdc[hdc_num].hpc;
|
||||
drive->tracks = hdc[hdc_num].tracks;
|
||||
drive->sectors = hdc[hdc_num].spt * hdc[hdc_num].hpc * hdc[hdc_num].tracks;
|
||||
drive->hdc_num = hdc_num;
|
||||
drive->present = 1;
|
||||
}
|
||||
|
||||
static void *esdi_init()
|
||||
@@ -878,9 +851,8 @@ static void esdi_close(void *p)
|
||||
for (d = 0; d < 2; d++)
|
||||
{
|
||||
esdi_drive_t *drive = &esdi->drives[d];
|
||||
|
||||
if (drive->hdfile != NULL)
|
||||
fclose(drive->hdfile);
|
||||
|
||||
hdd_image_close(drive->hdc_num);
|
||||
}
|
||||
|
||||
free(esdi);
|
||||
|
||||
441
src/hdd_image.c
Normal file
441
src/hdd_image.c
Normal file
@@ -0,0 +1,441 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "ide.h"
|
||||
#include "hdd_image.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE *file;
|
||||
uint32_t base;
|
||||
uint32_t last_sector;
|
||||
uint8_t type;
|
||||
uint8_t loaded;
|
||||
} hdd_image_t;
|
||||
|
||||
hdd_image_t hdd_images[HDC_NUM];
|
||||
|
||||
static char empty_sector[512];
|
||||
static char *empty_sector_1mb;
|
||||
|
||||
int hdd_image_do_log = 0;
|
||||
|
||||
void hdd_image_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_HDD_IMAGE_LOG
|
||||
if (hdd_image_do_log)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int image_is_hdi(const wchar_t *s)
|
||||
{
|
||||
int len;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcsicmp(ext, L".HDI") == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int image_is_hdx(const wchar_t *s, int check_signature)
|
||||
{
|
||||
int len;
|
||||
FILE *f;
|
||||
uint64_t filelen;
|
||||
uint64_t signature;
|
||||
char *ws = (char *) s;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcsicmp(ext, L".HDX") == 0)
|
||||
{
|
||||
if (check_signature)
|
||||
{
|
||||
f = _wfopen(s, L"rb");
|
||||
if (!f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
filelen = ftello64(f);
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (filelen < 44)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fread(&signature, 1, 8, f);
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int hdd_image_load(int id)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
uint64_t spt = 0, hpc = 0, tracks = 0;
|
||||
int c;
|
||||
uint64_t i = 0, s = 0, t = 0;
|
||||
wchar_t *fn = hdc[id].fn;
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
|
||||
hdd_images[id].base = 0;
|
||||
hdd_images[id].loaded = 0;
|
||||
|
||||
if (hdd_images[id].file != NULL)
|
||||
{
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.')
|
||||
{
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].file = _wfopen(fn, L"rb+");
|
||||
if (hdd_images[id].file == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdc[id].wp)
|
||||
{
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdd_images[id].file = _wfopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL)
|
||||
{
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
{
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
}
|
||||
hdd_images[id].type = 1;
|
||||
}
|
||||
else if (image_is_hdx(fn, 0))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
|
||||
s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
|
||||
goto prepare_new_hard_disk;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
fseeko64(hdd_images[id].file, 0x8, SEEK_SET);
|
||||
fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0xC, SEEK_SET);
|
||||
full_size = 0;
|
||||
fread(&full_size, 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
hdd_image_log("HDI: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
hdd_images[id].type = 1;
|
||||
}
|
||||
else if (image_is_hdx(fn, 1))
|
||||
{
|
||||
hdd_images[id].base = 0x28;
|
||||
fseeko64(hdd_images[id].file, 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
hdd_image_log("HDX: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
fread(&(hdc[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fread(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base))
|
||||
{
|
||||
s = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file);
|
||||
prepare_new_hard_disk:
|
||||
s >>= 9;
|
||||
t = (s >> 11) << 11;
|
||||
s -= t;
|
||||
t >>= 11;
|
||||
|
||||
empty_sector_1mb = (char *) malloc(1048576);
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
if (s > 0)
|
||||
{
|
||||
for (i = 0; i < s; i++)
|
||||
{
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
for (i = 0; i < t; i++)
|
||||
{
|
||||
fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
free(empty_sector_1mb);
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
|
||||
return 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
}
|
||||
|
||||
void hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
uint64_t addr = sector;
|
||||
addr <<= 9;
|
||||
addr += hdd_images[id].base;
|
||||
|
||||
fseeko64(hdd_images[id].file, addr, SEEK_SET);
|
||||
}
|
||||
|
||||
void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
count <<= 9;
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
memset(buffer, 0, count);
|
||||
fread(buffer, 1, count, hdd_images[id].file);
|
||||
}
|
||||
|
||||
void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
count <<= 9;
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
fwrite(buffer, 1, count, hdd_images[id].file);
|
||||
}
|
||||
|
||||
void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t *b;
|
||||
|
||||
b = (uint8_t *) malloc(512);
|
||||
memset(b, 0, 512);
|
||||
|
||||
hdd_image_seek(id, sector);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
fwrite(b, 1, 512, hdd_images[id].file);
|
||||
}
|
||||
|
||||
free(b);
|
||||
}
|
||||
|
||||
uint32_t hdd_image_get_last_sector(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].last_sector;
|
||||
}
|
||||
|
||||
uint8_t hdd_image_get_type(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].type;
|
||||
}
|
||||
|
||||
void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt)
|
||||
{
|
||||
if (hdd_images[id].type == 2)
|
||||
{
|
||||
hdc[id].at_hpc = hpc;
|
||||
hdc[id].at_spt = spt;
|
||||
fseeko64(hdd_images[id].file, 0x20, SEEK_SET);
|
||||
fwrite(&(hdc[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
void hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
{
|
||||
if (wcslen(hdc[id].fn) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdd_images[id].loaded)
|
||||
{
|
||||
if (hdd_images[id].file != NULL)
|
||||
{
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = -1;
|
||||
|
||||
memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn));
|
||||
if (fn_preserve)
|
||||
{
|
||||
wcscpy(hdc[id].prev_fn, hdc[id].fn);
|
||||
}
|
||||
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
}
|
||||
|
||||
void hdd_image_close(uint8_t id)
|
||||
{
|
||||
if (hdd_images[id].file != NULL)
|
||||
{
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
}
|
||||
10
src/hdd_image.h
Normal file
10
src/hdd_image.h
Normal file
@@ -0,0 +1,10 @@
|
||||
extern int hdd_image_load(int id);
|
||||
extern void hdd_image_seek(uint8_t id, uint32_t sector);
|
||||
extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern uint32_t hdd_image_get_last_sector(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);
|
||||
extern void hdd_image_close(uint8_t id);
|
||||
@@ -471,6 +471,8 @@ enum
|
||||
ROM_S1668, /*Tyan Titan-Pro ATX / 440FX / AMI BIOS / SMC FDC37C669*/
|
||||
ROM_IBMPS1_2133,
|
||||
|
||||
ROM_PRESIDENT, /*President Award 430FX PCI / 430FX / Award BIOS / Unknown Super I/O chip*/
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
||||
|
||||
275
src/ide.c
275
src/ide.c
@@ -9,7 +9,7 @@
|
||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||
* CD-ROM devices.
|
||||
*
|
||||
* Version: @(#)ide.c 1.0.1 2017/06/03
|
||||
* Version: @(#)ide.c 1.0.2 2017/06/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,23 +18,14 @@
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2016-2017 TheCollector1995.
|
||||
*/
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "86box.h"
|
||||
#include "cdrom.h"
|
||||
#include "ibm.h"
|
||||
#include "hdd_image.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
@@ -163,79 +154,6 @@ int ide_drive_is_cdrom(IDE *ide)
|
||||
}
|
||||
}
|
||||
|
||||
int image_is_hdi(const wchar_t *s)
|
||||
{
|
||||
int len;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcsicmp(ext, L".HDI") == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int image_is_hdx(const wchar_t *s, int check_signature)
|
||||
{
|
||||
int len;
|
||||
FILE *f;
|
||||
uint64_t filelen;
|
||||
uint64_t signature;
|
||||
char *ws = (char *) s;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcsicmp(ext, L".HDX") == 0)
|
||||
{
|
||||
if (check_signature)
|
||||
{
|
||||
f = _wfopen(s, L"rb");
|
||||
if (!f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
filelen = ftello64(f);
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (filelen < 44)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fread(&signature, 1, 8, f);
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ide_enable[5] = { 1, 1, 0, 0, 1 };
|
||||
int ide_irq[5] = { 14, 15, 10, 11, 0 };
|
||||
|
||||
@@ -371,7 +289,7 @@ static void ide_identify(IDE *ide)
|
||||
#if 0
|
||||
uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt);
|
||||
#endif
|
||||
|
||||
|
||||
device_identify[6] = (ide->hdc_num / 10) + 0x30;
|
||||
device_identify[7] = (ide->hdc_num % 10) + 0x30;
|
||||
ide_log("IDE Identify: %s\n", device_identify);
|
||||
@@ -525,126 +443,22 @@ static void ide_next_sector(IDE *ide)
|
||||
|
||||
static void loadhd(IDE *ide, int d, const wchar_t *fn)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
int c;
|
||||
ide->base = 0;
|
||||
ide->hdi = 0;
|
||||
if (ide->hdfile == NULL)
|
||||
int ret = 0;
|
||||
|
||||
ret = hdd_image_load(d);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == L'.')
|
||||
{
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
ide->hdfile = _wfopen(fn, L"rb+");
|
||||
if (ide->hdfile == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
ide->hdfile = _wfopen(fn, L"wb+");
|
||||
if (ide->hdfile == NULL)
|
||||
{
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
full_size = hdc[d].spt * hdc[d].hpc * hdc[d].tracks * 512;
|
||||
ide->base = 0x1000;
|
||||
ide->hdi = 1;
|
||||
fwrite(&zero, 1, 4, ide->hdfile);
|
||||
fwrite(&zero, 1, 4, ide->hdfile);
|
||||
fwrite(&(ide->base), 1, 4, ide->hdfile);
|
||||
fwrite(&full_size, 1, 4, ide->hdfile);
|
||||
fwrite(§or_size, 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].spt), 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].hpc), 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].tracks), 1, 4, ide->hdfile);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
{
|
||||
fwrite(&zero, 1, 4, ide->hdfile);
|
||||
}
|
||||
}
|
||||
else if (image_is_hdx(fn, 0))
|
||||
{
|
||||
full_size = hdc[d].spt * hdc[d].hpc * hdc[d].tracks * 512;
|
||||
ide->base = 0x28;
|
||||
ide->hdi = 2;
|
||||
fwrite(&signature, 1, 8, ide->hdfile);
|
||||
fwrite(&full_size, 1, 8, ide->hdfile);
|
||||
fwrite(§or_size, 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].spt), 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].hpc), 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[d].tracks), 1, 4, ide->hdfile);
|
||||
fwrite(&zero, 1, 4, ide->hdfile);
|
||||
fwrite(&zero, 1, 4, ide->hdfile);
|
||||
}
|
||||
ide->hdc_num = d;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
fseeko64(ide->hdfile, 0x8, SEEK_SET);
|
||||
fread(&(ide->base), 1, 4, ide->hdfile);
|
||||
fseeko64(ide->hdfile, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, ide->hdfile);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
fclose(ide->hdfile);
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
fread(&(hdc[d].spt), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].hpc), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].tracks), 1, 4, ide->hdfile);
|
||||
ide->hdi = 1;
|
||||
}
|
||||
else if (image_is_hdx(fn, 1))
|
||||
{
|
||||
ide->base = 0x28;
|
||||
fseeko64(ide->hdfile, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, ide->hdfile);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
fclose(ide->hdfile);
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
fread(&(hdc[d].spt), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].hpc), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].tracks), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].at_spt), 1, 4, ide->hdfile);
|
||||
fread(&(hdc[d].at_hpc), 1, 4, ide->hdfile);
|
||||
ide->hdi = 2;
|
||||
}
|
||||
}
|
||||
ide->type = IDE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
ide->spt = hdc[d].spt;
|
||||
ide->hpc = hdc[d].hpc;
|
||||
ide->tracks = hdc[d].tracks;
|
||||
ide->type = IDE_HDD;
|
||||
|
||||
ide->spt = hdc[d].spt;
|
||||
ide->hpc = hdc[d].hpc;
|
||||
ide->tracks = hdc[d].tracks;
|
||||
ide->type = IDE_HDD;
|
||||
ide->hdc_num = d;
|
||||
ide->hdi = hdd_image_get_type(d);
|
||||
}
|
||||
|
||||
void ide_set_signature(IDE *ide)
|
||||
@@ -771,11 +585,7 @@ void resetide(void)
|
||||
{
|
||||
ide_drives[d].channel = d;
|
||||
ide_drives[d].type = IDE_NONE;
|
||||
if (ide_drives[d].hdfile != NULL)
|
||||
{
|
||||
fclose(ide_drives[d].hdfile);
|
||||
ide_drives[d].hdfile = NULL;
|
||||
}
|
||||
hdd_image_close(ide_drives[d].hdc_num);
|
||||
if (ide_drive_is_cdrom(&ide_drives[d]))
|
||||
{
|
||||
cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT;
|
||||
@@ -856,13 +666,6 @@ void ide_write_data(int ide_board, uint32_t val, int length)
|
||||
uint16_t *idebufferw = ide->buffer;
|
||||
uint32_t *idebufferl = (uint32_t *) ide->buffer;
|
||||
|
||||
#if 0
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
ide_log("CD-ROM write data: %04X\n", val);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ide->command == WIN_PACKETCMD)
|
||||
{
|
||||
ide->pos = 0;
|
||||
@@ -1621,8 +1424,6 @@ int times30=0;
|
||||
void callbackide(int ide_board)
|
||||
{
|
||||
IDE *ide, *ide_other;
|
||||
off64_t addr;
|
||||
int c;
|
||||
int64_t snum;
|
||||
int cdrom_id;
|
||||
uint64_t full_size = 0;
|
||||
@@ -1760,10 +1561,8 @@ void callbackide(int ide_board)
|
||||
{
|
||||
goto id_not_found;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
fread(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->pos=0;
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
|
||||
@@ -1781,9 +1580,7 @@ void callbackide(int ide_board)
|
||||
{
|
||||
goto id_not_found;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, addr, SEEK_SET);
|
||||
fread(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->pos=0;
|
||||
|
||||
if (ide_bus_master_read)
|
||||
@@ -1831,9 +1628,7 @@ void callbackide(int ide_board)
|
||||
goto id_not_found;
|
||||
}
|
||||
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
fread(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->pos=0;
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
if (!ide->blockcount)
|
||||
@@ -1859,9 +1654,7 @@ void callbackide(int ide_board)
|
||||
{
|
||||
goto id_not_found;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide_irq_raise(ide);
|
||||
ide->secount = (ide->secount - 1) & 0xff;
|
||||
if (ide->secount)
|
||||
@@ -1898,9 +1691,7 @@ void callbackide(int ide_board)
|
||||
else
|
||||
{
|
||||
/*DMA successful*/
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
|
||||
@@ -1931,9 +1722,7 @@ void callbackide(int ide_board)
|
||||
{
|
||||
goto id_not_found;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->blockcount++;
|
||||
if (ide->blockcount >= ide->blocksize || ide->secount == 1)
|
||||
{
|
||||
@@ -1980,13 +1769,8 @@ void callbackide(int ide_board)
|
||||
{
|
||||
goto id_not_found;
|
||||
}
|
||||
addr = ide_get_sector(ide) * 512;
|
||||
fseeko64(ide->hdfile, ide->base + addr, SEEK_SET);
|
||||
memset(ide->buffer, 0, 512);
|
||||
for (c=0;c<ide->secount;c++)
|
||||
{
|
||||
fwrite(ide->buffer, 512, 1, ide->hdfile);
|
||||
}
|
||||
hdd_image_zero(ide->hdc_num, ide_get_sector(ide), ide->secount);
|
||||
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide_irq_raise(ide);
|
||||
|
||||
@@ -2019,14 +1803,7 @@ void callbackide(int ide_board)
|
||||
full_size /= (ide->head+1);
|
||||
full_size /= ide->secount;
|
||||
ide->specify_success = 1;
|
||||
if (ide->hdi == 2)
|
||||
{
|
||||
hdc[ide->hdc_num].at_hpc = ide->head+1;
|
||||
hdc[ide->hdc_num].at_spt = ide->secount;
|
||||
fseeko64(ide->hdfile, 0x20, SEEK_SET);
|
||||
fwrite(&(hdc[ide->hdc_num].at_spt), 1, 4, ide->hdfile);
|
||||
fwrite(&(hdc[ide->hdc_num].at_hpc), 1, 4, ide->hdfile);
|
||||
}
|
||||
hdd_image_specify(ide->hdc_num, ide->head + 1, ide->secount);
|
||||
ide->spt=ide->secount;
|
||||
ide->hpc=ide->head+1;
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
|
||||
@@ -38,7 +38,6 @@ typedef struct {
|
||||
int packetstatus;
|
||||
uint8_t asc;
|
||||
int reset;
|
||||
FILE *hdfile;
|
||||
uint16_t buffer[65536];
|
||||
int irqstat;
|
||||
int service;
|
||||
|
||||
@@ -700,6 +700,14 @@ int loadbios()
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_PRESIDENT:
|
||||
f = romfopen(L"roms/president/BIOS.BIN", L"rb");
|
||||
if (!f) break;
|
||||
fread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_P54TP4XE:
|
||||
f = romfopen(L"roms/p54tp4xe/T15I0302.AWD", L"rb");
|
||||
if (!f) break;
|
||||
|
||||
81
src/mfm_at.c
81
src/mfm_at.c
@@ -1,16 +1,7 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "hdd_image.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
@@ -53,7 +44,8 @@ typedef struct mfm_drive_t
|
||||
int cfg_spt;
|
||||
int cfg_hpc;
|
||||
int current_cylinder;
|
||||
FILE *hdfile;
|
||||
int present;
|
||||
int hdc_num;
|
||||
} mfm_drive_t;
|
||||
|
||||
typedef struct mfm_t
|
||||
@@ -163,39 +155,21 @@ static void mfm_next_sector(mfm_t *mfm)
|
||||
static void loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn)
|
||||
{
|
||||
mfm_drive_t *drive = &mfm->drives[c];
|
||||
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Try to open existing hard disk image */
|
||||
drive->hdfile = _wfopen(fn, L"rb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
drive->hdfile = _wfopen(fn, L"wb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
pclog("Cannot create file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
pclog("Cannot open file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
ret = hdd_image_load(d);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
drive->present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
drive->spt = hdc[d].spt;
|
||||
drive->hpc = hdc[d].hpc;
|
||||
drive->tracks = hdc[d].tracks;
|
||||
drive->hdc_num = d;
|
||||
drive->present = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,14 +207,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p)
|
||||
case 0x1F6: /* Drive/Head */
|
||||
mfm->head = val & 0xF;
|
||||
mfm->drive_sel = (val & 0x10) ? 1 : 0;
|
||||
if (mfm->drives[mfm->drive_sel].hdfile == NULL)
|
||||
mfm->status = 0;
|
||||
else
|
||||
if (mfm->drives[mfm->drive_sel].present)
|
||||
mfm->status = STAT_READY | STAT_DSC;
|
||||
else
|
||||
mfm->status = 0;
|
||||
return;
|
||||
|
||||
case 0x1F7: /* Command register */
|
||||
if (mfm->drives[mfm->drive_sel].hdfile == NULL)
|
||||
if (!mfm->drives[mfm->drive_sel].present)
|
||||
fatal("Command on non-present drive\n");
|
||||
|
||||
mfm_irq_lower(mfm);
|
||||
@@ -462,7 +436,6 @@ void mfm_callback(void *p)
|
||||
mfm_t *mfm = (mfm_t *)p;
|
||||
mfm_drive_t *drive = &mfm->drives[mfm->drive_sel];
|
||||
off64_t addr;
|
||||
int c;
|
||||
|
||||
mfm->callback = 0;
|
||||
if (mfm->reset)
|
||||
@@ -500,8 +473,7 @@ void mfm_callback(void *p)
|
||||
break;
|
||||
}
|
||||
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
fread(mfm->buffer, 512, 1, drive->hdfile);
|
||||
hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||
mfm_irq_raise(mfm);
|
||||
@@ -517,8 +489,7 @@ void mfm_callback(void *p)
|
||||
mfm_irq_raise(mfm);
|
||||
break;
|
||||
}
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
fwrite(mfm->buffer, 512, 1, drive->hdfile);
|
||||
hdd_image_write(drive->hdc_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||
mfm_irq_raise(mfm);
|
||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||
if (mfm->secount)
|
||||
@@ -552,12 +523,7 @@ void mfm_callback(void *p)
|
||||
mfm_irq_raise(mfm);
|
||||
break;
|
||||
}
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
memset(mfm->buffer, 0, 512);
|
||||
for (c = 0; c < mfm->secount; c++)
|
||||
{
|
||||
fwrite(mfm->buffer, 512, 1, drive->hdfile);
|
||||
}
|
||||
hdd_image_zero(drive->hdc_num, addr, mfm->secount);
|
||||
mfm->status = STAT_READY | STAT_DSC;
|
||||
mfm_irq_raise(mfm);
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
@@ -624,9 +590,8 @@ void mfm_close(void *p)
|
||||
for (d = 0; d < 2; d++)
|
||||
{
|
||||
mfm_drive_t *drive = &mfm->drives[d];
|
||||
|
||||
if (drive->hdfile != NULL)
|
||||
fclose(drive->hdfile);
|
||||
|
||||
hdd_image_close(drive->hdc_num);
|
||||
}
|
||||
|
||||
free(mfm);
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include "ibm.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "dma.h"
|
||||
#include "hdd_image.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
@@ -43,7 +36,8 @@ typedef struct mfm_drive_t
|
||||
int cfg_hpc;
|
||||
int cfg_cyl;
|
||||
int current_cylinder;
|
||||
FILE *hdfile;
|
||||
int present;
|
||||
int hdc_num;
|
||||
} mfm_drive_t;
|
||||
|
||||
typedef struct xebec_t
|
||||
@@ -297,6 +291,8 @@ static void xebec_next_sector(xebec_t *xebec)
|
||||
|
||||
static void xebec_callback(void *p)
|
||||
{
|
||||
off64_t addr;
|
||||
|
||||
xebec_t *xebec = (xebec_t *)p;
|
||||
mfm_drive_t *drive;
|
||||
|
||||
@@ -310,13 +306,13 @@ static void xebec_callback(void *p)
|
||||
switch (xebec->command[0])
|
||||
{
|
||||
case CMD_TEST_DRIVE_READY:
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
xebec_error(xebec, ERR_NOT_READY);
|
||||
xebec_complete(xebec);
|
||||
break;
|
||||
|
||||
case CMD_RECALIBRATE:
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
xebec_error(xebec, ERR_NOT_READY);
|
||||
else
|
||||
{
|
||||
@@ -357,8 +353,6 @@ static void xebec_callback(void *p)
|
||||
xebec->sector_count = xebec->command[4];
|
||||
do
|
||||
{
|
||||
off64_t addr;
|
||||
|
||||
if (xebec_get_sector(xebec, &addr))
|
||||
{
|
||||
pclog("xebec_get_sector failed\n");
|
||||
@@ -384,9 +378,6 @@ static void xebec_callback(void *p)
|
||||
|
||||
case CMD_FORMAT_TRACK:
|
||||
{
|
||||
off64_t addr;
|
||||
int c;
|
||||
|
||||
xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2);
|
||||
drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder;
|
||||
xebec->head = xebec->command[1] & 0x1f;
|
||||
@@ -398,10 +389,8 @@ static void xebec_callback(void *p)
|
||||
xebec_complete(xebec);
|
||||
return;
|
||||
}
|
||||
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
for (c = 0; c < 17; c++)
|
||||
fwrite(xebec->sector_buf, 512, 1, drive->hdfile);
|
||||
|
||||
hdd_image_zero(drive->hdc_num, addr, 17);
|
||||
|
||||
xebec_complete(xebec);
|
||||
}
|
||||
@@ -420,8 +409,6 @@ static void xebec_callback(void *p)
|
||||
xebec->data_pos = 0;
|
||||
xebec->data_len = 512;
|
||||
{
|
||||
off64_t addr;
|
||||
|
||||
if (xebec_get_sector(xebec, &addr))
|
||||
{
|
||||
xebec_error(xebec, xebec->error);
|
||||
@@ -429,8 +416,7 @@ static void xebec_callback(void *p)
|
||||
return;
|
||||
}
|
||||
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
fread(xebec->sector_buf, 512, 1, drive->hdfile);
|
||||
hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf);
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
}
|
||||
if (xebec->irq_dma_mask & DMA_ENA)
|
||||
@@ -474,8 +460,6 @@ static void xebec_callback(void *p)
|
||||
|
||||
if (xebec->sector_count)
|
||||
{
|
||||
off64_t addr;
|
||||
|
||||
if (xebec_get_sector(xebec, &addr))
|
||||
{
|
||||
xebec_error(xebec, xebec->error);
|
||||
@@ -483,8 +467,7 @@ static void xebec_callback(void *p)
|
||||
return;
|
||||
}
|
||||
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
fread(xebec->sector_buf, 512, 1, drive->hdfile);
|
||||
hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf);
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
|
||||
xebec->state = STATE_SEND_DATA;
|
||||
@@ -559,8 +542,6 @@ static void xebec_callback(void *p)
|
||||
memcpy(xebec->sector_buf, xebec->data, 512);
|
||||
|
||||
{
|
||||
off64_t addr;
|
||||
|
||||
if (xebec_get_sector(xebec, &addr))
|
||||
{
|
||||
xebec_error(xebec, xebec->error);
|
||||
@@ -568,8 +549,7 @@ static void xebec_callback(void *p)
|
||||
return;
|
||||
}
|
||||
|
||||
fseeko64(drive->hdfile, addr * 512, SEEK_SET);
|
||||
fwrite(xebec->sector_buf, 512, 1, drive->hdfile);
|
||||
hdd_image_write(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf);
|
||||
}
|
||||
|
||||
update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
@@ -596,7 +576,7 @@ static void xebec_callback(void *p)
|
||||
break;
|
||||
|
||||
case CMD_SEEK:
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
xebec_error(xebec, ERR_NOT_READY);
|
||||
else
|
||||
{
|
||||
@@ -766,39 +746,21 @@ static void xebec_callback(void *p)
|
||||
static void loadhd(xebec_t *xebec, int c, int d, const wchar_t *fn)
|
||||
{
|
||||
mfm_drive_t *drive = &xebec->drives[d];
|
||||
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Try to open existing hard disk image */
|
||||
drive->hdfile = _wfopen(fn, L"rb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
drive->hdfile = _wfopen(fn, L"wb+");
|
||||
if (drive->hdfile == NULL)
|
||||
{
|
||||
pclog("Cannot create file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
pclog("Cannot open file '%s': %s",
|
||||
fn, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
ret = hdd_image_load(d);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
drive->present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
drive->spt = hdc[c].spt;
|
||||
drive->hpc = hdc[c].hpc;
|
||||
drive->tracks = hdc[c].tracks;
|
||||
drive->hdc_num = c;
|
||||
drive->present = 1;
|
||||
}
|
||||
|
||||
static struct
|
||||
@@ -822,7 +784,7 @@ static void xebec_set_switches(xebec_t *xebec)
|
||||
{
|
||||
mfm_drive_t *drive = &xebec->drives[d];
|
||||
|
||||
if (!drive->hdfile)
|
||||
if (!drive->present)
|
||||
continue;
|
||||
|
||||
for (c = 0; c < 4; c++)
|
||||
@@ -878,9 +840,8 @@ static void xebec_close(void *p)
|
||||
for (d = 0; d < 2; d++)
|
||||
{
|
||||
mfm_drive_t *drive = &xebec->drives[d];
|
||||
|
||||
if (drive->hdfile != NULL)
|
||||
fclose(drive->hdfile);
|
||||
|
||||
hdd_image_close(drive->hdc_num);
|
||||
}
|
||||
|
||||
free(xebec);
|
||||
|
||||
35
src/model.c
35
src/model.c
@@ -82,6 +82,9 @@
|
||||
#include "sound/snd_ps1.h"
|
||||
#include "sound/snd_pssj.h"
|
||||
#include "sound/snd_sn76489.h"
|
||||
#if 0
|
||||
#include "superio_detect.h"
|
||||
#endif
|
||||
#include "tandy_eeprom.h"
|
||||
#include "tandy_rom.h"
|
||||
#if 0
|
||||
@@ -120,12 +123,16 @@ extern void at_ali1429_init(void);
|
||||
extern void at_headland_init(void);
|
||||
extern void at_opti495_init(void);
|
||||
extern void at_batman_init(void);
|
||||
#if 0
|
||||
extern void at_586mc1_init(void);
|
||||
#endif
|
||||
extern void at_endeavor_init(void);
|
||||
|
||||
extern void at_dtk486_init(void);
|
||||
extern void at_r418_init(void);
|
||||
extern void at_plato_init(void);
|
||||
extern void at_mb500n_init(void);
|
||||
extern void at_president_init(void);
|
||||
extern void at_p54tp4xe_init(void);
|
||||
extern void at_ap53_init(void);
|
||||
extern void at_p55t2s_init(void);
|
||||
@@ -203,13 +210,17 @@ MODEL models[] =
|
||||
{"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL},
|
||||
{"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL},
|
||||
{"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL},
|
||||
#if 0
|
||||
{"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL},
|
||||
#endif
|
||||
{"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL},
|
||||
{"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL},
|
||||
{"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL},
|
||||
{"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL},
|
||||
{"President Award 430FX PCI", ROM_PRESIDENT, "president", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL},
|
||||
{"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL},
|
||||
{"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL},
|
||||
{"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL},
|
||||
{"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL},
|
||||
{"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL},
|
||||
{"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL},
|
||||
{"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL},
|
||||
@@ -648,7 +659,7 @@ void at_premiere_common_init(void)
|
||||
pci_slot(0xc);
|
||||
pci_slot(0xe);
|
||||
pci_slot(0x6);
|
||||
sio_init(2, 0xc, 0xe, 0x6, 0);
|
||||
sio_init(1, 0xc, 0xe, 0x6, 0);
|
||||
fdc37c665_init();
|
||||
intel_batman_init();
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
@@ -670,7 +681,7 @@ void at_586mc1_init(void)
|
||||
pci_slot(0xc);
|
||||
pci_slot(0xe);
|
||||
pci_slot(0x6);
|
||||
sio_init(2, 0xc, 0xe, 0x6, 0);
|
||||
sio_init(1, 0xc, 0xe, 0x6, 0);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
secondary_ide_check();
|
||||
}
|
||||
@@ -716,6 +727,24 @@ void at_mb500n_init(void)
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
void at_president_init(void)
|
||||
{
|
||||
at_ide_init();
|
||||
memregs_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_slot(8);
|
||||
pci_slot(9);
|
||||
pci_slot(10);
|
||||
pci_slot(11);
|
||||
i430fx_init();
|
||||
piix_init(7, 8, 9, 10, 11);
|
||||
#if 0
|
||||
superio_detect_init();
|
||||
#endif
|
||||
w83877f_init();
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
void at_p54tp4xe_init(void)
|
||||
{
|
||||
at_ide_init();
|
||||
|
||||
@@ -1796,12 +1796,12 @@ aha_disk_cmd(aha_t *dev)
|
||||
pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]);
|
||||
}
|
||||
|
||||
memset(temp_cdb, 0, shdc[hdc_id].cdb_len);
|
||||
if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) {
|
||||
memset(temp_cdb, 0, 12);
|
||||
if (req->CmdBlock.common.CdbLength <= 12) {
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
|
||||
req->CmdBlock.common.CdbLength);
|
||||
} else {
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len);
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1685,12 +1685,12 @@ BuslogicHDCommand(Buslogic_t *bl)
|
||||
pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]);
|
||||
}
|
||||
|
||||
memset(temp_cdb, 0, shdc[hdc_id].cdb_len);
|
||||
if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) {
|
||||
memset(temp_cdb, 0, 12);
|
||||
if (req->CmdBlock.common.CdbLength <= 12) {
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb,
|
||||
req->CmdBlock.common.CdbLength);
|
||||
} else {
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len);
|
||||
memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
552
src/scsi_disk.c
552
src/scsi_disk.c
@@ -6,26 +6,19 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.c 1.0.1 2017/06/03
|
||||
* Version: @(#)scsi_disk.c 1.0.2 2017/06/16
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017-2017 Miran Grca.
|
||||
*/
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "86box.h"
|
||||
#include "cdrom.h"
|
||||
#include "ibm.h"
|
||||
#include "hdd_image.h"
|
||||
#include "ide.h"
|
||||
#include "piix.h"
|
||||
#include "scsi.h"
|
||||
@@ -213,278 +206,28 @@ void scsi_disk_insert(uint8_t id)
|
||||
shdc[id].unit_attention = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0;
|
||||
}
|
||||
|
||||
static char empty_sector[512];
|
||||
static char *empty_sector_1mb;
|
||||
|
||||
void scsi_loadhd(int scsi_id, int scsi_lun, int id)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
uint64_t spt = 0, hpc = 0, tracks = 0;
|
||||
int c;
|
||||
uint64_t i = 0, s = 0, t = 0;
|
||||
wchar_t *fn = hdc[id].fn;
|
||||
int ret = 0;
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
ret = hdd_image_load(id);
|
||||
|
||||
shdc[id].base = 0;
|
||||
|
||||
if (shdf[id] != NULL)
|
||||
if (!ret)
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
}
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.')
|
||||
{
|
||||
scsi_hd_log("File name starts with .\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
scsi_hard_disks[scsi_id][scsi_lun] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
shdf[id] = _wfopen(fn, L"rb+");
|
||||
if (shdf[id] == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdc[id].wp)
|
||||
{
|
||||
scsi_hd_log("A write-protected image must exist\n");
|
||||
goto scsi_hd_load_error;
|
||||
}
|
||||
|
||||
shdf[id] = _wfopen(fn, L"wb+");
|
||||
if (shdf[id] == NULL)
|
||||
{
|
||||
scsi_hd_load_error:
|
||||
scsi_hd_log("Unable to open image\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
scsi_hard_disks[scsi_id][scsi_lun] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t));
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
shdc[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&(shdc[id].base), 1, 4, shdf[id]);
|
||||
fwrite(&full_size, 1, 4, shdf[id]);
|
||||
fwrite(§or_size, 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].spt), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, shdf[id]);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
{
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
}
|
||||
}
|
||||
else if (image_is_hdx(fn, 0))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
shdc[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, shdf[id]);
|
||||
fwrite(&full_size, 1, 8, shdf[id]);
|
||||
fwrite(§or_size, 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].spt), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
}
|
||||
shdc[id].last_sector = 0;
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
|
||||
scsi_disk_insert(id);
|
||||
|
||||
s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
|
||||
goto prepare_new_hard_disk;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
scsi_hd_log("Failed for another reason\n");
|
||||
if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
scsi_hard_disks[scsi_id][scsi_lun] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t));
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
fseeko64(shdf[id], 0x8, SEEK_SET);
|
||||
fread(&(shdc[id].base), 1, 4, shdf[id]);
|
||||
fseeko64(shdf[id], 0xC, SEEK_SET);
|
||||
full_size = 0;
|
||||
fread(&full_size, 1, 4, shdf[id]);
|
||||
fseeko64(shdf[id], 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, shdf[id]);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
scsi_hd_log("HDI: Sector size is not 512\n");
|
||||
fclose(shdf[id]);
|
||||
if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
scsi_hard_disks[scsi_id][scsi_lun] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
fread(&spt, 1, 4, shdf[id]);
|
||||
fread(&hpc, 1, 4, shdf[id]);
|
||||
fread(&tracks, 1, 4, shdf[id]);
|
||||
if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
goto scsi_hd_load_error;
|
||||
}
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
}
|
||||
else if (image_is_hdx(fn, 1))
|
||||
{
|
||||
shdc[id].base = 0x28;
|
||||
fseeko64(shdf[id], 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, shdf[id]);
|
||||
fseeko64(shdf[id], 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, shdf[id]);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
scsi_hd_log("HDX: Sector size is not 512\n");
|
||||
fclose(shdf[id]);
|
||||
if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
scsi_hard_disks[scsi_id][scsi_lun] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
return;
|
||||
}
|
||||
fread(&spt, 1, 4, shdf[id]);
|
||||
fread(&hpc, 1, 4, shdf[id]);
|
||||
fread(&tracks, 1, 4, shdf[id]);
|
||||
if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
{
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
goto scsi_hd_load_error;
|
||||
}
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
fread(&(hdc[id].at_spt), 1, 4, shdf[id]);
|
||||
fread(&(hdc[id].at_hpc), 1, 4, shdf[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
}
|
||||
shdc[id].cdb_len = 12;
|
||||
scsi_disk_insert(id);
|
||||
}
|
||||
|
||||
fseeko64(shdf[id], 0, SEEK_END);
|
||||
if (ftello64(shdf[id]) < (full_size + shdc[id].base))
|
||||
{
|
||||
s = (full_size + shdc[id].base) - ftello64(shdf[id]);
|
||||
prepare_new_hard_disk:
|
||||
s >>= 9;
|
||||
t = (s >> 11) << 11;
|
||||
s -= t;
|
||||
t >>= 11;
|
||||
|
||||
empty_sector_1mb = (char *) malloc(1048576);
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
if (s > 0)
|
||||
{
|
||||
for (i = 0; i < s; i++)
|
||||
{
|
||||
fwrite(empty_sector, 1, 512, shdf[id]);
|
||||
}
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
for (i = 0; i < t; i++)
|
||||
{
|
||||
fwrite(empty_sector_1mb, 1, 1045876, shdf[id]);
|
||||
}
|
||||
}
|
||||
|
||||
free(empty_sector_1mb);
|
||||
}
|
||||
|
||||
shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
|
||||
#if 0
|
||||
fclose(shdf[id]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void scsi_reloadhd(int id)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
uint64_t spt = 0, hpc = 0, tracks = 0;
|
||||
int c;
|
||||
uint64_t i = 0, s = 0, t = 0;
|
||||
wchar_t *fn = hdc[id].fn;
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
int ret = 0;
|
||||
|
||||
if(hdc[id].prev_fn == NULL)
|
||||
{
|
||||
@@ -496,232 +239,17 @@ void scsi_reloadhd(int id)
|
||||
memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn));
|
||||
}
|
||||
|
||||
shdc[id].base = 0;
|
||||
ret = hdd_image_load(id);
|
||||
|
||||
if (shdf[id] != NULL)
|
||||
if (ret)
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
}
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.')
|
||||
{
|
||||
scsi_hd_log("File name starts with .\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
return;
|
||||
}
|
||||
shdf[id] = _wfopen(fn, L"rb+");
|
||||
if (shdf[id] == NULL)
|
||||
{
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdc[id].wp)
|
||||
{
|
||||
scsi_hd_log("A write-protected image must exist\n");
|
||||
goto scsi_hd_reload_error;
|
||||
}
|
||||
|
||||
shdf[id] = _wfopen(fn, L"wb+");
|
||||
if (shdf[id] == NULL)
|
||||
{
|
||||
scsi_hd_reload_error:
|
||||
scsi_hd_log("Unable to open image\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t));
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
shdc[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&(shdc[id].base), 1, 4, shdf[id]);
|
||||
fwrite(&full_size, 1, 4, shdf[id]);
|
||||
fwrite(§or_size, 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].spt), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, shdf[id]);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
{
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
}
|
||||
}
|
||||
else if (image_is_hdx(fn, 0))
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
shdc[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, shdf[id]);
|
||||
fwrite(&full_size, 1, 8, shdf[id]);
|
||||
fwrite(§or_size, 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].spt), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].hpc), 1, 4, shdf[id]);
|
||||
fwrite(&(hdc[id].tracks), 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
fwrite(&zero, 1, 4, shdf[id]);
|
||||
}
|
||||
shdc[id].last_sector = 0;
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
|
||||
scsi_disk_insert(id);
|
||||
|
||||
s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
|
||||
goto reload_prepare_new_hard_disk;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed for another reason */
|
||||
scsi_hd_log("Failed for another reason\n");
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t));
|
||||
if (image_is_hdi(fn))
|
||||
{
|
||||
fseeko64(shdf[id], 0x8, SEEK_SET);
|
||||
fread(&(shdc[id].base), 1, 4, shdf[id]);
|
||||
fseeko64(shdf[id], 0xC, SEEK_SET);
|
||||
full_size = 0;
|
||||
fread(&full_size, 1, 4, shdf[id]);
|
||||
fseeko64(shdf[id], 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, shdf[id]);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
scsi_hd_log("HDI: Sector size is not 512\n");
|
||||
fclose(shdf[id]);
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
return;
|
||||
}
|
||||
fread(&spt, 1, 4, shdf[id]);
|
||||
fread(&hpc, 1, 4, shdf[id]);
|
||||
fread(&tracks, 1, 4, shdf[id]);
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
goto scsi_hd_reload_error;
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
}
|
||||
else if (image_is_hdx(fn, 1))
|
||||
{
|
||||
shdc[id].base = 0x28;
|
||||
fseeko64(shdf[id], 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, shdf[id]);
|
||||
fseeko64(shdf[id], 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, shdf[id]);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
/* Sector size is not 512 */
|
||||
scsi_hd_log("HDX: Sector size is not 512\n");
|
||||
fclose(shdf[id]);
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
shdc[id].cdb_len = 12;
|
||||
return;
|
||||
}
|
||||
fread(&spt, 1, 4, shdf[id]);
|
||||
fread(&hpc, 1, 4, shdf[id]);
|
||||
fread(&tracks, 1, 4, shdf[id]);
|
||||
if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks))
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
goto scsi_hd_reload_error;
|
||||
}
|
||||
hdc[id].spt = spt;
|
||||
hdc[id].hpc = hpc;
|
||||
hdc[id].tracks = tracks;
|
||||
fread(&(hdc[id].at_spt), 1, 4, shdf[id]);
|
||||
fread(&(hdc[id].at_hpc), 1, 4, shdf[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512;
|
||||
}
|
||||
shdc[id].cdb_len = 12;
|
||||
scsi_disk_insert(id);
|
||||
}
|
||||
|
||||
fseeko64(shdf[id], 0, SEEK_END);
|
||||
if (ftello64(shdf[id]) < (full_size + shdc[id].base))
|
||||
{
|
||||
s = (full_size + shdc[id].base) - ftello64(shdf[id]);
|
||||
reload_prepare_new_hard_disk:
|
||||
s >>= 9;
|
||||
t = (s >> 11) << 11;
|
||||
s -= t;
|
||||
t >>= 11;
|
||||
|
||||
empty_sector_1mb = (char *) malloc(1048576);
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
if (s > 0)
|
||||
{
|
||||
for (i = 0; i < s; i++)
|
||||
{
|
||||
fwrite(empty_sector, 1, 512, shdf[id]);
|
||||
}
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
for (i = 0; i < t; i++)
|
||||
{
|
||||
fwrite(empty_sector_1mb, 1, 1045876, shdf[id]);
|
||||
}
|
||||
}
|
||||
|
||||
free(empty_sector_1mb);
|
||||
}
|
||||
|
||||
shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
|
||||
#if 0
|
||||
fclose(shdf[id]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void scsi_unloadhd(int scsi_id, int scsi_lun, int id)
|
||||
{
|
||||
if (wcslen(hdc[id].fn) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (shdf[id] != NULL)
|
||||
{
|
||||
fclose(shdf[id]);
|
||||
shdf[id] = NULL;
|
||||
}
|
||||
|
||||
shdc[id].last_sector = -1;
|
||||
|
||||
memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn));
|
||||
wcscpy(hdc[id].prev_fn, hdc[id].fn);
|
||||
|
||||
memset(hdc[id].fn, 0, sizeof(hdc[id].fn));
|
||||
|
||||
shdc[id].cdb_len = 12;
|
||||
|
||||
fclose(shdf[id]);
|
||||
hdd_image_unload(id, 1);
|
||||
}
|
||||
|
||||
void build_scsi_hd_map()
|
||||
@@ -746,10 +274,6 @@ void build_scsi_hd_map()
|
||||
{
|
||||
scsi_loadhd(i, j, scsi_hard_disks[i][j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
shdc[scsi_hard_disks[i][j]].cdb_len = 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,7 +283,7 @@ int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *l
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
size = shdc[id].last_sector;
|
||||
size = hdd_image_get_last_sector(id);
|
||||
memset(buffer, 0, 8);
|
||||
buffer[0] = (size >> 24) & 0xff;
|
||||
buffer[1] = (size >> 16) & 0xff;
|
||||
@@ -771,16 +295,6 @@ int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *l
|
||||
return 1;
|
||||
}
|
||||
|
||||
void scsi_hd_set_cdb_len(int id, int cdb_len)
|
||||
{
|
||||
shdc[id].cdb_len = cdb_len;
|
||||
}
|
||||
|
||||
void scsi_hd_reset_cdb_len(int id)
|
||||
{
|
||||
shdc[id].cdb_len = 12;
|
||||
}
|
||||
|
||||
void scsi_hd_update_request_length(uint8_t id, int len, int block_len)
|
||||
{
|
||||
/* For media access commands, make sure the requested DRQ length matches the block length. */
|
||||
@@ -1080,7 +594,7 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb)
|
||||
static void scsi_hd_seek(uint8_t id, uint32_t pos)
|
||||
{
|
||||
/* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */
|
||||
shdc[id].seek_pos = pos;
|
||||
hdd_image_seek(id, pos);
|
||||
}
|
||||
|
||||
static void scsi_hd_rezero(uint8_t id)
|
||||
@@ -1179,14 +693,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
unsigned size_idx;
|
||||
unsigned preamble_len;
|
||||
uint32_t alloc_length;
|
||||
uint64_t pos64;
|
||||
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
|
||||
char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
|
||||
char *tempbuffer;
|
||||
uint8_t *tempbuffer;
|
||||
uint32_t last_sector = 0;
|
||||
|
||||
#if 0
|
||||
int CdbLength;
|
||||
#endif
|
||||
last_sector = hdd_image_get_last_sector(id);
|
||||
|
||||
shdc[id].status &= ~ERR_STAT;
|
||||
|
||||
shdc[id].packet_len = 0;
|
||||
@@ -1210,7 +726,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
|
||||
shdc[id].data_pos = 0;
|
||||
|
||||
memcpy(shdc[id].current_cdb, cdb, shdc[id].cdb_len);
|
||||
memcpy(shdc[id].current_cdb, cdb, 12);
|
||||
|
||||
if (cdb[0] != 0)
|
||||
{
|
||||
@@ -1218,7 +734,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
scsi_hd_log("SCSI HD %i: Request length: %04X\n", id, shdc[id].request_length);
|
||||
|
||||
#if 0
|
||||
for (CdbLength = 1; CdbLength < shdc[id].cdb_len; CdbLength++)
|
||||
for (CdbLength = 1; CdbLength < 12; CdbLength++)
|
||||
{
|
||||
scsi_hd_log("SCSI HD %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]);
|
||||
}
|
||||
@@ -1284,7 +800,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector))
|
||||
if ((shdc[id].sector_pos > last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector))
|
||||
{
|
||||
scsi_hd_lba_out_of_range(id);
|
||||
return;
|
||||
@@ -1301,27 +817,18 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
max_len = shdc[id].sector_len;
|
||||
shdc[id].requested_blocks = max_len;
|
||||
|
||||
pos64 = (uint64_t) shdc[id].sector_pos;
|
||||
|
||||
alloc_length = shdc[id].packet_len = max_len << 9;
|
||||
|
||||
if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0))
|
||||
{
|
||||
#if 0
|
||||
shdf[id] = _wfopen(hdc[id].fn, L"rb+");
|
||||
#endif
|
||||
fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET);
|
||||
if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength)
|
||||
{
|
||||
fread(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]);
|
||||
hdd_image_read(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb);
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(hdbufferb, 1, alloc_length, shdf[id]);
|
||||
hdd_image_read(id, shdc[id].sector_pos, max_len, hdbufferb);
|
||||
}
|
||||
#if 0
|
||||
fclose(shdf[id]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (shdc[id].requested_blocks > 1)
|
||||
@@ -1369,7 +876,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector))
|
||||
if ((shdc[id].sector_pos > last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector))
|
||||
{
|
||||
scsi_hd_lba_out_of_range(id);
|
||||
return;
|
||||
@@ -1386,27 +893,18 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
max_len = shdc[id].sector_len;
|
||||
shdc[id].requested_blocks = max_len;
|
||||
|
||||
pos64 = (uint64_t) shdc[id].sector_pos;
|
||||
|
||||
alloc_length = shdc[id].packet_len = max_len << 9;
|
||||
|
||||
if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0))
|
||||
{
|
||||
#if 0
|
||||
shdf[id] = _wfopen(hdc[id].fn, L"rb+");
|
||||
#endif
|
||||
fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET);
|
||||
if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength)
|
||||
{
|
||||
fwrite(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]);
|
||||
hdd_image_write(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(hdbufferb, 1, alloc_length, shdf[id]);
|
||||
hdd_image_write(id, shdc[id].sector_pos, max_len, hdbufferb);
|
||||
}
|
||||
#if 0
|
||||
fclose(shdf[id]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (shdc[id].requested_blocks > 1)
|
||||
|
||||
@@ -36,14 +36,10 @@ typedef struct {
|
||||
uint8_t error;
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t last_sector;
|
||||
uint32_t seek_pos;
|
||||
int data_pos;
|
||||
int old_len;
|
||||
int cdb_len_setting;
|
||||
int cdb_len;
|
||||
int request_pos;
|
||||
uint64_t base;
|
||||
uint8_t hd_cdb[16];
|
||||
} scsi_hard_disk_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
52
src/superio_detect.c
Normal file
52
src/superio_detect.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
SMSC SMC FDC37C665 Super I/O Chip
|
||||
Used by Batman's Revenge
|
||||
*/
|
||||
|
||||
#include "ibm.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "disc.h"
|
||||
#include "fdd.h"
|
||||
#include "fdc.h"
|
||||
#include "superio_detect.h"
|
||||
|
||||
static int fdc37c665_locked;
|
||||
static int fdc37c665_curreg = 0;
|
||||
static uint8_t detect_regs[2];
|
||||
static uint8_t tries;
|
||||
|
||||
void superio_detect_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
uint8_t valxor = 0;
|
||||
int temp;
|
||||
pclog("superio_detect_write : port=%04x = %02X\n", port, val);
|
||||
|
||||
detect_regs[port & 1] = val;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t superio_detect_read(uint16_t port, void *priv)
|
||||
{
|
||||
pclog("superio_detect_read : port=%04x = %02X\n", port, detect_regs[port & 1]);
|
||||
|
||||
return detect_regs[port & 1];
|
||||
}
|
||||
|
||||
void superio_detect_init()
|
||||
{
|
||||
fdc_remove();
|
||||
fdc_add_for_superio();
|
||||
|
||||
io_sethandler(0x24, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x26, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x2e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x44, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x46, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x4e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x108, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x250, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x370, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x3f0, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/superio_detect.h
Normal file
1
src/superio_detect.h
Normal file
@@ -0,0 +1 @@
|
||||
extern void superio_detect_init();
|
||||
@@ -216,6 +216,7 @@ static void w83877f_remap()
|
||||
winbond_port = (HEFRAS ? 0x3f0 : 0x250);
|
||||
winbond_key_times = HEFRAS + 1;
|
||||
winbond_key = (HEFRAS ? 0x86 : 0x88) | HEFERE;
|
||||
pclog("W83877F: Remapped to port %04X, key %02X\n", winbond_port, winbond_key);
|
||||
}
|
||||
|
||||
static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port)
|
||||
@@ -282,6 +283,24 @@ static uint16_t make_port(uint8_t reg)
|
||||
return p;
|
||||
}
|
||||
|
||||
void w83877f_serial_handler(int id)
|
||||
{
|
||||
int reg_mask = (id - 1) ? 0x10 : 0x20;
|
||||
int reg_id = (id - 1) ? 0x24 : 0x25;
|
||||
int irq_mask = (id - 1) ? 0xF : 0xF0;
|
||||
|
||||
/* pclog("Registers (%i): %02X %02X %02X\n", id, w83877f_regs[4], w83877f_regs[reg_id], w83877f_regs[0x28]); */
|
||||
|
||||
if ((w83877f_regs[4] & reg_mask) || !(w83877f_regs[reg_id] & 0xc0))
|
||||
{
|
||||
serial_remove(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
serial_setup(id, make_port(reg_id), w83877f_regs[0x28] & irq_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void w83877f_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
@@ -353,16 +372,11 @@ process_value:
|
||||
case 4:
|
||||
if (valxor & 0x10)
|
||||
{
|
||||
serial_remove(2);
|
||||
if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF);
|
||||
w83877f_serial_handler(2);
|
||||
}
|
||||
if (valxor & 0x20)
|
||||
{
|
||||
serial_remove(1);
|
||||
if (!(w83877f_regs[4] & 0x20))
|
||||
{
|
||||
serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
|
||||
}
|
||||
w83877f_serial_handler(1);
|
||||
}
|
||||
if (valxor & 0x80)
|
||||
{
|
||||
@@ -418,16 +432,13 @@ process_value:
|
||||
case 0x24:
|
||||
if (valxor & 0xfe)
|
||||
{
|
||||
if (!(w83877f_regs[4] & 0x20))
|
||||
{
|
||||
serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8);
|
||||
}
|
||||
w83877f_serial_handler(1);
|
||||
}
|
||||
break;
|
||||
case 0x25:
|
||||
if (valxor & 0xfe)
|
||||
{
|
||||
if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF);
|
||||
w83877f_serial_handler(2);
|
||||
}
|
||||
break;
|
||||
case 0x28:
|
||||
@@ -486,7 +497,7 @@ void w83877f_reset(void)
|
||||
w83877f_regs[0xA] = 0x1F;
|
||||
w83877f_regs[0xC] = 0x28;
|
||||
w83877f_regs[0xD] = 0xA3;
|
||||
w83877f_regs[0x16] = 5;
|
||||
w83877f_regs[0x16] = (romset == ROM_PRESIDENT) ? 4 : 5;
|
||||
w83877f_regs[0x1E] = 0x81;
|
||||
w83877f_regs[0x20] = (0x3f0 >> 2) & 0xfc;
|
||||
w83877f_regs[0x21] = (0x1f0 >> 2) & 0xfc;
|
||||
|
||||
Reference in New Issue
Block a user