(MESS) g7400: Moved the EF9340/1 code into a separate device. Merged all the odyseey2 code into the driver file. (nw)

This commit is contained in:
Wilbert Pol 2013-01-12 21:54:10 +00:00
parent c972bc6caf
commit 5df1c82e6d
8 changed files with 231 additions and 215 deletions

6
.gitattributes vendored
View File

@ -1697,6 +1697,9 @@ src/emu/video/crt9212.c svneol=native#text/plain
src/emu/video/crt9212.h svneol=native#text/plain
src/emu/video/dm9368.c svneol=native#text/plain
src/emu/video/dm9368.h svneol=native#text/plain
src/emu/video/ef9340_1.c svneol=native#text/plain
src/emu/video/ef9340_1.h svneol=native#text/plain
src/emu/video/ef9341_chargen.h svneol=native#text/plain
src/emu/video/generic.c svneol=native#text/plain
src/emu/video/generic.h svneol=native#text/plain
src/emu/video/h63484.c svneol=native#text/plain
@ -6434,7 +6437,6 @@ src/mess/includes/nes_mmc.h svneol=native#text/plain
src/mess/includes/newbrain.h svneol=native#text/plain
src/mess/includes/next.h svneol=native#text/plain
src/mess/includes/ob68k1a.h svneol=native#text/plain
src/mess/includes/odyssey2.h svneol=native#text/plain
src/mess/includes/ondra.h svneol=native#text/plain
src/mess/includes/orao.h svneol=native#text/plain
src/mess/includes/oric.h svneol=native#text/plain
@ -7686,7 +7688,6 @@ src/mess/video/dai.c svneol=native#text/plain
src/mess/video/dgn_beta.c svneol=native#text/plain
src/mess/video/dl1416.c svneol=native#text/plain
src/mess/video/dl1416.h svneol=native#text/plain
src/mess/video/ef9341_chargen.h svneol=native#text/plain
src/mess/video/ef9345.c svneol=native#text/plain
src/mess/video/ef9345.h svneol=native#text/plain
src/mess/video/electron.c svneol=native#text/plain
@ -7784,7 +7785,6 @@ src/mess/video/nubus_vikbw.c svneol=native#text/plain
src/mess/video/nubus_vikbw.h svneol=native#text/plain
src/mess/video/nubus_wsportrait.c svneol=native#text/plain
src/mess/video/nubus_wsportrait.h svneol=native#text/plain
src/mess/video/odyssey2.c svneol=native#text/plain
src/mess/video/ondra.c svneol=native#text/plain
src/mess/video/orao.c svneol=native#text/plain
src/mess/video/oric.c svneol=native#text/plain

View File

@ -298,6 +298,7 @@ EMUVIDEOOBJS = \
$(EMUVIDEO)/crt9021.o \
$(EMUVIDEO)/crt9212.o \
$(EMUVIDEO)/dm9368.o \
$(EMUVIDEO)/ef9340_1.o \
$(EMUVIDEO)/generic.o \
$(EMUVIDEO)/h63484.o \
$(EMUVIDEO)/hd44102.o \

View File

