amiga/agnus_copper: delay MOVE writes regardless of what register it triggers

This commit is contained in:
angelosa 2025-01-09 14:51:32 +01:00
parent 999a9a252e
commit 252fba2a86
5 changed files with 21 additions and 44 deletions

View File

@ -49337,7 +49337,7 @@ ATK test: OK
<publisher>Team 17</publisher>
<notes><![CDATA[
Red screen [FDC] dsksync (fixed?)
a500: no main sprite (works with a500p, a1200)
Main sprite randomly don't show up, [Copper]?
[Copper] cuts bottom part of screen badly during gameplay, may use SKIP
ATK test: failed
]]></notes>

View File

@ -309,22 +309,14 @@ int agnus_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy,
word0 = (word0 >> 1) & 0xff;
if (word0 >= m_cdang_setting)
{
if (delay[word0] == 0)
{
//LOGCHIPSET("%02X.%02X: Write to %s = %04x\n", ypos, xpos / 2, s_custom_reg_names[word0 & 0xff], word1);
LOGCHIPSET("%02X.%02X: MOVE $dff%03x = %04x\n",
ypos,
xpos / 2,
word0 << 1,
word1
);
m_host_space->write_word(0xdff000 | (word0 << 1), word1);
}
else // additional 2 cycles needed for non-Agnus registers
{
m_pending_offset = word0;
m_pending_data = word1;
}
// delay write to the next available DMA slot if not in blanking area
// - bchvolly (title), suprfrog & abreed (bottom playfield rows)
const bool horizontal_blank = xpos < 0x47;
const int move_offset = horizontal_blank ? 0 : std::max(num_planes - 4, 0);
m_pending_offset = word0;
m_pending_data = word1;
xpos += COPPER_CYCLES_TO_PIXELS(move_offset);
}
/* illegal writes suspend until next frame */
@ -351,7 +343,8 @@ int agnus_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy,
/* handle a wait */
if ((word1 & 1) == 0)
{
const int wait_offset = std::max(num_planes - 4, 0) + 1;
const bool horizontal_blank = xpos < 0x47;
const int wait_offset = horizontal_blank ? 0 : std::max(num_planes - 4, 0) + 1;
LOGINST(" WAIT %04x & %04x (currently %04x, num planes %d +%d)\n",
m_waitval,
@ -383,6 +376,8 @@ int agnus_copper_device::execute_next(int xpos, int ypos, bool is_blitter_busy,
LOGINST(" Skipped\n");
/* count the cycles it out have taken to fetch the next instruction */
// TODO: look ahead, check if next instruction is a valid MOVE
// SKIP/WAIT and illegal instructions aren't skipped.
m_pc += 4;
xpos += COPPER_CYCLES_TO_PIXELS(2);
}

View File

@ -68,30 +68,6 @@ private:
u16 m_waitmask;
u16 m_pending_offset;
u16 m_pending_data;
// waitstate delays for copper
// basically anything that doesn't belong to Angus has a penalty for Copper
static constexpr u16 delay[256] =
{
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 0x000 - 0x03e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x040 - 0x05e */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x060 - 0x07e */
0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x080 - 0x09e */
1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0, /* 0x0a0 - 0x0de */
/* BPLxPTH/BPLxPTL */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x0e0 - 0x0fe */
/* BPLCON0-3,BPLMOD1-2 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x100 - 0x11e */
/* SPRxPTH/SPRxPTL */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x120 - 0x13e */
/* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0x140 - 0x17e */
/* COLORxx */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x180 - 0x1be */
/* RESERVED */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0x1c0 - 0x1fe */
};
};

View File

@ -1700,6 +1700,9 @@ void amiga_state::custom_chip_w(offs_t offset, uint16_t data)
{
CUSTOM_REG(REG_BEAMCON0) = data;
update_screenmode();
// TODO: variable beam counter, disables hard display stops, enables HTOTAL/VTOTAL programming
if (BIT(data, 7))
popmessage("BEAMCON0: VARBEAMEN enabled");
}
break;

View File

@ -623,10 +623,13 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
if ((raw_scanline & 1) == 0)
{
const int min_x = 0x18 << 1;
const int max_x = 0x34 << 1;
// TODO: refine, merge with OCS version
if (x >= 0x18 && x <= 0x34 && (x & 3) == 0)
if (x >= min_x && x <= max_x && (x & 7) == 0)
{
int num = (x - 0x18) >> 2;
int num = (x - min_x) >> 3;
//printf("%d %02x\n", num, x);
aga_update_sprite_dma(raw_scanline >> 1, num);
}