From 1f53ff94c649d7ac52a3674eb9e9e38aee8fdae7 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 21 Feb 2024 17:27:22 -0500 Subject: [PATCH] pic16c62x: Core overhaul - Use callbacks rather than address space for I/O ports - Eliminate unsafe use of get_write_ptr and let the internal memory map decode each special register individually - Eliminate several macros, magic ID numbers and some unnecessary tables - Adjust execution of a few opcodes to avoid reading operands twice and set flags correctly - Add PCLATH to state display --- src/devices/cpu/pic16c62x/pic16c62x.cpp | 700 +++++++++++++----------- src/devices/cpu/pic16c62x/pic16c62x.h | 82 ++- src/mame/sega/naomigd.cpp | 29 +- src/mame/sega/naomigd.h | 5 +- 4 files changed, 467 insertions(+), 349 deletions(-) diff --git a/src/devices/cpu/pic16c62x/pic16c62x.cpp b/src/devices/cpu/pic16c62x/pic16c62x.cpp index 1f956508107..22914038a2d 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.cpp +++ b/src/devices/cpu/pic16c62x/pic16c62x.cpp @@ -85,86 +85,97 @@ void pic16c62x_device::pic16c62x_rom_11(address_map &map) map(0x000, 0x7ff).rom(); } +void pic16c62x_device::core_regs(address_map &map) +{ + map(0x01, 0x01).rw(FUNC(pic16c62x_device::tmr0_r), FUNC(pic16c62x_device::tmr0_w)); + map(0x02, 0x02).mirror(0x80).rw(FUNC(pic16c62x_device::pcl_r), FUNC(pic16c62x_device::pcl_w)); + map(0x03, 0x03).mirror(0x80).rw(FUNC(pic16c62x_device::status_r), FUNC(pic16c62x_device::status_w)); + map(0x04, 0x04).mirror(0x80).rw(FUNC(pic16c62x_device::fsr_r), FUNC(pic16c62x_device::fsr_w)); + map(0x05, 0x05).rw(FUNC(pic16c62x_device::porta_r), FUNC(pic16c62x_device::porta_w)); + map(0x06, 0x06).rw(FUNC(pic16c62x_device::portb_r), FUNC(pic16c62x_device::portb_w)); + map(0x0a, 0x0a).mirror(0x80).rw(FUNC(pic16c62x_device::pclath_r), FUNC(pic16c62x_device::pclath_w)); + map(0x0b, 0x0b).mirror(0x80).rw(FUNC(pic16c62x_device::intcon_r), FUNC(pic16c62x_device::intcon_w)); + map(0x0c, 0x0c).rw(FUNC(pic16c62x_device::pir1_r), FUNC(pic16c62x_device::pir1_w)); + map(0x1f, 0x1f).rw(FUNC(pic16c62x_device::cmcon_r), FUNC(pic16c62x_device::cmcon_w)); + map(0x81, 0x81).rw(FUNC(pic16c62x_device::option_r), FUNC(pic16c62x_device::option_w)); + map(0x85, 0x85).rw(FUNC(pic16c62x_device::trisa_r), FUNC(pic16c62x_device::trisa_w)); + map(0x86, 0x86).rw(FUNC(pic16c62x_device::trisb_r), FUNC(pic16c62x_device::trisb_w)); + map(0x8c, 0x8c).rw(FUNC(pic16c62x_device::pie1_r), FUNC(pic16c62x_device::pie1_w)); + map(0x8e, 0x8e).rw(FUNC(pic16c62x_device::pcon_r), FUNC(pic16c62x_device::pcon_w)); + map(0x9f, 0x9f).rw(FUNC(pic16c62x_device::vrcon_r), FUNC(pic16c62x_device::vrcon_w)); +} + void pic16c62x_device::pic16c620_ram(address_map &map) { - map(0x00, 0x06).ram(); - map(0x0a, 0x0c).ram(); - map(0x1f, 0x6f).ram(); - map(0x80, 0x86).ram(); - map(0x8a, 0x8e).ram(); - map(0x9f, 0x9f).ram(); + core_regs(map); + map(0x20, 0x6f).ram(); } void pic16c62x_device::pic16c622_ram(address_map &map) { - map(0x00, 0x06).ram(); - map(0x0a, 0x0c).ram(); - map(0x1f, 0x7f).ram(); - map(0x80, 0x86).ram(); - map(0x8a, 0x8e).ram(); - map(0x9f, 0xbf).ram(); + core_regs(map); + map(0x20, 0x7f).ram(); + map(0xa0, 0xbf).ram(); } -// pic16c620a, pic16c621a and pic16c622a -void pic16c62x_device::pic16c62xa_ram(address_map &map) +void pic16c62x_device::pic16c620a_ram(address_map &map) { - map(0x00, 0x06).ram(); - map(0x0a, 0x0c).ram(); - map(0x1f, 0x6f).ram(); - map(0x70, 0x7f).ram().share(nullptr); - map(0x80, 0x86).ram(); - map(0x8a, 0x8e).ram(); - map(0x9f, 0xbf).ram(); - map(0xf0, 0xff).ram().share(nullptr); + core_regs(map); + map(0x20, 0x6f).ram(); + map(0x70, 0x7f).mirror(0x80).ram(); +} + +void pic16c62x_device::pic16c622a_ram(address_map &map) +{ + core_regs(map); + map(0x20, 0x6f).ram(); + map(0x70, 0x7f).mirror(0x80).ram(); + map(0xa0, 0xbf).ram(); } -pic16c62x_device::pic16c62x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int picmodel) +pic16c62x_device::pic16c62x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, address_map_constructor ram_map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 16, program_width, -1 , ( ( program_width == 9 ) ? address_map_constructor(FUNC(pic16c62x_device::pic16c62x_rom_9), this) : ( ( program_width == 10 ) ? address_map_constructor(FUNC(pic16c62x_device::pic16c62x_rom_10), this) : address_map_constructor(FUNC(pic16c62x_device::pic16c62x_rom_11), this) ))) - , m_data_config("data", ENDIANNESS_LITTLE, 8, 8, 0 - , ( ( picmodel == 0x16C620 || picmodel == 0x16C621 ) ? address_map_constructor(FUNC(pic16c62x_device::pic16c620_ram), this) : - ( ( picmodel == 0x16C622 ) ? address_map_constructor(FUNC(pic16c62x_device::pic16c622_ram), this) : - address_map_constructor(FUNC(pic16c62x_device::pic16c62xa_ram), this) ) ) ) - , m_io_config("io", ENDIANNESS_LITTLE, 8, 5, 0) + , m_data_config("data", ENDIANNESS_LITTLE, 8, 8, 0, ram_map) , m_CONFIG(0x3fff) , m_reset_vector(0x0) - , m_picmodel(picmodel) - , m_picRAMmask(0xff) + , m_read_port(*this, 0) + , m_write_port(*this) { } pic16c620_device::pic16c620_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C620, tag, owner, clock, 9, 0x16C620) + : pic16c62x_device(mconfig, PIC16C620, tag, owner, clock, 9, address_map_constructor(FUNC(pic16c620_device::pic16c620_ram), this)) { } pic16c620a_device::pic16c620a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C620A, tag, owner, clock, 9, 0x16C620A) + : pic16c62x_device(mconfig, PIC16C620A, tag, owner, clock, 9, address_map_constructor(FUNC(pic16c620a_device::pic16c620a_ram), this)) { } pic16c621_device::pic16c621_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C621, tag, owner, clock, 10, 0x16C621) + : pic16c62x_device(mconfig, PIC16C621, tag, owner, clock, 10, address_map_constructor(FUNC(pic16c621_device::pic16c620_ram), this)) { } pic16c621a_device::pic16c621a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C621A, tag, owner, clock, 10, 0x16C621A) + : pic16c62x_device(mconfig, PIC16C621A, tag, owner, clock, 10, address_map_constructor(FUNC(pic16c621a_device::pic16c620a_ram), this)) { } pic16c622_device::pic16c622_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C622, tag, owner, clock, 11, 0x16C622) + : pic16c62x_device(mconfig, PIC16C622, tag, owner, clock, 11, address_map_constructor(FUNC(pic16c622_device::pic16c622_ram), this)) { } pic16c622a_device::pic16c622a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : pic16c62x_device(mconfig, PIC16C622A, tag, owner, clock, 11, 0x16C622A) + : pic16c62x_device(mconfig, PIC16C622A, tag, owner, clock, 11, address_map_constructor(FUNC(pic16c622a_device::pic16c622a_ram), this)) { } @@ -173,8 +184,7 @@ device_memory_interface::space_config_vector pic16c62x_device::memory_space_conf { return space_config_vector{ std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_DATA, &m_data_config), - std::make_pair(AS_IO, &m_io_config) + std::make_pair(AS_DATA, &m_data_config) }; } @@ -184,37 +194,16 @@ std::unique_ptr pic16c62x_device::create_disassembler() } -void pic16c62x_device::update_internalram_ptr() -{ - m_internalram = (uint8_t *)m_data.space().get_write_ptr(0x00); -} - #define PIC16C62x_RDOP(A) (m_cache.read_word(A)) -#define PIC16C62x_RAM_RDMEM(A) ((uint8_t)m_data.read_byte(A)) -#define PIC16C62x_RAM_WRMEM(A,V) (m_data.write_byte(A,V)) -#define PIC16C62x_In(Port) ((uint8_t)m_io.read_byte((Port))) -#define PIC16C62x_Out(Port,Value) (m_io.write_byte((Port),Value)) /************ Read the state of the T0 Clock input signal ************/ -#define PIC16C62x_T0_In (m_io.read_byte(PIC16C62x_T0) >> 4) +#define PIC16C62x_T0_In ((porta_r() >> 4) & 1) -#define M_RDRAM(A) (((A) == 0) ? m_internalram[0] : PIC16C62x_RAM_RDMEM(A)) -#define M_WRTRAM(A,V) do { if ((A) == 0) m_internalram[0] = (V); else PIC16C62x_RAM_WRMEM(A,V); } while (0) #define M_RDOP(A) PIC16C62x_RDOP(A) -#define P_IN(A) PIC16C62x_In(A) -#define P_OUT(A,V) PIC16C62x_Out(A,V) #define S_T0_IN PIC16C62x_T0_In #define ADDR_MASK 0x1fff -#define TMR0 m_internalram[1] -#define PCL m_internalram[2] -#define STATUS m_internalram[3] -#define FSR m_internalram[4] -#define PORTA m_internalram[5] -#define PORTB m_internalram[6] -#define INDF M_RDRAM(FSR) - #define RISING_EDGE_T0 (( (int)(T0_in - m_old_T0) > 0) ? 1 : 0) #define FALLING_EDGE_T0 (( (int)(T0_in - m_old_T0) < 0) ? 1 : 0) @@ -231,14 +220,14 @@ void pic16c62x_device::update_internalram_ptr() #define DC_FLAG 0x02 /* DC Digit Carry/Borrow flag (Nibble) */ #define C_FLAG 0x01 /* C Carry/Borrow Flag (Byte) */ -#define IRP (STATUS & IRP_FLAG) -#define RP1 (STATUS & RP1_FLAG) -#define RP0 (STATUS & RP0_FLAG) -#define TO (STATUS & TO_FLAG) -#define PD (STATUS & PD_FLAG) -#define ZERO (STATUS & Z_FLAG) -#define DC (STATUS & DC_FLAG) -#define CARRY (STATUS & C_FLAG) +#define IRP (m_STATUS & IRP_FLAG) +#define RP1 (m_STATUS & RP1_FLAG) +#define RP0 (m_STATUS & RP0_FLAG) +#define TO (m_STATUS & TO_FLAG) +#define PD (m_STATUS & PD_FLAG) +#define ZERO (m_STATUS & Z_FLAG) +#define DC (m_STATUS & DC_FLAG) +#define CARRY (m_STATUS & C_FLAG) #define ADDR ((m_opcode.b.l & 0x7f) | (RP0 << 2)) @@ -279,55 +268,53 @@ void pic16c62x_device::update_internalram_ptr() /* Easy bit position selectors */ -#define POS ((m_opcode.w.l >> 7) & 7) -static const unsigned int bit_clr[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }; -static const unsigned int bit_set[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +#define POS ((m_opcode.w >> 7) & 7) void pic16c62x_device::CALCULATE_Z_FLAG() { - if (m_ALU == 0) SET(STATUS, Z_FLAG); - else CLR(STATUS, Z_FLAG); + if (m_ALU == 0) SET(m_STATUS, Z_FLAG); + else CLR(m_STATUS, Z_FLAG); } void pic16c62x_device::CALCULATE_ADD_CARRY() { if ((uint8_t)(m_old_data) > (uint8_t)(m_ALU)) { - SET(STATUS, C_FLAG); + SET(m_STATUS, C_FLAG); } else { - CLR(STATUS, C_FLAG); + CLR(m_STATUS, C_FLAG); } } void pic16c62x_device::CALCULATE_ADD_DIGITCARRY() { if (((uint8_t)(m_old_data) & 0x0f) > ((uint8_t)(m_ALU) & 0x0f)) { - SET(STATUS, DC_FLAG); + SET(m_STATUS, DC_FLAG); } else { - CLR(STATUS, DC_FLAG); + CLR(m_STATUS, DC_FLAG); } } void pic16c62x_device::CALCULATE_SUB_CARRY() { if ((uint8_t)(m_old_data) < (uint8_t)(m_ALU)) { - CLR(STATUS, C_FLAG); + CLR(m_STATUS, C_FLAG); } else { - SET(STATUS, C_FLAG); + SET(m_STATUS, C_FLAG); } } void pic16c62x_device::CALCULATE_SUB_DIGITCARRY() { if (((uint8_t)(m_old_data) & 0x0f) < ((uint8_t)(m_ALU) & 0x0f)) { - CLR(STATUS, DC_FLAG); + CLR(m_STATUS, DC_FLAG); } else { - SET(STATUS, DC_FLAG); + SET(m_STATUS, DC_FLAG); } } @@ -359,119 +346,26 @@ void pic16c62x_device::PUSH_STACK(uint16_t data) -uint8_t pic16c62x_device::GET_REGFILE(offs_t addr) /* Read from internal memory */ +uint8_t pic16c62x_device::GET_REGFILE(uint8_t addr) /* Read from internal memory */ { - uint8_t data; - - if (addr == 0) { /* Indirect addressing */ - addr = (FSR & m_picRAMmask); + if ((addr & 0x7f) == 0) { /* Indirect addressing */ + addr = m_FSR; } - switch(addr) - { - case 0x00: /* Not an actual register, so return 0 */ - case 0x80: - data = 0; - break; - case 0x02: - case 0x03: - case 0x0b: - case 0x82: - case 0x83: - case 0x8b: - data = M_RDRAM(addr & 0x7f); - break; - case 0x84: - case 0x04: data = (FSR | (uint8_t)(~m_picRAMmask)); - break; - case 0x05: data = P_IN(0); - data &= m_TRISA; - data |= ((uint8_t)(~m_TRISA) & PORTA); - data &= 0x1f; /* 5-bit port (only lower 5 bits used) */ - break; - case 0x06: data = P_IN(1); - data &= m_TRISB; - data |= ((uint8_t)(~m_TRISB) & PORTB); - break; - case 0x8a: - case 0x0a: data = m_PCLATH; - break; - case 0x81: data = m_OPTION; - break; - case 0x85: data = m_TRISA; - break; - case 0x86: data = m_TRISB; - break; - default: data = M_RDRAM(addr); - break; - } - return data; + return m_data.read_byte(addr); } -void pic16c62x_device::STORE_REGFILE(offs_t addr, uint8_t data) /* Write to internal memory */ +void pic16c62x_device::STORE_REGFILE(uint8_t addr, uint8_t data) /* Write to internal memory */ { - if (addr == 0) { /* Indirect addressing */ - addr = (FSR & m_picRAMmask); + if ((addr & 0x7f) == 0) { /* Indirect addressing */ + addr = m_FSR; } - switch(addr) - { - case 0x80: - case 0x00: /* Not an actual register, nothing to save */ - break; - case 0x01: m_delay_timer = 2; /* Timer starts after next two instructions */ - if (PSA == 0) m_prescaler = 0; /* Must clear the Prescaler */ - TMR0 = data; - break; - case 0x82: - case 0x02: PCL = data; - m_PC = (m_PCLATH << 8) | data; - break; - case 0x83: - case 0x03: STATUS &= (uint8_t)(~(IRP_FLAG|RP1_FLAG|RP0_FLAG)); STATUS |= (data & (IRP_FLAG|RP1_FLAG|RP0_FLAG)); - break; - case 0x84: - case 0x04: FSR = (data | (uint8_t)(~m_picRAMmask)); - break; - case 0x05: data &= 0x1f; /* 5-bit port (only lower 5 bits used) */ - P_OUT(0,data & (uint8_t)(~m_TRISA)); PORTA = data; - break; - case 0x06: P_OUT(1,data & (uint8_t)(~m_TRISB)); PORTB = data; - break; - case 0x8a: - case 0x0a: - m_PCLATH = data & 0x1f; - M_WRTRAM(0x0a, m_PCLATH); - break; - case 0x8b: - case 0x0b: M_WRTRAM(0x0b, data); - break; - case 0x81: m_OPTION = data; - M_WRTRAM(0x81, data); - break; - case 0x85: if (m_TRISA != data) - { - m_TRISA = data | 0xf0; - P_OUT(2,m_TRISA); - P_OUT(0,PORTA & (uint8_t)(~m_TRISA) & 0x0f); - M_WRTRAM(addr, data); - } - break; - case 0x86: if (m_TRISB != data) - { - m_TRISB = data; - P_OUT(3,m_TRISB); - P_OUT(1,PORTB & (uint8_t)(~m_TRISB)); - M_WRTRAM(addr, data); - } - break; - default: M_WRTRAM(addr, data); - break; - } + m_data.write_byte(addr, data); } -void pic16c62x_device::STORE_RESULT(offs_t addr, uint8_t data) +void pic16c62x_device::STORE_RESULT(uint8_t addr, uint8_t data) { if (m_opcode.b.l & 0x80) { @@ -484,6 +378,190 @@ void pic16c62x_device::STORE_RESULT(offs_t addr, uint8_t data) } +uint8_t pic16c62x_device::tmr0_r() +{ + return m_TMR0; +} + +void pic16c62x_device::tmr0_w(uint8_t data) +{ + m_delay_timer = 2; /* Timer starts after next two instructions */ + if (PSA == 0) m_prescaler = 0; /* Must clear the Prescaler */ + m_TMR0 = data; +} + +uint8_t pic16c62x_device::pcl_r() +{ + return m_PC & 0xff; +} + +void pic16c62x_device::pcl_w(uint8_t data) +{ + m_PC = (m_PCLATH << 8) | data; +} + +uint8_t pic16c62x_device::status_r() +{ + return m_STATUS; +} + +void pic16c62x_device::status_w(uint8_t data) +{ + m_STATUS &= (uint8_t)(~(IRP_FLAG|RP1_FLAG|RP0_FLAG)); + m_STATUS |= (data & (IRP_FLAG|RP1_FLAG|RP0_FLAG)); +} + +uint8_t pic16c62x_device::fsr_r() +{ + return m_FSR; +} + +void pic16c62x_device::fsr_w(uint8_t data) +{ + m_FSR = data; +} + +uint8_t pic16c62x_device::porta_r() +{ + uint8_t data = m_read_port[0](0, ~m_port_tris[0]); + data &= m_port_tris[0]; + data |= ((uint8_t)(~m_port_tris[0]) & m_port_data[0]); + return data & 0x1f; /* 5-bit port (only lower 5 bits used) */ +} + +void pic16c62x_device::porta_w(uint8_t data) +{ + data &= 0x1f; /* 5-bit port (only lower 5 bits used) */ + m_write_port[0](0, data & (~m_port_tris[0]), ~m_port_tris[0]); + m_port_data[0] = data; +} + +uint8_t pic16c62x_device::portb_r() +{ + uint8_t data = m_read_port[1](0, ~m_port_tris[1]); + data &= m_port_tris[1]; + data |= ((uint8_t)(~m_port_tris[1]) & m_port_data[1]); + return data; +} + +void pic16c62x_device::portb_w(uint8_t data) +{ + m_write_port[1](0, data & (~m_port_tris[1]), ~m_port_tris[1]); + m_port_data[1] = data; +} + +uint8_t pic16c62x_device::pclath_r() +{ + return m_PCLATH; +} + +void pic16c62x_device::pclath_w(uint8_t data) +{ + m_PCLATH = data & 0x1f; +} + +uint8_t pic16c62x_device::intcon_r() +{ + return m_INTCON; +} + +void pic16c62x_device::intcon_w(uint8_t data) +{ + m_INTCON = data; +} + +uint8_t pic16c62x_device::option_r() +{ + return m_OPTION; +} + +void pic16c62x_device::option_w(uint8_t data) +{ + m_OPTION = data; +} + +uint8_t pic16c62x_device::trisa_r() +{ + return m_port_tris[0]; +} + +void pic16c62x_device::trisa_w(uint8_t data) +{ + data &= 0x1f; + if (m_port_tris[0] != data) + { + m_port_tris[0] = data; + m_write_port[0](0, m_port_data[0] & (~m_port_tris[0]), ~m_port_tris[0] & 0x1f); + } +} + +uint8_t pic16c62x_device::trisb_r() +{ + return m_port_tris[1]; +} + +void pic16c62x_device::trisb_w(uint8_t data) +{ + if (m_port_tris[1] != data) + { + m_port_tris[1] = data; + m_write_port[1](0, m_port_data[1] & (~m_port_tris[1]), ~m_port_tris[1]); + } +} + +uint8_t pic16c62x_device::pir1_r() +{ + return m_PIR1; +} + +void pic16c62x_device::pir1_w(uint8_t data) +{ + // Only CMIF is implemented + m_PIR1 = data & 0x40; +} + +uint8_t pic16c62x_device::pie1_r() +{ + return m_PIE1; +} + +void pic16c62x_device::pie1_w(uint8_t data) +{ + // Only CMIE is implemented + m_PIE1 = data & 0x40; +} + +uint8_t pic16c62x_device::pcon_r() +{ + return m_PCON; +} + +void pic16c62x_device::pcon_w(uint8_t data) +{ + m_PCON = data & 0x03; +} + +uint8_t pic16c62x_device::cmcon_r() +{ + // TODO: C1OUT, C2OUT + return m_CMCON; +} + +void pic16c62x_device::cmcon_w(uint8_t data) +{ + m_CMCON = data & 0x0f; +} + +uint8_t pic16c62x_device::vrcon_r() +{ + return m_VRCON; +} + +void pic16c62x_device::vrcon_w(uint8_t data) +{ + m_VRCON = data & 0xef; +} + /************************************************************************ * Emulate the Instructions ************************************************************************/ @@ -494,7 +572,7 @@ void pic16c62x_device::STORE_RESULT(offs_t addr, uint8_t data) void pic16c62x_device::illegal() { - logerror("PIC16C62x: PC=%03x, Illegal opcode = %04x\n", (m_PC-1), m_opcode.w.l); + logerror("PIC16C62x: PC=%03x, Illegal opcode = %04x\n", (m_PC-1), m_opcode.w); } @@ -534,33 +612,31 @@ void pic16c62x_device::andlw() void pic16c62x_device::bcf() { m_ALU = GET_REGFILE(ADDR); - m_ALU &= bit_clr[POS]; + m_ALU &= ~(1 << POS); STORE_REGFILE(ADDR, m_ALU); } void pic16c62x_device::bsf() { m_ALU = GET_REGFILE(ADDR); - m_ALU |= bit_set[POS]; + m_ALU |= 1 << POS; STORE_REGFILE(ADDR, m_ALU); } void pic16c62x_device::btfss() { - if ((GET_REGFILE(ADDR) & bit_set[POS]) == bit_set[POS]) + if ((GET_REGFILE(ADDR) & (1 << POS)) != 0) { m_PC++; - PCL = m_PC & 0xff; m_inst_cycles += 1; /* Add NOP cycles */ } } void pic16c62x_device::btfsc() { - if ((GET_REGFILE(ADDR) & bit_set[POS]) == 0) + if ((GET_REGFILE(ADDR) & (1 << POS)) == 0) { m_PC++; - PCL = m_PC & 0xff; m_inst_cycles += 1; /* Add NOP cycles */ } } @@ -568,29 +644,28 @@ void pic16c62x_device::btfsc() void pic16c62x_device::call() { PUSH_STACK(m_PC); - m_PC = ((m_PCLATH & 0x18) << 8) | (m_opcode.w.l & 0x7ff); + m_PC = ((m_PCLATH & 0x18) << 8) | (m_opcode.w & 0x7ff); m_PC &= ADDR_MASK; - PCL = m_PC & 0xff; } void pic16c62x_device::clrw() { m_W = 0; - SET(STATUS, Z_FLAG); + SET(m_STATUS, Z_FLAG); } void pic16c62x_device::clrf() { STORE_REGFILE(ADDR, 0); - SET(STATUS, Z_FLAG); + SET(m_STATUS, Z_FLAG); } void pic16c62x_device::clrwdt() { m_WDT = 0; if (PSA) m_prescaler = 0; - SET(STATUS, TO_FLAG); - SET(STATUS, PD_FLAG); + SET(m_STATUS, TO_FLAG); + SET(m_STATUS, PD_FLAG); } void pic16c62x_device::comf() @@ -614,16 +689,14 @@ void pic16c62x_device::decfsz() if (m_ALU == 0) { m_PC++; - PCL = m_PC & 0xff; m_inst_cycles += 1; /* Add NOP cycles */ } } void pic16c62x_device::goto_op() { - m_PC = ((m_PCLATH & 0x18) << 8) | (m_opcode.w.l & 0x7ff); + m_PC = ((m_PCLATH & 0x18) << 8) | (m_opcode.w & 0x7ff); m_PC &= ADDR_MASK; - PCL = m_PC & 0xff; } void pic16c62x_device::incf() @@ -640,7 +713,6 @@ void pic16c62x_device::incfsz() if (m_ALU == 0) { m_PC++; - PCL = m_PC & 0xff; m_inst_cycles += 1; /* Add NOP cycles */ } } @@ -690,39 +762,36 @@ void pic16c62x_device::retlw() { m_W = m_opcode.b.l; m_PC = POP_STACK(); - PCL = m_PC & 0xff; } void pic16c62x_device::returns() { m_PC = POP_STACK(); - PCL = m_PC & 0xff; } void pic16c62x_device::retfie() { m_PC = POP_STACK(); - PCL = m_PC & 0xff; //INTCON(7)=1; } void pic16c62x_device::rlf() { - m_ALU = GET_REGFILE(ADDR); - m_ALU <<= 1; - if (STATUS & C_FLAG) m_ALU |= 1; - if (GET_REGFILE(ADDR) & 0x80) SET(STATUS, C_FLAG); - else CLR(STATUS, C_FLAG); + m_old_data = GET_REGFILE(ADDR); + m_ALU = m_old_data << 1; + if (m_STATUS & C_FLAG) m_ALU |= 1; + if (m_old_data & 0x80) SET(m_STATUS, C_FLAG); + else CLR(m_STATUS, C_FLAG); STORE_RESULT(ADDR, m_ALU); } void pic16c62x_device::rrf() { - m_ALU = GET_REGFILE(ADDR); - m_ALU >>= 1; - if (STATUS & C_FLAG) m_ALU |= 0x80; - if (GET_REGFILE(ADDR) & 1) SET(STATUS, C_FLAG); - else CLR(STATUS, C_FLAG); + m_old_data = GET_REGFILE(ADDR); + m_ALU = m_old_data >> 1; + if (m_STATUS & C_FLAG) m_ALU |= 0x80; + if (m_old_data & 1) SET(m_STATUS, C_FLAG); + else CLR(m_STATUS, C_FLAG); STORE_RESULT(ADDR, m_ALU); } @@ -730,8 +799,8 @@ void pic16c62x_device::sleepic() { if (WDTE) m_WDT = 0; if (PSA) m_prescaler = 0; - SET(STATUS, TO_FLAG); - CLR(STATUS, PD_FLAG); + SET(m_STATUS, TO_FLAG); + CLR(m_STATUS, PD_FLAG); } void pic16c62x_device::subwf() @@ -746,7 +815,8 @@ void pic16c62x_device::subwf() void pic16c62x_device::sublw() { - m_ALU = (m_opcode.b.l & 0xff) - m_W; + m_old_data = m_opcode.b.l; + m_ALU = m_old_data - m_W; m_W = m_ALU; CALCULATE_Z_FLAG(); CALCULATE_SUB_CARRY(); @@ -755,8 +825,8 @@ void pic16c62x_device::sublw() void pic16c62x_device::swapf() { - m_ALU = ((GET_REGFILE(ADDR) << 4) & 0xf0); - m_ALU |= ((GET_REGFILE(ADDR) >> 4) & 0x0f); + m_ALU = GET_REGFILE(ADDR); + m_ALU = (m_ALU << 4) | (m_ALU >> 4); STORE_RESULT(ADDR, m_ALU); } @@ -764,8 +834,8 @@ void pic16c62x_device::tris() { switch(m_opcode.b.l & 0x7) { - case 5: STORE_REGFILE(0x85, m_W); break; - case 6: STORE_REGFILE(0x86, m_W); break; + case 5: m_data.write_byte(0x85, m_W); break; + case 6: m_data.write_byte(0x86, m_W); break; default: illegal(); break; } } @@ -791,43 +861,43 @@ void pic16c62x_device::xorwf() const pic16c62x_device::pic16c62x_instruction pic16c62x_device::s_instructiontable[]= { - {(char *)"000111dfffffff", &pic16c62x_device::addwf, 1}, - {(char *)"000101dfffffff", &pic16c62x_device::andwf, 1}, - {(char *)"0000011fffffff", &pic16c62x_device::clrf, 1}, - {(char *)"00000100000011", &pic16c62x_device::clrw, 1}, - {(char *)"001001dfffffff", &pic16c62x_device::comf, 1}, - {(char *)"000011dfffffff", &pic16c62x_device::decf, 1}, - {(char *)"001011dfffffff", &pic16c62x_device::decfsz, 1}, - {(char *)"001010dfffffff", &pic16c62x_device::incf, 1}, - {(char *)"001111dfffffff", &pic16c62x_device::incfsz, 1}, - {(char *)"000100dfffffff", &pic16c62x_device::iorwf, 1}, - {(char *)"001000dfffffff", &pic16c62x_device::movf, 1}, - {(char *)"0000001fffffff", &pic16c62x_device::movwf, 1}, - {(char *)"0000000xx00000", &pic16c62x_device::nop, 1}, - {(char *)"001101dfffffff", &pic16c62x_device::rlf, 1}, - {(char *)"001100dfffffff", &pic16c62x_device::rrf, 1}, - {(char *)"000010dfffffff", &pic16c62x_device::subwf, 1}, - {(char *)"001110dfffffff", &pic16c62x_device::swapf, 1}, - {(char *)"000110dfffffff", &pic16c62x_device::xorwf, 1}, - {(char *)"0100bbbfffffff", &pic16c62x_device::bcf, 1}, - {(char *)"0101bbbfffffff", &pic16c62x_device::bsf, 1}, - {(char *)"0110bbbfffffff", &pic16c62x_device::btfsc, 1}, - {(char *)"0111bbbfffffff", &pic16c62x_device::btfss, 1}, - {(char *)"11111xkkkkkkkk", &pic16c62x_device::addlw, 1}, - {(char *)"111001kkkkkkkk", &pic16c62x_device::andlw, 1}, - {(char *)"100aaaaaaaaaaa", &pic16c62x_device::call, 2}, - {(char *)"101aaaaaaaaaaa", &pic16c62x_device::goto_op, 2}, - {(char *)"111000kkkkkkkk", &pic16c62x_device::iorlw, 1}, - {(char *)"1100xxkkkkkkkk", &pic16c62x_device::movlw, 1}, - {(char *)"00000000001001", &pic16c62x_device::retfie, 2}, - {(char *)"1101xxkkkkkkkk", &pic16c62x_device::retlw, 2}, - {(char *)"00000000001000", &pic16c62x_device::returns, 2}, - {(char *)"00000001100011", &pic16c62x_device::sleepic, 1}, - {(char *)"11110xkkkkkkkk", &pic16c62x_device::sublw, 1}, - {(char *)"111010kkkkkkkk", &pic16c62x_device::xorlw, 1}, - {(char *)"00000001100100", &pic16c62x_device::clrwdt, 1}, - {(char *)"00000001100010", &pic16c62x_device::option, 1}, // deprecated - {(char *)"00000001100fff", &pic16c62x_device::tris, 1}, // deprecated + {"000111dfffffff", &pic16c62x_device::addwf, 1}, + {"000101dfffffff", &pic16c62x_device::andwf, 1}, + {"0000011fffffff", &pic16c62x_device::clrf, 1}, + {"00000100000011", &pic16c62x_device::clrw, 1}, + {"001001dfffffff", &pic16c62x_device::comf, 1}, + {"000011dfffffff", &pic16c62x_device::decf, 1}, + {"001011dfffffff", &pic16c62x_device::decfsz, 1}, + {"001010dfffffff", &pic16c62x_device::incf, 1}, + {"001111dfffffff", &pic16c62x_device::incfsz, 1}, + {"000100dfffffff", &pic16c62x_device::iorwf, 1}, + {"001000dfffffff", &pic16c62x_device::movf, 1}, + {"0000001fffffff", &pic16c62x_device::movwf, 1}, + {"0000000xx00000", &pic16c62x_device::nop, 1}, + {"001101dfffffff", &pic16c62x_device::rlf, 1}, + {"001100dfffffff", &pic16c62x_device::rrf, 1}, + {"000010dfffffff", &pic16c62x_device::subwf, 1}, + {"001110dfffffff", &pic16c62x_device::swapf, 1}, + {"000110dfffffff", &pic16c62x_device::xorwf, 1}, + {"0100bbbfffffff", &pic16c62x_device::bcf, 1}, + {"0101bbbfffffff", &pic16c62x_device::bsf, 1}, + {"0110bbbfffffff", &pic16c62x_device::btfsc, 1}, + {"0111bbbfffffff", &pic16c62x_device::btfss, 1}, + {"11111xkkkkkkkk", &pic16c62x_device::addlw, 1}, + {"111001kkkkkkkk", &pic16c62x_device::andlw, 1}, + {"100aaaaaaaaaaa", &pic16c62x_device::call, 2}, + {"101aaaaaaaaaaa", &pic16c62x_device::goto_op, 2}, + {"111000kkkkkkkk", &pic16c62x_device::iorlw, 1}, + {"1100xxkkkkkkkk", &pic16c62x_device::movlw, 1}, + {"00000000001001", &pic16c62x_device::retfie, 2}, + {"1101xxkkkkkkkk", &pic16c62x_device::retlw, 2}, + {"00000000001000", &pic16c62x_device::returns, 2}, + {"00000001100011", &pic16c62x_device::sleepic, 1}, + {"11110xkkkkkkkk", &pic16c62x_device::sublw, 1}, + {"111010kkkkkkkk", &pic16c62x_device::xorlw, 1}, + {"00000001100100", &pic16c62x_device::clrwdt, 1}, + {"00000001100010", &pic16c62x_device::option, 1}, // deprecated + {"00000001100fff", &pic16c62x_device::tris, 1}, // deprecated {nullptr, nullptr, 0} }; @@ -887,33 +957,48 @@ void pic16c62x_device::build_opcode_table(void) void pic16c62x_device::device_start() { space(AS_PROGRAM).cache(m_cache); - space(AS_PROGRAM).specific(m_program); space(AS_DATA).specific(m_data); - space(AS_IO).specific(m_io); - - /* ensure the internal ram pointers are set before get_info is called */ - update_internalram_ptr(); build_opcode_table(); + // Set largely arbitrary initial values for special registers + m_W = 0; + m_ALU = 0; + m_WDT = 0; + m_TMR0 = 0; + m_STATUS = 0x18; + m_FSR = 0; + m_port_data[0] = 0; + m_port_data[1] = 0; + m_PCON = 0; + m_INTCON = 0; + std::fill(std::begin(m_STACK), std::end(m_STACK), 0); + save_item(NAME(m_W)); save_item(NAME(m_ALU)); save_item(NAME(m_OPTION)); save_item(NAME(m_PCLATH)); - save_item(NAME(m_TRISA)); - save_item(NAME(m_TRISB)); + save_item(NAME(m_TMR0)); + save_item(NAME(m_STATUS)); + save_item(NAME(m_FSR)); + save_item(NAME(m_port_data)); + save_item(NAME(m_port_tris)); + save_item(NAME(m_INTCON)); + save_item(NAME(m_PIR1)); + save_item(NAME(m_PIE1)); + save_item(NAME(m_PCON)); + save_item(NAME(m_CMCON)); + save_item(NAME(m_VRCON)); save_item(NAME(m_old_T0)); save_item(NAME(m_old_data)); - save_item(NAME(m_picRAMmask)); save_item(NAME(m_WDT)); save_item(NAME(m_prescaler)); save_item(NAME(m_STACK)); save_item(NAME(m_PC)); save_item(NAME(m_PREVPC)); save_item(NAME(m_CONFIG)); - save_item(NAME(m_opcode.d)); + save_item(NAME(m_opcode.w)); save_item(NAME(m_delay_timer)); - save_item(NAME(m_picmodel)); save_item(NAME(m_reset_vector)); save_item(NAME(m_temp_config)); @@ -936,10 +1021,11 @@ void pic16c62x_device::device_start() state_add( PIC16C62x_STK7, "STK7", m_STACK[7]).mask(0xfff).formatstr("%03X"); state_add( PIC16C62x_PRTA, "PRTA", m_debugger_temp).mask(0x1f).callimport().callexport().formatstr("%02X"); state_add( PIC16C62x_PRTB, "PRTB", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); - state_add( PIC16C62x_TRSA, "TRSA", m_TRISA).mask(0x1f).formatstr("%02X"); - state_add( PIC16C62x_TRSB, "TRSB", m_TRISB).formatstr("%02X"); + state_add( PIC16C62x_TRSA, "TRSA", m_port_tris[0]).mask(0x1f).formatstr("%02X"); + state_add( PIC16C62x_TRSB, "TRSB", m_port_tris[1]).formatstr("%02X"); state_add( PIC16C62x_FSR, "FSR", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); state_add( PIC16C62x_PSCL, "PSCL", m_debugger_temp).callimport().formatstr("%3s"); + state_add( PIC16C62x_PCLATH, "PCLATH", m_PCLATH).mask(0x1f); state_add( STATE_GENPC, "GENPC", m_PC).noshow(); state_add( STATE_GENPCBASE, "CURPC", m_PREVPC).noshow(); @@ -953,19 +1039,19 @@ void pic16c62x_device::state_import(const device_state_entry &entry) switch (entry.index()) { case PIC16C62x_STR: - STATUS = m_debugger_temp; + m_STATUS = m_debugger_temp; break; case PIC16C62x_TMR0: - TMR0 = m_debugger_temp; + m_TMR0 = m_debugger_temp; break; case PIC16C62x_PRTA: - PORTA = m_debugger_temp; + m_port_data[0] = m_debugger_temp; break; case PIC16C62x_PRTB: - PORTB = m_debugger_temp; + m_port_data[1] = m_debugger_temp; break; case PIC16C62x_FSR: - FSR = ((m_debugger_temp & m_picRAMmask) | (uint8_t)(~m_picRAMmask)); + m_FSR = m_debugger_temp; break; case PIC16C62x_PSCL: m_prescaler = m_debugger_temp; @@ -978,19 +1064,19 @@ void pic16c62x_device::state_export(const device_state_entry &entry) switch (entry.index()) { case PIC16C62x_STR: - m_debugger_temp = STATUS; + m_debugger_temp = m_STATUS; break; case PIC16C62x_TMR0: - m_debugger_temp = TMR0; + m_debugger_temp = m_TMR0; break; case PIC16C62x_PRTA: - m_debugger_temp = PORTA & 0x1f; + m_debugger_temp = m_port_data[0] & 0x1f; break; case PIC16C62x_PRTB: - m_debugger_temp = PORTB; + m_debugger_temp = m_port_data[1]; break; case PIC16C62x_FSR: - m_debugger_temp = ((FSR) & m_picRAMmask) | (uint8_t)(~m_picRAMmask); + m_debugger_temp = m_FSR; break; } } @@ -1005,12 +1091,12 @@ void pic16c62x_device::state_string_export(const device_state_entry &entry, std: case STATE_GENFLAGS: str = string_format("%01x%c%c%c%c%c %c%c%c%03x", - (STATUS & 0xe0) >> 5, - STATUS & 0x10 ? '.':'O', /* WDT Overflow */ - STATUS & 0x08 ? 'P':'D', /* Power/Down */ - STATUS & 0x04 ? 'Z':'.', /* Zero */ - STATUS & 0x02 ? 'c':'b', /* Nibble Carry/Borrow */ - STATUS & 0x01 ? 'C':'B', /* Carry/Borrow */ + (m_STATUS & 0xe0) >> 5, + m_STATUS & 0x10 ? '.':'O', /* WDT Overflow */ + m_STATUS & 0x08 ? 'P':'D', /* Power/Down */ + m_STATUS & 0x04 ? 'Z':'.', /* Zero */ + m_STATUS & 0x02 ? 'c':'b', /* Nibble Carry/Borrow */ + m_STATUS & 0x01 ? 'C':'B', /* Carry/Borrow */ m_OPTION & 0x20 ? 'C':'T', /* Counter/Timer */ m_OPTION & 0x10 ? 'N':'P', /* Negative/Positive */ @@ -1027,25 +1113,26 @@ void pic16c62x_device::state_string_export(const device_state_entry &entry, std: void pic16c62x_device::pic16c62x_reset_regs() { m_PC = m_reset_vector; - m_TRISA = 0x1f; - m_TRISB = 0xff; + m_port_tris[0] = 0x1f; + m_port_tris[1] = 0xff; m_OPTION = 0xff; - STATUS = 0x18; - PCL = 0; - FSR |= (uint8_t)(~m_picRAMmask); - PORTA = 0; + m_STATUS &= 0x1f; + m_port_data[0] &= 0x10; m_prescaler = 0; m_delay_timer = 0; m_old_T0 = 0; m_inst_cycles = 0; - PIC16C62x_RAM_WRMEM(0x85,m_TRISA); - PIC16C62x_RAM_WRMEM(0x86,m_TRISB); - PIC16C62x_RAM_WRMEM(0x81,m_OPTION); + m_PCLATH = 0; + m_INTCON &= 0x01; + m_PIR1 = 0; + m_PIE1 = 0; + m_CMCON = 0; + m_VRCON = 0; } void pic16c62x_device::pic16c62x_soft_reset() { - SET(STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG)); + SET(m_STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG)); pic16c62x_reset_regs(); } @@ -1070,7 +1157,7 @@ void pic16c62x_device::pic16c62x_update_watchdog(int counts) /* If the current instruction is CLRWDT or SLEEP, don't update the WDT */ - if ((m_opcode.w.l != 0x64) && (m_opcode.w.l != 0x63)) + if ((m_opcode.w != 0x64) && (m_opcode.w != 0x63)) { uint16_t old_WDT = m_WDT; @@ -1086,12 +1173,12 @@ void pic16c62x_device::pic16c62x_update_watchdog(int counts) m_prescaler++; if (m_prescaler >= (1 << PS)) { /* Prescale values from 1 to 128 */ m_prescaler = 0; - CLR(STATUS, TO_FLAG); + CLR(m_STATUS, TO_FLAG); pic16c62x_soft_reset(); } } else { - CLR(STATUS, TO_FLAG); + CLR(m_STATUS, TO_FLAG); pic16c62x_soft_reset(); } } @@ -1108,12 +1195,12 @@ void pic16c62x_device::pic16c62x_update_timer(int counts) if (PSA == 0) { m_prescaler += counts; if (m_prescaler >= (2 << PS)) { /* Prescale values from 2 to 256 */ - TMR0 += (m_prescaler / (2 << PS)); + m_TMR0 += (m_prescaler / (2 << PS)); m_prescaler %= (2 << PS); /* Overflow prescaler */ } } else { - TMR0 += counts; + m_TMR0 += counts; } } @@ -1126,8 +1213,6 @@ void pic16c62x_device::execute_run() { uint8_t T0_in; - update_internalram_ptr(); - do { if (PD == 0) /* Sleep Mode */ @@ -1144,12 +1229,11 @@ void pic16c62x_device::execute_run() debugger_instruction_hook(m_PC); - m_opcode.d = M_RDOP(m_PC); + m_opcode.w = M_RDOP(m_PC); m_PC++; - PCL++; - m_inst_cycles = m_opcode_table[m_opcode.w.l & 0x3fff].cycles; - (this->*m_opcode_table[m_opcode.w.l & 0x3fff].function)(); + m_inst_cycles = m_opcode_table[m_opcode.w & 0x3fff].cycles; + (this->*m_opcode_table[m_opcode.w & 0x3fff].function)(); if (T0CS) { /* Count mode */ T0_in = S_T0_IN; @@ -1187,8 +1271,6 @@ void pic16c62x_device::execute_run() void pic16c62x_device::device_reset() { - update_internalram_ptr(); - pic16c62x_reset_regs(); - SET(STATUS, (TO_FLAG | PD_FLAG)); + SET(m_STATUS, (TO_FLAG | PD_FLAG)); } diff --git a/src/devices/cpu/pic16c62x/pic16c62x.h b/src/devices/cpu/pic16c62x/pic16c62x.h index d08eeed60c0..5465743b52d 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.h +++ b/src/devices/cpu/pic16c62x/pic16c62x.h @@ -36,7 +36,7 @@ enum PIC16C62x_STK7, PIC16C62x_FSR, PIC16C62x_W, PIC16C62x_ALU, PIC16C62x_STR, PIC16C62x_OPT, PIC16C62x_TMR0, PIC16C62x_PRTA, PIC16C62x_PRTB, PIC16C62x_WDT, PIC16C62x_TRSA, PIC16C62x_TRSB, - PIC16C62x_PSCL + PIC16C62x_PSCL, PIC16C62x_PCLATH }; #define PIC16C62x_T0 0 @@ -54,11 +54,17 @@ DECLARE_DEVICE_TYPE(PIC16C622A, pic16c622a_device) class pic16c62x_device : public cpu_device { public: + auto read_a() { return m_read_port[0].bind(); } + auto write_a() { return m_write_port[0].bind(); } + + auto read_b() { return m_read_port[1].bind(); } + auto write_b() { return m_write_port[1].bind(); } + void set_config(int data); protected: // construction/destruction - pic16c62x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int picmodel); + pic16c62x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, address_map_constructor ram_map); // device-level overrides virtual void device_start() override; @@ -86,7 +92,6 @@ protected: private: address_space_config m_program_config; address_space_config m_data_config; - address_space_config m_io_config; /******************** CPU Internal Registers *******************/ uint16_t m_PC; @@ -97,27 +102,34 @@ private: uint16_t m_CONFIG; uint8_t m_ALU; uint16_t m_WDT; - uint8_t m_TRISA; /* 85 */ - uint8_t m_TRISB; /* 86 */ + uint8_t m_TMR0; + uint8_t m_STATUS; + uint8_t m_FSR; + uint8_t m_port_data[2]; + uint8_t m_port_tris[2]; + uint8_t m_INTCON; + uint8_t m_PIR1; + uint8_t m_PIE1; + uint8_t m_PCON; + uint8_t m_CMCON; + uint8_t m_VRCON; uint16_t m_STACK[8]; uint16_t m_prescaler; /* Note: this is really an 8-bit register */ - PAIR m_opcode; - uint8_t *m_internalram; + PAIR16 m_opcode; int m_icount; int m_reset_vector; - int m_picmodel; int m_delay_timer; uint16_t m_temp_config; uint8_t m_old_T0; int8_t m_old_data; - uint8_t m_picRAMmask; int m_inst_cycles; memory_access<11, 1, -1, ENDIANNESS_LITTLE>::cache m_cache; - memory_access<11, 1, -1, ENDIANNESS_LITTLE>::specific m_program; memory_access< 8, 0, 0, ENDIANNESS_LITTLE>::specific m_data; - memory_access< 5, 0, 0, ENDIANNESS_LITTLE>::specific m_io; + + devcb_read8::array<2> m_read_port; + devcb_write8::array<2> m_write_port; // For debugger int m_debugger_temp; @@ -134,13 +146,12 @@ private: /* instruction list entry */ struct pic16c62x_instruction { - char *format; + const char *format; pic16c62x_ophandler function; uint8_t cycles; }; static const pic16c62x_instruction s_instructiontable[]; - void update_internalram_ptr(); void CALCULATE_Z_FLAG(); void CALCULATE_ADD_CARRY(); void CALCULATE_ADD_DIGITCARRY(); @@ -148,9 +159,43 @@ private: void CALCULATE_SUB_DIGITCARRY(); uint16_t POP_STACK(); void PUSH_STACK(uint16_t data); - uint8_t GET_REGFILE(offs_t addr); - void STORE_REGFILE(offs_t addr, uint8_t data); - void STORE_RESULT(offs_t addr, uint8_t data); + uint8_t GET_REGFILE(uint8_t addr); + void STORE_REGFILE(uint8_t addr, uint8_t data); + void STORE_RESULT(uint8_t addr, uint8_t data); + + uint8_t tmr0_r(); + void tmr0_w(uint8_t data); + uint8_t pcl_r(); + void pcl_w(uint8_t data); + uint8_t status_r(); + void status_w(uint8_t data); + uint8_t fsr_r(); + void fsr_w(uint8_t data); + uint8_t porta_r(); + void porta_w(uint8_t data); + uint8_t portb_r(); + void portb_w(uint8_t data); + uint8_t pclath_r(); + void pclath_w(uint8_t data); + uint8_t intcon_r(); + void intcon_w(uint8_t data); + uint8_t option_r(); + void option_w(uint8_t data); + uint8_t trisa_r(); + void trisa_w(uint8_t data); + uint8_t trisb_r(); + void trisb_w(uint8_t data); + uint8_t pir1_r(); + void pir1_w(uint8_t data); + uint8_t pie1_r(); + void pie1_w(uint8_t data); + uint8_t pcon_r(); + void pcon_w(uint8_t data); + uint8_t cmcon_r(); + void cmcon_w(uint8_t data); + uint8_t vrcon_r(); + void vrcon_w(uint8_t data); + void illegal(); void addwf(); void addlw(); @@ -195,12 +240,15 @@ private: void pic16c62x_update_watchdog(int counts); void pic16c62x_update_timer(int counts); +protected: + void core_regs(address_map &map); void pic16c620_ram(address_map &map); void pic16c622_ram(address_map &map); void pic16c62x_rom_10(address_map &map); void pic16c62x_rom_11(address_map &map); void pic16c62x_rom_9(address_map &map); - void pic16c62xa_ram(address_map &map); + void pic16c620a_ram(address_map &map); + void pic16c622a_ram(address_map &map); }; diff --git a/src/mame/sega/naomigd.cpp b/src/mame/sega/naomigd.cpp index f3baf0e341a..a06d360d389 100644 --- a/src/mame/sega/naomigd.cpp +++ b/src/mame/sega/naomigd.cpp @@ -808,30 +808,18 @@ void naomi_gdrom_board::i2cmem_dimm_w(uint64_t data) } } -void naomi_gdrom_board::pic_map(address_map &map) +uint8_t naomi_gdrom_board::pic_dimm_r() { - map(0x00, 0x1f).rw(FUNC(naomi_gdrom_board::pic_dimm_r), FUNC(naomi_gdrom_board::pic_dimm_w)); + return picbus | picbus_pullup; } -uint8_t naomi_gdrom_board::pic_dimm_r(offs_t offset) +void naomi_gdrom_board::pic_dimm_w(offs_t offset, uint8_t data, uint8_t mem_mask) { - if (offset == 1) - return picbus | picbus_pullup; - return 0; -} + picbus = data; + m_securitycpu->abort_timeslice(); -void naomi_gdrom_board::pic_dimm_w(offs_t offset, uint8_t data) -{ - if (offset == 1) - { - picbus = data; - m_securitycpu->abort_timeslice(); - } - if (offset == 3) - { - picbus_io[1] = data; // for each bit specify direction, 0 out 1 in - picbus_pullup = (picbus_io[0] & picbus_io[1]) & 0xf; // high if both are inputs - } + picbus_io[1] = ~mem_mask; // for each bit specify direction, 0 out 1 in + picbus_pullup = (picbus_io[0] & picbus_io[1]) & 0xf; // high if both are inputs } void naomi_gdrom_board::find_file(const char *name, const uint8_t *dir_sector, uint32_t &file_start, uint32_t &file_size) @@ -1098,7 +1086,8 @@ void naomi_gdrom_board::device_add_mconfig(machine_config &config) IDE_GDROM(config, m_idegdrom, 0, image_tag, m_315_6154->tag(), sega_315_6154_device::AS_PCI_MEMORY); m_idegdrom->irq_callback().set_inputline(m_maincpu, SH4_IRL2); PIC16C622(config, m_securitycpu, PIC_CLOCK); - m_securitycpu->set_addrmap(AS_IO, &naomi_gdrom_board::pic_map); + m_securitycpu->read_b().set(FUNC(naomi_gdrom_board::pic_dimm_r)); + m_securitycpu->write_b().set(FUNC(naomi_gdrom_board::pic_dimm_w)); m_securitycpu->set_config(0x3fff - 0x04); I2C_24C01(config, m_i2c0, 0); m_i2c0->set_e0(0); diff --git a/src/mame/sega/naomigd.h b/src/mame/sega/naomigd.h index 245a0f6356e..aa46a60ac34 100644 --- a/src/mame/sega/naomigd.h +++ b/src/mame/sega/naomigd.h @@ -75,7 +75,6 @@ public: virtual void submap(address_map &map) override; void sh4_map(address_map &map); void sh4_io_map(address_map &map); - void pic_map(address_map &map); void pci_map(address_map &map); void pci_config_map(address_map &map); @@ -125,8 +124,8 @@ public: void shared_sh4_sdram_w(offs_t offset, uint32_t data, uint32_t mem_mask); uint64_t i2cmem_dimm_r(); void i2cmem_dimm_w(uint64_t data); - uint8_t pic_dimm_r(offs_t offset); - void pic_dimm_w(offs_t offset, uint8_t data); + uint8_t pic_dimm_r(); + void pic_dimm_w(offs_t offset, uint8_t data, uint8_t mem_mask); protected: virtual void device_start() override;