cpu/tlcs900: Added the TMP94C241 variant (used by the Technics SX-KN5000). (#13220)

matsushita/kn5000.cpp: Use TMP94C241 CPU, hooked up I/O to onboard CPU peripherals.
This commit is contained in:
Felipe Corrêa da Silva Sanches 2025-02-17 16:06:48 -03:00 committed by GitHub
parent 803b85fb0f
commit 2905f85348
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 1745 additions and 90 deletions

View File

@ -2982,6 +2982,8 @@ if CPUS["TLCS900"] then
MAME_DIR .. "src/devices/cpu/tlcs900/tlcs900.h",
MAME_DIR .. "src/devices/cpu/tlcs900/900tbl.hxx",
MAME_DIR .. "src/devices/cpu/tlcs900/900htbl.hxx",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp94c241.cpp",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp94c241.h",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.cpp",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.h",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c063.cpp",

View File

@ -138,7 +138,7 @@ void tlcs900_device::device_start()
save_item( NAME(m_dmac) );
save_item( NAME(m_dmam) );
save_item( NAME(m_timer_pre) );
save_item( NAME(m_timer) );
save_item( NAME(m_timer_8) );
save_item( NAME(m_timer_change) );
save_item( NAME(m_level) );
save_item( NAME(m_check_irqs) );

View File

@ -20,6 +20,9 @@ enum tlcs900_inputs
TLCS900_INT6,
TLCS900_INT7,
TLCS900_INT8,
TLCS900_INT9,
TLCS900_INTA,
TLCS900_INTB,
TLCS900_TIO,
TLCS900_NUM_INPUTS
};
@ -102,8 +105,8 @@ protected:
/* Internal timers, irqs, etc */
uint32_t m_timer_pre;
uint8_t m_timer[6];
int m_timer_change[4];
uint8_t m_timer_8[6];
int m_timer_change[8];
bool m_prefetch_clear;
uint8_t m_prefetch_index;
uint8_t m_prefetch[4];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
// license:BSD-3-Clause
// copyright-holders:AJR,Felipe Sanches
/****************************************************************************
Toshiba TMP94C241 microcontroller
****************************************************************************/
#ifndef MAME_CPU_TLCS900_TMP94C241_H
#define MAME_CPU_TLCS900_TMP94C241_H
#pragma once
#include "tlcs900.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> tmp94c241_device
class tmp94c241_device : public tlcs900h_device
{
static constexpr uint8_t PORT_0 = 0; // 8 bit I/O. Shared with d0-d7
static constexpr uint8_t PORT_1 = 1; // 8 bit I/O. Shared with d8-d15
static constexpr uint8_t PORT_2 = 2; // 8 bit I/O. Shared with d16-d23
static constexpr uint8_t PORT_3 = 3; // 8 bit I/O. Shared with d24-d31
static constexpr uint8_t PORT_4 = 4; // 8 bit I/O. Shared with a0-a7
static constexpr uint8_t PORT_5 = 5; // 8 bit I/O. Shared with a8-a15
static constexpr uint8_t PORT_6 = 6; // 8 bit I/O. Shared with a16-a23
static constexpr uint8_t PORT_7 = 7; // 8 bit I/O. Shared with external memory & bus signals
static constexpr uint8_t PORT_8 = 8; // 7 bit I/O. Shared with chip-select signals
static constexpr uint8_t PORT_A = 9; // 5 bit I/O. Shared with external DRAM (channel 0)
static constexpr uint8_t PORT_B = 10; // 5 bit I/O. Shared with external DRAM (channel 1)
static constexpr uint8_t PORT_C = 11; // 2 bit I/O. Shared with outputs for 8-bit or 16-bit timers
static constexpr uint8_t PORT_D = 12; // 6 bit I/O. Shared with 16-bit timer I/O and interrupt input
static constexpr uint8_t PORT_E = 13; // 6 bit I/O. Shared with 8-bit or 16-bit timer output and interrupt input
static constexpr uint8_t PORT_F = 14; // 6 bit I/O. Shared with I/O functions of serial interface
static constexpr uint8_t PORT_G = 15; // 8 bit input-only. Shared with AD converter.
static constexpr uint8_t PORT_H = 16; // 5 bit I/O. Shared with /INT0 and micro DMA
static constexpr uint8_t PORT_Z = 17; // 8 bit I/O.
static constexpr uint8_t NUM_PORTS = 18;
static constexpr uint8_t TREG0 = 0;
static constexpr uint8_t TREG1 = 1;
static constexpr uint8_t TREG2 = 2;
static constexpr uint8_t TREG3 = 3;
static constexpr uint8_t TREG4 = 0;
static constexpr uint8_t TREG5 = 1;
static constexpr uint8_t TREG6 = 2;
static constexpr uint8_t TREG7 = 3;
static constexpr uint8_t TREG8 = 4;
static constexpr uint8_t TREG9 = 5;
static constexpr uint8_t TREGA = 6;
static constexpr uint8_t TREGB = 7;
static constexpr uint8_t CAP4 = 0;
static constexpr uint8_t CAP5 = 1;
static constexpr uint8_t CAP6 = 2;
static constexpr uint8_t CAP7 = 3;
static constexpr uint8_t CAP8 = 4;
static constexpr uint8_t CAP9 = 5;
static constexpr uint8_t CAPA = 6;
static constexpr uint8_t CAPB = 7;
public:
// device type constructor
tmp94c241_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
auto port0_read() { return m_port_read[PORT_0].bind(); }
auto port0_write() { return m_port_write[PORT_0].bind(); }
auto port1_read() { return m_port_read[PORT_1].bind(); }
auto port1_write() { return m_port_write[PORT_1].bind(); }
auto port2_read() { return m_port_read[PORT_2].bind(); }
auto port2_write() { return m_port_write[PORT_2].bind(); }
auto port3_read() { return m_port_read[PORT_3].bind(); }
auto port3_write() { return m_port_write[PORT_3].bind(); }
auto port4_read() { return m_port_read[PORT_4].bind(); }
auto port4_write() { return m_port_write[PORT_4].bind(); }
auto port5_read() { return m_port_read[PORT_5].bind(); }
auto port5_write() { return m_port_write[PORT_5].bind(); }
auto port6_read() { return m_port_read[PORT_6].bind(); }
auto port6_write() { return m_port_write[PORT_6].bind(); }
auto port7_read() { return m_port_read[PORT_7].bind(); }
auto port7_write() { return m_port_write[PORT_7].bind(); }
auto port8_read() { return m_port_read[PORT_8].bind(); }
auto port8_write() { return m_port_write[PORT_8].bind(); }
auto porta_read() { return m_port_read[PORT_A].bind(); }
auto porta_write() { return m_port_write[PORT_A].bind(); }
auto portb_read() { return m_port_read[PORT_B].bind(); }
auto portb_write() { return m_port_write[PORT_B].bind(); }
auto portc_read() { return m_port_read[PORT_C].bind(); }
auto portc_write() { return m_port_write[PORT_C].bind(); }
auto portd_read() { return m_port_read[PORT_D].bind(); }
auto portd_write() { return m_port_write[PORT_D].bind(); }
auto porte_read() { return m_port_read[PORT_E].bind(); }
auto porte_write() { return m_port_write[PORT_E].bind(); }
auto portf_read() { return m_port_read[PORT_F].bind(); }
auto portf_write() { return m_port_write[PORT_F].bind(); }
auto portg_read() { return m_port_read[PORT_G].bind(); }
auto porth_read() { return m_port_read[PORT_H].bind(); }
auto porth_write() { return m_port_write[PORT_H].bind(); }
auto portz_read() { return m_port_read[PORT_Z].bind(); }
auto portz_write() { return m_port_write[PORT_Z].bind(); }
protected:
// device_t implementation
virtual void device_config_complete() override ATTR_COLD;
virtual void device_resolve_objects() override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
// device_execute_interface overrides
virtual void execute_set_input(int inputnum, int state) override;
// tlcs900_device overrides
virtual void tlcs900_check_hdma() override;
virtual void tlcs900_check_irqs() override;
virtual void tlcs900_handle_ad() override;
virtual void tlcs900_handle_timers() override;
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
void change_timer_flipflop(uint8_t flipflop, uint8_t operation);
// Ports
template <uint8_t P> uint8_t port_r();
template <uint8_t P> void port_w(uint8_t data);
template <uint8_t P> void port_cr_w(uint8_t data);
template <uint8_t P> void port_fc_w(uint8_t data);
// Special Function Registers
template <uint8_t N> void bNcs_w(offs_t offset, uint16_t data, uint16_t mem_mask);
template <uint8_t Timer> uint16_t cap_r();
template <uint8_t N> uint8_t mamr_r();
template <uint8_t N> void mamr_w(uint8_t data);
template <uint8_t N> uint8_t msar_r();
template <uint8_t N> void msar_w(uint8_t data);
template <uint8_t Timer> void treg_8_w(uint8_t data);
template <uint8_t Timer> void treg_16_w(uint16_t data);
template <uint8_t Channel> uint8_t scNbuf_r();
template <uint8_t Channel> void scNbuf_w(uint8_t data);
template <uint8_t Channel> uint8_t scNcr_r();
template <uint8_t Channel> void scNcr_w(uint8_t data);
template <uint8_t Channel> uint8_t scNmod_r();
template <uint8_t Channel> void scNmod_w(uint8_t data);
template <uint8_t Channel> uint8_t brNcr_r();
template <uint8_t Channel> void brNcr_w(uint8_t data);
uint8_t t8run_r();
void t8run_w(uint8_t data);
uint8_t t01mod_r();
void t01mod_w(uint8_t data);
uint8_t tffcr_r();
void tffcr_w(uint8_t data);
uint8_t t23mod_r();
void t23mod_w(uint8_t data);
uint8_t trdc_r();
void trdc_w(uint8_t data);
uint8_t t4mod_r();
uint8_t t6mod_r();
uint8_t t8mod_r();
uint8_t tamod_r();
void t4mod_w(uint8_t data);
void t6mod_w(uint8_t data);
void t8mod_w(uint8_t data);
void tamod_w(uint8_t data);
uint8_t t4ffcr_r();
void t4ffcr_w(uint8_t data);
uint8_t t8ffcr_r();
void t8ffcr_w(uint8_t data);
uint8_t t6ffcr_r();
void t6ffcr_w(uint8_t data);
uint8_t taffcr_r();
void taffcr_w(uint8_t data);
uint8_t t16run_r();
void t16run_w(uint8_t data);
uint8_t wdmod_r();
void wdmod_w(uint8_t data);
void wdcr_w(uint8_t data);
uint8_t ode_r();
void ode_w(uint8_t data);
uint8_t admod1_r();
void admod1_w(uint8_t data);
uint8_t admod2_r();
void admod2_w(uint8_t data);
uint8_t adreg_r(offs_t offset);
uint8_t inte_r(offs_t offset);
void inte_w(offs_t offset, uint8_t data);
uint8_t intnmwdt_r(offs_t offset);
void intnmwdt_w(offs_t offset, uint8_t data);
void iimc_w(uint8_t data);
void intclr_w(uint8_t data);
void dmav_w(offs_t offset, uint8_t data);
uint8_t drefcr1_r();
void drefcr1_w(uint8_t data);
uint8_t dmemcr1_r();
void dmemcr1_w(uint8_t data);
uint8_t drefcr3_r();
void drefcr3_w(uint8_t data);
uint8_t dmemcr3_r();
void dmemcr3_w(uint8_t data);
uint8_t dadrv_r();
void dadrv_w(uint8_t data);
void dareg_w(offs_t offset, uint8_t data);
void internal_mem(address_map &map);
// analogue inputs, sampled at 10 bits
devcb_read16::array<8> m_an_read;
// I/O Ports
devcb_read8::array<NUM_PORTS> m_port_read;
devcb_write8::array<NUM_PORTS> m_port_write;
uint8_t m_port_latch[NUM_PORTS];
uint8_t m_port_control[NUM_PORTS];
uint8_t m_port_function[NUM_PORTS];
// Timer Control
bool m_timer_flipflops[12];
uint8_t m_t8run;
uint8_t m_t01mod;
uint8_t m_t23mod;
uint8_t m_t4mod;
uint8_t m_t6mod;
uint8_t m_t8mod;
uint8_t m_tamod;
uint8_t m_tffcr;
uint8_t m_t4ffcr;
uint8_t m_t6ffcr;
uint8_t m_t8ffcr;
uint8_t m_taffcr;
uint8_t m_trdc;
uint8_t m_t16run;
uint8_t m_treg_8[4]; // TREG0 - TREG3
uint16_t m_treg_16[8]; //TREG4 - TREGB
uint16_t m_t16_cap[8]; //CAP4 - CAPB
uint16_t m_timer_16[4]; // UPCOUNTERA - UPCOUNTERB
// Watchdog Timer
uint8_t m_watchdog_mode;
// Serial Channel
uint8_t m_serial_control[2];
uint8_t m_serial_mode[2];
uint8_t m_baud_rate[2];
uint8_t m_od_enable;
// A/D Converter Control
uint8_t m_ad_mode1;
uint8_t m_ad_mode2;
uint16_t m_ad_result[4];
// Interrupt Control
uint8_t m_int_reg[18];
uint8_t m_iimc;
uint8_t m_dma_vector[4];
// Chip Select/Wait Control
uint16_t m_block_cs[6];
uint8_t m_external_cs;
uint8_t m_msar[6];
uint8_t m_mamr[6];
// DRAM Control
uint8_t m_dram_refresh[2];
uint8_t m_dram_access[2];
// D/A Converter Control
uint8_t m_da_drive;
};
// device type declaration
DECLARE_DEVICE_TYPE(TMP94C241, tmp94c241_device)
#endif // MAME_CPU_TLCS900_TMP94C241_H

