From 6484baaf9f49b54e56da429c01d8c45d242c5dd2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 2 Jul 2017 18:10:36 +0100 Subject: [PATCH] Abstracted hard disc image handling to separate file. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/hdd_esdi.c | 101 +++++++---------------------- src/hdd_file.c | 85 ++++++++++++++++++++++++ src/hdd_file.h | 14 ++++ src/ide.c | 103 +++++++++++++++++++---------- src/mfm_at.c | 89 +++++--------------------- src/mfm_xebec.c | 121 ++++++++++------------------------- 15 files changed, 251 insertions(+), 280 deletions(-) create mode 100644 src/hdd_file.c create mode 100644 src/hdd_file.h diff --git a/src/Makefile.am b/src/Makefile.am index 8965c21..b8ae928 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c sis496.c sound.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index b8dc43f..ea65156 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -8,7 +8,7 @@ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o alle allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index d828df9..2735900 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(sh OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 3e1f78d..7715e58 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -7,7 +7,7 @@ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o alle allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index e331164..15c2f3e 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-con OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index cbc49d7..7e1f51a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 8c2e2bf..741ad5f 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 67df2c0..812b4ce 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index bf8a60f..953f665 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64= OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 2aaa644..6226425 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -12,6 +12,7 @@ #include "device.h" #include "dma.h" +#include "hdd_file.h" #include "io.h" #include "mca.h" #include "mem.h" @@ -27,14 +28,6 @@ extern char ide_fn[4][512]; -typedef struct esdi_drive_t -{ - int spt, hpc; - int tracks; - int sectors; - FILE *hdfile; -} esdi_drive_t; - typedef struct esdi_t { rom_t bios_rom; @@ -74,7 +67,7 @@ typedef struct esdi_t int req_in_progress; } cmds[3]; - esdi_drive_t drives[2]; + hdd_file_t hdd_file[2]; uint8_t pos_regs[8]; } esdi_t; @@ -379,15 +372,15 @@ static void device_not_present(esdi_t *esdi) return; \ } \ if (esdi->cmd_dev == ATTN_DEVICE_0) \ - drive = &esdi->drives[0]; \ + hdd_file = &esdi->hdd_file[0]; \ else \ - drive = &esdi->drives[1]; \ + hdd_file = &esdi->hdd_file[1]; \ } while (0) static void esdi_callback(void *p) { esdi_t *esdi = (esdi_t *)p; - esdi_drive_t *drive; + hdd_file_t *hdd_file; esdi->callback = 0; @@ -406,7 +399,7 @@ static void esdi_callback(void *p) case CMD_READ: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -441,11 +434,9 @@ static void esdi_callback(void *p) { if (!esdi->data_pos) { - if (esdi->rba >= drive->sectors) + if (esdi->rba >= hdd_file->sectors) fatal("Read past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fread(esdi->data, 512, 1, drive->hdfile); - readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); + hdd_read_sectors(hdd_file, esdi->rba, 1, esdi->data); } // pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); while (esdi->data_pos < 256) @@ -486,7 +477,7 @@ static void esdi_callback(void *p) case CMD_WRITE_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -534,10 +525,9 @@ static void esdi_callback(void *p) esdi->data[esdi->data_pos++] = val & 0xffff; } - if (esdi->rba >= drive->sectors) + if (esdi->rba >= hdd_file->sectors) fatal("Write past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fwrite(esdi->data, 512, 1, drive->hdfile); + hdd_write_sectors(hdd_file, esdi->rba, 1, esdi->data); esdi->rba++; esdi->sector_pos++; readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); @@ -563,7 +553,7 @@ static void esdi_callback(void *p) case CMD_READ_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -578,7 +568,7 @@ static void esdi_callback(void *p) case CMD_SEEK: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -593,7 +583,7 @@ static void esdi_callback(void *p) case CMD_GET_DEV_CONFIG: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -607,10 +597,10 @@ static void esdi_callback(void *p) esdi->status_len = 6; esdi->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; esdi->status_data[1] = 0x10; /*Zero defect*/ - esdi->status_data[2] = drive->sectors & 0xffff; - esdi->status_data[3] = drive->sectors >> 16; - esdi->status_data[4] = drive->tracks; - esdi->status_data[5] = drive->hpc | (drive->spt << 16); + esdi->status_data[2] = hdd_file->sectors & 0xffff; + esdi->status_data[3] = hdd_file->sectors >> 16; + esdi->status_data[4] = hdd_file->tracks; + esdi->status_data[5] = hdd_file->hpc | (hdd_file->spt << 16); /* pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", drive->sectors, esdi->status_data[0], esdi->status_data[1], @@ -827,45 +817,6 @@ static void esdi_mca_write(int port, uint8_t val, void *p) } } -static void loadhd(esdi_t *esdi, int d, const char *fn) -{ - esdi_drive_t *drive = &esdi->drives[d]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "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 = fopen64(fn, "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; - } - } - } - - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; - drive->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; -} - static void *esdi_init() { esdi_t *esdi = malloc(sizeof(esdi_t)); @@ -874,8 +825,8 @@ static void *esdi_init() rom_init_interleaved(&esdi->bios_rom, "roms/90x8970.bin", "roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&esdi->bios_rom.mapping); - loadhd(esdi, 0, ide_fn[0]); - loadhd(esdi, 1, ide_fn[1]); + hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); + hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]); timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); @@ -894,16 +845,10 @@ static void *esdi_init() static void esdi_close(void *p) { esdi_t *esdi = (esdi_t *)p; - int d; - - for (d = 0; d < 2; d++) - { - esdi_drive_t *drive = &esdi->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); - } + hdd_close(&esdi->hdd_file[0]); + hdd_close(&esdi->hdd_file[1]); + free(esdi); } diff --git a/src/hdd_file.c b/src/hdd_file.c new file mode 100644 index 0000000..01e5007 --- /dev/null +++ b/src/hdd_file.c @@ -0,0 +1,85 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include + +#include "ibm.h" +#include "hdd_file.h" + +void hdd_load(hdd_file_t *hdd, int d, const char *fn) +{ + if (hdd->f == NULL) + { + /* Try to open existing hard disk image */ + hdd->f = fopen64(fn, "rb+"); + if (hdd->f == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + hdd->f = fopen64(fn, "wb+"); + if (hdd->f == 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; + } + } + } + + hdd->spt = hdc[d].spt; + hdd->hpc = hdc[d].hpc; + hdd->tracks = hdc[d].tracks; + hdd->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; +} + +void hdd_close(hdd_file_t *hdd) +{ + if (hdd->f) + { + fclose(hdd->f); + hdd->f = NULL; + } +} + +void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +{ + off64_t addr; + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + fread(buffer, nr_sectors*512, 1, hdd->f); +} + +void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +{ + off64_t addr; + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + fwrite(buffer, nr_sectors*512, 1, hdd->f); +} + +void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) +{ + off64_t addr; + int c; + uint8_t zero_buffer[512]; + + memset(zero_buffer, 0, 512); + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + for (c = 0; c < nr_sectors; c++) + fwrite(zero_buffer, 512, 1, hdd->f); +} diff --git a/src/hdd_file.h b/src/hdd_file.h new file mode 100644 index 0000000..83ef438 --- /dev/null +++ b/src/hdd_file.h @@ -0,0 +1,14 @@ +typedef struct hdd_file_t +{ + FILE *f; + int spt; + int hpc; + int tracks; + int sectors; +} hdd_file_t; + +void hdd_load(hdd_file_t *hdd, int d, const char *fn); +void hdd_close(hdd_file_t *hdd); +void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors); diff --git a/src/ide.c b/src/ide.c index 9c7b150..6d5d4e3 100644 --- a/src/ide.c +++ b/src/ide.c @@ -23,6 +23,7 @@ #include "io.h" #include "pic.h" #include "timer.h" + #include "hdd_file.h" #endif #include "ide.h" @@ -247,13 +248,10 @@ typedef struct IDE uint8_t fdisk; int pos; int packlen; - int spt,hpc; - int tracks; int packetstatus; int cdpos,cdlen; uint8_t asc; int reset; - FILE *hdfile; uint16_t buffer[65536]; int irqstat; int service; @@ -264,6 +262,13 @@ typedef struct IDE uint8_t sector_buffer[256*512]; int do_initial_read; int sector_pos; +#ifdef RPCEMU_IDE + FILE *hdfile; + int spt,hpc; + int tracks; +#else + hdd_file_t hdd_file; +#endif } IDE; IDE ide_drives[4]; @@ -561,9 +566,13 @@ static off64_t ide_get_sector(IDE *ide) } else { +#ifdef RPCEMU_IDE int heads = ide->hpc; int sectors = ide->spt; - +#else + int heads = ide->hdd_file.hpc; + int sectors = ide->hdd_file.spt; +#endif return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (ide->sector - 1) + ide->skip512; } @@ -581,10 +590,18 @@ static void ide_next_sector(IDE *ide) else { ide->sector++; +#ifdef RPCEMU_IDE if (ide->sector == (ide->spt + 1)) { +#else + if (ide->sector == (ide->hdd_file.spt + 1)) { +#endif ide->sector = 1; ide->head++; +#ifdef RPCEMU_IDE if (ide->head == ide->hpc) { +#else + if (ide->head == ide->hdd_file.hpc) { +#endif ide->head = 0; ide->cylinder++; } @@ -649,35 +666,12 @@ static void loadhd(IDE *ide, int d, const char *fn) #else static void loadhd(IDE *ide, int d, const char *fn) { - if (ide->hdfile == NULL) { - /* Try to open existing hard disk image */ - ide->hdfile = fopen64(fn, "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 = fopen64(fn, "wb+"); - if (ide->hdfile == NULL) { - ide->type = IDE_NONE; -/* fatal("Cannot create file '%s': %s", - fn, strerror(errno));*/ - return; - } - } else { - /* Failed for another reason */ - ide->type = IDE_NONE; -/* fatal("Cannot open file '%s': %s", - fn, strerror(errno));*/ - return; - } - } - } - - ide->spt = hdc[d].spt; - ide->hpc = hdc[d].hpc; - ide->tracks = hdc[d].tracks; - ide->type = IDE_HDD; + hdd_load(&ide->hdd_file, d, fn); + + if (ide->hdd_file.f) + ide->type = IDE_HDD; + else + ide->type = IDE_NONE; } #endif @@ -697,10 +691,14 @@ void resetide(void) /* Close hard disk image files (if previously open) */ for (d = 0; d < 4; d++) { ide_drives[d].type = IDE_NONE; +#ifdef RPCEMU_IDE if (ide_drives[d].hdfile != NULL) { fclose(ide_drives[d].hdfile); ide_drives[d].hdfile = NULL; } +#else + hdd_close(&ide_drives[d].hdd_file); +#endif ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = (d & 2) ? 1 : 0; @@ -1295,8 +1293,10 @@ void callbackide(int ide_board) { IDE *ide = &ide_drives[cur_ide[ide_board]]; IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; +#if RPCEMU_IDE off64_t addr; int c; +#endif ext_ide = ide; // return; if (ide->command==0x30) times30++; @@ -1373,12 +1373,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1405,12 +1409,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } ide->pos=0; @@ -1450,12 +1458,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1479,10 +1491,14 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; // pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide_irq_raise(ide); ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) @@ -1510,9 +1526,13 @@ void callbackide(int ide_board) else { /*DMA successful*/ +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1538,10 +1558,14 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; // pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->secount == 1) { @@ -1580,6 +1604,7 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; // pclog("Format cyl %i head %i offset %08X %08X %08X secount %i\n",ide.cylinder,ide.head,addr,addr>>32,addr,ide.secount); fseeko64(ide->hdfile, addr, SEEK_SET); @@ -1588,6 +1613,9 @@ void callbackide(int ide_board) { fwrite(ide->buffer, 512, 1, ide->hdfile); } +#else + hdd_format_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount); +#endif ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); #ifndef RPCEMU_IDE @@ -1616,8 +1644,13 @@ void callbackide(int ide_board) #endif goto abort_cmd; } - ide->spt=ide->secount; - ide->hpc=ide->head+1; +#if RPCEMU_IDE + ide->spt = ide->secount; + ide->hpc = ide->head+1; +#else + ide->hdd_file.spt = ide->secount; + ide->hdd_file.hpc = ide->head+1; +#endif ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE // pclog("SPECIFY - %i sectors per track, %i heads per cylinder %i %i\n",ide->spt,ide->hpc,cur_ide[ide_board],ide_board); diff --git a/src/mfm_at.c b/src/mfm_at.c index 81d0bd6..c3c7346 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -11,6 +11,7 @@ #include "ibm.h" #include "device.h" +#include "hdd_file.h" #include "io.h" #include "pic.h" #include "timer.h" @@ -49,12 +50,10 @@ extern char ide_fn[4][512]; typedef struct mfm_drive_t { - int spt, hpc; - int tracks; int cfg_spt; int cfg_hpc; int current_cylinder; - FILE *hdfile; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct mfm_t @@ -123,12 +122,12 @@ static int mfm_get_sector(mfm_t *mfm, off64_t *addr) pclog("mfm_get_sector: past end of configured sectors\n"); return 1; } - if (mfm->head > drive->hpc) + if (mfm->head > drive->hdd_file.hpc) { pclog("mfm_get_sector: past end of heads\n"); return 1; } - if (mfm->sector >= drive->spt+1) + if (mfm->sector >= drive->hdd_file.spt+1) { pclog("mfm_get_sector: past end of sectors\n"); return 1; @@ -156,52 +155,12 @@ static void mfm_next_sector(mfm_t *mfm) { mfm->head = 0; mfm->cylinder++; - if (drive->current_cylinder < drive->tracks) + if (drive->current_cylinder < drive->hdd_file.tracks) drive->current_cylinder++; } } } -static void loadhd(mfm_t *mfm, int d, const char *fn) -{ - mfm_drive_t *drive = &mfm->drives[d]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "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 = fopen64(fn, "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; - } - } - } - - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; -} - - - void mfm_write(uint16_t port, uint8_t val, void *p) { mfm_t *mfm = (mfm_t *)p; @@ -236,14 +195,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) + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) mfm->status = 0; else mfm->status = STAT_READY | STAT_DSC; return; case 0x1F7: /* Command register */ - if (mfm->drives[mfm->drive_sel].hdfile == NULL) + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) fatal("Command on non-present drive\n"); mfm_irq_lower(mfm); @@ -458,10 +417,10 @@ static void do_seek(mfm_t *mfm) { mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - if (mfm->cylinder < drive->tracks) + if (mfm->cylinder < drive->hdd_file.tracks) drive->current_cylinder = mfm->cylinder; else - drive->current_cylinder = drive->tracks-1; + drive->current_cylinder = drive->hdd_file.tracks-1; } void mfm_callback(void *p) @@ -469,7 +428,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; // pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); mfm->callback = 0; @@ -510,8 +468,7 @@ void mfm_callback(void *p) } // pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(mfm->buffer, 512, 1, drive->hdfile); + hdd_read_sectors(&drive->hdd_file, addr, 1, mfm->buffer); mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; // pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); @@ -529,8 +486,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_write_sectors(&drive->hdd_file, addr, 1, mfm->buffer); mfm_irq_raise(mfm); mfm->secount = (mfm->secount - 1) & 0xff; if (mfm->secount) @@ -562,12 +518,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_format_sectors(&drive->hdd_file, addr, mfm->secount); mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); readflash_set(READFLASH_HDC, mfm->drive_sel); @@ -601,8 +552,8 @@ void *mfm_init() mfm_t *mfm = malloc(sizeof(mfm_t)); memset(mfm, 0, sizeof(mfm_t)); - loadhd(mfm, 0, ide_fn[0]); - loadhd(mfm, 1, ide_fn[1]); + hdd_load(&mfm->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&mfm->drives[1].hdd_file, 1, ide_fn[1]); mfm->status = STAT_READY | STAT_DSC; mfm->error = 1; /*No errors*/ @@ -619,15 +570,9 @@ void *mfm_init() void mfm_close(void *p) { mfm_t *mfm = (mfm_t *)p; - int d; - - for (d = 0; d < 2; d++) - { - mfm_drive_t *drive = &mfm->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); - } + + hdd_close(&mfm->drives[0].hdd_file); + hdd_close(&mfm->drives[1].hdd_file); free(mfm); } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index bf583a9..9cfdf23 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -12,6 +12,7 @@ #include "device.h" #include "dma.h" +#include "hdd_file.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -39,13 +40,11 @@ enum typedef struct mfm_drive_t { - int spt, hpc; - int tracks; int cfg_spt; int cfg_hpc; int cfg_cyl; int current_cylinder; - FILE *hdfile; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct xebec_t @@ -271,7 +270,7 @@ static int xebec_get_sector(xebec_t *xebec, off64_t *addr) xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; return 1; } - if (xebec->head > drive->hpc) + if (xebec->head > drive->hdd_file.hpc) { pclog("mfm_get_sector: past end of heads\n"); xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; @@ -325,13 +324,13 @@ static void xebec_callback(void *p) switch (xebec->command[0]) { case CMD_TEST_DRIVE_READY: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); xebec_complete(xebec); break; case CMD_RECALIBRATE: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); else { @@ -402,7 +401,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; @@ -417,10 +415,8 @@ static void xebec_callback(void *p) return; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - for (c = 0; c < 17; c++) - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); - + hdd_format_sectors(&drive->hdd_file, addr, 17); + xebec_complete(xebec); } break; @@ -448,8 +444,7 @@ static void xebec_callback(void *p) } // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); readflash_set(READFLASH_HDC, xebec->drive_sel); } if (xebec->irq_dma_mask & DMA_ENA) @@ -503,9 +498,8 @@ static void xebec_callback(void *p) } // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); readflash_set(READFLASH_HDC, xebec->drive_sel); xebec->state = STATE_SEND_DATA; @@ -587,9 +581,8 @@ static void xebec_callback(void *p) } // pclog("xebec Write %i,%i,%i %i\n", xebec->cylinder, xebec->head, xebec->sector, xebec->drive_sel); - - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + + hdd_write_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); } readflash_set(READFLASH_HDC, xebec->drive_sel); @@ -616,7 +609,7 @@ static void xebec_callback(void *p) break; case CMD_SEEK: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); else { @@ -723,10 +716,10 @@ static void xebec_callback(void *p) xebec->data_len = 4; xebec->status = STAT_BSY | STAT_IO | STAT_REQ; memset(xebec->data, 0, 4); - xebec->data[0] = drive->tracks & 0xff; - xebec->data[1] = 17 | ((drive->tracks >> 2) & 0xc0); - xebec->data[2] = drive->hpc-1; - pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->tracks); + xebec->data[0] = drive->hdd_file.tracks & 0xff; + xebec->data[1] = 17 | ((drive->hdd_file.tracks >> 2) & 0xc0); + xebec->data[2] = drive->hdd_file.hpc-1; + pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->hdd_file.tracks); break; case STATE_SENT_DATA: @@ -747,9 +740,9 @@ static void xebec_callback(void *p) xebec->data_len = 16; xebec->status = STAT_BSY | STAT_IO | STAT_REQ; memset(xebec->data, 0, 16); - xebec->data[0x4] = drive->tracks & 0xff; - xebec->data[0x5] = (drive->tracks >> 8) & 0xff; - xebec->data[0xa] = drive->hpc; + xebec->data[0x4] = drive->hdd_file.tracks & 0xff; + xebec->data[0x5] = (drive->hdd_file.tracks >> 8) & 0xff; + xebec->data[0xa] = drive->hdd_file.hpc; break; case STATE_SENT_DATA: @@ -783,44 +776,6 @@ static void xebec_callback(void *p) } } -static void loadhd(xebec_t *xebec, int d, const char *fn) -{ - mfm_drive_t *drive = &xebec->drives[d]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "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 = fopen64(fn, "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; - } - } - } - - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; -} - static struct { int tracks, hpc; @@ -842,14 +797,14 @@ static void xebec_set_switches(xebec_t *xebec) { mfm_drive_t *drive = &xebec->drives[d]; - if (!drive->hdfile) + if (!drive->hdd_file.f) continue; for (c = 0; c < 4; c++) { - if (drive->spt == 17 && - drive->hpc == xebec_hd_types[c].hpc && - drive->tracks == xebec_hd_types[c].tracks) + if (drive->hdd_file.spt == 17 && + drive->hdd_file.hpc == xebec_hd_types[c].hpc && + drive->hdd_file.tracks == xebec_hd_types[c].tracks) { xebec->switches |= (c << (d ? 0 : 2)); break; @@ -866,8 +821,8 @@ static void *xebec_init() xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); - loadhd(xebec, 0, ide_fn[0]); - loadhd(xebec, 1, ide_fn[1]); + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); xebec_set_switches(xebec); rom_init(&xebec->bios_rom, "roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); @@ -882,16 +837,10 @@ static void *xebec_init() static void xebec_close(void *p) { xebec_t *xebec = (xebec_t *)p; - int d; - - for (d = 0; d < 2; d++) - { - mfm_drive_t *drive = &xebec->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); - } + hdd_close(&xebec->drives[0].hdd_file); + hdd_close(&xebec->drives[1].hdd_file); + free(xebec); } @@ -918,14 +867,14 @@ static void *dtc_5150x_init() xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); - loadhd(xebec, 0, ide_fn[0]); - loadhd(xebec, 1, ide_fn[1]); + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); xebec->switches = 0xff; - xebec->drives[0].cfg_cyl = xebec->drives[0].tracks; - xebec->drives[0].cfg_hpc = xebec->drives[0].hpc; - xebec->drives[1].cfg_cyl = xebec->drives[1].tracks; - xebec->drives[1].cfg_hpc = xebec->drives[1].hpc; + xebec->drives[0].cfg_cyl = xebec->drives[0].hdd_file.tracks; + xebec->drives[0].cfg_hpc = xebec->drives[0].hdd_file.hpc; + xebec->drives[1].cfg_cyl = xebec->drives[1].hdd_file.tracks; + xebec->drives[1].cfg_hpc = xebec->drives[1].hdd_file.hpc; rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);