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;
head += nextch - '0';
nextch = fgetc (tablef);
}
+ head *= neg;
while (isspace(nextch))
getnextch();
for (;;) {
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);
|| 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)
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++) {
p->cs_ciaatod = 0;
p->cs_df0idhw = 1;
p->cs_resetwarning = 0;
+ p->cs_ciatodbug = false;
_tcscpy (p->romfile, _T(""));
_tcscpy (p->romextfile, _T(""));
p->cs_df0idhw = 1;
p->cs_resetwarning = 1;
p->cs_slowmemisfast = 0;
+ p->cs_ciatodbug = false;
switch (p->cs_compatible)
{
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)
// 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
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
// 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
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);
}
}
// 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)
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
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;
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];
#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,
/* 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;
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;
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
static int toscr_nbits;
/* undocumented bitplane delay hardware feature */
-static int delayoffset, delayoffset2;
+static int delayoffset;
STATIC_INLINE void compute_delay_offset (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)
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)
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);
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];
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;
}
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
#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);
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. */
}
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;
}
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
add_modulos ();
pos += count;
fetch_cycle += count;
- fetch_align ^= count & fetchunit_align_mask;
}
}
#endif
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. */
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;
}
}
bpldmasetupphase = 0;
ddfstrt_old_hpos = -1;
bpldmawasactive = false;
+ reset_bplmod ();
if (plf_state > plf_active)
plf_state = plf_idle;
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)) &&
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;
}
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)
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) {
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;
}
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)
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,
}
#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);
}
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);
}
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);
}
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);
}
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);
}
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
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
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;
}
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;
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
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
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;
}
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;
max = 0;
vsynctimeperline = 1;
} else {
- vsynctimeperline = max / (maxvpos_nom + 1);
+ vsynctimeperline = max / (maxvpos_display + 1);
}
vsyncmaxtime = curr_time + max;
}
}
} 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 ();
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) {
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.. */
}
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;
}
put_word (addr, v);
else if (mode == 0)
put_byte (addr, v);
+
x_do_cycles_post (CYCLE_UNIT, 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)
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);
unsigned long c;
int extra;
- sync_ce020 ();
c = get_cycles ();
extra = c & (CYCLE_UNIT - 1);
if (extra) {
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);
{
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;
}
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;
int oldcyl, oldside;
ret = 0;
- *crc32 = 0;
+ memset (di, 0, sizeof di);
+ di->unreadable = true;
oldcyl = drv->cyl;
oldside = side;
drv->cyl = 0;
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) {
}
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;
ret = 3;
goto end;
}
+ di->bb_crc_valid = true;
if (dos == 0x444f5300)
ret = 10;
else if (dos == 0x444f5301 || dos == 0x444f5302 || dos == 0x444f5303)
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;
}
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);
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;
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;
}
}
/* 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)
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]) {
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;
static int mmufixupstate;
static int mmudisp020cnt;
static bool candormw;
+static bool genastore_done;
static char rmw_varname[100];
#define GENA_GETV_NO_FETCH 0
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");
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)
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;
}
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)
irc2ir (false);
}
-static int did_prefetch;
-
static void fill_prefetch_2 (void)
{
if (!using_prefetch)
#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)
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)
{
* 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;
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) {
}
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)
}
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) {
}
}
+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;
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);
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)
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);
}
if (strcmp (rmw_varname, to) != 0)
candormw = false;
}
+ genastore_done = true;
+ returntail (mode != Dreg && mode != Areg);
switch (mode) {
case Dreg:
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);
} 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");
}
count_ncycles++;
fill_prefetch_next ();
+ get_prefetch_ce020 ();
}
static void genmovemel_ce (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)
}
count_ncycles++;
fill_prefetch_next ();
+ get_prefetch_ce020 ();
}
static void genmovemle_ce (uae_u16 opcode)
static void resetvars (void)
{
+ memory_cycle_cnt = 4;
insn_n_cycles = using_prefetch ? 0 : 4;
insn_n_cycles020 = 0;
ir2irc = 0;
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;
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";
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";
dstb = "x_put_byte";
nextw = "next_iword_020_prefetch";
nextl = "next_ilong_020_prefetch";
+ memory_cycle_cnt = 2;
}
#if 0
} else if (using_ce020) {
resetvars ();
start_brace ();
+
m68k_pc_offset = 2;
switch (curi->plev) {
case 0: /* not privileged */
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 ? '&' : '^');
//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;
// 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)) {
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)
genmovemel_ce (opcode);
else
genmovemel (opcode);
+ tail_ce020_done = true;
break;
case i_MVMLE:
// confirmed
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);
}
/* PC is set and prefetch filled. */
m68k_pc_offset = 0;
+ tail_ce020_done = true;
fill_prefetch_full ();
break;
case i_RTD:
setpc ("pc");
/* PC is set and prefetch filled. */
m68k_pc_offset = 0;
+ tail_ce020_done = true;
fill_prefetch_full ();
need_endlabel = 1;
break;
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);
}
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);
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);
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);
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;
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);
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;
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);
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);
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,
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");
{
sync_m68k_pc ();
pop_braces (old_brace_level);
}
+ tail_ce020_done = false;
+ returntail (false);
}
break;
case i_BKPT: /* only needed for hardware emulators */
term ();
break;
}
+ if (!genastore_done)
+ returntail (0);
finish_braces ();
if (limit_braces) {
printf ("\n#endif\n");
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)
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);
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);
#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;
#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);
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);
uae_u32 cacheholdingdata020;
uae_u32 cacheholdingaddr020;
int ce020memcycles;
+ bool ce020memcycle_data;
int ce020_tail;
+ frame_time_t ce020_tail_cycles;
};
extern struct regstruct regs;
bool cs_denisenoehb;
bool cs_dipagnus;
bool cs_agnusbltbusybug;
+ bool cs_ciatodbug;
int cs_hacks;
TCHAR romfile[MAX_DPATH];
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);
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;
}
}
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;
}
}
|| 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;
}
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."));
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)) {
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);
// 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);
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;
}
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.
// 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);
}
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;
}
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)
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)
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v110</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Test|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
#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
#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
#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
#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
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
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
"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
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
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
#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")
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;
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);
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);
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);
rp_set_hwnd_delayed ();
#endif
- if (isfullscreen () > 0)
+ if (isfullscreen () != 0)
setmouseactive (-1);
return 1;
}
}
+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)) {
{
int ret;
int reload = 0;
- uae_u32 crc32;
+ struct diskinfo di;
int messageid = -1;
TCHAR tmp[MAX_DPATH];
}
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)
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:
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;
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;
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);
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)
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) {
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);
} 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) {
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) {
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);
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(""));
- 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.
#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 };
}
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))
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;
}
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;
}
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)
*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
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]
- 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]
- 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]
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]
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]
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]
- 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
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
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
% 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
- 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]
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