@ -1,71 +1,66 @@
/***************************************************************************
video/odyssey2.c
2012-02-04 DanBoris
- Changed color of background grid color 0 to match sprite color 0 (Fixes KTAA title screen)
- Fixed Odyssey2_video_w so that m_o2_vdc.reg[] is always updated (Fixes Blockout)
- Changed quad character generation so character height is always taken from 4th character (KTAA level 2)
ef9340_1.h
Thomson EF9340 + EF9341 teletext graphics chips with 1KB external
character ram.
***************************************************************************/
#include "emu.h"
#include "includes/odyssey2.h"
#include "video/ef9341_chargen.h"
#include "ef9340_1.h"
#include "ef9341_chargen.h"
#define I824X_START_ACTIVE_SCAN 6
#define I824X_END_ACTIVE_SCAN (6 + 160)
#define I824X_START_Y 1
#define I824X_SCREEN_HEIGHT 243
#define I824X_LINE_CLOCKS 228
// device type definition
const device_type EF9340_1 = &device_creator<ef9340_1_device>;
void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
static const UINT8 bgr2rgb[8] =
{
int vpos = m_screen->vpos();
0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07
};
switch ( id )
{
case TIMER_LINE:
if ( m_g7400 )
{
ef9340_scanline(vpos);
}
break;
case TIMER_HBLANK:
break;
}
ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, EF9340_1, "EF9340+EF9341", tag, owner, clock)
, m_screen_tag(NULL)
, m_screen(NULL)
//, m_start_vpos(START_Y)
//, m_start_vblank(START_Y + SCREEN_HEIGHT)
//, m_screen_lines(LINES)
{
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
void odyssey2_state::video_start()
void ef9340_1_device::device_start()
{
m_start_vpos = I824X_START_Y;
m_start_vblank = I824X_START_Y + I824X_SCREEN_HEIGHT;
assert( m_screen_tag != NULL );
m_screen = machine().device<screen_device>(m_screen_tag);
assert( m_screen != NULL );
// Let the screen create our temporary bitmap with the screen's dimensions
m_screen->register_screen_bitmap(m_tmp_bitmap);
m_line_timer = timer_alloc(TIMER_LINE);
m_line_timer->adjust( m_screen->time_until_pos(1, I824X_START_ACTIVE_SCAN ), 0, m_screen->scan_period() );
m_line_timer->adjust( m_screen->time_until_pos(0, 0), 0, m_screen->scan_period() );
m_hblank_timer = timer_alloc(TIMER_HBLANK);
m_hblank_timer->adjust( m_screen->time_until_pos(1, I824X_END_ACTIVE_SCAN + 18 ), 0, m_screen->scan_period() );
// register our state
save_item(NAME(m_ef9341.TA));
save_item(NAME(m_ef9341.TB));
save_item(NAME(m_ef9341.busy));
save_item(NAME(m_ef9340.X));
save_item(NAME(m_ef9340.Y));
save_item(NAME(m_ef9340.Y0));
save_item(NAME(m_ef9340.R));
save_item(NAME(m_ef9340.M));
save_pointer(NAME(m_ef934x_ram_a), 1024);
save_pointer(NAME(m_ef934x_ram_b), 1024);
save_pointer(NAME(m_ef934x_ext_char_ram), 1024);
}
void odyssey2_state::video_start_g7400()
void ef9340_1_device::device_reset()
{
video_start();
m_ef9340.X = 0;
m_ef9340.Y = 0;
m_ef9340.Y0 = 0;
@ -74,17 +69,21 @@ void odyssey2_state::video_start_g7400()
m_ef9341.TA = 0;
m_ef9341.TB = 0;
m_ef9341.busy = 0;
m_g7400 = true;
}
void ef9340_1_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch ( id )
{
case TIMER_LINE:
ef9340_scanline(m_screen->vpos());
break;
}
}
/*
Thomson EF9340/EF9341 extra chips in the g7400
*/
UINT16 odyssey2_state::ef9340_get_c_addr(UINT8 x, UINT8 y)
UINT16 ef9340_1_device::ef9340_get_c_addr(UINT8 x, UINT8 y)
{
if ( ( y & 0x18 ) == 0x18 )
{
@ -98,7 +97,7 @@ UINT16 odyssey2_state::ef9340_get_c_addr(UINT8 x, UINT8 y)
}
void odyssey2_state::ef9340_inc_c()
void ef9340_1_device::ef9340_inc_c()
{
m_ef9340.X++;
if ( m_ef9340.X >= 40 )
@ -109,7 +108,7 @@ void odyssey2_state::ef9340_inc_c()
}
UINT16 odyssey2_state::external_chargen_address(UINT8 b, UINT8 slice)
UINT16 ef9340_1_device::external_chargen_address(UINT8 b, UINT8 slice)
{
UINT8 cc = b & 0x7f;
@ -123,7 +122,7 @@ UINT16 odyssey2_state::external_chargen_address(UINT8 b, UINT8 slice)
}
void odyssey2_state::ef9341_w( UINT8 command, UINT8 b, UINT8 data )
void ef9340_1_device::ef9341_write( UINT8 command, UINT8 b, UINT8 data )
{
logerror("ef9341 %s write, t%s, data %02X\n", command ? "command" : "data", b ? "B" : "A", data );
@ -226,7 +225,7 @@ void odyssey2_state::ef9341_w( UINT8 command, UINT8 b, UINT8 data )
}
UINT8 odyssey2_state::ef9341_r( UINT8 command, UINT8 b )
UINT8 ef9340_1_device::ef9341_read( UINT8 command, UINT8 b )
{
UINT8 data = 0xFF;
@ -257,16 +256,11 @@ UINT8 odyssey2_state::ef9341_r( UINT8 command, UINT8 b )
}
void odyssey2_state::ef9340_scanline(int vpos)
void ef9340_1_device::ef9340_scanline(int vpos)
{
if ( vpos < m_start_vpos )
if ( vpos < 250 )
{
return;
}
if ( vpos < m_start_vblank )
{
int y = vpos - m_start_vpos;
int y = vpos - 0;
int y_row, slice;
if ( y < 10 )
@ -286,7 +280,7 @@ void odyssey2_state::ef9340_scanline(int vpos)
for ( int i = 0; i < 40 * 8; i++ )
{
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN*2 + i ) = 24;
m_tmp_bitmap.pix16(vpos, 0 + i ) = 24;
}
return;
}
@ -303,8 +297,8 @@ void odyssey2_state::ef9340_scanline(int vpos)
UINT16 addr = ef9340_get_c_addr( x, y_row );
UINT8 a = m_ef934x_ram_a[addr];
UINT8 b = m_ef934x_ram_b[addr];
UINT8 fg = 24;
UINT8 bg = 24;
UINT8 fg = 0;
UINT8 bg = 0;
UINT8 char_data = 0x00;
if ( a & 0x80 )
@ -322,13 +316,13 @@ void odyssey2_state::ef9340_scanline(int vpos)
{
// Normal
char_data = ef9341_char_set[0][b & 0x7f][slice];
fg = 24 + ( a & 0x07 );
fg = bgr2rgb[ a & 0x07 ];
}
}
for ( int i = 0; i < 8; i++ )
{
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN*2 + x*8 + i ) = (char_data & 0x80) ? fg : bg;
m_tmp_bitmap.pix16(vpos, 0 + x*8 + i ) = (char_data & 0x80) ? fg : bg;
char_data <<= 1;
}
}

