mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
advision: get rid of led fade, fix INS(MAME fastforward) not working, add driver notes
This commit is contained in:
parent
14cf63fd84
commit
3f3e1e2135
@ -3,7 +3,7 @@
|
||||
<!--
|
||||
license:CC0
|
||||
-->
|
||||
<softwarelist name="advision" description="Entex AdventureVision cartridges">
|
||||
<softwarelist name="advision" description="Entex Adventure Vision cartridges">
|
||||
<software name="defender">
|
||||
<description>Defender</description>
|
||||
<year>1982</year>
|
||||
@ -11,8 +11,8 @@ license:CC0
|
||||
<info name="serial" value="6075" />
|
||||
|
||||
<part name="cart" interface="advision_cart">
|
||||
<dataarea name="rom" size="4096">
|
||||
<rom name="defender.bin" size="4096" crc="3e280096" sha1="33e6bc08b3e8a951942e078102e90fbc8ba729a8"/>
|
||||
<dataarea name="rom" size="0x1000">
|
||||
<rom name="defender.bin" size="0x1000" crc="3e280096" sha1="33e6bc08b3e8a951942e078102e90fbc8ba729a8"/>
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
@ -24,8 +24,8 @@ license:CC0
|
||||
<info name="serial" value="6076" />
|
||||
|
||||
<part name="cart" interface="advision_cart">
|
||||
<dataarea name="rom" size="4096">
|
||||
<rom name="turtles.bin" size="4096" crc="33a23eba" sha1="88748cf4080646e0a2f115a7f6e6001916314816"/>
|
||||
<dataarea name="rom" size="0x1000">
|
||||
<rom name="turtles.bin" size="0x1000" crc="33a23eba" sha1="88748cf4080646e0a2f115a7f6e6001916314816"/>
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
@ -37,8 +37,8 @@ license:CC0
|
||||
<info name="serial" value="6077" />
|
||||
|
||||
<part name="cart" interface="advision_cart">
|
||||
<dataarea name="rom" size="4096">
|
||||
<rom name="supcobra.bin" size="4096" crc="b6045c9e" sha1="fd059081d8d82f51dd1415cc3710f1fa5ebb1336"/>
|
||||
<dataarea name="rom" size="0x1000">
|
||||
<rom name="supcobra.bin" size="0x1000" crc="b6045c9e" sha1="fd059081d8d82f51dd1415cc3710f1fa5ebb1336"/>
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
@ -50,8 +50,8 @@ license:CC0
|
||||
<info name="serial" value="6078" />
|
||||
|
||||
<part name="cart" interface="advision_cart">
|
||||
<dataarea name="rom" size="4096">
|
||||
<rom name="spcforce.bin" size="4096" crc="c70d4028" sha1="86c1a6eb8a5070f4be32bf4e83c0d5951e831d27"/>
|
||||
<dataarea name="rom" size="0x1000">
|
||||
<rom name="spcforce.bin" size="0x1000" crc="c70d4028" sha1="86c1a6eb8a5070f4be32bf4e83c0d5951e831d27"/>
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
@ -735,10 +735,10 @@ void pioneer_ldv4200hle_device::device_reset()
|
||||
// reset our state
|
||||
m_vbi_fetch->adjust(attotime::never);
|
||||
|
||||
std::fill_n(m_cmd_buffer, 0, std::size(m_cmd_buffer));
|
||||
std::fill_n(m_cmd_buffer, std::size(m_cmd_buffer), 0);
|
||||
m_cmd_length = 0;
|
||||
m_cmd_running = false;
|
||||
std::fill_n(m_reply_buffer, 0, std::size(m_reply_buffer));
|
||||
std::fill_n(m_reply_buffer, std::size(m_reply_buffer), 0);
|
||||
m_reply_write_index = 0;
|
||||
m_reply_read_index = 0;
|
||||
m_replying = false;
|
||||
|
@ -1,275 +1,154 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Dan Boris
|
||||
/*************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Driver for the Entex Adventure Vision
|
||||
Entex Adventure Vision, tabletop video game console
|
||||
|
||||
Hardware notes:
|
||||
- INS8048-11 @ 11MHz (1KB internal ROM)
|
||||
- COP411 for the sound, 1-bit speaker with volume control
|
||||
- 4KB EPROM socket
|
||||
- 1KB external RAM (2*MM2114N)
|
||||
- 40 small rectangular red LEDs, a motor with a fast spinning mirror gives the
|
||||
illusion of a 150*40 screen (similar to Nintendo Virtual Boy)
|
||||
- 4-way joystick, 8 buttons (other than having buttons 2/4 swapped, left and
|
||||
right button panels are electronically the same)
|
||||
|
||||
The mirror is faked in MAME. On the real thing, the picture is not as stable.
|
||||
|
||||
A game cartridge is basically an EPROM chip wearing a jacket, there is no
|
||||
dedicated cartridge slot as is common on other consoles. Only 4 games were
|
||||
released in total.
|
||||
|
||||
TODO:
|
||||
- convert to discrete sound
|
||||
- screen pincushion distortion
|
||||
- EA banking is ugly, it can be turd-polished but the real issue is in mcs48
|
||||
- display refresh is actually 15Hz, but doing that will make MAME very sluggish
|
||||
- Do the spinning mirror simulation differently? Right now it relies on the BIOS
|
||||
specifying a width of 150, and the official games work fine. But it should be
|
||||
possible to update the leds at a different rate. In fact, the homebrew demo
|
||||
Code Red doesn't use the BIOS for it, and runs at 50*40.
|
||||
|
||||
**************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "screen.h"
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/generic/carts.h"
|
||||
#include "cpu/cop400/cop400.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/dac.h"
|
||||
#include "emupal.h"
|
||||
#include "sound/flt_vol.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#define I8048_TAG "i8048"
|
||||
#define COP411_TAG "cop411"
|
||||
|
||||
class advision_state : public driver_device
|
||||
{
|
||||
public:
|
||||
advision_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, I8048_TAG)
|
||||
, m_soundcpu(*this, COP411_TAG)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_soundcpu(*this, "soundcpu")
|
||||
, m_dac(*this, "dac")
|
||||
, m_volume(*this, "volume")
|
||||
, m_screen(*this, "screen")
|
||||
, m_mirror_sync(*this, "mirror_sync")
|
||||
, m_cart(*this, "cartslot")
|
||||
, m_bank1(*this, "bank1")
|
||||
, m_joy(*this, "joystick")
|
||||
, m_palette(*this, "palette")
|
||||
, m_ea_bank(*this, "ea_bank")
|
||||
, m_joy(*this, "JOY")
|
||||
{ }
|
||||
|
||||
required_device<i8048_device> m_maincpu;
|
||||
required_device<cop411_cpu_device> m_soundcpu;
|
||||
required_device<dac_byte_interface> m_dac;
|
||||
required_device<dac_1bit_device> m_dac;
|
||||
required_device<filter_volume_device> m_volume;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<timer_device> m_mirror_sync;
|
||||
required_device<generic_slot_device> m_cart;
|
||||
required_memory_bank m_bank1;
|
||||
required_memory_bank m_ea_bank;
|
||||
required_ioport m_joy;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void update_dac();
|
||||
void vh_write(int data);
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(vblank);
|
||||
void vh_update(int x);
|
||||
|
||||
uint8_t rom_r(offs_t offset);
|
||||
uint8_t ext_ram_r(offs_t offset);
|
||||
void ext_ram_w(offs_t offset, uint8_t data);
|
||||
uint8_t controller_r();
|
||||
void bankswitch_w(uint8_t data);
|
||||
void av_control_w(uint8_t data);
|
||||
DECLARE_READ_LINE_MEMBER( vsync_r );
|
||||
u8 ext_ram_r(offs_t offset);
|
||||
void ext_ram_w(offs_t offset, u8 data);
|
||||
u8 controller_r();
|
||||
void bankswitch_w(u8 data);
|
||||
void av_control_w(u8 data);
|
||||
DECLARE_READ_LINE_MEMBER(vsync_r);
|
||||
|
||||
TIMER_CALLBACK_MEMBER( sound_cmd_sync );
|
||||
uint8_t sound_cmd_r();
|
||||
void sound_g_w(uint8_t data);
|
||||
void sound_d_w(uint8_t data);
|
||||
TIMER_CALLBACK_MEMBER(sound_cmd_sync);
|
||||
u8 sound_cmd_r();
|
||||
void sound_g_w(u8 data);
|
||||
void sound_d_w(u8 data);
|
||||
|
||||
memory_region *m_cart_rom = nullptr;
|
||||
|
||||
int m_ea_bank = 0;
|
||||
|
||||
/* external RAM state */
|
||||
std::vector<uint8_t> m_ext_ram;
|
||||
std::vector<u8> m_ext_ram;
|
||||
int m_rambank = 0;
|
||||
|
||||
/* video state */
|
||||
int m_frame_count = 0;
|
||||
int m_frame_start = 0;
|
||||
int m_video_enable = 0;
|
||||
int m_video_bank = 0;
|
||||
int m_video_hpos = 0;
|
||||
uint8_t m_led_latch[8] = {};
|
||||
std::unique_ptr<uint8_t []> m_display;
|
||||
u8 m_led_latch[5] = { };
|
||||
std::unique_ptr<u8 []> m_display;
|
||||
|
||||
/* sound state */
|
||||
int m_sound_cmd = 0;
|
||||
int m_sound_d = 0;
|
||||
int m_sound_g = 0;
|
||||
void advision_palette(palette_device &palette) const;
|
||||
|
||||
void advision(machine_config &config);
|
||||
void io_map(address_map &map);
|
||||
void program_map(address_map &map);
|
||||
};
|
||||
|
||||
/* Memory Maps */
|
||||
|
||||
uint8_t advision_state::rom_r(offs_t offset)
|
||||
|
||||
/*******************************************************************************
|
||||
Video
|
||||
*******************************************************************************/
|
||||
|
||||
u32 advision_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
offset += 0x400;
|
||||
return m_cart->read_rom(offset & 0xfff);
|
||||
}
|
||||
|
||||
void advision_state::program_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x03ff).bankr("bank1");
|
||||
map(0x0400, 0x0fff).r(FUNC(advision_state::rom_r));
|
||||
}
|
||||
|
||||
void advision_state::io_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0xff).rw(FUNC(advision_state::ext_ram_r), FUNC(advision_state::ext_ram_w));
|
||||
}
|
||||
|
||||
/* Input Ports */
|
||||
|
||||
static INPUT_PORTS_START( advision )
|
||||
PORT_START("joystick")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY
|
||||
INPUT_PORTS_END
|
||||
|
||||
/*
|
||||
8048 Ports:
|
||||
|
||||
P1 Bit 0..1 - RAM bank select
|
||||
Bit 3..7 - Keypad input
|
||||
|
||||
P2 Bit 0..3 - A8-A11
|
||||
Bit 4..7 - Sound control/Video write address
|
||||
|
||||
T1 Mirror sync pulse
|
||||
*/
|
||||
|
||||
/* Machine Initialization */
|
||||
|
||||
void advision_state::machine_start()
|
||||
{
|
||||
std::string region_tag;
|
||||
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
|
||||
/* configure EA banking */
|
||||
m_bank1->configure_entry(0, memregion(I8048_TAG)->base());
|
||||
if (m_cart_rom)
|
||||
m_bank1->configure_entry(1, m_cart_rom->base());
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_bank(0x0000, 0x03ff, m_bank1);
|
||||
m_bank1->set_entry(0);
|
||||
|
||||
m_sound_d = 0;
|
||||
m_sound_g = 0;
|
||||
|
||||
m_video_hpos = 0;
|
||||
m_display = std::make_unique<uint8_t []>(8 * 8 * 256);
|
||||
std::fill_n(m_display.get(), 8 * 8 * 256, 0);
|
||||
|
||||
/* allocate external RAM */
|
||||
m_ext_ram.resize(0x400);
|
||||
save_item(NAME(m_ext_ram));
|
||||
|
||||
save_item(NAME(m_ea_bank));
|
||||
save_item(NAME(m_rambank));
|
||||
save_item(NAME(m_frame_count));
|
||||
save_item(NAME(m_frame_start));
|
||||
save_item(NAME(m_video_enable));
|
||||
save_item(NAME(m_video_bank));
|
||||
save_item(NAME(m_led_latch));
|
||||
save_item(NAME(m_sound_cmd));
|
||||
save_item(NAME(m_sound_d));
|
||||
save_item(NAME(m_sound_g));
|
||||
save_pointer(NAME(m_display), 8 * 8 * 256);
|
||||
save_item(NAME(m_video_hpos));
|
||||
}
|
||||
|
||||
void advision_state::machine_reset()
|
||||
{
|
||||
m_ea_bank = 1;
|
||||
m_rambank = 0x300;
|
||||
m_frame_start = 0;
|
||||
m_video_enable = 0;
|
||||
m_sound_cmd = 0;
|
||||
|
||||
/* enable internal ROM */
|
||||
m_maincpu->set_input_line(MCS48_INPUT_EA, CLEAR_LINE);
|
||||
if (m_cart_rom)
|
||||
m_bank1->set_entry(m_ea_bank);
|
||||
|
||||
/* reset sound CPU */
|
||||
m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
}
|
||||
|
||||
/* Bank Switching */
|
||||
|
||||
void advision_state::bankswitch_w(uint8_t data)
|
||||
{
|
||||
m_ea_bank = BIT(data, 2);
|
||||
m_rambank = (data & 0x03) << 8;
|
||||
|
||||
m_maincpu->set_input_line(MCS48_INPUT_EA, m_ea_bank ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (m_cart_rom)
|
||||
m_bank1->set_entry(m_ea_bank);
|
||||
}
|
||||
|
||||
/* External RAM */
|
||||
|
||||
uint8_t advision_state::ext_ram_r(offs_t offset)
|
||||
{
|
||||
uint8_t data = m_ext_ram[m_rambank + offset];
|
||||
|
||||
/* the video hardware interprets reads as writes */
|
||||
vh_write(data);
|
||||
|
||||
if (m_video_bank == 0x06)
|
||||
for (int y = 0; y < 40; y++)
|
||||
{
|
||||
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
|
||||
u8 *src = &m_display[y * 256];
|
||||
|
||||
for (int x = 0; x < 150; x++)
|
||||
{
|
||||
int dx = x + 1;
|
||||
int dy = y * 2 + 1;
|
||||
|
||||
if (cliprect.contains(dx, dy))
|
||||
bitmap.pix(dy, dx) = src[x] ? (0xff << 16) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void advision_state::ext_ram_w(offs_t offset, uint8_t data)
|
||||
void advision_state::vh_update(int x)
|
||||
{
|
||||
m_ext_ram[m_rambank + offset] = data;
|
||||
u8 *dst = &m_display[x];
|
||||
|
||||
for (int y = 4; y >= 0; y--)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
dst[i * 256] = BIT(m_led_latch[y], 7 - i) ? 0 : 1;
|
||||
|
||||
m_led_latch[y] = 0xff;
|
||||
dst += 8 * 256;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sound */
|
||||
|
||||
TIMER_CALLBACK_MEMBER( advision_state::sound_cmd_sync )
|
||||
void advision_state::av_control_w(u8 data)
|
||||
{
|
||||
m_sound_cmd = param;
|
||||
}
|
||||
|
||||
uint8_t advision_state::sound_cmd_r()
|
||||
{
|
||||
return m_sound_cmd;
|
||||
}
|
||||
|
||||
void advision_state::update_dac()
|
||||
{
|
||||
int translate[] = { 2, 0, 0, 1 };
|
||||
m_dac->write(translate[(m_sound_g << 1) | m_sound_d]);
|
||||
}
|
||||
|
||||
void advision_state::sound_g_w(uint8_t data)
|
||||
{
|
||||
m_sound_g = data & 0x01;
|
||||
|
||||
update_dac();
|
||||
}
|
||||
|
||||
void advision_state::sound_d_w(uint8_t data)
|
||||
{
|
||||
m_sound_d = data & 0x01;
|
||||
|
||||
update_dac();
|
||||
}
|
||||
|
||||
/* Video */
|
||||
|
||||
void advision_state::av_control_w(uint8_t data)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(advision_state::sound_cmd_sync), this), data >> 4);
|
||||
|
||||
if ((m_video_enable == 0x00) && (data & 0x10))
|
||||
{
|
||||
vh_update(m_video_hpos);
|
||||
@ -285,124 +164,184 @@ void advision_state::av_control_w(uint8_t data)
|
||||
|
||||
m_video_enable = data & 0x10;
|
||||
m_video_bank = (data & 0xe0) >> 5;
|
||||
|
||||
// sync soundlatch (using gen_latch device here would give lots of logerror)
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(advision_state::sound_cmd_sync), this), data >> 4);
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER( advision_state::vsync_r )
|
||||
WRITE_LINE_MEMBER(advision_state::vblank)
|
||||
{
|
||||
if (m_frame_start)
|
||||
if (!state && (m_screen->frame_number() & 3) == 0)
|
||||
{
|
||||
m_frame_start = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
std::fill_n(m_display.get(), 256 * 40, 0);
|
||||
m_mirror_sync->adjust(attotime::from_usec(100));
|
||||
m_video_hpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Input */
|
||||
|
||||
uint8_t advision_state::controller_r()
|
||||
READ_LINE_MEMBER(advision_state::vsync_r)
|
||||
{
|
||||
// Get joystick switches
|
||||
uint8_t in = m_joy->read();
|
||||
uint8_t data = in | 0x0f;
|
||||
// mirror sync pulse (half rotation)
|
||||
return (m_mirror_sync->enabled()) ? 0 : 1;
|
||||
}
|
||||
|
||||
// Get buttons
|
||||
if (in & 0x02) data = data & 0xf7; /* Button 3 */
|
||||
if (in & 0x08) data = data & 0xcf; /* Button 1 */
|
||||
if (in & 0x04) data = data & 0xaf; /* Button 2 */
|
||||
if (in & 0x01) data = data & 0x6f; /* Button 4 */
|
||||
|
||||
data &= 0xf8;
|
||||
data |= (m_ea_bank << 2);
|
||||
data |= (m_rambank >> 8);
|
||||
|
||||
/*******************************************************************************
|
||||
Sound
|
||||
*******************************************************************************/
|
||||
|
||||
TIMER_CALLBACK_MEMBER(advision_state::sound_cmd_sync)
|
||||
{
|
||||
m_sound_cmd = param;
|
||||
}
|
||||
|
||||
u8 advision_state::sound_cmd_r()
|
||||
{
|
||||
return m_sound_cmd;
|
||||
}
|
||||
|
||||
void advision_state::sound_g_w(u8 data)
|
||||
{
|
||||
m_dac->write(data & 1);
|
||||
}
|
||||
|
||||
void advision_state::sound_d_w(u8 data)
|
||||
{
|
||||
m_volume->flt_volume_set_volume((data & 1) ? 0.5 : 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Memory
|
||||
*******************************************************************************/
|
||||
|
||||
void advision_state::bankswitch_w(u8 data)
|
||||
{
|
||||
m_rambank = (data & 0x03) << 8;
|
||||
|
||||
m_maincpu->set_input_line(MCS48_INPUT_EA, BIT(data, 2) ? ASSERT_LINE : CLEAR_LINE);
|
||||
if (m_cart_rom)
|
||||
m_ea_bank->set_entry(BIT(data, 2));
|
||||
}
|
||||
|
||||
u8 advision_state::ext_ram_r(offs_t offset)
|
||||
{
|
||||
u8 data = m_ext_ram[m_rambank + offset];
|
||||
if (machine().side_effects_disabled())
|
||||
return data;
|
||||
|
||||
// the video hardware interprets reads as writes
|
||||
if (m_video_bank >= 1 && m_video_bank <= 5)
|
||||
m_led_latch[m_video_bank - 1] = data;
|
||||
|
||||
else if (m_video_bank == 6)
|
||||
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Initialise the palette.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void advision_state::advision_palette(palette_device &palette) const
|
||||
void advision_state::ext_ram_w(offs_t offset, u8 data)
|
||||
{
|
||||
// 8 shades of RED
|
||||
for (int i = 0; i < 8; i++)
|
||||
m_palette->set_pen_color(i, pal3bit(i), 0x00, 0x00);
|
||||
m_ext_ram[m_rambank + offset] = data;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Update the display data.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void advision_state::vh_write(int data)
|
||||
void advision_state::program_map(address_map &map)
|
||||
{
|
||||
if (m_video_bank >= 1 && m_video_bank <=5)
|
||||
m_led_latch[m_video_bank] = data;
|
||||
map(0x0000, 0x0fff).r(m_cart, FUNC(generic_slot_device::read_rom));
|
||||
map(0x0000, 0x03ff).bankr("ea_bank");
|
||||
}
|
||||
|
||||
void advision_state::vh_update(int x)
|
||||
void advision_state::io_map(address_map &map)
|
||||
{
|
||||
uint8_t *dst = &m_display[x];
|
||||
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
uint8_t data = m_led_latch[7 - y];
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (!BIT(data, 7 - i))
|
||||
dst[i * 256] = 8;
|
||||
}
|
||||
|
||||
m_led_latch[7 - y] = 0xff;
|
||||
dst += 8 * 256;
|
||||
}
|
||||
map(0x00, 0xff).rw(FUNC(advision_state::ext_ram_r), FUNC(advision_state::ext_ram_w));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Refresh the video screen
|
||||
/*******************************************************************************
|
||||
Inputs
|
||||
*******************************************************************************/
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
uint32_t advision_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u8 advision_state::controller_r()
|
||||
{
|
||||
u8 data = m_joy->read();
|
||||
|
||||
// some of the buttons share the same bitmask as joystick directions
|
||||
if (~data & 0x01) data &= 0xcf; // button 1: down + up
|
||||
if (~data & 0x02) data &= 0xaf; // button 2: down + right
|
||||
if (~data & 0x04) data &= 0x6f; // button 4: down + left
|
||||
|
||||
return data | 0x07;
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( advision )
|
||||
PORT_START("JOY")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) // u
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) // r
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON4 ) // l
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON3 ) // d
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Machine Initialization
|
||||
*******************************************************************************/
|
||||
|
||||
void advision_state::machine_start()
|
||||
{
|
||||
// configure EA banking
|
||||
std::string region_tag;
|
||||
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
|
||||
m_ea_bank->configure_entry(0, memregion("maincpu")->base());
|
||||
if (m_cart_rom)
|
||||
m_ea_bank->configure_entry(1, m_cart_rom->base());
|
||||
m_maincpu->space(AS_PROGRAM).install_read_bank(0x0000, 0x03ff, m_ea_bank);
|
||||
m_ea_bank->set_entry(0);
|
||||
|
||||
// allocate display buffer
|
||||
m_display = std::make_unique<u8 []>(256 * 40);
|
||||
std::fill_n(m_display.get(), 256 * 40, 0);
|
||||
save_pointer(NAME(m_display), 256 * 40);
|
||||
|
||||
// allocate external RAM
|
||||
m_ext_ram.resize(0x400);
|
||||
save_item(NAME(m_ext_ram));
|
||||
|
||||
std::fill_n(m_led_latch, std::size(m_led_latch), 0xff);
|
||||
save_item(NAME(m_led_latch));
|
||||
|
||||
save_item(NAME(m_rambank));
|
||||
save_item(NAME(m_video_enable));
|
||||
save_item(NAME(m_video_bank));
|
||||
save_item(NAME(m_sound_cmd));
|
||||
save_item(NAME(m_video_hpos));
|
||||
}
|
||||
|
||||
void advision_state::machine_reset()
|
||||
{
|
||||
if ((m_frame_count++ % 4) == 0)
|
||||
{
|
||||
m_frame_start = 1;
|
||||
m_video_hpos = 0;
|
||||
}
|
||||
|
||||
for (int x = 0; x < 150; x++)
|
||||
{
|
||||
uint8_t *led = &m_display[x];
|
||||
|
||||
for (int y = 0; y < 128; y+=2)
|
||||
{
|
||||
if (*led > 0)
|
||||
bitmap.pix(30 + y, 85 + x) = --(*led);
|
||||
else
|
||||
bitmap.pix(30 + y, 85 + x) = 0;
|
||||
|
||||
led += 256;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
// reset sound CPU
|
||||
m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
}
|
||||
|
||||
/* Machine Driver */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Machine Config
|
||||
*******************************************************************************/
|
||||
|
||||
void advision_state::advision(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
// basic machine hardware
|
||||
I8048(config, m_maincpu, XTAL(11'000'000));
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &advision_state::program_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &advision_state::io_map);
|
||||
@ -411,45 +350,54 @@ void advision_state::advision(machine_config &config)
|
||||
m_maincpu->p2_out_cb().set(FUNC(advision_state::av_control_w));
|
||||
m_maincpu->t1_in_cb().set(FUNC(advision_state::vsync_r));
|
||||
|
||||
COP411(config, m_soundcpu, 52631*4); // COP411L-KCN/N, R11=82k, C8=56pF
|
||||
COP411(config, m_soundcpu, 210000); // COP411L-KCN/N, R11=82k, C8=56pF
|
||||
m_soundcpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_RAM_POWER_SUPPLY, false);
|
||||
m_soundcpu->read_l().set(FUNC(advision_state::sound_cmd_r));
|
||||
m_soundcpu->write_g().set(FUNC(advision_state::sound_g_w));
|
||||
m_soundcpu->write_d().set(FUNC(advision_state::sound_d_w));
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(4*15);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
|
||||
screen.set_screen_update(FUNC(advision_state::screen_update));
|
||||
screen.set_size(320, 200);
|
||||
screen.set_visarea(84, 235, 60, 142);
|
||||
screen.set_palette(m_palette);
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(4*15); // actually 15Hz
|
||||
m_screen->set_vblank_time(0);
|
||||
m_screen->set_size(150 + 2, 40 * 2 + 1);
|
||||
m_screen->set_visarea_full();
|
||||
m_screen->set_screen_update(FUNC(advision_state::screen_update));
|
||||
m_screen->screen_vblank().set(FUNC(advision_state::vblank));
|
||||
|
||||
PALETTE(config, m_palette, FUNC(advision_state::advision_palette), 8);
|
||||
TIMER(config, "mirror_sync").configure_generic(nullptr);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
DAC_2BIT_BINARY_WEIGHTED(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.25); // unknown DAC
|
||||
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "volume", 0.25);
|
||||
FILTER_VOLUME(config, m_volume).add_route(ALL_OUTPUTS, "speaker", 1.0);
|
||||
|
||||
/* cartridge */
|
||||
// cartridge
|
||||
GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "advision_cart");
|
||||
|
||||
/* Software lists */
|
||||
SOFTWARE_LIST(config, "cart_list").set_original("advision");
|
||||
}
|
||||
|
||||
/* ROMs */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
ROMs
|
||||
*******************************************************************************/
|
||||
|
||||
ROM_START( advision )
|
||||
ROM_REGION( 0x1000, I8048_TAG, ROMREGION_ERASE00 )
|
||||
ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "b225__ins8048-11kdp_n.u5", 0x000, 0x400, CRC(279e33d1) SHA1(bf7b0663e9125c9bfb950232eab627d9dbda8460) ) // "<natsemi logo> /B225 \\ INS8048-11KDP/N"
|
||||
|
||||
ROM_REGION( 0x200, COP411_TAG, 0 )
|
||||
ROM_REGION( 0x200, "soundcpu", 0 )
|
||||
ROM_LOAD( "b8223__cop411l-kcn_n.u8", 0x000, 0x200, CRC(81e95975) SHA1(8b6f8c30dd3e9d8e43f1ea20fba2361b383790eb) ) // "<natsemi logo> /B8223 \\ COP411L-KCN/N"
|
||||
ROM_END
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
CONS( 1982, advision, 0, 0, advision, advision, advision_state, empty_init, "Entex", "Adventure Vision", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Driver
|
||||
*******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
CONS( 1982, advision, 0, 0, advision, advision, advision_state, empty_init, "Entex", "Adventure Vision", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1493,9 +1493,9 @@ private:
|
||||
required_device<filter_volume_device> m_volume;
|
||||
required_device<timer_device> m_tempo_timer;
|
||||
|
||||
virtual void write_o(u16 data);
|
||||
virtual void write_r(u32 data);
|
||||
virtual u8 read_k();
|
||||
void write_o(u16 data);
|
||||
void write_r(u32 data);
|
||||
u8 read_k();
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(speaker_decay_sim);
|
||||
double m_speaker_volume = 0.0;
|
||||
@ -3080,9 +3080,9 @@ public:
|
||||
|
||||
protected:
|
||||
void update_display();
|
||||
virtual void write_o(u16 data);
|
||||
virtual void write_r(u32 data);
|
||||
virtual u8 read_k();
|
||||
void write_o(u16 data);
|
||||
void write_r(u32 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -6159,9 +6159,9 @@ public:
|
||||
|
||||
private:
|
||||
void update_display();
|
||||
virtual void write_r(u32 data);
|
||||
virtual void write_o(u16 data);
|
||||
virtual u8 read_k();
|
||||
void write_r(u32 data);
|
||||
void write_o(u16 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -6285,9 +6285,9 @@ public:
|
||||
|
||||
private:
|
||||
void update_display();
|
||||
virtual void write_r(u32 data);
|
||||
virtual void write_o(u16 data);
|
||||
virtual u8 read_k();
|
||||
void write_r(u32 data);
|
||||
void write_o(u16 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -6414,9 +6414,9 @@ private:
|
||||
void expander_w(offs_t offset, u8 data);
|
||||
|
||||
void update_display();
|
||||
virtual void write_r(u32 data);
|
||||
virtual void write_o(u16 data);
|
||||
virtual u8 read_k();
|
||||
void write_r(u32 data);
|
||||
void write_o(u16 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -10926,9 +10926,9 @@ private:
|
||||
required_device<s14001a_device> m_speech;
|
||||
|
||||
void update_display();
|
||||
virtual void write_r(u32 data);
|
||||
virtual void write_o(u16 data);
|
||||
virtual u8 read_k();
|
||||
void write_r(u32 data);
|
||||
void write_o(u16 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -12570,10 +12570,10 @@ public:
|
||||
private:
|
||||
required_device<tmc0999_device> m_ram;
|
||||
|
||||
virtual void update_display();
|
||||
virtual void write_o(u16 data);
|
||||
virtual void write_r(u32 data);
|
||||
virtual u8 read_k();
|
||||
void update_display();
|
||||
void write_o(u16 data);
|
||||
void write_r(u32 data);
|
||||
u8 read_k();
|
||||
};
|
||||
|
||||
// handlers
|
||||
@ -14475,8 +14475,8 @@ private:
|
||||
void expander_w(offs_t offset, u8 data);
|
||||
|
||||
void update_display();
|
||||
virtual void write_r(u32 data);
|
||||
virtual void write_o(u16 data);
|
||||
void write_r(u32 data);
|
||||
void write_o(u16 data);
|
||||
};
|
||||
|
||||
// handlers
|
||||
|
Loading…
Reference in New Issue
Block a user