mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
Merge branch 'master' of https://github.com/mamedev/mame
This commit is contained in:
commit
5675bdec9c
@ -242,13 +242,8 @@ void elan_eu3a05_state::elan_eu3a05_map(address_map &map)
|
||||
map(0x502a, 0x502a).rw(m_vid, FUNC(elan_eu3a05vid_device::tile_gfxbase_hi_r), FUNC(elan_eu3a05vid_device::tile_gfxbase_hi_w)); // tilebase
|
||||
map(0x502b, 0x502b).rw(m_vid, FUNC(elan_eu3a05vid_device::sprite_gfxbase_lo_r), FUNC(elan_eu3a05vid_device::sprite_gfxbase_lo_w)); // tilebase (spr?)
|
||||
map(0x502c, 0x502c).rw(m_vid, FUNC(elan_eu3a05vid_device::sprite_gfxbase_hi_r), FUNC(elan_eu3a05vid_device::sprite_gfxbase_hi_w)); // tilebase (spr?)
|
||||
map(0x502d, 0x502d).ram();
|
||||
map(0x502e, 0x502e).rw(m_vid, FUNC(elan_eu3a05vid_device::splitpos_r), FUNC(elan_eu3a05vid_device::splitpos_w)); // split position
|
||||
map(0x502f, 0x502f).ram();
|
||||
|
||||
map(0x5030, 0x5030).ram();
|
||||
map(0x5031, 0x5032).rw(m_vid, FUNC(elan_eu3a05vid_device::tile_scroll_r), FUNC(elan_eu3a05vid_device::tile_scroll_w));
|
||||
map(0x5033, 0x5036).rw(m_vid, FUNC(elan_eu3a05vid_device::tile_xscroll_r), FUNC(elan_eu3a05vid_device::tile_xscroll_w)); // there are 2 scroll values in here, air blaster 3d stages uses split scrolling like huntin'3 on eu3a14
|
||||
map(0x502d, 0x502e).rw(m_vid, FUNC(elan_eu3a05vid_device::splitpos_r), FUNC(elan_eu3a05vid_device::splitpos_w)); // split position
|
||||
map(0x502f, 0x5036).rw(m_vid, FUNC(elan_eu3a05vid_device::tile_scroll_r), FUNC(elan_eu3a05vid_device::tile_scroll_w)); // there are 4 scroll values in here, x scroll, y scroll, xscroll1 for split, xscroll2 for split (eu3a14 can do split too)
|
||||
// 5037
|
||||
map(0x5038, 0x5038).ram();
|
||||
|
||||
@ -444,20 +439,26 @@ INTERRUPT_GEN_MEMBER(elan_eu3a05_state::interrupt)
|
||||
}
|
||||
|
||||
|
||||
// Tetris (PAL version) has XTAL of 21.281370
|
||||
// Air Blaster (PAL version) has XTAL of 21.2813
|
||||
// what are the NTSC clocks?
|
||||
/* Tetris (PAL version) has XTAL of 21.281370
|
||||
Air Blaster (PAL version) has XTAL of 21.2813
|
||||
what are the NTSC clocks?
|
||||
|
||||
// not confirmed on Space Invaders, actual CPU clock unknown.
|
||||
// 21281370 is the same value as a PAL SNES
|
||||
// game speed in Air Blaster appears to be limited entirely by CPU speed (and therefore needs to be around 2mhz at most to match hardware)
|
||||
// low clock speed also helps with the badly programmed controls in Tetris
|
||||
not confirmed on Space Invaders, actual CPU clock unknown.
|
||||
21281370 is the same value as a PAL SNES
|
||||
|
||||
game logic speed (but not level scroll speed) in Air Blaster appears to be limited entirely by CPU speed (and therefore needs to be around 2-3mhz
|
||||
at most to match hardware) - a divider of 8 gives something close to original hardware
|
||||
it is unclear exactly what limits the clock speed (maybe video / sound causes waitstates? - dma in progress could also slow / stop the CPU
|
||||
and is not going to be 'instant' on hardware)
|
||||
|
||||
using a low clock speed also helps with the badly programmed controls in Tetris as that likewise seems to run the game logic 'as fast as possible'
|
||||
there don't appear to be any kind of blanking bits being checked.
|
||||
*/
|
||||
|
||||
void elan_eu3a05_state::elan_eu3a05(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M6502(config, m_maincpu, XTAL(21'281'370)/12); // wrong, this is the PAL clock
|
||||
M6502(config, m_maincpu, XTAL(21'281'370)/8); // wrong, this is the PAL clock
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &elan_eu3a05_state::elan_eu3a05_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(elan_eu3a05_state::interrupt));
|
||||
|
||||
|
@ -35,19 +35,17 @@ void elan_eu3a05vid_device::device_reset()
|
||||
|
||||
m_vidctrl = 0x00; // need to default to an 8x8 mode for Space Invaders test mode at least
|
||||
|
||||
for (int i=0;i<2;i++)
|
||||
for (int i=0;i<4*2;i++)
|
||||
m_tile_scroll[i] = 0x00;
|
||||
|
||||
for (int i=0;i<2;i++)
|
||||
m_tile_xscroll[i] = 0x00;
|
||||
|
||||
m_tile_gfxbase_lo_data = 0x00;
|
||||
m_tile_gfxbase_hi_data = 0x00;
|
||||
|
||||
m_sprite_gfxbase_lo_data = 0x00;
|
||||
m_sprite_gfxbase_hi_data = 0x00;
|
||||
|
||||
m_splitpos = 0x00;
|
||||
for (int i=0;i<2;i++)
|
||||
m_splitpos[i] = 0x00;
|
||||
}
|
||||
|
||||
uint8_t elan_eu3a05vid_device::read_spriteram(int offset)
|
||||
@ -258,11 +256,11 @@ bool elan_eu3a05vid_device::get_tile_data(int base, int drawpri, int& tile, int
|
||||
}
|
||||
void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& bitmap, const rectangle& cliprect, int drawpri)
|
||||
{
|
||||
/*
|
||||
/*
|
||||
this doesn't handle 8x8 4bpp (not used by anything yet)
|
||||
*/
|
||||
|
||||
int scroll = (m_tile_scroll[1] << 8) | m_tile_scroll[0];
|
||||
int scroll = get_scroll(1);
|
||||
address_space& fullbankspace = m_bank->space(AS_PROGRAM);
|
||||
|
||||
// Phoenix scrolling actually skips a pixel, jumping from 0x001 to 0x1bf, scroll 0x000 isn't used, maybe it has other meanings?
|
||||
@ -331,10 +329,20 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
|
||||
int scrollx;
|
||||
|
||||
// split can be probably configured in more ways than this
|
||||
if (drawline > m_splitpos)
|
||||
scrollx = get_xscroll(1);
|
||||
// exact enable conditions unclear
|
||||
int splitpos = (m_splitpos[0] << 8) | m_splitpos[1];
|
||||
|
||||
if (splitpos != 0xffff)
|
||||
{
|
||||
if (drawline > splitpos)
|
||||
scrollx = get_scroll(3);
|
||||
else
|
||||
scrollx = get_scroll(2);
|
||||
}
|
||||
else
|
||||
scrollx = get_xscroll(0);
|
||||
{
|
||||
scrollx = get_scroll(0);
|
||||
}
|
||||
|
||||
int base;
|
||||
|
||||
@ -362,92 +370,64 @@ void elan_eu3a05vid_device::draw_tilemaps(screen_device& screen, bitmap_ind16& b
|
||||
|
||||
int colour = attr & 0xf0;
|
||||
|
||||
if (m_vidctrl & 0x40) // 16x16 tiles
|
||||
{
|
||||
if (m_vidctrl & 0x20) // 4bpp mode
|
||||
{
|
||||
tile = (tile & 0xf) + ((tile & ~0xf) * 16);
|
||||
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
tile = (tile & 0xf) + ((tile & ~0xf) * 16);
|
||||
tile <<= 1;
|
||||
/* 'tiles' are organized / extracted from 'texture' lines that form a 'page' the length of the rom
|
||||
each texture line in 8bpp mode is 256 bytes
|
||||
each texture line in 4bpp mode is 128 bytes
|
||||
in 8x8 mode these pages are 32 tiles wide
|
||||
in 16x16 mode these pages are 16 tiles wide
|
||||
tiles can start on any line
|
||||
|
||||
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_vidctrl & 0x20) // 4bpp
|
||||
{
|
||||
// TODO
|
||||
tile = 0x0000;//machine().rand() & 0x1ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
tile = (tile & 0x1f) + ((tile & ~0x1f) * 8);
|
||||
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
|
||||
}
|
||||
}
|
||||
it is unclear what the behavior is if the tile starts at the far edge of a line (wrap around on line?)
|
||||
|
||||
this is eu3a05 specific, eu3a14 uses a more traditional approach
|
||||
*/
|
||||
|
||||
const int tilespersrcline = 256 / tilexsize;
|
||||
const int tilespersrcline_mask = tilespersrcline - 1;
|
||||
|
||||
tile = (tile & tilespersrcline_mask) + ((tile & ~tilespersrcline_mask) * tilexsize);
|
||||
|
||||
if (!(m_vidctrl & 0x20)) // 8bpp
|
||||
tile <<= 1;
|
||||
|
||||
if (!(m_vidctrl & 0x40)) // 8*8 tiles
|
||||
tile >>= 1;
|
||||
|
||||
tile += ((m_tile_gfxbase_lo_data | m_tile_gfxbase_hi_data << 8) << 5);
|
||||
|
||||
uint16_t* row = &bitmap.pix16(drawline);
|
||||
|
||||
if (m_vidctrl & 0x40) // 16x16 tiles
|
||||
if (m_vidctrl & 0x20) // 4bpp
|
||||
{
|
||||
if (m_vidctrl & 0x20) // 4bpp
|
||||
for (int xx = 0; xx < tilexsize; xx += 2)
|
||||
{
|
||||
for (int xx = 0; xx < tilexsize; xx += 2)
|
||||
{
|
||||
int realaddr = ((tile + i * 16) << 3) + (xx >> 1);
|
||||
uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
int realaddr = ((tile + i * 16) << 3) + (xx >> 1);
|
||||
uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
|
||||
int drawxpos;
|
||||
int drawxpos;
|
||||
|
||||
drawxpos = x * 16 + xx + 0;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0xf0) >> 4) + colour;
|
||||
drawxpos = x * tilexsize + xx + 0 - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0xf0) >> 4) + colour;
|
||||
|
||||
drawxpos = x * 16 + xx + 1;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0x0f) >> 0) + colour;
|
||||
}
|
||||
}
|
||||
else // 8bpp
|
||||
{
|
||||
for (int xx = 0; xx < tilexsize; xx++)
|
||||
{
|
||||
int realaddr = ((tile + i * 32) << 3) + xx;
|
||||
uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
|
||||
int drawxpos = x * 16 + xx;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
|
||||
}
|
||||
drawxpos = x * tilexsize + xx + 1 - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = ((pix & 0x0f) >> 0) + colour;
|
||||
}
|
||||
}
|
||||
else // 8x8 tiles
|
||||
else // 8bpp
|
||||
{
|
||||
if (m_vidctrl & 0x20) // 4bpp
|
||||
for (int xx = 0; xx < tilexsize; xx++)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int xx = 0; xx < tilexsize; xx++)
|
||||
{
|
||||
const int realaddr = ((tile + i * 32) << 3) + xx;
|
||||
const uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
int realaddr = ((tile + i * 32) << 3) + xx;
|
||||
uint8_t pix = fullbankspace.read_byte(realaddr);
|
||||
|
||||
int drawxpos = x * tilexsize + xx - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
|
||||
}
|
||||
int drawxpos = x * tilexsize + xx - scrollx;
|
||||
drawxpos &= 0x1ff;
|
||||
if ((drawxpos >= 0) && (drawxpos < 256))
|
||||
row[drawxpos] = (pix + ((colour & 0x70) << 1)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -533,34 +513,26 @@ WRITE8_MEMBER(elan_eu3a05vid_device::tile_scroll_w)
|
||||
m_tile_scroll[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(elan_eu3a05vid_device::tile_xscroll_r)
|
||||
{
|
||||
return m_tile_xscroll[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05vid_device::tile_xscroll_w)
|
||||
{
|
||||
m_tile_xscroll[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(elan_eu3a05vid_device::splitpos_r)
|
||||
{
|
||||
return m_splitpos;
|
||||
return m_splitpos[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05vid_device::splitpos_w)
|
||||
{
|
||||
m_splitpos = data;
|
||||
m_splitpos[offset] = data;
|
||||
}
|
||||
|
||||
uint16_t elan_eu3a05vid_device::get_xscroll(int which)
|
||||
uint16_t elan_eu3a05vid_device::get_scroll(int which)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0x0: return (m_tile_xscroll[1] << 8) | (m_tile_xscroll[0]);
|
||||
case 0x1: return (m_tile_xscroll[3] << 8) | (m_tile_xscroll[2]);
|
||||
case 0x0: return (m_tile_scroll[1] << 8) | (m_tile_scroll[0]); // xscroll
|
||||
case 0x1: return (m_tile_scroll[3] << 8) | (m_tile_scroll[2]); // yscroll
|
||||
case 0x2: return (m_tile_scroll[5] << 8) | (m_tile_scroll[4]); // xsplit 1 scroll
|
||||
case 0x3: return (m_tile_scroll[7] << 8) | (m_tile_scroll[6]); // scplit 2 scroll
|
||||
}
|
||||
|
||||
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,10 @@ public:
|
||||
DECLARE_READ8_MEMBER(tile_scroll_r);
|
||||
DECLARE_WRITE8_MEMBER(tile_scroll_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(tile_xscroll_r);
|
||||
DECLARE_WRITE8_MEMBER(tile_xscroll_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(splitpos_r);
|
||||
DECLARE_WRITE8_MEMBER(splitpos_w);
|
||||
|
||||
uint16_t get_xscroll(int which);
|
||||
uint16_t get_scroll(int which);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
@ -61,10 +58,9 @@ private:
|
||||
uint8_t m_sprite_gfxbase_lo_data;
|
||||
uint8_t m_sprite_gfxbase_hi_data;
|
||||
|
||||
uint8_t m_tile_scroll[2];
|
||||
uint8_t m_tile_xscroll[4];
|
||||
uint8_t m_tile_scroll[4*2];
|
||||
|
||||
uint8_t m_splitpos;
|
||||
uint8_t m_splitpos[2];
|
||||
|
||||
bool get_tile_data(int base, int drawpri, int& tile, int &attr, int &unk2);
|
||||
void draw_tilemaps(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int drawpri);
|
||||
|
Loading…
Reference in New Issue
Block a user