decocass modernized and cleaned (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2012-09-20 12:00:57 +00:00
parent 8270986acb
commit 086b4d97cd
8 changed files with 1208 additions and 1280 deletions

4
.gitattributes vendored
View File

@ -3685,6 +3685,7 @@ src/mame/includes/dec0.h svneol=native#text/plain
src/mame/includes/dec8.h svneol=native#text/plain
src/mame/includes/deco32.h svneol=native#text/plain
src/mame/includes/deco_mlc.h svneol=native#text/plain
src/mame/includes/decocass.h svneol=native#text/plain
src/mame/includes/decocrpt.h svneol=native#text/plain
src/mame/includes/decoprot.h svneol=native#text/plain
src/mame/includes/deniam.h svneol=native#text/plain
@ -4496,7 +4497,8 @@ src/mame/machine/dec0.c svneol=native#text/plain
src/mame/machine/deco102.c svneol=native#text/plain
src/mame/machine/deco156.c svneol=native#text/plain
src/mame/machine/decocass.c svneol=native#text/plain
src/mame/machine/decocass.h svneol=native#text/plain
src/mame/machine/decocass_tape.c svneol=native#text/plain
src/mame/machine/decocass_tape.h svneol=native#text/plain
src/mame/machine/decocrpt.c svneol=native#text/plain
src/mame/machine/decoprot.c svneol=native#text/plain
src/mame/machine/docastle.c svneol=native#text/plain

View File

@ -34,7 +34,8 @@
#include "emu.h"
#include "cpu/m6502/m6502.h"
#include "cpu/mcs48/mcs48.h"
#include "machine/decocass.h"
#include "includes/decocass.h"
#include "machine/decocass_tape.h"
#include "sound/ay8910.h"
#define MASTER_CLOCK XTAL_12MHz
@ -55,124 +56,116 @@ INLINE int swap_bits_5_6(int data)
return (data & 0x9f) | ((data & 0x20) << 1) | ((data & 0x40) >> 1);
}
static WRITE8_HANDLER( ram_w )
WRITE8_MEMBER(decocass_state::ram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0x0000 + offset] = swap_bits_5_6(data);
state->m_rambase[0x0000 + offset] = data;
m_decrypted[0x0000 + offset] = swap_bits_5_6(data);
m_rambase[0x0000 + offset] = data;
}
static WRITE8_HANDLER( charram_w )
WRITE8_MEMBER(decocass_state::charram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0x6000 + offset] = swap_bits_5_6(data);
m_decrypted[0x6000 + offset] = swap_bits_5_6(data);
decocass_charram_w(space, offset, data);
}
static WRITE8_HANDLER( fgvideoram_w )
WRITE8_MEMBER(decocass_state::fgvideoram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0xc000 + offset] = swap_bits_5_6(data);
m_decrypted[0xc000 + offset] = swap_bits_5_6(data);
decocass_fgvideoram_w(space, offset, data);
}
static WRITE8_HANDLER( fgcolorram_w )
WRITE8_MEMBER(decocass_state::fgcolorram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0xc400 + offset] = swap_bits_5_6(data);
m_decrypted[0xc400 + offset] = swap_bits_5_6(data);
decocass_colorram_w(space, offset, data);
}
static WRITE8_HANDLER( tileram_w )
WRITE8_MEMBER(decocass_state::tileram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0xd000 + offset] = swap_bits_5_6(data);
m_decrypted[0xd000 + offset] = swap_bits_5_6(data);
decocass_tileram_w(space, offset, data);
}
static WRITE8_HANDLER( objectram_w )
WRITE8_MEMBER(decocass_state::objectram_w)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_decrypted[0xd800 + offset] = swap_bits_5_6(data);
m_decrypted[0xd800 + offset] = swap_bits_5_6(data);
decocass_objectram_w(space, offset, data);
}
static WRITE8_HANDLER( mirrorvideoram_w ) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgvideoram_w(space, offset, data, mem_mask); }
static WRITE8_HANDLER( mirrorcolorram_w ) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgcolorram_w(space, offset, data, mem_mask); }
WRITE8_MEMBER(decocass_state::mirrorvideoram_w) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgvideoram_w(space, offset, data, mem_mask); }
WRITE8_MEMBER(decocass_state::mirrorcolorram_w) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgcolorram_w(space, offset, data, mem_mask); }
static READ8_HANDLER( mirrorvideoram_r )
READ8_MEMBER(decocass_state::mirrorvideoram_r)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5);
return state->m_fgvideoram[offset];
return m_fgvideoram[offset];
}
static READ8_HANDLER( mirrorcolorram_r )
READ8_MEMBER(decocass_state::mirrorcolorram_r)
{
decocass_state *state = space.machine().driver_data<decocass_state>();
offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5);
return state->m_colorram[offset];
return m_colorram[offset];
}
static ADDRESS_MAP_START( decocass_map, AS_PROGRAM, 8, decocass_state )
AM_RANGE(0x0000, 0x5fff) AM_RAM_WRITE_LEGACY(ram_w) AM_SHARE("rambase")
AM_RANGE(0x6000, 0xbfff) AM_RAM_WRITE_LEGACY(charram_w) AM_SHARE("charram") /* still RMS3 RAM */
AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE_LEGACY(fgvideoram_w) AM_SHARE("fgvideoram") /* DSP3 RAM */
AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE_LEGACY(fgcolorram_w) AM_SHARE("colorram")
AM_RANGE(0xc800, 0xcbff) AM_READWRITE_LEGACY(mirrorvideoram_r, mirrorvideoram_w)
AM_RANGE(0xcc00, 0xcfff) AM_READWRITE_LEGACY(mirrorcolorram_r, mirrorcolorram_w)
AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE_LEGACY(tileram_w) AM_SHARE("tileram")
AM_RANGE(0xd800, 0xdbff) AM_RAM_WRITE_LEGACY(objectram_w) AM_SHARE("objectram")
AM_RANGE(0xe000, 0xe0ff) AM_RAM_WRITE_LEGACY(decocass_paletteram_w) AM_SHARE("paletteram")
AM_RANGE(0xe300, 0xe300) AM_READ_PORT("DSW1") AM_WRITE_LEGACY(decocass_watchdog_count_w)
AM_RANGE(0xe301, 0xe301) AM_READ_PORT("DSW2") AM_WRITE_LEGACY(decocass_watchdog_flip_w)
AM_RANGE(0xe302, 0xe302) AM_WRITE_LEGACY(decocass_color_missiles_w)
AM_RANGE(0xe400, 0xe400) AM_WRITE_LEGACY(decocass_reset_w)
AM_RANGE(0x0000, 0x5fff) AM_RAM_WRITE(ram_w) AM_SHARE("rambase")
AM_RANGE(0x6000, 0xbfff) AM_RAM_WRITE(charram_w) AM_SHARE("charram") /* still RMS3 RAM */
AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE(fgvideoram_w) AM_SHARE("fgvideoram") /* DSP3 RAM */
AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE(fgcolorram_w) AM_SHARE("colorram")
AM_RANGE(0xc800, 0xcbff) AM_READWRITE(mirrorvideoram_r, mirrorvideoram_w)
AM_RANGE(0xcc00, 0xcfff) AM_READWRITE(mirrorcolorram_r, mirrorcolorram_w)
AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(tileram_w) AM_SHARE("tileram")
AM_RANGE(0xd800, 0xdbff) AM_RAM_WRITE(objectram_w) AM_SHARE("objectram")
AM_RANGE(0xe000, 0xe0ff) AM_RAM_WRITE(decocass_paletteram_w) AM_SHARE("paletteram")
AM_RANGE(0xe300, 0xe300) AM_READ_PORT("DSW1") AM_WRITE(decocass_watchdog_count_w)
AM_RANGE(0xe301, 0xe301) AM_READ_PORT("DSW2") AM_WRITE(decocass_watchdog_flip_w)
AM_RANGE(0xe302, 0xe302) AM_WRITE(decocass_color_missiles_w)
AM_RANGE(0xe400, 0xe400) AM_WRITE(decocass_reset_w)
/* BIO-3 board */
AM_RANGE(0xe402, 0xe402) AM_WRITE_LEGACY(decocass_mode_set_w)
AM_RANGE(0xe403, 0xe403) AM_WRITE_LEGACY(decocass_back_h_shift_w)
AM_RANGE(0xe404, 0xe404) AM_WRITE_LEGACY(decocass_back_vl_shift_w)
AM_RANGE(0xe405, 0xe405) AM_WRITE_LEGACY(decocass_back_vr_shift_w)
AM_RANGE(0xe406, 0xe406) AM_WRITE_LEGACY(decocass_part_h_shift_w)
AM_RANGE(0xe407, 0xe407) AM_WRITE_LEGACY(decocass_part_v_shift_w)
AM_RANGE(0xe402, 0xe402) AM_WRITE(decocass_mode_set_w)
AM_RANGE(0xe403, 0xe403) AM_WRITE(decocass_back_h_shift_w)
AM_RANGE(0xe404, 0xe404) AM_WRITE(decocass_back_vl_shift_w)
AM_RANGE(0xe405, 0xe405) AM_WRITE(decocass_back_vr_shift_w)
AM_RANGE(0xe406, 0xe406) AM_WRITE(decocass_part_h_shift_w)
AM_RANGE(0xe407, 0xe407) AM_WRITE(decocass_part_v_shift_w)
AM_RANGE(0xe410, 0xe410) AM_WRITE_LEGACY(decocass_color_center_bot_w)
AM_RANGE(0xe411, 0xe411) AM_WRITE_LEGACY(decocass_center_h_shift_space_w)
AM_RANGE(0xe412, 0xe412) AM_WRITE_LEGACY(decocass_center_v_shift_w)
AM_RANGE(0xe413, 0xe413) AM_WRITE_LEGACY(decocass_coin_counter_w)
AM_RANGE(0xe414, 0xe414) AM_WRITE_LEGACY(decocass_sound_command_w)
AM_RANGE(0xe415, 0xe416) AM_WRITE_LEGACY(decocass_quadrature_decoder_reset_w)
AM_RANGE(0xe417, 0xe417) AM_WRITE_LEGACY(decocass_nmi_reset_w)
AM_RANGE(0xe420, 0xe42f) AM_WRITE_LEGACY(decocass_adc_w)
AM_RANGE(0xe410, 0xe410) AM_WRITE(decocass_color_center_bot_w)
AM_RANGE(0xe411, 0xe411) AM_WRITE(decocass_center_h_shift_space_w)
AM_RANGE(0xe412, 0xe412) AM_WRITE(decocass_center_v_shift_w)
AM_RANGE(0xe413, 0xe413) AM_WRITE(decocass_coin_counter_w)
AM_RANGE(0xe414, 0xe414) AM_WRITE(decocass_sound_command_w)
AM_RANGE(0xe415, 0xe416) AM_WRITE(decocass_quadrature_decoder_reset_w)
AM_RANGE(0xe417, 0xe417) AM_WRITE(decocass_nmi_reset_w)
AM_RANGE(0xe420, 0xe42f) AM_WRITE(decocass_adc_w)
AM_RANGE(0xe500, 0xe5ff) AM_READWRITE_LEGACY(decocass_e5xx_r, decocass_e5xx_w) /* read data from 8041/status */
AM_RANGE(0xe500, 0xe5ff) AM_READWRITE(decocass_e5xx_r, decocass_e5xx_w) /* read data from 8041/status */
AM_RANGE(0xe600, 0xe6ff) AM_READ_LEGACY(decocass_input_r) /* inputs */
AM_RANGE(0xe700, 0xe700) AM_READ_LEGACY(decocass_sound_data_r) /* read sound CPU data */
AM_RANGE(0xe701, 0xe701) AM_READ_LEGACY(decocass_sound_ack_r) /* read sound CPU ack status */
AM_RANGE(0xe600, 0xe6ff) AM_READ(decocass_input_r) /* inputs */
AM_RANGE(0xe700, 0xe700) AM_READ(decocass_sound_data_r) /* read sound CPU data */
AM_RANGE(0xe701, 0xe701) AM_READ(decocass_sound_ack_r) /* read sound CPU ack status */
AM_RANGE(0xf000, 0xffff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START( decocass_sound_map, AS_PROGRAM, 8, decocass_state )
AM_RANGE(0x0000, 0x0fff) AM_RAM
AM_RANGE(0x1000, 0x17ff) AM_READWRITE_LEGACY(decocass_sound_nmi_enable_r, decocass_sound_nmi_enable_w)
AM_RANGE(0x1800, 0x1fff) AM_READWRITE_LEGACY(decocass_sound_data_ack_reset_r, decocass_sound_data_ack_reset_w)
AM_RANGE(0x1000, 0x17ff) AM_READWRITE(decocass_sound_nmi_enable_r, decocass_sound_nmi_enable_w)
AM_RANGE(0x1800, 0x1fff) AM_READWRITE(decocass_sound_data_ack_reset_r, decocass_sound_data_ack_reset_w)
AM_RANGE(0x2000, 0x2fff) AM_DEVWRITE_LEGACY("ay1", ay8910_data_w)
AM_RANGE(0x4000, 0x4fff) AM_DEVWRITE_LEGACY("ay1", ay8910_address_w)
AM_RANGE(0x6000, 0x6fff) AM_DEVWRITE_LEGACY("ay2", ay8910_data_w)
AM_RANGE(0x8000, 0x8fff) AM_DEVWRITE_LEGACY("ay2", ay8910_address_w)
AM_RANGE(0xa000, 0xafff) AM_READ_LEGACY(decocass_sound_command_r)
AM_RANGE(0xc000, 0xcfff) AM_WRITE_LEGACY(decocass_sound_data_w)
AM_RANGE(0xa000, 0xafff) AM_READ(decocass_sound_command_r)
AM_RANGE(0xc000, 0xcfff) AM_WRITE(decocass_sound_data_w)
AM_RANGE(0xf800, 0xffff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START( decocass_mcu_portmap, AS_IO, 8, decocass_state )
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE_LEGACY(i8041_p1_r, i8041_p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE_LEGACY(i8041_p2_r, i8041_p2_w)
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(i8041_p1_r, i8041_p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(i8041_p2_r, i8041_p2_w)
ADDRESS_MAP_END
static INPUT_PORTS_START( decocass )
@ -1617,9 +1610,9 @@ DRIVER_INIT_MEMBER(decocass_state,decocass)
save_pointer(NAME(m_decrypted), 0x10000);
/* Call the state save setup code in machine/decocass.c */
decocass_machine_state_save_init(machine());
decocass_machine_state_save_init();
/* and in video/decocass.c, too */
decocass_video_state_save_init(machine());
decocass_video_state_save_init();
}
DRIVER_INIT_MEMBER(decocass_state,decocrom)
@ -1639,7 +1632,7 @@ DRIVER_INIT_MEMBER(decocass_state,decocrom)
/* convert charram to a banked ROM */
machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_bank(0x6000, 0xafff, "bank1");
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x6000, 0xafff, FUNC(decocass_de0091_w));
machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x6000, 0xafff, write8_delegate(FUNC(decocass_state::decocass_de0091_w),this));
membank("bank1")->configure_entry(0, m_charram);
membank("bank1")->configure_entry(1, memregion("user3")->base());
membank("bank1")->configure_decrypted_entry(0, &m_decrypted[0x6000]);
@ -1647,14 +1640,13 @@ DRIVER_INIT_MEMBER(decocass_state,decocrom)
membank("bank1")->set_entry(0);
/* install the bank selector */
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xe900, 0xe900, FUNC(decocass_e900_w));
machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xe900, 0xe900, write8_delegate(FUNC(decocass_state::decocass_e900_w),this));
save_pointer(NAME(m_decrypted2), romlength);
}
static READ8_HANDLER( cdsteljn_input_r )
READ8_MEMBER(decocass_state::cdsteljn_input_r )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
UINT8 res;
static const char *const portnames[2][4] = {
{"P1_MP0", "P1_MP1", "P1_MP2", "P1_MP3"},
@ -1663,16 +1655,14 @@ static READ8_HANDLER( cdsteljn_input_r )
if(offset & 6)
return decocass_input_r(space,offset);
res = space.machine().root_device().ioport(portnames[offset & 1][state->m_mux_data])->read();
res = machine().root_device().ioport(portnames[offset & 1][m_mux_data])->read();
return res;
}
static WRITE8_HANDLER( cdsteljn_mux_w )
WRITE8_MEMBER(decocass_state::cdsteljn_mux_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_mux_data = (data & 0xc) >> 2;
m_mux_data = (data & 0xc) >> 2;
/* bit 0 and 1 are p1/p2 lamps */
if(data & ~0xf)
@ -1685,8 +1675,8 @@ DRIVER_INIT_MEMBER(decocass_state,cdsteljn)
DRIVER_INIT_CALL(decocass);
/* install custom mahjong panel */
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xe413, 0xe413, FUNC(cdsteljn_mux_w));
machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xe600, 0xe6ff, FUNC(cdsteljn_input_r));
machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xe413, 0xe413, write8_delegate(FUNC(decocass_state::cdsteljn_mux_w), this));
machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0xe600, 0xe6ff, read8_delegate(FUNC(decocass_state::cdsteljn_input_r), this));
}
/* -- */ GAME( 1981, decocass, 0, decocass, decocass, decocass_state, decocass, ROT270, "Data East Corporation", "DECO Cassette System", GAME_IS_BIOS_ROOT )

