i8244: fix problem with missing characters, add dot grid

This commit is contained in:
hap 2020-08-03 20:00:14 +02:00
parent 6ea41576be
commit e9871210e4
3 changed files with 87 additions and 126 deletions

View File

@ -543,7 +543,7 @@ The C7010 Chess Module had a NSC800 CMOS microprocessor, with 2K RAM and 8K ROM.
</part>
</software>
<software name="chess" supported="partial">
<software name="chess">
<description>Chess Module (Euro)</description>
<year>1982</year>
<publisher>Philips</publisher>
@ -710,7 +710,7 @@ The C7010 Chess Module had a NSC800 CMOS microprocessor, with 2K RAM and 8K ROM.
</part>
</software>
<software name="2dpthmrk" supported="partial">
<software name="2dpthmrk">
<description>Depth Charge/Marksman (Euro)</description>
<year>1980</year>
<publisher>Philips</publisher>
@ -1707,7 +1707,7 @@ The C7010 Chess Module had a NSC800 CMOS microprocessor, with 2K RAM and 8K ROM.
</part>
</software>
<software name="turtles" supported="partial">
<software name="turtles">
<description>Turtles (Euro)</description>
<year>1982</year>
<publisher>Philips</publisher>
@ -1721,7 +1721,7 @@ The C7010 Chess Module had a NSC800 CMOS microprocessor, with 2K RAM and 8K ROM.
</part>
</software>
<software name="turtlesu" cloneof="turtles" supported="partial">
<software name="turtlesu" cloneof="turtles">
<description>Turtles (USA)</description>
<year>1983</year>
<publisher>Philips</publisher>

View File

