From 5f19568e74c61d6f94a5e685303771c2ad5bce5f Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 8 Apr 2007 12:02:50 +0300 Subject: [PATCH] imported winuaesrc1420b5.zip --- ar.c | 1 + blitter.c | 4 + cfgfile.c | 54 ++- custom.c | 9 +- drawing.c | 2 +- filesys.c | 36 +- gayle.c | 764 ++++++++++++++++++++++++++++++---- hardfile.c | 2 +- include/blitter.h | 1 + include/custom.h | 3 + include/filesys.h | 3 +- include/gayle.h | 6 +- include/memory.h | 1 + include/options.h | 3 +- include/savestate.h | 5 + main.c | 2 +- memory.c | 9 +- newcpu.c | 26 +- od-win32/parser.c | 18 +- od-win32/resources/resource | 8 +- od-win32/resources/resource.h | 1 + od-win32/resources/winuae.rc | 25 +- od-win32/win32.h | 4 +- od-win32/win32_filesys.c | 2 +- od-win32/win32_scale2x.c | 1 + od-win32/win32gfx.c | 2 +- od-win32/win32gui.c | 87 ++-- od-win32/winuaechangelog.txt | 44 ++ savestate.c | 18 +- uaeserial.c | 12 +- 30 files changed, 964 insertions(+), 189 deletions(-) diff --git a/ar.c b/ar.c index aec5f8f2..60cc16f7 100755 --- a/ar.c +++ b/ar.c @@ -1455,6 +1455,7 @@ static void hrtmon_configure(void) cfg->keyboard = hrtmon_lang; do_put_mem_long(&cfg->max_chip, currprefs.chipmem_size); do_put_mem_long(&cfg->mon_size, 0x800000); + cfg->ide = currprefs.cs_ide ? 1 : 0; } int hrtmon_load(void) diff --git a/blitter.c b/blitter.c index 9235baf4..b943c8e5 100755 --- a/blitter.c +++ b/blitter.c @@ -807,6 +807,7 @@ void decide_blitter (int hpos) if (!blitter_cycle_exact) return; if (blitline) { + blt_info.got_cycle = 1; decide_blitter_line (hpos); return; } @@ -840,6 +841,7 @@ void decide_blitter (int hpos) break; } + blt_info.got_cycle = 1; if (c < 0) { /* no channel but bus still needs to be allocated.. */ cycle_line[blit_last_hpos] |= CYCLE_BLITTER; blit_cyclecounter++; @@ -1007,6 +1009,7 @@ void do_blitter (int hpos) bltstate = BLT_init; preva = 0; prevb = 0; + blt_info.got_cycle = 0; blit_firstline_cycles = blit_first_cycle = get_cycles (); blit_misscyclecounter = 0; @@ -1069,6 +1072,7 @@ void do_blitter (int hpos) return; } + blt_info.got_cycle = 1; if (currprefs.immediate_blits) cycles = 1; diff --git a/cfgfile.c b/cfgfile.c index c24ac77c..4ed2afde 100755 --- a/cfgfile.c +++ b/cfgfile.c @@ -219,6 +219,7 @@ static void write_filesys_config (struct uae_prefs *p, const char *unexpanded, { int i; char tmp[MAX_DPATH]; + char *hdcontrollers[] = { "uae", "ide0", "ide1" }; for (i = 0; i < p->mountitems; i++) { struct uaedev_config_info *uci = &p->mountconfig[i]; @@ -233,11 +234,11 @@ static void write_filesys_config (struct uae_prefs *p, const char *unexpanded, uci->volname, str); zfile_fputs (f, tmp); } else { - sprintf (tmp, "hardfile2=%s,%s:%s,%d,%d,%d,%d,%d,%s\n", + sprintf (tmp, "hardfile2=%s,%s:%s,%d,%d,%d,%d,%d,%s,%s\n", uci->readonly ? "ro" : "rw", uci->devname ? uci->devname : "", str, uci->sectors, uci->surfaces, uci->reserved, uci->blocksize, - uci->bootpri, uci->filesys ? uci->filesys : ""); + uci->bootpri, uci->filesys ? uci->filesys : "", hdcontrollers[uci->controller]); zfile_fputs (f, tmp); sprintf (tmp, "hardfile=%s,%d,%d,%d,%d,%s\n", uci->readonly ? "ro" : "rw", uci->sectors, @@ -1090,7 +1091,7 @@ static struct uaedev_config_info *getuci(struct uae_prefs *p) int add_filesys_config (struct uae_prefs *p, int index, char *devname, char *volname, char *rootdir, int readonly, int secspertrack, int surfaces, int reserved, - int blocksize, int bootpri, char *filesysdir, int flags) { + int blocksize, int bootpri, char *filesysdir, int hdc, int flags) { struct uaedev_config_info *uci; if (index < 0) uci = getuci(p); @@ -1109,6 +1110,7 @@ int add_filesys_config (struct uae_prefs *p, int index, uci->blocksize = blocksize; uci->bootpri = bootpri; uci->configoffset = -1; + uci->controller = hdc; strcpy (uci->filesys, filesysdir ? filesysdir : ""); if (!uci->devname[0]) sprintf(uci->devname,"DH%d", uci - &p->mountconfig[0]); @@ -1353,7 +1355,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu } str = cfgfile_subst_path (UNEXPANDED, p->path_hardfile, root); #ifdef FILESYS - add_filesys_config (p, -1, NULL, aname, str, ro, secs, heads, reserved, bs, 0, NULL, 0); + add_filesys_config (p, -1, NULL, aname, str, ro, secs, heads, reserved, bs, 0, NULL, 0, 0); #endif free (str); return 1; @@ -1363,8 +1365,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu if (strcmp (option, "filesystem2") == 0 || strcmp (option, "hardfile2") == 0) { - int secs, heads, reserved, bs, ro, bp; - char *dname, *aname, *root, *fs; + int secs, heads, reserved, bs, ro, bp, hdcv; + char *dname, *aname, *root, *fs, *hdc; char *tmpp = strchr (value, ','); char *str; @@ -1380,7 +1382,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu else goto invalid_fs; secs = 0; heads = 0; reserved = 0; bs = 0; bp = 0; - fs = 0; + fs = 0; hdc = 0; hdcv = 0; value = tmpp; if (strcmp (option, "filesystem2") == 0) { @@ -1421,13 +1423,21 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu if (getintval2 (&tmpp, &bp, ',')) { fs = tmpp; tmpp = strchr (tmpp, ','); - if (tmpp != 0) - *tmpp = 0; + if (tmpp != 0) { + *tmpp++ = 0; + hdc = tmpp; + if(!strcmp(hdc, "ide0")) + hdcv = 1; + if(!strcmp(hdc, "ide1")) + hdcv = 2; + if (secs > 0 || heads > 0 || reserved > 0) + hdcv = 0; + } } } str = cfgfile_subst_path (UNEXPANDED, p->path_hardfile, root); #ifdef FILESYS - add_filesys_config (p, -1, dname, aname, str, ro, secs, heads, reserved, bs, bp, fs, 0); + add_filesys_config (p, -1, dname, aname, str, ro, secs, heads, reserved, bs, bp, fs, hdcv, 0); #endif free (str); return 1; @@ -1911,7 +1921,7 @@ static void parse_filesys_spec (struct uae_prefs *p, int readonly, char *spec) } #endif #ifdef FILESYS - add_filesys_config (p, -1, NULL, buf, s2, readonly, 0, 0, 0, 0, 0, 0, 0); + add_filesys_config (p, -1, NULL, buf, s2, readonly, 0, 0, 0, 0, 0, 0, 0, 0); #endif } else { write_log ("Usage: [-m | -M] VOLNAME:mount_point\n"); @@ -1940,7 +1950,7 @@ static void parse_hardfile_spec (struct uae_prefs *p, char *spec) goto argh; *x4++ = '\0'; #ifdef FILESYS - add_filesys_config (p, -1, NULL, NULL, x4, 0, atoi (x0), atoi (x1), atoi (x2), atoi (x3), 0, 0, 0); + add_filesys_config (p, -1, NULL, NULL, x4, 0, atoi (x0), atoi (x1), atoi (x2), atoi (x3), 0, 0, 0, 0); #endif free (x0); return; @@ -2666,6 +2676,18 @@ void default_prefs (struct uae_prefs *p, int type) p->cs_compatible = 1; p->cs_rtc = 2; p->cs_df0idhw = 1; + p->cs_a1000ram = 0; + p->cs_fatgaryrev = -1; + p->cs_ramseyrev = -1; + p->cs_agnusrev = -1; + p->cs_deniserev = -1; + p->cs_mbdmac = -1; + p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0; + p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcard = 0; + p->cs_pcmcia = 0; + p->cs_ksmirror = 1; + p->cs_ciaatod = 0; + p->cs_df0idhw = 1; p->gfx_filter = 0; p->gfx_filter_horiz_zoom_mult = 1000; @@ -2866,12 +2888,14 @@ static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck) p->chipset_mask = 0; p->bogomem_size = 0; p->sound_filter = FILTER_SOUND_ON; - if (config == 1) - p->chipmem_size = 0x40000; set_68000_compa (p, compa); p->dfxtype[1] = DRV_NONE; p->cs_compatible = 7; build_in_chipset_prefs (p); + if (config > 0) + p->chipset_mask |= CSMASK_NO_EHB; + if (config > 1) + p->chipmem_size = 0x40000; return configure_rom (p, roms, romcheck); } @@ -3159,6 +3183,7 @@ int build_in_chipset_prefs (struct uae_prefs *p) if (!p->cs_compatible) return 1; + p->chipset_mask &= ~CSMASK_BUGS; p->cs_a1000ram = 0; p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0; p->cs_cdtvcd = p->cs_cdtvram = 0; @@ -3206,6 +3231,7 @@ int build_in_chipset_prefs (struct uae_prefs *p) p->cs_ciaatod = p->ntscmode ? 2 : 1; p->cs_ksmirror = 0; p->cs_rtc = 0; + p->chipset_mask |= CSMASK_BLTBUSY_BUG; break; case 8: // A1200 p->cs_ide = 1; diff --git a/custom.c b/custom.c index e0a8e7d3..a1e855f2 100755 --- a/custom.c +++ b/custom.c @@ -2381,7 +2381,7 @@ STATIC_INLINE uae_u16 DMACONR (void) { uae_u16 v; decide_blitter (current_hpos ()); - v = dmacon | (bltstate == BLT_done ? 0 : 0x4000) + v = dmacon | (bltstate == BLT_done || (bltstate != BLT_done && (currprefs.chipset_mask & CSMASK_BLTBUSY_BUG) && !blt_info.got_cycle) ? 0 : 0x4000) | (blt_info.blitzero ? 0x2000 : 0); return v; } @@ -2413,16 +2413,16 @@ STATIC_INLINE uae_u16 VPOSR (void) int vp = (GETVPOS() >> 8) & 7; if (currprefs.cs_agnusrev >= 0) { - csbit |= currprefs.cs_agnusrev << 8; + csbit |= currprefs.cs_agnusrev << 8; } else { - if (currprefs.ntscmode) - csbit |= 0x1000; #ifdef AGA csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; #endif csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; if (currprefs.chipmem_size > 1024 * 1024 && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) csbit |= 0x2100; + if (currprefs.ntscmode) + csbit |= 0x1000; } if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) @@ -4612,6 +4612,7 @@ void customreset (void) a1000_reset (); DISK_reset (); CIA_reset (); + gayle_reset (0); #ifdef JIT compemu_reset (); #endif diff --git a/drawing.c b/drawing.c index 18e2c010..a551c58a 100755 --- a/drawing.c +++ b/drawing.c @@ -1297,7 +1297,7 @@ static void pfield_expand_dp_bplcon (void) * stuff, and it's set by some demos (e.g. Andromeda Seven Seas) */ bplehb = ((dp_for_drawing->bplcon0 & 0x7010) == 0x6000 && !(dp_for_drawing->bplcon2 & 0x200)); } else { - bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000; + bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000 && !(currprefs.chipset_mask & CSMASK_NO_EHB); } plf1pri = dp_for_drawing->bplcon2 & 7; plf2pri = (dp_for_drawing->bplcon2 >> 3) & 7; diff --git a/filesys.c b/filesys.c index f095ca6a..0c845e53 100755 --- a/filesys.c +++ b/filesys.c @@ -44,6 +44,7 @@ #include "fsdb.h" #include "zfile.h" #include "gui.h" +#include "gayle.h" #include "savestate.h" #define TRACING_ENABLED 0 @@ -107,6 +108,7 @@ typedef struct { int readonly; /* disallow write access? */ int bootpri; /* boot priority */ int devno; + int controller; struct hardfiledata hf; @@ -216,7 +218,8 @@ int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo * hdf_close (&ui->hf); } } else { - mi->ismounted = 1; + if (!ui->controller || (ui->controller && p->cs_ide)) + mi->ismounted = 1; } mi->size = ui->hf.size; mi->nrcyls = (int)(uci->sectors * uci->surfaces ? (ui->hf.size / uci->blocksize) / (uci->sectors * uci->surfaces) : 0); @@ -241,11 +244,13 @@ static void stripsemicolon(char *s) static int set_filesys_unit_1 (int nr, char *devname, char *volname, char *rootdir, int readonly, int secspertrack, int surfaces, int reserved, - int blocksize, int bootpri, char *filesysdir, int flags) + int blocksize, int bootpri, char *filesysdir, int hdc, int flags) { UnitInfo *ui; int i; + if (hdc) + return -1; if (nr < 0) { for (nr = 0; nr < MAX_FILESYSTEM_UNITS; nr++) { if (!mountinfo.ui[nr].open) @@ -346,18 +351,18 @@ err: static int set_filesys_unit (int nr, char *devname, char *volname, char *rootdir, int readonly, int secspertrack, int surfaces, int reserved, - int blocksize, int bootpri, char *filesysdir, int flags) + int blocksize, int bootpri, char *filesysdir, int hdc, int flags) { int ret; ret = set_filesys_unit_1 (nr, devname, volname, rootdir, readonly, - secspertrack, surfaces, reserved, blocksize, bootpri, filesysdir, flags); + secspertrack, surfaces, reserved, blocksize, bootpri, filesysdir, hdc, flags); return ret; } static int add_filesys_unit (char *devname, char *volname, char *rootdir, int readonly, int secspertrack, int surfaces, int reserved, - int blocksize, int bootpri, char *filesysdir, int flags) + int blocksize, int bootpri, char *filesysdir, int hdc, int flags) { int ret; @@ -365,7 +370,7 @@ static int add_filesys_unit (char *devname, char *volname, char *rootdir, int re return -1; ret = set_filesys_unit_1 (-1, devname, volname, rootdir, readonly, - secspertrack, surfaces, reserved, blocksize, bootpri, filesysdir, flags); + secspertrack, surfaces, reserved, blocksize, bootpri, filesysdir, hdc, flags); return ret; } @@ -409,11 +414,15 @@ static void initialize_mountinfo(void) for (i = 0; i < currprefs.mountitems; i++) { int idx; uci = &currprefs.mountconfig[i]; - idx = set_filesys_unit_1 (-1, uci->devname, uci->volname, uci->rootdir, - uci->readonly, uci->sectors, uci->surfaces, uci->reserved, - uci->blocksize, uci->bootpri, uci->filesys, 0); - if (idx >= 0) - uci->configoffset = idx; + if (uci->controller == 0) { + idx = set_filesys_unit_1 (-1, uci->devname, uci->volname, uci->rootdir, + uci->readonly, uci->sectors, uci->surfaces, uci->reserved, + uci->blocksize, uci->bootpri, uci->filesys, 0, 0); + if (idx >= 0) + uci->configoffset = idx; + } else { + gayle_add_ide_unit (uci->controller - 1, uci->rootdir, uci->blocksize, uci->readonly); + } } filesys_addexternals(); } @@ -437,6 +446,7 @@ void free_mountinfo (void) int i; for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) close_filesys_unit (mountinfo.ui + i); + gayle_free_ide_units(); } struct hardfiledata *get_hardfile_data (int nr) @@ -4958,7 +4968,7 @@ uae_u8 *restore_filesys (uae_u8 *src) int type, devno; UnitInfo *ui; char *devname = 0, *volname = 0, *rootdir = 0, *filesysdir = 0; - int bootpri, readonly; + int bootpri, readonly, hdc; if (restore_u32 () != 2) return src; @@ -4977,7 +4987,7 @@ uae_u8 *restore_filesys (uae_u8 *src) src = restore_filesys_hardfile(ui, src); if (set_filesys_unit (devno, devname, volname, rootdir, readonly, ui->hf.secspertrack, ui->hf.surfaces, ui->hf.reservedblocks, ui->hf.blocksize, - bootpri, filesysdir[0] ? filesysdir : NULL, 0) < 0) { + bootpri, filesysdir[0] ? filesysdir : NULL, 0, 0) < 0) { write_log ("filesys '%s' failed to restore\n", rootdir); goto end; } diff --git a/gayle.c b/gayle.c index d528fd18..f0187ce7 100755 --- a/gayle.c +++ b/gayle.c @@ -3,10 +3,11 @@ * * Gayle (and motherboard resources) memory bank * - * (c) 2006 Toni Wilen + * (c) 2006 - 2007 Toni Wilen */ #define GAYLE_LOG 0 +#define IDE_LOG 0 #include "sysconfig.h" #include "sysdeps.h" @@ -17,6 +18,10 @@ #include "custom.h" #include "newcpu.h" #include "gayle.h" +#include "zfile.h" +#include "filesys.h" +#include "savestate.h" +#include "gui.h" /* D80000 to D8FFFF 64 KB SPARE chip select @@ -37,23 +42,34 @@ DE0000 to DEFFFF 64 KB Motherboard resources */ #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ -/* - * Offsets from one of the above bases - */ -#define GAYLE_DATA 0x00 -#define GAYLE_ERROR 0x06 /* see err-bits */ -#define GAYLE_NSECTOR 0x0a /* nr of sectors to read/write */ -#define GAYLE_SECTOR 0x0e /* starting sector */ -#define GAYLE_LCYL 0x12 /* starting cylinder */ -#define GAYLE_HCYL 0x16 /* high byte of starting cyl */ -#define GAYLE_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ -#define GAYLE_STATUS 0x1e /* see status-bits */ -#define GAYLE_CONTROL 0x101a + +#define IDE_DATA 0x00 +#define IDE_ERROR 0x01 /* see err-bits */ +#define IDE_NSECTOR 0x02 /* nr of sectors to read/write */ +#define IDE_SECTOR 0x03 /* starting sector */ +#define IDE_LCYL 0x04 /* starting cylinder */ +#define IDE_HCYL 0x05 /* high byte of starting cyl */ +#define IDE_SELECT 0x06 /* 101dhhhh , d=drive, hhhh=head */ +#define IDE_STATUS 0x07 /* see status-bits */ +#define IDE_DEVCON 0x0406 +#define IDE_DRVADDR 0x0407 + +/* STATUS bits */ +#define IDE_STATUS_ERR 0x01 +#define IDE_STATUS_IDX 0x02 +#define IDE_STATUS_DRQ 0x08 +#define IDE_STATUS_DSC 0x10 +#define IDE_STATUS_DRDY 0x40 +#define IDE_STATUS_BSY 0x80 +/* ERROR bits */ +#define IDE_ERR_ABRT 0x04 + /* * These are at different offsets from the base */ -#define GAYLE_IRQ_4000 0x3020 /* MSB = 1, Harddisk is source of */ -#define GAYLE_IRQ_1200 0x9000 /* interrupt */ +#define GAYLE_IRQ_4000 0x3020 /* MSB = 1, Harddisk is source of interrupt */ +#define GAYLE_IRQ_1200 0x9000 +#define GAYLE_INT_1200 0xA000 /* GAYLE_IRQ bit def */ #define GAYLE_IRQ_IDE 0x80 @@ -68,105 +84,473 @@ DE0000 to DEFFFF 64 KB Motherboard resources #define GAYLE_IRQ_IDEACK1 0x02 #define GAYLE_IRQ_IDEACK0 0x01 -static uae_u8 gayle_irq; +struct ide_hdf +{ + struct hardfiledata hfd; + int cyls, heads, secspertrack; + int cyls_def, heads_def, secspertrack_def; + uae_u64 size; + char *path; + + uae_u8 secbuf[512 * 256]; + int data_offset; + int data_size; + int data_multi; + uae_u8 multiple_mode; + uae_u8 status; +}; + +static struct ide_hdf idedrive[2]; + +static int gayle_id_cnt; +static uae_u8 gayle_irq, gayle_intena; +static uae_u8 ide_select, ide_nsector, ide_sector, ide_lcyl, ide_hcyl, ide_devcon, ide_error, ide_feat; +static int ide_drv; + +STATIC_INLINE pw(int offset, uae_u16 w) +{ + idedrive[ide_drv].secbuf[offset * 2 + 0] = (uae_u8)w; + idedrive[ide_drv].secbuf[offset * 2 + 1] = w >> 8; +} +static void ps(int offset, char *s, int max) +{ + int i, len; + + offset *= 2; + len = strlen(s); + for (i = 0; i < max; i++) { + char c = ' '; + if (i < len) + c = s[i]; + idedrive[ide_drv].secbuf[offset ^ 1] = c; + offset++; + } +} static void ide_interrupt(void) { - gayle_irq |= GAYLE_IRQ_IDE; - INTREQ (0x8000 | 0x0008); + if (gayle_intena & GAYLE_IRQ_IDE) { + gayle_irq |= GAYLE_IRQ_IDE; + INTREQ (0x8000 | 0x0008); + } +} +static void ide_fail(void) +{ + ide_error |= IDE_ERR_ABRT; + if (ide_drv == 1 && idedrive[1].size == 0) + idedrive[0].status |= IDE_STATUS_ERR; + idedrive[ide_drv].status |= IDE_STATUS_ERR; + ide_interrupt(); +} + +static void ide_data_ready(int blocks) +{ + struct ide_hdf *ide = &idedrive[ide_drv]; + + memset(ide->secbuf, 0, 512 * 256); + ide->data_offset = 0; + ide->status |= IDE_STATUS_DRQ; + ide->data_size = blocks * 512; + ide->data_multi = 1; + if (!(ide_devcon & 2)) + ide_interrupt(); +} + +static void ide_recalibrate(void) +{ + write_log("IDE%d recalibrate\n", ide_drv); + ide_sector = 0; + ide_lcyl = ide_hcyl = 0; + ide_interrupt(); +} +static void ide_identify_drive(void) +{ + struct ide_hdf *ide = &idedrive[ide_drv]; + int totalsecs; + int v; + uae_u8 *buf = ide->secbuf; + + if (ide->size == 0) { + ide_fail(); + return; + } + ide_data_ready(1); + pw(0, (1 << 10) | (1 << 6) | (1 << 2) | (1 << 3)); + pw(1, ide->cyls_def); + pw(3, ide->heads_def); + pw(4, 512 * ide->secspertrack_def); + pw(5, 512); + pw(6, ide->secspertrack_def); + ps(10, "68000", 20); /* serial */ + pw(20, 3); + pw(21, 512); + ps(23, "0.1", 8); /* firmware revision */ + ps(27, "UAE-IDE", 40); /* model */ + pw(47, 128); /* max 128 sectors multiple mode */ + pw(48, 1); + pw(49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */ + pw(53, 1); + pw(54, ide->cyls); + pw(55, ide->heads); + pw(56, ide->secspertrack); + totalsecs = ide->cyls * ide->heads * ide->secspertrack; + pw(57, totalsecs); + pw(58, totalsecs >> 16); + v = idedrive[ide_drv].multiple_mode; + pw(59, (v > 0 ? 0x100 : 0) | v); + totalsecs = ide->size / 512; + pw(60, totalsecs); + pw(61, totalsecs >> 16); + pw(62, 0x0f); + pw(63, 0x0f); +} +static void ide_initialize_drive_parameters(void) +{ + struct ide_hdf *ide = &idedrive[ide_drv]; + + if (ide->size) { + ide->secspertrack = ide_nsector; + ide->heads = (ide_select & 15) + 1; + ide->cyls = (ide->size / 512) / (ide->secspertrack * ide->heads); + } else { + ide_error |= IDE_ERR_ABRT; + idedrive[ide_drv].status |= IDE_STATUS_ERR; + } + write_log("IDE%d initialize drive parameters, CYL=%d,SPT=%d,HEAD=%d\n", + ide_drv, ide->cyls, ide->secspertrack, ide->heads); + ide_interrupt(); +} +static void ide_set_multiple_mode(void) +{ + write_log("IDE%d drive multiple mode = %d\n", ide_drv, ide_nsector); + idedrive[ide_drv].multiple_mode = ide_nsector; + ide_interrupt(); +} +static void ide_set_features(void) +{ + write_log("IDE%d set features %02.2X (%02.2X)\n", ide_drv, ide_feat, ide_nsector); + ide_fail(); +} + +static void get_lbachs(struct ide_hdf *ide, int *lba, int *cyl, int *head, int *sec) +{ + if (ide_select & 0x40) { + *lba = ((ide_select & 15) << 24) | (ide_hcyl << 16) | (ide_lcyl << 8) | ide_sector; + } else { + *cyl = (ide_hcyl << 8) | ide_lcyl; + *head = ide_select & 15; + *sec = ide_sector; + *lba = (((*cyl) * ide->heads + (*head)) * ide->secspertrack) + (*sec) - 1; + } +} +static void put_lbachs(struct ide_hdf *ide, int lba, int cyl, int head, int sec, int inc) +{ + if (ide_select & 0x40) { + lba += inc; + ide_select &= ~15; + ide_select |= (lba >> 24) & 15; + ide_hcyl = (lba >> 16) & 0xff; + ide_lcyl = (lba >> 8) & 0xff; + ide_sector = lba & 0xff; + } else { + sec += inc; + while (sec >= ide->secspertrack) { + sec -= ide->secspertrack; + head++; + if (head >= ide->heads) { + head -= ide->heads; + cyl++; + } + } + ide_select &= ~15; + ide_select |= head; + ide_sector = sec; + ide_hcyl = cyl >> 8; + ide_lcyl = (uae_u8)cyl; + } + ide_nsector = 0; +} + +static void ide_read_sectors(int multi) +{ + int cyl, head, sec, nsec, lba; + struct ide_hdf *ide = &idedrive[ide_drv]; + + if (multi && ide->multiple_mode == 0) { + ide_fail(); + return; + } + gui_hd_led (1); + nsec = ide_nsector == 0 ? 256 : ide_nsector; + ide_data_ready(nsec); + get_lbachs(ide, &lba, &cyl, &head, &sec); + if (IDE_LOG > 0) + write_log("IDE read offset=%d, sectors=%d\n", lba, nsec); + if (multi && ide->multiple_mode > nsec) + nsec = ide->multiple_mode; + if (lba * 512 >= ide->size) { + ide_fail(); + return; + } + if (nsec * 512 > ide->size - lba * 512) + nsec = (ide->size - lba * 512) / 512; + hdf_read (&ide->hfd, ide->secbuf, lba * 512, nsec * 512); + put_lbachs(ide, lba, cyl, head, sec, nsec); + ide->data_multi = multi ? ide->multiple_mode : 1; +} +static void ide_write_sectors(int multi) +{ + int cyl, head, sec, nsec, lba; + struct ide_hdf *ide = &idedrive[ide_drv]; + + if (multi && ide->multiple_mode == 0) { + ide_fail(); + return; + } + gui_hd_led (1); + nsec = ide_nsector == 0 ? 256 : ide_nsector; + get_lbachs(ide, &lba, &cyl, &head, &sec); + if (lba * 512 >= ide->size) { + ide_fail(); + return; + } + if (nsec * 512 > ide->size - lba * 512) + nsec = (ide->size - lba * 512) / 512; + ide_data_ready(nsec); + ide->data_multi = multi ? ide->multiple_mode : 1; +} + +static void ide_do_command(uae_u8 cmd) +{ + if (IDE_LOG > 1) + write_log("**** IDE command %02.2X\n", cmd); + idedrive[ide_drv].status &= ~(IDE_STATUS_DRDY | IDE_STATUS_DRQ | IDE_STATUS_ERR); + ide_error = 0; + + if (cmd == 0x10) { /* recalibrate */ + ide_recalibrate(); + } else if (cmd == 0xec) { /* identify drive */ + ide_identify_drive(); + } else if (cmd == 0x91) { /* initialize drive parameters */ + ide_initialize_drive_parameters(); + } else if (cmd == 0xc6) { /* set multiple mode */ + ide_set_multiple_mode(); + } else if (cmd == 0x20 || cmd == 0x21) { /* read sectors */ + ide_read_sectors(0); + } else if (cmd == 0x30 || cmd == 0x31) { /* write sectors */ + ide_write_sectors(0); + } else if (cmd == 0xc4) { /* read multiple */ + ide_read_sectors(1); + } else if (cmd == 0xc5) { /* write multiple */ + ide_write_sectors(1); + } else if (cmd == 0x50) { /* format track (nop) */ + ide_interrupt(); + } else if (cmd == 0xa1) { /* ATAPI identify (IDE HD is not ATAPI) */ + ide_fail(); + } else if (cmd == 0xef) { /* set features */ + ide_set_features(); + } else { + ide_fail(); + write_log("IDE: unknown command %x\n", cmd); + } } -static int ide_read (uaecptr addr, int size) +static uae_u8 ide_get_data(void) { + struct ide_hdf *ide = &idedrive[ide_drv]; + uae_u8 v; + + v = ide->secbuf[ide->data_offset]; + ide->data_offset++; + ide->data_size--; + if (((ide->data_offset % 512) == 0) && ((ide->data_offset / 512) % ide->data_multi) == 0) + ide_interrupt(); + if (ide->data_size == 0) + ide->status &= ~IDE_STATUS_DRQ; + return v; +} +static void ide_put_data(uae_u8 v) +{ + struct ide_hdf *ide = &idedrive[ide_drv]; + if (ide->data_size == 0) + return; + ide->secbuf[ide->data_offset] = v; + ide->data_offset++; + ide->data_size--; + if (((ide->data_offset % 512) == 0) && ((ide->data_offset / 512) % ide->data_multi) == 0) + ide_interrupt(); + if (ide->data_size == 0) { + int lba, cyl, head, sec, nsec; + ide->status &= ~IDE_STATUS_DRQ; + nsec = ide->data_offset / 512; + get_lbachs(ide, &lba, &cyl, &head, &sec); + if (IDE_LOG > 0) + write_log("block=%d, %d bytes written\n", lba, ide->data_offset); + hdf_write(&ide->hfd, ide->secbuf, lba * 512, ide->data_offset); + put_lbachs(ide, lba, cyl, head, sec, nsec); + } +} + +static uae_u32 ide_read (uaecptr addr) +{ + uae_u8 v = 0; addr &= 0xffff; - if (GAYLE_LOG) - write_log ("IDE_READ %08.8X\n", addr); - if (addr == 0x201c) // AR1200 IDE detection hack - return 0; - if (currprefs.cs_ide <= 0) - return 0xffff; - if (addr == GAYLE_IRQ_4000) { - if (currprefs.cs_ide == 2) { - uae_u8 v = gayle_irq; - gayle_irq = 0; - return v; + if (IDE_LOG > 1 && addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200) + write_log ("IDE_READ %08.8X PC=%X\n", addr, M68K_GETPC); + if (currprefs.cs_ide <= 0) { + if (addr == 0x201c) // AR1200 IDE detection hack + return 0; + return 0xff; + } + if (addr >= 0x3020) { + if (addr == GAYLE_IRQ_4000) { + if (currprefs.cs_ide == 2) { + uae_u8 v = gayle_irq; + gayle_irq = 0; + return v; + } + return 0; + } else if (addr == GAYLE_IRQ_1200) { + if (currprefs.cs_ide == 1) + return gayle_irq; + return 0; + } else if (addr == GAYLE_INT_1200) { + if (currprefs.cs_ide == 1) + return gayle_intena; + return 0; } return 0; - } else if (addr == GAYLE_IRQ_1200) { - if (currprefs.cs_ide == 1) - return gayle_irq; - return 0; } if (currprefs.cs_ide == 2 && (addr & 0x2020) == 0x2020) - addr &= ~0x2020; + addr &= ~0x20; + addr &= ~0x2000; + addr >>= 2; + /* Emulated "ide hack". Prevents long KS boot delay if no drives installed */ + if (idedrive[0].size == 0) + return 0xff; switch (addr) { - case GAYLE_DATA: - case GAYLE_ERROR: - case GAYLE_NSECTOR: - case GAYLE_SECTOR: - case GAYLE_LCYL: - case GAYLE_HCYL: - case GAYLE_SELECT: - case GAYLE_STATUS: + case IDE_DRVADDR: + v = 0; + break; + case IDE_DATA: + v = ide_get_data(); + break; + case IDE_ERROR: + v = ide_error; + break; + case IDE_NSECTOR: + v = ide_nsector; + break; + case IDE_SECTOR: + v = ide_sector; + break; + case IDE_LCYL: + v = ide_lcyl; + break; + case IDE_HCYL: + v = ide_hcyl; + break; + case IDE_SELECT: + v = ide_select; + break; + case IDE_DEVCON: + case IDE_STATUS: + if (idedrive[ide_drv].size == 0) { + v = 0; + if (ide_error) + v |= IDE_STATUS_ERR; + } else { + v = idedrive[ide_drv].status; + v |= IDE_STATUS_DRDY; + } break; } - return 0xffff; + if (IDE_LOG > 2 && addr > 0) + write_log("IDE register %d->%02.2X\n", addr, (uae_u32)v & 0xff); + return v; } -static void ide_write (uaecptr addr, uae_u32 val, int size) +static void ide_write (uaecptr addr, uae_u32 val) { addr &= 0xffff; - if (GAYLE_LOG) - write_log ("IDE_WRITE %08.8X=%08.8X (%d)\n", addr, val, size); + if (IDE_LOG > 1) + write_log ("IDE_WRITE %08.8X=%02.2X PC=%X\n", addr, (uae_u32)val & 0xff, M68K_GETPC); if (currprefs.cs_ide <= 0) return; - if (addr == GAYLE_IRQ_1200 && currprefs.cs_ide == 1) { - gayle_irq &= val; - return; + if (currprefs.cs_ide == 1) { + if (addr == GAYLE_IRQ_1200) { + gayle_irq = 0; + return; + } + if (addr == GAYLE_INT_1200) { + gayle_intena = val; + return; + } } + if (addr >= 0x3020) + return; if (currprefs.cs_ide == 2 && (addr & 0x2020) == 0x2020) - addr &= ~0x2020; + addr &= ~0x20; + addr &= ~0x2000; + addr >>= 2; + if (IDE_LOG > 2 && addr > 0) + write_log("IDE register %d=%02.2X\n", addr, (uae_u32)val & 0xff); switch (addr) { - case GAYLE_DATA: - case GAYLE_ERROR: - case GAYLE_NSECTOR: - case GAYLE_SECTOR: - case GAYLE_LCYL: - case GAYLE_HCYL: - case GAYLE_SELECT: - case GAYLE_STATUS: + case IDE_DRVADDR: + break; + case IDE_DEVCON: + ide_devcon = val; + break; + case IDE_DATA: + ide_put_data((uae_u8)val); + break; + case IDE_ERROR: + ide_feat = val; + break; + case IDE_NSECTOR: + ide_nsector = val; + break; + case IDE_SECTOR: + ide_sector = val; + break; + case IDE_LCYL: + ide_lcyl = val; + break; + case IDE_HCYL: + ide_hcyl = val; + break; + case IDE_SELECT: + ide_select = val; + ide_drv = (val & 0x10) ? 1 : 0; + break; + case IDE_STATUS: + ide_do_command (val); break; } } -static int gayle_read (uaecptr addr, int size) +static int gayle_read (uaecptr addr) { + uaecptr oaddr = addr; + uae_u32 v = 0; #ifdef JIT special_mem |= S_READ; #endif + v = ide_read(addr); if (GAYLE_LOG) - write_log ("GAYLE_READ %08.8X PC=%08.8X\n", addr, M68K_GETPC); - addr &= 0xfffff; - if(addr >= 0xa0000 && addr <= 0xaffff) - return ide_read(addr, size); - else if(addr >= 0xd0000 && addr <= 0xdffff) - return ide_read(addr, size); - return 0; + write_log ("GAYLE_READ %08.8X=%02.2X PC=%08.8X\n", oaddr, (uae_u32)v & 0xff, M68K_GETPC); + return v; } -static void gayle_write (uaecptr addr, int val, int size) +static void gayle_write (uaecptr addr, int val) { #ifdef JIT special_mem |= S_WRITE; #endif if (GAYLE_LOG) - write_log ("GAYLE_WRITE %08.8X=%08.8X (%d) PC=%08.8X\n", addr, val, size, M68K_GETPC); - addr &= 0x3ffff; - if(addr >= 0xa0000 && addr <= 0xaffff) - ide_write(addr, val, size); - else if(addr >= 0xd0000 && addr <= 0xdffff) - ide_write(addr, val, size); + write_log ("GAYLE_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, (uae_u32)val & 0xff, M68K_GETPC); + ide_write(addr, val); } static uae_u32 REGPARAM3 gayle_lget (uaecptr) REGPARAM; @@ -179,22 +563,25 @@ static void REGPARAM3 gayle_bput (uaecptr, uae_u32) REGPARAM; addrbank gayle_bank = { gayle_lget, gayle_wget, gayle_bget, gayle_lput, gayle_wput, gayle_bput, - default_xlate, default_check, NULL, "Gayle", + default_xlate, default_check, NULL, "Gayle (low)", dummy_lgeti, dummy_wgeti, ABFLAG_IO }; uae_u32 REGPARAM2 gayle_lget (uaecptr addr) { - addr &= 0xFFFF; - return (uae_u32)(gayle_wget (addr) << 16) + gayle_wget (addr + 2); + uae_u32 v = gayle_wget (addr) << 16; + v |= gayle_wget (addr + 2); + return v; } uae_u32 REGPARAM2 gayle_wget (uaecptr addr) { - return gayle_read (addr, 2); + uae_u16 v = gayle_bget (addr) << 8; + v |= gayle_bget (addr + 1); + return v; } uae_u32 REGPARAM2 gayle_bget (uaecptr addr) { - return gayle_read (addr, 1); + return gayle_read (addr); } void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value) @@ -205,12 +592,81 @@ void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value) void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value) { - gayle_write (addr, value, 2); + gayle_bput (addr, value >> 8); + gayle_bput (addr + 1, value & 0xff); } void REGPARAM2 gayle_bput (uaecptr addr, uae_u32 value) { - gayle_write (addr, value, 1); + gayle_write (addr, value); +} + +void gayle2_write(uaecptr addr, uae_u32 v) +{ + gayle_id_cnt = 0; +} + +uae_u32 gayle2_read(uaecptr addr) +{ + uae_u8 v = 0; + addr &= 0xffff; + if (addr == 0x1000) { + /* Gayle ID */ + if ((gayle_id_cnt & 3) == 2) + v = 0x7f; + else + v = 0x80; + gayle_id_cnt++; + } + return v; +} + +static uae_u32 REGPARAM3 gayle2_lget (uaecptr) REGPARAM; +static uae_u32 REGPARAM3 gayle2_wget (uaecptr) REGPARAM; +static uae_u32 REGPARAM3 gayle2_bget (uaecptr) REGPARAM; +static void REGPARAM3 gayle2_lput (uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 gayle2_wput (uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 gayle2_bput (uaecptr, uae_u32) REGPARAM; + +addrbank gayle2_bank = { + gayle2_lget, gayle2_wget, gayle2_bget, + gayle2_lput, gayle2_wput, gayle2_bput, + default_xlate, default_check, NULL, "Gayle (high)", + dummy_lgeti, dummy_wgeti, ABFLAG_IO +}; + +uae_u32 REGPARAM2 gayle2_lget (uaecptr addr) +{ + uae_u32 v = gayle2_wget (addr) << 16; + v |= gayle2_wget (addr + 2); + return v; +} +uae_u32 REGPARAM2 gayle2_wget (uaecptr addr) +{ + uae_u16 v = gayle2_bget (addr) << 8; + v |= gayle2_bget (addr + 1); + return v; +} +uae_u32 REGPARAM2 gayle2_bget (uaecptr addr) +{ + return gayle2_read (addr); +} + +void REGPARAM2 gayle2_lput (uaecptr addr, uae_u32 value) +{ + gayle2_wput (addr, value >> 16); + gayle2_wput (addr + 2, value & 0xffff); +} + +void REGPARAM2 gayle2_wput (uaecptr addr, uae_u32 value) +{ + gayle2_bput (addr, value >> 8); + gayle2_bput (addr + 1, value & 0xff); +} + +void REGPARAM2 gayle2_bput (uaecptr addr, uae_u32 value) +{ + gayle2_write (addr, value); } static uae_u8 ramsey_config; @@ -280,8 +736,9 @@ static void REGPARAM3 mbres_bput (uaecptr, uae_u32) REGPARAM; uae_u32 REGPARAM2 mbres_lget (uaecptr addr) { - addr &= 0xFFFF; - return (uae_u32)(mbres_wget (addr) << 16) + mbres_wget (addr + 2); + uae_u32 v = mbres_wget (addr) << 16; + v |= mbres_wget (addr + 2); + return v; } uae_u32 REGPARAM2 mbres_wget (uaecptr addr) { @@ -561,8 +1018,83 @@ addrbank mbdmac_bank = { dummy_lgeti, dummy_wgeti, ABFLAG_IO }; +static int rl (uae_u8 *p) +{ + return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]); +} + +void gayle_free_ide_units(void) +{ + int i; + + for (i = 0; i < 2; i++) { + struct ide_hdf *ide = &idedrive[i]; + if (ide->hfd.handle_valid) + hdf_close(&ide->hfd); + xfree(ide->path); + memset(ide, 0, sizeof (struct ide_hdf)); + } +} + +int gayle_add_ide_unit(int ch, char *path, int blocksize, int readonly) +{ + struct ide_hdf *ide; + uae_u8 bufrdb[512]; + int i; + int cyls, secspertrack, heads, tpt; + + if (ch >= 2) + return -1; + ide = &idedrive[ch]; + ide->hfd.readonly = readonly; + ide->hfd.blocksize = blocksize; + if (!hdf_open(&ide->hfd, path)) + return -1; + ide->path = my_strdup(path); + write_log("IDE%d initialized ('%s')\n", ch, path); + cyls = secspertrack = heads = 0; + for (i = 0; i < 64; i++) { + memset(bufrdb, 0, 512); + hdf_read(&ide->hfd, bufrdb, 0, 512); + if (!memcmp(bufrdb, "RDSK", 4)) { + ide->hfd.cylinders = rl (bufrdb + 64); + ide->hfd.sectors = rl (bufrdb + 68); + ide->hfd.heads = rl (bufrdb + 72); + break; + } + } + getchs2(&ide->hfd, &ide->cyls, &tpt, &ide->heads, &ide->secspertrack); + ide->cyls_def = ide->cyls; + ide->secspertrack_def = ide->secspertrack; + ide->heads_def = ide->heads; + ide->size = ide->hfd.size; + write_log("CHS=%d,%d,%d\n", ide->cyls, ide->heads, ide->secspertrack); + + ide->status = 0; + ide->data_offset = 0; + ide->data_size = 0; + return 1; +} + +static void initide(void) +{ + if (savestate_state == STATE_RESTORE) + return; + ide_error = 1; + ide_sector = ide_nsector = 1; + ide_select = 0; + ide_lcyl = ide_hcyl = ide_devcon = ide_feat = 0; + ide_drv = 0; + + gayle_irq = gayle_intena = 0; + if (currprefs.cs_ide == 2) + gayle_intena = 0xff; + +} + void gayle_reset (int hardreset) { + initide(); if (hardreset) { ramsey_config = 0; gary_coldboot = 1; @@ -570,3 +1102,69 @@ void gayle_reset (int hardreset) gary_toenb = 0; } } + +uae_u8 *restore_gayle(uae_u8 *src) +{ + changed_prefs.cs_ide = restore_u8(); + gayle_intena = restore_u8(); + gayle_irq = restore_u8(); + ide_error = 0; + return src; +} + +uae_u8 *save_gayle (int *len) +{ + uae_u8 *dstbak, *dst; + + if (currprefs.cs_ide <= 0) + return NULL; + dstbak = dst = malloc (1000); + save_u8 (currprefs.cs_ide); + save_u8 (gayle_intena); + save_u8 (gayle_irq); + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *save_ide (int num, int *len) +{ + uae_u8 *dstbak, *dst; + struct ide_hdf *ide = &idedrive[num]; + + if (currprefs.cs_ide <= 0) + return NULL; + dstbak = dst = malloc (1000); + save_u32(num); + save_u64(ide->size); + save_u32(ide->hfd.blocksize); + save_u32(ide->hfd.readonly); + save_u8(ide->multiple_mode); + save_u32(ide->cyls); + save_u32(ide->heads); + save_u32(ide->secspertrack); + save_string(ide->path); + *len = dst - dstbak; + return dstbak; +} + +uae_u8 *restore_ide (uae_u8 *src) +{ + int num, readonly, blocksize; + uae_u64 size; + char *path; + struct ide_hdf *ide; + + num = restore_u32(); + ide = &idedrive[num]; + size = restore_u64(); + blocksize = restore_u32(); + readonly = restore_u32(); + ide->multiple_mode = restore_u8(); + ide->cyls = restore_u32(); + ide->heads = restore_u32(); + ide->secspertrack = restore_u32(); + path = restore_string(); + gayle_add_ide_unit (num, path, blocksize, readonly); + xfree(path); + return src; +} diff --git a/hardfile.c b/hardfile.c index 52651add..e0325024 100755 --- a/hardfile.c +++ b/hardfile.c @@ -433,7 +433,7 @@ static uae_u32 REGPARAM2 hardfile_expunge (TrapContext *context) return 0; /* Simply ignore this one... */ } -static void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec) +void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec) { unsigned int total = (unsigned int)(hfd->size / 1024); int heads; diff --git a/include/blitter.h b/include/blitter.h index c51cd06a..36fd4c1b 100755 --- a/include/blitter.h +++ b/include/blitter.h @@ -12,6 +12,7 @@ struct bltinfo { uae_u16 bltadat, bltbdat, bltcdat,bltddat,bltahold,bltbhold,bltafwm,bltalwm; int vblitsize,hblitsize; int bltamod,bltbmod,bltcmod,bltdmod; + int got_cycle; }; extern enum blitter_states { diff --git a/include/custom.h b/include/custom.h index 02ea74fe..90a06c23 100755 --- a/include/custom.h +++ b/include/custom.h @@ -13,6 +13,9 @@ #define CSMASK_ECS_AGNUS 1 #define CSMASK_ECS_DENISE 2 #define CSMASK_AGA 4 +#define CSMASK_BUGS 0x300 +#define CSMASK_NO_EHB 0x100 +#define CSMASK_BLTBUSY_BUG 0x200 uae_u32 get_copper_address(int copno); diff --git a/include/filesys.h b/include/filesys.h index 8ab02557..a3272a9b 100755 --- a/include/filesys.h +++ b/include/filesys.h @@ -55,4 +55,5 @@ extern int hdf_getnumharddrives (void); extern char *hdf_getnameharddrive (int index, int flags); extern int hdf_init (void); extern int isspecialdrive(const char *name); -extern int get_native_path(uae_u32 lock, char *out); \ No newline at end of file +extern int get_native_path(uae_u32 lock, char *out); +extern void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec); diff --git a/include/gayle.h b/include/gayle.h index 1453de9b..95eb0bef 100755 --- a/include/gayle.h +++ b/include/gayle.h @@ -1,3 +1,5 @@ -void gayle_reset(int); -void mbdmac_hsync(void); +extern void gayle_reset(int); +extern void mbdmac_hsync(void); +extern int gayle_add_ide_unit(int, char*, int, int); +extern void gayle_free_ide_units(void); diff --git a/include/memory.h b/include/memory.h index 3090ad4b..cb834fb8 100755 --- a/include/memory.h +++ b/include/memory.h @@ -109,6 +109,7 @@ extern addrbank expamem_bank; extern addrbank fastmem_bank; extern addrbank gfxmem_bank, gfxmem_bankx; extern addrbank gayle_bank; +extern addrbank gayle2_bank; extern addrbank mbres_bank; extern addrbank akiko_bank; extern addrbank mbdmac_bank; diff --git a/include/options.h b/include/options.h index c352fc5e..7dbd19d9 100755 --- a/include/options.h +++ b/include/options.h @@ -64,6 +64,7 @@ struct uaedev_config_info { int reserved; int blocksize; int configoffset; + int controller; }; struct uae_prefs { @@ -320,7 +321,7 @@ extern void cfgfile_backup (const char *path); extern int add_filesys_config (struct uae_prefs *p, int index, char *devname, char *volname, char *rootdir, int readonly, int secspertrack, int surfaces, int reserved, - int blocksize, int bootpri, char *filesysdir, int flags); + int blocksize, int bootpri, char *filesysdir, int hdc, int flags); extern void default_prefs (struct uae_prefs *, int); extern void discard_prefs (struct uae_prefs *, int); diff --git a/include/savestate.h b/include/savestate.h index b57b97d1..ed20b8f3 100755 --- a/include/savestate.h +++ b/include/savestate.h @@ -86,6 +86,11 @@ extern uae_u8 *restore_filesys_common (uae_u8 *src); extern uae_u8 *save_filesys_common (int *len); extern int save_filesys_cando(void); +extern uae_u8 *restore_gayle(uae_u8 *src); +extern uae_u8 *save_gayle (int *len); +extern uae_u8 *restore_ide (uae_u8 *src); +extern uae_u8 *save_ide (int num, int *len); + extern void restore_cram (int, size_t); extern void restore_bram (int, size_t); extern void restore_fram (int, size_t); diff --git a/main.c b/main.c index 7a378bb4..dd1e384e 100755 --- a/main.c +++ b/main.c @@ -330,7 +330,7 @@ void fixup_prefs (struct uae_prefs *p) } if (p->parallel_postscript_emulation) p->parallel_postscript_detection = 1; - if (p->cs_compatible) { + if (p->cs_compatible == 1) { p->cs_fatgaryrev = p->cs_ramseyrev = p->cs_mbdmac = -1; p->cs_ide = 0; if (p->cpu_model >= 68020) { diff --git a/memory.c b/memory.c index d51e7362..91874004 100755 --- a/memory.c +++ b/memory.c @@ -2318,15 +2318,20 @@ void memory_reset (void) t = 0x10; map_banks (&bogomem_bank, 0xC0, t, 0); } - if (currprefs.cs_ide) + if (currprefs.cs_ide) { map_banks (&gayle_bank, 0xD8, 6, 0); + if(currprefs.cs_ide == 1) + map_banks (&gayle2_bank, 0xDD, 2, 0); + else if (currprefs.cs_ide == 2) + map_banks (&gayle_bank, 0xDD, 2, 0); + } if (currprefs.cs_rtc) map_banks (&clock_bank, 0xDC, 1, 0); if (currprefs.cs_fatgaryrev >= 0|| currprefs.cs_ramseyrev >= 0) map_banks (&mbres_bank, 0xDE, 1, 0); if (currprefs.cs_cd32c2p || currprefs.cs_cd32cd || currprefs.cs_cd32nvram) map_banks (&akiko_bank, AKIKO_BASE >> 16, 1, 0); - if (currprefs.cs_mbdmac >= 0) + if (currprefs.cs_mbdmac >= 0 && currprefs.cs_ide <= 0) map_banks (&mbdmac_bank, 0xDD, 1, 0); if (a3000lmemory != 0) map_banks (&a3000lmem_bank, a3000lmem_start >> 16, allocated_a3000lmem >> 16, 0); diff --git a/newcpu.c b/newcpu.c index 28187fd4..4cce579f 100755 --- a/newcpu.c +++ b/newcpu.c @@ -137,8 +137,10 @@ static void set_cpu_caches(void) #ifdef JIT if (currprefs.cpu_model < 68040) { set_cache_state(cacr & 1); - if (cacr & 0x08) + if (cacr & 0x08) { + cacr &= ~0x08; flush_icache(1); + } } else { set_cache_state(cacr & 0x8000); } @@ -1180,13 +1182,13 @@ int m68k_move2c (int regno, uae_u32 *regp) { uae_u32 cacr_mask = 0; if (currprefs.cpu_model == 68020) - cacr_mask = 0x00000003; + cacr_mask = 0x0000000f; else if (currprefs.cpu_model == 68030) - cacr_mask = 0x00003313; + cacr_mask = 0x00003f1f; else if (currprefs.cpu_model == 68040) cacr_mask = 0x80008000; else if (currprefs.cpu_model == 68060) - cacr_mask = 0xf880e000; + cacr_mask = 0xf8e0e000; cacr = *regp & cacr_mask; set_cpu_caches(); } @@ -1245,7 +1247,21 @@ int m68k_movec2 (int regno, uae_u32 *regp) switch (regno) { case 0: *regp = regs.sfc; break; case 1: *regp = regs.dfc; break; - case 2: *regp = cacr; break; + case 2: + { + uae_u32 v = cacr; + uae_u32 cacr_mask = 0; + if (currprefs.cpu_model == 68020) + cacr_mask = 0x00000003; + else if (currprefs.cpu_model == 68030) + cacr_mask = 0x00003313; + else if (currprefs.cpu_model == 68040) + cacr_mask = 0x80008000; + else if (currprefs.cpu_model == 68060) + cacr_mask = 0xf880e000; + *regp = v & cacr_mask; + } + break; case 3: *regp = tcr; break; case 4: *regp = itt0; break; case 5: *regp = itt1; break; diff --git a/od-win32/parser.c b/od-win32/parser.c index d6261129..25c9eed3 100755 --- a/od-win32/parser.c +++ b/od-win32/parser.c @@ -550,9 +550,11 @@ int uaeser_setparams (struct uaeserialdatawin32 *sd, int baud, int rbuffer, int if (!GetCommState (sd->hCom, &dcb)) return 5; + dcb.fBinary = TRUE; dcb.BaudRate = baud; dcb.ByteSize = bits; dcb.Parity = parity == 0 ? NOPARITY : (parity == 1 ? ODDPARITY : EVENPARITY); + dcb.fParity = FALSE; dcb.StopBits = sbits == 1 ? ONESTOPBIT : TWOSTOPBITS; dcb.fDsrSensitivity = FALSE; @@ -568,11 +570,11 @@ int uaeser_setparams (struct uaeserialdatawin32 *sd, int baud, int rbuffer, int } dcb.fTXContinueOnXoff = FALSE; - dcb.XonChar = (xonxoff >> 8) & 0xff; - dcb.XoffChar = (xonxoff >> 16) & 0xff; if (xonxoff & 1) { dcb.fOutX = TRUE; dcb.fInX = TRUE; + dcb.XonChar = (xonxoff >> 8) & 0xff; + dcb.XoffChar = (xonxoff >> 16) & 0xff; } else { dcb.fOutX = FALSE; dcb.fInX = FALSE; @@ -582,8 +584,8 @@ int uaeser_setparams (struct uaeserialdatawin32 *sd, int baud, int rbuffer, int dcb.fNull = FALSE; dcb.fAbortOnError = FALSE; - dcb.XoffLim = 512; - dcb.XonLim = 2048; + //dcb.XoffLim = 512; + //dcb.XonLim = 2048; if (!SetCommState (sd->hCom, &dcb)) { write_log("uaeserial: SetCommState() failed %d\n", GetLastError()); @@ -793,7 +795,7 @@ int openser (char *sername) } SetCommMask (hCom, EV_RXFLAG); - SetupComm (hCom, 65536,128); + SetupComm (hCom, 65536, 128); PurgeComm (hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; @@ -805,9 +807,11 @@ int openser (char *sername) dcb.DCBlength = sizeof (DCB); GetCommState (hCom, &dcb); + dcb.fBinary = TRUE; dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; + dcb.fParity = FALSE; dcb.StopBits = ONESTOPBIT; dcb.fDsrSensitivity = FALSE; @@ -830,8 +834,8 @@ int openser (char *sername) dcb.fNull = FALSE; dcb.fAbortOnError = FALSE; - dcb.XoffLim = 512; - dcb.XonLim = 2048; + //dcb.XoffLim = 512; + //dcb.XonLim = 2048; if (SetCommState (hCom, &dcb)) { write_log ("SERIAL: Using %s CTS/RTS=%d\n", sername, currprefs.serial_hwctsrts); diff --git a/od-win32/resources/resource b/od-win32/resources/resource index d9beb8cd..b3d44a6c 100755 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -368,9 +368,6 @@ #define IDC_CPU3 1203 #define IDC_CPU4 1204 #define IDC_CPU5 1205 -#define IDC_FPU1 1206 -#define IDC_FPU2 1207 -#define IDC_FPU3 1208 #define IDC_CS_HOST 1209 #define IDC_CS_68000 1210 #define IDC_CS_ADJUSTABLE 1211 @@ -389,6 +386,10 @@ #define IDC_FASTERRTG 1221 #define IDC_COMPATIBLE24 1222 #define IDC_SPEED 1223 +#define IDC_FPU0 1224 +#define IDC_FPU1 1225 +#define IDC_FPU2 1226 +#define IDC_FPU3 1227 #define IDC_SOUNDSETTINGS 1229 #define IDC_8BIT 1230 #define IDC_16BIT 1231 @@ -518,6 +519,7 @@ #define IDC_HF_CREATE 1502 #define IDC_SOCKETS 1503 #define IDC_HF_DOSTYPE 1503 +#define IDC_HDF_CONTROLLER 1504 #define IDC_RESETAMIGA 1504 #define IDC_QUITEMU 1505 #define IDC_TEST16BIT 1506 diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 5928a30c..b3d44a6c 100755 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -519,6 +519,7 @@ #define IDC_HF_CREATE 1502 #define IDC_SOCKETS 1503 #define IDC_HF_DOSTYPE 1503 +#define IDC_HDF_CONTROLLER 1504 #define IDC_RESETAMIGA 1504 #define IDC_QUITEMU 1505 #define IDC_TEST16BIT 1506 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 856926fc..922444f1 100755 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -435,16 +435,16 @@ BEGIN PUSHBUTTON "...",IDC_FILESYS_SELECTOR,271,34,11,15 RTEXT "Device:",IDC_HARDFILE_DEVICE_TEXT,17,58,31,10 EDITTEXT IDC_HARDFILE_DEVICE,52,54,40,15,ES_AUTOHSCROLL - RTEXT "Boot priority:",IDC_HARDFILE_BOOTPRI_TEXT,15,101,44,8 - EDITTEXT IDC_HARDFILE_BOOTPRI,65,96,40,15 + RTEXT "Boot priority:",IDC_HARDFILE_BOOTPRI_TEXT,24,79,44,8 + EDITTEXT IDC_HARDFILE_BOOTPRI,74,75,40,15 CONTROL "Read/write",IDC_RW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,57,50,10 PUSHBUTTON "Enable RDB mode",IDC_HDF_RDB,192,55,92,14 - RTEXT "Surfaces:",IDC_SURFACES_TEXT,112,79,30,10 - EDITTEXT IDC_HEADS,147,75,35,15,ES_NUMBER + RTEXT "Surfaces:",IDC_SURFACES_TEXT,120,79,30,10 + EDITTEXT IDC_HEADS,155,75,35,15,ES_NUMBER RTEXT "Reserved:",IDC_RESERVED_TEXT,197,79,35,10 EDITTEXT IDC_RESERVED,237,75,35,15,ES_NUMBER - RTEXT "Sectors:",IDC_SECTORS_TEXT,112,101,30,10 - EDITTEXT IDC_SECTORS,147,96,35,15,ES_NUMBER + RTEXT "Sectors:",IDC_SECTORS_TEXT,120,101,30,10 + EDITTEXT IDC_SECTORS,155,96,35,15,ES_NUMBER RTEXT "Block size:",IDC_BLOCKSIZE_TEXT,197,101,35,10 EDITTEXT IDC_BLOCKSIZE,237,96,35,15,ES_NUMBER GROUPBOX "New hard disk image file",IDC_STATIC,10,120,280,62 @@ -453,10 +453,11 @@ BEGIN PUSHBUTTON "OK",IDOK,102,191,50,14 PUSHBUTTON "Cancel",IDCANCEL,158,191,50,14 EDITTEXT IDC_HF_DOSTYPE,146,158,61,15 - COMBOBOX IDC_HF_TYPE,50,158,80,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_HDF_CONTROLLER,73,97,41,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP RTEXT "DOS type",IDC_STATIC,214,160,32,10,SS_CENTERIMAGE RTEXT "MB",IDC_STATIC,214,138,13,10,SS_CENTERIMAGE RTEXT "Type:",IDC_STATIC,18,160,25,10,SS_CENTERIMAGE + RTEXT "HD Controller:",IDC_STATIC,13,98,52,10,SS_CENTERIMAGE END IDD_FILESYS DIALOGEX 15, 25, 299, 111 @@ -562,10 +563,10 @@ BEGIN CONTROL "Motherboard Super DMAC",IDC_CS_DMAC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,227,118,10 CONTROL "Compatible Settings",IDC_CS_COMPATIBLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,21,234,10 CONTROL "DF0: ID Hardware",IDC_CS_DF0IDHW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,128,92,10 - CONTROL "Agnus/Alice revision:",IDC_CS_AGNUS,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,150,201,81,10 - EDITTEXT IDC_CS_AGNUSREV,235,199,45,13,ES_AUTOHSCROLL | NOT WS_VISIBLE - CONTROL "Denise/Lisa revision:",IDC_CS_DENISE,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,150,214,81,10 - EDITTEXT IDC_CS_DENISEREV,235,213,45,13,ES_AUTOHSCROLL | NOT WS_VISIBLE + CONTROL "Agnus/Alice revision:",IDC_CS_AGNUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,201,81,10 + EDITTEXT IDC_CS_AGNUSREV,235,199,45,13,ES_AUTOHSCROLL + CONTROL "Denise/Lisa revision:",IDC_CS_DENISE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,217,81,10 + EDITTEXT IDC_CS_DENISEREV,235,216,45,13,ES_AUTOHSCROLL END IDD_AVIOUTPUT DIALOGEX 0, 0, 288, 203 @@ -1229,7 +1230,7 @@ BEGIN IDS_QS_MODEL_A500 "1.3 ROM, OCS, 512 KB Chip + 512 KB Slow RAM (most common)\nThis configuration is capable of running most games and demos produced for first-generation hardware. Only few exceptions need a different configuration (e.g. the oldest games tend to be incompatible with this configuration).\n1.3 ROM, ECS Agnus, 512 KB Chip RAM + 512 KB Slow RAM\nLater hardware revision of the A500. Nearly 100% compatible with the previous configuration.\n1.3 ROM, ECS Agnus, 1 MB Chip RAM\nFew newer games and demos require this configuration.\n1.3 ROM, OCS Agnus, 512 KB Chip RAM\nVery old (e.g. pre-1988) games and demos may require this configuration.\n1.2 ROM, OCS Agnus, 512 KB Chip RAM\nAs available for the A1000, and installed on the first A500 and A2000 series. Some very old programs only work correctly with this configuration. Note: This system ROM version can only boot from floppy disk (no hard disk boot support).\n1.2 ROM, OCS Agnus, 512 KB Chip RAM + 512 KB Slow RAM\nThis configuration adds expansion memory to the first A500 produced. Try this if your game does not work with newer configurations, but works with the previous one. It could add some features to the game, including faster loading times. Note: This system ROM version can only boot from floppy disk (no hard disk boot support)." IDS_QS_MODEL_A500P "Basic non-expanded configuration\nThe A500+ adds an ECS Agnus chip, 1 MB of Chip RAM and a 2.0 ROM to the A500. Many A500 games and demos don't work properly on an A500+.\n2 MB Chip RAM expanded configuration\n\n4 MB Fast RAM expanded configuration\n" IDS_QS_MODEL_A600 "Basic non-expanded configuration\nThe A600 is smaller than the A500+ and has an updated 2.0 ROM.\n2 MB Chip RAM expanded configuration\n\n4 MB Fast RAM expanded configuration\n" - IDS_QS_MODEL_A1000 "512 KB Chip RAM\nThe A1000 was the first model produced, with a configuration equivalent to that of an A500 with OCS chipset. You normally don't need to use this configuration, unless you are nostalgic and would like to hear the short A1000 boot tune\n256 KB Chip RAM\nUnexpanded A1000. All later A1000 models were sold with a 256 KB RAM expansion built-in." + IDS_QS_MODEL_A1000 "512 KB Chip RAM\nThe A1000 was the first model produced, with a configuration equivalent to that of an A500 with OCS chipset. You normally don't need to use this configuration, unless you are nostalgic and would like to hear the short A1000 boot tune\n""ICS"" Denise without EHB support\nVery first A1000 models had Denise without EHB capability.\n256 KB Chip RAM\n Unexpanded A1000. All later A1000 models were sold with a 256 KB RAM expansion built-in." IDS_QS_MODEL_A1200 "Basic non-expanded configuration\nUse this configuration to run most AGA demos and games\n4 MB Fast RAM expanded configuration\nSome newer AGA games and demos need an expanded A1200 to run." IDS_QS_MODEL_CD32 "CD32\nThe CD32 was one the first 32-bit consoles on the market. It is basically an A1200 with a built-in CD-ROM drive. Insert your CD32 or CDTV CD-ROM into a free CD-ROM drive before starting the emulation." IDS_QS_MODEL_CDTV "CDTV\nThe CDTV was the first model with a built-in CD-ROM drive. Looking like a black CD player, it featured a configuration equivalent to that of an A500 with 1 MB RAM and an ECS chipset.\nFloppy drive and 64KB SRAM card expanded CDTV\n" diff --git a/od-win32/win32.h b/od-win32/win32.h index bbd359fe..b72e99ad 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,9 +15,9 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEBETA 4 +#define WINUAEBETA 5 #define WINUAEPUBLICBETA 1 -#define WINUAEDATE MAKEBD(2007, 4, 6) +#define WINUAEDATE MAKEBD(2007, 4, 8) #define IHF_WINDOWHIDDEN 6 #define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU) diff --git a/od-win32/win32_filesys.c b/od-win32/win32_filesys.c index 2c7ecbd0..f3601b40 100755 --- a/od-win32/win32_filesys.c +++ b/od-win32/win32_filesys.c @@ -119,7 +119,7 @@ static void filesys_addexternals(void) else strcat(volumepath, ".."); add_filesys_unit (0, volumename, volumepath, - 0, 0, 0, 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0, 0, 0, 0); } /* if drivemask */ dwDriveMask >>= 1; } diff --git a/od-win32/win32_scale2x.c b/od-win32/win32_scale2x.c index f752c63f..6113b801 100755 --- a/od-win32/win32_scale2x.c +++ b/od-win32/win32_scale2x.c @@ -64,6 +64,7 @@ void S2X_init (int dw, int dh, int aw, int ah, int mult, int ad, int dd) usedfilter = &uaefilters[0]; mult = 1; } else if (mult) { + flags = usedfilter->x[mult]; if ((ad == 16 && !(flags & UAE_FILTER_MODE_16)) || (ad == 32 && !(flags & UAE_FILTER_MODE_32))) { usedfilter = &uaefilters[0]; mult = 1; diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 5ce5bcd8..eeed1807 100755 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -2077,7 +2077,7 @@ static BOOL doInit (void) } //If screen depth is equal to the desired window_depth then no overlay is needed. - if (!(currentmode->flags & (DM_OPENGL | DM_D3D)) && DirectDraw_GetSurfaceBitCount() == (unsigned)currentmode->current_depth) { + if (!(currentmode->flags & (DM_OPENGL | DM_D3D)) && DirectDraw_GetSurfaceBitCount() == currentmode->current_depth) { write_log ("ignored overlay because desktop depth == requested depth (%d)\n", currentmode->current_depth); modefallback (DM_OVERLAY); updatemodes (); diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 8646c24a..fb7e222f 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -1981,12 +1981,17 @@ void InitializeListView (HWND hDlg) else sprintf (size_str, "%.1fM", ((double)(uae_u32)(mi.size / (1024))) / 1024.0); - if (type == FILESYS_HARDFILE) { + if (uci->controller) { + sprintf (blocksize_str, "%d", uci->blocksize); + strcpy (devname_str, uci->controller == 1 ? "*IDE0*" : "*IDE1*"); + strcpy (volname_str, "n/a"); + strcpy (bootpri_str, "n/a"); + } else if (type == FILESYS_HARDFILE) { sprintf (blocksize_str, "%d", uci->blocksize); strcpy (devname_str, uci->devname); strcpy (volname_str, "n/a"); sprintf (bootpri_str, "%d", uci->bootpri); - } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE) { + } else if (type == FILESYS_HARDFILE_RDB || type == FILESYS_HARDDRIVE || uci->controller) { sprintf (blocksize_str, "%d", uci->blocksize); strcpy (devname_str, "n/a"); strcpy (volname_str, "n/a"); @@ -1998,13 +2003,12 @@ void InitializeListView (HWND hDlg) strcpy (size_str, "n/a"); sprintf (bootpri_str, "%d", uci->bootpri); } - if (uci->readonly) - WIN32GUI_LoadUIString (IDS_NO, readwrite_str, sizeof (readwrite_str)); - else - WIN32GUI_LoadUIString (IDS_YES, readwrite_str, sizeof (readwrite_str)); + WIN32GUI_LoadUIString (uci->readonly ? IDS_NO : IDS_YES, readwrite_str, sizeof (readwrite_str)); lvstruct.mask = LVIF_TEXT | LVIF_PARAM; lvstruct.pszText = nosize ? "X" : (mi.ismounted ? "*" : " "); + if (uci->controller) + lvstruct.pszText = " "; lvstruct.lParam = 0; lvstruct.iItem = i; lvstruct.iSubItem = 0; @@ -4228,7 +4232,7 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM workprefs.cs_ramseyrev = IsDlgButtonChecked (hDlg, IDC_CS_RAMSEY) ? 0x0f : -1; workprefs.cs_fatgaryrev = IsDlgButtonChecked (hDlg, IDC_CS_FATGARY) ? 0x00 : -1; workprefs.cs_mbdmac = IsDlgButtonChecked (hDlg, IDC_CS_DMAC) ? 0x00 : -1; - workprefs.cs_ide = (IsDlgButtonChecked (hDlg, IDC_CS_IDE1) ? 1 : 0) | (IsDlgButtonChecked (hDlg, IDC_CS_IDE2) ? 2 : 0); + workprefs.cs_ide = IsDlgButtonChecked (hDlg, IDC_CS_IDE1) ? 1 : (IsDlgButtonChecked (hDlg, IDC_CS_IDE2) ? 2 : 0); workprefs.cs_ciaatod = IsDlgButtonChecked (hDlg, IDC_CS_CIAA_TOD1) ? 0 : (IsDlgButtonChecked (hDlg, IDC_CS_CIAA_TOD2) ? 1 : 2); workprefs.cs_rtc = IsDlgButtonChecked (hDlg, IDC_CS_RTC1) ? 0 @@ -5847,6 +5851,7 @@ struct hfdlg_vals int rw; int rdb; int bootpri; + int controller; }; static struct hfdlg_vals empty_hfdlg = { "", "", "", "", 32, 2, 1, 0, 512, 1, 0, 0 }; @@ -5860,7 +5865,7 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPITEMIDLIST browse; char szTitle[MAX_DPATH]; - WIN32GUI_LoadUIString( IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH ); + WIN32GUI_LoadUIString(IDS_SELECTFILESYSROOT, szTitle, MAX_DPATH); browse_info.hwndOwner = hDlg; browse_info.pidlRoot = NULL; @@ -5928,13 +5933,18 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, GetDlgItemText (hDlg, IDC_VOLUME_NAME, current_fsvdlg.volume, sizeof current_fsvdlg.volume); GetDlgItemText (hDlg, IDC_VOLUME_DEVICE, current_fsvdlg.device, sizeof current_fsvdlg.device); current_fsvdlg.rw = IsDlgButtonChecked (hDlg, IDC_RW); - current_fsvdlg.bootpri = GetDlgItemInt( hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE ); + current_fsvdlg.bootpri = GetDlgItemInt(hDlg, IDC_VOLUME_BOOTPRI, NULL, TRUE); recursive--; break; } return FALSE; } +STATIC_INLINE int is_hdf_rdb(void) +{ + return current_hfdlg.sectors == 0 && current_hfdlg.surfaces == 0 && current_hfdlg.reserved == 0; +} + static void sethardfile (HWND hDlg) { SetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.filename); @@ -5946,8 +5956,8 @@ static void sethardfile (HWND hDlg) SetDlgItemInt (hDlg, IDC_BLOCKSIZE, current_hfdlg.blocksize, FALSE); SetDlgItemInt (hDlg, IDC_HARDFILE_BOOTPRI, current_hfdlg.bootpri, TRUE); CheckDlgButton (hDlg, IDC_RW, current_hfdlg.rw); - ew (hDlg, IDC_HDF_RDB, - !(current_hfdlg.sectors == 0 && current_hfdlg.surfaces == 0 && current_hfdlg.reserved == 0)); + ew (hDlg, IDC_HDF_RDB, !is_hdf_rdb()); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, current_hfdlg.controller, 0); } static void inithardfile (HWND hDlg) @@ -5956,6 +5966,12 @@ static void inithardfile (HWND hDlg) ew (hDlg, IDC_HF_DOSTYPE, FALSE); ew (hDlg, IDC_HF_CREATE, FALSE); + SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"UAE"); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"IDE0"); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"IDE1"); + SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, 0, 0); + ew (hDlg, IDC_HDF_CONTROLLER, is_hdf_rdb()); SendDlgItemMessage(hDlg, IDC_HF_TYPE, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_HF_FS_CUSTOM, tmp, sizeof (tmp)); SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)"OFS/FFS/RDB"); @@ -5994,7 +6010,7 @@ static void hardfile_testrdb (HWND hDlg) static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive = 0; - LRESULT res; + LRESULT res, posn; switch (msg) { case WM_INITDIALOG: @@ -6041,17 +6057,18 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam DiskSelection (hDlg, IDC_PATH_NAME, 2, &workprefs, 0); GetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.filename, sizeof current_hfdlg.filename); hardfile_testrdb (hDlg); + inithardfile(hDlg); break; case IDC_FILESYS_SELECTOR: DiskSelection (hDlg, IDC_PATH_FILESYS, 12, &workprefs, 0); break; case IDOK: - if( strlen(current_hfdlg.filename) == 0 ) + if(strlen(current_hfdlg.filename) == 0 ) { char szMessage[MAX_DPATH]; char szTitle[MAX_DPATH]; - WIN32GUI_LoadUIString( IDS_MUSTSELECTFILE, szMessage, MAX_DPATH ); - WIN32GUI_LoadUIString( IDS_SETTINGSERROR, szTitle, MAX_DPATH ); + WIN32GUI_LoadUIString(IDS_MUSTSELECTFILE, szMessage, MAX_DPATH); + WIN32GUI_LoadUIString(IDS_SETTINGSERROR, szTitle, MAX_DPATH); MessageBox( hDlg, szMessage, szTitle, MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND); @@ -6079,11 +6096,14 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam GetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.filename, sizeof current_hfdlg.filename); GetDlgItemText (hDlg, IDC_PATH_FILESYS, current_hfdlg.fsfilename, sizeof current_hfdlg.fsfilename); GetDlgItemText (hDlg, IDC_HARDFILE_DEVICE, current_hfdlg.devicename, sizeof current_hfdlg.devicename); - current_hfdlg.sectors = GetDlgItemInt( hDlg, IDC_SECTORS, NULL, FALSE ); - current_hfdlg.reserved = GetDlgItemInt( hDlg, IDC_RESERVED, NULL, FALSE ); - current_hfdlg.surfaces = GetDlgItemInt( hDlg, IDC_HEADS, NULL, FALSE ); - current_hfdlg.blocksize = GetDlgItemInt( hDlg, IDC_BLOCKSIZE, NULL, FALSE ); - current_hfdlg.bootpri = GetDlgItemInt( hDlg, IDC_HARDFILE_BOOTPRI, NULL, TRUE ); + current_hfdlg.sectors = GetDlgItemInt(hDlg, IDC_SECTORS, NULL, FALSE); + current_hfdlg.reserved = GetDlgItemInt(hDlg, IDC_RESERVED, NULL, FALSE); + current_hfdlg.surfaces = GetDlgItemInt(hDlg, IDC_HEADS, NULL, FALSE); + current_hfdlg.blocksize = GetDlgItemInt(hDlg, IDC_BLOCKSIZE, NULL, FALSE); + current_hfdlg.bootpri = GetDlgItemInt(hDlg, IDC_HARDFILE_BOOTPRI, NULL, TRUE); + posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_GETCURSEL, 0, 0); + if (posn != CB_ERR) + current_hfdlg.controller = posn; recursive--; break; @@ -6111,8 +6131,9 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara ew (hDlg, IDC_RW, FALSE); index = -1; for (i = 0; i < hdf_getnumharddrives(); i++) { - SendDlgItemMessage( hDlg, IDC_HARDDRIVE, CB_ADDSTRING, 0, (LPARAM)hdf_getnameharddrive(i, 1)); - if (!strcmp (current_hfdlg.filename, hdf_getnameharddrive (i, 0))) index = i; + SendDlgItemMessage(hDlg, IDC_HARDDRIVE, CB_ADDSTRING, 0, (LPARAM)hdf_getnameharddrive(i, 1)); + if (!strcmp (current_hfdlg.filename, hdf_getnameharddrive (i, 0))) + index = i; } if (index >= 0) SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_SETCURSEL, index, 0); @@ -6124,7 +6145,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara break; recursive++; posn = SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_GETCURSEL, 0, 0); - if (oposn != posn) { + if (oposn != posn && posn != CB_ERR) { oposn = posn; if (posn >= 0) { ew (hDlg, IDC_HARDDRIVE_IMAGE, TRUE); @@ -6160,7 +6181,7 @@ static void new_filesys (HWND hDlg) int result; result = add_filesys_config (&workprefs, -1, current_fsvdlg.device, current_fsvdlg.volume, - current_fsvdlg.rootdir, ! current_fsvdlg.rw, 0, 0, 0, 0, current_fsvdlg.bootpri, 0, 0); + current_fsvdlg.rootdir, ! current_fsvdlg.rw, 0, 0, 0, 0, current_fsvdlg.bootpri, 0, 0, 0); } @@ -6172,7 +6193,8 @@ static void new_hardfile (HWND hDlg) current_hfdlg.filename, ! current_hfdlg.rw, current_hfdlg.sectors, current_hfdlg.surfaces, current_hfdlg.reserved, current_hfdlg.blocksize, - current_hfdlg.bootpri, current_hfdlg.fsfilename, 0); + current_hfdlg.bootpri, current_hfdlg.fsfilename, + current_hfdlg.controller, 0); } static void new_harddrive (HWND hDlg) @@ -6181,7 +6203,7 @@ static void new_harddrive (HWND hDlg) result = add_filesys_config (&workprefs, -1, 0, 0, current_hfdlg.filename, ! current_hfdlg.rw, 0, 0, - 0, current_hfdlg.blocksize, 0, 0, 0); + 0, current_hfdlg.blocksize, 0, 0, current_hfdlg.controller, 0); } static void harddisk_remove (HWND hDlg) @@ -6222,6 +6244,7 @@ static void harddisk_edit (HWND hDlg) current_hfdlg.reserved = uci->reserved; current_hfdlg.cylinders = mi.nrcyls; current_hfdlg.blocksize = uci->blocksize; + current_hfdlg.controller = uci->controller; strncpy (current_hfdlg.filename, uci->rootdir, (sizeof current_hfdlg.filename) - 1); current_hfdlg.filename[(sizeof current_hfdlg.filename) - 1] = '\0'; @@ -6241,7 +6264,8 @@ static void harddisk_edit (HWND hDlg) { int result = add_filesys_config (&workprefs, entry, current_hfdlg.devicename, 0, current_hfdlg.filename, ! current_hfdlg.rw, current_hfdlg.sectors, current_hfdlg.surfaces, - current_hfdlg.reserved, current_hfdlg.blocksize, current_hfdlg.bootpri, current_hfdlg.fsfilename, 0); + current_hfdlg.reserved, current_hfdlg.blocksize, current_hfdlg.bootpri, + current_hfdlg.fsfilename, current_hfdlg.controller, 0); } } else if (type == FILESYS_HARDDRIVE) /* harddisk */ @@ -6253,7 +6277,8 @@ static void harddisk_edit (HWND hDlg) { int result = add_filesys_config (&workprefs, entry, 0, 0, current_hfdlg.filename, ! current_hfdlg.rw, 0, 0, - 0, current_hfdlg.blocksize, current_hfdlg.bootpri, 0, 0); + 0, current_hfdlg.blocksize, current_hfdlg.bootpri, 0, + current_hfdlg.controller, 0); } } else /* Filesystem */ @@ -6271,7 +6296,7 @@ static void harddisk_edit (HWND hDlg) current_fsvdlg.bootpri = uci->bootpri; if (CustomDialogBox(IDD_FILESYS, hDlg, VolumeSettingsProc)) { int result = add_filesys_config (&workprefs, entry, current_fsvdlg.device, current_fsvdlg.volume, - current_fsvdlg.rootdir, ! current_fsvdlg.rw, 0, 0, 0, 0, current_fsvdlg.bootpri, 0, 0); + current_fsvdlg.rootdir, ! current_fsvdlg.rw, 0, 0, 0, 0, current_fsvdlg.bootpri, 0, 0, 0); } } } @@ -9333,10 +9358,10 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) if (currentpage == HARDDISK_ID) { if (flags & FILE_ATTRIBUTE_DIRECTORY) { add_filesys_config (&workprefs, -1, NULL, "XXX", file, 0, - 0, 0, 0, 0, 0, NULL, 0); + 0, 0, 0, 0, 0, NULL, 0, 0); } else { add_filesys_config (&workprefs, -1, NULL, NULL, file, 0, - 32, 1, 2, 512, 0, NULL, 0); + 32, 1, 2, 512, 0, NULL, 0, 0); } } } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 5f59bf00..82c60565 100755 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,48 @@ +Beta 5: + +- A600/A1200 and A4000 IDE emulation (mount RDB HDF as a IDE drive) + - Following IDE harddrive commands emulated (commands that KS ROM + require, also IDEFix97 appears to work fine) + - Format Track (50, dummy command) + - Identify Drive (EC) + - Initialize Drive Parameters (91) + - Read Sector(s) (20 and 21) + - Read Multiple (C4) + - Write Sector(s) (30 and 31) + - Write Multiple (C5) + - Recalibrate (10, dummy command) + - Set Multiple Mode (C6) + - Set Features (EF, no feature commands supported) + + - max 2 drives available. "HD Controller"-selection added to GUI. + - support statefiles (WARNING: HDF data corruption danger!) + - ATAPI (IDE CDROM) emulation not supported (yet?) + + Notes: you can't mix Kickstart versions. A4000 KS has only A4000 + IDE driver, A600/A1200 KS has only A600/A1200 driver. + + Emulated drive is ancient ATA-1 feature level drive, size limits + not tested, PIO-0 speed restrictions not emulated :) + + This also means some defaults have been changed. Real IDE without + harddrive installed is now enabled if chipset extra is set to + A600/A1200 or A4000. Emulated "IDE wire trick" is enabled if no + drives installed to prevent long KS boot delay. + + Interesting note: A600/A1200 and A4000 KS IDE drivers are totally + different, for example A4000 uses LBA addressing but A600/A1200 + uses CHS. I don't see the point when the only hardware differences + basically are base IO address and different interrupt register.. + +- HRTMon IDE activated if IDE emulation enabled. AR A1200 also works. +- non-3d filters work again (broke in 1.4.2b2) +- Agnus/Denise revision settings re-added to advanced chipset +- added non-EHB A1000 to Quickstart (not yet in advanced chipset), + also added blitter busy bug to A1000 QS if cycle-exact enabled. + (busy flag not set until blitter gets first bus access cycle) + + Beta 4: - statefiles with autoconfigurable (fast and z3fast) memory wasn't diff --git a/savestate.c b/savestate.c index c5d45ed3..4b448d68 100755 --- a/savestate.c +++ b/savestate.c @@ -107,7 +107,7 @@ static void state_incompatible_warn(void) for(i = 0; i < currprefs.mountitems; i++) { struct mountedinfo mi; int type = get_filesys_unitconfig (&currprefs, i, &mi); - if (type != FILESYS_VIRTUAL) + if (mi.ismounted && type != FILESYS_VIRTUAL && type != FILESYS_HARDFILE && type != FILESYS_HARDFILE_RDB) dowarn = 1; } #endif @@ -501,6 +501,10 @@ void restore_state (char *filename) else if (!strcmp (name, "FSYC")) end = restore_filesys_common (chunk); #endif + else if (!strcmp (name, "GAYL")) + end = restore_gayle (chunk); + else if (!strcmp (name, "IDE ")) + end = restore_ide (chunk); else write_log ("unknown chunk '%s' size %d bytes\n", name, len); if (len != end - chunk) @@ -717,6 +721,18 @@ int save_state (char *filename, char *description) } } #endif + dst = save_gayle(&len); + if (dst) { + save_chunk (f, dst, len, "GAYL", 0); + xfree(dst); + } + for (i = 0; i < 2; i++) { + dst = save_ide (i, &len); + if (dst) { + save_chunk (f, dst, len, "IDE ", 0); + xfree(dst); + } + } zfile_fwrite ("END ", 1, 4, f); zfile_fwrite ("\0\0\0\08", 1, 4, f); diff --git a/uaeserial.c b/uaeserial.c index 2781bd53..019f20cc 100755 --- a/uaeserial.c +++ b/uaeserial.c @@ -201,7 +201,7 @@ static uae_u32 REGPARAM2 dev_close (TrapContext *context) static void resetparams(struct devstruct *dev, uaecptr req) { put_long(req + io_CtlChar, 0x00001311); - put_long(req + io_RBufLen, 8192); + put_long(req + io_RBufLen, 1024); put_long(req + io_ExtFlags, 0); put_long(req + io_Baud, 9600); put_long(req + io_BrkTime, 250000); @@ -271,7 +271,7 @@ static uae_u32 REGPARAM2 dev_open (TrapContext *context) uae_u32 unit = m68k_dreg (&context->regs, 0); uae_u32 flags = m68k_dreg (&context->regs, 1); struct devstruct *dev; - int i; + int i, err; for (i = 0; i < MAX_TOTAL_DEVICES; i++) { if (devst[i].unit == unit && devst[i].exclusive) @@ -295,7 +295,13 @@ static uae_u32 REGPARAM2 dev_open (TrapContext *context) dev->exclusive = (get_word(ioreq + io_SerFlags) & SERF_SHARED) ? 0 : 1; put_long (ioreq + 24, dev->uniq); resetparams (dev, ioreq); - setparams (dev, ioreq); + err = setparams (dev, ioreq); + if (err) { + uaeser_close (dev->sysdata); + dev->open = 0; + xfree (dev->sysdata); + return openfail (ioreq, err); + } if (log_uaeserial) write_log ("%s:%d open ioreq=%08.8X\n", getdevname(), unit, ioreq); start_thread (dev); -- 2.47.3