diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a2b5e746d..900e874a9 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -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, # Fred N. van Kempen, @@ -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 diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 00a80c429..56623d054 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -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() diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 4c3cc152d..4f31c8836 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -1,17 +1,9 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include +#include #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); diff --git a/src/hdd_image.c b/src/hdd_image.c new file mode 100644 index 000000000..ecfcbeb3a --- /dev/null +++ b/src/hdd_image.c @@ -0,0 +1,441 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#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; + } +} diff --git a/src/hdd_image.h b/src/hdd_image.h new file mode 100644 index 000000000..e972894fe --- /dev/null +++ b/src/hdd_image.h @@ -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); diff --git a/src/ibm.h b/src/ibm.h index a95d3635e..f75e5924f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -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 }; diff --git a/src/ide.c b/src/ide.c index d92ce13be..4a11ed3a7 100644 --- a/src/ide.c +++ b/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, * Miran Grca, @@ -18,23 +18,14 @@ * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 TheCollector1995. */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include #include -#include -#include -#include - #include #include #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;csecount;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; diff --git a/src/ide.h b/src/ide.h index 003cbbb07..57057af13 100644 --- a/src/ide.h +++ b/src/ide.h @@ -38,7 +38,6 @@ typedef struct { int packetstatus; uint8_t asc; int reset; - FILE *hdfile; uint16_t buffer[65536]; int irqstat; int service; diff --git a/src/mem.c b/src/mem.c index 971d4ebb6..c401f0841 100644 --- a/src/mem.c +++ b/src/mem.c @@ -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; diff --git a/src/mfm_at.c b/src/mfm_at.c index b62fbbef0..eca973a85 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -1,16 +1,7 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include #include -#include -#include -#include - -#include -#include #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); diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index b318c4de3..eb56d2ec0 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -1,17 +1,10 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include - +#include #include #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); diff --git a/src/model.c b/src/model.c index a1cc25433..fdae935df 100644 --- a/src/model.c +++ b/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(); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index dfb851d7f..a91abdf87 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -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); } /* diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 1b4c8794d..f9a215bee 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -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); } /* diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 69726cf0b..340ffd6b3 100644 --- a/src/scsi_disk.c +++ b/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, * Copyright 2017-2017 Miran Grca. */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include +#include #include -#include +#include #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) diff --git a/src/scsi_disk.h b/src/scsi_disk.h index 95fdd9316..db3ea9848 100644 --- a/src/scsi_disk.h +++ b/src/scsi_disk.h @@ -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) diff --git a/src/superio_detect.c b/src/superio_detect.c new file mode 100644 index 000000000..dbedca3cd --- /dev/null +++ b/src/superio_detect.c @@ -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); +} diff --git a/src/superio_detect.h b/src/superio_detect.h new file mode 100644 index 000000000..542fafac5 --- /dev/null +++ b/src/superio_detect.h @@ -0,0 +1 @@ +extern void superio_detect_init(); diff --git a/src/w83877f.c b/src/w83877f.c index 6a6dd0552..f9fc3c6ec 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -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;