From: Toni Wilen Date: Sat, 6 Apr 2013 13:55:45 +0000 (+0300) Subject: 2600b15 X-Git-Tag: 2600~6 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=93d244039a80a3cf4b3216dc7ea5ca114a57df8a;p=francis%2Fwinuae.git 2600b15 --- diff --git a/blitter.cpp b/blitter.cpp index d9fdf071..896064c7 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -269,6 +269,7 @@ STATIC_INLINE void record_dma_blit (uae_u16 reg, uae_u16 dat, uae_u32 addr, int static void blitter_dump (void) { + int chipsize = currprefs.chipmem_size; write_log (_T("PT A=%08X B=%08X C=%08X D=%08X\n"), bltapt, bltbpt, bltcpt, bltdpt); write_log (_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); @@ -276,6 +277,10 @@ static void blitter_dump (void) blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); write_log (_T("PC=%08X DMA=%d\n"), m68k_getpc (), dmaen (DMA_BLITTER)); + + if (((bltcon0 & 0x800) && bltapt >= chipsize) || ((bltcon0 & 0x400) && bltbpt >= chipsize) || + ((bltcon0 & 0x200) && bltcpt >= chipsize) || ((bltcon0 & 0x100) && bltdpt >= chipsize)) + write_log (_T("PT outside of chipram\n")); } STATIC_INLINE const int *get_ch (void) diff --git a/custom.cpp b/custom.cpp index f80137fc..082bde27 100644 --- a/custom.cpp +++ b/custom.cpp @@ -901,7 +901,7 @@ int is_bitplane_dma (int hpos) { if (fetch_state == fetch_not_started || hpos < plfstrt) return 0; - if ((plf_state == plf_end && hpos >= thisline_decision.plfright) + if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle) return 0; return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; @@ -911,7 +911,7 @@ STATIC_INLINE int is_bitplane_dma_inline (int hpos) { if (fetch_state == fetch_not_started || hpos < plfstrt) return 0; - if ((plf_state == plf_end && hpos >= thisline_decision.plfright) + if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle) return 0; return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; @@ -1582,14 +1582,11 @@ static void do_long_fetch (int hpos, int nwords, int dma, int fm) #endif /* make sure fetch that goes beyond maxhpos is finished */ -static void finish_final_fetch (int fm) +static void finish_final_fetch (void) { - int pos = maxhpos; if (plf_state != plf_end) return; - pos += flush_plane_data (fm); - thisline_decision.plfright = pos; - thisline_decision.plflinelen = out_offs; + plf_state = plf_finished; finish_playfield_line (); } @@ -1597,14 +1594,16 @@ static void finish_last_fetch (int pos, int fm) { if (thisline_decision.plfleft < 0) return; - if (plf_state == plf_end) + if (plf_state >= plf_end) return; plf_state = plf_end; - if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { - finish_final_fetch (fm); - } else { + + pos += flush_plane_data (fm); + thisline_decision.plfright = pos; + thisline_decision.plflinelen = out_offs; + + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { bpl1dat_early = true; - pos += flush_plane_data (fm); ddfstate = DIW_waiting_start; fetch_state = fetch_not_started; } @@ -1625,7 +1624,6 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int } else if (plf_state == plf_passed_stop2) { plf_state = plf_end; } - } maybe_check (pos); @@ -1754,7 +1752,7 @@ STATIC_INLINE void update_fetch (int until, int fm) int ddfstop_to_test; - if (nodraw () || plf_state == plf_end) + if (nodraw () || plf_state >= plf_end) return; /* We need an explicit test against HARD_DDF_STOP here to guard against @@ -1928,6 +1926,12 @@ static void start_bpl_dma (int hpos, int hstart) bpldmawasactive = true; + } else { + + // this is a hack, something weird happens without this + // (Subtle Shades) + thisline_decision.plfright++; + thisline_decision.plflinelen = ++out_offs; } last_fetch_hpos = hstart; @@ -2093,10 +2097,10 @@ static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3) record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (brdsprt ? 2 : 0)); current_colors.bordersprite = brdsprt; remembered_color_entry = -1; - if (brdsprt) + if (brdsprt && !current_colors.borderblank) thisline_decision.bordersprite_seen = true; } - return brdsprt; + return brdsprt && !current_colors.borderblank; } static void record_register_change (int hpos, int regno, uae_u16 value) @@ -2422,7 +2426,7 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 unsigned int da = *data; unsigned int db = *datb; uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] - | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]); + | (sprtabb[db & 0xFF] << 16) | sprtabb[db >> 8]); int off = (i << dbl) >> half; uae_u16 *buf = spixels + word_offs + off; if (currprefs.collision_level > 0 && collision_mask) @@ -2481,7 +2485,7 @@ static int tospritexdiw (int diw) } static int tospritexddf (int ddf) { - return (ddf * 2) << sprite_buffer_res; + return (ddf * 2 - DIW_DDF_OFFSET) << sprite_buffer_res; } static int fromspritexdiw (int ddf) { @@ -2509,7 +2513,7 @@ static void calcsprite (void) } } /* sprites are visible from first BPL1DAT write to end of line - * ECS Denise/AGA: not limits + * ECS Denise/AGA: no limits * OCS Denise: BPL1DAT write only enables sprite if hpos >= 0x28 or so. * (undocumented feature) */ @@ -2660,7 +2664,7 @@ static void finish_decisions (void) decide_diw (hpos); decide_line (hpos); decide_fetch (hpos); - finish_final_fetch (fetchmode); + finish_final_fetch (); record_color_change2 (hsyncstartpos, 0xffff, 0); if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) { @@ -3295,7 +3299,7 @@ static void calcdiw (void) plfstrt = HARD_DDF_START; plfstrt_start = plfstrt - 4; } else { - plfstrt_start = plfstrt - 4; + plfstrt_start = plfstrt; } } else { if (!bpldmawasactive) { @@ -3441,8 +3445,10 @@ static uae_u16 VPOSR (void) csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; #endif csbit |= (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 0x2000 : 0; +#if 0 /* apparently "8372 (Fat-hr) (agnushr),rev 5" does not exist */ if (currprefs.chipmem_size > 1024 * 1024 && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) csbit |= 0x2100; +#endif if (currprefs.ntscmode) csbit |= 0x1000; } @@ -4108,7 +4114,7 @@ static void BPLxDAT (int hpos, int num, uae_u16 v) bpl1dat_written = true; bpl1dat_written_at_least_once = true; if (thisline_decision.plfleft < 0) { - thisline_decision.plfleft = hpos & ~3; + thisline_decision.plfleft = (hpos + 3) & ~3; reset_bpl_vars (); compute_delay_offset (); } diff --git a/drawing.cpp b/drawing.cpp index efd8805d..c0cca803 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -219,7 +219,8 @@ static int first_block_line, last_block_line; /* These are generated by the drawing code from the line_decisions array for each line that needs to be drawn. These are basically extracted out of bit fields in the hardware registers. */ -static int bplehb, bplham, bpldualpf, bpldualpfpri, bpldualpf2of, bplplanecnt, ecsshres, issprites; +static int bplehb, bplham, bpldualpf, bpldualpfpri, bpldualpf2of, bplplanecnt, ecsshres; +static bool issprites; static int bplres; static int plf1pri, plf2pri, bplxor; static uae_u32 plf_sprite_mask; @@ -694,6 +695,7 @@ static int playfield_start, playfield_end; static int real_playfield_start, real_playfield_end; static int linetoscr_diw_start, linetoscr_diw_end; static int native_ddf_left, native_ddf_right; +static bool can_have_bordersprite; static int pixels_offset; static int src_pixel, ham_src_pixel; @@ -764,6 +766,22 @@ static void pfield_init_linetoscr (void) real_playfield_end = playfield_end; real_playfield_start = playfield_start; + // Sprite hpos don't include DIW_DDF_OFFSET and can appear 1 lores pixel + // before first bitplane pixel appears. + // This means "bordersprite" conditions is possible under OCS/ECS too. Argh! + if (dip_for_drawing->nr_sprites) { + /* bordersprite off or not supported: sprites are visible until diw_end */ + if (playfield_end < linetoscr_diw_end) + playfield_end = linetoscr_diw_end; + int end = coord_hw_to_window_x (dp_for_drawing->plfleft * 2); + if (end < playfield_start && end > linetoscr_diw_start) { + playfield_start = end; + can_have_bordersprite = true; + } + } else { + can_have_bordersprite = dp_for_drawing->bordersprite_seen; + } + #ifdef AGA if (dp_for_drawing->bordersprite_seen && dip_for_drawing->nr_sprites) { int min = visible_right_border, max = visible_left_border, i; @@ -1268,6 +1286,7 @@ static int NOINLINE linetoscr_16_shrink2f_sh (int spix, int dpix, int stoppos, i static void pfield_do_linetoscr (int start, int stop, bool blank) { xlinecheck(start, stop); +#ifdef AGA if (issprites && (currprefs.chipset_mask & CSMASK_AGA)) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { @@ -1310,7 +1329,6 @@ static void pfield_do_linetoscr (int start, int stop, bool blank) } } } else -#ifdef AGA if (currprefs.chipset_mask & CSMASK_AGA) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { @@ -1450,6 +1468,15 @@ static void pfield_do_linetoscr (int start, int stop, bool blank) } +// left or right border sprite +static void pfield_do_linetoscr_border (int start, int stop, bool blank) +{ + bool old = issprites; + issprites = colors_for_drawing.bordersprite != 0; + pfield_do_linetoscr (start, stop, blank); + issprites = old; +} + static void dummy_worker (int start, int stop, bool blank) { } @@ -1681,9 +1708,8 @@ STATIC_INLINE void draw_sprites_ecs (struct sprite_entry *e) } } -#ifdef AGA /* clear possible bitplane data outside DIW area */ -static void clear_bitplane_border_aga (void) +static void clear_bitplane_border (void) { int len, shift = res_shift; uae_u8 v = 0; @@ -1701,7 +1727,6 @@ static void clear_bitplane_border_aga (void) memset (pixdata.apixels + pixels_offset + (real_playfield_end >> shift), v, len); } } -#endif /* emulate OCS/ECS only undocumented "SWIV" hardware feature */ static void weird_bitplane_fix (void) @@ -1994,7 +2019,7 @@ static void pfield_expand_dp_bplcon (void) bplehb = dp_for_drawing->ehb_seen; if ((currprefs.chipset_mask & CSMASK_AGA) && (dp_for_drawing->bplcon2 & 0x0200)) bplehb = 0; - issprites = dip_for_drawing->nr_sprites; + issprites = dip_for_drawing->nr_sprites > 0; #ifdef ECS_DENISE ecsshres = bplres == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); #endif @@ -2081,6 +2106,7 @@ static void adjust_drawing_colors (int ctable, int need_full) memcpy (colors_for_drawing.acolors, curr_color_tables[ctable].acolors, sizeof colors_for_drawing.acolors); colors_for_drawing.borderblank = curr_color_tables[ctable].borderblank; + colors_for_drawing.bordersprite = curr_color_tables[ctable].bordersprite; color_match_type = color_match_acolors; } drawing_color_matches = ctable; @@ -2191,7 +2217,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in case LINE_BLACK: linestate[lineno] = LINE_REMEMBERED_AS_BLACK; - border = 2; + border = -1; break; case LINE_REMEMBERED_AS_BLACK: @@ -2261,10 +2287,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in if (dip_for_drawing->nr_sprites) { int i; -#ifdef AGA - if (dp_for_drawing->bordersprite_seen) - clear_bitplane_border_aga (); -#endif + if (can_have_bordersprite) + clear_bitplane_border (); + for (i = 0; i < dip_for_drawing->nr_sprites; i++) { #ifdef AGA if (currprefs.chipset_mask & CSMASK_AGA) @@ -2289,13 +2314,14 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in do_flush_line (vb, follow_ypos); } - } else if (border == 1) { + } else if (border > 0) { + // border > 0: top or bottom border bool dosprites = false; adjust_drawing_colors (dp_for_drawing->ctable, 0); #ifdef AGA /* this makes things complex.. */ - if (dp_for_drawing->bordersprite_seen && dip_for_drawing->nr_sprites > 0) { + if (dp_for_drawing->bordersprite_seen && dip_for_drawing->nr_sprites) { dosprites = true; pfield_expand_dp_bplcon (); pfield_init_linetoscr (); @@ -2327,7 +2353,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in uae_u16 oxor = bplxor; memset (pixdata.apixels, 0, sizeof pixdata); bplxor = 0; - do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno); + do_color_changes (pfield_do_fill_line, pfield_do_linetoscr_border, lineno); bplxor = oxor; } else { diff --git a/gayle.cpp b/gayle.cpp index a4c00a91..15a6dbc2 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -110,7 +110,7 @@ read 1 byte to stop reset */ /* * These are at different offsets from the base */ -#define GAYLE_IRQ_4000 0x3020 /* MSB = 1, Harddisk is source of interrupt */ +#define GAYLE_IRQ_4000 0x3020 /* WORD register MSB = 1, Harddisk is source of interrupt */ #define GAYLE_CS_1200 0x8000 #define GAYLE_IRQ_1200 0x9000 #define GAYLE_INT_1200 0xA000 @@ -228,19 +228,17 @@ static int pcmcia_configured; static int gayle_id_cnt; static uae_u8 gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg; -static int ide2, ide_splitter; - -static struct ide_hdf *ide; +static int ide_splitter; static smp_comm_pipe requests; static volatile int gayle_thread_running; -STATIC_INLINE void pw (int offset, uae_u16 w) +STATIC_INLINE void pw (struct ide_hdf *ide, int offset, uae_u16 w) { ide->secbuf[offset * 2 + 0] = (uae_u8)w; ide->secbuf[offset * 2 + 1] = w >> 8; } -static void ps (int offset, const TCHAR *src, int max) +static void ps (struct ide_hdf *ide, int offset, const TCHAR *src, int max) { int i, len; char *s; @@ -277,9 +275,9 @@ static uae_u8 checkpcmciaideirq (void) return 0; } -static bool isdrive (struct ide_hdf *drv) +static bool isdrive (struct ide_hdf *ide) { - return drv->hdhfd.size != 0 || drv->atapi; + return ide && (ide->hdhfd.size != 0 || ide->atapi); } static uae_u8 checkgayleideirq (void) @@ -434,11 +432,11 @@ static uae_u8 read_gayle_cs (void) return v; } -static void ide_interrupt (void) +static void ide_interrupt (struct ide_hdf *ide) { ide->irq_delay = 2; } -static void ide_fast_interrupt (void) +static void ide_fast_interrupt (struct ide_hdf *ide) { ide->irq_delay = 1; } @@ -446,6 +444,8 @@ static void ide_fast_interrupt (void) static void ide_interrupt_do (struct ide_hdf *ide) { ide->regs.ide_status &= ~IDE_STATUS_BSY; + if (ide->direction) + ide->regs.ide_status |= IDE_STATUS_DRQ; ide->irq_delay = 0; if (ide->regs.ide_devcon & 2) return; @@ -453,37 +453,37 @@ static void ide_interrupt_do (struct ide_hdf *ide) rethink_gayle (); } -static void ide_fail_err (uae_u8 err) +static void ide_fail_err (struct ide_hdf *ide, uae_u8 err) { ide->regs.ide_error |= err; - if (ide->ide_drv == 1 && !isdrive (ide + 1)) - idedrive[ide2]->regs.ide_status |= IDE_STATUS_ERR; + if (ide->ide_drv == 1 && !isdrive (ide->pair)) + idedrive[ide->ide_drv >= 2 ? 2 : 0]->regs.ide_status |= IDE_STATUS_ERR; ide->regs.ide_status |= IDE_STATUS_ERR; - ide_interrupt (); + ide_interrupt (ide); } -static void ide_fail (void) +static void ide_fail (struct ide_hdf *ide) { - ide_fail_err (IDE_ERR_ABRT); + ide_fail_err (ide, IDE_ERR_ABRT); } -static void ide_data_ready (void) +static void ide_data_ready (struct ide_hdf *ide) { memset (ide->secbuf, 0, ide->blocksize); ide->data_offset = 0; ide->regs.ide_status |= IDE_STATUS_DRQ; ide->data_size = ide->blocksize; ide->data_multi = 1; - ide_interrupt (); + ide_interrupt (ide); } -static void ide_recalibrate (void) +static void ide_recalibrate (struct ide_hdf *ide) { write_log (_T("IDE%d recalibrate\n"), ide->num); ide->regs.ide_sector = 0; ide->regs.ide_lcyl = ide->regs.ide_hcyl = 0; - ide_interrupt (); + ide_interrupt (ide); } -static void ide_identify_drive (void) +static void ide_identify_drive (struct ide_hdf *ide) { uae_u64 totalsecs; int v; @@ -492,73 +492,73 @@ static void ide_identify_drive (void) bool atapi = ide->atapi; if (!isdrive (ide)) { - ide_fail (); + ide_fail (ide); return; } memset (buf, 0, ide->blocksize); if (IDE_LOG > 0) write_log (_T("IDE%d identify drive\n"), ide->num); - ide_data_ready (); + ide_data_ready (ide); ide->direction = 0; - pw (0, atapi ? 0x85c0 : 1 << 6); - pw (1, ide->hdhfd.cyls_def); - pw (2, 0xc837); - pw (3, ide->hdhfd.heads_def); - pw (4, ide->blocksize * ide->hdhfd.secspertrack_def); - pw (5, ide->blocksize); - pw (6, ide->hdhfd.secspertrack_def); - ps (10, _T("68000"), 20); /* serial */ - pw (20, 3); - pw (21, ide->blocksize); - pw (22, 4); - ps (23, _T("0.5"), 8); /* firmware revision */ + pw (ide, 0, atapi ? 0x85c0 : 1 << 6); + pw (ide, 1, ide->hdhfd.cyls_def); + pw (ide, 2, 0xc837); + pw (ide, 3, ide->hdhfd.heads_def); + pw (ide, 4, ide->blocksize * ide->hdhfd.secspertrack_def); + pw (ide, 5, ide->blocksize); + pw (ide, 6, ide->hdhfd.secspertrack_def); + ps (ide, 10, _T("68000"), 20); /* serial */ + pw (ide, 20, 3); + pw (ide, 21, ide->blocksize); + pw (ide, 22, 4); + ps (ide, 23, _T("0.5"), 8); /* firmware revision */ if (ide->atapi) _tcscpy (tmp, _T("UAE-ATAPI")); else _stprintf (tmp, _T("UAE-IDE %s"), ide->hdhfd.hfd.product_id); - ps (27, tmp, 40); /* model */ - pw (47, MAX_IDE_MULTIPLE_SECTORS >> (ide->blocksize / 512 - 1)); /* max sectors in multiple mode */ - pw (48, 1); - pw (49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */ - pw (51, 0x200); /* PIO cycles */ - pw (52, 0x200); /* DMA cycles */ - pw (53, 1 | 2 | 4); - pw (54, ide->hdhfd.cyls); - pw (55, ide->hdhfd.heads); - pw (56, ide->hdhfd.secspertrack); + ps (ide, 27, tmp, 40); /* model */ + pw (ide, 47, MAX_IDE_MULTIPLE_SECTORS >> (ide->blocksize / 512 - 1)); /* max sectors in multiple mode */ + pw (ide, 48, 1); + pw (ide, 49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */ + pw (ide, 51, 0x200); /* PIO cycles */ + pw (ide, 52, 0x200); /* DMA cycles */ + pw (ide, 53, 1 | 2 | 4); + pw (ide, 54, ide->hdhfd.cyls); + pw (ide, 55, ide->hdhfd.heads); + pw (ide, 56, ide->hdhfd.secspertrack); totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack; - pw (57, (uae_u16)totalsecs); - pw (58, (uae_u16)(totalsecs >> 16)); + pw (ide, 57, (uae_u16)totalsecs); + pw (ide, 58, (uae_u16)(totalsecs >> 16)); v = idedrive[ide->ide_drv]->multiple_mode; - pw (59, (v > 0 ? 0x100 : 0) | v); + pw (ide, 59, (v > 0 ? 0x100 : 0) | v); totalsecs = ide->blocksize ? ide->hdhfd.size / ide->blocksize : 0; if (totalsecs > 0x0fffffff) totalsecs = 0x0fffffff; - pw (60, (uae_u16)totalsecs); - pw (61, (uae_u16)(totalsecs >> 16)); - pw (62, 0x0f); - pw (63, 0x0f); - pw (64, 0x03); /* PIO3 and PIO4 */ - pw (65, 120); /* MDMA2 supported */ - pw (66, 120); - pw (67, 120); - pw (68, 120); - pw (80, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); /* ATA-1 to ATA-6 */ - pw (81, 0x1c); /* ATA revision */ - pw (82, (1 << 14) | (atapi ? 0x10 | 4 : 0)); /* NOP, ATAPI: PACKET and Removable media features supported */ - pw (83, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 supported */ - pw (84, 1 << 14); - pw (85, 1 << 14); - pw (86, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 enabled */ - pw (87, 1 << 14); - pw (88, (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); /* UDMA modes */ - pw (93, (1 << 14) | (1 << 13) | (1 << 0)); + pw (ide, 60, (uae_u16)totalsecs); + pw (ide, 61, (uae_u16)(totalsecs >> 16)); + pw (ide, 62, 0x0f); + pw (ide, 63, 0x0f); + pw (ide, 64, 0x03); /* PIO3 and PIO4 */ + pw (ide, 65, 120); /* MDMA2 supported */ + pw (ide, 66, 120); + pw (ide, 67, 120); + pw (ide, 68, 120); + pw (ide, 80, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); /* ATA-1 to ATA-6 */ + pw (ide, 81, 0x1c); /* ATA revision */ + pw (ide, 82, (1 << 14) | (atapi ? 0x10 | 4 : 0)); /* NOP, ATAPI: PACKET and Removable media features supported */ + pw (ide, 83, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 supported */ + pw (ide, 84, 1 << 14); + pw (ide, 85, 1 << 14); + pw (ide, 86, (1 << 14) | (1 << 13) | (1 << 12) | (ide->lba48 ? (1 << 10) : 0)); /* cache flushes, LBA 48 enabled */ + pw (ide, 87, 1 << 14); + pw (ide, 88, (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); /* UDMA modes */ + pw (ide, 93, (1 << 14) | (1 << 13) | (1 << 0)); if (ide->lba48) { totalsecs = ide->hdhfd.size / ide->blocksize; - pw (100, (uae_u16)(totalsecs >> 0)); - pw (101, (uae_u16)(totalsecs >> 16)); - pw (102, (uae_u16)(totalsecs >> 32)); - pw (103, (uae_u16)(totalsecs >> 48)); + pw (ide, 100, (uae_u16)(totalsecs >> 0)); + pw (ide, 101, (uae_u16)(totalsecs >> 16)); + pw (ide, 102, (uae_u16)(totalsecs >> 32)); + pw (ide, 103, (uae_u16)(totalsecs >> 48)); } } @@ -582,23 +582,23 @@ static void set_signature (struct ide_hdf *ide) ide->packet_state = 0; } -static void reset_device (bool both) +static void reset_device (struct ide_hdf *ide, bool both) { set_signature (ide); if (both) set_signature (ide->pair); } -static void ide_execute_drive_diagnostics (bool irq) +static void ide_execute_drive_diagnostics (struct ide_hdf *ide, bool irq) { - reset_device (irq); + reset_device (ide, irq); if (irq) - ide_interrupt (); + ide_interrupt (ide); else ide->regs.ide_status &= ~IDE_STATUS_BSY; } -static void ide_initialize_drive_parameters (void) +static void ide_initialize_drive_parameters (struct ide_hdf *ide) { if (ide->hdhfd.size) { ide->hdhfd.secspertrack = ide->regs.ide_nsector == 0 ? 256 : ide->regs.ide_nsector; @@ -621,26 +621,26 @@ static void ide_initialize_drive_parameters (void) } write_log (_T("IDE%d initialize drive parameters, CYL=%d,SPT=%d,HEAD=%d\n"), ide->num, ide->hdhfd.cyls, ide->hdhfd.secspertrack, ide->hdhfd.heads); - ide_interrupt (); + ide_interrupt (ide); } -static void ide_set_multiple_mode (void) +static void ide_set_multiple_mode (struct ide_hdf *ide) { write_log (_T("IDE%d drive multiple mode = %d\n"), ide->num, ide->regs.ide_nsector); ide->multiple_mode = ide->regs.ide_nsector; - ide_interrupt (); + ide_interrupt (ide); } -static void ide_set_features (void) +static void ide_set_features (struct ide_hdf *ide) { int type = ide->regs.ide_nsector >> 3; int mode = ide->regs.ide_nsector & 7; write_log (_T("IDE%d set features %02X (%02X)\n"), ide->num, ide->regs.ide_feat, ide->regs.ide_nsector); - ide_fail (); + ide_fail (ide); } -static void get_lbachs (struct ide_hdf *ide, uae_u64 *lbap, unsigned int *cyl, unsigned int *head, unsigned int *sec, int lba48) +static void get_lbachs (struct ide_hdf *ide, uae_u64 *lbap, unsigned int *cyl, unsigned int *head, unsigned int *sec) { - if (lba48 && (ide->regs.ide_select & 0x40)) { + if (ide->lba48 && (ide->regs.ide_select & 0x40)) { uae_u64 lba; lba = (ide->regs.ide_hcyl << 16) | (ide->regs.ide_lcyl << 8) | ide->regs.ide_sector; lba |= ((ide->regs.ide_hcyl2 << 16) | (ide->regs.ide_lcyl2 << 8) | ide->regs.ide_sector2) << 24; @@ -657,16 +657,16 @@ static void get_lbachs (struct ide_hdf *ide, uae_u64 *lbap, unsigned int *cyl, u } } -static int get_nsec (int lba48) +static int get_nsec (struct ide_hdf *ide) { - if (lba48) + if (ide->lba48) return (ide->regs.ide_nsector == 0 && ide->regs.ide_nsector2 == 0) ? 65536 : (ide->regs.ide_nsector2 * 256 + ide->regs.ide_nsector); else return ide->regs.ide_nsector == 0 ? 256 : ide->regs.ide_nsector; } -static int dec_nsec (int lba48, int v) +static int dec_nsec (struct ide_hdf *ide, int v) { - if (lba48) { + if (ide->lba48) { uae_u16 nsec; nsec = ide->regs.ide_nsector2 * 256 + ide->regs.ide_nsector; ide->regs.ide_nsector -= v; @@ -679,9 +679,9 @@ static int dec_nsec (int lba48, int v) } } -static void put_lbachs (struct ide_hdf *ide, uae_u64 lba, unsigned int cyl, unsigned int head, unsigned int sec, unsigned int inc, int lba48) +static void put_lbachs (struct ide_hdf *ide, uae_u64 lba, unsigned int cyl, unsigned int head, unsigned int sec, unsigned int inc) { - if (lba48) { + if (ide->lba48) { lba += inc; ide->regs.ide_hcyl = (lba >> 16) & 0xff; ide->regs.ide_lcyl = (lba >> 8) & 0xff; @@ -717,7 +717,7 @@ static void put_lbachs (struct ide_hdf *ide, uae_u64 lba, unsigned int cyl, unsi } } -static void check_maxtransfer (int state) +static void check_maxtransfer (struct ide_hdf *ide, int state) { if (state == 1) { // transfer was started @@ -739,20 +739,20 @@ static void check_maxtransfer (int state) } } -static void process_rw_command (void) +static void process_rw_command (struct ide_hdf *ide) { ide->regs.ide_status |= IDE_STATUS_BSY; ide->regs.ide_status &= ~IDE_STATUS_DRQ; write_comm_pipe_u32 (&requests, ide->num, 1); } -static void process_packet_command (void) +static void process_packet_command (struct ide_hdf *ide) { ide->regs.ide_status |= IDE_STATUS_BSY; ide->regs.ide_status &= ~IDE_STATUS_DRQ; write_comm_pipe_u32 (&requests, ide->num | 0x80, 1); } -static void atapi_data_done (void) +static void atapi_data_done (struct ide_hdf *ide) { ide->regs.ide_nsector = ATAPI_IO | ATAPI_CD; ide->regs.ide_status = IDE_STATUS_DRDY; @@ -788,7 +788,7 @@ static bool atapi_set_size (struct ide_hdf *ide) return false; } -static void atapi_packet (void) +static void atapi_packet (struct ide_hdf *ide) { ide->packet_data_offset = 0; ide->packet_data_size = (ide->regs.ide_hcyl << 8) | ide->regs.ide_lcyl; @@ -826,14 +826,14 @@ static void do_packet_command (struct ide_hdf *ide) // error ide->regs.ide_status = ATAPI_STATUS_CHK; ide->regs.ide_error = ide->scsi->status << 4; - atapi_data_done (); + atapi_data_done (ide); } else if (ide->scsi->data_len) { // data in memcpy (ide->secbuf, ide->scsi->buffer, ide->scsi->data_len); ide->regs.ide_nsector = ATAPI_IO; } else { // no data - atapi_data_done (); + atapi_data_done (ide); } } else { // data out @@ -874,8 +874,8 @@ static void do_process_rw_command (struct ide_hdf *ide) bool last; ide->data_offset = 0; - get_lbachs (ide, &lba, &cyl, &head, &sec, ide->lba48); - nsec = get_nsec (ide->lba48); + get_lbachs (ide, &lba, &cyl, &head, &sec); + nsec = get_nsec (ide); if (IDE_LOG > 1) write_log (_T("IDE%d off=%d, nsec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 ? 48 : 28); if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) { @@ -884,8 +884,8 @@ static void do_process_rw_command (struct ide_hdf *ide) write_log (_T("IDE%d nsec changed to %d\n"), ide->num, nsec); } if (nsec <= 0) { - ide_data_ready (); - ide_fail_err (IDE_ERR_IDNF); + ide_data_ready (ide); + ide_fail_err (ide, IDE_ERR_IDNF); return; } if (nsec > ide->data_multi) @@ -901,8 +901,8 @@ static void do_process_rw_command (struct ide_hdf *ide) write_log (_T("IDE%d read, read %d bytes\n"), ide->num, nsec * ide->blocksize); } ide->regs.ide_status |= IDE_STATUS_DRQ; - last = dec_nsec (ide->lba48, nsec) == 0; - put_lbachs (ide, lba, cyl, head, sec, last ? nsec - 1 : nsec, ide->lba48); + last = dec_nsec (ide, nsec) == 0; + put_lbachs (ide, lba, cyl, head, sec, last ? nsec - 1 : nsec); if (last) { if (ide->direction) { if (IDE_LOG > 1) @@ -913,74 +913,73 @@ static void do_process_rw_command (struct ide_hdf *ide) ide->irq_delay = 1; } -static void ide_read_sectors (int flags) +static void ide_read_sectors (struct ide_hdf *ide, int flags) { unsigned int cyl, head, sec, nsec; uae_u64 lba; int multi = flags & 1; - int lba48 = flags & 2; if (multi && ide->multiple_mode == 0) { - ide_fail (); + ide_fail (ide); return; } - check_maxtransfer(1); + check_maxtransfer (ide, 1); gui_flicker_led (LED_HD, ide->num, 1); - nsec = get_nsec (lba48); - get_lbachs (ide, &lba, &cyl, &head, &sec, lba48); + nsec = get_nsec (ide); + get_lbachs (ide, &lba, &cyl, &head, &sec); if (lba * ide->blocksize >= ide->hdhfd.size) { - ide_data_ready (); - ide_fail_err (IDE_ERR_IDNF); + ide_data_ready (ide); + ide_fail_err (ide, IDE_ERR_IDNF); return; } ide->data_multi = multi ? ide->multiple_mode : 1; ide->data_offset = 0; - ide->regs.ide_status |= IDE_STATUS_DRQ; ide->data_size = nsec * ide->blocksize; ide->direction = 0; - process_rw_command (); + process_rw_command (ide); } -static void ide_write_sectors (int flags) +static void ide_write_sectors (struct ide_hdf *ide, int flags) { unsigned int cyl, head, sec, nsec; uae_u64 lba; int multi = flags & 1; - int lba48 = flags & 2; if (multi && ide->multiple_mode == 0) { - ide_fail (); + ide_fail (ide); return; } - check_maxtransfer (1); + check_maxtransfer (ide, 1); gui_flicker_led (LED_HD, ide->num, 2); - nsec = get_nsec (lba48); - get_lbachs (ide, &lba, &cyl, &head, &sec, lba48); + nsec = get_nsec (ide); + get_lbachs (ide, &lba, &cyl, &head, &sec); if (lba * ide->blocksize >= ide->hdhfd.size) { - ide_data_ready (); - ide_fail_err (IDE_ERR_IDNF); + ide_data_ready (ide); + ide_fail_err (ide, IDE_ERR_IDNF); return; } if (IDE_LOG > 0) - write_log (_T("IDE%d write off=%d, sec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, lba48 ? 48 : 28); + write_log (_T("IDE%d write off=%d, sec=%d (%d) lba%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 ? 48 : 28); if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) nsec = (ide->hdhfd.size - lba * ide->blocksize) / ide->blocksize; if (nsec <= 0) { - ide_data_ready (); - ide_fail_err (IDE_ERR_IDNF); + ide_data_ready (ide); + ide_fail_err (ide, IDE_ERR_IDNF); return; } ide->data_multi = multi ? ide->multiple_mode : 1; ide->data_offset = 0; - ide->regs.ide_status |= IDE_STATUS_DRQ; ide->data_size = nsec * ide->blocksize; ide->direction = 1; - ide_fast_interrupt (); + ide->regs.ide_status |= IDE_STATUS_BSY; + ide->regs.ide_status &= ~IDE_STATUS_DRQ; + + ide_fast_interrupt (ide); } -static void ide_do_command (uae_u8 cmd) +static void ide_do_command (struct ide_hdf *ide, uae_u8 cmd) { int lba48 = ide->lba48; @@ -994,69 +993,69 @@ static void ide_do_command (uae_u8 cmd) gui_flicker_led (LED_CD, ide->num, 1); ide->atapi_drdy = true; if (cmd == 0x00) { /* nop */ - ide_interrupt (); + ide_interrupt (ide); } else if (cmd == 0x08) { /* device reset */ - ide_execute_drive_diagnostics (true); + ide_execute_drive_diagnostics (ide, true); } else if (cmd == 0xa1) { /* identify packet device */ - ide_identify_drive (); + ide_identify_drive (ide); } else if (cmd == 0xa0) { /* packet */ - atapi_packet (); + atapi_packet (ide); } else if (cmd == 0x90) { /* execute drive diagnostics */ - ide_execute_drive_diagnostics (true); + ide_execute_drive_diagnostics (ide, true); } else { - ide_execute_drive_diagnostics (false); + ide_execute_drive_diagnostics (ide, false); ide->atapi_drdy = false; - ide_fail (); + ide_fail (ide); write_log (_T("IDE%d: unknown ATAPI command 0x%02x\n"), ide->num, cmd); } } else { if (cmd == 0x10) { /* recalibrate */ - ide_recalibrate (); + ide_recalibrate (ide); } else if (cmd == 0xec) { /* identify drive */ - ide_identify_drive (); + ide_identify_drive (ide); } else if (cmd == 0x90) { /* execute drive diagnostics */ - ide_execute_drive_diagnostics (true); + ide_execute_drive_diagnostics (ide, true); } else if (cmd == 0x91) { /* initialize drive parameters */ - ide_initialize_drive_parameters (); + ide_initialize_drive_parameters (ide); } else if (cmd == 0xc6) { /* set multiple mode */ - ide_set_multiple_mode (); + ide_set_multiple_mode (ide); } else if (cmd == 0x20 || cmd == 0x21) { /* read sectors */ - ide_read_sectors (0); + ide_read_sectors (ide, 0); } else if (cmd == 0x24 && lba48) { /* read sectors ext */ - ide_read_sectors (2); + ide_read_sectors (ide, 2); } else if (cmd == 0xc4) { /* read multiple */ - ide_read_sectors (1); + ide_read_sectors (ide, 1); } else if (cmd == 0x29 && lba48) { /* read multiple ext */ - ide_read_sectors (1|2); + ide_read_sectors (ide, 1|2); } else if (cmd == 0x30 || cmd == 0x31) { /* write sectors */ - ide_write_sectors (0); + ide_write_sectors (ide, 0); } else if (cmd == 0x34 && lba48) { /* write sectors ext */ - ide_write_sectors (2); + ide_write_sectors (ide, 2); } else if (cmd == 0xc5) { /* write multiple */ - ide_write_sectors (1); + ide_write_sectors (ide, 1); } else if (cmd == 0x39 && lba48) { /* write multiple ext */ - ide_write_sectors (1|2); + ide_write_sectors (ide, 1|2); } else if (cmd == 0x50) { /* format track (nop) */ - ide_interrupt (); + ide_interrupt (ide); } else if (cmd == 0xef) { /* set features */ - ide_set_features (); + ide_set_features (ide); } else if (cmd == 0x00) { /* nop */ - ide_fail (); + ide_fail (ide); } else if (cmd == 0xe0 || cmd == 0xe1 || cmd == 0xe7 || cmd == 0xea) { /* standby now/idle/flush cache/flush cache ext */ - ide_interrupt (); + ide_interrupt (ide); } else if (cmd == 0xe5) { /* check power mode */ ide->regs.ide_nsector = 0xff; - ide_interrupt (); + ide_interrupt (ide); } else { - ide_fail (); + ide_fail (ide); write_log (_T("IDE%d: unknown ATA command 0x%02x\n"), ide->num, cmd); } } } -static uae_u16 ide_get_data (void) +static uae_u16 ide_get_data (struct ide_hdf *ide) { bool irq = false; bool last = false; @@ -1083,12 +1082,12 @@ static uae_u16 ide_get_data (void) write_log (_T("IDE%d ATAPI partial read finished, %d bytes remaining\n"), ide->num, ide->data_size); if (ide->data_size == 0) { ide->packet_state = 0; - atapi_data_done (); + atapi_data_done (ide); if (IDE_LOG > 1) write_log (_T("IDE%d ATAPI read finished, %d bytes\n"), ide->num, ide->packet_data_offset + ide->data_offset); irq = true; } else { - process_packet_command (); + process_packet_command (ide); } } } else { @@ -1100,7 +1099,7 @@ static uae_u16 ide_get_data (void) ide->data_size -= 2; if (((ide->data_offset % ide->blocksize) == 0) && ((ide->data_offset / ide->blocksize) % ide->data_multi) == 0) { if (ide->data_size) - process_rw_command (); + process_rw_command (ide); } } if (ide->data_size == 0) { @@ -1110,11 +1109,11 @@ static uae_u16 ide_get_data (void) } } if (irq) - ide_fast_interrupt (); + ide_fast_interrupt (ide); return v; } -static void ide_put_data (uae_u16 v) +static void ide_put_data (struct ide_hdf *ide, uae_u16 v) { if (IDE_LOG > 4) write_log (_T("IDE%d DATA write %04x %d/%d\n"), ide->num, v, ide->data_offset, ide->data_size); @@ -1133,21 +1132,23 @@ static void ide_put_data (uae_u16 v) uae_u16 v = (ide->regs.ide_hcyl << 8) | ide->regs.ide_lcyl; write_log (_T("Data size after command received = %d (%d)\n"), v, ide->packet_data_size); } - process_packet_command (); + process_packet_command (ide); } } else { if (ide->data_size == 0) { - process_rw_command (); + process_rw_command (ide); } else if (((ide->data_offset % ide->blocksize) == 0) && ((ide->data_offset / ide->blocksize) % ide->data_multi) == 0) { - process_rw_command (); + process_rw_command (ide); } } } -static int get_gayle_ide_reg (uaecptr addr) +static int get_gayle_ide_reg (uaecptr addr, struct ide_hdf **ide) { + int ide2; uaecptr a = addr; addr &= 0xffff; + *ide = NULL; if (addr >= GAYLE_IRQ_4000 && addr <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == IDE_A4000) return -1; addr &= ~0x2020; @@ -1159,15 +1160,18 @@ static int get_gayle_ide_reg (uaecptr addr) addr &= ~0x400; } } - ide = idedrive[ide2 + idedrive[ide2]->ide_drv]; + *ide = idedrive[ide2 + idedrive[ide2]->ide_drv]; return addr; } -static uae_u32 ide_read_reg (int ide_reg) +static uae_u32 ide_read_reg (struct ide_hdf *ide, int ide_reg) { uae_u8 v = 0; bool isdrv = isdrive (ide); + if (!ide) + goto end; + if (ide->regs.ide_status & IDE_STATUS_BSY) ide_reg = IDE_STATUS; if (!isdrive (ide)) { @@ -1204,7 +1208,7 @@ static uae_u32 ide_read_reg (int ide_reg) v = ide->regs.ide_sector2; else v = ide->regs.ide_sector; - check_maxtransfer (2); + check_maxtransfer (ide, 2); } break; case IDE_LCYL: @@ -1247,8 +1251,11 @@ end: return v; } -static void ide_write_reg (int ide_reg, uae_u32 val) +static void ide_write_reg (struct ide_hdf *ide, int ide_reg, uae_u32 val) { + if (!ide) + return; + ide->regs1->ide_devcon &= ~0x80; /* clear HOB */ ide->regs0->ide_devcon &= ~0x80; /* clear HOB */ if (IDE_LOG > 2 && ide_reg > 0 && (1 || ide->num > 0)) @@ -1260,7 +1267,7 @@ static void ide_write_reg (int ide_reg, uae_u32 val) break; case IDE_DEVCON: if ((ide->regs.ide_devcon & 4) == 0 && (val & 4) != 0) { - reset_device (true); + reset_device (ide, true); if (IDE_LOG > 1) write_log (_T("IDE%d: SRST\n"), ide->num); } @@ -1312,7 +1319,7 @@ static void ide_write_reg (int ide_reg, uae_u32 val) ide->irq = 0; if (isdrive (ide)) { ide->regs.ide_status |= IDE_STATUS_BSY; - ide_do_command (val); + ide_do_command (ide, val); } break; } @@ -1320,6 +1327,7 @@ static void ide_write_reg (int ide_reg, uae_u32 val) static uae_u32 gayle_read2 (uaecptr addr) { + struct ide_hdf *ide = NULL; int ide_reg; uae_u8 v = 0; @@ -1348,18 +1356,19 @@ static uae_u32 gayle_read2 (uaecptr addr) } return 0; } - ide_reg = get_gayle_ide_reg (addr); + ide_reg = get_gayle_ide_reg (addr, &ide); /* Emulated "ide killer". Prevents long KS boot delay if no drives installed */ if (!isdrive (idedrive[0]) && !isdrive (idedrive[1]) && !isdrive (idedrive[2]) && !isdrive (idedrive[3])) { if (ide_reg == IDE_STATUS) return 0x7f; return 0xff; } - return ide_read_reg (ide_reg); + return ide_read_reg (ide, ide_reg); } static void gayle_write2 (uaecptr addr, uae_u32 val) { + struct ide_hdf *ide = NULL; int ide_reg; if ((IDE_LOG > 3 && (addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)) || IDE_LOG > 5) @@ -1378,8 +1387,8 @@ static void gayle_write2 (uaecptr addr, uae_u32 val) } if (addr >= 0x4000) return; - ide_reg = get_gayle_ide_reg (addr); - ide_write_reg (ide_reg, val); + ide_reg = get_gayle_ide_reg (addr, &ide); + ide_write_reg (ide, ide_reg, val); } static int gayle_read (uaecptr addr) @@ -1500,6 +1509,7 @@ static uae_u32 REGPARAM2 gayle_lget (uaecptr addr) } static uae_u32 REGPARAM2 gayle_wget (uaecptr addr) { + struct ide_hdf *ide = NULL; int ide_reg; uae_u16 v; #ifdef JIT @@ -1509,9 +1519,9 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr) addr -= NCR_OFFSET; return (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1); } - ide_reg = get_gayle_ide_reg (addr); + ide_reg = get_gayle_ide_reg (addr, &ide); if (ide_reg == IDE_DATA) - return ide_get_data (); + return ide_get_data (ide); v = gayle_bget (addr) << 8; v |= gayle_bget (addr + 1); return v; @@ -1538,6 +1548,7 @@ static void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value) } static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value) { + struct ide_hdf *ide = NULL; int ide_reg; #ifdef JIT special_mem |= S_WRITE; @@ -1548,9 +1559,9 @@ static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value) ncr_bput2 (addr + 1, value); return; } - ide_reg = get_gayle_ide_reg (addr); + ide_reg = get_gayle_ide_reg (addr, &ide); if (ide_reg == IDE_DATA) { - ide_put_data (value); + ide_put_data (ide, value); return; } gayle_bput (addr, value >> 8); @@ -1878,10 +1889,11 @@ static int pcmcia_write_min, pcmcia_write_max; static int pcmcia_oddevenflip; static uae_u16 pcmcia_idedata; -static int get_pcmcmia_ide_reg (uaecptr addr, int width) +static int get_pcmcmia_ide_reg (uaecptr addr, int width, struct ide_hdf **ide) { int reg = -1; + *ide = NULL; addr &= 0x80000 - 1; if (addr < 0x20000) return -1; /* attribute */ @@ -1893,9 +1905,9 @@ static int get_pcmcmia_ide_reg (uaecptr addr, int width) addr &= ~0x10000; addr |= 1; } - ide = idedrive[PCMCIA_IDE_ID * 2]; - if (ide->ide_drv) - ide = idedrive[PCMCIA_IDE_ID * 2 + 1]; + *ide = idedrive[PCMCIA_IDE_ID * 2]; + if ((*ide)->ide_drv) + *ide = idedrive[PCMCIA_IDE_ID * 2 + 1]; if (pcmcia_configured == 1) { // IO mapped linear reg = addr & 15; @@ -1930,6 +1942,7 @@ static int get_pcmcmia_ide_reg (uaecptr addr, int width) static uae_u32 gayle_attr_read (uaecptr addr) { + struct ide_hdf *ide = NULL; uae_u8 v = 0; if (PCMCIA_LOG > 1) @@ -1948,17 +1961,17 @@ static uae_u32 gayle_attr_read (uaecptr addr) return pcmcia_configuration[offset]; } if (pcmcia_configured >= 0) { - int reg = get_pcmcmia_ide_reg (addr, 1); + int reg = get_pcmcmia_ide_reg (addr, 1, &ide); if (reg >= 0) { if (reg == 0) { if (addr >= 0x30000) { return pcmcia_idedata & 0xff; } else { - pcmcia_idedata = ide_get_data (); + pcmcia_idedata = ide_get_data (ide); return (pcmcia_idedata >> 8) & 0xff; } } else { - return ide_read_reg (reg); + return ide_read_reg (ide, reg); } } } @@ -1969,6 +1982,7 @@ static uae_u32 gayle_attr_read (uaecptr addr) static void gayle_attr_write (uaecptr addr, uae_u32 v) { + struct ide_hdf *ide = NULL; if (PCMCIA_LOG > 1) write_log (_T("PCMCIA ATTR W: %x=%x %x\n"), addr, v, M68K_GETPC); addr &= 0x80000 - 1; @@ -1996,7 +2010,7 @@ static void gayle_attr_write (uaecptr addr, uae_u32 v) } } if (pcmcia_configured >= 0) { - int reg = get_pcmcmia_ide_reg (addr, 1); + int reg = get_pcmcmia_ide_reg (addr, 1, &ide); if (reg >= 0) { if (reg == 0) { if (addr >= 0x30000) { @@ -2004,11 +2018,11 @@ static void gayle_attr_write (uaecptr addr, uae_u32 v) } else { pcmcia_idedata &= 0xff00; pcmcia_idedata |= v & 0xff; - ide_put_data (pcmcia_idedata); + ide_put_data (ide, pcmcia_idedata); } return; } - ide_write_reg (reg, v); + ide_write_reg (ide, reg, v); } } } @@ -2411,10 +2425,11 @@ static uae_u32 REGPARAM2 gayle_attr_wget (uaecptr addr) #endif if (pcmcia_type == PCMCIA_IDE && pcmcia_configured >= 0) { - int reg = get_pcmcmia_ide_reg (addr, 2); + struct ide_hdf *ide = NULL; + int reg = get_pcmcmia_ide_reg (addr, 2, &ide); if (reg == IDE_DATA) { // 16-bit register - pcmcia_idedata = ide_get_data (); + pcmcia_idedata = ide_get_data (ide); return pcmcia_idedata; } } @@ -2445,11 +2460,12 @@ static void REGPARAM2 gayle_attr_wput (uaecptr addr, uae_u32 value) #endif if (pcmcia_type == PCMCIA_IDE && pcmcia_configured >= 0) { - int reg = get_pcmcmia_ide_reg (addr, 2); + struct ide_hdf *ide = NULL; + int reg = get_pcmcmia_ide_reg (addr, 2, &ide); if (reg == IDE_DATA) { // 16-bit register pcmcia_idedata = value; - ide_put_data (pcmcia_idedata); + ide_put_data (ide, pcmcia_idedata); return; } } @@ -2647,6 +2663,8 @@ static void initide (void) if (isrestore ()) return; for (i = 0; i < TOTAL_IDE; i++) { + struct ide_hdf *ide; + ide = idedrive[i * 2 + 0]; ide->regs0 = &ide->regs; ide->regs1 = &idedrive[i * 2 + 1]->regs; @@ -2657,7 +2675,7 @@ static void initide (void) ide->regs0 = &idedrive[i * 2 + 0]->regs; ide->pair = idedrive[i * 2 + 0]; - reset_device (true); + reset_device (ide, true); } ide_splitter = 0; if (isdrive (idedrive[2]) || isdrive(idedrive[3])) { diff --git a/gencpu.cpp b/gencpu.cpp index a6b8f637..c291ea92 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -2293,6 +2293,10 @@ static void gen_opcode (unsigned long int opcode) case i_BCHG: case i_BCLR: case i_BSET: + // on 68000 these have weird side-effect, if EA points to write-only custom register + //during instruction's read access CPU data lines appear as zero to outside world, + // (normally previously fetched data appears in data lines if reading write-only register) + // this allows stupid things like bset #2,$dff002 to work "correctly" genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC | GF_RMW); fill_prefetch_next (); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 1cd6f8b3..246c511a 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -661,7 +661,7 @@ static int hdf_seek (struct hardfiledata *hfd, uae_u64 offset) abort(); } if (offset >= hfd->physsize - hfd->virtual_size) { - gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X)\n"), offset, hfd->physsize); + gui_message (_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size); abort (); } offset += hfd->offset; diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index c035b646..bf75cbc0 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -1692,7 +1692,7 @@ void rp_screenmode_changed (void) { write_log (_T("rp_screenmode_changed\n")); if (!screenmode_request) { - screenmode_request = 2; + screenmode_request = 6; write_log (_T("rp_screenmode_changed -> screenmode_request started\n")); } } @@ -1744,9 +1744,9 @@ void rp_vsync (void) if (screenmode_request) { screenmode_request--; if (screenmode_request == 0) { + write_log (_T("RP_IPC_TO_HOST_SCREENMODE screenmode_request timeout\n")); struct RPScreenMode sm = { 0 }; get_screenmode (&sm, &currprefs); - write_log (_T("RP_IPC_TO_HOST_SCREENMODE screenmode_request timeout\n")); RPSendMessagex (RP_IPC_TO_HOST_SCREENMODE, 0, 0, &sm, sizeof sm, &guestinfo, NULL); } } diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 161f10d0..bed9792f 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -592,7 +592,7 @@ static void releasecapture (void) { if (!showcursor) return; - write_log (_T("releasecapture\n")); + //write_log (_T("releasecapture\n")); ClipCursor (NULL); ReleaseCapture (); ShowCursor (TRUE); @@ -603,7 +603,7 @@ void updatemouseclip (void) { if (showcursor) { ClipCursor (&amigawin_rect); - write_log (_T("CLIP %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, isfullscreen ()); + //write_log (_T("CLIP %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, isfullscreen ()); } } @@ -613,7 +613,7 @@ void updatewinrect (bool allowfullscreen) if (!allowfullscreen && f > 0) return; GetWindowRect (hAmigaWnd, &amigawin_rect); - write_log (_T("GetWindowRect %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, f); + //write_log (_T("GetWindowRect %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, f); if (f == 0) { changed_prefs.gfx_size_win.x = amigawin_rect.left; changed_prefs.gfx_size_win.y = amigawin_rect.top; @@ -650,7 +650,7 @@ static bool iswindowfocus (void) static void setmouseactive2 (int active, bool allowpause) { - write_log (_T("setmouseactive %d->%d showcursor=%d focus=%d recap=%d\n"), mouseactive, active, showcursor, focus, recapture); + //write_log (_T("setmouseactive %d->%d showcursor=%d focus=%d recap=%d\n"), mouseactive, active, showcursor, focus, recapture); if (active == 0) releasecapture (); if (mouseactive == active && active >= 0) diff --git a/od-win32/win32.h b/od-win32/win32.h index 4763cdbe..7e997658 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("14") +#define WINUAEBETA _T("15") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2013, 3, 30) +#define WINUAEDATE MAKEBD(2013, 4, 6) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 239f3631..d6a3af9d 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,6 +1,17 @@ - restore only single input target to default. +Beta 15: + +- IDE emulation drive status bit fix (DRQ and BSY active at the same time), fixes data corruption if IDEFix was active. (b5). +- Added support for previously unemulated and undocumented feature, sprites can appear 1 lores pixel earlier than first bitplane pixel. + (First BPL1DAT access enables sprites immediately, only bitplanes need HRM documented delay). + This is not normally visible because horizontal DIWSTRT usually equals bitplane left edge. + Fixes "original" Rink-a-Dink/Lemon missing left white border in rotozoomer part. +- Do not use "8372 (Fat-hr) (agnushr),rev 5" VPOSR chipset id when config is ECS 2M chip RAM. This ID does not appear to exist in real world. +- Both bordersprite and borderblank active: sprites were incorrectly visible in upper and lower borders (241b13) +- Rewritten b4 "Subtle Shades" update, it was wrong and caused bad side-effects. + Beta 14: - A3000 SCSI emulation crashed if no SCSI drives configured.