85
src/emu/video/ef9340_1.h Normal file
View File

@ -0,0 +1,85 @@
/***************************************************************************
ef9340_1.h
Thomson EF9340 + EF9341 teletext graphics chips with 1KB external
character ram.
***************************************************************************/
#pragma once
#ifndef __EF9340_1_H__
#define __EF9340_1_H__
#include "emu.h"
#define MCFG_EF9340_1_ADD(_tag, _clock, _screen_tag) \
MCFG_DEVICE_ADD(_tag, EF9340_1, _clock) \
ef9340_1_device::set_screen_tag(*device, _screen_tag); \
class ef9340_1_device : public device_t
{
public:
// construction/destruction
ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// static configuration helpers
static void set_screen_tag(device_t &device, const char *screen_tag) { downcast<ef9340_1_device &>(device).m_screen_tag = screen_tag; }
inline bitmap_ind16 *get_bitmap() { return &m_tmp_bitmap; }
void ef9341_write( UINT8 command, UINT8 b, UINT8 data );
UINT8 ef9341_read( UINT8 command, UINT8 b );
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
inline UINT16 ef9340_get_c_addr(UINT8 x, UINT8 y);
inline void ef9340_inc_c();
// Calculate the external chargen address for a character and slice
inline UINT16 external_chargen_address(UINT8 b, UINT8 slice);
void ef9340_scanline(int vpos);
/* timers */
static const device_timer_id TIMER_LINE = 0;
emu_timer *m_line_timer;
const char *m_screen_tag;
screen_device *m_screen;
bitmap_ind16 m_tmp_bitmap;
struct
{
UINT8 TA;
UINT8 TB;
UINT8 busy;
} m_ef9341;
struct
{
UINT8 X;
UINT8 Y;
UINT8 Y0;
UINT8 R;
UINT8 M;
} m_ef9340;
UINT8 m_ef934x_ram_a[1024];
UINT8 m_ef934x_ram_b[1024];
UINT8 m_ef934x_ext_char_ram[1024];
};
// device type definition
extern const device_type EF9340_1;
#endif /* __EF9340_1_H__ */

View File