View File

@ -191,6 +191,15 @@ void tmp95c061_device::device_config_complete()
}
void tmp95c061_device::device_resolve_objects()
{
m_nmi_state = CLEAR_LINE;
for( int i = 0; i < TLCS900_NUM_INPUTS; i++ )
{
m_level[i] = CLEAR_LINE;
}
}
void tmp95c061_device::device_start()
{
@ -239,7 +248,6 @@ void tmp95c061_device::device_reset()
m_to3 = 0;
m_ad_cycles_left = 0;
m_nmi_state = CLEAR_LINE;
m_timer_pre = 0;
m_timer_change[0] = 0;
m_timer_change[1] = 0;
@ -289,11 +297,6 @@ void tmp95c061_device::device_reset()
std::fill_n(&m_mem_start_mask[0], 4, 0xff);
m_dram_refresh = 0x00;
m_dram_access = 0x80;
for (int i = 0; i < TLCS900_NUM_INPUTS; i++)
{
m_level[i] = CLEAR_LINE;
}
}
enum
@ -492,11 +495,6 @@ void tmp95c061_device::tlcs900_check_hdma()
void tmp95c061_device::tlcs900_check_irqs()
{
int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int level = 0;
int irq = -1;
int i;
/* Check for NMI */
if ( m_nmi_state == ASSERT_LINE )
{
@ -516,7 +514,8 @@ void tmp95c061_device::tlcs900_check_irqs()
}
/* Check regular irqs */
for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
for( int i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c061_irq_vector_map[i].reg] & tmp95c061_irq_vector_map[i].iff )
{
@ -533,7 +532,9 @@ void tmp95c061_device::tlcs900_check_irqs()
}
/* Check highest allowed priority irq */
for ( i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
int irq = -1;
int level = 0;
for ( int i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
{
if ( irq_vectors[i] >= 0 )
{
@ -690,8 +691,8 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[0] > 0; m_timer_change[0]-- )
{
m_timer[0] += 1;
if ( m_timer[0] == m_t8_reg[0] )
m_timer_8[0] += 1;
if ( m_timer_8[0] == m_t8_reg[0] )
{
if ( ( m_trun & 0x02 ) && ( m_t8_mode[0] & 0x0c ) == 0x00 )
{
@ -701,7 +702,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
m_int_reg[INTET10] |= 0x08;
}
}
@ -728,10 +729,10 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[1] > 0; m_timer_change[1]-- )
{
m_timer[1] += 1;
if ( m_timer[1] == m_t8_reg[1] )
m_timer_8[1] += 1;
if ( m_timer_8[1] == m_t8_reg[1] )
{
m_timer[1] = 0;
m_timer_8[1] = 0;
m_int_reg[INTET10] |= 0x80;
if ( m_t8_invert & 0x02 )
@ -742,7 +743,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 0 */
if ( ( m_t8_mode[0] & 0xc0 ) == 0x40 )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
}
}
}
@ -767,8 +768,8 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[2] > 0; m_timer_change[2]-- )
{
m_timer[2] += 1;
if ( m_timer[2] == m_t8_reg[2] )
m_timer_8[2] += 1;
if ( m_timer_8[2] == m_t8_reg[2] )
{
if ( ( m_trun & 0x08 ) && ( m_t8_mode[1] & 0x0c ) == 0x00 )
{
@ -778,7 +779,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
m_int_reg[INTET32] |= 0x08;
}
}
@ -805,10 +806,10 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[3] > 0; m_timer_change[3]-- )
{
m_timer[3] += 1;
if ( m_timer[3] == m_t8_reg[3] )
m_timer_8[3] += 1;
if ( m_timer_8[3] == m_t8_reg[3] )
{
m_timer[3] = 0;
m_timer_8[3] = 0;
m_int_reg[INTET32] |= 0x80;
if ( m_t8_invert & 0x20 )
@ -819,7 +820,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 2 */
if ( ( m_t8_mode[1] & 0xc0 ) == 0x40 )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
}
}
}
@ -916,28 +917,28 @@ void tmp95c061_device::trun_w(uint8_t data)
{
if ( ! ( data & 0x01 ) )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
m_timer_change[0] = 0;
}
if ( ! ( data & 0x02 ) )
{
m_timer[1] = 0;
m_timer_8[1] = 0;
m_timer_change[1] = 0;
}
if ( ! ( data & 0x04 ) )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
m_timer_change[2] = 0;
}
if ( ! ( data & 0x08 ) )
{
m_timer[3] = 0;
m_timer_8[3] = 0;
m_timer_change[3] = 0;
}
if ( ! ( data & 0x10 ) )
m_timer[4] = 0;
m_timer_8[4] = 0;
if ( ! ( data & 0x20 ) )
m_timer[5] = 0;
m_timer_8[5] = 0;
m_trun = data;
}

