summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/pc6001.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/pc6001.cpp')
-rw-r--r--src/mame/drivers/pc6001.cpp170
1 files changed, 70 insertions, 100 deletions
diff --git a/src/mame/drivers/pc6001.cpp b/src/mame/drivers/pc6001.cpp
index dc10cefadbc..d1e67756ca0 100644
--- a/src/mame/drivers/pc6001.cpp
+++ b/src/mame/drivers/pc6001.cpp
@@ -18,6 +18,8 @@
- PC-6001SR: get it to boot, also implement MK-2 compatibility mode (it changes
the memory map to behave like the older versions)
- Hookup MC6847 for vanilla PC-6001 and fix video bugs for that device;
+ - voice speech device doesn't work properly, is it even a uPD7752?
+ Chrith game is a good test case, it's supposed to talk before title screen;
TODO (game specific):
- (several AX* games, namely Galaxy Mission Part 1/2 and others): inputs doesn't work;
@@ -147,8 +149,7 @@ inline void pc6001_state::cassette_latch_control(bool new_state)
m_cas_switch = 0;
//m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
//m_cassette->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE);
- //m_irq_vector = 0x00;
- //m_maincpu->set_input_line(0, ASSERT_LINE);
+ //set_maincpu_irq_line(0x00);
}
}
@@ -175,6 +176,12 @@ inline void pc6001_state::ppi_control_hack_w(uint8_t data)
m_port_c_8255 |= 0xa8;
}
+inline void pc6001_state::set_maincpu_irq_line(uint8_t vector_num)
+{
+ m_irq_vector = vector_num;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+}
+
WRITE8_MEMBER(pc6001_state::system_latch_w)
{
static const uint16_t startaddr[] = {0xC000, 0xE000, 0x8000, 0xA000 };
@@ -563,29 +570,14 @@ WRITE8_MEMBER(pc6001mk2_state::necmk2_ppi8255_w)
void pc6001mk2_state::vram_bank_change(uint8_t vram_bank)
{
- uint8_t *work_ram = m_region_maincpu->base();
+ uint32_t bank_base_values[8] = { 0x8000, 0xc000, 0xc000, 0xe000, 0x0000, 0x8000, 0x4000, 0xa000 };
+ uint8_t vram_bank_index = ((vram_bank & 0x60) >> 4) | ((vram_bank & 2) >> 1);
+// uint8_t *work_ram = m_region_maincpu->base();
-// popmessage("%02x",vram_bank);
+// bit 2 of vram_bank sets up 4 color mode
+ set_videoram_bank(0x28000 + bank_base_values[vram_bank_index]);
- switch(vram_bank & 0x66)
- {
- case 0x00: m_video_ram = work_ram + 0x8000 + 0x28000; break; //4 color mode
- case 0x02: m_video_ram = work_ram + 0xc000 + 0x28000; break;
- case 0x04: m_video_ram = work_ram + 0x8000 + 0x28000; break;
- case 0x06: m_video_ram = work_ram + 0xc000 + 0x28000; break;
- case 0x20: m_video_ram = work_ram + 0xc000 + 0x28000; break; //4 color mode
- case 0x22: m_video_ram = work_ram + 0xe000 + 0x28000; break;
- case 0x24: m_video_ram = work_ram + 0xc000 + 0x28000; break;
- case 0x26: m_video_ram = work_ram + 0xe000 + 0x28000; break;
- case 0x40: m_video_ram = work_ram + 0x0000 + 0x28000; break; //4 color mode
- case 0x42: m_video_ram = work_ram + 0x8000 + 0x28000; break;
- case 0x44: m_video_ram = work_ram + 0x0000 + 0x28000; break;
- case 0x46: m_video_ram = work_ram + 0x8000 + 0x28000; break;
- case 0x60: m_video_ram = work_ram + 0x4000 + 0x28000; break; //4 color mode
- case 0x62: m_video_ram = work_ram + 0xa000 + 0x28000; break;
- case 0x64: m_video_ram = work_ram + 0x4000 + 0x28000; break;
- case 0x66: m_video_ram = work_ram + 0xa000 + 0x28000; break;
- }
+// popmessage("%02x",vram_bank);
}
WRITE8_MEMBER(pc6001mk2_state::mk2_system_latch_w)
@@ -599,6 +591,18 @@ WRITE8_MEMBER(pc6001mk2_state::mk2_system_latch_w)
//printf("%02x B0\n",data);
}
+inline void pc6001mk2_state::refresh_crtc_params()
+{
+ /* Apparently bitmap modes changes the screen res to 320 x 200 */
+ rectangle visarea = m_screen->visible_area();
+ int y_height;
+
+ y_height = (m_exgfx_bitmap_mode || m_exgfx_2bpp_mode) ? 200 : 240;
+
+ visarea.set(0, (320) - 1, 0, (y_height) - 1);
+
+ m_screen->configure(m_screen->width(), m_screen->height(), visarea, m_screen->frame_period().attoseconds());
+}
WRITE8_MEMBER(pc6001mk2_state::mk2_vram_bank_w)
{
@@ -613,19 +617,7 @@ WRITE8_MEMBER(pc6001mk2_state::mk2_vram_bank_w)
m_exgfx_bitmap_mode = (data & 8);
m_exgfx_2bpp_mode = ((data & 6) == 0);
- {
- /* Apparently bitmap modes changes the screen res to 320 x 200 */
- {
- rectangle visarea = machine().first_screen()->visible_area();
- int y_height;
-
- y_height = (m_exgfx_bitmap_mode || m_exgfx_2bpp_mode) ? 200 : 240;
-
- visarea.set(0, (320) - 1, 0, (y_height) - 1);
-
- machine().first_screen()->configure(320, 240, visarea, machine().first_screen()->frame_period().attoseconds());
- }
- }
+ refresh_crtc_params();
// popmessage("%02x",data);
@@ -653,13 +645,18 @@ WRITE8_MEMBER(pc6001mk2_state::mk2_0xf3_w)
m_timer_irq_mask2 = data & 4;
}
-WRITE8_MEMBER(pc6001mk2_state::mk2_timer_adj_w)
+inline void pc6001_state::set_timer_divider(uint8_t data)
{
m_timer_hz_div = data;
attotime period = attotime::from_hz((487.5*4)/(m_timer_hz_div+1));
m_timer_irq_timer->adjust(period, 0, period);
}
+WRITE8_MEMBER(pc6001mk2_state::mk2_timer_adj_w)
+{
+ set_timer_divider(data);
+}
+
WRITE8_MEMBER(pc6001mk2_state::mk2_timer_irqv_w)
{
m_timer_irq_vector = data;
@@ -844,9 +841,7 @@ WRITE8_MEMBER(pc6001sr_state::sr_mode_w)
WRITE8_MEMBER(pc6001sr_state::sr_vram_bank_w)
{
- uint8_t *work_ram = m_region_maincpu->base();
-
- m_video_ram = work_ram + 0x70000 + ((data & 0x0f)*0x1000);
+ set_videoram_bank(0x70000 + ((data & 0x0f)*0x1000));
}
WRITE8_MEMBER(pc6001sr_state::sr_system_latch_w)
@@ -998,10 +993,10 @@ static INPUT_PORTS_START( pc6001 )
PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x19 cancel
PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1a em
PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1b sub
- PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(27)
- PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1d fs
- PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1e gs
- PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1f us
+ PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
+ PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
+ PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
+ PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_START("key2") //0x20-0x3f
PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
@@ -1086,8 +1081,7 @@ TIMER_CALLBACK_MEMBER(pc6001_state::audio_callback)
if(m_cas_switch == 0 && ((m_timer_irq_mask == 0) || (m_timer_irq_mask2 == 0)))
{
if(IRQ_LOG) printf("Timer IRQ called %02x\n",m_timer_irq_vector);
- m_irq_vector = m_timer_irq_vector;
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(m_timer_irq_vector);
}
}
@@ -1095,8 +1089,7 @@ INTERRUPT_GEN_MEMBER(pc6001_state::vrtc_irq)
{
m_cur_keycode = check_joy_press();
if(IRQ_LOG) printf("VRTC IRQ called 0x16\n"); // was "stick" IRQ?
- m_irq_vector = 0x16;
- device.execute().set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(0x16);
}
INTERRUPT_GEN_MEMBER(pc6001sr_state::sr_vrtc_irq)
@@ -1105,8 +1098,7 @@ INTERRUPT_GEN_MEMBER(pc6001sr_state::sr_vrtc_irq)
m_cur_keycode = check_joy_press();
if(IRQ_LOG) printf("VRTC IRQ called 0x16\n");
- m_irq_vector = (m_kludge) ? 0x22 : 0x16;
- device.execute().set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line((m_kludge) ? 0x22 : 0x16);
}
IRQ_CALLBACK_MEMBER(pc6001_state::irq_callback)
@@ -1242,8 +1234,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::cassette_callback)
m_cur_keycode = cas_data_poll;
cas_data_i = 0x80;
/* data ready, poll irq */
- m_irq_vector = 0x08;
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(0x08);
}
else
cas_data_i>>=1;
@@ -1256,14 +1247,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::cassette_callback)
m_cas_offset = 0;
m_cas_switch = 0;
if(IRQ_LOG) printf("Tape-E IRQ 0x12\n");
- m_irq_vector = 0x12;
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(0x12);
}
else
{
if(IRQ_LOG) printf("Tape-D IRQ 0x08\n");
- m_irq_vector = 0x08;
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(0x08);
}
#endif
}
@@ -1277,13 +1266,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)
// uint8_t p1_key = m_io_p1->read();
if(m_cas_switch == 0)
- {
+ {
if((key1 != m_old_key1) || (key2 != m_old_key2) || (key3 != m_old_key3))
{
m_cur_keycode = check_keyboard_press();
if(IRQ_LOG) printf("KEY IRQ 0x02\n");
- m_irq_vector = 0x02;
- m_maincpu->set_input_line(0, ASSERT_LINE);
+ set_maincpu_irq_line(0x02);
m_old_key1 = key1;
m_old_key2 = key2;
m_old_key3 = key3;
@@ -1293,10 +1281,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)
{
m_cur_keycode = check_joy_press();
if(m_cur_keycode)
- {
- m_irq_vector = 0x16;
- m_maincpu->set_input_line(0, ASSERT_LINE);
- }
+ set_maincpu_irq_line(0x16);
}
#endif
}
@@ -1304,18 +1289,18 @@ TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)
void pc6001_state::machine_start()
{
- m_timer_hz_div = 3;
- {
- attotime period = attotime::from_hz((487.5*4)/(m_timer_hz_div+1));
- m_timer_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc6001_state::audio_callback),this));
- m_timer_irq_timer->adjust(period, 0, period);
- }
+ m_timer_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc6001_state::audio_callback),this));
}
-void pc6001_state::machine_reset()
+inline void pc6001_state::set_videoram_bank(uint32_t offs)
{
- m_video_ram = m_region_maincpu->base() + 0xc000;
+ m_video_ram = m_region_maincpu->base() + offs;
+}
+void pc6001_state::machine_reset()
+{
+ set_videoram_bank(0xc000);
+
if (m_cart->exists())
m_maincpu->space(AS_PROGRAM).install_read_handler(0x4000, 0x5fff, read8_delegate(FUNC(generic_slot_device::read_rom),(generic_slot_device*)m_cart));
@@ -1329,26 +1314,22 @@ void pc6001_state::machine_reset()
m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
m_timer_irq_mask = 1;
m_timer_irq_mask2 = 1;
- m_timer_irq_vector = 0x06; // actually vector is fixed in plain PC-6001
- m_timer_hz_div = 3;
+ // timer irq vector is fixed in plain PC-6001
+ m_timer_irq_vector = 0x06;
+ set_timer_divider(3);
}
-MACHINE_RESET_MEMBER(pc6001mk2_state,pc6001mk2)
+void pc6001mk2_state::machine_reset()
{
- m_video_ram = m_region_maincpu->base() + 0xc000 + 0x28000;
+ pc6001_state::machine_reset();
+ set_videoram_bank(0xc000 + 0x28000);
std::string region_tag;
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
- // hackish way to simplify bankswitch handling
+ // TODO: hackish way to simplify bankswitch handling
if (m_cart_rom)
memcpy(m_region_maincpu->base() + 0x48000, m_cart_rom->base(), 0x4000);
- m_port_c_8255=0;
-
- m_cas_switch = 0;
- m_cas_offset = 0;
- m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
-
/* set default bankswitch */
{
uint8_t *ROM = m_region_maincpu->base();
@@ -1367,25 +1348,18 @@ MACHINE_RESET_MEMBER(pc6001mk2_state,pc6001mk2)
m_gfx_bank_on = 0;
}
- m_timer_irq_mask = 1;
- m_timer_irq_mask2 = 1;
- m_timer_irq_vector = 0x06;
+// refresh_crtc_params();
}
-MACHINE_RESET_MEMBER(pc6001sr_state,pc6001sr)
+void pc6001sr_state::machine_reset()
{
- m_video_ram = m_region_maincpu->base() + 0x70000;
+ pc6001_state::machine_reset();
+ set_videoram_bank(0x70000);
std::string region_tag;
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
// should this be mirrored into the EXROM regions? hard to tell without an actual cart dump...
- m_port_c_8255=0;
-
- m_cas_switch = 0;
- m_cas_offset = 0;
- m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
-
/* set default bankswitch */
{
uint8_t *ROM = m_region_maincpu->base();
@@ -1409,12 +1383,8 @@ MACHINE_RESET_MEMBER(pc6001sr_state,pc6001sr)
m_sr_bank_w[6] = 0x0c;
m_sr_bank_w[7] = 0x0e;
- m_gfx_bank_on = 0;
+// m_gfx_bank_on = 0;
}
-
- m_timer_irq_mask = 1;
- m_timer_irq_mask2 = 1;
- m_timer_irq_vector = 0x06;
}
@@ -1520,7 +1490,7 @@ MACHINE_CONFIG_DERIVED(pc6001mk2_state::pc6001mk2, pc6001)
MCFG_CPU_PROGRAM_MAP(pc6001mk2_map)
MCFG_CPU_IO_MAP(pc6001mk2_io)
- MCFG_MACHINE_RESET_OVERRIDE(pc6001mk2_state,pc6001mk2)
+// MCFG_MACHINE_RESET_OVERRIDE(pc6001mk2_state,pc6001mk2)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(pc6001mk2_state, screen_update_pc6001mk2)
@@ -1556,7 +1526,7 @@ MACHINE_CONFIG_DERIVED(pc6001sr_state::pc6001sr, pc6001mk2)
MCFG_CPU_VBLANK_INT_DRIVER("screen", pc6001sr_state, sr_vrtc_irq)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(pc6001_state, irq_callback)
- MCFG_MACHINE_RESET_OVERRIDE(pc6001sr_state,pc6001sr)
+// MCFG_MACHINE_RESET_OVERRIDE(pc6001sr_state,pc6001sr)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(pc6001sr_state, screen_update_pc6001sr)