@ -9,17 +9,80 @@
TODO:
- Reimplement the cartridge slot, and thus also the voice, as a slot device
- In case any more machines (TVs?) turn up using the EF9340 and/or EF9341,
reimplement as a real device.
***************************************************************************/
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
#include "includes/odyssey2.h"
#include "imagedev/cartslot.h"
#include "sound/sp0256.h"
#include "video/i8244.h"
#include "machine/i8243.h"
#include "video/ef9340_1.h"
class odyssey2_state : public driver_device
{
public:
odyssey2_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_i8243(*this, "i8243")
, m_i8244(*this, "i8244")
, m_ef9340_1(*this, "ef9340_1")
{ }
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
optional_device<i8243_device> m_i8243;
required_device<i8244_device> m_i8244;
optional_device<ef9340_1_device> m_ef9340_1;
int m_the_voice_lrq_state;
UINT8 *m_ram;
UINT8 m_p1;
UINT8 m_p2;
size_t m_cart_size;
UINT8 m_lum;
DECLARE_READ8_MEMBER(t0_read);
DECLARE_READ8_MEMBER(io_read);
DECLARE_WRITE8_MEMBER(io_write);
DECLARE_READ8_MEMBER(bus_read);
DECLARE_WRITE8_MEMBER(bus_write);
DECLARE_READ8_MEMBER(g7400_io_read);
DECLARE_WRITE8_MEMBER(g7400_io_write);
DECLARE_READ8_MEMBER(p1_read);
DECLARE_WRITE8_MEMBER(p1_write);
DECLARE_READ8_MEMBER(p2_read);
DECLARE_WRITE8_MEMBER(p2_write);
DECLARE_READ8_MEMBER(t1_read);
DECLARE_DRIVER_INIT(odyssey2);
virtual void machine_reset();
virtual void palette_init();
UINT32 screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(the_voice_lrq_callback);
DECLARE_WRITE8_MEMBER(i8243_port_w);
DECLARE_WRITE_LINE_MEMBER(irq_callback);
DECLARE_WRITE16_MEMBER(scanline_postprocess);
DECLARE_WRITE16_MEMBER(scanline_postprocess_g7400);
protected:
/* constants */
static const UINT8 P1_BANK_LO_BIT = 0x01;
static const UINT8 P1_BANK_HI_BIT = 0x02;
static const UINT8 P1_KEYBOARD_SCAN_ENABLE = 0x04; /* active low */
static const UINT8 P1_VDC_ENABLE = 0x08; /* active low */
static const UINT8 P1_EXT_RAM_ENABLE = 0x10; /* active low */
static const UINT8 P1_VDC_COPY_MODE_ENABLE = 0x40;
static const UINT8 P2_KEYBOARD_SELECT_MASK = 0x07; /* select row to scan */
UINT8 m_g7400_ic674_decode[8];
UINT8 m_g7400_ic678_decode[8];
void switch_banks();
};
static ADDRESS_MAP_START( odyssey2_mem , AS_PROGRAM, 8, odyssey2_state )
@ -263,22 +326,6 @@ DRIVER_INIT_MEMBER(odyssey2_state,odyssey2)
}
void odyssey2_state::machine_start()
{
save_item(NAME(m_ef934x_ram_a));
save_item(NAME(m_ef934x_ram_b));
save_item(NAME(m_ef9340.X));
save_item(NAME(m_ef9340.Y));
save_item(NAME(m_ef9340.Y0));
save_item(NAME(m_ef9340.R));
save_item(NAME(m_ef9340.M));
save_item(NAME(m_ef9341.TA));
save_item(NAME(m_ef9341.TB));
save_item(NAME(m_ef9341.busy));
save_item(NAME(m_ef934x_ext_char_ram));
}
void odyssey2_state::machine_reset()
{
m_lum = 0;
@ -349,7 +396,7 @@ READ8_MEMBER(odyssey2_state::g7400_io_read)
}
else
{
return ef9341_r( offset & 0x02, offset & 0x01 );
return m_ef9340_1->ef9341_read( offset & 0x02, offset & 0x01 );
}
return 0;
@ -368,7 +415,7 @@ WRITE8_MEMBER(odyssey2_state::g7400_io_write)
}
else
{
ef9341_w( offset & 0x02, offset & 0x01, data );
m_ef9340_1->ef9341_write( offset & 0x02, offset & 0x01, data );
}
}
@ -386,6 +433,18 @@ WRITE16_MEMBER(odyssey2_state::scanline_postprocess)
}
WRITE16_MEMBER(odyssey2_state::scanline_postprocess_g7400)
{
int vpos = data;
bitmap_ind16 *bitmap = m_i8244->get_bitmap();
// apply external LUM setting
for ( int x = i8244_device::START_ACTIVE_SCAN; x < i8244_device::END_ACTIVE_SCAN; x++ )
{
bitmap->pix16( vpos, x ) |= ( m_lum ^ 0x08 );
}
}
UINT32 odyssey2_state::screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
return m_i8244->screen_update(screen, bitmap, cliprect);
@ -667,15 +726,15 @@ static MACHINE_CONFIG_START( g7400, odyssey2_state )
MCFG_SCREEN_RAW_PARAMS( 3540000*2, i8244_device::LINE_CLOCKS, i8244_device::START_ACTIVE_SCAN, i8244_device::END_ACTIVE_SCAN, i8245_device::LINES, i8244_device::START_Y, i8244_device::START_Y + i8244_device::SCREEN_HEIGHT )
MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2)
MCFG_VIDEO_START_OVERRIDE(odyssey2_state,g7400)
MCFG_GFXDECODE( odyssey2 )
MCFG_PALETTE_LENGTH(32)
MCFG_I8243_ADD( "i8243", NOOP, WRITE8(odyssey2_state,i8243_port_w))
MCFG_EF9340_1_ADD( "ef9340_1", 3540000, "screen" )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_I8245_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
MCFG_I8245_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess_g7400 ) )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
MCFG_FRAGMENT_ADD(odyssey2_cartslot)

