summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/mame/amiga/amiga.h4
-rw-r--r--src/mame/amiga/amiga_v.cpp116
-rw-r--r--src/mame/amiga/amigaaga.cpp127
-rw-r--r--src/mame/amiga/amigaaga.h2
4 files changed, 135 insertions, 114 deletions
diff --git a/src/mame/amiga/amiga.h b/src/mame/amiga/amiga.h
index 0f6c6d1e307..5a0f2323bca 100644
--- a/src/mame/amiga/amiga.h
+++ b/src/mame/amiga/amiga.h
@@ -641,7 +641,7 @@ private:
void sprite_dma_reset(int which);
void sprite_enable_comparitor(int which, int enable);
void fetch_sprite_data(int scanline, int sprite);
- void update_sprite_dma(int scanline);
+ void update_sprite_dma(int scanline, int num);
uint32_t interleave_sprite_data(uint16_t lobits, uint16_t hibits);
int get_sprite_pixel(int x);
uint8_t assemble_odd_bitplanes(int planes, int ebitoffs);
@@ -655,7 +655,7 @@ private:
void aga_palette_write(int color_reg, uint16_t data);
void aga_fetch_sprite_data(int scanline, int sprite);
void aga_render_scanline(bitmap_rgb32 &bitmap, int scanline);
- void aga_update_sprite_dma(int scanline);
+ void aga_update_sprite_dma(int scanline, int num);
int aga_get_sprite_pixel(int x);
uint8_t aga_assemble_odd_bitplanes(int planes, int obitoffs);
uint8_t aga_assemble_even_bitplanes(int planes, int ebitoffs);
diff --git a/src/mame/amiga/amiga_v.cpp b/src/mame/amiga/amiga_v.cpp
index d61c7746f6d..fd9f04b0597 100644
--- a/src/mame/amiga/amiga_v.cpp
+++ b/src/mame/amiga/amiga_v.cpp
@@ -190,63 +190,62 @@ void amiga_state::fetch_sprite_data(int scanline, int sprite)
LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d fetch: data=%04X-%04X\n", scanline, sprite, CUSTOM_REG(REG_SPR0DATA + 4 * sprite), CUSTOM_REG(REG_SPR0DATB + 4 * sprite));
}
-void amiga_state::update_sprite_dma(int scanline)
+void amiga_state::update_sprite_dma(int scanline, int num)
{
int dmaenable = (CUSTOM_REG(REG_DMACON) & (DMACON_SPREN | DMACON_DMAEN)) == (DMACON_SPREN | DMACON_DMAEN);
- int num, maxdma;
+ int maxdma;
/* channels are limited by DDFSTART */
maxdma = (CUSTOM_REG(REG_DDFSTRT) - 0x14) / 4;
if (maxdma > 8)
maxdma = 8;
- /* loop over sprite channels */
- for (num = 0; num < maxdma; num++)
- {
- int bitmask = 1 << num;
- int vstart, vstop;
+ if (num >= maxdma)
+ return;
- /* if we are == VSTOP, fetch new control words */
- if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_dma_reload_mask & bitmask))
- {
- /* disable the sprite */
- m_sprite_comparitor_enable_mask &= ~bitmask;
- m_sprite_dma_reload_mask &= ~bitmask;
-
- /* fetch data into the control words */
- CUSTOM_REG(REG_SPR0POS + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0);
- CUSTOM_REG(REG_SPR0CTL + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2);
- CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num));
- }
+ int bitmask = 1 << num;
+ int vstart, vstop;
- /* compute vstart/vstop */
- vstart = (CUSTOM_REG(REG_SPR0POS + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 6) & 0x100);
- vstop = (CUSTOM_REG(REG_SPR0CTL + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 7) & 0x100);
+ /* if we are == VSTOP, fetch new control words */
+ if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_dma_reload_mask & bitmask))
+ {
+ /* disable the sprite */
+ m_sprite_comparitor_enable_mask &= ~bitmask;
+ m_sprite_dma_reload_mask &= ~bitmask;
+
+ /* fetch data into the control words */
+ CUSTOM_REG(REG_SPR0POS + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0);
+ CUSTOM_REG(REG_SPR0CTL + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2);
+ CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num));
+ }
- /* if we hit vstart, enable the comparitor */
- if (scanline == vstart)
- {
- m_sprite_comparitor_enable_mask |= 1 << num;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor enable\n", scanline, num);
- }
+ /* compute vstart/vstop */
+ vstart = (CUSTOM_REG(REG_SPR0POS + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 6) & 0x100);
+ vstop = (CUSTOM_REG(REG_SPR0CTL + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 7) & 0x100);
- /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */
- if (scanline == vstop)
- {
- m_sprite_ctl_written &= ~bitmask;
- m_sprite_comparitor_enable_mask &= ~bitmask;
- m_sprite_dma_reload_mask |= 1 << num;
- CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */
- CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num);
- }
+ /* if we hit vstart, enable the comparitor */
+ if (scanline == vstart)
+ {
+ m_sprite_comparitor_enable_mask |= 1 << num;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor enable\n", scanline, num);
+ }
- /* fetch data if this sprite is enabled */
- if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_comparitor_enable_mask & bitmask))
- {
- fetch_sprite_data(scanline, num);
- }
+ /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */
+ if (scanline == vstop)
+ {
+ m_sprite_ctl_written &= ~bitmask;
+ m_sprite_comparitor_enable_mask &= ~bitmask;
+ m_sprite_dma_reload_mask |= 1 << num;
+ CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */
+ CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num);
+ }
+
+ /* fetch data if this sprite is enabled */
+ if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_comparitor_enable_mask & bitmask))
+ {
+ fetch_sprite_data(scanline, num);
}
}
@@ -471,6 +470,7 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
int hires = 0, dualpf = 0, ham = 0;
int pf1pri = 0, pf2pri = 0;
int planes = 0;
+ int raw_scanline = 0;
uint32_t *dst = nullptr;
int ebitoffs = 0, obitoffs = 0;
@@ -522,11 +522,7 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
}
}
- /* update sprite data fetching */
- // ensure this happens once every two scanlines for the RAM manipulation, kickoff cares
- // this is also unaffected by LACE
- if ((scanline & 1) == 0)
- update_sprite_dma(scanline >> 1);
+ raw_scanline = scanline;
scanline /= 2;
@@ -549,8 +545,8 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
// - no separation of video and logic models;
// - the offsets we are applying to DDFSTRT and DDFSTOP, they mustn't be right (copper timings?);
// - ditto for DIW related values, they are offset in far too many places;
- // - Twintris intro expects +11 on fast scrolling section (glitches at sides)
- for (int x = 0; x < (amiga_state::SCREEN_WIDTH / 2) + 10; x++)
+ // - Twintris intro/suprfrog expects +11 on fast scrolling section (glitches at sides)
+ for (int x = 0; x < (amiga_state::SCREEN_WIDTH / 2) + 11; x++)
{
int sprpix;
const bool out_of_beam = x >= amiga_state::SCREEN_WIDTH / 2;
@@ -606,6 +602,24 @@ void amiga_state::render_scanline(bitmap_rgb32 &bitmap, int scanline)
ecolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x2a;
}
+ /* update sprite data fetching */
+ // ensure this happens once every two scanlines for the RAM manipulation, kickoff cares
+ // this is also unaffected by LACE
+ if ((raw_scanline & 1) == 0)
+ {
+ // TODO: refine
+ // Sprite DMA loads first two words at $14 + num * 4, other 2 words at $18 + num * 4
+ // NOTE: position $28 for sprite 4 has a typo on HRM diagram
+ // non-zero DMA fetches are required by:
+ // - beast gameplay, suprfrog player sprite, abreed (top left counter)
+ if (x >= 0x18 && x <= 0x34 && (x & 3) == 0)
+ {
+ int num = (x - 0x18) >> 2;
+ //printf("%d %02x\n", num, x);
+ update_sprite_dma(raw_scanline >> 1, num);
+ }
+ }
+
/* clear the target pixels to the background color as a starting point */
if (dst != nullptr && !out_of_beam)
{
diff --git a/src/mame/amiga/amigaaga.cpp b/src/mame/amiga/amigaaga.cpp
index d7697827121..a6956a7d51d 100644
--- a/src/mame/amiga/amigaaga.cpp
+++ b/src/mame/amiga/amigaaga.cpp
@@ -153,10 +153,10 @@ void amiga_state::aga_fetch_sprite_data(int scanline, int sprite)
m_aga_sprite_dma_used_words[sprite] = 0;
}
-void amiga_state::aga_update_sprite_dma(int scanline)
+void amiga_state::aga_update_sprite_dma(int scanline, int num)
{
int dmaenable = (CUSTOM_REG(REG_DMACON) & (DMACON_SPREN | DMACON_DMAEN)) == (DMACON_SPREN | DMACON_DMAEN);
- int num, maxdma;
+ int maxdma;
const u16 sprctl_offs[4] = {2, 4, 4, 8};
const u16 spr_fmode_inc = sprctl_offs[(CUSTOM_REG(REG_FMODE) >> 2) & 0x03];
@@ -165,63 +165,62 @@ void amiga_state::aga_update_sprite_dma(int scanline)
if (maxdma > 8)
maxdma = 8;
- /* loop over sprite channels */
- for (num = 0; num < maxdma; num++)
- {
- int bitmask = 1 << num;
- int vstart, vstop;
+ if (num >= maxdma)
+ return;
- /* if we are == VSTOP, fetch new control words */
- if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_dma_reload_mask & bitmask) && !(m_sprite_ctl_written & bitmask))
- {
- /* disable the sprite */
- m_sprite_comparitor_enable_mask &= ~bitmask;
- m_sprite_dma_reload_mask &= ~bitmask;
-
- /* fetch data into the control words */
- CUSTOM_REG(REG_SPR0POS + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0);
- // diggers AGA suggests that the fmode increments with ctl are interleaved,
- // otherwise no sprites are drawn.
- // (it enables sprite 0 only, and +8 for the vstop values)
- CUSTOM_REG(REG_SPR0CTL + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + spr_fmode_inc);
- CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 2 * spr_fmode_inc;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num));
- }
+ int bitmask = 1 << num;
+ int vstart, vstop;
- u16 spr0ctl = CUSTOM_REG(REG_SPR0CTL + 4 * num);
- /* compute vstart/vstop */
- // bits 6 and 5 are respectively vstart bit 9 and vstop bit 9
- // TODO: do they disable with non-AGA modes?
- vstart = (CUSTOM_REG(REG_SPR0POS + 4 * num) >> 8);
- vstart |= (spr0ctl & 0x04) ? 0x100 : 0;
- vstart |= (spr0ctl & 0x40) ? 0x200 : 0;
- vstop = (spr0ctl >> 8);
- vstop |= (spr0ctl & 0x02) ? 0x100 : 0;
- vstop |= (spr0ctl & 0x20) ? 0x200 : 0;
-
- /* if we hit vstart, enable the comparitor */
- if (scanline == vstart)
- {
- m_sprite_comparitor_enable_mask |= 1 << num;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor enable\n", scanline, num);
- }
+ /* if we are == VSTOP, fetch new control words */
+ if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_dma_reload_mask & bitmask) && !(m_sprite_ctl_written & bitmask))
+ {
+ /* disable the sprite */
+ m_sprite_comparitor_enable_mask &= ~bitmask;
+ m_sprite_dma_reload_mask &= ~bitmask;
+
+ /* fetch data into the control words */
+ CUSTOM_REG(REG_SPR0POS + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0);
+ // diggers AGA suggests that the fmode increments with ctl are interleaved,
+ // otherwise no sprites are drawn.
+ // (it enables sprite 0 only, and +8 for the vstop values)
+ CUSTOM_REG(REG_SPR0CTL + 4 * num) = read_chip_ram(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + spr_fmode_inc);
+ CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 2 * spr_fmode_inc;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num));
+ }
- /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */
- if (scanline == vstop)
- {
- m_sprite_ctl_written &= ~bitmask;
- m_sprite_comparitor_enable_mask &= ~bitmask;
- m_sprite_dma_reload_mask |= 1 << num;
- CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */
- CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0;
- LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num);
- }
+ u16 spr0ctl = CUSTOM_REG(REG_SPR0CTL + 4 * num);
+ /* compute vstart/vstop */
+ // bits 6 and 5 are respectively vstart bit 9 and vstop bit 9
+ // TODO: do they disable with non-AGA modes?
+ vstart = (CUSTOM_REG(REG_SPR0POS + 4 * num) >> 8);
+ vstart |= (spr0ctl & 0x04) ? 0x100 : 0;
+ vstart |= (spr0ctl & 0x40) ? 0x200 : 0;
+ vstop = (spr0ctl >> 8);
+ vstop |= (spr0ctl & 0x02) ? 0x100 : 0;
+ vstop |= (spr0ctl & 0x20) ? 0x200 : 0;
+
+ /* if we hit vstart, enable the comparitor */
+ if (scanline == vstart)
+ {
+ m_sprite_comparitor_enable_mask |= 1 << num;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor enable\n", scanline, num);
+ }
- /* fetch data if this sprite is enabled */
- if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_comparitor_enable_mask & bitmask))
- {
- aga_fetch_sprite_data(scanline, num);
- }
+ /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */
+ if (scanline == vstop)
+ {
+ m_sprite_ctl_written &= ~bitmask;
+ m_sprite_comparitor_enable_mask &= ~bitmask;
+ m_sprite_dma_reload_mask |= 1 << num;
+ CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */
+ CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0;
+ LOGMASKED(LOG_SPRITE_DMA, "%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num);
+ }
+
+ /* fetch data if this sprite is enabled */
+ if (dmaenable && (m_sprite_dma_live_mask & bitmask) && (m_sprite_comparitor_enable_mask & bitmask))
+ {
+ aga_fetch_sprite_data(scanline, num);
}
}
@@ -462,6 +461,7 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
int hires = 0, dualpf = 0, ham = 0, ehb = 0;
int pf1pri = 0, pf2pri = 0;
int planes = 0;
+ int raw_scanline = 0;
uint32_t *dst = nullptr;
int ebitoffs = 0, obitoffs = 0;
@@ -513,14 +513,12 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
}
}
+ raw_scanline = scanline;
+
scanline /= 2;
m_last_scanline = scanline;
- /* update sprite data fetching */
- // FIXME: verify and apply same logic as per OCS
- aga_update_sprite_dma(scanline);
-
/* all sprites off at the start of the line */
memset(m_sprite_remain, 0, sizeof(m_sprite_remain));
@@ -623,6 +621,17 @@ void amiga_state::aga_render_scanline(bitmap_rgb32 &bitmap, int scanline)
ecolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x2a;
}
+ if ((raw_scanline & 1) == 0)
+ {
+ // TODO: refine, merge with OCS version
+ if (x >= 0x18 && x <= 0x34 && (x & 3) == 0)
+ {
+ int num = (x - 0x18) >> 2;
+ //printf("%d %02x\n", num, x);
+ aga_update_sprite_dma(raw_scanline >> 1, num);
+ }
+ }
+
/* clear the target pixels to the background color as a starting point */
if (dst != nullptr && !out_of_beam)
dst[x*2+0] =
diff --git a/src/mame/amiga/amigaaga.h b/src/mame/amiga/amigaaga.h
index 3baeca8cf9b..0e864480ad3 100644
--- a/src/mame/amiga/amigaaga.h
+++ b/src/mame/amiga/amigaaga.h
@@ -5,6 +5,4 @@
#pragma once
-void amiga_aga_palette_write(running_machine &machine, int color_reg, uint16_t data);
-
#endif // MAME_AMIGA_AMIGAAGA_H