From 9ddd1fc679d06e79b764254ae263c2c64d71b950 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Mar 2017 21:15:28 +0000 Subject: [PATCH] Added support for IBM AT Fixed Disk Adapter (MFM). Added ability to configure hard drive controller. Changed XTIDE to be generic device. --- src/Makefile.am | 4 +- src/Makefile.linux32 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/device.h | 3 +- src/hdd.c | 93 +++++++ src/hdd.h | 8 + src/mem.c | 48 ---- src/mfm_at.c | 645 +++++++++++++++++++++++++++++++++++++++++++ src/mfm_at.h | 1 + src/model.c | 59 ++-- src/model.h | 1 + src/pc.c | 12 +- src/pc.rc | 126 +++++++-- src/resources.h | 3 + src/win-config.c | 85 +++++- src/win-hdconf.c | 142 ++++++++-- src/xtide.c | 92 +++++- src/xtide.h | 3 +- 20 files changed, 1207 insertions(+), 134 deletions(-) create mode 100644 src/hdd.c create mode 100644 src/hdd.h create mode 100644 src/mfm_at.c create mode 100644 src/mfm_at.h diff --git a/src/Makefile.am b/src/Makefile.am index 96a7829..94f6aeb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,9 +19,9 @@ allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro- allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c 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 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 \ -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 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 \ -lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +lpt.c mcr.c mem.c mfm_at.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 rom.c rtc.c scat.c serial.c sis496.c sound.c \ sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index e5f2f42..7e05a38 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -8,9 +8,9 @@ allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro- allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.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 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 \ -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 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 \ -lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +lpt.o mcr.o mem.o mfm_at.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 rom.o rtc.o scat.o serial.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 1de1969..7940fbf 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -7,9 +7,9 @@ allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro- allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.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 disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.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 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 \ -lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +lpt.o mcr.o mem.o mfm_at.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 rom.o rtc.o scat.o serial.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index be18bdb..14e1188 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,9 +5,9 @@ WINDRES = windres.exe CFLAGS = -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-iso.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 disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.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 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 lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o mfm_at.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 rom.o rtc.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index dcc49a7..730662a 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -5,9 +5,9 @@ WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.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 \ - 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 headland.o i430lx.o i430fx.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 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 lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o mfm_at.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 rom.o rtc.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ diff --git a/src/device.h b/src/device.h index ef1c60f..a190170 100644 --- a/src/device.h +++ b/src/device.h @@ -46,7 +46,8 @@ char *device_get_config_string(char *name); enum { - DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_AT = 2 /*Device requires an AT-compatible system*/ }; int model_get_config_int(char *s); diff --git a/src/hdd.c b/src/hdd.c new file mode 100644 index 0000000..f40322d --- /dev/null +++ b/src/hdd.c @@ -0,0 +1,93 @@ +#include "ibm.h" +#include "device.h" +#include "hdd.h" + +#include "mfm_at.h" +#include "xtide.h" + +char hdd_controller_name[16]; + +static device_t null_hdd_device; + +static int hdd_controller_current; + +static struct +{ + char name[50]; + char internal_name[16]; + device_t *device; + int is_mfm; +} hdd_controllers[] = +{ + {"None", "none", &null_hdd_device, 0}, + {"AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, + {"XTIDE", "xtide", &xtide_device, 0}, + {"XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, + {"", "", NULL, 0} +}; + +char *hdd_controller_get_name(int hdd) +{ + return hdd_controllers[hdd].name; +} + +char *hdd_controller_get_internal_name(int hdd) +{ + return hdd_controllers[hdd].internal_name; +} + +int hdd_controller_get_flags(int hdd) +{ + return hdd_controllers[hdd].device->flags; +} + +int hdd_controller_available(int hdd) +{ + return device_available(hdd_controllers[hdd].device); +} + +int hdd_controller_current_is_mfm() +{ + return hdd_controllers[hdd_controller_current].is_mfm; +} + +void hdd_controller_init(char *internal_name) +{ + int c = 0; + + while (hdd_controllers[c].device) + { + if (!strcmp(internal_name, hdd_controllers[c].internal_name)) + { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + device_add(hdd_controllers[c].device); + return; + } + c++; + } + fatal("Could not find hdd_controller %s\n", internal_name); +} + + +static void *null_hdd_init() +{ + return NULL; +} + +static void null_hdd_close(void *p) +{ +} + +static device_t null_hdd_device = +{ + "Null HDD controller", + 0, + null_hdd_init, + null_hdd_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/hdd.h b/src/hdd.h new file mode 100644 index 0000000..c0443e0 --- /dev/null +++ b/src/hdd.h @@ -0,0 +1,8 @@ +char *hdd_controller_get_name(int hdd); +char *hdd_controller_get_internal_name(int hdd); +int hdd_controller_get_flags(int hdd); +int hdd_controller_available(int hdd); +int hdd_controller_current_is_mfm(); +void hdd_controller_init(char *internal_name); + +extern char hdd_controller_name[16]; diff --git a/src/mem.c b/src/mem.c index 788e3c0..c08b35e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -57,32 +57,6 @@ int cachesize=256; uint8_t *ram,*rom; uint8_t romext[32768]; -static void mem_load_xtide_bios() -{ - FILE *f; - f=romfopen("roms/ide_xt.bin","rb"); - -// is486=0; - if (f) - { - fread(romext,16384,1,f); - fclose(f); - } -} - -static void mem_load_atide_bios() -{ - FILE *f; - f=romfopen("roms/ide_at.bin","rb"); - -// is486=0; - if (f) - { - fread(romext,16384,1,f); - fclose(f); - } -} - static void mem_load_atide115_bios() { FILE *f; @@ -124,7 +98,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); loadfont("roms/pc1512/40078.ic127", 2); return 1; case ROM_PC1640: @@ -141,7 +114,6 @@ int loadbios() f=romfopen("roms/pc1640/40100","rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); return 1; case ROM_PC200: f=romfopen("roms/pc200/pc20v2.1","rb"); @@ -154,7 +126,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); loadfont("roms/pc200/40109.bin", 1); return 1; case ROM_TANDY: @@ -162,7 +133,6 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_TANDY1000HX: f = romfopen("roms/tandy1000hx/v020000.u12", "rb"); @@ -170,7 +140,6 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - mem_load_xtide_bios(); return 1; case ROM_TANDY1000SL2: f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); @@ -185,7 +154,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); return 1; /* case ROM_IBMPCJR: f=fopen("pcjr/bios.rom","rb"); @@ -206,14 +174,12 @@ int loadbios() fread(rom + 0x8000, 0x8000, 1, ff); fclose(ff); fclose(f); - mem_load_xtide_bios(); return 1; } else { fread(rom,65536,1,f); fclose(f); - mem_load_xtide_bios(); return 1; } break; @@ -230,14 +196,12 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_DTKXT: f=romfopen("roms/dtk/DTK_ERSO_2.42_2764.bin","rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_OLIM24: f = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); @@ -250,7 +214,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_PC2086: @@ -269,7 +232,6 @@ int loadbios() f = romfopen("roms/pc2086/40186.ic171", "rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); biosmask = 0x3fff; return 1; @@ -281,7 +243,6 @@ int loadbios() f = romfopen("roms/pc3086/c000.bin", "rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); biosmask = 0x3fff; return 1; @@ -302,7 +263,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_atide_bios(); return 1; case ROM_CMDPC30: f = romfopen("roms/cmdpc30/commodore pc 30 iii even.bin", "rb"); @@ -414,7 +374,6 @@ int loadbios() if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_MEGAPC: @@ -555,7 +514,6 @@ int loadbios() fclose(ff); fclose(f); biosmask = 0x7fff; - mem_load_atide_bios(); return 1; case ROM_AMIXT: @@ -563,7 +521,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_LTXT: @@ -571,7 +528,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_LXT3: @@ -579,7 +535,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_PX386: /*Phoenix 80386 BIOS*/ @@ -607,7 +562,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_JUKOPC: @@ -615,7 +569,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); return 1; case ROM_IBMPS2_M30_286: @@ -624,7 +577,6 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - mem_load_atide_bios(); return 1; } diff --git a/src/mfm_at.c b/src/mfm_at.c new file mode 100644 index 0000000..e9f610f --- /dev/null +++ b/src/mfm_at.c @@ -0,0 +1,645 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include + +#include + +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "pic.h" +#include "timer.h" + +#include "mfm_at.h" + + +#define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) + +#define STAT_ERR 0x01 +#define STAT_INDEX 0x02 +#define STAT_CORRECTED_DATA 0x04 +#define STAT_DRQ 0x08 /* Data request */ +#define STAT_DSC 0x10 +#define STAT_SEEK_COMPLETE 0x20 +#define STAT_READY 0x40 +#define STAT_BUSY 0x80 + +#define ERR_DAM_NOT_FOUND 0x01 /*Data Address Mark not found*/ +#define ERR_TR000 0x02 /*Track 0 not found*/ +#define ERR_ABRT 0x04 /*Command aborted*/ +#define ERR_ID_NOT_FOUND 0x10 /*ID not found*/ +#define ERR_DATA_CRC 0x40 /*Data CRC error*/ +#define ERR_BAD_BLOCK 0x80 /*Bad Block detected*/ + +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 + +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; +} mfm_drive_t; + +typedef struct mfm_t +{ + uint8_t status; + uint8_t error; + int secount,sector,cylinder,head,cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; + + int callback; + + mfm_drive_t drives[2]; +} mfm_t; + +uint16_t mfm_readw(uint16_t port, void *p); +void mfm_writew(uint16_t port, uint16_t val, void *p); + +static inline void mfm_irq_raise(mfm_t *mfm) +{ +// pclog("IDE_IRQ_RAISE\n"); + if (!(mfm->fdisk&2)) + picint(1 << 14); + + mfm->irqstat=1; +} + +static inline void mfm_irq_lower(mfm_t *mfm) +{ + picintc(1 << 14); +} + +void mfm_irq_update(mfm_t *mfm) +{ + if (mfm->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(mfm->fdisk & 2)) + picint(1 << 14); +} + +/* + * Return the sector offset for the current register values + */ +static int mfm_get_sector(mfm_t *mfm, off64_t *addr) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + + if (drive->current_cylinder != mfm->cylinder) + { + pclog("mfm_get_sector: wrong cylinder\n"); + return 1; + } + if (mfm->head > heads) + { + pclog("mfm_get_sector: past end of configured heads\n"); + return 1; + } + if (mfm->sector >= sectors+1) + { + pclog("mfm_get_sector: past end of configured sectors\n"); + return 1; + } + if (mfm->head > drive->hpc) + { + pclog("mfm_get_sector: past end of heads\n"); + return 1; + } + if (mfm->sector >= drive->spt+1) + { + pclog("mfm_get_sector: past end of sectors\n"); + return 1; + } + + *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * + sectors) + (mfm->sector - 1); + + return 0; +} + +/** + * Move to the next sector using CHS addressing + */ +static void mfm_next_sector(mfm_t *mfm) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + + mfm->sector++; + if (mfm->sector == (drive->cfg_spt + 1)) + { + mfm->sector = 1; + mfm->head++; + if (mfm->head == drive->cfg_hpc) + { + mfm->head = 0; + mfm->cylinder++; + if (drive->current_cylinder < drive->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; + +// pclog("mfm_write: addr=%04x val=%02x\n", port, val); + switch (port) + { + case 0x1F0: /* Data */ + mfm_writew(port, val | (val << 8), p); + return; + + case 0x1F1: /* Write precompenstation */ + mfm->cylprecomp = val; + return; + + case 0x1F2: /* Sector count */ + mfm->secount = val; + return; + + case 0x1F3: /* Sector */ + mfm->sector = val; + return; + + case 0x1F4: /* Cylinder low */ + mfm->cylinder = (mfm->cylinder & 0xFF00) | val; + return; + + case 0x1F5: /* Cylinder high */ + mfm->cylinder = (mfm->cylinder & 0xFF) | (val << 8); + return; + + 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 + mfm->status = STAT_READY | STAT_DSC; + return; + + case 0x1F7: /* Command register */ + if (mfm->drives[mfm->drive_sel].hdfile == NULL) + fatal("Command on non-present drive\n"); + + mfm_irq_lower(mfm); + mfm->command = val; + mfm->error = 0; + + switch (val & 0xf0) + { + case CMD_RESTORE: +// pclog("Restore\n"); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_SEEK: +// pclog("Seek to cylinder %i\n", mfm->cylinder); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + switch (val) + { + case CMD_READ: case CMD_READ+1: + case CMD_READ+2: case CMD_READ+3: +// pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head,ins); + mfm->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_WRITE: case CMD_WRITE+1: + case CMD_WRITE+2: case CMD_WRITE+3: +// pclog("Write %i sectors to sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + mfm->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; + mfm->pos=0; + break; + + case CMD_VERIFY: case CMD_VERIFY+1: +// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~1; + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200 * IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_FORMAT: +// pclog("Format track %i head %i\n", mfm->cylinder, mfm->head); + mfm->status = STAT_DRQ | STAT_BUSY; + mfm->pos=0; + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 30*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + pclog("Bad MFM command %02X\n", val); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + } + } + break; + + case 0x3F6: /* Device control */ + if ((mfm->fdisk & 4) && !(val & 4)) + { + timer_process(); + mfm->callback = 500*IDE_TIME; + timer_update_outstanding(); + mfm->reset = 1; + mfm->status = STAT_BUSY; +// pclog("MFM Reset\n"); + } + if (val & 4) + { + /*Drive held in reset*/ + timer_process(); + mfm->callback = 0; + timer_update_outstanding(); + mfm->status = STAT_BUSY; + } + mfm->fdisk = val; + mfm_irq_update(mfm); + return; + } +// fatal("Bad IDE write %04X %02X\n", addr, val); +} + +void mfm_writew(uint16_t port, uint16_t val, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + +// pclog("Write IDEw %04X\n",val); + mfm->buffer[mfm->pos >> 1] = val; + mfm->pos += 2; + + if (mfm->pos >= 512) + { + mfm->pos = 0; + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 6*IDE_TIME; + timer_update_outstanding(); + } +} + +uint8_t mfm_read(uint16_t port, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + uint8_t temp; + + switch (port) + { + case 0x1F0: /* Data */ + temp = mfm_readw(port, mfm) & 0xff; + break; + + case 0x1F1: /* Error */ + temp = mfm->error; + break; + + case 0x1F2: /* Sector count */ + temp = (uint8_t)mfm->secount; + break; + + case 0x1F3: /* Sector */ + temp = (uint8_t)mfm->sector; + break; + + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(mfm->cylinder&0xFF); + break; + + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(mfm->cylinder>>8); + break; + + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(mfm->head | (mfm->drive_sel ? 0x10 : 0) | 0xa0); + break; + + case 0x1F7: /* Status */ + mfm_irq_lower(mfm); + temp = mfm->status; + break; + } + +// pclog("mfm_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); + return temp; +} + +uint16_t mfm_readw(uint16_t port, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + uint16_t temp; + + temp = mfm->buffer[mfm->pos >> 1]; + mfm->pos += 2; + + if (mfm->pos >= 512) + { +// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + mfm->pos=0; + mfm->status = STAT_READY | STAT_DSC; + if (mfm->command == CMD_READ) + { + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) + { + mfm_next_sector(mfm); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 6*IDE_TIME; + timer_update_outstanding(); + } + } + } + +// pclog("mem_readw: temp=%04x %i\n", temp, mfm->pos); + return temp; +} + +static void do_seek(mfm_t *mfm) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + + if (mfm->cylinder < drive->tracks) + drive->current_cylinder = mfm->cylinder; + else + drive->current_cylinder = drive->tracks-1; +} + +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; + if (mfm->reset) + { + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + mfm->secount = 1; + mfm->sector = 1; + mfm->head = 0; + mfm->cylinder = 0; + mfm->reset = 0; +// pclog("Reset callback\n"); + return; + } + switch (mfm->command) + { + case CMD_RESTORE: + drive->current_cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_SEEK: + do_seek(mfm); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_READ: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + +// 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); + 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]); +// if (addr) output=3; + mfm_irq_raise(mfm); + readflash = 1; + break; + + case CMD_WRITE: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fwrite(mfm->buffer, 512, 1, drive->hdfile); + mfm_irq_raise(mfm); + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) + { + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; + mfm->pos = 0; + mfm_next_sector(mfm); + } + else + mfm->status = STAT_READY | STAT_DSC; + readflash = 1; + break; + + case CMD_VERIFY: + do_seek(mfm); + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; +// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); + mfm_irq_raise(mfm); + readflash=1; + break; + + case CMD_FORMAT: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + 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); + } + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + readflash = 1; + break; + + case CMD_DIAGNOSE: + mfm->error = 1; /*No error detected*/ + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head+1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + default: + pclog("Callback on unknown command %02x\n", mfm->command); + mfm->status = STAT_READY | STAT_ERR | STAT_DSC; + mfm->error = ERR_ABRT; + mfm_irq_raise(mfm); + break; + } +} + +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]); + + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; /*No errors*/ + + io_sethandler(0x01f0, 0x0001, mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); + io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); + io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); + + timer_add(mfm_callback, &mfm->callback, &mfm->callback, mfm); + + return mfm; +} + +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); + } + + free(mfm); +} + +device_t mfm_at_device = +{ + "IBM PC AT Fixed Disk Adapter", + DEVICE_AT, + mfm_init, + mfm_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/mfm_at.h b/src/mfm_at.h new file mode 100644 index 0000000..00d045e --- /dev/null +++ b/src/mfm_at.h @@ -0,0 +1 @@ +extern device_t mfm_at_device; diff --git a/src/model.c b/src/model.c index 2cf0843..0f9201b 100644 --- a/src/model.c +++ b/src/model.c @@ -51,7 +51,6 @@ #include "vid_pcjr.h" #include "vid_tandy.h" #include "wd76c10.h" -#include "xtide.h" void xt_init(); void pcjr_init(); @@ -61,6 +60,7 @@ void ams_init(); void europc_init(); void olim24_init(); void at_init(); +void at_ide_init(); void deskpro386_init(); void ps1_m2011_init(); void ps1_m2121_init(); @@ -105,28 +105,28 @@ MODEL models[] = {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"Acer 386SX25/N", ROM_ACER386, "acer386", { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, + {"Acer 386SX25/N", ROM_ACER386, "acer386", { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, /* {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},*/ - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, /* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_um8881f_init},*/ - {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_sis496_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_batman_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, - {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_i430vx_init, NULL}, + {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; @@ -200,7 +200,6 @@ void xt_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_xt); keyboard_xt_init(); - xtide_init(); nmi_init(); device_add(&gameport_device); } @@ -228,7 +227,6 @@ void tandy1k_init() device_add(&sn76489_device); else device_add(&ncr8496_device); - xtide_init(); nmi_init(); if (romset != ROM_TANDY) device_add(&tandy_eeprom_device); @@ -241,7 +239,6 @@ void tandy1ksl2_init() mem_add_bios(); keyboard_tandy_init(); device_add(&pssj_device); - xtide_init(); nmi_init(); device_add(&tandy_rom_device); device_add(&tandy_eeprom_device); @@ -256,7 +253,6 @@ void ams_init() amstrad_init(); keyboard_amstrad_init(); nvr_init(); - xtide_init(); nmi_init(); fdc_set_dskchg_activelow(); device_add(&gameport_device); @@ -268,7 +264,6 @@ void europc_init() mem_add_bios(); jim_init(); keyboard_xt_init(); - xtide_init(); nmi_init(); device_add(&gameport_device); } @@ -280,7 +275,6 @@ void olim24_init() keyboard_olim24_init(); nvr_init(); olivetti_m24_init(); - xtide_init(); nmi_init(); device_add(&gameport_device); } @@ -292,13 +286,18 @@ void at_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_at); dma16_init(); - ide_init(); keyboard_at_init(); nvr_init(); pic2_init(); device_add(&gameport_device); } +void at_ide_init() +{ + at_init(); + ide_init(); +} + void deskpro386_init() { at_init(); @@ -354,48 +353,56 @@ void ps2_m30_286_init() void at_neat_init() { at_init(); + ide_init(); neat_init(); } void at_scat_init() { at_init(); + ide_init(); scat_init(); } void at_acer386sx_init() { at_init(); + ide_init(); acer386sx_init(); } void at_wd76c10_init() { at_init(); + ide_init(); wd76c10_init(); } void at_headland_init() { at_init(); + ide_init(); headland_init(); } void at_opti495_init() { at_init(); + ide_init(); opti495_init(); } void at_ali1429_init() { at_init(); + ide_init(); ali1429_init(); } void at_um8881f_init() { at_init(); + ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); um8881f_init(); } @@ -403,6 +410,7 @@ void at_um8881f_init() void at_sis496_init() { at_init(); + ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); device_add(&sis496_device); } @@ -410,6 +418,7 @@ void at_sis496_init() void at_batman_init() { at_init(); + ide_init(); pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); i430lx_init(); fdc37c665_init(); @@ -419,6 +428,7 @@ void at_batman_init() void at_endeavor_init() { at_init(); + ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430fx_init(); piix_init(7); @@ -430,6 +440,7 @@ void at_endeavor_init() void at_i430vx_init() { at_init(); + ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430vx_init(); piix_init(7); diff --git a/src/model.h b/src/model.h index 769c928..1dbfe0e 100644 --- a/src/model.h +++ b/src/model.h @@ -2,6 +2,7 @@ #define MODEL_PS2 2 #define MODEL_AMSTRAD 4 #define MODEL_OLIM24 8 +#define MODEL_HAS_IDE 0x10 typedef struct { diff --git a/src/pc.c b/src/pc.c index ad18e3e..182273c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -38,6 +38,7 @@ #include "vid_voodoo.h" #include "video.h" #include "amstrad.h" +#include "hdd.h" int window_w, window_h, window_x, window_y, window_remember; @@ -370,7 +371,8 @@ void resetpchard() if (SSI2001) device_add(&ssi2001_device); if (voodoo_enabled) - device_add(&voodoo_device); + device_add(&voodoo_device); + hdd_controller_init(hdd_controller_name); pc_reset(); resetide(); @@ -614,6 +616,12 @@ void loadconfig(char *fn) if (p) strcpy(discfns[1], p); else strcpy(discfns[1], ""); + p = (char *)config_get_string(NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + mem_size = config_get_int(NULL, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); @@ -720,6 +728,8 @@ void saveconfig() config_set_int(NULL, "has_fpu", hasfpu); config_set_string(NULL, "disc_a", discfns[0]); config_set_string(NULL, "disc_b", discfns[1]); + config_set_string(NULL, "hdd_controller", hdd_controller_name); + config_set_int(NULL, "mem_size", mem_size); config_set_int(NULL, "cdrom_drive", cdrom_drive); config_set_int(NULL, "cdrom_enabled", cdrom_enabled); diff --git a/src/pc.rc b/src/pc.rc index e2dea61..4b73e42 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -57,13 +57,13 @@ BEGIN END END -ConfigureDlg DIALOGEX 0, 0, 232+40, 392 +ConfigureDlg DIALOGEX 0, 0, 292, 412 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure PCem" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,64,368,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,128,368,50,14, WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,64,388,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,388,50,14, WS_TABSTOP COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP @@ -78,12 +78,12 @@ BEGIN EDITTEXT IDC_MEMTEXT, 62, 172, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 172, 12, 14 LTEXT "MB", IDC_TEXT_MB, 98, 172, 40, 10 - CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,292,118,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,308,118,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,324,118,10 - CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,340,118,10 - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,356,118,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 356, 40, 14, WS_TABSTOP + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,312,118,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,328,118,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,344,118,10 + CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,360,118,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,376,118,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 376, 40, 14, WS_TABSTOP LTEXT "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Video :",IDC_STATIC,15,36,34,10 LTEXT "CPU type :",IDC_STATIC,15,56,34,10 @@ -92,18 +92,20 @@ BEGIN LTEXT "Video speed :",IDC_STATIC,15,136,40,10 LTEXT "Soundcard :",IDC_STATIC,15,156,40,10 LTEXT "Memory :",IDC_STATIC,15,176,40,10 - LTEXT "Drive A: :",IDC_STATIC,15,196,40,10 - LTEXT "Drive B: :",IDC_STATIC,15,216,40,10 - COMBOBOX IDC_COMBODRA,62,196,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBODRB,62,216,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Mouse :",IDC_STATIC,15,236,40,10 - COMBOBOX IDC_COMBOMOUSE,62,236,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Joystick :",IDC_STATIC,15,256,40,10 - COMBOBOX IDC_COMBOJOY,62,256,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,272,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 2...",IDC_JOY2,80,272,50,14, WS_TABSTOP - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,272,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 4...",IDC_JOY4,208,272,50,14, WS_TABSTOP + LTEXT "HDD :",IDC_STATIC,15,196,40,10 + COMBOBOX IDC_COMBOHDD, 62,196,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Drive A: :",IDC_STATIC,15,216,40,10 + LTEXT "Drive B: :",IDC_STATIC,15,236,40,10 + COMBOBOX IDC_COMBODRA,62,216,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBODRB,62,236,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Mouse :",IDC_STATIC,15,256,40,10 + COMBOBOX IDC_COMBOMOUSE,62,256,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Joystick :",IDC_STATIC,15,276,40,10 + COMBOBOX IDC_COMBOJOY,62,276,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,292,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 2...",IDC_JOY2,80,292,50,14, WS_TABSTOP + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,292,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 4...",IDC_JOY4,208,292,50,14, WS_TABSTOP END HdConfDlg DIALOGEX 0, 0, 210, 312+4*16 @@ -227,3 +229,85 @@ BEGIN LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 LTEXT "1",IDC_STEXT1,16,186,180,1000 END + +HdConfDlgMfm DIALOGEX 0, 0, 210, 172 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Hard Discs" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31+12,152,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101+12,152,50,14 + + LTEXT "C:",IDC_STATIC,7,6,27,10 + EDITTEXT IDC_EDIT_C_FN, 7, 22, 136, 12, WS_DISABLED + PUSHBUTTON "...",IDC_CFILE,7 + 136, 22, 16, 14 + PUSHBUTTON "New",IDC_CNEW,7 + 136 + 16, 22, 24, 14 + PUSHBUTTON "Eject", IDC_EJECTC, 7 + 136 + 16 + 24, 22, 24, 14 + + EDITTEXT IDC_EDIT_C_SPT,36,38,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_C_HPC,94,38,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_C_CYL,152,38,28,12, WS_DISABLED + LTEXT "Sectors:",IDC_STATIC,7,38,27,10 + LTEXT "Heads:",IDC_STATIC,63,38,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,38,32,12 + LTEXT "", IDC_TEXT_C_SIZE, 7, 54, 136, 12 + + LTEXT "D:",IDC_STATIC,7,76,27,10 + EDITTEXT IDC_EDIT_D_FN, 7, 92, 136, 12, WS_DISABLED + PUSHBUTTON "...",IDC_DFILE,7 + 136, 92, 16, 14 + PUSHBUTTON "New",IDC_DNEW,7 + 136 + 16, 92, 24, 14 + PUSHBUTTON "Eject", IDC_EJECTD, 7 + 136 + 16 + 24, 92, 24, 14 + + EDITTEXT IDC_EDIT_D_SPT,36,108,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_D_HPC,94,108,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_D_CYL,152,108,28,12, WS_DISABLED + LTEXT "Sectors:",IDC_STATIC,7,108,27,10 + LTEXT "Heads:",IDC_STATIC,63,108,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,108,32,12 + LTEXT "", IDC_TEXT_D_SIZE, 7, 124, 136, 12 +END + +HdNewDlgMfm DIALOGEX 0, 0, 186, 102 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New Hard Disc" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31,82,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 + + EDITTEXT IDC_EDITC, 7, 6, 136, 12 + PUSHBUTTON "...",IDC_CFILE,7 + 136, 6, 16, 14 + + EDITTEXT IDC_EDIT1,36,22,16,12 + EDITTEXT IDC_EDIT2,94,22,16,12 + EDITTEXT IDC_EDIT3,152,22,28,12 + LTEXT "Sectors:",IDC_STATIC,7,22,27,10 + LTEXT "Heads:",IDC_STATIC,63,22,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 + LTEXT "", IDC_TEXT1, 7, 38, 136, 12 + + COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + +END + +HdSizeDlgMfm DIALOGEX 0, 0, 186, 102 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Hard disc parameters" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31,82,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 + + LTEXT "Initial settings are based on file size",IDC_STATIC,7,6,170,10 + + EDITTEXT IDC_EDIT1,36,22,16,12 + EDITTEXT IDC_EDIT2,94,22,16,12 + EDITTEXT IDC_EDIT3,152,22,28,12 + LTEXT "Sectors:",IDC_STATIC,7,22,27,10 + LTEXT "Heads:",IDC_STATIC,63,22,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 + LTEXT "", IDC_TEXT1, 7, 38, 136, 12 + + COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + +END diff --git a/src/resources.h b/src/resources.h index ebe0bfe..dc00796 100644 --- a/src/resources.h +++ b/src/resources.h @@ -39,6 +39,7 @@ #define IDC_COMBOJOY 1064 #define IDC_COMBOWS 1065 #define IDC_COMBOMOUSE 1066 +#define IDC_COMBOHDD 1067 #define IDC_CHECK1 1010 #define IDC_CHECK2 1011 #define IDC_CHECK3 1012 @@ -115,6 +116,8 @@ #define IDC_EDIT_E_FN 1232 #define IDC_EDIT_F_FN 1233 +#define IDC_HDTYPE 1280 + #define IDC_CONFIGUREVID 1200 #define IDC_CONFIGURESND 1201 #define IDC_CONFIGUREVOODOO 1202 diff --git a/src/win-config.c b/src/win-config.c index 5a54961..78c12ad 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -10,6 +10,7 @@ #include "device.h" #include "fdd.h" #include "gameport.h" +#include "hdd.h" #include "model.h" #include "mouse.h" #include "nvr.h" @@ -23,6 +24,7 @@ extern int is486; static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; static int settings_sound_to_list[20], settings_list_to_sound[20]; static int settings_mouse_to_list[20], settings_list_to_mouse[20]; +static char *hdd_names[16]; static int mouse_valid(int type, int model) { @@ -35,6 +37,71 @@ static int mouse_valid(int type, int model) return 1; } +static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) +{ + HWND h; + + h = GetDlgItem(hdlg, IDC_COMBOHDD); + + if (models[model].flags & MODEL_HAS_IDE) + { + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Internal IDE"); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else + { + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + if (use_selected_hdd) + { + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + strncpy(old_name, hdd_names[c], sizeof(old_name)-1); + else + strcpy(old_name, "none"); + } + else + strncpy(old_name, hdd_controller_name, sizeof(old_name)-1); + + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + break; + if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + SendMessage(h, CB_SETCURSEL, 0, 0); + } +} + static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { char temp_str[256]; @@ -290,6 +357,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR c++; } SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + + recalc_hdd_list(hdlg, romstomodel[romset], 0); + return TRUE; case WM_COMMAND: @@ -350,13 +420,17 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBOMOUSE); temp_mouse_type = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBOHDD); + c = SendMessage(h, CB_GETCURSEL, 0, 0); if (temp_model != model || gfx != gfxcard || mem != mem_size || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || temp_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type) + temp_mouse_type != mouse_type || + strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1)) { if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL)==IDOK) { @@ -377,6 +451,12 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fdd_set_type(0, temp_fda_type); fdd_set_type(1, temp_fdb_type); + + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); + else + strcpy(hdd_controller_name, "none"); + mem_resize(); loadbios(); @@ -542,6 +622,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); else SendMessage(h, CB_SETCURSEL, 0, 0); + + recalc_hdd_list(hdlg, temp_model, 1); + } break; case IDC_COMBOCPUM: diff --git a/src/win-hdconf.c b/src/win-hdconf.c index bf61fe7..14c011c 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -8,12 +8,61 @@ #include "resources.h" #include "win.h" +static struct +{ + int cylinders; + int heads; +} hd_types[] = +{ + {306, 4}, {615, 4}, {615, 6}, {940, 8}, + {940, 6}, {615, 4}, {462, 8}, {733, 5}, + {900, 15}, {820, 3}, {855, 5}, {855, 7}, + {306, 8}, {733, 7}, {0, 0}, {612, 4}, + {977, 5}, {977, 7}, {1024, 7}, {733, 5}, + {733, 7}, {733, 5}, {306, 4}, {925, 7}, + {925, 9}, {754, 7}, {754, 11}, {699, 7}, + {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, + {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, + {615, 8}, {987, 3}, {462, 7}, {820, 6}, + {977, 5}, {981, 5}, {830, 7}, {830, 10}, + {917, 15}, {1224, 15} +}; + static int hd_changed = 0; static char hd_new_name[512]; static int hd_new_spt, hd_new_hpc, hd_new_cyl; +static int hd_new_type; static int new_cdrom_channel; +static void check_hd_type(off64_t sz) +{ + int c; + + hd_new_type = 0; + + if (hdd_controller_current_is_mfm()) + { + for (c = 0; c < 46; c++) + { + if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) + { + hd_new_spt = 17; + hd_new_hpc = hd_types[c].heads; + hd_new_cyl = hd_types[c].cylinders; + hd_new_type = c+1; + return; + } + } + } + else + { + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } +} + static void update_hdd_cdrom(HWND hdlg) { HWND h; @@ -44,6 +93,8 @@ static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA PcemHDC hd[4]; FILE *f; uint8_t buf[512]; + int hd_type; + switch (message) { case WM_INITDIALOG: @@ -64,6 +115,16 @@ static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA sprintf(s, "Size : %imb", (((511*16*63)*512)/1024)/1024); SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); +// hd_type = 0; + h = GetDlgItem(hdlg, IDC_HDTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + SendMessage(h, CB_SETCURSEL, 0, 0); + return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) @@ -132,17 +193,57 @@ static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA case IDC_EDIT1: case IDC_EDIT2: case IDC_EDIT3: h = GetDlgItem(hdlg, IDC_EDIT1); SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); + pclog("EDIT1: %s\n", s); sscanf(s, "%i", &hd[0].spt); h = GetDlgItem(hdlg, IDC_EDIT2); SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); + pclog("EDIT2: %s\n", s); sscanf(s, "%i", &hd[0].hpc); h = GetDlgItem(hdlg, IDC_EDIT3); SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); + pclog("EDIT3: %s\n", s); sscanf(s, "%i", &hd[0].tracks); h = GetDlgItem(hdlg, IDC_TEXT1); sprintf(s, "Size : %imb", (((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + + hd_type = 0; + for (c = 1; c <= 46; c++) + { + pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); + if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) + { + hd_type = c; + break; + } + } + h = GetDlgItem(hdlg, IDC_HDTYPE); + SendMessage(h, CB_SETCURSEL, hd_type, 0); + + return TRUE; + + case IDC_HDTYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_HDTYPE); + hd_type = SendMessage(h, CB_GETCURSEL, 0, 0); + if (hd_type) + { + h = GetDlgItem(hdlg, IDC_EDIT3); + sprintf(s, "%i", hd_types[hd_type-1].cylinders); + SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + h = GetDlgItem(hdlg, IDC_EDIT2); + sprintf(s, "%i", hd_types[hd_type-1].heads); + SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + h = GetDlgItem(hdlg, IDC_EDIT1); + SendMessage(h, WM_SETTEXT, 0, (LPARAM)"17"); + + h = GetDlgItem(hdlg, IDC_TEXT1); + sprintf(s, "Size : %imb", (((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); + SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + } + } return TRUE; } break; @@ -156,9 +257,20 @@ BOOL CALLBACK hdsize_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar char s[260]; HWND h; PcemHDC hd[2]; + int c; + switch (message) { case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_HDTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + SendMessage(h, CB_SETCURSEL, hd_new_type, 0); + h = GetDlgItem(hdlg, IDC_EDIT1); sprintf(s, "%i", hd_new_spt); SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); @@ -172,6 +284,7 @@ BOOL CALLBACK hdsize_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar h = GetDlgItem(hdlg, IDC_TEXT1); sprintf(s, "Size : %imb", ((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) @@ -436,7 +549,7 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR return TRUE; case IDC_CNEW: - if (DialogBox(hinstance, TEXT("HdNewDlg"), hdlg, hdnew_dlgproc) == 1) + if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdNewDlgMfm") : TEXT("HdNewDlg"), hdlg, hdnew_dlgproc) == 1) { h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); sprintf(s, "%i", hd_new_spt); @@ -470,11 +583,9 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fseeko64(f, -1, SEEK_END); sz = ftello64(f) + 1; fclose(f); - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; + check_hd_type(sz); - if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) + if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdSizeDlgMfm") : TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) { h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); sprintf(s, "%i", hd_new_spt); @@ -498,7 +609,7 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR return TRUE; case IDC_DNEW: - if (DialogBox(hinstance, TEXT("HdNewDlg"), hdlg, hdnew_dlgproc) == 1) + if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdNewDlgMfm") : TEXT("HdNewDlg"), hdlg, hdnew_dlgproc) == 1) { h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); sprintf(s, "%i", hd_new_spt); @@ -532,11 +643,9 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fseeko64(f, -1, SEEK_END); sz = ftello64(f) + 1; fclose(f); - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; + check_hd_type(sz); - if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) + if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdSizeDlgMfm") : TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) { h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); sprintf(s, "%i", hd_new_spt); @@ -594,9 +703,7 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fseeko64(f, -1, SEEK_END); sz = ftello64(f) + 1; fclose(f); - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; + check_hd_type(sz); if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) { @@ -656,9 +763,7 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fseeko64(f, -1, SEEK_END); sz = ftello64(f) + 1; fclose(f); - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; + check_hd_type(sz); if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc) == 1) { @@ -793,5 +898,8 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR void hdconf_open(HWND hwnd) { - DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, hdconf_dlgproc); + if (hdd_controller_current_is_mfm()) + DialogBox(hinstance, TEXT("HdConfDlgMfm"), hwnd, hdconf_dlgproc); + else + DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, hdconf_dlgproc); } diff --git a/src/xtide.c b/src/xtide.c index 9205040..874a46b 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,17 +1,26 @@ #include "ibm.h" +#include "device.h" #include "io.h" #include "ide.h" +#include "mem.h" +#include "rom.h" #include "xtide.h" -uint8_t xtide_high; - -void xtide_write(uint16_t port, uint8_t val, void *priv) +typedef struct xtide_t { + uint8_t data_high; + rom_t bios_rom; +} xtide_t; + +static void xtide_write(uint16_t port, uint8_t val, void *p) +{ + xtide_t *xtide = (xtide_t *)p; + switch (port & 0xf) { case 0x0: - writeidew(0, val | (xtide_high << 8)); + writeidew(0, val | (xtide->data_high << 8)); return; case 0x1: case 0x2: case 0x3: @@ -20,7 +29,7 @@ void xtide_write(uint16_t port, uint8_t val, void *priv) return; case 0x8: - xtide_high = val; + xtide->data_high = val; return; case 0xe: @@ -29,14 +38,16 @@ void xtide_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t xtide_read(uint16_t port, void *priv) +static uint8_t xtide_read(uint16_t port, void *p) { + xtide_t *xtide = (xtide_t *)p; uint16_t tempw; + switch (port & 0xf) { case 0x0: tempw = readidew(0); - xtide_high = tempw >> 8; + xtide->data_high = tempw >> 8; return tempw & 0xff; case 0x1: case 0x2: case 0x3: @@ -44,15 +55,76 @@ uint8_t xtide_read(uint16_t port, void *priv) return readide(0, (port & 0xf) | 0x1f0); case 0x8: - return xtide_high; + return xtide->data_high; case 0xe: return readide(0, 0x3f6); } } -void xtide_init() +static void *xtide_init() { + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); - io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, NULL); + ide_pri_disable(); + ide_sec_disable(); + io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); + + return xtide; } + +static void *xtide_at_init() +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ide_init(); + + return xtide; +} + +static void xtide_close(void *p) +{ + xtide_t *xtide = (xtide_t *)p; + + free(xtide); +} + +static int xtide_available() +{ + return rom_present("roms/ide_xt.bin"); +} + +static int xtide_at_available() +{ + return rom_present("roms/ide_at.bin"); +} + +device_t xtide_device = +{ + "XTIDE", + 0, + xtide_init, + xtide_close, + xtide_available, + NULL, + NULL, + NULL, + NULL +}; +device_t xtide_at_device = +{ + "XTIDE (AT)", + DEVICE_AT, + xtide_at_init, + xtide_close, + xtide_at_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/xtide.h b/src/xtide.h index ac5413d..739c987 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1 +1,2 @@ -void xtide_init(); +extern device_t xtide_device; +extern device_t xtide_at_device;