blob: 0a74cef6ccf7c9ea04e5194e5fc13526c8115599 (
plain) (
tree)
|
|
// license:BSD-3-Clause
// copyright-holders:Dan Boris
/***************************************************************************
Machine file to handle emulation of the AdventureVision.
***************************************************************************/
#include "emu.h"
#include "includes/advision.h"
#include "cpu/mcs48/mcs48.h"
/*
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;
/* 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));
}
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)
{
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
}
return data;
}
void advision_state::ext_ram_w(offs_t offset, uint8_t data)
{
m_ext_ram[m_rambank + offset] = data;
}
/* Sound */
TIMER_CALLBACK_MEMBER( advision_state::sound_cmd_sync )
{
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);
m_video_hpos++;
if (m_video_hpos > 255)
{
m_video_hpos = 0;
logerror("HPOS OVERFLOW\n");
}
}
m_video_enable = data & 0x10;
m_video_bank = (data & 0xe0) >> 5;
}
READ_LINE_MEMBER( advision_state::vsync_r )
{
if (m_frame_start)
{
m_frame_start = 0;
return 0;
}
else
{
return 1;
}
}
/* Input */
uint8_t advision_state::controller_r()
{
// Get joystick switches
uint8_t in = m_joy->read();
uint8_t data = in | 0x0f;
// 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);
return data;
}
|