From: Toni Wilen Date: Sun, 20 Oct 2013 12:05:09 +0000 (+0300) Subject: 2700b9 X-Git-Tag: 2700~9 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=be4bcd69856ddbf53a615833a057ca4fff41c8a9;p=francis%2Fwinuae.git 2700b9 --- diff --git a/build68k.cpp b/build68k.cpp index 4b292db9..be6ed1a6 100644 --- a/build68k.cpp +++ b/build68k.cpp @@ -231,10 +231,16 @@ int main(int argc, char **argv) getnextch(); if (nextch == '-') { - char c, fm[20]; + int neg; + char fm[20]; getnextch(); while (isspace(nextch)) getnextch(); + neg = 1; + if (nextch == '-') { + neg = -1; + getnextch(); + } for (;;) { if (nextch < '0' || nextch > '9') break; @@ -242,6 +248,7 @@ int main(int argc, char **argv) head += nextch - '0'; nextch = fgetc (tablef); } + head *= neg; while (isspace(nextch)) getnextch(); for (;;) { diff --git a/cfgfile.cpp b/cfgfile.cpp index 47e45f5f..3cfd9d20 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1308,6 +1308,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_bool (f, _T("denise_noehb"), p->cs_denisenoehb); cfgfile_dwrite_bool (f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug); cfgfile_dwrite_bool (f, _T("ics_agnus"), p->cs_dipagnus); + cfgfile_dwrite_bool (f, _T("cia_todbug"), p->cs_ciatodbug); cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks); cfgfile_dwrite_bool (f, _T("fastmem_autoconfig"), p->fastmem_autoconfig); @@ -3209,6 +3210,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno (option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0) || cfgfile_yesno (option, value, _T("ksmirror_a8"), &p->cs_ksmirror_a8) || cfgfile_yesno (option, value, _T("resetwarning"), &p->cs_resetwarning) + || cfgfile_yesno (option, value, _T("cia_todbug"), &p->cs_ciatodbug) || cfgfile_yesno (option, value, _T("denise_noehb"), &p->cs_denisenoehb) || cfgfile_yesno (option, value, _T("ics_agnus"), &p->cs_dipagnus) || cfgfile_yesno (option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug) @@ -4964,6 +4966,7 @@ void default_prefs (struct uae_prefs *p, int type) p->cs_df0idhw = 1; p->cs_slowmemisfast = 0; p->cs_resetwarning = 1; + p->cs_ciatodbug = false; p->gfx_filter = 0; for (int i = 0; i <= 2 * MAX_FILTERSHADERS; i++) { @@ -5210,6 +5213,7 @@ static void buildin_default_prefs (struct uae_prefs *p) p->cs_ciaatod = 0; p->cs_df0idhw = 1; p->cs_resetwarning = 0; + p->cs_ciatodbug = false; _tcscpy (p->romfile, _T("")); _tcscpy (p->romextfile, _T("")); @@ -5743,6 +5747,7 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_df0idhw = 1; p->cs_resetwarning = 1; p->cs_slowmemisfast = 0; + p->cs_ciatodbug = false; switch (p->cs_compatible) { diff --git a/cia.cpp b/cia.cpp index c61382c0..6b6fcc89 100644 --- a/cia.cpp +++ b/cia.cpp @@ -450,21 +450,25 @@ void cia_parallelack (void) RethinkICRA (); } -static int checkalarm (unsigned long tod, unsigned long alarm, bool inc) +static bool checkalarm (unsigned long tod, unsigned long alarm, bool inc, int ab) { if (tod == alarm) - return 1; + return true; +// if (!ab) +// return false; + if (!currprefs.cs_ciatodbug) + return false; if (!inc) - return 0; + return false; /* emulate buggy TODMED counter. * it counts: .. 29 2A 2B 2C 2D 2E 2F 20 30 31 32 .. * (2F->20->30 only takes couple of cycles but it will trigger alarm.. */ if (tod & 0x000fff) - return 0; + return false; if (((tod - 1) & 0xfff000) == alarm) - return -1; - return 0; + return true; + return false; } STATIC_INLINE bool ciab_checkalarm (bool inc, bool irq) @@ -474,12 +478,13 @@ STATIC_INLINE bool ciab_checkalarm (bool inc, bool irq) // modes. Real hardware value written to ciabtod by KS is always // at least 1 or larger due to bus cycle delays when reading // old value. +#if 1 if ((munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000) { if (ciabtod == 0 && ciabalarm == 0) return false; } - int v = checkalarm (ciabtod, ciabalarm, inc); - if (v > 0) { +#endif + if (checkalarm (ciabtod, ciabalarm, inc, 1)) { #if CIAB_DEBUG_IRQ write_log (_T("CIAB tod %08x %08x\n"), ciabtod, ciabalarm); #endif @@ -494,8 +499,7 @@ STATIC_INLINE bool ciab_checkalarm (bool inc, bool irq) STATIC_INLINE void ciaa_checkalarm (bool inc) { - int v = checkalarm (ciaatod, ciaaalarm, inc); - if (v > 0) { + if (checkalarm (ciaatod, ciaaalarm, inc, 0)) { #if CIAA_DEBUG_IRQ write_log (_T("CIAA tod %08x %08x\n"), ciaatod, ciaaalarm); #endif @@ -680,12 +684,21 @@ static int ciab_tod_event_state; // Possibly TICK input pin has built-in debounce circuit #define TOD_INC_DELAY (14 * (ECLOCK_DATA_CYCLE + ECLOCK_WAIT_CYCLE) / 2) -static void CIAB_tod_inc (uae_u32 v) +static void CIAB_tod_inc (bool irq) { ciab_tod_event_state = 3; // done + if (!ciaatodon) + return; ciabtod++; ciabtod &= 0xFFFFFF; - ciab_checkalarm (true, true); + ciab_checkalarm (true, irq); +} + +static void CIAB_tod_inc_event (uae_u32 v) +{ + if (ciab_tod_event_state != 2) + return; + CIAB_tod_inc (true); } // Someone reads or writes TOD registers, sync TOD increase @@ -697,31 +710,24 @@ static void CIAB_tod_check (void) hpos -= ciab_tod_hoffset; if (hpos >= 0 || currprefs.m68k_speed < 0) { // Program should see the changed TOD - CIAB_tod_inc (0); + CIAB_tod_inc (true); return; } // Not yet, add event to guarantee exact TOD inc position ciab_tod_event_state = 2; // event active - event2_newevent_xx (-1, -hpos, 0, CIAB_tod_inc); + event2_newevent_xx (-1, -hpos, 0, CIAB_tod_inc_event); } void CIAB_tod_handler (int hoffset) { - uae_u32 v; - - ciab_tod_hoffset = hoffset + TOD_INC_DELAY; if (!ciabtodon) return; + ciab_tod_hoffset = hoffset + TOD_INC_DELAY; ciab_tod_event_state = 1; // TOD inc needed - v = ciabtod; - ciabtod++; - ciabtod &= 0xFFFFFF; - bool irq = ciab_checkalarm (false, false); - ciabtod = v; - if (irq) { + if (checkalarm ((ciabtod + 1) & 0xffffff, ciabalarm, true, 1)) { // causes interrupt on this line, add event ciab_tod_event_state = 2; // event active - event2_newevent_xx (-1, ciab_tod_hoffset, 0, CIAB_tod_inc); + event2_newevent_xx (-1, ciab_tod_hoffset, 0, CIAB_tod_inc_event); } } @@ -730,7 +736,7 @@ void CIA_hsync_posthandler (bool dotod) // Previous line was supposed to increase TOD but // no one cared. Do it now. if (ciab_tod_event_state == 1) - CIAB_tod_inc (0); + CIAB_tod_inc (false); ciab_tod_event_state = 0; if (currprefs.tod_hack && ciaatodon) @@ -1541,7 +1547,7 @@ addrbank cia_bank = { cia_lget, cia_wget, cia_bget, cia_lput, cia_wput, cia_bput, default_xlate, default_check, NULL, _T("CIA"), - cia_lgeti, cia_wgeti, ABFLAG_IO, 0x3f00, 0xbfc000 + cia_lgeti, cia_wgeti, ABFLAG_IO, 0x3f01, 0xbfc000 }; // Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected diff --git a/custom.cpp b/custom.cpp index 14442926..000feda2 100644 --- a/custom.cpp +++ b/custom.cpp @@ -194,6 +194,7 @@ int maxhpos = MAXHPOS_PAL; int maxhpos_short = MAXHPOS_PAL; int maxvpos = MAXVPOS_PAL; int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes) +int maxvpos_display = MAXVPOS_PAL; // value used for display size int hsyncendpos, hsyncstartpos; static int maxvpos_total = 511; int minfirstline = VBLANK_ENDLINE_PAL; @@ -259,7 +260,8 @@ uae_u8 cycle_line[256]; static uae_u16 bplxdat[8]; static bool bpl1dat_written, bpl1dat_early, bpl1dat_written_at_least_once; static bool bpldmawasactive; -static uae_s16 bpl1mod, bpl2mod; +static uae_s16 bpl1mod, bpl2mod, dbpl1mod, dbpl2mod; +static int dbpl1mod_on, dbpl2mod_on; static uaecptr prevbpl[2][MAXVPOS][8]; static uaecptr bplpt[8], bplptx[8]; @@ -385,13 +387,14 @@ static uae_u32 thisline_changed; #endif static struct decision thisline_decision; -static int fetch_cycle, fetch_modulo_cycle, fetch_align; +static int fetch_cycle, fetch_modulo_cycle; enum plfstate { plf_idle, plf_start, plf_active, + plf_wait_stop, plf_passed_stop, plf_passed_stop2, plf_end, @@ -656,9 +659,30 @@ STATIC_INLINE int GET_PLANES_LIMIT (uae_u16 bc0) /* Programmed rates or superhires (!) disable normal DMA limits */ #define HARD_DDF_START (HARD_DDF_LIMITS_DISABLED ? 0x04 : 0x18) -static void add_modulo (int nr) +static void reset_bplmod (void) +{ + if (dbpl1mod_on > 0) { + bpl1mod = dbpl1mod; + dbpl1mod_on = 0; + } + if (dbpl2mod_on > 0) { + bpl2mod = dbpl2mod; + dbpl2mod_on = 0; + } +} + +static void add_modulo (int hpos, int nr) { int mod; + + if (dbpl1mod_on != hpos && dbpl1mod_on) { + bpl1mod = dbpl1mod; + dbpl1mod_on = 0; + } + if (dbpl2mod_on != hpos && dbpl2mod_on) { + bpl2mod = dbpl2mod; + dbpl2mod_on = 0; + } if (fmode & 0x4000) { if (((diwstrt >> 8) ^ vpos) & 1) mod = bpl2mod; @@ -670,12 +694,14 @@ static void add_modulo (int nr) mod = bpl1mod; bplpt[nr] += mod; bplptx[nr] += mod; + reset_bplmod (); } static void add_modulos (void) { int m1, m2; + reset_bplmod (); if (fmode & 0x4000) { if (((diwstrt >> 8) ^ vpos) & 1) m1 = m2 = bpl2mod; @@ -727,7 +753,7 @@ static void finish_playfield_line (void) are contained in an indivisible block during which ddf is active. E.g. if DDF starts at 0x30, and fetchunit is 8, then possible DDF stops are 0x30 + n * 8. */ -static int fetchunit, fetchunit_mask, fetchunit_align_mask; +static int fetchunit, fetchunit_mask; /* The delay before fetching the same bitplane again. Can be larger than the number of bitplanes; in that case there are additional empty cycles with no data fetch (this happens for high fetchmodes and low @@ -865,7 +891,7 @@ we can do more work at once. */ static int toscr_nbits; /* undocumented bitplane delay hardware feature */ -static int delayoffset, delayoffset2; +static int delayoffset; STATIC_INLINE void compute_delay_offset (void) { @@ -924,7 +950,7 @@ STATIC_INLINE int isocs7planes (void) int is_bitplane_dma (int hpos) { - if (fetch_state == fetch_not_started || hpos < plfstrt) + if (fetch_state == fetch_not_started || hpos < plfstrt || plf_state == plf_wait_stop) return 0; if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle) @@ -934,7 +960,7 @@ int is_bitplane_dma (int hpos) STATIC_INLINE int is_bitplane_dma_inline (int hpos) { - if (fetch_state == fetch_not_started || hpos < plfstrt) + if (fetch_state == fetch_not_started || hpos < plfstrt || plf_state == plf_wait_stop) return 0; if ((plf_state >= plf_end && hpos >= thisline_decision.plfright) || hpos >= estimated_last_fetch_cycle) @@ -968,8 +994,8 @@ static void compute_toscr_delay_1 (int bplcon1) int delaymask; int fetchwidth = 16 << fetchmode; - delay1 += delayoffset + delayoffset2; - delay2 += delayoffset + delayoffset2; + delay1 += delayoffset; + delay2 += delayoffset; delaymask = (fetchwidth - 1) >> toscr_res; toscr_delay1 = (delay1 & delaymask) << toscr_res; toscr_delay1 |= shdelay1 >> (RES_MAX - toscr_res); @@ -1008,13 +1034,21 @@ static void setup_fmodes (int hpos) bplcon0_planes_limit = GET_PLANES_LIMIT (bplcon0); fetchunit = fetchunits[fetchmode * 4 + bplcon0_res]; fetchunit_mask = fetchunit - 1; - fetchunit_align_mask = fetchunit >> 1; fetchstart_shift = fetchstarts[fetchmode * 4 + bplcon0_res]; fetchstart = 1 << fetchstart_shift; fetchstart_mask = fetchstart - 1; fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res]; fm_maxplane = 1 << fm_maxplane_shift; fetch_modulo_cycle = fetchunit - fetchstart; + + // wacky pixels / raf megademo hires unaligned scroller feature + if (thisline_decision.plfleft < 0) { + if (fetch_cycle & (fetchunit >> 1)) { + fetch_cycle &= ~(fetchunit_mask >> 1); + fetch_cycle += fetchunit; + } + } + if (is_bitplane_dma (hpos - 1)) cycle_line[hpos - 1] = 1; curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit]; @@ -1025,8 +1059,7 @@ static void setup_fmodes (int hpos) bpldmasetupphase = 0; toscr_nr_planes_agnus = bplcon0_planes; if (isocs7planes ()) { - if (toscr_nr_planes_agnus < 6) - toscr_nr_planes_agnus = 6; + toscr_nr_planes_agnus = 6; } ddf_change = vpos; } @@ -1162,6 +1195,15 @@ STATIC_INLINE void fetch (int nr, int fm, int hpos) uaecptr p = bplpt[nr]; bplpt[nr] += 2 << fm; bplptx[nr] += 2 << fm; + + if (hpos == 0xe2 && !(beamcon0 & 0x80)) { + static int warned = 30; + if (warned > 0) { + write_log (_T("WARNING: BPL fetch at hpos 0x%02X!\n"), hpos); + warned--; + } + } + if (nr == 0) bpl1dat_written = true; #ifdef DEBUGGER @@ -1186,7 +1228,7 @@ STATIC_INLINE void fetch (int nr, int fm, int hpos) #endif } if (plf_state == plf_passed_stop2 && fetch_cycle >= (fetch_cycle & ~fetchunit_mask) + fetch_modulo_cycle) { - add_modulo (nr); + add_modulo (hpos, nr); if ((currprefs.cs_hacks & 2) || 0) do_right_ddf_hack (nr, hpos); @@ -1761,7 +1803,7 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int maybe_check (pos); - if (dma) { + if (dma && plf_state != plf_wait_stop) { /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0. This means that the remaining cycles are idle; we'll fall through the whole switch without doing anything. */ @@ -1780,29 +1822,17 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int } break; case 4: - if ((fetch_cycle & fetchunit_align_mask) == fetch_align) { - switch (cycle_start) { - case 0: fetch (3, fm, pos); break; - case 1: fetch (1, fm, pos); break; - case 2: fetch (2, fm, pos); break; - case 3: - fetch (0, fm, pos); - fetch_align += fetchunit_align_mask; - fetch_align &= fetchunit_align_mask; - break; - } + switch (cycle_start) { + case 0: fetch (3, fm, pos); break; + case 1: fetch (1, fm, pos); break; + case 2: fetch (2, fm, pos); break; + case 3: fetch (0, fm, pos); break; } break; case 2: - if ((fetch_cycle & fetchunit_align_mask) == fetch_align) { - switch (cycle_start) { - case 0: fetch (1, fm, pos); break; - case 1: - fetch (0, fm, pos); - fetch_align += fetchunit_align_mask; - fetch_align &= fetchunit_align_mask; - break; - } + switch (cycle_start) { + case 0: fetch (1, fm, pos); break; + case 1: fetch (0, fm, pos); break; } break; } @@ -1930,9 +1960,22 @@ STATIC_INLINE void update_fetch (int until, int fm) if (one_fetch_cycle (pos, ddfstop_to_test, dma, fm)) return; } + +#if 1 + // vdiw getting cleared mid-scan = fetches also stop + if (diwstate == DIW_waiting_start && plf_state < plf_wait_stop) { + // ecs = continue at passed_stop + // ocs = line is done + if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) + plf_state = plf_wait_stop; + else + plf_state = plf_passed_stop2; + } +#endif + #ifdef SPEEDUP /* Unrolled version of the for loop below. */ - if (plf_state < plf_passed_stop && ddf_change != vpos && ddf_change + 1 != vpos + if (plf_state < plf_wait_stop && ddf_change != vpos && ddf_change + 1 != vpos && dma && (fetch_cycle & fetchstart_mask) == (fm_maxplane & fetchstart_mask) && !badmode && !debug_dma @@ -1974,7 +2017,6 @@ STATIC_INLINE void update_fetch (int until, int fm) add_modulos (); pos += count; fetch_cycle += count; - fetch_align ^= count & fetchunit_align_mask; } } #endif @@ -2052,7 +2094,6 @@ static void start_bpl_dma (int hpos, int hstart) plfstrt_sprite = plfstrt; fetch_cycle = 0; - fetch_align = 0; compute_toscr_delay (last_fetch_hpos, bplcon1); /* If someone already wrote BPL1DAT, clear the area between that point and the real fetch start. */ @@ -2127,33 +2168,36 @@ STATIC_INLINE void decide_line (int hpos) if (hpos <= last_decide_line_hpos) return; - if (fetch_state == fetch_not_started && (diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) { + if (fetch_state == fetch_not_started) { int start = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? plfstrt - 4 : HARD_DDF_START_REAL - 2; - int ok = 0; if (last_decide_line_hpos < start && hpos >= start) { if (plf_state == plf_idle || plf_state == plf_end) plf_state = plf_start; } - if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { - if (plf_state == plf_start) - plf_state = plf_active; - if (plf_state == plf_active) - ok = 1; - /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored - * (correct fix would be emulate this delay for every custom register, but why bother..) */ - if (hpos - 2 == ddfstrt_old_hpos) - ok = 0; - } - if (ok && diwstate == DIW_waiting_stop) { - if (dmaen (DMA_BITPLANE)) { - start_bpl_dma (hpos, plfstrt); - estimate_last_fetch_cycle (plfstrt); + if ((diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) { + int ok = 0; + + if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { + if (plf_state == plf_start) + plf_state = plf_active; + if (plf_state == plf_active) + ok = 1; + /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored + * (correct fix would be emulate this delay for every custom register, but why bother..) */ + if (hpos - 2 == ddfstrt_old_hpos) + ok = 0; + } + if (ok && diwstate == DIW_waiting_stop) { + if (dmaen (DMA_BITPLANE)) { + start_bpl_dma (hpos, plfstrt); + estimate_last_fetch_cycle (plfstrt); + } + last_decide_line_hpos = hpos; + #ifndef CUSTOM_SIMPLE + do_sprites (hpos); + #endif + return; } - last_decide_line_hpos = hpos; -#ifndef CUSTOM_SIMPLE - do_sprites (hpos); -#endif - return; } } @@ -2942,6 +2986,7 @@ static void reset_decisions (void) bpldmasetupphase = 0; ddfstrt_old_hpos = -1; bpldmawasactive = false; + reset_bplmod (); if (plf_state > plf_active) plf_state = plf_idle; @@ -3080,7 +3125,7 @@ struct chipset_refresh *get_chipset_refresh (void) for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) { struct chipset_refresh *cr = &currprefs.cr[i]; if ((cr->horiz < 0 || cr->horiz == maxhpos) && - (cr->vert < 0 || cr->vert == maxvpos_nom) && + (cr->vert < 0 || cr->vert == maxvpos_display) && (cr->ntsc < 0 || (cr->ntsc > 0 && isntsc) || (cr->ntsc == 0 && !isntsc)) && (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) && (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) && @@ -3210,7 +3255,7 @@ void compute_framesync (void) gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; gfxvidinfo.drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1; gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.inheight = ((maxvpos_nom + 1) - minfirstline + 1) << currprefs.gfx_vresolution; + gfxvidinfo.drawbuffer.inheight = ((maxvpos_display + 1) - minfirstline + 1) << currprefs.gfx_vresolution; gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; } @@ -3308,6 +3353,7 @@ void init_hz (bool fullinit) vblank_hz = vblank_hz_lof; maxvpos_nom = maxvpos; + maxvpos_display = maxvpos; if (vpos_count > 0) { // we come here if vpos_count != maxvpos and beamcon0 didn't change // (someone poked VPOSW) @@ -3316,6 +3362,13 @@ void init_hz (bool fullinit) vblank_hz = (isntsc ? 15734 : 15625.0) / vpos_count; vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; maxvpos_nom = vpos_count - (lof_current ? 1 : 0); + if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) { + maxvpos_display = maxvpos_nom; + } else if (maxvpos_nom < 256) { + maxvpos_display = 255; + } else { + maxvpos_display = 313; + } reset_drawing (); } if (beamcon0 & 0x80) { @@ -3339,6 +3392,7 @@ void init_hz (bool fullinit) minfirstline = maxvpos - 1; sprite_vblank_endline = minfirstline - 2; maxvpos_nom = maxvpos; + maxvpos_display = maxvpos; equ_vblank_endline = -1; doublescan = htotal <= 164 ? 1 : 0; programmedmode = true; @@ -3347,6 +3401,8 @@ void init_hz (bool fullinit) } if (maxvpos_nom >= MAXVPOS) maxvpos_nom = MAXVPOS; + if (maxvpos_display >= MAXVPOS) + maxvpos_display = MAXVPOS; if (currprefs.gfx_scandoubler && doublescan == 0) doublescan = -1; if (doublescan != odbl || maxvpos != omaxvpos) @@ -4238,21 +4294,36 @@ STATIC_INLINE void BPLCON4 (int hpos, uae_u16 v) static void BPL1MOD (int hpos, uae_u16 v) { v &= ~1; - if ((uae_s16)bpl1mod == (uae_s16)v) - return; - decide_line (hpos); - decide_fetch (hpos); - bpl1mod = v; + if ((uae_s16)bpl1mod != (uae_s16)v) { + decide_line (hpos); + decide_fetch (hpos); + } + // write to BPLxMOD one cycle before + // BPL fetch that also adds modulo: + // Old BPLxMOD value is added. + if (is_bitplane_dma (hpos + 1) & 1) { + dbpl1mod = v; + dbpl1mod_on = hpos + 1; + } else { + bpl1mod = v; + dbpl1mod_on = 0; + } } static void BPL2MOD (int hpos, uae_u16 v) { v &= ~1; - if ((uae_s16)bpl2mod == (uae_s16)v) - return; - decide_line (hpos); - decide_fetch (hpos); - bpl2mod = v; + if ((uae_s16)bpl2mod != (uae_s16)v) { + decide_line (hpos); + decide_fetch (hpos); + } + if (is_bitplane_dma (hpos + 1) & 2) { + dbpl2mod = v; + dbpl2mod_on = hpos + 1; + } else { + bpl2mod = v; + dbpl2mod_on = 0; + } } /* Needed in special OCS/ECS "7-plane" mode, @@ -4507,11 +4578,13 @@ STATIC_INLINE void SPRxCTLPOS (int num) } #endif s->xpos = sprxp; - s->vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); - s->vstop = (sprctl[num] >> 8) | ((sprctl[num] << 7) & 0x100); + s->vstart = sprpos[num] >> 8; + s->vstart |= (sprctl[num] & 0x04) ? 0x0100 : 0; + s->vstop = sprctl[num] >> 8; + s->vstop |= (sprctl[num] & 0x02) ? 0x100 : 0; if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - s->vstart |= (sprctl[num] << 3) & 0x200; - s->vstop |= (sprctl[num] << 4) & 0x200; + s->vstart |= (sprctl[num] & 0x40) ? 0x0200 : 0; + s->vstop |= (sprctl[num] & 0x20) ? 0x0200 : 0; } sprstartstop (s); } @@ -4523,7 +4596,7 @@ STATIC_INLINE void SPRxCTL_1 (uae_u16 v, int num, int hpos) spr_arm (num, 0); SPRxCTLPOS (num); #if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dCTL %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n"), vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC); } @@ -4536,7 +4609,7 @@ STATIC_INLINE void SPRxPOS_1 (uae_u16 v, int num, int hpos) sprpos[num] = v; SPRxCTLPOS (num); #if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dPOS %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n"), vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC); } @@ -4551,8 +4624,8 @@ STATIC_INLINE void SPRxDATA_1 (uae_u16 v, int num, int hpos) sprdata[num][3] = v; #endif spr_arm (num, 1); -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dDATA %04X P=%06X D=%d A=%d PC=%x\n"), vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC); } @@ -4566,8 +4639,8 @@ STATIC_INLINE void SPRxDATB_1 (uae_u16 v, int num, int hpos) sprdatb[num][2] = v; sprdatb[num][3] = v; #endif -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dDATB %04X P=%06X D=%d A=%d PC=%x\n"), vpos, hpos, num, v, spr[num].pt, spr[num].dmastate, spr[num].armed, M68K_GETPC); } @@ -4585,7 +4658,7 @@ static void SPRxPTH (int hpos, uae_u16 v, int num) spr[num].pt |= (uae_u32)v << 16; } #if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dPTH %06X\n"), vpos, hpos, num, spr[num].pt); } #endif @@ -4598,7 +4671,7 @@ static void SPRxPTL (int hpos, uae_u16 v, int num) spr[num].pt |= v & ~1; } #if SPRITE_DEBUG > 0 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dPTL %06X\n"), vpos, hpos, num, spr[num].pt); } #endif @@ -5354,13 +5427,13 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) return; } #endif -#if SPRITE_DEBUG > 3 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) +#if SPRITE_DEBUG >= 3 * 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) write_log (_T("%d:%d:slot%d:%d\n"), vpos, hpos, num, cycle); #endif if (vpos == s->vstart) { #if SPRITE_DEBUG > 0 - if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) + if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) write_log (_T("%d:%d:SPR%d START\n"), vpos, hpos, num); #endif s->dmastate = 1; @@ -5369,7 +5442,7 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) } if (vpos == s->vstop || vpos == sprite_vblank_endline) { #if SPRITE_DEBUG > 0 - if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) + if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) write_log (_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); #endif s->dmastate = 0; @@ -5412,8 +5485,12 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) sprstartstop (s); } } -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { + if (vpos == sprite_vblank_endline) { + // s->vstart == sprite_vblank_endline won't enable the sprite. + s->dmastate = 0; + } +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); } #endif @@ -5422,8 +5499,8 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) uae_u16 data; data = sprite_fetch (s, dma, hpos, cycle, 1); -#if SPRITE_DEBUG > 1 - if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY) { +#if SPRITE_DEBUG >= 256 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); } #endif @@ -5708,7 +5785,7 @@ static bool framewait (void) t = vsynctimebase * 2 / 3; if (currprefs.m68k_speed < 0) { - vsynctimeperline = (vsynctimebase - t) / (maxvpos_nom + 1); + vsynctimeperline = (vsynctimebase - t) / (maxvpos_display + 1); } else { vsynctimeperline = (vsynctimebase - t) / 3; } @@ -5792,7 +5869,7 @@ static bool framewait (void) vsyncmintime = now; vsyncwaittime = curr_time + (vsynctimebase - 0); - vsynctimeperline = max / (maxvpos_nom + 1); + vsynctimeperline = max / (maxvpos_display + 1); if (status <= 0 || vsynctimeperline < 1) vsynctimeperline = 1; vsyncmaxtime = now + max; @@ -5931,7 +6008,7 @@ static bool framewait (void) max = 0; vsynctimeperline = 1; } else { - vsynctimeperline = max / (maxvpos_nom + 1); + vsynctimeperline = max / (maxvpos_display + 1); } vsyncmaxtime = curr_time + max; @@ -6697,7 +6774,7 @@ static void hsync_handler_post (bool onvsync) } } } else { - if (vpos + 1 < maxvpos + lof_store && (vpos == maxvpos_nom * 1 / 3 || vpos == maxvpos_nom * 2 / 3)) { + if (vpos + 1 < maxvpos + lof_store && (vpos == maxvpos_display * 1 / 3 || vpos == maxvpos_display * 2 / 3)) { vsyncmintime += vsynctimeperline; if (!vsync_isdone () && !currprefs.turbo_emulation) { frame_time_t rpt = read_processor_time (); @@ -8312,8 +8389,8 @@ STATIC_INLINE int dma_cycle (void) int blitpri = dmacon & DMA_BLITPRI; hpos_old = current_hpos (); hpos = hpos_old + 1; - sync_copper (hpos); decide_line (hpos); + sync_copper (hpos); decide_fetch_ce (hpos); bpldma = is_bitplane_dma (hpos_old); if (bltstate != BLT_done) { @@ -8329,7 +8406,6 @@ STATIC_INLINE int dma_cycle (void) alloc_cycle (hpos_old, CYCLE_CPU); break; } - regs.ce020memcycles -= CYCLE_UNIT; do_cycles (1 * CYCLE_UNIT); /* bus was allocated to dma channel, wait for next cycle.. */ } @@ -8427,7 +8503,8 @@ uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode) if (debug_dma) dr->dat = v; #endif - //x_do_cycles_post (CYCLE_UNIT / 2, v); + if (currprefs.cpu_model == 68020) + x_do_cycles_post (CYCLE_UNIT / 2, v); return v; } @@ -8459,6 +8536,7 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) put_word (addr, v); else if (mode == 0) put_byte (addr, v); + x_do_cycles_post (CYCLE_UNIT, v); } @@ -8492,7 +8570,8 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v) else if (mode == 0) put_byte (addr, v); - //x_do_cycles_post (CYCLE_UNIT / 2, v); + if (currprefs.cpu_model == 68020) + x_do_cycles_post (CYCLE_UNIT / 2, v); } void do_cycles_ce (unsigned long cycles) @@ -8502,8 +8581,8 @@ void do_cycles_ce (unsigned long cycles) c = cycles + extra_cycle; while (cycles >= CYCLE_UNIT) { int hpos = current_hpos () + 1; - sync_copper (hpos); decide_line (hpos); + sync_copper (hpos); decide_fetch_ce (hpos); if (bltstate != BLT_done) decide_blitter (hpos); @@ -8518,7 +8597,6 @@ void do_cycles_ce020 (unsigned long cycles) unsigned long c; int extra; - sync_ce020 (); c = get_cycles (); extra = c & (CYCLE_UNIT - 1); if (extra) { @@ -8533,8 +8611,8 @@ void do_cycles_ce020 (unsigned long cycles) c = cycles; while (c >= CYCLE_UNIT) { int hpos = current_hpos () + 1; - sync_copper (hpos); decide_line (hpos); + sync_copper (hpos); decide_fetch_ce (hpos); if (bltstate != BLT_done) decide_blitter (hpos); @@ -8558,5 +8636,5 @@ bool ispal (void) { if (beamcon0 & 0x80) return currprefs.ntscmode == 0; - return maxvpos_nom >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2; + return maxvpos_display >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2; } diff --git a/disk.cpp b/disk.cpp index b2880e7d..b2bd64df 100644 --- a/disk.cpp +++ b/disk.cpp @@ -3655,7 +3655,7 @@ void DISK_reset (void) setamax (); } -int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) +int DISK_examine_image (struct uae_prefs *p, int num, struct diskinfo *di) { int drvsec; int ret, i; @@ -3666,7 +3666,8 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) int oldcyl, oldside; ret = 0; - *crc32 = 0; + memset (di, 0, sizeof di); + di->unreadable = true; oldcyl = drv->cyl; oldside = side; drv->cyl = 0; @@ -3676,8 +3677,10 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) side = oldside; return 1; } - *crc32 = zfile_crc32 (drv->diskfile); + di->crc32 = zfile_crc32 (drv->diskfile); + di->unreadable = false; decode_buffer (drv->bigmfmbuf, drv->cyl, 11, drv->ddhd, drv->filetype, &drvsec, sectable, 1); + di->hd = drvsec == 22; drv->cyl = oldcyl; side = oldside; if (sectable[0] == 0 || sectable[1] == 0) { @@ -3686,6 +3689,10 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) } crc = crc2 = 0; for (i = 0; i < 1024; i += 4) { + di->bootblock[i + 0] = writebuffer[i + 0]; + di->bootblock[i + 1] = writebuffer[i + 1]; + di->bootblock[i + 2] = writebuffer[i + 2]; + di->bootblock[i + 3] = writebuffer[i + 3]; uae_u32 v = (writebuffer[i] << 24) | (writebuffer[i + 1] << 16) | (writebuffer[i + 2] << 8) | writebuffer[i + 3]; if (i == 0) dos = v; @@ -3706,6 +3713,7 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32) ret = 3; goto end; } + di->bb_crc_valid = true; if (dos == 0x444f5300) ret = 10; else if (dos == 0x444f5301 || dos == 0x444f5302 || dos == 0x444f5303) diff --git a/drawing.cpp b/drawing.cpp index 19e98e11..a90a691f 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -1965,7 +1965,7 @@ void init_aspect_maps (void) if (currprefs.gfx_ycenter && !currprefs.gfx_filter_autoscale) { /* @@@ verify maxvpos vs. MAXVPOS */ - extra_y_adjust = (h - (maxvpos_nom << linedbl)) >> 1; + extra_y_adjust = (h - (maxvpos_display << linedbl)) >> 1; if (extra_y_adjust < 0) extra_y_adjust = 0; } @@ -2111,7 +2111,7 @@ static void pfield_expand_dp_bplconx (int regno, int v) regno -= 0x1000; switch (regno) { - case 0x100: // BPLCON1 + case 0x100: // BPLCON0 dp_for_drawing->bplcon0 = v; dp_for_drawing->bplres = GET_RES_DENISE (v); dp_for_drawing->nr_planes = GET_PLANES (v); @@ -2142,7 +2142,7 @@ static enum { color_match_acolors, color_match_full } color_match_type; line. Try to avoid copying color tables around whenever possible. */ static void adjust_drawing_colors (int ctable, int need_full) { - if (drawing_color_matches != ctable) { + if (drawing_color_matches != ctable || need_full < 0) { if (need_full) { color_reg_cpy (&colors_for_drawing, curr_color_tables + ctable); color_match_type = color_match_full; @@ -2323,7 +2323,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in int ohposblank = hposblank; do_color_changes (dummy_worker, decode_ham, lineno); hposblank = ohposblank; - adjust_drawing_colors (dp_for_drawing->ctable, dp_for_drawing->ham_seen || bplehb); + // reset colors to state before above do_color_changes() + adjust_drawing_colors (dp_for_drawing->ctable, (dp_for_drawing->ham_seen || bplehb) ? -1 : 0); + pfield_expand_dp_bplcon (); } bplham = dp_for_drawing->ham_at_start; } @@ -2511,13 +2513,13 @@ static void center_image (void) } /* Make sure the value makes sense */ - if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos_nom) - thisframe_y_adjust = maxvpos_nom - max_drawn_amiga_line; + if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos_display) + thisframe_y_adjust = maxvpos_display - max_drawn_amiga_line; if (thisframe_y_adjust < minfirstline) thisframe_y_adjust = minfirstline; thisframe_y_adjust_real = thisframe_y_adjust << linedbl; - tmp = (maxvpos_nom - thisframe_y_adjust + 1) << linedbl; + tmp = (maxvpos_display - thisframe_y_adjust + 1) << linedbl; if (tmp != max_ypos_thisframe) { last_max_ypos = tmp; if (last_max_ypos < 0) @@ -2624,7 +2626,7 @@ static void init_drawing_frame (void) if (thisframe_first_drawn_line > thisframe_last_drawn_line) thisframe_last_drawn_line = thisframe_first_drawn_line; - maxline = ((maxvpos_nom + 1) << linedbl) + 2; + maxline = ((maxvpos_display + 1) << linedbl) + 2; #ifdef SMART_UPDATE for (i = 0; i < maxline; i++) { switch (linestate[i]) { diff --git a/gencpu.cpp b/gencpu.cpp index 8994d0ec..b6d0c5cc 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -39,8 +39,11 @@ static int using_tracer; static int using_waitstates; static int cpu_level; static int count_read, count_write, count_cycles, count_ncycles; +static int count_cycles_ce020; static int count_read_ea, count_write_ea, count_cycles_ea; static const char *mmu_postfix; +static int memory_cycle_cnt; +static int did_prefetch; static int optimized_flags; @@ -71,6 +74,7 @@ static int mmufixupcnt; static int mmufixupstate; static int mmudisp020cnt; static bool candormw; +static bool genastore_done; static char rmw_varname[100]; #define GENA_GETV_NO_FETCH 0 @@ -93,6 +97,12 @@ static char *srcld, *dstld; static char *srcwd, *dstwd; static char *do_cycles, *disp000, *disp020; +#define fetchmode_fea 1 +#define fetchmode_cea 2 +#define fetchmode_fiea 3 +#define fetchmode_ciea 4 +#define fetchmode_jea 5 + static void term (void) { printf("Abort!\n"); @@ -149,6 +159,9 @@ static int m68k_pc_offset, m68k_pc_offset_old; static int insn_n_cycles, insn_n_cycles020; static int ir2irc; +static int tail_ce020, total_ce020, head_in_ea_ce020; +static bool head_ce020_cycs_done, tail_ce020_done; + static void fpulimit (void) { if (limit_braces) @@ -162,9 +175,88 @@ static void cpulimit (void) printf ("#ifndef CPUEMU_68000_ONLY\n"); } + +static void addcycles_ce020 (int cycles, char *s) +{ + if (!using_ce020) + return; + if (cycles > 0) { + if (s == NULL) + printf ("\t%s (%d);\n", do_cycles, cycles); + else + printf ("\t%s (%d); /* %d */\n", do_cycles, cycles, s); + } + count_cycles += cycles; + count_cycles_ce020 += cycles; +} +static void addcycles_ce020 (int cycles) +{ + addcycles_ce020 (cycles, NULL); +} + +static void get_prefetch_ce020 (void) +{ + if (!using_ce020) + return; + printf ("\tregs.irc = %s (%d);\n", prefetch_word, m68k_pc_offset); +} +static void get_prefetch_ce020_0 (void) +{ + if (!using_ce020) + return; + printf ("\tregs.irc = %s (0);\n", prefetch_word); +} + + +static void returntail (bool iswrite) +{ + if (!using_ce020) + return; + if (!tail_ce020_done) { + total_ce020 -= 2; + if (iswrite) { + printf("\t/* C - %d = %d */\n", memory_cycle_cnt, total_ce020 - memory_cycle_cnt); + total_ce020 -= memory_cycle_cnt; + } else { + printf("\t/* C = %d */\n", total_ce020); + } + if (0 && total_ce020 <= 0) { + printf ("\t/* C was zero */\n"); + total_ce020 = 1; + } + if (!did_prefetch) + get_prefetch_ce020 (); + if (total_ce020 > 0) + addcycles_ce020 (total_ce020); + + //printf ("\tregs.irc = %s;\n", prefetch_word); + if (0 && total_ce020 >= 2) { + printf ("\top_cycles = get_cycles () - op_cycles;\n"); + printf ("\top_cycles /= cpucycleunit;\n"); + printf ("\tif (op_cycles < %d) {\n", total_ce020); + printf ("\t\tdo_cycles_ce020 ((%d) - op_cycles);\n", total_ce020); + printf ("\t}\n"); + } +#if 0 + if (tail_ce020 > 0) { + printf ("\tregs.ce020_tail = %d * cpucycleunit;\n", tail_ce020); + printf ("\tregs.ce020_tail_cycles = get_cycles () + regs.ce020_tail;\n"); + } else { + printf ("\tregs.ce020_tail = 0;\n"); + } +#endif + tail_ce020_done = true; + } +} + + static void returncycles (char *s, int cycles) { if (using_ce || using_ce020) { + if (tail_ce020 == 1) + printf ("\tregs.ce020memcycles -= 1 * cpucycleunit; /* T=1 */ \n"); + else if (tail_ce020 == 2) + printf ("\tregs.ce020memcycles -= 2 * cpucycleunit; /* T=2 */\n"); printf ("%sreturn;\n", s); return; } @@ -177,33 +269,26 @@ static void addcycles_ce020 (char *name, int head, int tail, int cycles) return; if (!head && !tail && !cycles) return; - printf ("\t/* %d,%d,%d %s */\n", head, tail, cycles, name); + printf ("\t/* %s H:%d,T:%d,C:%d */\n", name, head, tail, cycles); } static void addcycles_ce020 (char *name, int head, int tail, int cycles, int ophead) { if (!using_ce020) return; - if (!head && !tail && !cycles && !ophead) + if (!head && !tail && !cycles && !ophead) { + printf ("\t/* OP zero */\n"); return; + } count_cycles += cycles; if (!ophead) { addcycles_ce020 (name, head, tail, cycles); } else if (ophead > 0) { - printf ("\t/* %d+%d=%d,%d,%d %s */\n", head, ophead, head + ophead, tail, cycles, name); + printf ("\t/* %s H:%d-,T:%d,C:%d */\n", name, head, tail, cycles); } else { - printf ("\t/* %d-%d=%d,%d,%d %s */\n", head, -ophead, head + ophead, tail, cycles, name); + printf ("\t/* %s H:%d+,T:%d,C:%d */\n", name, head, tail, cycles); } } -static void addcycles_ce020 (int cycles) -{ - if (!using_ce020) - return; - if (cycles > 0) - printf ("\t%s (%d);\n", do_cycles, cycles); - count_cycles += cycles; -} - static void addcycles000 (int cycles) { if (!using_ce) @@ -422,8 +507,6 @@ static void irc2ir (void) irc2ir (false); } -static int did_prefetch; - static void fill_prefetch_2 (void) { if (!using_prefetch) @@ -615,30 +698,85 @@ static void syncmovepc (int getv, int flags) #endif } -static int tail_ce020; +static void head_cycs (int h) +{ + if (head_ce020_cycs_done) + return; + if (h < 0) + return; + //printf ("\tdo_sync_tail (%d);\n", h); + //printf ("\tdo_head_cycles_ce020 (%d);\n", h); + head_ce020_cycs_done = true; + tail_ce020 = -1; +} + +static void add_head_cycs (int h) +{ + if (!using_ce020) + return; + head_ce020_cycs_done = false; + head_cycs (h); +} static void addopcycles_ce20 (int h, int t, int c, int subhead) { - int largest = tail_ce020 > h ? tail_ce020: h; - if (largest) { + head_cycs (h); + + //c = 0; + + if (tail_ce020 >= 0 && h >= 0 && head_in_ea_ce020 == 0) { + int largest = tail_ce020 > h ? tail_ce020: h; + if (tail_ce020 != h) { + //printf ("\tdo_cycles_ce020 (%d - %d);\n", tail_ce020 > h ? tail_ce020 : h, tail_ce020 > h ? h : tail_ce020); + //printf ("\tdo_cycles_ce020 (%d - %d);\n", tail_ce020 > h ? tail_ce020 : h, tail_ce020 > h ? h : tail_ce020); + if (h) { + printf ("\tregs.ce020memcycles -= %d * cpucycleunit;\n", h); + printf ("\tif (regs.ce020memcycles < 0) {\n"); + //printf ("\t\tx_do_cycles (-regs.ce020memcycles);\n"); + printf ("\t\tregs.ce020memcycles = 0;\n"); + printf ("\t}\n"); + } else { + printf ("\tregs.ce020memcycles = 0;\n"); + } + //printf ("\tregs.ce020memcycles = 0;\n"); + +#if 0 if (tail_ce020) printf ("\tregs.ce020_tail = get_cycles () - regs.ce020_tail;\n"); else printf ("\tregs.ce020_tail = 0;\n"); printf ("\tif (regs.ce020_tail < %d * cpucycleunit)\n", largest); printf ("\t\tx_do_cycles (%d * cpucycleunit - regs.ce020_tail);\n", largest); - } else { - printf ("\t/* ea tail == op head */\n"); +#endif + } else if (h) { + printf ("\t/* ea tail == op head (%d) */\n", h); + printf ("\tregs.ce020memcycles -= %d * cpucycleunit;\n", h); + printf ("\tif (regs.ce020memcycles < 0) {\n"); + //printf ("\t\tx_do_cycles (-regs.ce020memcycles);\n"); + printf ("\t\tregs.ce020memcycles = 0;\n"); + printf ("\t}\n"); + } } - c = c - h - t; + if (h < 0) + h = 0; + + //c = 0; + // c = internal cycles needed after head cycles and before tail cycles. Not total cycles. - addcycles_ce020 ("op", h, t, c, -subhead); + addcycles_ce020 ("op", h, t, c - h - t, -subhead); //printf ("\tregs.irc = get_word_ce020_prefetch (%d);\n", m68k_pc_offset); - if (c > 0) { - printf ("\t%s (%d);\n", do_cycles, c); +#if 0 + if (c - h - t > 0) { + printf ("\t%s (%d);\n", do_cycles, c - h - t); + count_cycles_ce020 += c; count_cycles += c; } - printf ("\tregs.ce020_tail = 0;\n"); +#endif + //printf ("\tregs.ce020_tail = 0;\n"); + total_ce020 = c; + tail_ce020 = t; +// if (total_ce020 >= 2) +// printf ("\tint op_cycles = get_cycles ();\n"); } static void addop_ce020 (instr *curi, int subhead) @@ -659,30 +797,36 @@ static void addop_ce020 (instr *curi, int subhead) static void addcycles_ea_ce020 (char *ea, int h, int t, int c, int oph) { - if (!h && !h && !c && !oph) - return; + head_cycs (h + oph); + +// if (!h && !h && !c && !oph) +// return; c = c - h - t; + + //c = 0; + if (!oph) { - printf ("\t/* %d,%d,%d %s */\n", h, t, c, ea); + printf ("\t/* ea H:%d,T:%d,C:%d %s */\n", h, t, c, ea); } else { if (oph && t) term ("Both op head and tail can't be non-zero"); if (oph > 0) { - printf ("\t/* %d+%d=%d,%d,%d %s */\n", h, oph, h + oph, t, c, ea); + printf ("\t/* ea H:%d+%d=%d,T:%d,C:%d %s */\n", h, oph, h + oph, t, c, ea); h += oph; } else { - printf ("\t/* %d-%d=%d,%d,%d %s */\n", h, -oph, h + oph, t, c, ea); + printf ("\t/* ea H:%d-%d=%d,T:%d,C:%d %s */\n", h, -oph, h + oph, t, c, ea); h += oph; } } - if (c > 0) { + if (0 && c > 0) { printf ("\t%s (%d);\n", do_cycles, c); count_cycles += c; } tail_ce020 = t; - if (t > 0) - printf ("\tregs.ce020_tail = get_cycles ();\n", h, t, c); + head_in_ea_ce020 = oph; +// if (t > 0) +// printf ("\tregs.ce020_tail = get_cycles () + %d * cpucycleunit;\n", t); } static void addcycles_ea_ce020 (char *ea, int h, int t, int c) { @@ -939,7 +1083,7 @@ static int gence020cycles_jea (amodes mode) * side effect in case a bus fault is generated by any memory access. * XJ - 2006/11/13 */ -static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) +static void genamode2x (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int fetchmode) { char namea[100]; int m68k_pc_offset_last = m68k_pc_offset; @@ -1000,16 +1144,43 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g syncmovepc (getv, flags); return; case Aind: // (An) + switch (fetchmode) + { + case fetchmode_fea: + addcycles_ce020 (1); + break; + case fetchmode_cea: + addcycles_ce020 (2); + break; + case fetchmode_jea: + addcycles_ce020 (2); + break; + } printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); break; case Aipi: // (An)+ + switch (fetchmode) + { + case fetchmode_fea: + addcycles_ce020 (1); + break; + case fetchmode_cea: + break; + } printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); break; case Apdi: // -(An) + switch (fetchmode) + { + case fetchmode_fea: + case fetchmode_cea: + addcycles_ce020 (2); + break; + } printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); switch (size) { @@ -1035,12 +1206,30 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g } break; case Ad16: // (d16,An) + switch (fetchmode) + { + case fetchmode_fea: + case fetchmode_cea: + addcycles_ce020 (2); + break; + case fetchmode_jea: + addcycles_ce020 (4); + break; + } printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); printf ("\t%sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags)); count_read_ea++; break; case Ad8r: // (d8,An,Xn) + switch (fetchmode) + { + case fetchmode_fea: + case fetchmode_cea: + case fetchmode_jea: + addcycles_ce020 (4); + break; + } printf ("\tuaecptr %sa;\n", name); if (cpu_level > 1) { if (next_cpu_level < 1) @@ -1062,12 +1251,27 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g } break; case PC16: // (d16,PC,Xn) + switch (fetchmode) + { + case fetchmode_fea: + case fetchmode_cea: + case fetchmode_jea: + addcycles_ce020 (4); + break; + } printf ("\tuaecptr %sa;\n", name); add_mmu040_movem (movem); printf ("\t%sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); break; case PC8r: // (d8,PC,Xn) + switch (fetchmode) + { + case fetchmode_fea: + case fetchmode_cea: + addcycles_ce020 (4); + break; + } printf ("\tuaecptr tmppc;\n"); printf ("\tuaecptr %sa;\n", name); if (cpu_level > 1) { @@ -1258,6 +1462,11 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g } } +static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) +{ + genamode2x (mode, reg, size, name, getv, movem, flags, -1); +} + static void genamode (instr *curi, amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) { int oldfixup = mmufixupstate; @@ -1265,18 +1474,20 @@ static void genamode (instr *curi, amodes mode, char *reg, wordsizes size, char if (using_ce020 && curi) { switch (curi->fetchmode) { - case 1: + case fetchmode_fea: subhead = gence020cycles_fea (mode); break; - case 2: + case fetchmode_cea: subhead = gence020cycles_cea (curi, mode); break; - case 5: + case fetchmode_jea: subhead = gence020cycles_jea (mode); break; } + genamode2x (mode, reg, size, name, getv, movem, flags, curi->fetchmode); + } else { + genamode2 (mode, reg, size, name, getv, movem, flags); } - genamode2 (mode, reg, size, name, getv, movem, flags); if (using_mmu == 68040 && (oldfixup & 1)) { // we have fixup already active = this genamode call is destination mode and we can now clear previous source fixup. clearmmufixup (0); @@ -1285,6 +1496,15 @@ static void genamode (instr *curi, amodes mode, char *reg, wordsizes size, char addop_ce020 (curi, subhead); } +static void genamode3 (instr *curi, amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) +{ + int oldfixup = mmufixupstate; + genamode2x (mode, reg, size, name, getv, movem, flags, curi ? curi->fetchmode : -1); + if (using_mmu == 68040 && (oldfixup & 1)) { + // we have fixup already active = this genamode call is destination mode and we can now clear previous source fixup. + clearmmufixup (0); + } +} static void genamodedual (instr *curi, amodes smode, char *sreg, wordsizes ssize, char *sname, int sgetv, int sflags, amodes dmode, char *dreg, wordsizes dsize, char *dname, int dgetv, int dflags) @@ -1293,28 +1513,31 @@ static void genamodedual (instr *curi, amodes smode, char *sreg, wordsizes ssize if (using_ce020) { switch (curi->fetchmode) { - case 1: - if (smode >= imm) - subhead = gence020cycles_fea(dmode); + case fetchmode_fea: + if (smode >= imm || isreg (smode)) + subhead = gence020cycles_fea (dmode); else subhead = gence020cycles_fea (smode); break; - case 2: + case fetchmode_cea: subhead = gence020cycles_cea (curi, smode); break; - case 3: + case fetchmode_fiea: subhead = gence020cycles_fiea (curi, ssize, dmode); break; - case 4: + case fetchmode_ciea: subhead = gence020cycles_ciea (curi, ssize, dmode); break; - case 5: + case fetchmode_jea: subhead = gence020cycles_jea (smode); break; + default: + printf ("\t/* No EA */\n"); + break; } } - genamode (NULL, smode, sreg, ssize, sname, sgetv, 0, sflags); - genamode (NULL, dmode, dreg, dsize, dname, dgetv, 0, dflags); + genamode3 (curi, smode, sreg, ssize, sname, sgetv, 0, sflags); + genamode3 (NULL, dmode, dreg, dsize, dname, dgetv, 0, dflags); if (using_ce020) addop_ce020 (curi, subhead); } @@ -1325,6 +1548,8 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha if (strcmp (rmw_varname, to) != 0) candormw = false; } + genastore_done = true; + returntail (mode != Dreg && mode != Areg); switch (mode) { case Dreg: @@ -1683,7 +1908,7 @@ static void genmovemel (uae_u16 opcode) printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0); - addcycles_ce020 (8); + addcycles_ce020 (8 - 2); start_brace (); if (using_mmu == 68030) { movem_mmu030 (getcode, size, false, table68k[opcode].dmode == Aipi, false); @@ -1694,11 +1919,11 @@ static void genmovemel (uae_u16 opcode) } else { printf ("\twhile (dmask) {\n"); printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask];\n", getcode, size); - addcycles_ce020 (1); + //addcycles_ce020 (1); printf ("\t}\n"); printf ("\twhile (amask) {\n"); printf ("\t\tm68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask];\n", getcode, size); - addcycles_ce020 (1); + //addcycles_ce020 (1); printf ("\t}\n"); if (table68k[opcode].dmode == Aipi) { printf ("\tm68k_areg (regs, dstreg) = srca;\n"); @@ -1707,6 +1932,7 @@ static void genmovemel (uae_u16 opcode) } count_ncycles++; fill_prefetch_next (); + get_prefetch_ce020 (); } static void genmovemel_ce (uae_u16 opcode) @@ -1752,7 +1978,7 @@ static void genmovemle (uae_u16 opcode) printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0); - addcycles_ce020 (4); + addcycles_ce020 (4 - 2); start_brace (); if (using_mmu >= 68030) { if (table68k[opcode].dmode == Apdi) @@ -1793,6 +2019,7 @@ static void genmovemle (uae_u16 opcode) } count_ncycles++; fill_prefetch_next (); + get_prefetch_ce020 (); } static void genmovemle_ce (uae_u16 opcode) @@ -2149,6 +2376,7 @@ static int islongimm (struct instr *curi) static void resetvars (void) { + memory_cycle_cnt = 4; insn_n_cycles = using_prefetch ? 0 : 4; insn_n_cycles020 = 0; ir2irc = 0; @@ -2156,8 +2384,13 @@ static void resetvars (void) mmufixupstate = 0; mmudisp020cnt = 0; candormw = false; + genastore_done = false; rmw_varname[0] = 0; tail_ce020 = 0; + total_ce020 = 0; + tail_ce020_done = false; + head_in_ea_ce020 = 0; + head_ce020_cycs_done = false; prefetch_long = NULL; srcli = NULL; @@ -2209,6 +2442,7 @@ static void resetvars (void) do_cycles = "do_cycles_ce020"; nextw = "next_iword_020ce"; nextl = "next_ilong_020ce"; + memory_cycle_cnt = 3; } else if (using_ce020 == 2) { // 68030 CE disp020 = "x_get_disp_ea_ce030"; @@ -2226,6 +2460,7 @@ static void resetvars (void) do_cycles = "do_cycles_ce020"; nextw = "next_iword_030ce"; nextl = "next_ilong_030ce"; + memory_cycle_cnt = 3; } else if (using_prefetch_020) { disp020 = "x_get_disp_ea_020"; prefetch_word = "get_word_020_prefetch"; @@ -2241,6 +2476,7 @@ static void resetvars (void) dstb = "x_put_byte"; nextw = "next_iword_020_prefetch"; nextl = "next_ilong_020_prefetch"; + memory_cycle_cnt = 2; } #if 0 } else if (using_ce020) { @@ -2416,6 +2652,7 @@ static void gen_opcode (unsigned long int opcode) resetvars (); start_brace (); + m68k_pc_offset = 2; switch (curi->plev) { case 0: /* not privileged */ @@ -2446,7 +2683,9 @@ static void gen_opcode (unsigned long int opcode) case i_EOR: { int c = 0; - genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW); + genamodedual (curi, + curi->smode, "srcreg", curi->size, "src", 1, 0, + curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW); // genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); // genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); @@ -2812,7 +3051,7 @@ static void gen_opcode (unsigned long int opcode) //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); fill_prefetch_next (); - addcycles000 (4); + addcycles000 (2); start_brace (); genflags (flag_cmp, sz_long, "newv", "src", "dst"); break; @@ -2860,7 +3099,10 @@ static void gen_opcode (unsigned long int opcode) // MOVE is too complex to handle in table68k int h = 0, t = 0, c = 0, subhead = 0; bool fea = false; - if (isreg (curi->smode) && isreg (curi->dmode)) { + if (curi->smode == immi && isreg (curi->dmode)) { + // MOVEQ + h = 2; t = 0; c = 0; + } else if (isreg (curi->smode) && isreg (curi->dmode)) { // MOVE Rn,Rn h = 2; t = 0; c = 2; } else if (isreg (curi->dmode)) { @@ -2916,7 +3158,7 @@ static void gen_opcode (unsigned long int opcode) else subhead = gence020cycles_fea (curi->smode); } - genamode2 (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE); + genamode2x (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE, fea ? fetchmode_fea : -1); genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_MOVE); addopcycles_ce20 (h, t, c, -subhead); if (curi->mnemo == i_MOVEA && curi->size == sz_word) @@ -3020,6 +3262,7 @@ static void gen_opcode (unsigned long int opcode) genmovemel_ce (opcode); else genmovemel (opcode); + tail_ce020_done = true; break; case i_MVMLE: // confirmed @@ -3027,6 +3270,7 @@ static void gen_opcode (unsigned long int opcode) genmovemle_ce (opcode); else genmovemle (opcode); + tail_ce020_done = true; break; case i_TRAP: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0); @@ -3142,6 +3386,7 @@ static void gen_opcode (unsigned long int opcode) } /* PC is set and prefetch filled. */ m68k_pc_offset = 0; + tail_ce020_done = true; fill_prefetch_full (); break; case i_RTD: @@ -3165,6 +3410,7 @@ static void gen_opcode (unsigned long int opcode) setpc ("pc"); /* PC is set and prefetch filled. */ m68k_pc_offset = 0; + tail_ce020_done = true; fill_prefetch_full (); need_endlabel = 1; break; @@ -3179,6 +3425,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tm68k_areg(regs, 7) += offs;\n"); genastore ("src", Apdi, "7", sz_long, "old"); } else { + addop_ce020 (curi, 0); genamode (NULL, Apdi, "7", sz_long, "old", 2, 0, GF_AA); genamode (NULL, curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); genamode (NULL, curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); @@ -3204,12 +3451,15 @@ static void gen_opcode (unsigned long int opcode) } break; case i_RTS: + addop_ce020 (curi, 0); printf ("\tuaecptr pc = m68k_getpc ();\n"); - if (using_ce020 == 1) + if (using_ce020 == 1) { + add_head_cycs (1); printf ("\tm68k_do_rts_ce020 ();\n"); - else if (using_ce020 == 2) + } else if (using_ce020 == 2) { + add_head_cycs (1); printf ("\tm68k_do_rts_ce030 ();\n"); - else if (using_ce) + } else if (using_ce) printf ("\tm68k_do_rts_ce ();\n"); else if (using_mmu) printf ("\tm68k_do_rts_mmu%s ();\n", mmu_postfix); @@ -3253,6 +3503,7 @@ static void gen_opcode (unsigned long int opcode) m68k_pc_offset = 0; fill_prefetch_full (); need_endlabel = 1; + tail_ce020_done = true; break; case i_JSR: // TODO: check stack write order genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); @@ -3344,6 +3595,7 @@ static void gen_opcode (unsigned long int opcode) case i_Bcc: // bcc.b branch: idle cycle, prefetch, prefetch // bcc.b not branch: 2 idle cycles, prefetch + tail_ce020_done = true; if (curi->size == sz_long) { if (cpu_level < 2) { addcycles000 (2); @@ -3380,24 +3632,25 @@ static void gen_opcode (unsigned long int opcode) printf ("\treturn 10 * CYCLE_UNIT / 2;\n"); } else { incpc ("(uae_s32)src + 2"); - addcycles_ce020 (6); + add_head_cycs (6); fill_prefetch_full_020 (); returncycles ("\t", 10); } printf ("didnt_jump:;\n"); need_endlabel = 1; sync_m68k_pc (); + get_prefetch_ce020_0 (); if (curi->size == sz_byte) { addcycles000 (2); irc2ir (); - addcycles_ce020 (4); + add_head_cycs (4); fill_prefetch_2 (); } else if (curi->size == sz_word) { addcycles000 (2); - addcycles_ce020 (6); + add_head_cycs (6); fill_prefetch_full_000 (); } else { - addcycles_ce020 (6); + add_head_cycs (6); fill_prefetch_full_000 (); } insn_n_cycles = curi->size == sz_byte ? 8 : 12; @@ -3429,8 +3682,12 @@ static void gen_opcode (unsigned long int opcode) fill_prefetch_next (); break; case i_DBcc: - genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); - genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); + tail_ce020_done = true; + genamodedual (curi, + curi->smode, "srcreg", curi->size, "src", 1, GF_AA | GF_NOREFILL, + curi->dmode, "dstreg", curi->size, "offs", 1, GF_AA | GF_NOREFILL); + //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); + //genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); printf ("\tuaecptr oldpc = m68k_getpc ();\n"); addcycles000 (2); printf ("\tif (!cctrue (%d)) {\n", curi->cc); @@ -3449,21 +3706,22 @@ static void gen_opcode (unsigned long int opcode) need_endlabel = 1; } irc2ir (); - addcycles_ce020 (6); + add_head_cycs (6); fill_prefetch_1 (2); fill_prefetch_full_020 (); returncycles ("\t\t\t", 12); if (using_ce) printf ("\t\t\treturn;\n"); printf ("\t\t}\n"); - addcycles_ce020 (10); + add_head_cycs (10); printf ("\t} else {\n"); // cc == true addcycles000_2 ("\t\t", 2); - addcycles_ce020 (6); + add_head_cycs (6); printf ("\t}\n"); setpc ("oldpc + %d", m68k_pc_offset); m68k_pc_offset = 0; + get_prefetch_ce020_0 (); fill_prefetch_full_000 (); insn_n_cycles = 12; need_endlabel = 1; @@ -3484,6 +3742,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "src"); break; case i_DIVU: + tail_ce020_done = true; genamodedual (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, 0); @@ -3523,8 +3782,11 @@ static void gen_opcode (unsigned long int opcode) count_ncycles++; insn_n_cycles += 136 - (136 - 76) / 2; /* average */ need_endlabel = 1; + tail_ce020_done = false; + returntail (false); break; case i_DIVS: + tail_ce020_done = true; genamodedual (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, curi->dmode, "dstreg", sz_long, "dst", 1, 0); @@ -3567,6 +3829,8 @@ static void gen_opcode (unsigned long int opcode) count_ncycles++; insn_n_cycles += 156 - (156 - 120) / 2; /* average */ need_endlabel = 1; + tail_ce020_done = false; + returntail (false); break; case i_MULU: genamodedual (curi, @@ -4196,6 +4460,7 @@ static void gen_opcode (unsigned long int opcode) case i_MOVES: /* ignore DFC and SFC when using_mmu == false */ { int old_brace_level; + tail_ce020_done = true; genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); printf ("\tif (extra & 0x800)\n"); { @@ -4226,6 +4491,8 @@ static void gen_opcode (unsigned long int opcode) sync_m68k_pc (); pop_braces (old_brace_level); } + tail_ce020_done = false; + returntail (false); } break; case i_BKPT: /* only needed for hardware emulators */ @@ -4546,6 +4813,8 @@ static void gen_opcode (unsigned long int opcode) term (); break; } + if (!genastore_done) + returntail (0); finish_braces (); if (limit_braces) { printf ("\n#endif\n"); @@ -4796,6 +5065,7 @@ static void generate_one_opcode (int rp, char *extra) endlabelno++; sprintf (endlabelstr, "endlabel%d", endlabelno); count_read = count_write = count_ncycles = count_cycles = 0; + count_cycles_ce020 = 0; count_read_ea = count_write_ea = count_cycles_ea = 0; gen_opcode (opcode); if (need_endlabel) diff --git a/genlinetoscr.cpp b/genlinetoscr.cpp index 63ce40b3..ff08dc24 100644 --- a/genlinetoscr.cpp +++ b/genlinetoscr.cpp @@ -442,7 +442,7 @@ static void out_linetoscr (DEPTH_T bpp, HMODE_T hmode, int aga, int spr) outln ( " uae_u8 xor_val = bplxor;"); outln ( ""); - outln ( " if (dp_for_drawing->ham_seen) {"); + outln ( " if (bplham) {"); out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_HAM); outln ( " } else if (bpldualpf) {"); out_linetoscr_mode (bpp, hmode, aga, spr, CMODE_DUALPF); diff --git a/include/cpu_prefetch.h b/include/cpu_prefetch.h index 2284d4c0..caeb8cc0 100644 --- a/include/cpu_prefetch.h +++ b/include/cpu_prefetch.h @@ -47,23 +47,48 @@ STATIC_INLINE uae_u32 get_long_020_prefetch (int o) head = h; tail = t; cycles = c; #define CE020_COUNTCYCLES() - +// only for CPU internal cycles STATIC_INLINE void do_cycles_ce020 (int clocks) { - x_do_cycles (clocks * cpucycleunit); + int cycs = clocks * cpucycleunit; + if (regs.ce020memcycles > 0) { + if (regs.ce020memcycles >= cycs) { + regs.ce020memcycles -= cycs; + return; + } + cycs = cycs - regs.ce020memcycles; + } + regs.ce020memcycles = 0; + x_do_cycles (cycs); } + STATIC_INLINE void do_cycles_ce020_mem (int clocks, uae_u32 val) { x_do_cycles_post (clocks * cpucycleunit, val); } -extern void usecycles_ce020 (int cycles); - STATIC_INLINE void resetcycles_ce020 (void) { regs.ce020memcycles = 0; + regs.ce020memcycle_data = true; } +#if 0 +STATIC_INLINE void do_head_cycles_ce020 (int h) +{ + if (regs.ce020_tail) { + int cycs = regs.ce020_tail_cycles - get_cycles (); + if (cycs < 0) + cycs = 0; + cycs -= h * cpucycleunit; + if (cycs) + x_do_cycles (cycs < 0 ? -cycs : cycs); + } else if (h > 0) { + do_cycles_ce020 (h); + } +} +#endif + void mem_access_delay_long_write_ce020 (uaecptr addr, uae_u32 v); void mem_access_delay_word_write_ce020 (uaecptr addr, uae_u32 v); void mem_access_delay_byte_write_ce020 (uaecptr addr, uae_u32 v); diff --git a/include/custom.h b/include/custom.h index d3e26675..21dd8c24 100644 --- a/include/custom.h +++ b/include/custom.h @@ -120,7 +120,7 @@ extern uae_u16 INTREQR (void); #define EQU_ENDLINE_NTSC 10 extern int maxhpos, maxhpos_short; -extern int maxvpos, maxvpos_nom; +extern int maxvpos, maxvpos_nom, maxvpos_display; extern int hsyncstartpos, hsyncendpos; extern int minfirstline, vblank_endline, numscrlines; extern double vblank_hz, fake_vblank_hz; diff --git a/include/disk.h b/include/disk.h index f3273e16..bcef9993 100644 --- a/include/disk.h +++ b/include/disk.h @@ -11,6 +11,15 @@ typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ES #define HISTORY_FLOPPY 0 #define HISTORY_CD 1 +struct diskinfo +{ + uae_u8 bootblock[1024]; + bool bb_crc_valid; + uae_u32 crc32; + bool hd; + bool unreadable; +}; + extern void DISK_init (void); extern void DISK_free (void); extern void DISK_select (uae_u8 data); @@ -34,7 +43,7 @@ extern bool disk_creatediskfile (const TCHAR *name, int type, drive_type adftype extern void dumpdisk (void); extern int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck); extern TCHAR *DISK_history_get (int idx, int type); -int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32); +int DISK_examine_image (struct uae_prefs *p, int num, struct diskinfo *di); extern TCHAR *DISK_get_saveimagepath (const TCHAR *name); extern void DISK_reinsert (int num); extern int disk_prevnext (int drive, int dir); diff --git a/include/newcpu.h b/include/newcpu.h index 6c726d94..2c849ea3 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -185,7 +185,9 @@ struct regstruct uae_u32 cacheholdingdata020; uae_u32 cacheholdingaddr020; int ce020memcycles; + bool ce020memcycle_data; int ce020_tail; + frame_time_t ce020_tail_cycles; }; extern struct regstruct regs; diff --git a/include/options.h b/include/options.h index 3614f577..c6f37466 100644 --- a/include/options.h +++ b/include/options.h @@ -414,6 +414,7 @@ struct uae_prefs { bool cs_denisenoehb; bool cs_dipagnus; bool cs_agnusbltbusybug; + bool cs_ciatodbug; int cs_hacks; TCHAR romfile[MAX_DPATH]; diff --git a/include/readcpu.h b/include/readcpu.h index 81f6af16..1a3be419 100644 --- a/include/readcpu.h +++ b/include/readcpu.h @@ -101,7 +101,7 @@ extern struct instr { unsigned int clev:3, unimpclev:3; unsigned int isjmp:1; unsigned int unused2:1; - unsigned char head, tail, clocks, fetchmode; + char head, tail, clocks, fetchmode; } *table68k; extern void read_table68k (void); diff --git a/main.cpp b/main.cpp index 08f6d3a3..478e40f2 100644 --- a/main.cpp +++ b/main.cpp @@ -157,11 +157,11 @@ static void fixup_prefs_dim2 (struct wh *wh) wh->height = 128; } if (wh->width > max_uae_width) { - error_log (_T("Width (%d) must be at least %d."), wh->width, max_uae_width); + error_log (_T("Width (%d) max is %d."), wh->width, max_uae_width); wh->width = max_uae_width; } if (wh->height > max_uae_height) { - error_log (_T("Height (%d) must be at least %d."), wh->height, max_uae_height); + error_log (_T("Height (%d) max is %d."), wh->height, max_uae_height); wh->height = max_uae_height; } } @@ -204,7 +204,7 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs) prefs->gfx_filter = 1; } if (prefs->gfx_filter == 0 && prefs->monitoremu) { - error_log (_T("A2024 and Graffiti require at least null filter.")); + error_log (_T("A2024 and Graffiti require at least null filter enabled.")); prefs->gfx_filter = 1; } } @@ -291,58 +291,67 @@ void fixup_prefs (struct uae_prefs *p) || p->chipmem_size < 0x20000 || p->chipmem_size > 0x800000) { - error_log (_T("Unsupported chipmem size %x."), p->chipmem_size); + error_log (_T("Unsupported chipmem size %d (0x%x)."), p->chipmem_size, p->chipmem_size); p->chipmem_size = 0x200000; err = 1; } if ((p->fastmem_size & (p->fastmem_size - 1)) != 0 || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000))) - { - error_log (_T("Unsupported fastmem size %x."), p->fastmem_size); +{ + error_log (_T("Unsupported fastmem size %d (0x%x)."), p->fastmem_size, p->fastmem_size); err = 1; } - if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0 - || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000 || (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3)))) - { - error_log (_T("Unsupported graphics card memory size %x (%x)."), p->rtgmem_size, max_z3fastmem); + if (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3) { + error_log (_T("Graphics card memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), p->rtgmem_size, p->rtgmem_size, max_z3fastmem, max_z3fastmem); + p->rtgmem_size = max_z3fastmem; + err = 1; + } + if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0 || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000))) { + error_log (_T("Unsupported graphics card memory size %d (0x%x)."), p->rtgmem_size, p->rtgmem_size); if (p->rtgmem_size > max_z3fastmem) p->rtgmem_size = max_z3fastmem; else p->rtgmem_size = 0; err = 1; } - - if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0 - || (p->z3fastmem_size != 0 && (p->z3fastmem_size < 0x100000 || p->z3fastmem_size > max_z3fastmem))) + + if (p->z3fastmem_size > max_z3fastmem) { + error_log (_T("Zorro III fastmem size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size, max_z3fastmem, max_z3fastmem); + p->z3fastmem_size = max_z3fastmem; + err = 1; + } + if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0 || (p->z3fastmem_size != 0 && p->z3fastmem_size < 0x100000)) { - error_log (_T("Unsupported Zorro III fastmem size %x (%x)."), p->z3fastmem_size, max_z3fastmem); - if (p->z3fastmem_size > max_z3fastmem) - p->z3fastmem_size = max_z3fastmem; - else - p->z3fastmem_size = 0; + error_log (_T("Unsupported Zorro III fastmem size %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size); + p->z3fastmem_size = 0; err = 1; } - if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0 - || (p->z3fastmem2_size != 0 && (p->z3fastmem2_size < 0x100000 || p->z3fastmem2_size > max_z3fastmem))) + + if (p->z3fastmem2_size > max_z3fastmem) { + error_log (_T("Zorro III fastmem2 size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem2_size, p->z3fastmem2_size, max_z3fastmem, max_z3fastmem); + p->z3fastmem2_size = max_z3fastmem; + err = 1; + } + if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0 || (p->z3fastmem2_size != 0 && p->z3fastmem2_size < 0x100000)) { - error_log (_T("Unsupported Zorro III fastmem size %x (%x)."), p->z3fastmem2_size, max_z3fastmem); - if (p->z3fastmem2_size > max_z3fastmem) - p->z3fastmem2_size = max_z3fastmem; - else - p->z3fastmem2_size = 0; + error_log (_T("Unsupported Zorro III fastmem2 size %x (%x)."), p->z3fastmem2_size, p->z3fastmem2_size); + p->z3fastmem2_size = 0; err = 1; } + p->z3fastmem_start &= ~0xffff; if (p->z3fastmem_start < 0x1000000) p->z3fastmem_start = 0x1000000; - if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 - || (p->z3chipmem_size != 0 && (p->z3chipmem_size < 0x100000 || p->z3chipmem_size > max_z3fastmem))) + + if (p->z3chipmem_size > max_z3fastmem) { + error_log (_T("Zorro III fake chipmem size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size, max_z3fastmem, max_z3fastmem); + p->z3chipmem_size = max_z3fastmem; + err = 1; + } + if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0 || (p->z3chipmem_size != 0 && p->z3chipmem_size < 0x100000)) { - error_log (_T("Unsupported Zorro III fake chipmem size %x (%x)."), p->z3chipmem_size, max_z3fastmem); - if (p->z3chipmem_size > max_z3fastmem) - p->z3chipmem_size = max_z3fastmem; - else - p->z3chipmem_size = 0; + error_log (_T("Unsupported Zorro III fake chipmem size %d (0x%x)."), p->z3chipmem_size, p->z3chipmem_size); + p->z3chipmem_size = 0; err = 1; } @@ -350,11 +359,13 @@ void fixup_prefs (struct uae_prefs *p) p->z3fastmem_size = p->z3fastmem2_size = p->z3chipmem_size = 0; error_log (_T("Can't use a Z3 graphics card or 32-bit memory when using a 24 bit address space.")); } + if (p->bogomem_size != 0 && p->bogomem_size != 0x80000 && p->bogomem_size != 0x100000 && p->bogomem_size != 0x180000 && p->bogomem_size != 0x1c0000) { - error_log (_T("Unsupported bogomem size %x"), p->bogomem_size); + error_log (_T("Unsupported bogomem size %d (0x%x)"), p->bogomem_size, p->bogomem_size); p->bogomem_size = 0; err = 1; } + if (p->bogomem_size > 0x180000 && (p->cs_fatgaryrev >= 0 || p->cs_ide || p->cs_ramseyrev >= 0)) { p->bogomem_size = 0x180000; error_log (_T("Possible Gayle bogomem conflict fixed.")); @@ -429,9 +440,11 @@ void fixup_prefs (struct uae_prefs *p) p->cachesize = 0; err = 1; } - if (p->z3fastmem_size > 0 && (p->address_space_24 || p->cpu_model < 68020)) { + if ((p->z3fastmem_size || p->z3fastmem2_size || p->z3chipmem_size) && (p->address_space_24 || p->cpu_model < 68020)) { error_log (_T("Z3 fast memory can't be used with a 68000/68010 emulation. Turning off Z3 fast memory.")); p->z3fastmem_size = 0; + p->z3fastmem2_size = 0; + p->z3chipmem_size = 0; err = 1; } if (p->rtgmem_size > 0 && p->rtgmem_type == GFXBOARD_UAE_Z3 && (p->cpu_model < 68020 || p->address_space_24)) { diff --git a/newcpu.cpp b/newcpu.cpp index 88dc0c6d..9a769325 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -4685,9 +4685,15 @@ static void m68k_run_2ce (void) set_cpu_tracer (false); for (;;) { + static int prevopcode; r->instruction_pc = m68k_getpc (); - opcode = currprefs.cpu_model == 68020 ? get_word_ce020_prefetch (0) : get_word_ce030_prefetch (0); + if (regs.irc == 0xffff) + gui_message (_T("OPCODE %04X HAS FAULTY PREFETCH!"), prevopcode); + + opcode = regs.irc; + prevopcode = opcode; + regs.irc = 0xffff; //write_log (_T("%08x %04x\n"), r->instruction_pc, opcode); @@ -6355,14 +6361,14 @@ static void fill_icache020 (uae_u32 addr, uae_u32 (*fetch)(uaecptr)) // even if bus controller is currently processing // previous data access. // Other combinations are not possible. - if (regs.ce020memcycles < 0) + if (!regs.ce020memcycle_data) regs.ce020memcycles = 0; + regs.ce020memcycle_data = false; unsigned long cycs = get_cycles (); data = fetch (addr); - // negative cycles = prefetch - // ce020memcycles was guaranteed zero or positive. + // add as available "free" internal CPU time. cycs = get_cycles () - cycs; - regs.ce020memcycles = -regs.ce020memcycles - cycs; + regs.ce020memcycles += cycs; if (!(regs.cacr & 2)) { c->tag = tag; c->valid = !!(regs.cacr & 1); @@ -6382,9 +6388,10 @@ uae_u32 get_word_ce020_prefetch (int o) regs.prefetch020[0] = regs.prefetch020[1]; fill_icache020 (pc + 2 + 4, mem_access_delay_longi_read_ce020); regs.prefetch020[1] = regs.cacheholdingdata020; - return v; + } else { + v = regs.prefetch020[0] >> 16; } - v = regs.prefetch020[0] >> 16; + do_cycles_ce020 (2); return v; } @@ -6398,31 +6405,10 @@ uae_u32 get_word_020_prefetch (int o) regs.prefetch020[0] = regs.prefetch020[1]; fill_icache020 (pc + 2 + 4, get_longi); regs.prefetch020[1] = regs.cacheholdingdata020; - return v; - } - v = regs.prefetch020[0] >> 16; - return v; -} - -void usecycles_ce020 (int cycles) -{ - if (regs.ce020memcycles < 0) { - if (regs.ce020memcycles <= -cycles) { - regs.ce020memcycles += cycles; - } else { - cycles -= -regs.ce020memcycles; - regs.ce020memcycles = 0; - x_do_cycles (cycles); - } } else { - if (regs.ce020memcycles >= cycles) { - regs.ce020memcycles -= cycles; - } else { - cycles -= regs.ce020memcycles; - regs.ce020memcycles = 0; - x_do_cycles (cycles); - } + v = regs.prefetch020[0] >> 16; } + return v; } // these are also used by 68030. @@ -6696,13 +6682,14 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr) // cache miss if (currprefs.cpu_cycle_exact) { - // see fill_icache020 - if (regs.ce020memcycles < 0) + if (!regs.ce020memcycle_data) regs.ce020memcycles = 0; + regs.ce020memcycle_data = false; unsigned long cycs = get_cycles (); data = mem_access_delay_longi_read_ce020 (addr); + // add as available "free" internal CPU time. cycs = get_cycles () - cycs; - regs.ce020memcycles = -regs.ce020memcycles - cycs; + regs.ce020memcycles += cycs; } else { data = get_longi (addr); } @@ -6877,9 +6864,10 @@ uae_u32 get_word_ce030_prefetch (int o) regs.prefetch020[0] = regs.prefetch020[1]; fill_icache030 (pc + 2 + 4); regs.prefetch020[1] = regs.cacheholdingdata020; - return v; + } else { + v = regs.prefetch020[0] >> 16; } - v = regs.prefetch020[0] >> 16; + do_cycles_ce020 (2); return v; } @@ -6902,9 +6890,12 @@ void fill_prefetch_030 (void) uaecptr pc = m68k_getpc (); pc &= ~3; fill_icache030 (pc); + do_cycles_ce020 (2); regs.prefetch020[0] = regs.cacheholdingdata020; fill_icache030 (pc + 4); + do_cycles_ce020 (2); regs.prefetch020[1] = regs.cacheholdingdata020; + regs.irc = get_word_ce030_prefetch (0); } void fill_prefetch_020 (void) @@ -6913,9 +6904,12 @@ void fill_prefetch_020 (void) uae_u32 (*fetch)(uaecptr) = currprefs.cpu_cycle_exact ? mem_access_delay_longi_read_ce020 : get_longi; pc &= ~3; fill_icache020 (pc, fetch); + do_cycles_ce020 (2); regs.prefetch020[0] = regs.cacheholdingdata020; fill_icache020 (pc + 4, fetch); + do_cycles_ce020 (2); regs.prefetch020[1] = regs.cacheholdingdata020; + regs.irc = get_word_020_prefetch (0); } void fill_prefetch (void) diff --git a/od-win32/gencpu_msvc/gencpu_msvc.vcxproj b/od-win32/gencpu_msvc/gencpu_msvc.vcxproj index 29974897..86f21c94 100644 --- a/od-win32/gencpu_msvc/gencpu_msvc.vcxproj +++ b/od-win32/gencpu_msvc/gencpu_msvc.vcxproj @@ -49,13 +49,13 @@ Application false Unicode - v110 + v120_xp Application false Unicode - v110 + v120_xp diff --git a/od-win32/genlinetoscr_msvc/genlinetoscr_msvc.vcxproj b/od-win32/genlinetoscr_msvc/genlinetoscr_msvc.vcxproj index f1ad0825..547e83db 100644 --- a/od-win32/genlinetoscr_msvc/genlinetoscr_msvc.vcxproj +++ b/od-win32/genlinetoscr_msvc/genlinetoscr_msvc.vcxproj @@ -35,7 +35,7 @@ Application Unicode true - v110 + v120_xp Application diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 195c5234..bc2cded6 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -549,6 +549,7 @@ #define IDC_CREATE 1282 #define IDC_CREATE_RAW 1283 #define IDC_SNAPSHOTNAME 1284 +#define IDC_INFO0 1284 #define IDC_SNAPSHOT 1285 #define IDC_SAVEIMAGE0 1285 #define IDC_DOSAVESTATE 1286 @@ -559,7 +560,10 @@ #define IDC_SAVEIMAGE3 1288 #define IDC_GUI_FONT 1288 #define IDC_GUI_DEFAULT 1289 +#define IDC_INFO1 1289 #define IDC_GUI_LISTFONT 1290 +#define IDC_INFO2 1290 +#define IDC_INFO3 1291 #define IDC_PORT0_JOYSC 1302 #define IDC_PORT0_KBDA 1303 #define IDC_PORT0_KBDB 1304 @@ -949,6 +953,8 @@ #define IDC_DF1WPQ 1686 #define IDC_EJECT1Q 1687 #define IDC_DF1TEXTQ 1688 +#define IDC_INFO0Q 1689 +#define IDC_INFO1Q 1690 #define IDC_FILTERXLV 1692 #define IDC_FILTERVOV 1693 #define IDC_FILTERHOV 1694 @@ -1034,6 +1040,8 @@ #define IDC_DBG_FPREG 1750 #define IDC_DBG_FPSR 1751 #define IDC_DBG_OUTPUT2 1752 +#define IDC_CS_RESETWARNING2 1752 +#define IDC_CS_CIATODBUG 1752 #define IDC_DBG_MEMINPUT 1753 #define IDC_DBG_MEMDOWN 1754 #define IDC_DBG_MEMUP 1755 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index a3ab0f48..e5b29904 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -243,34 +243,34 @@ FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN GROUPBOX "Floppy Drives",IDC_SETTINGSTEXT3,1,0,393,163 CONTROL "DF0:",IDC_DF0ENABLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,14,34,15 - PUSHBUTTON "Delete save image",IDC_SAVEIMAGE0,97,13,78,15,NOT WS_VISIBLE - COMBOBOX IDC_DF0TYPE,180,14,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Write-protected",IDC_STATIC,249,17,74,10,SS_CENTERIMAGE - CONTROL "",IDC_DF0WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,328,13,10,15 + PUSHBUTTON "Delete save image",IDC_SAVEIMAGE0,69,13,78,15,NOT WS_VISIBLE + COMBOBOX IDC_DF0TYPE,152,14,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Write-protected",IDC_STATIC,221,17,74,10,SS_CENTERIMAGE + CONTROL "",IDC_DF0WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,300,13,10,15 PUSHBUTTON "Eject",IDC_EJECT0,345,12,30,15 PUSHBUTTON "...",IDC_DF0,379,12,10,15 COMBOBOX IDC_DF0TEXT,6,31,384,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP CONTROL "DF1:",IDC_DF1ENABLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,51,34,15 - PUSHBUTTON "Delete save image",IDC_SAVEIMAGE1,97,49,78,15,NOT WS_VISIBLE - COMBOBOX IDC_DF1TYPE,180,51,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Write-protected",IDC_STATIC,249,53,74,10,SS_CENTERIMAGE - CONTROL "",IDC_DF1WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,328,50,10,15 + PUSHBUTTON "Delete save image",IDC_SAVEIMAGE1,69,49,78,15,NOT WS_VISIBLE + COMBOBOX IDC_DF1TYPE,152,51,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Write-protected",IDC_STATIC,221,53,74,10,SS_CENTERIMAGE + CONTROL "",IDC_DF1WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,300,50,10,15 PUSHBUTTON "Eject",IDC_EJECT1,345,49,30,15 PUSHBUTTON "...",IDC_DF1,379,49,10,15 COMBOBOX IDC_DF1TEXT,6,68,383,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP CONTROL "DF2:",IDC_DF2ENABLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,87,34,15 - PUSHBUTTON "Delete save image",IDC_SAVEIMAGE2,97,85,78,15,NOT WS_VISIBLE - COMBOBOX IDC_DF2TYPE,180,87,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Write-protected",IDC_STATIC,250,88,73,10,SS_CENTERIMAGE - CONTROL "",IDC_DF2WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,328,86,9,15 + PUSHBUTTON "Delete save image",IDC_SAVEIMAGE2,69,85,78,15,NOT WS_VISIBLE + COMBOBOX IDC_DF2TYPE,152,87,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Write-protected",IDC_STATIC,222,88,73,10,SS_CENTERIMAGE + CONTROL "",IDC_DF2WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,300,86,9,15 PUSHBUTTON "Eject",IDC_EJECT2,345,85,30,15 PUSHBUTTON "...",IDC_DF2,379,85,10,15 COMBOBOX IDC_DF2TEXT,6,104,384,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP CONTROL "DF3:",IDC_DF3ENABLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,7,123,34,15 - PUSHBUTTON "Delete save image",IDC_SAVEIMAGE3,97,121,78,15,NOT WS_VISIBLE - COMBOBOX IDC_DF3TYPE,180,123,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Write-protected",IDC_STATIC,250,125,73,10,SS_CENTERIMAGE - CONTROL "",IDC_DF3WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,328,123,9,15 + PUSHBUTTON "Delete save image",IDC_SAVEIMAGE3,69,121,78,15,NOT WS_VISIBLE + COMBOBOX IDC_DF3TYPE,152,123,65,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Write-protected",IDC_STATIC,222,125,73,10,SS_CENTERIMAGE + CONTROL "",IDC_DF3WP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,300,123,9,15 PUSHBUTTON "Eject",IDC_EJECT3,345,121,30,15 PUSHBUTTON "...",IDC_DF3,379,121,10,15 COMBOBOX IDC_DF3TEXT,6,140,383,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP @@ -285,6 +285,10 @@ BEGIN EDITTEXT IDC_CREATE_NAME,130,243,97,13,ES_AUTOHSCROLL CONTROL "Bootblock",IDC_FLOPPY_BOOTABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,235,242,59,15 CONTROL "FFS",IDC_FLOPPY_FFS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,300,242,34,15 + PUSHBUTTON "?",IDC_INFO0,323,12,17,15 + PUSHBUTTON "?",IDC_INFO1,323,49,17,15 + PUSHBUTTON "?",IDC_INFO2,323,85,17,15 + PUSHBUTTON "?",IDC_INFO3,323,122,17,15 END IDD_HARDDISK DIALOGEX 0, 0, 396, 315 @@ -653,7 +657,7 @@ BEGIN "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,182,147,181,10 END -IDD_CHIPSET2 DIALOGEX 0, 0, 396, 288 +IDD_CHIPSET2 DIALOGEX 0, 0, 396, 296 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN @@ -668,41 +672,42 @@ BEGIN CONTROL "Vertical Sync",IDC_CS_CIAA_TOD1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,41,68,86,10 CONTROL "Power Supply 50Hz",IDC_CS_CIAA_TOD2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,133,68,109,10 CONTROL "Power Supply 60Hz",IDC_CS_CIAA_TOD3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,249,68,116,10 - GROUPBOX "Chipset Features",IDC_STATIC,1,88,393,146 + GROUPBOX "Chipset Features",IDC_STATIC,1,88,393,158 CONTROL "CIA ROM Overlay",IDC_CS_CIAOVERLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,102,104,11 CONTROL "CD32 CD",IDC_CS_CD32CD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,116,104,11 CONTROL "CDTV CD",IDC_CS_CDTVCD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,130,105,11 CONTROL "A600/A1200 IDE",IDC_CS_IDE1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,143,104,11 CONTROL "ROM Mirror (E0)",IDC_CS_KSMIRROR_E0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,157,104,11 CONTROL "KB Reset Warning",IDC_CS_RESETWARNING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,171,104,11 - LTEXT "A4091/A4000T SCSI not yet implemented.",IDC_STATIC,17,187,247,8,SS_CENTERIMAGE - CONTROL "A590/A2091 SCSI",IDC_CS_A2091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,202,104,11 - CONTROL "A4091 SCSI",IDC_CS_A4091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,215,104,11 + LTEXT "A4091/A4000T SCSI not yet implemented.",IDC_STATIC,17,202,247,8,SS_CENTERIMAGE + CONTROL "A590/A2091 SCSI",IDC_CS_A2091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,216,104,11 + CONTROL "A4091 SCSI",IDC_CS_A4091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,229,104,11 CONTROL "A1000 Boot RAM/ROM",IDC_CS_A1000RAM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,102,121,11 CONTROL "CD32 C2P",IDC_CS_CD32C2P,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,116,121,11 CONTROL "CDTV SRAM",IDC_CS_CDTVRAM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,129,121,11 CONTROL "A4000/A4000T IDE",IDC_CS_IDE2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,143,121,11 CONTROL "ROM Mirror (A8)",IDC_CS_KSMIRROR_A8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,157,121,11 CONTROL "No-EHB Denise",IDC_CS_NOEHB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,171,121,11 - CONTROL "A3000 SCSI",IDC_CS_DMAC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,202,121,11 - CONTROL "CDTV SCSI",IDC_CS_CDTVSCSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,215,121,11 + CONTROL "A3000 SCSI",IDC_CS_DMAC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,216,121,11 + CONTROL "CDTV SCSI",IDC_CS_CDTVSCSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,229,121,11 CONTROL "DF0: ID Hardware",IDC_CS_DF0IDHW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,102,125,11 CONTROL "CD32 NVRAM",IDC_CS_CD32NVRAM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,116,125,11 CONTROL "CDTV SRAM Expansion",IDC_CS_CDTVRAMEXP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,129,125,11 CONTROL "PCMCIA",IDC_CS_PCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,143,125,11 CONTROL "C00000 is Fast RAM",IDC_CS_SLOWISFAST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,157,125,11 CONTROL "A1000 Agnus (8361/8367)",IDC_CS_DIPAGNUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,171,125,11 - CONTROL "A4000T SCSI",IDC_CS_DMAC2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,202,125,11 - CONTROL "Include host SCSI devices",IDC_CS_SCSIMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,215,125,11 - GROUPBOX "Chipset Revision",IDC_STATIC,1,236,393,46 - CONTROL "Ramsey revision:",IDC_CS_RAMSEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,248,97,11 - CONTROL "Fat Gary revision:",IDC_CS_FATGARY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,262,97,11 - EDITTEXT IDC_CS_RAMSEYREV,136,247,45,13,ES_AUTOHSCROLL - EDITTEXT IDC_CS_FATGARYREV,136,262,45,13,ES_AUTOHSCROLL - CONTROL "Agnus/Alice revision:",IDC_CS_AGNUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,248,107,11 - CONTROL "Denise/Lisa revision:",IDC_CS_DENISE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,262,107,11 - EDITTEXT IDC_CS_AGNUSREV,311,247,45,13,ES_AUTOHSCROLL - EDITTEXT IDC_CS_DENISEREV,311,262,45,13,ES_AUTOHSCROLL + CONTROL "A4000T SCSI",IDC_CS_DMAC2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,216,125,11 + CONTROL "Include host SCSI devices",IDC_CS_SCSIMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,229,125,11 + GROUPBOX "Chipset Revision",IDC_STATIC,1,249,393,46 + CONTROL "Ramsey revision:",IDC_CS_RAMSEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,261,97,11 + CONTROL "Fat Gary revision:",IDC_CS_FATGARY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,275,97,11 + EDITTEXT IDC_CS_RAMSEYREV,136,260,45,13,ES_AUTOHSCROLL + EDITTEXT IDC_CS_FATGARYREV,136,275,45,13,ES_AUTOHSCROLL + CONTROL "Agnus/Alice revision:",IDC_CS_AGNUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,261,107,11 + CONTROL "Denise/Lisa revision:",IDC_CS_DENISE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,275,107,11 + EDITTEXT IDC_CS_AGNUSREV,311,260,45,13,ES_AUTOHSCROLL + EDITTEXT IDC_CS_DENISEREV,311,275,45,13,ES_AUTOHSCROLL + CONTROL "CIA TOD bug",IDC_CS_CIATODBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,184,104,11 END IDD_AVIOUTPUT DIALOGEX 0, 0, 396, 260 @@ -958,6 +963,8 @@ BEGIN GROUPBOX "Mode",IDC_STATIC,250,231,144,28,BS_LEFT CONTROL "Start in Quickstart mode",IDC_QUICKSTARTMODE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,259,242,131,12 COMBOBOX IDC_CD0Q_TYPE,199,187,74,50,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "?",IDC_INFO0Q,334,148,19,15 + PUSHBUTTON "?",IDC_INFO1Q,334,186,19,15 END IDD_FRONTEND DIALOGEX 0, 0, 420, 242 diff --git a/od-win32/win32.h b/od-win32/win32.h index 74b9c519..88d095bd 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("8") +#define WINUAEBETA _T("9") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2013, 9, 21) +#define WINUAEDATE MAKEBD(2013, 10, 20) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") @@ -36,7 +36,6 @@ extern HWND hAmigaWnd, hMainWnd, hHiddenWnd, hGUIWnd; extern RECT amigawin_rect, mainwin_rect; extern int in_sizemove; extern int manual_painting_needed; -extern int manual_palette_refresh_needed; extern int mouseactive; extern int minimized; extern int monitor_off; @@ -55,7 +54,6 @@ int WIN32_RegisterClasses (void); int WIN32_InitHtmlHelp (void); int WIN32_InitLibraries (void); int WIN32_CleanupLibraries (void); -void WIN32_MouseDefaults (int, int); void WIN32_HandleRegistryStuff (void); extern void setup_brkhandler (void); extern void remove_brkhandler (void); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 7b15c6c4..f1dce312 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1649,8 +1649,18 @@ static int open_windows (bool mousecapture) if (!rp_isactive () && mousecapture && startactive) setmouseactive (-1); + bool upd = false; if (startactive) { setpriority (&priorities[currprefs.win32_active_capture_priority]); + upd = true; + } else if (startminimized) { + setpriority (&priorities[currprefs.win32_iconified_priority]); + setminimized (); + } else { + setpriority (&priorities[currprefs.win32_inactive_priority]); + upd = true; + } + if (upd) { for (i = 0; i < NUM_LEDS; i++) gui_flicker_led (i, -1, -1); gui_led (LED_POWER, gui_data.powerled); @@ -1659,13 +1669,10 @@ static int open_windows (bool mousecapture) if (currprefs.floppyslots[i].dfxtype >= 0) gui_led (LED_DF0 + i, 0); } - inputdevice_acquire (TRUE); - } else if (startminimized) { - setpriority (&priorities[currprefs.win32_iconified_priority]); - setminimized (); - } else { - setpriority (&priorities[currprefs.win32_inactive_priority]); + if (isfocus ()) + inputdevice_acquire (TRUE); } + if (startpaused) setpaused (1); @@ -4202,7 +4209,7 @@ static BOOL doInit (void) rp_set_hwnd_delayed (); #endif - if (isfullscreen () > 0) + if (isfullscreen () != 0) setmouseactive (-1); return 1; diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 315425b5..c3f4a6a6 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -2018,6 +2018,47 @@ static void eject_cd (void) } } +static void infofloppy (int n) +{ + struct diskinfo di; + FILE *f; + TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH]; + + DISK_examine_image (&workprefs, n, &di); + + tmp[0] = 0; + if (GetTempPath (MAX_DPATH, tmp) <= 0) + return; + _tcscat (tmp, _T("floppy_info.txt")); + f = _tfopen (tmp, _T("wt, ccs=UTF-8")); + if (f) { + _stprintf (tmp2, + _T("\nDisk readable: %s\nCRC32: %08X\nBoot block checksum valid: %s\n\n"), + di.unreadable ? _T("No") : _T("Yes"), + di.crc32, + di.bb_crc_valid ? _T("Yes") : _T("No") + ); + fputws (tmp2, f); + int w = 32; + for (int i = 0; i < 1024; i += w) { + for (int j = 0; j < w; j++) { + uae_u8 b = di.bootblock[i + j]; + _stprintf (tmp2 + j * 2, _T("%02X"), b); + if (b >= 32 && b < 127) + tmp2[w * 2 + 1 + j] = (TCHAR)b; + else + tmp2[w * 2 + 1 + j] = '.'; + } + tmp2[w * 2] = ' '; + tmp2[w * 2 + 1 + w] = 0; + fputws (tmp2, f); + fputws (_T("\n"), f); + } + fclose (f); + ShellExecute (NULL, _T("open"), tmp, NULL, NULL, SW_SHOWNORMAL); + } +} + static void ejectfloppy (int n) { if (iscd (n)) { @@ -5481,7 +5522,7 @@ static void testimage (HWND hDlg, int num) { int ret; int reload = 0; - uae_u32 crc32; + struct diskinfo di; int messageid = -1; TCHAR tmp[MAX_DPATH]; @@ -5493,10 +5534,10 @@ static void testimage (HWND hDlg, int num) } if (!workprefs.floppyslots[num].df[0]) return; - ret = DISK_examine_image (&workprefs, num, &crc32); + ret = DISK_examine_image (&workprefs, num, &di); if (!ret) return; - floppytooltip (hDlg, num, crc32); + floppytooltip (hDlg, num, di.crc32); if (num > 0) return; if (!full_property_sheet) @@ -5711,7 +5752,9 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L case IDC_DF1QQ: case IDC_DF0QENABLE: case IDC_DF1QENABLE: - if (currentpage == QUICKSTART_ID) + case IDC_INFO0Q: + case IDC_INFO1Q: + if (currentpage == QUICKSTART_ID) ret = FloppyDlgProc (hDlg, msg, wParam, lParam); break; case IDC_QUICKSTART_SETCONFIG: @@ -6857,6 +6900,7 @@ static void values_to_chipsetdlg2 (HWND hDlg) CheckDlgButton (hDlg, IDC_CS_SCSIMODE, workprefs.scsi == 2); CheckDlgButton (hDlg, IDC_CS_PCMCIA, workprefs.cs_pcmcia); CheckDlgButton (hDlg, IDC_CS_SLOWISFAST, workprefs.cs_slowmemisfast); + CheckDlgButton (hDlg, IDC_CS_CIATODBUG, workprefs.cs_ciatodbug); CheckDlgButton (hDlg, IDC_CS_IDE1, workprefs.cs_ide > 0 && (workprefs.cs_ide & 1)); CheckDlgButton (hDlg, IDC_CS_IDE2, workprefs.cs_ide > 0 && (workprefs.cs_ide & 2)); txt[0] = 0; @@ -6907,6 +6951,7 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM workprefs.cs_compatible = ischecked (hDlg, IDC_CS_COMPATIBLE); workprefs.cs_resetwarning = ischecked (hDlg, IDC_CS_RESETWARNING); + workprefs.cs_ciatodbug = ischecked (hDlg, IDC_CS_CIATODBUG); workprefs.cs_denisenoehb = ischecked (hDlg, IDC_CS_NOEHB); workprefs.cs_dipagnus = ischecked (hDlg, IDC_CS_DIPAGNUS); workprefs.cs_agnusbltbusybug = workprefs.cs_dipagnus; @@ -7007,6 +7052,7 @@ static void enable_for_chipsetdlg2 (HWND hDlg) ew (hDlg, IDC_CS_CDTVRAM, e); ew (hDlg, IDC_CS_CDTVRAMEXP, e); ew (hDlg, IDC_CS_RESETWARNING, e); + ew (hDlg, IDC_CS_CIATODBUG, e); ew (hDlg, IDC_CS_NOEHB, e); ew (hDlg, IDC_CS_DIPAGNUS, e); ew (hDlg, IDC_CS_KSMIRROR_E0, e); @@ -10704,18 +10750,18 @@ static void out_floppyspeed (HWND hDlg) SetDlgItemText (hDlg, IDC_FLOPPYSPDTEXT, txt); } -#define BUTTONSPERFLOPPY 8 +#define BUTTONSPERFLOPPY 9 static int floppybuttons[][BUTTONSPERFLOPPY] = { - { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP,-1,IDC_SAVEIMAGE0,IDC_DF0ENABLE }, - { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP,-1,IDC_SAVEIMAGE1,IDC_DF1ENABLE }, - { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP,-1,IDC_SAVEIMAGE2,IDC_DF2ENABLE }, - { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP,-1,IDC_SAVEIMAGE3,IDC_DF3ENABLE } + { IDC_DF0TEXT,IDC_DF0,IDC_EJECT0,IDC_DF0TYPE,IDC_DF0WP,-1,IDC_SAVEIMAGE0,IDC_DF0ENABLE, IDC_INFO0 }, + { IDC_DF1TEXT,IDC_DF1,IDC_EJECT1,IDC_DF1TYPE,IDC_DF1WP,-1,IDC_SAVEIMAGE1,IDC_DF1ENABLE, IDC_INFO1 }, + { IDC_DF2TEXT,IDC_DF2,IDC_EJECT2,IDC_DF2TYPE,IDC_DF2WP,-1,IDC_SAVEIMAGE2,IDC_DF2ENABLE, IDC_INFO2 }, + { IDC_DF3TEXT,IDC_DF3,IDC_EJECT3,IDC_DF3TYPE,IDC_DF3WP,-1,IDC_SAVEIMAGE3,IDC_DF3ENABLE, IDC_INFO3 } }; static int floppybuttonsq[][BUTTONSPERFLOPPY] = { - { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,-1,IDC_DF0WPQ,IDC_DF0WPTEXTQ,-1,IDC_DF0QENABLE }, - { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,-1,IDC_DF1WPQ,IDC_DF1WPTEXTQ,-1,IDC_DF1QENABLE }, - { -1,-1,-1,-1,-1,-1,-1 }, - { -1,-1,-1,-1,-1,-1,-1 } + { IDC_DF0TEXTQ,IDC_DF0QQ,IDC_EJECT0Q,-1,IDC_DF0WPQ,IDC_DF0WPTEXTQ,-1,IDC_DF0QENABLE, IDC_INFO0Q }, + { IDC_DF1TEXTQ,IDC_DF1QQ,IDC_EJECT1Q,-1,IDC_DF1WPQ,IDC_DF1WPTEXTQ,-1,IDC_DF1QENABLE, IDC_INFO1Q }, + { -1,-1,-1,-1,-1,-1,-1,-1 }, + { -1,-1,-1,-1,-1,-1,-1,-1 } }; static void floppytooltip (HWND hDlg, int num, uae_u32 crc32) @@ -10874,6 +10920,7 @@ static void addfloppytype (HWND hDlg, int n) int f_wptext = floppybuttons[n][5]; int f_si = floppybuttons[n][6]; int f_enable = floppybuttons[n][7]; + int f_info = floppybuttons[n][8]; text = workprefs.floppyslots[n].df; if (currentpage == QUICKSTART_ID) { @@ -10886,12 +10933,14 @@ static void addfloppytype (HWND hDlg, int n) f_wptext = floppybuttonsq[n][5]; f_si = -1; f_enable = floppybuttonsq[n][7]; + f_info = floppybuttonsq[n][8]; if (iscd (n)) showcd = 1; if (showcd) { nn = 1; hide (hDlg, f_wp, 1); hide (hDlg, f_wptext, 1); + hide (hDlg, f_info, 1); ew (hDlg, f_enable, FALSE); WIN32GUI_LoadUIString (IDS_QS_CD, tmp, sizeof tmp / sizeof (TCHAR)); SetWindowText (GetDlgItem (hDlg, f_enable), tmp); @@ -10903,6 +10952,7 @@ static void addfloppytype (HWND hDlg, int n) } else { hide (hDlg, f_wp, 0); hide (hDlg, f_wptext, 0); + hide (hDlg, f_info, 0); } } if (!showcd && f_enable > 0 && n == 1 && currentpage == QUICKSTART_ID) { @@ -10926,7 +10976,7 @@ static void addfloppytype (HWND hDlg, int n) if (f_text >= 0) ew (hDlg, f_text, state); if (f_eject >= 0) - ew (hDlg, f_eject, TRUE); + ew (hDlg, f_eject, workprefs.floppyslots[n].df[0] != 0); if (f_drive >= 0) ew (hDlg, f_drive, state); if (f_enable >= 0) { @@ -10940,6 +10990,8 @@ static void addfloppytype (HWND hDlg, int n) chk = !showcd && disk_getwriteprotect (&workprefs, text) && state == TRUE ? BST_CHECKED : 0; if (f_wp >= 0) CheckDlgButton (hDlg, f_wp, chk); + if (f_info >= 0) + ew (hDlg, f_info, workprefs.floppyslots[n].df[0] != 0); chk = !showcd && state && DISK_validate_filename (&workprefs, text, 0, NULL, NULL, NULL) ? TRUE : FALSE; if (f_wp >= 0) { ew (hDlg, f_wp, chk && !workprefs.floppy_read_only); @@ -11277,6 +11329,20 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA case IDC_DF3: diskselect (hDlg, wParam, &workprefs, 3, NULL); break; + case IDC_INFO0: + case IDC_INFO0Q: + infofloppy (0); + break; + case IDC_INFO1: + case IDC_INFO1Q: + infofloppy (1); + break; + case IDC_INFO2: + infofloppy (2); + break; + case IDC_INFO3: + infofloppy (3); + break; case IDC_EJECT0: case IDC_EJECT0Q: SetDlgItemText (hDlg, IDC_DF0TEXT, _T("")); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 3198125a..00099a4a 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,6 +1,50 @@ - restore only single input target to default. +Beta 9: + +NOTE: 68020 CE mode can be used now. + +- Added CIA tod bug option to Advanced chipset. Demo The end / Trilobit running under + KS 1.3 has corruption in "photos" part if tod alarm bug is not emulated. KS 1.3 + real A500 + does not have corruption. (I don't understand what is going on, some programs require this bug, + some will hang if it is emulated. There has to be some unknown variable.) +- Writing to DIWSTOP during mid scanline and new value matches current vertical line: + bitplane DMA fetches stop. Fixes Demo Starflight / Phenomena, OCS only. + Interestingly ECS DMA fetches restart when DDFSTOP matches, causing scroller to jump horizontally. +- Writing to BPLxMOD exactly one cycle before bitplane fetch that also adds modulos + uses old modulo value. (Copper Slave / Ram Jam) +- Mouse was uncaptured when switching from non-fullwindow to fullwindow mode. +- b8 hires unaligned check removed, it was wrong, logic analyzer confirmed. +- CMPA idle cycle was 2 cycles too slow in 68000 CE mode. +- Tape read command returned size of read request, not actual length which may be smaller than request size. +- OCS/ECS "7-planes" feature got broken in b8. +- HAM mode double pass display emulation's first pass didn't reset colors back to original before + second pass. (Animotion / Phenomena) +- New memwatchpoint code didn't work with CIA registers. +- Log message if bitplane DMA ends at 0xe2 (can happen if start position is unaligned enough), this causes + odd looking corruption on real hardware. (each scanline has random looking few pixels shift). Previously + only DMA that ended at the start of next scanline were logged. +- Sprite vertical start == sprite DMA first line won't enable sprites. (Ultrademo #1 / The Link) +- If windowed mode was reset (for example RTG to custom chipset mode change) and mouse was not captured + but window had focus: input got disabled, extra mouse click was required to enable input. +- Copper cycles were emulated too early before bitplane DMA decisions, copper might have used + cycle reserved for bitplane DMA in some situations. +- Added "?" buttons to floppy GUIs. Current implementation is very lazy, few lines of information, + boot block contents and it opens in default text editor. +- Limit VPOSW refresh rate display size changes to sane values, min display size is 256 lines and max + is not allowed outside PAL size. Reduces flickering if program does something really weird or stupid + with VPOSW. + +Second 68EC020 cycle-exact emulation rewrite. Timing may not be much better but cycle usage emulation +should be much more closer to real hardware. (This needs logic analyzer check but I don't have +all required hardware yet) + +Lots of work left to do but at least it should not be any worse than old code and it also should be +much more accurate now when code has small loops (for example stupid CPU delays). + +NOTE: 68030 can queue data memory accesses, this is not yet emulated. + Beta 8: NOTE: Still no 68020/030 CE mode changes. Do not use. diff --git a/scsi.cpp b/scsi.cpp index 880761ad..0e10cac7 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -17,7 +17,7 @@ #include "zfile.h" static int outcmd[] = { 0x0a, 0x2a, 0x2f, 0xaa, 0x15, 0x55, -1 }; -static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 }; +static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 }; static int nonecmd[] = { 0x00, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, -1 }; static int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 }; diff --git a/scsitape.cpp b/scsitape.cpp index 9aaf20b6..45211e29 100644 --- a/scsitape.cpp +++ b/scsitape.cpp @@ -203,13 +203,20 @@ static bool next_file (struct scsi_data_tape *tape) } end: write_log (_T("TAPEEMU: end of tape\n")); + tape->beom = 1; return false; } -static int tape_read (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) +static int tape_read (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len, bool *eof) { int got; + *eof = false; + if (tape->beom > 0) { + *eof = true; + return -1; + } + if (!tape->zf) { rewind (tape); if (!next_file (tape)) @@ -218,8 +225,10 @@ static int tape_read (struct scsi_data_tape *tape, uae_u8 *scsi_data, int len) zfile_fseek (tape->zf, tape->file_offset, SEEK_SET); got = zfile_fread (scsi_data, 1, len, tape->zf); tape->file_offset += got; - if (got < len) + if (got < len) { + *eof = true; next_file (tape); + } return got; } @@ -259,18 +268,19 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd int scsi_len = -1; int status = 0; int lun; + bool eof; if (log_tapeemu) - write_log (_T("TAPEEMU: scsi command 0x%02X.%02X.%02X.%02X.%02X.%02X\n"), + write_log (_T("TAPEEMU: %02X.%02X.%02X.%02X.%02X.%02X\n"), cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5]); if (cmdbuf[0] == 3) { - s[0] = 0x70; - if (tape->beom < 0) + if (tape->beom == -1) s[9] |= 0x8; // beginning of media - if (tape->beom > 0) + if (tape->beom == 1) s[2] |= 0x40; // end of media - *sense_len = 0x12; + if (*sense_len < 0x12) + *sense_len = 0x12; return 0; } @@ -415,28 +425,42 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd goto unloaded; if (tape->beom < 0) tape->beom = 0; - scsi_len = tape_read (tape, scsi_data, len); + scsi_len = tape_read (tape, scsi_data, len, &eof); + if (log_tapeemu) + write_log (_T("-> READ %d bytes\n"), scsi_len); + if ((cmdbuf[1] & 1) && scsi_len > 0 && scsi_len < len) { + int gap = tape->blocksize - (scsi_len & (tape->blocksize - 1)); + if (gap > 0 && gap < tape->blocksize) + memset (scsi_data + scsi_len, 0, gap); + scsi_len += tape->blocksize - 1; + scsi_len &= ~(tape->blocksize - 1); + } if (scsi_len < 0) { - tape->beom = 1; + tape->beom = 2; status = SCSI_STATUS_CHECK_CONDITION; - s[0] = 0x70; - s[2] = 0x80 | 0x40 | 0; /* File Mark Detected + End of Media + NO SENSE */ + s[0] = 0x80 | 0x70; + s[2] = 8; /* BLANK CHECK */ + if (cmdbuf[1] & 1) + wl (&s[3], len / tape->blocksize); + else + wl (&s[3], len); s[12] = 0; s[13] = 2; /* End-of-partition/medium detected */ ls = 0x12; - } else if (scsi_len < len) { + } else if (eof) { status = SCSI_STATUS_CHECK_CONDITION; - s[0] = 0x70; + s[0] = 0x80 | 0x70; // Valid + code s[2] = 0x80 | 0; /* File Mark Detected + NO SENSE */ - wl (&s[3], len - scsi_len); + if (cmdbuf[1] & 1) + wl (&s[3], (len - scsi_len) / tape->blocksize); + else + wl (&s[3], len); s[12] = 0; s[13] = 1; /* File Mark detected */ ls = 0x12; if (log_tapeemu) write_log (_T("TAPEEMU READ FILE END, %d remaining\n"), len - scsi_len); } - scsi_len = len; - break; case 0x5a: // MODE SENSE(10) @@ -636,10 +660,16 @@ notape: *reply_len = lr; *sense_len = ls; if (ls > 0) { - if (tape->beom > 0) + if (tape->beom == 1) s[2] |= 0x40; - if (tape->beom < 0) + if (tape->beom == -1) s[9] |= 0x8; + if (log_tapeemu) { + write_log (_T("TAPEEMU SENSE: ")); + for (int i = 0; i < ls; i++) + write_log (_T("%02X."), s[i]); + write_log (_T("\n")); + } } return status; } \ No newline at end of file diff --git a/table68k b/table68k index fb3722c7..b8f016b5 100644 --- a/table68k +++ b/table68k @@ -70,12 +70,15 @@ 0000 0000 0011 1100:000:XNZVC:XNZVC:10: ORSR.B #1 0000 0000 0111 1100:002:?????:?????:10: ORSR.W #1 0000 0zz0 11ss sSSS:250:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] + 0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[Dreg] - 2 0 2 fiea 0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z #z,d[!Areg,Dreg] - 0 1 3 fiea + 0000 0010 0011 1100:000:XNZVC:XNZVC:10: ANDSR.B #1 0000 0010 0111 1100:002:?????:?????:10: ANDSR.W #1 + 0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[Dreg] - 2 0 2 fiea 0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z #z,d[!Areg,Dreg] @@ -88,8 +91,10 @@ - 2 0 2 fiea 0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z #z,d[!Areg,Dreg] - 0 1 3 fiea + 0000 0110 11ss sSSS:230:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] 0000 0110 11ss sSSS:230:?????:?????:10: RTM s[Dreg,Areg] + 0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[Dreg] - 4 0 4 0000 1000 00ss sSSS:000:--Z--:-----:11: BTST #1,s[!Areg,Dreg,Immd] @@ -106,8 +111,10 @@ - 6 0 6 0000 1000 11ss sSSS:000:--Z--:-----:13: BSET #1,s[!Areg,Dreg,Immd] - 0 0 6 fiea + 0000 1010 0011 1100:000:XNZVC:XNZVC:10: EORSR.B #1 0000 1010 0111 1100:002:?????:?????:10: EORSR.W #1 + 0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[Dreg] - 2 0 2 fiea 0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z #z,d[!Areg,Dreg] @@ -130,6 +137,7 @@ 0000 rrr1 01dd dDDD:050:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr 0000 rrr1 10dd dDDD:050:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16] 0000 rrr1 11dd dDDD:050:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16] + 0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[Dreg] - 4 0 4 0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST Dr,s[!Areg,Dreg] @@ -137,16 +145,17 @@ 0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[Dreg] - 6 0 6 0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG Dr,s[!Areg,Dreg,Immd] -- 0 0 6 fiea +- 0 0 6 fea 0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[Dreg] - 6 0 6 0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR Dr,s[!Areg,Dreg,Immd] -- 0 0 6 fiea +- 0 0 6 fea 0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[Dreg] - 6 0 6 0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET Dr,s[!Areg,Dreg,Immd] -- 0 0 6 fiea +- 0 0 6 fea +% Move cycles are special cased in gencpu.c 0001 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.B s,d[!Areg] 0011 DDDd ddss sSSS:000:-----:-----:12: MOVEA.W s,d[Areg] 0011 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.W s,d[!Areg] @@ -186,17 +195,24 @@ 0100 1000 0000 1rrr:200:-----:-----:31: LINK.L Ar,#2 - 2 0 6 0100 1000 00dd dDDD:000:X?Z?C:X-Z--:30: NBCD.B d[!Areg] +- 0 0 6 + 0100 1000 0100 1kkk:200:?????:?????:10: BKPT #k + 0100 1000 01ss sSSS:000:-NZ00:-----:30: SWAP.W s[Dreg] - 4 0 4 0100 1000 01ss sSSS:000:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 0 2 4 cea 0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W d[Dreg] - 4 0 4 + 0100 1000 10dd dDDD:000:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] + 0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L d[Dreg] - 4 0 4 + 0100 1000 11dd dDDD:000:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] + 0100 1001 11dd dDDD:200:-NZ00:-----:30: EXT.B d[Dreg] - 4 0 4 0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z s[Dreg] @@ -209,12 +225,15 @@ - 0 0 2 0100 1010 11dd dDDD:000:?????:?????:30: TAS.B d[!Areg,Dreg] - 0 0 2 fea + 0100 1010 1111 1100:000:?????:?????:00: ILLEGAL + 0100 1100 00ss sSSS:200:-NZVC:-----:13: MULL.L #1,s[!Areg] 0100 1100 01ss sSSS:200:?????:?????:13: DIVL.L #1,s[!Areg] 0100 1100 10ss sSSS:000:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] 0100 1100 11ss sSSS:000:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] 0100 1110 0100 JJJJ:000:-----:XNZVC:10: TRAP #J + 0100 1110 0101 0rrr:000:-----:-----:31: LINK.W Ar,#1 - 0 0 4 0100 1110 0101 1rrr:000:-----:-----:30: UNLK.L Ar @@ -230,18 +249,27 @@ 0100 1110 0111 0010:002:XNZVC:-----:10: STOP #1 - 0 0 8 0100 1110 0111 0011:002:XNZVC:-----:00: RTE +- 1 9 18 0100 1110 0111 0100:000:?????:?????:10: RTD #1 +- 2 0 10 0100 1110 0111 0101:000:-----:-----:00: RTS +- 1 0 9 + 0100 1110 0111 0110:000:-----:XNZVC:00: TRAPV + 0100 1110 0111 0111:000:XNZVC:-----:00: RTR +- 1 0 12 + 0100 1110 0111 1010:102:?????:?????:10: MOVEC2 #1 - 6 0 6 0100 1110 0111 1011:102:?????:?????:10: MOVE2C #1 - 6 0 6 0100 1110 10ss sSSS:000://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 0 0 4 jea + 0100 rrr1 00ss sSSS:200:?????:?????:11: CHK.L s[!Areg],Dr 0100 rrr1 10ss sSSS:000:?????:?????:11: CHK.W s[!Areg],Dr + 0100 1110 11ss sSSS:000://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] - 4 0 4 jea 0100 rrr1 11ss sSSS:000:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar @@ -264,10 +292,12 @@ 0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z #j,d[!Areg,Dreg] - 0 1 3 fea 0101 cccc 1100 1rrr:000:-----:-++++:31: DBcc.W Dr,#1 +- -1 0 0 0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[Dreg] - 0 0 2 0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B d[!Areg,Dreg] - 0 0 2 cea + 0101 cccc 1111 1010:200:?????:?????:10: TRAPcc #1 0101 cccc 1111 1011:200:?????:?????:10: TRAPcc #2 0101 cccc 1111 1100:200:?????:?????:00: TRAPcc @@ -276,40 +306,72 @@ % instruction exceptions when compiling a 68000 only emulation, which isn't % what we want either. 0110 0001 0000 0000:000://///://///:40: BSR.W #1 +- 2 0 6 0110 0001 IIII IIII:000://///://///:40: BSR.B #i +- 2 0 6 0110 0001 1111 1111:000://///://///:40: BSR.L #2 +- 2 0 6 0110 CCCC 0000 0000:000:-----:-++++:40: Bcc.W #1 +- -1 0 0 0110 CCCC IIII IIII:000:-----:-++++:40: Bcc.B #i +- -1 0 0 0110 CCCC 1111 1111:000:-----:-++++:40: Bcc.L #2 +- -1 0 0 0111 rrr0 iiii iiii:000:-NZ00:-----:12: MOVE.L #i,Dr -1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[!Areg],Dr -1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[!Areg],Dr -1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr +1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[Dreg],Dr +- 2 0 2 +1000 rrr0 zzss sSSS:000:-NZ00:-----:13: OR.z s[!Areg,Dreg],Dr +- 0 0 2 fea + +1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[Dreg],Dr +- 2 0 30 +1000 rrr0 11ss sSSS:000:?????:?????:13: DIVU.W s[!Areg,Dreg],Dr +- 0 0 30 fea + +1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr +- 0 0 4 1000 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp +- 2 1 13 + 1000 rrr1 zzdd dDDD:000:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg] -1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Dreg],Dr -1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Areg-Apdi],Arp -1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Dreg],Dr -1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Areg-Apdi],Arp +- 0 1 3 fea + +1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Dreg],Dr +- 6 0 6 +1000 rrr1 01dd dDDD:200:?????:?????:12: PACK d[Areg-Apdi],Arp +- 2 1 11 +1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Dreg],Dr +- 8 0 8 +1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK d[Areg-Apdi],Arp +- 2 1 11 + 1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[Dreg],Dr -- 2 0 56 +- 2 0 40 1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W s[!Areg,Dreg],Dr -- 0 0 56 fea +- 0 0 40 fea 1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[Areg,Dreg],Dr - 2 0 2 1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z s[!Areg,Dreg],Dr - 0 0 2 fea -1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s,Ar +1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[Areg,Dreg],Ar - 4 0 4 -1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr -1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp +1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W s[!Areg,Dreg],Ar +- 0 0 4 fea + +1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr +- 2 0 2 +1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp +- 2 1 9 + 1001 rrr1 zzdd dDDD:000:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s,Ar +1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[Areg,Dreg],Ar - 2 0 2 +1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L s[!Areg,Dreg],Ar +- 0 0 2 fea 1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z s[Areg,Dreg],Dr - 2 0 2 @@ -325,14 +387,25 @@ - 0 0 4 fea 1011 rrr1 zzdd dDDD:000:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP - 0 0 8 -1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[!Areg] +1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[Dreg] +- 2 0 2 +1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z Dr,d[!Areg,Dreg] +- 0 1 3 fea -1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[!Areg],Dr +1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[Dreg],Dr +- 2 0 2 fea +1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z s[!Areg,Dreg],Dr +- 0 1 3 fea 1100 rrr0 11ss sSSS:000:-NZ00:-----:13: MULU.W s[!Areg],Dr -- 2 0 28 fea -1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr -1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp +- 2 0 20 fea + +1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr +- 0 0 4 +1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp +- 2 1 13 + 1100 rrr1 zzdd dDDD:000:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg] +- 0 1 3 fea 1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Dr,d[Dreg] - 4 0 4 1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L Ar,d[Areg] @@ -340,20 +413,28 @@ 1100 rrr1 10dd dDDD:000:-----:-----:33: EXG.L Dr,d[Areg] - 4 0 4 1100 rrr1 11ss sSSS:000:-NZ00:-----:13: MULS.W s[!Areg],Dr -- 2 0 28 fea +- 2 0 20 fea 1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[Areg,Dreg],Dr - 2 0 2 1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z s[!Areg,Dreg],Dr - 0 0 2 fea -1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s,Ar -- 4 0 4 -1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr -1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp +1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[Areg,Dreg],Ar +- 0 0 4 +1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W s[!Areg,Dreg],Ar +- 4 0 4 fea + +1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr +- 2 0 2 +1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp +- 2 1 9 + 1101 rrr1 zzdd dDDD:000:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg] - 0 1 3 fea -1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s,Ar +1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[Areg,Dreg],Ar - 2 0 2 +1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L s[!Areg,Dreg],Ar +- 0 0 2 fea 1110 jjjf zz00 0RRR:000:XNZVC:-----:13: ASf.z #j,DR - 2 0 6