summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/s2650
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2017-06-22 18:21:28 -0400
committer AJR <ajrhacker@users.noreply.github.com>2017-06-22 18:29:16 -0400
commitaa191bfe6b78f6670647dd09e8c44f6c6f705484 (patch)
treeb1a0b7eb403ceca14b6831a1a09ed08c6525494f /src/devices/cpu/s2650
parent137a83532ba2c0f012d89a507fe688a4bcd81075 (diff)
s2650: I/O modernization
- Replace fake S2650_SENSE_PORT address with line read callback (set_input_line should also work). There are still some doubts regarding whether VBLANK should be inverted in various drivers. - Replace fake S2650_CTRL_PORT and S2650_DATA_PORT addresses with... well, these aren't dedicated parallel ports, so they actually haven't gone away. They have, however, been moved to a new 1-bit address space, since the ports share the main data bus and are distinguished from each other by an address line.
Diffstat (limited to 'src/devices/cpu/s2650')
-rw-r--r--src/devices/cpu/s2650/s2650.cpp67
-rw-r--r--src/devices/cpu/s2650/s2650.h24
2 files changed, 61 insertions, 30 deletions
diff --git a/src/devices/cpu/s2650/s2650.cpp b/src/devices/cpu/s2650/s2650.cpp
index 6f4dc66c016..702ed83906a 100644
--- a/src/devices/cpu/s2650/s2650.cpp
+++ b/src/devices/cpu/s2650/s2650.cpp
@@ -31,10 +31,12 @@ DEFINE_DEVICE_TYPE(S2650, s2650_device, "s2650", "S2650")
s2650_device::s2650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, S2650, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 15)
- , m_io_config("io", ENDIANNESS_LITTLE, 8, 9)
+ , m_io_config("io", ENDIANNESS_LITTLE, 8, 8)
+ , m_data_config("io", ENDIANNESS_LITTLE, 8, 1)
+ , m_sense_handler(*this)
, m_flag_handler(*this), m_intack_handler(*this)
, m_ppc(0), m_page(0), m_iar(0), m_ea(0), m_psl(0), m_psu(0), m_r(0)
- , m_halt(0), m_ir(0), m_irq_state(0), m_icount(0), m_program(nullptr), m_direct(nullptr), m_io(nullptr)
+ , m_halt(0), m_ir(0), m_irq_state(0), m_icount(0), m_direct(nullptr)
, m_debugger_temp(0)
{
memset(m_reg, 0x00, sizeof(m_reg));
@@ -48,6 +50,26 @@ offs_t s2650_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u
}
+const address_space_config *s2650_device::memory_space_config(address_spacenum spacenum) const
+{
+ switch (spacenum)
+ {
+ // Memory-mapped: M/~IO=1
+ case AS_PROGRAM: return &m_program_config;
+
+ // Extended I/O: M/~IO=0 ADR13(E)=1 ADR14=Don't Care
+ case AS_IO: return &m_io_config;
+
+ // Non-extended I/O: M/~IO=0 ADR13(~NE)=0 ADR14=D/~C
+ // "The D/~C line can be used as a 1-bit device address in simple systems."
+ // -- Signetics 2650 Microprocessor databook, page 41
+ case AS_DATA: return &m_data_config;
+
+ default: return nullptr;
+ }
+}
+
+
/* condition code changes for a byte */
static const uint8_t ccc[0x200] = {
0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
@@ -145,7 +167,7 @@ static const int S2650_relative[0x100] =
* RDMEM
* read memory byte from addr
***************************************************************/
-#define RDMEM(addr) m_program->read_byte(addr)
+#define RDMEM(addr) space(AS_PROGRAM).read_byte(addr)
inline void s2650_device::set_psu(uint8_t new_val)
{
@@ -156,6 +178,19 @@ inline void s2650_device::set_psu(uint8_t new_val)
m_flag_handler((new_val & FO) ? 1 : 0);
}
+inline uint8_t s2650_device::get_psu()
+{
+ if (!m_sense_handler.isnull())
+ {
+ if (m_sense_handler())
+ m_psu |= SI;
+ else
+ m_psu &= ~SI;
+ }
+
+ return m_psu;
+}
+
inline uint8_t s2650_device::get_sp()
{
return (m_psu & SP);
@@ -528,7 +563,7 @@ inline uint8_t s2650_device::ARG()
* Store source register to memory addr (CC unchanged)
***************************************************************/
#define M_STR(address,source) \
- m_program->write_byte(address, source)
+ space(AS_PROGRAM).write_byte(address, source)
/***************************************************************
* M_AND
@@ -673,7 +708,7 @@ inline uint8_t s2650_device::ARG()
***************************************************************/
#define M_SPSU() \
{ \
- R0 = ((m_psu & ~PSU34) | (m_io->read_byte(S2650_SENSE_PORT) ? SI : 0)); \
+ R0 = get_psu() & ~PSU34; \
SET_CC(R0); \
}
@@ -742,7 +777,7 @@ inline uint8_t s2650_device::ARG()
#define M_TPSU() \
{ \
uint8_t tpsu = ARG(); \
- uint8_t rpsu = (m_psu | (m_io->read_byte(S2650_SENSE_PORT) ? SI : 0)); \
+ uint8_t rpsu = get_psu(); \
m_psl &= ~CC; \
if( (rpsu & tpsu) != tpsu ) \
m_psl |= 0x80; \
@@ -787,12 +822,11 @@ static void BRA_EA(void) _BRA_EA()
void s2650_device::device_start()
{
+ m_sense_handler.resolve();
m_flag_handler.resolve_safe();
m_intack_handler.resolve_safe();
- m_program = &space(AS_PROGRAM);
- m_direct = &m_program->direct();
- m_io = &space(AS_IO);
+ m_direct = &space(AS_PROGRAM).direct();
save_item(NAME(m_ppc));
save_item(NAME(m_page));
@@ -913,9 +947,6 @@ void s2650_device::device_reset()
memset(m_reg, 0, sizeof(m_reg));
memset(m_ras, 0, sizeof(m_ras));
- m_program = &space(AS_PROGRAM);
- m_direct = &m_program->direct();
- m_io = &space(AS_IO);
m_psl = COM | WC;
/* force write */
m_psu = 0xff;
@@ -1095,7 +1126,7 @@ void s2650_device::execute_run()
case 0x32: /* REDC,2 */
case 0x33: /* REDC,3 */
m_icount -= 6;
- m_reg[m_r] = m_io->read_byte(S2650_CTRL_PORT);
+ m_reg[m_r] = space(AS_DATA).read_byte(S2650_CTRL_PORT);
SET_CC( m_reg[m_r] );
break;
@@ -1185,7 +1216,7 @@ void s2650_device::execute_run()
case 0x56: /* REDE,2 v */
case 0x57: /* REDE,3 v */
m_icount -= 9;
- m_reg[m_r] = m_io->read_byte( ARG() );
+ m_reg[m_r] = space(AS_IO).read_byte(ARG());
SET_CC(m_reg[m_r]);
break;
@@ -1244,7 +1275,7 @@ void s2650_device::execute_run()
case 0x72: /* REDD,2 */
case 0x73: /* REDD,3 */
m_icount -= 6;
- m_reg[m_r] = m_io->read_byte(S2650_DATA_PORT);
+ m_reg[m_r] = space(AS_DATA).read_byte(S2650_DATA_PORT);
SET_CC(m_reg[m_r]);
break;
@@ -1400,7 +1431,7 @@ void s2650_device::execute_run()
case 0xb2: /* WRTC,2 */
case 0xb3: /* WRTC,3 */
m_icount -= 6;
- m_io->write_byte(S2650_CTRL_PORT,m_reg[m_r]);
+ space(AS_DATA).write_byte(S2650_CTRL_PORT,m_reg[m_r]);
break;
case 0xb4: /* TPSU */
@@ -1486,7 +1517,7 @@ void s2650_device::execute_run()
case 0xd6: /* WRTE,2 v */
case 0xd7: /* WRTE,3 v */
m_icount -= 9;
- m_io->write_byte( ARG(), m_reg[m_r] );
+ space(AS_IO).write_byte( ARG(), m_reg[m_r] );
break;
case 0xd8: /* BIRR,0 (*)a */
@@ -1544,7 +1575,7 @@ void s2650_device::execute_run()
case 0xf2: /* WRTD,2 */
case 0xf3: /* WRTD,3 */
m_icount -= 6;
- m_io->write_byte(S2650_DATA_PORT, m_reg[m_r]);
+ space(AS_DATA).write_byte(S2650_DATA_PORT, m_reg[m_r]);
break;
case 0xf4: /* TMI,0 v */
diff --git a/src/devices/cpu/s2650/s2650.h b/src/devices/cpu/s2650/s2650.h
index 818fd57b300..119f7f9b38f 100644
--- a/src/devices/cpu/s2650/s2650.h
+++ b/src/devices/cpu/s2650/s2650.h
@@ -15,20 +15,21 @@ enum
S2650_HALT, S2650_SI, S2650_FO
};
-/* fake I/O space ports */
+// D/~C (A14) single-bit addresses for non-extended I/O ports
enum
{
- S2650_EXT_PORT = 0x00ff, /* M/~IO=0 D/~C=x E/~NE=1 */
- S2650_CTRL_PORT = 0x0100, /* M/~IO=0 D/~C=0 E/~NE=0 */
- S2650_DATA_PORT = 0x0101, /* M/~IO=0 D/~C=1 E/~NE=0 */
- S2650_SENSE_PORT = 0x0102 /* Fake Sense Line */
+ S2650_CTRL_PORT = 0,
+ S2650_DATA_PORT = 1
};
DECLARE_DEVICE_TYPE(S2650, s2650_device)
-#define MCFG_S2650_FLAG_HANDLER(_devcb) \
+#define MCFG_S2650_SENSE_INPUT(_devcb) \
+ devcb = &s2650_device::set_sense_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_S2650_FLAG_OUTPUT(_devcb) \
devcb = &s2650_device::set_flag_handler(*device, DEVCB_##_devcb);
#define MCFG_S2650_INTACK_HANDLER(_devcb) \
@@ -41,6 +42,7 @@ public:
s2650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// static configuration helpers
+ template <class Object> static devcb_base &set_sense_handler(device_t &device, Object &&cb) { return downcast<s2650_device &>(device).m_sense_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_flag_handler(device_t &device, Object &&cb) { return downcast<s2650_device &>(device).m_flag_handler.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_intack_handler(device_t &device, Object &&cb) { return downcast<s2650_device &>(device).m_intack_handler.set_callback(std::forward<Object>(cb)); }
@@ -58,10 +60,7 @@ protected:
virtual void execute_set_input(int inputnum, int state) override;
// device_memory_interface overrides
- virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override
- {
- return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : nullptr );
- }
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override;
// device_state_interface overrides
virtual void state_import(const device_state_entry &entry) override;
@@ -76,7 +75,9 @@ protected:
private:
address_space_config m_program_config;
address_space_config m_io_config;
+ address_space_config m_data_config;
+ devcb_read_line m_sense_handler;
devcb_write_line m_flag_handler;
devcb_write_line m_intack_handler;
@@ -94,14 +95,13 @@ private:
uint8_t m_irq_state;
int m_icount;
- address_space *m_program;
direct_read_data *m_direct;
- address_space *m_io;
// For debugger
uint16_t m_debugger_temp;
inline void set_psu(uint8_t new_val);
+ inline uint8_t get_psu();
inline uint8_t get_sp();
inline void set_sp(uint8_t new_sp);
inline int check_irq_line();