@ -365,27 +365,26 @@ void i8244_device::render_scanline(int vpos)
//static const uint8_t COLLISION_EXTERNAL_UNUSED = 0x40;
static const uint8_t COLLISION_CHARACTERS = 0x80;
uint8_t collision_map[160];
if ( vpos == m_start_vpos )
{
m_control_status &= ~0x08;
}
/* Clear collision map */
uint8_t collision_map[160];
memset( collision_map, 0, sizeof( collision_map ) );
/* Draw background color */
rectangle rect(START_ACTIVE_SCAN, END_ACTIVE_SCAN - 1, vpos, vpos);
rect &= screen().visible_area();
m_tmp_bitmap.fill( (m_vdc.s.color >> 3) & 0x7, rect );
if ( m_start_vpos < vpos && vpos < m_start_vblank )
{
rectangle rect;
int scanline = vpos - m_start_vpos;
m_control_status &= ~ 0x01;
/* Draw a line */
rect.set(START_ACTIVE_SCAN, END_ACTIVE_SCAN - 1, vpos, vpos);
m_tmp_bitmap.fill( (m_vdc.s.color >> 3) & 0x7, rect );
/* Clear collision map */
memset( collision_map, 0, sizeof( collision_map ) );
/* Display grid if enabled */
if ( m_vdc.s.control & 0x08 )
{
@ -455,18 +454,54 @@ void i8244_device::render_scanline(int vpos)
}
}
}
/* Draw dots part of the grid */
if ( m_vdc.s.control & 0x40 )
{
for ( int y = 0; y < 9; y++ )
{
if ( y_grid_offset + y * height <= scanline && scanline < y_grid_offset + y * height + 3 )
{
for ( int i = 0; i < 10; i++ )
{
for ( int k = 0; k < 2; k++ )
{
int px = x_grid_offset + i * width + k;
if ( px < 160 )
{
/* Check if we collide with an already drawn source object */
if ( collision_map[ px ] & m_vdc.s.collision )
{
m_collision_status |= COLLISION_HORIZ_GRID_DOTS;
}
/* Check if an already drawn object would collide with us */
if ( COLLISION_HORIZ_GRID_DOTS & m_vdc.s.collision && collision_map[ px ] )
{
m_collision_status |= collision_map[ px ];
}
collision_map[ px ] |= COLLISION_HORIZ_GRID_DOTS;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * px ) = color;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * px + 1 ) = color;
}
}
}
}
}
}
}
/* Display objects if enabled */
if ( m_vdc.s.control & 0x20 )
{
/* Regular foreground objects */
for ( int i = 0; i < ARRAY_LENGTH( m_vdc.s.foreground ); i++ )
for ( int i = ARRAY_LENGTH( m_vdc.s.foreground ) - 1; i >= 0; i-- )
{
int y = m_vdc.s.foreground[i].y & 0xFE;
int height = 8 - ( ( ( y >> 1 ) + m_vdc.s.foreground[i].ptr ) & 7 );
int height = 8 - ( ( ( y >> 1 ) + m_vdc.s.foreground[i].ptr + 1 ) & 7 );
if (height == 1) height = 8;
if ( y >= 0x0E && y <= scanline && scanline < y + height * 2 )
if ( y <= scanline && scanline < y + height * 2 )
{
uint16_t color = 8 + bgr2rgb[ ( ( m_vdc.s.foreground[i].color >> 1 ) & 0x07 ) ];
int offset = ( m_vdc.s.foreground[i].ptr | ( ( m_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( scanline - y ) >> 1 );
@ -499,59 +534,52 @@ void i8244_device::render_scanline(int vpos)
}
/* Quad objects */
for ( int i = 0; i < ARRAY_LENGTH( m_vdc.s.quad ); i++ )
for ( int i = ARRAY_LENGTH( m_vdc.s.quad ) - 1; i >= 0; i-- )
{
int y = m_vdc.s.quad[i].single[0].y & 0xFE;
int height = 8;
// Character height is always determined by the height of the 4th character
int height = 8 - ( ( ( y >> 1 ) + m_vdc.s.quad[i].single[3].ptr ) & 7 );
if (height == 1) height = 8;
if ( y <= scanline && scanline < y + height * 2 )
{
int x = m_vdc.s.quad[i].single[0].x;
// Character height is always determined by the height of the 4th character
int char_height = 8 - ( ( ( y >> 1 ) + m_vdc.s.quad[i].single[3].ptr ) & 7 );
for ( int j = 0; j < ARRAY_LENGTH( m_vdc.s.quad[0].single ); j++, x += 8 )
{
if ( y <= scanline && scanline < y + char_height * 2 )
{
uint16_t color = 8 + bgr2rgb[ ( ( m_vdc.s.quad[i].single[j].color >> 1 ) & 0x07 ) ];
int offset = ( m_vdc.s.quad[i].single[j].ptr | ( ( m_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( scanline - y ) >> 1 );
uint8_t chr = m_charset[ offset & 0x1FF ];
uint16_t color = 8 + bgr2rgb[ ( ( m_vdc.s.quad[i].single[j].color >> 1 ) & 0x07 ) ];
int offset = ( m_vdc.s.quad[i].single[j].ptr | ( ( m_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( scanline - y ) >> 1 );
uint8_t chr = m_charset[ offset & 0x1FF ];
for ( uint8_t m = 0x80; m > 0; m >>= 1, x++ )
for ( uint8_t m = 0x80; m > 0; m >>= 1, x++ )
{
if ( chr & m )
{
if ( chr & m )
if ( x >= 0 && x < 160 )
{
if ( x >= 0 && x < 160 )
/* Check if we collide with an already drawn source object */
if ( collision_map[ x ] & m_vdc.s.collision )
{
/* Check if we collide with an already drawn source object */
if ( collision_map[ x ] & m_vdc.s.collision )
{
m_collision_status |= COLLISION_CHARACTERS;
}
/* Check if an already drawn object would collide with us */
if ( COLLISION_CHARACTERS & m_vdc.s.collision && collision_map[ x ] )
{
m_collision_status |= collision_map[ x ];
}
collision_map[ x ] |= COLLISION_CHARACTERS;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * x ) = color;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * x + 1 ) = color;
m_collision_status |= COLLISION_CHARACTERS;
}
/* Check if an already drawn object would collide with us */
if ( COLLISION_CHARACTERS & m_vdc.s.collision && collision_map[ x ] )
{
m_collision_status |= collision_map[ x ];
}
collision_map[ x ] |= COLLISION_CHARACTERS;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * x ) = color;
m_tmp_bitmap.pix16( vpos, START_ACTIVE_SCAN + 10 + 2 * x + 1 ) = color;
}
}
}
else
{
x += 8;
}
}
}
}
/* Sprites */
for ( int i = 0; i < ARRAY_LENGTH( m_vdc.s.sprites ); i++ )
for ( int i = ARRAY_LENGTH( m_vdc.s.sprites ) - 1; i >= 0; i-- )
{
int y = m_vdc.s.sprites[i].y;
int height = 8;

View File

@ -5,15 +5,12 @@
Driver file to handle emulation of the Odyssey2.
TODO:
- odyssey3 cpu/video should have different clocks
- odyssey3 cpu/video should probably have a different XTAL
- backgamm does not work, it only shows the background graphics
- chess is missing some graphics: half of the statusbar chars at the top,
and the A-H row at the bottom
- missing questionmark graphics in turtles
- homecomp does not work, needs new slot device
- g7400 EF9341 R/W is connected to CPU A2, what happens if it is disobeyed?
- a lot more issues, probably, this TODO list was written by someone with
no knowledge on odyssey2
not much knowledge on odyssey2
***************************************************************************/
@ -48,12 +45,9 @@ public:
void videopac(machine_config &config);
void videopacf(machine_config &config);
void init_odyssey2();
uint32_t screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
protected:
required_device<i8048_device> m_maincpu;
required_device<i8244_device> m_i8244;
required_device<o2_cart_slot_device> m_cart;
@ -63,7 +57,6 @@ protected:
uint8_t m_p2;
uint8_t m_lum;
DECLARE_READ_LINE_MEMBER(t1_read);
void odyssey2_palette(palette_device &palette) const;
@ -294,18 +287,11 @@ void g7400_state::g7400_palette(palette_device &palette) const
palette.set_pen_colors(0, g7400_colors);
}
void odyssey2_state::init_odyssey2()
{
memset(m_ram, 0, 0x80);
uint8_t *gfx = memregion("gfx1")->base();
for (int i = 0; i < 256; i++)
gfx[i] = i; /* TODO: Why i and not 0? */
}
void odyssey2_state::machine_start()
{
memset(m_ram, 0, 0x80);
save_item(NAME(m_ram));
save_item(NAME(m_p1));
save_item(NAME(m_p2));
@ -605,51 +591,6 @@ void g7400_state::i8243_p7_w(uint8_t data)
}
static const gfx_layout odyssey2_graphicslayout =
{
8,1,
256, /* 256 characters */
1, /* 1 bits per pixel */
{ 0 }, /* no bitplanes; 1 bit per pixel */
/* x offsets */
{
0,
1,
2,
3,
4,
5,
6,
7,
},
/* y offsets */
{ 0 },
1*8
};
static const gfx_layout odyssey2_spritelayout =
{
8,1,
256, /* 256 characters */
1, /* 1 bits per pixel */
{ 0 }, /* no bitplanes; 1 bit per pixel */
/* x offsets */
{
7,6,5,4,3,2,1,0
},
/* y offsets */
{ 0 },
1*8
};
static GFXDECODE_START( gfx_odyssey2 )
GFXDECODE_ENTRY( "gfx1", 0x0000, odyssey2_graphicslayout, 0, 2 )
GFXDECODE_ENTRY( "gfx1", 0x0000, odyssey2_spritelayout, 0, 2 )
GFXDECODE_END
void odyssey2_state::odyssey2(machine_config &config)
{
@ -671,7 +612,6 @@ void odyssey2_state::odyssey2(machine_config &config)
screen.set_screen_update(FUNC(odyssey2_state::screen_update_odyssey2));
screen.set_palette("palette");
GFXDECODE(config, "gfxdecode", "palette", gfx_odyssey2);
PALETTE(config, "palette", FUNC(odyssey2_state::odyssey2_palette), 16);
SPEAKER(config, "mono").front_center();
@ -732,7 +672,6 @@ void g7400_state::g7400(machine_config &config)
screen.set_screen_update(FUNC(odyssey2_state::screen_update_odyssey2));
screen.set_palette("palette");
GFXDECODE(config, "gfxdecode", "palette", gfx_odyssey2);
PALETTE(config, "palette", FUNC(g7400_state::g7400_palette), 16);
I8243(config, m_i8243);
@ -772,46 +711,40 @@ void g7400_state::odyssey3(machine_config &config)
ROM_START (odyssey2)
ROM_REGION(0x0400,"maincpu",0)
ROM_LOAD ("o2bios.rom", 0x0000, 0x0400, CRC(8016a315) SHA1(b2e1955d957a475de2411770452eff4ea19f4cee))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
ROM_START (videopac)
ROM_REGION(0x0400,"maincpu",0)
ROM_LOAD ("o2bios.rom", 0x0000, 0x0400, CRC(8016a315) SHA1(b2e1955d957a475de2411770452eff4ea19f4cee))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
ROM_START (videopacf)
ROM_REGION(0x0400,"maincpu",0)
ROM_LOAD ("c52.rom", 0x0000, 0x0400, CRC(a318e8d6) SHA1(a6120aed50831c9c0d95dbdf707820f601d9452e))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
ROM_START (g7400)
ROM_REGION(0x0400,"maincpu",0)
ROM_LOAD ("g7400.bin", 0x0000, 0x0400, CRC(e20a9f41) SHA1(5130243429b40b01a14e1304d0394b8459a6fbae))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
ROM_START (jopac)
ROM_REGION(0x0400,"maincpu",0)
ROM_LOAD ("jopac.bin", 0x0000, 0x0400, CRC(11647ca5) SHA1(54b8d2c1317628de51a85fc1c424423a986775e4))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
ROM_START (odyssey3)
ROM_REGION(0x0400, "maincpu", 0)
ROM_LOAD ("odyssey3.bin", 0x0000, 0x0400, CRC(e2b23324) SHA1(0a38c5f2cea929d2fe0a23e5e1a60de9155815dc))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS */
COMP( 1978, odyssey2, 0, 0, odyssey2, odyssey2, odyssey2_state, init_odyssey2, "Magnavox", "Odyssey 2 (US)", 0 )
COMP( 1979, videopac, odyssey2, 0, videopac, odyssey2, odyssey2_state, init_odyssey2, "Philips", "Videopac G7000 (Europe)", 0 )
COMP( 1979, videopacf, odyssey2, 0, videopacf, odyssey2, odyssey2_state, init_odyssey2, "Philips", "Videopac C52 (France)", 0 )
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS */
COMP( 1978, odyssey2, 0, 0, odyssey2, odyssey2, odyssey2_state, empty_init, "Magnavox", "Odyssey 2 (US)", 0 )
COMP( 1979, videopac, odyssey2, 0, videopac, odyssey2, odyssey2_state, empty_init, "Philips", "Videopac G7000 (Europe)", 0 )
COMP( 1979, videopacf, odyssey2, 0, videopacf, odyssey2, odyssey2_state, empty_init, "Philips", "Videopac C52 (France)", 0 )
COMP( 1983, g7400, 0, 0, g7400, odyssey2, g7400_state, init_odyssey2, "Philips", "Videopac Plus G7400 (Europe)", MACHINE_IMPERFECT_GRAPHICS )
COMP( 1983, jopac, g7400, 0, g7400, odyssey2, g7400_state, init_odyssey2, "Philips (Brandt license)", "Jopac JO7400 (France)", MACHINE_IMPERFECT_GRAPHICS )
COMP( 1983, odyssey3, g7400, 0, odyssey3, odyssey2, g7400_state, init_odyssey2, "Magnavox", "Odyssey 3 Command Center (US, prototype)", MACHINE_IMPERFECT_GRAPHICS )
COMP( 1983, g7400, 0, 0, g7400, odyssey2, g7400_state, empty_init, "Philips", "Videopac Plus G7400 (Europe)", MACHINE_IMPERFECT_GRAPHICS )
COMP( 1983, jopac, g7400, 0, g7400, odyssey2, g7400_state, empty_init, "Philips (Brandt license)", "Jopac JO7400 (France)", MACHINE_IMPERFECT_GRAPHICS )
COMP( 1983, odyssey3, g7400, 0, odyssey3, odyssey2, g7400_state, empty_init, "Magnavox", "Odyssey 3 Command Center (US, prototype)", MACHINE_IMPERFECT_GRAPHICS )