diff --git a/hash/amigaocs_flop.xml b/hash/amigaocs_flop.xml
index 109f089a77f..be9a60a30fa 100644
--- a/hash/amigaocs_flop.xml
+++ b/hash/amigaocs_flop.xml
@@ -2725,6 +2725,8 @@ ATK test: failed
1994
Virgin
@@ -4995,6 +4997,7 @@ ATK test: OK
+
Batman (Europe)
@@ -21172,6 +21175,7 @@ ATK test: failed
+
Gear Works (Europe)
@@ -43731,7 +43735,7 @@ ATK test: OK
Red screen, [FDC] dsksync (fixed)
Title screen shows with foreground garbage, [Copper] sprites
https://codetapper.com/amiga/sprite-tricks/shadow-of-the-beast/
-Hangs during first intro in gameplay
+Hangs during first intro in gameplay, verify [DSKDAT R] access
ATK test: failed
]]>
diff --git a/src/devices/machine/amiga_copper.cpp b/src/devices/machine/amiga_copper.cpp
index df2cee3c2bb..f110edb3632 100644
--- a/src/devices/machine/amiga_copper.cpp
+++ b/src/devices/machine/amiga_copper.cpp
@@ -236,7 +236,8 @@ void amiga_copper_device::vblank_sync()
set_pc(0, true);
}
-int amiga_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy)
+// TODO: h/vblank checks against xpos/vpos
+int amiga_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy, int num_planes)
{
int word0, word1;
@@ -268,11 +269,7 @@ int amiga_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy)
(!m_state_waitblit || !(is_blitter_busy)))
{
m_state_waiting = false;
-//#if GUESS_COPPER_OFFSET
-// return xpos + COPPER_CYCLES_TO_PIXELS(1 + m_wait_offset);
-//#else
- return xpos + COPPER_CYCLES_TO_PIXELS(1 + 3);
-//#endif
+ return xpos + COPPER_CYCLES_TO_PIXELS(1);
}
/* otherwise, see if this line is even a possibility; if not, punt */
@@ -355,13 +352,18 @@ int amiga_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy)
/* handle a wait */
if ((word1 & 1) == 0)
{
- LOGINST(" WAIT %04x & %04x (currently %04x)\n",
+ const int wait_offset = std::max(num_planes - 4, 0) + 1;
+
+ LOGINST(" WAIT %04x & %04x (currently %04x, num planes %d +%d)\n",
m_waitval,
m_waitmask,
- (ypos << 8) | (xpos >> 1)
+ (ypos << 8) | (xpos >> 1),
+ num_planes,
+ wait_offset
);
m_state_waiting = true;
+ xpos += COPPER_CYCLES_TO_PIXELS(wait_offset);
}
/* handle a skip */
diff --git a/src/devices/machine/amiga_copper.h b/src/devices/machine/amiga_copper.h
index aa08820c6d2..e4746bccd46 100644
--- a/src/devices/machine/amiga_copper.h
+++ b/src/devices/machine/amiga_copper.h
@@ -33,7 +33,7 @@ public:
// getters/setters
void vblank_sync();
- int execute_next(int xpos, int ypos, bool is_blitter_busy);
+ int execute_next(int xpos, int ypos, bool is_blitter_busy, int num_planes);
protected:
// device-level overrides
@@ -68,7 +68,6 @@ private:
u16 m_waitmask;
u16 m_pending_offset;
u16 m_pending_data;
-// int m_wait_offset;
// waitstate delays for copper
// basically anything that doesn't belong to Angus has a penalty for Copper
diff --git a/src/mame/amiga/amiga_v.cpp b/src/mame/amiga/amiga_v.cpp
index 411e0f015e6..709a08dac37 100644
--- a/src/mame/amiga/amiga_v.cpp
+++ b/src/mame/amiga/amiga_v.cpp
@@ -539,6 +539,7 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
CUSTOM_REG(REG_COLOR00) = m_genlock_color;
/* loop over the line */
+ // TODO: copper runs on odd timeslots
next_copper_x = 0;
// FIXME: without the add this increment will skip bitplane ops
// ddf_stop_pixel_max = 0xd8 * 2 = 432 + 17 + 15 + 1(*) = 465 > width / 2 (455)
@@ -557,17 +558,20 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
{
/* execute the next batch, restoring and re-saving color 0 around it */
CUSTOM_REG(REG_COLOR00) = save_color0;
+
+ planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
+
next_copper_x = m_copper->execute_next(
x,
m_last_scanline & 0xff,
- bool(BIT(CUSTOM_REG(REG_DMACON), 14)) // BBUSY
+ bool(BIT(CUSTOM_REG(REG_DMACON), 14)), // BBUSY
+ planes
);
save_color0 = CUSTOM_REG(REG_COLOR00);
if (m_genlock_color != 0xffff)
CUSTOM_REG(REG_COLOR00) = m_genlock_color;
/* compute update-related register values */
- planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
hires = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HIRES;
ham = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HOMOD;
dualpf = CUSTOM_REG(REG_BPLCON0) & BPLCON0_DBLPF;
diff --git a/src/mame/amiga/amigaaga.cpp b/src/mame/amiga/amigaaga.cpp
index d60dc1a5ba3..d56f793d406 100644
--- a/src/mame/amiga/amigaaga.cpp
+++ b/src/mame/amiga/amigaaga.cpp
@@ -528,9 +528,8 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
CUSTOM_REG(REG_COLOR00) = m_genlock_color;
/* loop over the line */
- /* copper runs on odd timeslots */
- // TODO: diverges wrt OCS, is this right?
- next_copper_x = 2;
+ // TODO: copper runs on odd timeslots
+ next_copper_x = 0;
// TODO: verify where we're missing pixels here for the GFX pitch bitplane corruptions
// - wbenc30 scrolling in lores mode (fmode=3, expects a +58!, verify ddfstrt)
// - roadkill title (fmode=3, max +14), gameplay uses fmode=1
@@ -554,23 +553,24 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
/* time to execute the copper? */
if (x == next_copper_x)
{
+ planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
+ // TODO: verify number of planes that doesn't go beyond 8
+ if ( CUSTOM_REG(REG_BPLCON0) & BPLCON0_BPU3 )
+ planes |= 8;
+
/* execute the next batch, restoring and re-saving color 0 around it */
CUSTOM_REG(REG_COLOR00) = save_color0;
next_copper_x = m_copper->execute_next(
x,
m_last_scanline & 0xff,
- bool(BIT(CUSTOM_REG(REG_DMACON), 14)) // BBUSY
+ bool(BIT(CUSTOM_REG(REG_DMACON), 14)), // BBUSY
+ planes
);
save_color0 = CUSTOM_REG(REG_COLOR00);
if (m_genlock_color != 0xffff)
CUSTOM_REG(REG_COLOR00) = m_genlock_color;
/* compute update-related register values */
- planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
- // TODO: verify number of planes that doesn't go beyond 8
- if ( CUSTOM_REG(REG_BPLCON0) & BPLCON0_BPU3 )
- planes |= 8;
-
hires = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HIRES;
ham = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HOMOD;
dualpf = CUSTOM_REG(REG_BPLCON0) & BPLCON0_DBLPF;
@@ -606,7 +606,9 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
// FIXME: as like OCS/ECS Amiga verify this one
if ( ( CUSTOM_REG(REG_DDFSTRT) ^ CUSTOM_REG(REG_DDFSTOP) ) & 0x04 )
+ {
ddf_stop_pixel += 8;
+ }
// display window
update_display_window();
@@ -630,6 +632,8 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
{
odelay = CUSTOM_REG(REG_BPLCON1) & 0xf;
edelay = ( CUSTOM_REG(REG_BPLCON1) >> 4 ) & 0x0f;
+
+ //printf("%04x %d %04x %d %d (%02x %02x)\n", CUSTOM_REG(REG_BPLCON1), scanline, bitplane_fmode, ddf_start_pixel, ddf_stop_pixel, CUSTOM_REG(REG_DDFSTRT), CUSTOM_REG(REG_DDFSTOP));
// extended delays for AGA
// FIXME: check above table for implications about this
switch( bitplane_fmode )
@@ -876,6 +880,7 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
}
}
+// TODO: move to debugger command
#if 0
if ( m_screen->frame_number() % 16 == 0 && scanline == 250 )
{
@@ -883,18 +888,18 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
const char *m_hires = "HIRES";
const char *m_ham = "HAM";
const char *m_dualpf = "DUALPF";
- const char *m_lace = "LACE";
- const char *m_hilace = "HI-LACE";
+ //const char *m_lace = "LACE";
+ //const char *m_hilace = "HI-LACE";
const char *p = m_lores;
if ( hires ) p = m_hires;
if ( ham ) p = m_ham;
if ( dualpf ) p = m_dualpf;
- if ( lace ) p = m_lace;
+ //if ( lace ) p = m_lace;
- if ( hires && lace ) p = m_hilace;
+ //if ( hires && lace ) p = m_hilace;
- popmessage("%s(%d pl od=%02x ed=%02x start=%d stop=%d hstart=%04x hstop=%04x diwhigh=%04x fetchbits=%d )", p, planes, odelay, edelay, ddf_start_pixel, ddf_stop_pixel, CUSTOM_REG(REG_DIWSTRT), CUSTOM_REG(REG_DIWSTOP), CUSTOM_REG(REG_DIWHIGH), defbitoffs );
+ popmessage("%s(%d pl od=%02x ed=%02x start=%d stop=%d (%d %d H %d %d V) fetchbits=%d )", p, planes, odelay, edelay, ddf_start_pixel, ddf_stop_pixel, m_diw.min_x, m_diw.max_x, m_diw.min_y, m_diw.max_y, defbitoffs );
//popmessage("%s(%d pl bplpt1=%06X, bpl1mod=%04x, offset=%x)", p, planes, CUSTOM_REG_LONG(REG_BPL1PTH), CUSTOM_REG(REG_BPL1MOD), hires_modulo_offset );
}
#endif