View File

@ -1,122 +0,0 @@
/*****************************************************************************
*
* includes/odyssey2.h
*
****************************************************************************/
#ifndef ODYSSEY2_H_
#define ODYSSEY2_H_
#include "machine/i8243.h"
#include "video/i8244.h"
struct ef9341_t
{
UINT8 TA;
UINT8 TB;
UINT8 busy;
};
struct ef9340_t
{
UINT8 X;
UINT8 Y;
UINT8 Y0;
UINT8 R;
UINT8 M;
};
class odyssey2_state : public driver_device
{
public:
odyssey2_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_i8243(*this, "i8243")
, m_i8244(*this, "i8244")
, m_g7400(false)
{ }
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
optional_device<i8243_device> m_i8243;
required_device<i8244_device> m_i8244;
int m_the_voice_lrq_state;
UINT8 *m_ram;
UINT8 m_p1;
UINT8 m_p2;
size_t m_cart_size;
bitmap_ind16 m_tmp_bitmap;
int m_start_vpos;
int m_start_vblank;
UINT8 m_lum;
DECLARE_READ8_MEMBER(t0_read);
DECLARE_READ8_MEMBER(io_read);
DECLARE_WRITE8_MEMBER(io_write);
DECLARE_READ8_MEMBER(bus_read);
DECLARE_WRITE8_MEMBER(bus_write);
DECLARE_READ8_MEMBER(g7400_io_read);
DECLARE_WRITE8_MEMBER(g7400_io_write);
DECLARE_READ8_MEMBER(p1_read);
DECLARE_WRITE8_MEMBER(p1_write);
DECLARE_READ8_MEMBER(p2_read);
DECLARE_WRITE8_MEMBER(p2_write);
DECLARE_READ8_MEMBER(t1_read);
DECLARE_DRIVER_INIT(odyssey2);
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
void video_start_g7400();
virtual void palette_init();
UINT32 screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(the_voice_lrq_callback);
DECLARE_WRITE8_MEMBER(i8243_port_w);
DECLARE_WRITE_LINE_MEMBER(irq_callback);
void ef9341_w( UINT8 command, UINT8 b, UINT8 data );
UINT8 ef9341_r( UINT8 command, UINT8 b );
DECLARE_WRITE16_MEMBER(scanline_postprocess);
protected:
/* constants */
static const UINT8 P1_BANK_LO_BIT = 0x01;
static const UINT8 P1_BANK_HI_BIT = 0x02;
static const UINT8 P1_KEYBOARD_SCAN_ENABLE = 0x04; /* active low */
static const UINT8 P1_VDC_ENABLE = 0x08; /* active low */
static const UINT8 P1_EXT_RAM_ENABLE = 0x10; /* active low */
static const UINT8 P1_VDC_COPY_MODE_ENABLE = 0x40;
static const UINT8 P2_KEYBOARD_SELECT_MASK = 0x07; /* select row to scan */
ef9340_t m_ef9340;
ef9341_t m_ef9341;
UINT8 m_ef934x_ram_a[1024];
UINT8 m_ef934x_ram_b[1024];
UINT8 m_ef934x_ext_char_ram[1024];
bool m_g7400;
UINT8 m_g7400_ic674_decode[8];
UINT8 m_g7400_ic678_decode[8];
inline UINT16 ef9340_get_c_addr(UINT8 x, UINT8 y);
inline void ef9340_inc_c();
// Calculate the external chargen address for a character and slice
inline UINT16 external_chargen_address(UINT8 b, UINT8 slice);
void ef9340_scanline(int vpos);
/* timers */
static const device_timer_id TIMER_LINE = 0;
static const device_timer_id TIMER_HBLANK = 1;
emu_timer *m_line_timer;
emu_timer *m_hblank_timer;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
void switch_banks();
};
#endif /* ODYSSEY2_H_ */

View File

@ -1302,7 +1302,6 @@ $(MESSOBJ)/luxor.a: \
$(MESS_MACHINE)/s1410.o \
$(MESSOBJ)/magnavox.a: \
$(MESS_VIDEO)/odyssey2.o \
$(MESS_DRIVERS)/odyssey2.o \
$(MESSOBJ)/mattel.a: \