View File

@ -47,7 +47,8 @@ public:
template <size_t Bit> auto an_read() { return m_an_read[Bit].bind(); }
protected:
virtual void device_config_complete() override;
virtual void device_config_complete() override ATTR_COLD;
virtual void device_resolve_objects() override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;

View File

@ -271,8 +271,8 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[0] > 0; m_timer_change[0]-- )
{
m_timer[0] += 1;
if ( m_timer[0] == m_t8_reg[0] )
m_timer_8[0] += 1;
if ( m_timer_8[0] == m_t8_reg[0] )
{
if ( ( m_t8run & 0x02 ) && ( m_t8_mode[0] & 0x0c ) == 0x00 )
{
@ -282,7 +282,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
m_int_reg[INTET01] |= 0x08;
}
}
@ -309,10 +309,10 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[1] > 0; m_timer_change[1]-- )
{
m_timer[1] += 1;
if ( m_timer[1] == m_t8_reg[1] )
m_timer_8[1] += 1;
if ( m_timer_8[1] == m_t8_reg[1] )
{
m_timer[1] = 0;
m_timer_8[1] = 0;
m_int_reg[INTET01] |= 0x80;
if ( m_t8_invert[0] & 0x02 )
@ -323,7 +323,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 0 */
if ( ( m_t8_mode[0] & 0xc0 ) == 0x40 )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
}
}
}
@ -348,8 +348,8 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[2] > 0; m_timer_change[2]-- )
{
m_timer[2] += 1;
if ( m_timer[2] == m_t8_reg[2] )
m_timer_8[2] += 1;
if ( m_timer_8[2] == m_t8_reg[2] )
{
if ( ( m_t8run & 0x08 ) && ( m_t8_mode[1] & 0x0c ) == 0x00 )
{
@ -359,7 +359,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
m_int_reg[INTET23] |= 0x08;
}
}
@ -386,10 +386,10 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[3] > 0; m_timer_change[3]-- )
{
m_timer[3] += 1;
if ( m_timer[3] == m_t8_reg[3] )
m_timer_8[3] += 1;
if ( m_timer_8[3] == m_t8_reg[3] )
{
m_timer[3] = 0;
m_timer_8[3] = 0;
m_int_reg[INTET23] |= 0x80;
if ( m_t8_invert[1] & 0x20 )
@ -400,7 +400,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 2 */
if ( ( m_t8_mode[1] & 0xc0 ) == 0x40 )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
}
}
}
@ -416,11 +416,6 @@ void tmp95c063_device::tlcs900_check_hdma()
void tmp95c063_device::tlcs900_check_irqs()
{
int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int level = 0;
int irq = -1;
int i;
/* Check for NMI */
if ( m_nmi_state == ASSERT_LINE )
{
@ -440,7 +435,8 @@ void tmp95c063_device::tlcs900_check_irqs()
}
/* Check regular irqs */
for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
for( int i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c063_irq_vector_map[i].reg] & tmp95c063_irq_vector_map[i].iff )
{
@ -457,7 +453,9 @@ void tmp95c063_device::tlcs900_check_irqs()
}
/* Check highest allowed priority irq */
for ( i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
int irq = -1;
int level = 0;
for ( int i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
{
if ( irq_vectors[i] >= 0 )
{
@ -557,6 +555,15 @@ void tmp95c063_device::tlcs900_handle_ad()
}
void tmp95c063_device::device_resolve_objects()
{
m_nmi_state = CLEAR_LINE;
for( int i = 0; i < TLCS900_NUM_INPUTS; i++ )
{
m_level[i] = CLEAR_LINE;
}
}
void tmp95c063_device::device_start()
{
tlcs900h_device::device_start();
@ -602,7 +609,6 @@ void tmp95c063_device::device_reset()
tlcs900h_device::device_reset();
m_ad_cycles_left = 0;
m_nmi_state = CLEAR_LINE;
m_timer_pre = 0;
m_timer_change[0] = 0;
m_timer_change[1] = 0;
@ -655,9 +661,6 @@ void tmp95c063_device::device_reset()
std::fill_n(&m_dram_refresh[0], 2, 0x00);
std::fill_n(&m_dram_access[0], 2, 0x80);
m_da_drive = 0x00;
for (int i = 0; i < TLCS900_NUM_INPUTS; i++)
m_level[i] = CLEAR_LINE;
}
uint8_t tmp95c063_device::t8run_r()
@ -669,28 +672,28 @@ void tmp95c063_device::t8run_w(uint8_t data)
{
if ( ! ( data & 0x01 ) )
{
m_timer[0] = 0;
m_timer_8[0] = 0;
m_timer_change[0] = 0;
}
if ( ! ( data & 0x02 ) )
{
m_timer[1] = 0;
m_timer_8[1] = 0;
m_timer_change[1] = 0;
}
if ( ! ( data & 0x04 ) )
{
m_timer[2] = 0;
m_timer_8[2] = 0;
m_timer_change[2] = 0;
}
if ( ! ( data & 0x08 ) )
{
m_timer[3] = 0;
m_timer_8[3] = 0;
m_timer_change[3] = 0;
}
if ( ! ( data & 0x10 ) )
m_timer[4] = 0;
m_timer_8[4] = 0;
if ( ! ( data & 0x20 ) )
m_timer[5] = 0;
m_timer_8[5] = 0;
m_t8run = data;
}

View File

@ -57,7 +57,8 @@ public:
template <size_t Bit> auto an_read() { return m_an_read[Bit].bind(); }
protected:
virtual void device_config_complete() override;
virtual void device_config_complete() override ATTR_COLD;
virtual void device_resolve_objects() override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;

View File

@ -7,7 +7,7 @@
******************************************************************************/
#include "emu.h"
#include "cpu/tlcs900/tmp95c061.h" // TODO: tmp94c241.h
#include "cpu/tlcs900/tmp94c241.h"
#include "imagedev/floppy.h"
#include "machine/gen_latch.h"
#include "machine/upd765.h"
@ -109,8 +109,8 @@ public:
void kn5000(machine_config &config);
private:
required_device<tmp95c061_device> m_maincpu;
required_device<tmp95c061_device> m_subcpu;
required_device<tmp94c241_device> m_maincpu;
required_device<tmp94c241_device> m_subcpu;
required_device<generic_latch_8_device> m_maincpu_latch;
required_device<generic_latch_8_device> m_subcpu_latch;
required_device<upd72067_device> m_fdc;
@ -197,6 +197,37 @@ static INPUT_PORTS_START(kn5000)
PORT_DIPSETTING( 0xb0, "PC2")
PORT_DIPSETTING( 0x70, "Mac")
PORT_START("AREA")
PORT_DIPNAME(0x06, 0x06, "Area Selection")
PORT_DIPSETTING( 0x02, "Thailand, Indonesia, Iran, U.A.E., Panama, Argentina, Peru, Brazil")
PORT_DIPSETTING( 0x04, "USA, Mexico")
PORT_DIPSETTING( 0x06, "Other")
/*
Actual full list of regions (but it is unclear if there's any
other hardware difference among them):
PORT_DIPSETTING( 0x04, "(M): U.S.A.")
PORT_DIPSETTING( 0x06, "(MC): Canada")
PORT_DIPSETTING( 0x04, "(XM): Mexico")
PORT_DIPSETTING( 0x06, "(EN): Norway, Sweden, Denmark, Finland")
PORT_DIPSETTING( 0x06, "(EH): Holland, Belgium")
PORT_DIPSETTING( 0x06, "(EF): France, Italy")
PORT_DIPSETTING( 0x06, "(EZ): Germany")
PORT_DIPSETTING( 0x06, "(EW): Switzerland")
PORT_DIPSETTING( 0x06, "(EA): Austria")
PORT_DIPSETTING( 0x06, "(EP): Spain, Portugal, Greece, South Africa")
PORT_DIPSETTING( 0x06, "(EK): United Kingdom")
PORT_DIPSETTING( 0x06, "(XL): New Zealand")
PORT_DIPSETTING( 0x06, "(XR): Australia")
PORT_DIPSETTING( 0x06, "(XS): Malaysia")
PORT_DIPSETTING( 0x06, "(MD): Saudi Arabia, Hong Kong, Kuwait")
PORT_DIPSETTING( 0x06, "(XT): Taiwan")
PORT_DIPSETTING( 0x02, "(X): Thailand, Indonesia, Iran, U.A.E., Panama, Argentina, Peru, Brazil")
PORT_DIPSETTING( 0x06, "(XP): Philippines")
PORT_DIPSETTING( 0x06, "(XW): Singapore")
*/
PORT_START("CPR_SEG0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
@ -604,7 +635,7 @@ void kn5000_state::machine_reset()
void kn5000_state::kn5000(machine_config &config)
{
// Note: The CPU has an internal clock doubler
TMP95C061(config, m_maincpu, 2 * 8_MHz_XTAL); // actual cpu is TMP94C241F @ IC5
TMP94C241(config, m_maincpu, 2 * 8_MHz_XTAL); // TMP94C241F @ IC5
// Address bus is set to 32 bits by the pins AM1=+5v and AM0=GND
m_maincpu->set_addrmap(AS_PROGRAM, &kn5000_state::maincpu_mem);
// Interrupt 4: FDCINT
@ -636,14 +667,16 @@ void kn5000_state::kn5000(machine_config &config)
// MAINCPU PORT C:
// bit 0 (input) = "check terminal" switch
// bit 1 (output) = "check terminal" LED
// TODO: m_maincpu->portc_read().set([this] { return ioport("CN11")->read(); });
// TODO: m_maincpu->portc_write().set([this] (u8 data) { m_checking_device_led_cn11 = (BIT(data, 1) == 0); });
m_maincpu->portc_read().set_ioport("CN11");
m_maincpu->portc_write().set([this] (u8 data) {
m_checking_device_led_cn11 = (BIT(data, 1) == 0);
});
// MAINCPU PORT D:
// bit 0 (output) = FDCRST
// bit 6 (input) = FD.I/O
// TODO: m_maincpu->portd_write().set([this] (u8 data) { m_fdc->reset_w(BIT(data, 0)); });
m_maincpu->portd_write().set(m_fdc, FUNC(upd72067_device::reset_w)).bit(0);
// TODO: bit 6!
@ -651,7 +684,7 @@ void kn5000_state::kn5000(machine_config &config)
// bit 0 (input) = +5v
// bit 2 (input) = HDDRDY
// bit 4 (?) = MICSNS
// TODO: m_maincpu->porte_read().set([] { return 1; }); //checked at EF05A6 (v10 ROM)
m_maincpu->porte_read().set_constant(1); //checked at EF05A6 (v10 ROM)
// FIXME: Bit 0 should only be 1 if the
// optional hard-drive extension board is disabled;
@ -670,10 +703,7 @@ void kn5000_state::kn5000(machine_config &config)
// MAINCPU PORT H:
// bit 1 = TC1 Terminal count - microDMA
// TODO: m_maincpu->porth_read().set([] { return 2; }); // area/region detection: checked at EF083E (v10 ROM)
// FIXME: These are resistors on the pcb, but could be declared
// in the driver as a 2 bit DIP-Switch for area/region selection.
m_maincpu->porth_read().set_ioport("AREA"); // checked at EF083E (v10 ROM)
// MAINCPU PORT Z:
@ -701,15 +731,18 @@ void kn5000_state::kn5000(machine_config &config)
// AN1 = AFT
// Note: The CPU has an internal clock doubler
TMP95C061(config, m_subcpu, 2*10_MHz_XTAL); // actual cpu is TMP94C241F @ IC27
TMP94C241(config, m_subcpu, 2*10_MHz_XTAL); // TMP94C241F @ IC27
// Address bus is set to 8 bits by the pins AM1=GND and AM0=GND
m_subcpu->set_addrmap(AS_PROGRAM, &kn5000_state::subcpu_mem);
// SUBCPU PORT C:
// bit 0 (input) = "check terminal" switch
// bit 1 (output) = "check terminal" LED
// TODO: m_subcpu->portc_read().set([this] { return ioport("CN12")->read(); });
// TODO: m_subcpu->portc_write().set([this] (u8 data) { m_checking_device_led_cn12 = (BIT(data, 1) == 0); });
m_subcpu->portc_read().set_ioport("CN12");
m_subcpu->portc_write().set([this] (u8 data) {
m_checking_device_led_cn12 = (BIT(data, 1) == 0);
});
// SUBCPU PORT D:
// bit 0 = (output) SSTAT0
@ -717,12 +750,12 @@ void kn5000_state::kn5000(machine_config &config)
// bit 2 = (input) MSTAT0
// bit 3 (not used)
// bit 4 = (input) MSTAT1
// TODO: m_subcpu->portd_read().set([this] {
// TODO: return (BIT(m_mstat, 0) << 2) | (BIT(m_mstat, 1) << 4);
// TODO: });
// TODO: m_subcpu->portd_write().set([this] (u8 data) {
// TODO: m_sstat = data & 3;
// TODO: });
m_subcpu->portd_read().set([this] {
return (BIT(m_mstat, 0) << 2) | (BIT(m_mstat, 1) << 4);
});
m_subcpu->portd_write().set([this] (u8 data) {
m_sstat = data & 3;
});
GENERIC_LATCH_8(config, m_maincpu_latch); // @ IC23