diff options
author | 2017-06-22 18:21:28 -0400 | |
---|---|---|
committer | 2017-06-22 18:29:16 -0400 | |
commit | aa191bfe6b78f6670647dd09e8c44f6c6f705484 (patch) | |
tree | b1a0b7eb403ceca14b6831a1a09ed08c6525494f /src/devices/cpu/s2650 | |
parent | 137a83532ba2c0f012d89a507fe688a4bcd81075 (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.cpp | 67 | ||||
-rw-r--r-- | src/devices/cpu/s2650/s2650.h | 24 |
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(); |