View File

@ -1,5 +1,3 @@
#include "devlegcy.h"
#ifdef MAME_DEBUG
#define LOGLEVEL 5
#else
@ -7,39 +5,17 @@
#endif
#define LOG(n,x) do { if (LOGLEVEL >= n) logerror x; } while (0)
class decocass_tape_device : public device_t
{
public:
decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~decocass_tape_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
void *m_token;
};
extern const device_type DECOCASS_TAPE;
#define MCFG_DECOCASS_TAPE_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, DECOCASS_TAPE, 0)
#include "machine/decocass_tape.h"
class decocass_state : public driver_device
{
public:
decocass_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_mcu(*this, "mcu"),
m_cassette(*this, "cassette"),
m_rambase(*this, "rambase"),
m_charram(*this, "charram"),
m_fgvideoram(*this, "fgvideoram"),
@ -48,6 +24,12 @@ public:
m_objectram(*this, "objectram"),
m_paletteram(*this, "paletteram") { }
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_mcu;
required_device<decocass_tape_device> m_cassette;
/* memory pointers */
required_shared_ptr<UINT8> m_rambase;
required_shared_ptr<UINT8> m_charram;
@ -102,8 +84,8 @@ public:
int m_i8041_p2_read_latch;
/* dongles-related */
read8_space_func m_dongle_r;
write8_space_func m_dongle_w;
read8_delegate m_dongle_r;
write8_delegate m_dongle_w;
/* dongle type #1 */
UINT32 m_type1_inmap;
@ -130,11 +112,6 @@ public:
/* DS Telejan */
UINT8 m_mux_data;
/* devices */
cpu_device *m_maincpu;
cpu_device *m_audiocpu;
device_t *m_mcu;
device_t *m_cassette;
DECLARE_DRIVER_INIT(decocass);
DECLARE_DRIVER_INIT(decocrom);
DECLARE_DRIVER_INIT(cdsteljn);
@ -181,101 +158,97 @@ public:
DECLARE_MACHINE_RESET(cbdash);
DECLARE_MACHINE_RESET(cflyball);
UINT32 screen_update_decocass(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE8_MEMBER(decocass_coin_counter_w);
DECLARE_WRITE8_MEMBER(decocass_sound_command_w);
DECLARE_READ8_MEMBER(decocass_sound_data_r);
DECLARE_READ8_MEMBER(decocass_sound_ack_r);
DECLARE_WRITE8_MEMBER(decocass_sound_data_w);
DECLARE_READ8_MEMBER(decocass_sound_command_r);
DECLARE_WRITE8_MEMBER(decocass_sound_nmi_enable_w);
DECLARE_READ8_MEMBER(decocass_sound_nmi_enable_r);
DECLARE_READ8_MEMBER(decocass_sound_data_ack_reset_r);
DECLARE_WRITE8_MEMBER(decocass_sound_data_ack_reset_w);
DECLARE_WRITE8_MEMBER(decocass_nmi_reset_w);
DECLARE_WRITE8_MEMBER(decocass_quadrature_decoder_reset_w);
DECLARE_WRITE8_MEMBER(decocass_adc_w);
DECLARE_READ8_MEMBER(decocass_input_r);
DECLARE_WRITE8_MEMBER(decocass_reset_w);
DECLARE_READ8_MEMBER(decocass_e5xx_r);
DECLARE_WRITE8_MEMBER(decocass_e5xx_w);
DECLARE_WRITE8_MEMBER(decocass_de0091_w);
DECLARE_WRITE8_MEMBER(decocass_e900_w);
DECLARE_WRITE8_MEMBER(i8041_p1_w);
DECLARE_READ8_MEMBER(i8041_p1_r);
DECLARE_WRITE8_MEMBER(i8041_p2_w);
DECLARE_READ8_MEMBER(i8041_p2_r);
void decocass_machine_state_save_init();
DECLARE_WRITE8_MEMBER(decocass_paletteram_w);
DECLARE_WRITE8_MEMBER(decocass_charram_w);
DECLARE_WRITE8_MEMBER(decocass_fgvideoram_w);
DECLARE_WRITE8_MEMBER(decocass_colorram_w);
DECLARE_WRITE8_MEMBER(decocass_bgvideoram_w);
DECLARE_WRITE8_MEMBER(decocass_tileram_w);
DECLARE_WRITE8_MEMBER(decocass_objectram_w);
DECLARE_WRITE8_MEMBER(decocass_watchdog_count_w);
DECLARE_WRITE8_MEMBER(decocass_watchdog_flip_w);
DECLARE_WRITE8_MEMBER(decocass_color_missiles_w);
DECLARE_WRITE8_MEMBER(decocass_mode_set_w);
DECLARE_WRITE8_MEMBER(decocass_color_center_bot_w);
DECLARE_WRITE8_MEMBER(decocass_back_h_shift_w);
DECLARE_WRITE8_MEMBER(decocass_back_vl_shift_w);
DECLARE_WRITE8_MEMBER(decocass_back_vr_shift_w);
DECLARE_WRITE8_MEMBER(decocass_part_h_shift_w);
DECLARE_WRITE8_MEMBER(decocass_part_v_shift_w);
DECLARE_WRITE8_MEMBER(decocass_center_h_shift_space_w);
DECLARE_WRITE8_MEMBER(decocass_center_v_shift_w);
void decocass_video_state_save_init();
DECLARE_WRITE8_MEMBER(ram_w);
DECLARE_WRITE8_MEMBER(charram_w);
DECLARE_WRITE8_MEMBER(fgvideoram_w);
DECLARE_WRITE8_MEMBER(fgcolorram_w);
DECLARE_WRITE8_MEMBER(tileram_w);
DECLARE_WRITE8_MEMBER(objectram_w);
DECLARE_WRITE8_MEMBER(mirrorvideoram_w);
DECLARE_WRITE8_MEMBER(mirrorcolorram_w);
DECLARE_READ8_MEMBER(mirrorvideoram_r);
DECLARE_READ8_MEMBER(mirrorcolorram_r);
DECLARE_READ8_MEMBER(cdsteljn_input_r);
DECLARE_WRITE8_MEMBER(cdsteljn_mux_w);
private:
DECLARE_READ8_MEMBER(decocass_type1_latch_26_pass_3_inv_2_r);
DECLARE_READ8_MEMBER(decocass_type1_pass_136_r);
DECLARE_READ8_MEMBER(decocass_type1_latch_27_pass_3_inv_2_r);
DECLARE_READ8_MEMBER(decocass_type1_latch_26_pass_5_inv_2_r);
DECLARE_READ8_MEMBER(decocass_type1_latch_16_pass_3_inv_1_r);
DECLARE_READ8_MEMBER(decocass_type2_r);
DECLARE_WRITE8_MEMBER(decocass_type2_w);
DECLARE_READ8_MEMBER(decocass_type3_r);
DECLARE_WRITE8_MEMBER(decocass_type3_w);
DECLARE_READ8_MEMBER(decocass_type4_r);
DECLARE_WRITE8_MEMBER(decocass_type4_w);
DECLARE_READ8_MEMBER(decocass_type5_r);
DECLARE_WRITE8_MEMBER(decocass_type5_w);
DECLARE_READ8_MEMBER(decocass_nodong_r);
void draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect);
void mark_bg_tile_dirty(offs_t offset);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
int sprite_y_adjust, int sprite_y_adjust_flip_screen,
UINT8 *sprite_ram, int interleave);
void draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect,
int missile_y_adjust, int missile_y_adjust_flip_screen,
UINT8 *missile_ram, int interleave);
};
DECLARE_WRITE8_HANDLER( decocass_coin_counter_w );
DECLARE_WRITE8_HANDLER( decocass_sound_command_w );
DECLARE_READ8_HANDLER( decocass_sound_data_r );
DECLARE_READ8_HANDLER( decocass_sound_ack_r );
DECLARE_WRITE8_HANDLER( decocass_sound_data_w );
DECLARE_READ8_HANDLER( decocass_sound_command_r );
TIMER_DEVICE_CALLBACK( decocass_audio_nmi_gen );
DECLARE_WRITE8_HANDLER( decocass_sound_nmi_enable_w );
DECLARE_READ8_HANDLER( decocass_sound_nmi_enable_r );
DECLARE_READ8_HANDLER( decocass_sound_data_ack_reset_r );
DECLARE_WRITE8_HANDLER( decocass_sound_data_ack_reset_w );
DECLARE_WRITE8_HANDLER( decocass_nmi_reset_w );
DECLARE_WRITE8_HANDLER( decocass_quadrature_decoder_reset_w );
DECLARE_WRITE8_HANDLER( decocass_adc_w );
DECLARE_READ8_HANDLER( decocass_input_r );
DECLARE_WRITE8_HANDLER( decocass_reset_w );
DECLARE_READ8_HANDLER( decocass_e5xx_r );
DECLARE_WRITE8_HANDLER( decocass_e5xx_w );
DECLARE_WRITE8_HANDLER( decocass_de0091_w );
DECLARE_WRITE8_HANDLER( decocass_e900_w );
DECLARE_WRITE8_HANDLER( i8041_p1_w );
DECLARE_READ8_HANDLER( i8041_p1_r );
DECLARE_WRITE8_HANDLER( i8041_p2_w );
DECLARE_READ8_HANDLER( i8041_p2_r );
void decocass_machine_state_save_init(running_machine &machine);
/*----------- defined in video/decocass.c -----------*/
DECLARE_WRITE8_HANDLER( decocass_paletteram_w );
DECLARE_WRITE8_HANDLER( decocass_charram_w );
DECLARE_WRITE8_HANDLER( decocass_fgvideoram_w );
DECLARE_WRITE8_HANDLER( decocass_colorram_w );
DECLARE_WRITE8_HANDLER( decocass_bgvideoram_w );
DECLARE_WRITE8_HANDLER( decocass_tileram_w );
DECLARE_WRITE8_HANDLER( decocass_objectram_w );
DECLARE_WRITE8_HANDLER( decocass_watchdog_count_w );
DECLARE_WRITE8_HANDLER( decocass_watchdog_flip_w );
DECLARE_WRITE8_HANDLER( decocass_color_missiles_w );
DECLARE_WRITE8_HANDLER( decocass_mode_set_w );
DECLARE_WRITE8_HANDLER( decocass_color_center_bot_w );
DECLARE_WRITE8_HANDLER( decocass_back_h_shift_w );
DECLARE_WRITE8_HANDLER( decocass_back_vl_shift_w );
DECLARE_WRITE8_HANDLER( decocass_back_vr_shift_w );
DECLARE_WRITE8_HANDLER( decocass_part_h_shift_w );
DECLARE_WRITE8_HANDLER( decocass_part_v_shift_w );
DECLARE_WRITE8_HANDLER( decocass_center_h_shift_space_w );
DECLARE_WRITE8_HANDLER( decocass_center_v_shift_w );
void decocass_video_state_save_init(running_machine &machine);
TIMER_DEVICE_CALLBACK(decocass_audio_nmi_gen);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,467 @@
/***********************************************************************
DECO Cassette System machine
***********************************************************************/
#include "emu.h"
#include "cpu/m6502/m6502.h"
#include "cpu/mcs48/mcs48.h"
#include "machine/decocass_tape.h"
#define LOG_CASSETTE_STATE 0
/***************************************************************************
CASSETTE DEVICE INTERFACE
***************************************************************************/
/* regions within the virtual tape */
enum tape_region
{
REGION_LEADER, /* in clear leader section */
REGION_LEADER_GAP, /* in gap between leader and BOT */
REGION_BOT, /* in BOT hole */
REGION_BOT_GAP, /* in gap between BOT hole and data */
REGION_DATA_BLOCK_0, /* in data block 0 */
REGION_DATA_BLOCK_255 = REGION_DATA_BLOCK_0 + 255,
REGION_EOT_GAP, /* in gap between data and EOT hole */
REGION_EOT, /* in EOT hole */
REGION_TRAILER_GAP, /* in gap between trailer and EOT */
REGION_TRAILER /* in clear trailer section */
};
/* bytes within a data block on a virtual tape */
enum tape_byte
{
BYTE_PRE_GAP_0, /* 34 bytes of gap, clock held to 0, no data */
BYTE_PRE_GAP_33 = BYTE_PRE_GAP_0 + 33,
BYTE_LEADIN, /* 1 leadin byte, clocked value 0x00 */
BYTE_HEADER, /* 1 header byte, clocked value 0xAA */
BYTE_DATA_0, /* 256 bytes of data, clocked */
BYTE_DATA_255 = BYTE_DATA_0 + 255,
BYTE_CRC16_MSB, /* 2 bytes of CRC, clocked MSB first, then LSB */
BYTE_CRC16_LSB,
BYTE_TRAILER, /* 1 trailer byte, clocked value 0xAA */
BYTE_LEADOUT, /* 1 leadout byte, clocked value 0x00 */
BYTE_LONGCLOCK, /* 1 longclock byte, clock held to 1, no data */
BYTE_POSTGAP_0, /* 34 bytes of gap, no clock, no data */
BYTE_POSTGAP_33 = BYTE_POSTGAP_0 + 33,
BYTE_BLOCK_TOTAL /* total number of bytes in block */
};
/* state of the tape */
struct tape_state
{
running_machine * machine; /* pointer back to the machine */
emu_timer * timer; /* timer for running the tape */
INT8 speed; /* speed: <-1=fast rewind, -1=reverse, 0=stopped, 1=normal, >1=fast forward */
tape_region region; /* current region */
tape_byte bytenum; /* byte number within a datablock */
UINT8 bitnum; /* bit number within a byte */
UINT32 clockpos; /* the current clock position of the tape */
UINT32 numclocks; /* total number of clocks on the entire tape */
UINT16 crc16[256]; /* CRC16 for each block */
};
/* number of tape clock pulses per second */
#define TAPE_CLOCKRATE 4800
#define TAPE_CLOCKS_PER_BIT 2
#define TAPE_CLOCKS_PER_BYTE (8 * TAPE_CLOCKS_PER_BIT)
#define TAPE_MSEC_TO_CLOCKS(x) ((x) * TAPE_CLOCKRATE / 1000)
/* Note on a tapes leader-BOT-data-EOT-trailer format:
* A cassette has a transparent piece of tape on both ends,
* leader and trailer. And data tapes also have BOT and EOT
* holes, shortly before the the leader and trailer.
* The holes and clear tape are detected using a photo-resitor.
* When rewinding, the BOT/EOT signal will show a short
* pulse and if rewind continues a constant high signal later.
* The specs say the holes are "> 2ms" in length.
*/
/* duration of the clear LEADER (and trailer) of the tape */
#define REGION_LEADER_START_CLOCK 0
#define REGION_LEADER_LEN_CLOCKS TAPE_MSEC_TO_CLOCKS(1000) /* 1s */
#define REGION_LEADER_END_CLOCK (REGION_LEADER_START_CLOCK+REGION_LEADER_LEN_CLOCKS)
/* duration of the GAP between leader and BOT/EOT */
#define REGION_LEADER_GAP_START_CLOCK REGION_LEADER_END_CLOCK
#define REGION_LEADER_GAP_LEN_CLOCKS TAPE_MSEC_TO_CLOCKS(1500) /* 1.5s */
#define REGION_LEADER_GAP_END_CLOCK (REGION_LEADER_GAP_START_CLOCK+REGION_LEADER_GAP_LEN_CLOCKS)
/* duration of BOT/EOT holes */
#define REGION_BOT_START_CLOCK REGION_LEADER_GAP_END_CLOCK
#define REGION_BOT_LEN_CLOCKS TAPE_MSEC_TO_CLOCKS(2.5) /* 0.0025s */
#define REGION_BOT_END_CLOCK (REGION_BOT_START_CLOCK+REGION_BOT_LEN_CLOCKS)
/* gap between BOT/EOT and first/last data block */
#define REGION_BOT_GAP_START_CLOCK REGION_BOT_END_CLOCK
#define REGION_BOT_GAP_LEN_CLOCKS TAPE_MSEC_TO_CLOCKS(300) /* 300ms */
#define REGION_BOT_GAP_END_CLOCK (REGION_BOT_GAP_START_CLOCK+REGION_BOT_GAP_LEN_CLOCKS)
/*-------------------------------------------------
get_safe_token - makes sure that the passed
in device is, in fact, an IDE controller
-------------------------------------------------*/
INLINE tape_state *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == DECOCASS_TAPE);
return (tape_state *)downcast<decocass_tape_device *>(device)->token();
}
/*-------------------------------------------------
tape_crc16_byte - accumulate 8 bits worth of
CRC data
-------------------------------------------------*/
static UINT16 tape_crc16_byte(UINT16 crc, UINT8 data)
{
int bit;
for (bit = 0; bit < 8; bit++)
{
crc = (crc >> 1) | (crc << 15);
crc ^= (data << 7) & 0x80;
if (crc & 0x80)
crc ^= 0x0120;
data >>= 1;
}
return crc;
}
/*-------------------------------------------------
tape_describe_state - create a string that
describes the state of the tape
-------------------------------------------------*/
static const char *tape_describe_state(tape_state *tape)
{
static char buffer[40];
char temprname[40];
const char *rname = temprname;
if (tape->region == REGION_LEADER)
rname = "LEAD";
else if (tape->region == REGION_LEADER_GAP)
rname = "LGAP";
else if (tape->region == REGION_BOT)
rname = "BOT ";
else if (tape->region == REGION_BOT_GAP)
rname = "BGAP";
else if (tape->region == REGION_TRAILER)
rname = "TRLR";
else if (tape->region == REGION_TRAILER_GAP)
rname = "TGAP";
else if (tape->region == REGION_EOT)
rname = "EOT ";
else if (tape->region == REGION_EOT_GAP)
rname = "EGAP";
else
{
char tempbname[40];
const char *bname = tempbname;
int clk;
if (tape->bytenum <= BYTE_PRE_GAP_33)
sprintf(tempbname, "PR%02d", tape->bytenum - BYTE_PRE_GAP_0);
else if (tape->bytenum == BYTE_LEADIN)
bname = "LDIN";
else if (tape->bytenum == BYTE_HEADER)
bname = "HEAD";
else if (tape->bytenum <= BYTE_DATA_255)
sprintf(tempbname, "BY%02X", tape->bytenum - BYTE_DATA_0);
else if (tape->bytenum == BYTE_CRC16_MSB)
bname = "CRCM";
else if (tape->bytenum == BYTE_CRC16_LSB)
bname = "CRCL";
else if (tape->bytenum == BYTE_TRAILER)
bname = "TRLR";
else if (tape->bytenum == BYTE_LEADOUT)
bname = "LOUT";
else if (tape->bytenum == BYTE_LONGCLOCK)
bname = "LONG";
else
sprintf(tempbname, "PO%02d", tape->bytenum - BYTE_POSTGAP_0);
/* in the main data area, the clock alternates at the clock rate */
if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
clk = ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0 : 1;
else if (tape->bytenum == BYTE_LONGCLOCK)
clk = 1;
else
clk = 0;
sprintf(temprname, "BL%02X.%4s.%d.%d", tape->region - REGION_DATA_BLOCK_0, bname, tape->bitnum, clk);
}
sprintf(buffer, "{%9d=%s}", tape->clockpos, rname);
return buffer;
}
/*-------------------------------------------------
tape_clock_callback - called once per clock
to increment/decrement the tape location
-------------------------------------------------*/
static TIMER_CALLBACK( tape_clock_callback )
{
device_t *device = (device_t *)ptr;
tape_state *tape = get_safe_token(device);
/* advance by one clock in the desired direction */
if (tape->speed < 0 && tape->clockpos > 0)
tape->clockpos--;
else if (tape->speed > 0 && tape->clockpos < tape->numclocks)
tape->clockpos++;
/* look for states before the start of data */
if (tape->clockpos < REGION_LEADER_END_CLOCK)
tape->region = REGION_LEADER;
else if (tape->clockpos < REGION_LEADER_GAP_END_CLOCK)
tape->region = REGION_LEADER_GAP;
else if (tape->clockpos < REGION_BOT_END_CLOCK)
tape->region = REGION_BOT;
else if (tape->clockpos < REGION_BOT_GAP_END_CLOCK)
tape->region = REGION_BOT_GAP;
/* look for states after the end of data */
else if (tape->clockpos >= tape->numclocks - REGION_LEADER_END_CLOCK)
tape->region = REGION_TRAILER;
else if (tape->clockpos >= tape->numclocks - REGION_LEADER_GAP_END_CLOCK)
tape->region = REGION_TRAILER_GAP;
else if (tape->clockpos >= tape->numclocks - REGION_BOT_END_CLOCK)
tape->region = REGION_EOT;
else if (tape->clockpos >= tape->numclocks - REGION_BOT_GAP_END_CLOCK)
tape->region = REGION_EOT_GAP;
/* everything else is data */
else
{
UINT32 dataclock = tape->clockpos - REGION_BOT_GAP_END_CLOCK;
/* compute the block number */
tape->region = (tape_region)(REGION_DATA_BLOCK_0 + dataclock / (TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL));
dataclock -= (tape->region - REGION_DATA_BLOCK_0) * TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL;
/* compute the byte within the block */
tape->bytenum = (tape_byte)(dataclock / TAPE_CLOCKS_PER_BYTE);
dataclock -= tape->bytenum * TAPE_CLOCKS_PER_BYTE;
/* compute the bit within the byte */
tape->bitnum = dataclock / TAPE_CLOCKS_PER_BIT;
}
/* log */
if (LOG_CASSETTE_STATE)
tape_describe_state(tape);
}
/*-------------------------------------------------
tape_get_status_bits - return the 3 status
bits from the tape
-------------------------------------------------*/
UINT8 tape_get_status_bits(device_t *device)
{
tape_state *tape = get_safe_token(device);
UINT8 tape_bits = 0;
/* bit 0x20 is the BOT/EOT signal, which is also set in the leader/trailer area */
if (tape->region == REGION_LEADER || tape->region == REGION_BOT || tape->region == REGION_EOT || tape->region == REGION_TRAILER)
tape_bits |= 0x20;
/* bit 0x40 is the clock, which is only valid in some areas of the data block */
/* bit 0x80 is the data, which is only valid in some areas of the data block */
if (tape->region >= REGION_DATA_BLOCK_0 && tape->region <= REGION_DATA_BLOCK_255)
{
int blocknum = tape->region - REGION_DATA_BLOCK_0;
UINT8 byteval = 0x00;
/* in the main data area, the clock alternates at the clock rate */
if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
tape_bits |= ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0x00 : 0x40;
/* in the longclock area, the clock holds high */
else if (tape->bytenum == BYTE_LONGCLOCK)
tape_bits |= 0x40;
/* everywhere else, the clock holds to 0 */
else
;
/* lead-in and lead-out bytes are 0xAA */
if (tape->bytenum == BYTE_HEADER || tape->bytenum == BYTE_TRAILER)
byteval = 0xaa;
/* data block bytes are data */
else if (tape->bytenum >= BYTE_DATA_0 && tape->bytenum <= BYTE_DATA_255)
byteval = static_cast<UINT8 *>(*device->region())[blocknum * 256 + (tape->bytenum - BYTE_DATA_0)];
/* CRC MSB */
else if (tape->bytenum == BYTE_CRC16_MSB)
byteval = tape->crc16[blocknum] >> 8;
/* CRC LSB */
else if (tape->bytenum == BYTE_CRC16_LSB)
byteval = tape->crc16[blocknum];
/* select the appropriate bit from the byte and move to the upper bit */
if ((byteval >> tape->bitnum) & 1)
tape_bits |= 0x80;
}
return tape_bits;
}
/*-------------------------------------------------
tape_is_present - return TRUE if the tape is
present
-------------------------------------------------*/
UINT8 tape_is_present(device_t *device)
{
return device->region() != NULL;
}
/*-------------------------------------------------
tape_change_speed - alter the speed of tape
playback
-------------------------------------------------*/
void tape_change_speed(device_t *device, INT8 newspeed)
{
tape_state *tape = get_safe_token(device);
attotime newperiod;
INT8 absnewspeed;
/* do nothing if speed has not changed */
if (tape->speed == newspeed)
return;
/* compute how fast to run the tape timer */
absnewspeed = (newspeed < 0) ? -newspeed : newspeed;
if (newspeed == 0)
newperiod = attotime::never;
else
newperiod = attotime::from_hz(TAPE_CLOCKRATE * absnewspeed);
/* set the new speed */
tape->timer->adjust(newperiod, 0, newperiod);
tape->speed = newspeed;
}
/*-------------------------------------------------
device start callback
-------------------------------------------------*/
static DEVICE_START( decocass_tape )
{
tape_state *tape = get_safe_token(device);
int curblock, offs, numblocks;
/* validate some basic stuff */
assert(device != NULL);
assert(device->static_config() == NULL);
/* fetch the data pointer */
tape->timer = device->machine().scheduler().timer_alloc(FUNC(tape_clock_callback), (void *)device);
if (device->region() == NULL)
return;
UINT8 *regionbase = *device->region();
/* scan for the first non-empty block in the image */
for (offs = device->region()->bytes() - 1; offs >= 0; offs--)
if (regionbase[offs] != 0)
break;
numblocks = ((offs | 0xff) + 1) / 256;
assert(numblocks < ARRAY_LENGTH(tape->crc16));
/* compute the total length */
tape->numclocks = REGION_BOT_GAP_END_CLOCK + numblocks * BYTE_BLOCK_TOTAL * 16 + REGION_BOT_GAP_END_CLOCK;
/* compute CRCs for each block */
for (curblock = 0; curblock < numblocks; curblock++)
{
UINT16 crc = 0;
int testval;
/* first CRC the 256 bytes of data */
for (offs = 256 * curblock; offs < 256 * curblock + 256; offs++)
crc = tape_crc16_byte(crc, regionbase[offs]);
/* then find a pair of bytes that will bring the CRC to 0 (any better way than brute force?) */
for (testval = 0; testval < 0x10000; testval++)
if (tape_crc16_byte(tape_crc16_byte(crc, testval >> 8), testval) == 0)
break;
tape->crc16[curblock] = testval;
}
/* register states */
device->save_item(NAME(tape->speed));
device->save_item(NAME(tape->bitnum));
device->save_item(NAME(tape->clockpos));
}
/*-------------------------------------------------
device reset callback
-------------------------------------------------*/
static DEVICE_RESET( decocass_tape )
{
/* turn the tape off */
tape_change_speed(device, 0);
}
const device_type DECOCASS_TAPE = &device_creator<decocass_tape_device>;
decocass_tape_device::decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, DECOCASS_TAPE, "DECO Cassette Tape", tag, owner, clock)
{
m_token = global_alloc_clear(tape_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void decocass_tape_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void decocass_tape_device::device_start()
{
DEVICE_START_NAME( decocass_tape )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void decocass_tape_device::device_reset()
{
DEVICE_RESET_NAME( decocass_tape )(this);
}

View File

@ -0,0 +1,32 @@
#ifndef __DECOCASS_TAPE_H__
#define __DECOCASS_TAPE_H__
class decocass_tape_device : public device_t
{
public:
decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~decocass_tape_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
// internal state
void *m_token;
};
extern const device_type DECOCASS_TAPE;
UINT8 tape_get_status_bits(device_t *device);
UINT8 tape_is_present(device_t *device);
void tape_change_speed(device_t *device, INT8 newspeed);
#define MCFG_DECOCASS_TAPE_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, DECOCASS_TAPE, 0)
#endif

View File

@ -626,7 +626,7 @@ $(MAMEOBJ)/dataeast.a: \
$(DRIVERS)/deco156.o $(MACHINE)/deco156.o \
$(DRIVERS)/deco32.o $(VIDEO)/deco32.o $(VIDEO)/dvi.o \
$(AUDIO)/decobsmt.o \
$(DRIVERS)/decocass.o $(MACHINE)/decocass.o $(VIDEO)/decocass.o \
$(DRIVERS)/decocass.o $(MACHINE)/decocass.o $(MACHINE)/decocass_tape.o $(VIDEO)/decocass.o \
$(DRIVERS)/deshoros.o \
$(DRIVERS)/dietgo.o $(VIDEO)/dietgo.o \
$(DRIVERS)/exprraid.o $(VIDEO)/exprraid.o \

View File

@ -5,7 +5,7 @@
***********************************************************************/
#include "emu.h"
#include "machine/decocass.h"
#include "includes/decocass.h"
static const UINT32 tile_offset[32*32] = {
@ -46,22 +46,20 @@ static const UINT32 tile_offset[32*32] = {
/********************************************
state saving setup
********************************************/
void decocass_video_state_save_init( running_machine &machine )
void decocass_state::decocass_video_state_save_init()
{
decocass_state *state = machine.driver_data<decocass_state>();
state->save_item(NAME(state->m_watchdog_count));
state->save_item(NAME(state->m_watchdog_flip));
state->save_item(NAME(state->m_color_missiles));
state->save_item(NAME(state->m_color_center_bot));
state->save_item(NAME(state->m_mode_set));
state->save_item(NAME(state->m_back_h_shift));
state->save_item(NAME(state->m_back_vl_shift));
state->save_item(NAME(state->m_back_vr_shift));
state->save_item(NAME(state->m_part_h_shift));
state->save_item(NAME(state->m_part_v_shift));
state->save_item(NAME(state->m_center_h_shift_space));
state->save_item(NAME(state->m_center_v_shift));
save_item(NAME(m_watchdog_count));
save_item(NAME(m_watchdog_flip));
save_item(NAME(m_color_missiles));
save_item(NAME(m_color_center_bot));
save_item(NAME(m_mode_set));
save_item(NAME(m_back_h_shift));
save_item(NAME(m_back_vl_shift));
save_item(NAME(m_back_vr_shift));
save_item(NAME(m_part_h_shift));
save_item(NAME(m_part_v_shift));
save_item(NAME(m_center_h_shift_space));
save_item(NAME(m_center_v_shift));
}
/********************************************
@ -115,53 +113,51 @@ TILE_GET_INFO_MEMBER(decocass_state::get_fg_tile_info )
big object
********************************************/
static void draw_object( running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
void decocass_state::draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
decocass_state *state = machine.driver_data<decocass_state>();
int sx, sy, color;
if (0 == (state->m_mode_set & 0x80)) /* part_h_enable off? */
if (0 == (m_mode_set & 0x80)) /* part_h_enable off? */
return;
color = (state->m_color_center_bot >> 4) & 15;
color = (m_color_center_bot >> 4) & 15;
sy = 192 - (state->m_part_v_shift & 0x7f);
sy = 192 - (m_part_v_shift & 0x7f);
if (state->m_part_h_shift & 0x80)
sx = (state->m_part_h_shift & 0x7f) + 1;
if (m_part_h_shift & 0x80)
sx = (m_part_h_shift & 0x7f) + 1;
else
sx = 91 - (state->m_part_h_shift & 0x7f);
sx = 91 - (m_part_h_shift & 0x7f);
drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 0, color, 0, 0, sx + 64, sy, 0);
drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 1, color, 0, 0, sx, sy, 0);
drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 0, color, 0, 1, sx + 64, sy - 64, 0);
drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 1, color, 0, 1, sx, sy - 64, 0);
drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 0, color, 0, 0, sx + 64, sy, 0);
drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 1, color, 0, 0, sx, sy, 0);
drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 0, color, 0, 1, sx + 64, sy - 64, 0);
drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 1, color, 0, 1, sx, sy - 64, 0);
}
static void draw_center( running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
void decocass_state::draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
decocass_state *state = machine.driver_data<decocass_state>();
int sx, sy, x, y, color;
color = 0;
if (state->m_color_center_bot & 0x10)
if (m_color_center_bot & 0x10)
color |= 4;
if (state->m_color_center_bot & 0x20)
if (m_color_center_bot & 0x20)
color |= 2;
if (state->m_color_center_bot & 0x40)
if (m_color_center_bot & 0x40)
color |= 1;
if (state->m_color_center_bot & 0x80)
if (m_color_center_bot & 0x80)
color = (color & 4) + ((color << 1) & 2) + ((color >> 1) & 1);
sy = state->m_center_v_shift;
sx = (state->m_center_h_shift_space >> 2) & 0x3c;
sy = m_center_v_shift;
sx = (m_center_h_shift_space >> 2) & 0x3c;
for (y = 0; y < 4; y++)
if ((sy + y) >= cliprect.min_y && (sy + y) <= cliprect.max_y)
{
if (((sy + y) & state->m_color_center_bot & 3) == (sy & state->m_color_center_bot & 3))
if (((sy + y) & m_color_center_bot & 3) == (sy & m_color_center_bot & 3))
for (x = 0; x < 256; x++)
if (0 != (x & 16) || 0 != (state->m_center_h_shift_space & 1))
if (0 != (x & 16) || 0 != (m_center_h_shift_space & 1))
bitmap.pix16(sy + y, (sx + x) & 255) = color;
}
}
@ -170,102 +166,92 @@ static void draw_center( running_machine& machine, bitmap_ind16 &bitmap, const r
memory handlers
********************************************/
WRITE8_HANDLER( decocass_paletteram_w )
WRITE8_MEMBER(decocass_state::decocass_paletteram_w )
{
/*
* RGB output is inverted and A4 is inverted too
* (ME/ input on 1st paletteram, inverter -> ME/ on 2nd)
*/
offset = (offset & 31) ^ 16;
colortable_palette_set_color(space.machine().colortable, offset, MAKE_RGB(pal3bit(~data >> 0), pal3bit(~data >> 3), pal2bit(~data >> 6)));
colortable_palette_set_color(machine().colortable, offset, MAKE_RGB(pal3bit(~data >> 0), pal3bit(~data >> 3), pal2bit(~data >> 6)));
}
WRITE8_HANDLER( decocass_charram_w )
WRITE8_MEMBER(decocass_state::decocass_charram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_charram[offset] = data;
m_charram[offset] = data;
/* dirty sprite */
space.machine().gfx[1]->mark_dirty((offset >> 5) & 255);
machine().gfx[1]->mark_dirty((offset >> 5) & 255);
/* dirty char */
space.machine().gfx[0]->mark_dirty((offset >> 3) & 1023);
machine().gfx[0]->mark_dirty((offset >> 3) & 1023);
}
WRITE8_HANDLER( decocass_fgvideoram_w )
WRITE8_MEMBER(decocass_state::decocass_fgvideoram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_fgvideoram[offset] = data;
state->m_fg_tilemap->mark_tile_dirty(offset);
m_fgvideoram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
WRITE8_HANDLER( decocass_colorram_w )
WRITE8_MEMBER(decocass_state::decocass_colorram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_colorram[offset] = data;
state->m_fg_tilemap->mark_tile_dirty(offset);
m_colorram[offset] = data;
m_fg_tilemap->mark_tile_dirty(offset);
}
static void mark_bg_tile_dirty( running_machine &machine, offs_t offset )
void decocass_state::mark_bg_tile_dirty(offs_t offset )
{
decocass_state *state = machine.driver_data<decocass_state>();
if (offset & 0x80)
state->m_bg_tilemap_r->mark_tile_dirty(offset);
m_bg_tilemap_r->mark_tile_dirty(offset);
else
state->m_bg_tilemap_l->mark_tile_dirty(offset);
m_bg_tilemap_l->mark_tile_dirty(offset);
}
WRITE8_HANDLER( decocass_tileram_w )
WRITE8_MEMBER(decocass_state::decocass_tileram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_tileram[offset] = data;
m_tileram[offset] = data;
/* dirty tile (64 bytes per tile) */
space.machine().gfx[2]->mark_dirty((offset / 64) & 15);
machine().gfx[2]->mark_dirty((offset / 64) & 15);
/* first 1KB of tile RAM is shared with tilemap RAM */
if (offset < state->m_bgvideoram_size)
mark_bg_tile_dirty(space.machine(), offset);
if (offset < m_bgvideoram_size)
mark_bg_tile_dirty(offset);
}
WRITE8_HANDLER( decocass_objectram_w )
WRITE8_MEMBER(decocass_state::decocass_objectram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_objectram[offset] = data;
m_objectram[offset] = data;
/* dirty the object */
space.machine().gfx[3]->mark_dirty(0);
space.machine().gfx[3]->mark_dirty(1);
machine().gfx[3]->mark_dirty(0);
machine().gfx[3]->mark_dirty(1);
}
WRITE8_HANDLER( decocass_bgvideoram_w )
WRITE8_MEMBER(decocass_state::decocass_bgvideoram_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
state->m_bgvideoram[offset] = data;
mark_bg_tile_dirty(space.machine(), offset);
m_bgvideoram[offset] = data;
mark_bg_tile_dirty(offset);
}
/* The watchdog is a 4bit counter counting down every frame */
WRITE8_HANDLER( decocass_watchdog_count_w )
WRITE8_MEMBER(decocass_state::decocass_watchdog_count_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
LOG(1,("decocass_watchdog_count_w: $%02x\n", data));
state->m_watchdog_count = data & 0x0f;
m_watchdog_count = data & 0x0f;
}
WRITE8_HANDLER( decocass_watchdog_flip_w )
WRITE8_MEMBER(decocass_state::decocass_watchdog_flip_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
LOG(1,("decocass_watchdog_flip_w: $%02x\n", data));
state->m_watchdog_flip = data;
m_watchdog_flip = data;
}
WRITE8_HANDLER( decocass_color_missiles_w )
WRITE8_MEMBER(decocass_state::decocass_color_missiles_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
LOG(1,("decocass_color_missiles_w: $%02x\n", data));
/* only bits D0-D2 and D4-D6 are connected to
* the color RAM demux:
* D0-D2 to the IC0 inputs
* D4-D6 to the IC1 inputs
*/
state->m_color_missiles = data & 0x77;
m_color_missiles = data & 0x77;
}
/*
@ -278,10 +264,9 @@ WRITE8_HANDLER( decocass_color_missiles_w )
* D6 - tunnel
* D7 - part h enable
*/
WRITE8_HANDLER( decocass_mode_set_w )
WRITE8_MEMBER(decocass_state::decocass_mode_set_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_mode_set)
if (data == m_mode_set)
return;
LOG(1,("decocass_mode_set_w: $%02x (%s%s%s%s%s%s%s%s)\n", data,
(data & 0x01) ? "D0?" : "",
@ -293,13 +278,12 @@ WRITE8_HANDLER( decocass_mode_set_w )
(data & 0x40) ? " tunnel" : "",
(data & 0x80) ? " part_h_enable" : ""));
state->m_mode_set = data;
m_mode_set = data;
}
WRITE8_HANDLER( decocass_color_center_bot_w )
WRITE8_MEMBER(decocass_state::decocass_color_center_bot_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_color_center_bot)
if (data == m_color_center_bot)
return;
LOG(1,("decocass_color_center_bot_w: $%02x (color:%d, center_bot:%d)\n", data, data & 3, data >> 4));
/*
@ -313,86 +297,78 @@ WRITE8_HANDLER( decocass_color_center_bot_w )
* D0 CLD3
*/
if ((state->m_color_center_bot ^ data) & 0x80)
if ((m_color_center_bot ^ data) & 0x80)
{
state->m_bg_tilemap_r->mark_all_dirty();
state->m_bg_tilemap_l->mark_all_dirty();
m_bg_tilemap_r->mark_all_dirty();
m_bg_tilemap_l->mark_all_dirty();
}
if ((state->m_color_center_bot ^ data) & 0x01)
state->m_fg_tilemap->mark_all_dirty();
state->m_color_center_bot = data;
if ((m_color_center_bot ^ data) & 0x01)
m_fg_tilemap->mark_all_dirty();
m_color_center_bot = data;
}
WRITE8_HANDLER( decocass_back_h_shift_w )
WRITE8_MEMBER(decocass_state::decocass_back_h_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_back_h_shift)
if (data == m_back_h_shift)
return;
LOG(1,("decocass_back_h_shift_w: $%02x\n", data));
state->m_back_h_shift = data;
m_back_h_shift = data;
}
WRITE8_HANDLER( decocass_back_vl_shift_w )
WRITE8_MEMBER(decocass_state::decocass_back_vl_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_back_vl_shift)
if (data == m_back_vl_shift)
return;
LOG(1,("decocass_back_vl_shift_w: $%02x\n", data));
state->m_back_vl_shift = data;
m_back_vl_shift = data;
}
WRITE8_HANDLER( decocass_back_vr_shift_w )
WRITE8_MEMBER(decocass_state::decocass_back_vr_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_back_vr_shift)
if (data == m_back_vr_shift)
return;
LOG(1,("decocass_back_vr_shift_w: $%02x\n", data));
state->m_back_vr_shift = data;
m_back_vr_shift = data;
}
WRITE8_HANDLER( decocass_part_h_shift_w )
WRITE8_MEMBER(decocass_state::decocass_part_h_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_part_v_shift )
if (data == m_part_v_shift )
return;
LOG(1,("decocass_part_h_shift_w: $%02x\n", data));
state->m_part_h_shift = data;
m_part_h_shift = data;
}
WRITE8_HANDLER( decocass_part_v_shift_w )
WRITE8_MEMBER(decocass_state::decocass_part_v_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_part_v_shift )
if (data == m_part_v_shift )
return;
LOG(1,("decocass_part_v_shift_w: $%02x\n", data));
state->m_part_v_shift = data;
m_part_v_shift = data;
}
WRITE8_HANDLER( decocass_center_h_shift_space_w )
WRITE8_MEMBER(decocass_state::decocass_center_h_shift_space_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
if (data == state->m_center_h_shift_space)
if (data == m_center_h_shift_space)
return;
LOG(1,("decocass_center_h_shift_space_w: $%02x\n", data));
state->m_center_h_shift_space = data;
m_center_h_shift_space = data;
}
WRITE8_HANDLER( decocass_center_v_shift_w )
WRITE8_MEMBER(decocass_state::decocass_center_v_shift_w )
{
decocass_state *state = space.machine().driver_data<decocass_state>();
LOG(1,("decocass_center_v_shift_w: $%02x\n", data));
state->m_center_v_shift = data;
m_center_v_shift = data;
}
/********************************************
memory handlers
********************************************/
static void draw_sprites(running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
void decocass_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
int sprite_y_adjust, int sprite_y_adjust_flip_screen,
UINT8 *sprite_ram, int interleave)
{
decocass_state *state = machine.driver_data<decocass_state>();
int i,offs;
/* Draw the sprites */
@ -409,7 +385,7 @@ static void draw_sprites(running_machine& machine, bitmap_ind16 &bitmap, const r
flipx = sprite_ram[offs + 0] & 0x04;
flipy = sprite_ram[offs + 0] & 0x02;
if (state->flip_screen())
if (flip_screen())
{
sx = 240 - sx;
sy = 240 - sy + sprite_y_adjust_flip_screen;
@ -420,16 +396,16 @@ static void draw_sprites(running_machine& machine, bitmap_ind16 &bitmap, const r
sy -= sprite_y_adjust;
drawgfx_transpen(bitmap,cliprect, machine.gfx[1],
drawgfx_transpen(bitmap,cliprect, machine().gfx[1],
sprite_ram[offs + interleave],
color,
flipx,flipy,
sx,sy, 0);
sy += (state->flip_screen() ? -256 : 256);
sy += (flip_screen() ? -256 : 256);
// Wrap around
drawgfx_transpen(bitmap,cliprect, machine.gfx[1],
drawgfx_transpen(bitmap,cliprect, machine().gfx[1],
sprite_ram[offs + interleave],
color,
flipx,flipy,
@ -438,11 +414,10 @@ static void draw_sprites(running_machine& machine, bitmap_ind16 &bitmap, const r
}
static void draw_missiles(running_machine &machine,bitmap_ind16 &bitmap, const rectangle &cliprect,
void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect,
int missile_y_adjust, int missile_y_adjust_flip_screen,
UINT8 *missile_ram, int interleave)
{
decocass_state *state = machine.driver_data<decocass_state>();
int i, offs, x;
/* Draw the missiles (16 of them) seemingly with alternating colors
@ -453,7 +428,7 @@ static void draw_missiles(running_machine &machine,bitmap_ind16 &bitmap, const r
sy = 255 - missile_ram[offs + 0 * interleave];
sx = 255 - missile_ram[offs + 2 * interleave];
if (state->flip_screen())
if (flip_screen())
{
sx = 240 - sx;
sy = 240 - sy + missile_y_adjust_flip_screen;
@ -463,13 +438,13 @@ static void draw_missiles(running_machine &machine,bitmap_ind16 &bitmap, const r
for (x = 0; x < 4; x++)
{
if (sx >= cliprect.min_x && sx <= cliprect.max_x)
bitmap.pix16(sy, sx) = (state->m_color_missiles >> 4) & 7;
bitmap.pix16(sy, sx) = (m_color_missiles >> 4) & 7;
sx++;
}
sy = 255 - missile_ram[offs + 1 * interleave];
sx = 255 - missile_ram[offs + 3 * interleave];
if (state->flip_screen())
if (flip_screen())
{
sx = 240 - sx;
sy = 240 - sy + missile_y_adjust_flip_screen;
@ -479,7 +454,7 @@ static void draw_missiles(running_machine &machine,bitmap_ind16 &bitmap, const r
for (x = 0; x < 4; x++)
{
if (sx >= cliprect.min_x && sx <= cliprect.max_x)
bitmap.pix16(sy, sx) = state->m_color_missiles & 7;
bitmap.pix16(sy, sx) = m_color_missiles & 7;
sx++;
}
}
@ -587,13 +562,13 @@ UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind1
if (m_mode_set & 0x20)
{
draw_object(machine(), bitmap, cliprect);
draw_center(machine(), bitmap, cliprect);
draw_object(bitmap, cliprect);
draw_center(bitmap, cliprect);
}
else
{
draw_object(machine(), bitmap, cliprect);
draw_center(machine(), bitmap, cliprect);
draw_object(bitmap, cliprect);
draw_center(bitmap, cliprect);
if (m_mode_set & 0x08) /* bkg_ena on ? */
{
clip = m_bg_tilemap_l_clip;
@ -606,7 +581,7 @@ UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind1
}
}
m_fg_tilemap->draw(bitmap, cliprect, 0, 0);
draw_sprites(machine(), bitmap, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20);
draw_missiles(machine(), bitmap, cliprect, 1, 0, m_colorram, 0x20);
draw_sprites(bitmap, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20);
draw_missiles(bitmap, cliprect, 1, 0, m_colorram, 0x20);
return 0;
}