diff --git a/src/emu/cpu/pic16c5x/pic16c5x.c b/src/emu/cpu/pic16c5x/pic16c5x.c index 1b78a78b88f..3ab526f9a28 100644 --- a/src/emu/cpu/pic16c5x/pic16c5x.c +++ b/src/emu/cpu/pic16c5x/pic16c5x.c @@ -65,82 +65,109 @@ #include "pic16c5x.h" +const device_type PIC16C54 = &device_creator; +const device_type PIC16C55 = &device_creator; +const device_type PIC16C56 = &device_creator; +const device_type PIC16C57 = &device_creator; +const device_type PIC16C58 = &device_creator; -struct pic16c5x_state +/**************************************************************************** + * Internal Memory Maps + ****************************************************************************/ + +static ADDRESS_MAP_START( pic16c5x_rom_9, AS_PROGRAM, 16, pic16c5x_device ) + AM_RANGE(0x000, 0x1ff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( pic16c5x_ram_5, AS_DATA, 8, pic16c5x_device ) + AM_RANGE(0x00, 0x07) AM_RAM + AM_RANGE(0x08, 0x0f) AM_RAM + AM_RANGE(0x10, 0x1f) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( pic16c5x_rom_10, AS_PROGRAM, 16, pic16c5x_device ) + AM_RANGE(0x000, 0x3ff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( pic16c5x_rom_11, AS_PROGRAM, 16, pic16c5x_device ) + AM_RANGE(0x000, 0x7ff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( pic16c5x_ram_7, AS_DATA, 8, pic16c5x_device ) + AM_RANGE(0x00, 0x07) AM_RAM AM_MIRROR(0x60) + AM_RANGE(0x08, 0x0f) AM_RAM AM_MIRROR(0x60) + AM_RANGE(0x10, 0x1f) AM_RAM + AM_RANGE(0x30, 0x3f) AM_RAM + AM_RANGE(0x50, 0x5f) AM_RAM + AM_RANGE(0x70, 0x7f) AM_RAM +ADDRESS_MAP_END + + +pic16c5x_device::pic16c5x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, int program_width, int data_width, int picmodel) + : cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__) + , m_program_config("program", ENDIANNESS_LITTLE, 16, program_width, -1 + , ( ( program_width == 9 ) ? ADDRESS_MAP_NAME(pic16c5x_rom_9) : ( ( program_width == 10 ) ? ADDRESS_MAP_NAME(pic16c5x_rom_10) : ADDRESS_MAP_NAME(pic16c5x_rom_11) ))) + , m_data_config("data", ENDIANNESS_LITTLE, 8, data_width, 0 + , ( ( data_width == 5 ) ? ADDRESS_MAP_NAME(pic16c5x_ram_5) : ADDRESS_MAP_NAME(pic16c5x_ram_7) ) ) + , m_io_config("io", ENDIANNESS_LITTLE, 8, 5, 0) + , m_reset_vector((program_width == 9) ? 0x1ff : ((program_width == 10) ? 0x3ff : 0x7ff)) + , m_picmodel(picmodel) + , m_picRAMmask((data_width == 5) ? 0x1f : 0x7f) { - /******************** CPU Internal Registers *******************/ - UINT16 PC; - UINT16 PREVPC; /* previous program counter */ - UINT8 W; - UINT8 OPTION; - UINT16 CONFIG; - UINT8 ALU; - UINT16 WDT; - UINT8 TRISA; - UINT8 TRISB; - UINT8 TRISC; - UINT16 STACK[2]; - UINT16 prescaler; /* Note: this is really an 8-bit register */ - PAIR opcode; - UINT8 *internalram; - - int icount; - int reset_vector; - int picmodel; - int delay_timer; - UINT16 temp_config; - UINT8 old_T0; - INT8 old_data; - UINT8 picRAMmask; - int inst_cycles; - - - legacy_cpu_device *device; - address_space *program; - direct_read_data *direct; - address_space *data; - address_space *io; -}; - -INLINE pic16c5x_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == PIC16C54 || - device->type() == PIC16C55 || - device->type() == PIC16C56 || - device->type() == PIC16C57 || - device->type() == PIC16C58); - return (pic16c5x_state *)downcast(device)->token(); } -/* opcode table entry */ -struct pic16c5x_opcode +pic16c54_device::pic16c54_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pic16c5x_device(mconfig, PIC16C54, "PIC16C54", tag, owner, clock, "pic16c54", 9, 5, 0x16C54) { - UINT8 cycles; - void (*function)(pic16c5x_state *); -}; +} + +pic16c55_device::pic16c55_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pic16c5x_device(mconfig, PIC16C55, "PIC16C55", tag, owner, clock, "pic16c55", 9, 5, 0x16C55) +{ +} + +pic16c56_device::pic16c56_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pic16c5x_device(mconfig, PIC16C56, "PIC16C56", tag, owner, clock, "pic16c56", 10, 5, 0x16C56) +{ +} + +pic16c57_device::pic16c57_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pic16c5x_device(mconfig, PIC16C57, "PIC16C57", tag, owner, clock, "pic16c57", 11, 7, 0x16C57) +{ +} + +pic16c58_device::pic16c58_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : pic16c5x_device(mconfig, PIC16C58, "PIC16C58", tag, owner, clock, "pic16c58", 11, 7, 0x16C58) +{ +} -INLINE void update_internalram_ptr(pic16c5x_state *cpustate) +offs_t pic16c5x_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { - cpustate->internalram = (UINT8 *)cpustate->data->get_write_ptr(0x00); + extern CPU_DISASSEMBLE( pic16c5x ); + return CPU_DISASSEMBLE_NAME(pic16c5x)(this, buffer, pc, oprom, opram, options); +} + + +void pic16c5x_device::update_internalram_ptr() +{ + m_internalram = (UINT8 *)m_data->get_write_ptr(0x00); } - -#define PIC16C5x_RDOP(A) (cpustate->direct->read_decrypted_word((A)<<1)) -#define PIC16C5x_RAM_RDMEM(A) ((UINT8)cpustate->data->read_byte(A)) -#define PIC16C5x_RAM_WRMEM(A,V) (cpustate->data->write_byte(A,V)) -#define PIC16C5x_In(Port) ((UINT8)cpustate->io->read_byte((Port))) -#define PIC16C5x_Out(Port,Value) (cpustate->io->write_byte((Port),Value)) +#define PIC16C5x_RDOP(A) (m_direct->read_decrypted_word((A)<<1)) +#define PIC16C5x_RAM_RDMEM(A) ((UINT8)m_data->read_byte(A)) +#define PIC16C5x_RAM_WRMEM(A,V) (m_data->write_byte(A,V)) +#define PIC16C5x_In(Port) ((UINT8)m_io->read_byte((Port))) +#define PIC16C5x_Out(Port,Value) (m_io->write_byte((Port),Value)) /************ Read the state of the T0 Clock input signal ************/ -#define PIC16C5x_T0_In (cpustate->io->read_byte(PIC16C5x_T0)) +#define PIC16C5x_T0_In (m_io->read_byte(PIC16C5x_T0)) -#define M_RDRAM(A) (((A) < 8) ? cpustate->internalram[A] : PIC16C5x_RAM_RDMEM(A)) -#define M_WRTRAM(A,V) do { if ((A) < 8) cpustate->internalram[A] = (V); else PIC16C5x_RAM_WRMEM(A,V); } while (0) +#define M_RDRAM(A) (((A) < 8) ? m_internalram[A] : PIC16C5x_RAM_RDMEM(A)) +#define M_WRTRAM(A,V) do { if ((A) < 8) m_internalram[A] = (V); else PIC16C5x_RAM_WRMEM(A,V); } while (0) #define M_RDOP(A) PIC16C5x_RDOP(A) #define P_IN(A) PIC16C5x_In(A) #define P_OUT(A,V) PIC16C5x_Out(A,V) @@ -149,19 +176,19 @@ INLINE void update_internalram_ptr(pic16c5x_state *cpustate) -#define TMR0 internalram[1] -#define PCL internalram[2] -#define STATUS internalram[3] -#define FSR internalram[4] -#define PORTA internalram[5] -#define PORTB internalram[6] -#define PORTC internalram[7] -#define INDF M_RDRAM(cpustate->FSR) +#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 PORTC m_internalram[7] +#define INDF M_RDRAM(FSR) -#define ADDR (cpustate->opcode.b.l & 0x1f) +#define ADDR (m_opcode.b.l & 0x1f) -#define RISING_EDGE_T0 (( (int)(T0_in - cpustate->old_T0) > 0) ? 1 : 0) -#define FALLING_EDGE_T0 (( (int)(T0_in - cpustate->old_T0) < 0) ? 1 : 0) +#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) /******** The following is the Status Flag register definition. *********/ @@ -174,12 +201,12 @@ INLINE void update_internalram_ptr(pic16c5x_state *cpustate) #define DC_FLAG 0x02 /* DC Digit Carry/Borrow flag (Nibble) */ #define C_FLAG 0x01 /* C Carry/Borrow Flag (Byte) */ -#define PA (cpustate->STATUS & PA_REG) -#define TO (cpustate->STATUS & TO_FLAG) -#define PD (cpustate->STATUS & PD_FLAG) -#define ZERO (cpustate->STATUS & Z_FLAG) -#define DC (cpustate->STATUS & DC_FLAG) -#define CARRY (cpustate->STATUS & C_FLAG) +#define PA (STATUS & PA_REG) +#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) /******** The following is the Option Flag register definition. *********/ @@ -190,10 +217,10 @@ INLINE void update_internalram_ptr(pic16c5x_state *cpustate) #define PSA_FLAG 0x08 /* PSA Prescaler Assignment bit */ #define PS_REG 0x07 /* PS Prescaler Rate select */ -#define T0CS (cpustate->OPTION & T0CS_FLAG) -#define T0SE (cpustate->OPTION & T0SE_FLAG) -#define PSA (cpustate->OPTION & PSA_FLAG) -#define PS (cpustate->OPTION & PS_REG) +#define T0CS (m_OPTION & T0CS_FLAG) +#define T0SE (m_OPTION & T0SE_FLAG) +#define PSA (m_OPTION & PSA_FLAG) +#define PS (m_OPTION & PS_REG) /******** The following is the Config Flag register definition. *********/ @@ -203,8 +230,8 @@ INLINE void update_internalram_ptr(pic16c5x_state *cpustate) #define WDTE_FLAG 0x04 /* WDTE WatchDog Timer enable */ #define FOSC_FLAG 0x03 /* FOSC Oscillator source select */ -#define WDTE (cpustate->CONFIG & WDTE_FLAG) -#define FOSC (cpustate->CONFIG & FOSC_FLAG) +#define WDTE (m_CONFIG & WDTE_FLAG) +#define FOSC (m_CONFIG & FOSC_FLAG) /************************************************************************ @@ -216,84 +243,84 @@ INLINE void update_internalram_ptr(pic16c5x_state *cpustate) /* Easy bit position selectors */ -#define POS ((cpustate->opcode.b.l >> 5) & 7) +#define POS ((m_opcode.b.l >> 5) & 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 }; -INLINE void CALCULATE_Z_FLAG(pic16c5x_state *cpustate) +void pic16c5x_device::CALCULATE_Z_FLAG() { - if (cpustate->ALU == 0) SET(cpustate->STATUS, Z_FLAG); - else CLR(cpustate->STATUS, Z_FLAG); + if (m_ALU == 0) SET(STATUS, Z_FLAG); + else CLR(STATUS, Z_FLAG); } -INLINE void CALCULATE_ADD_CARRY(pic16c5x_state *cpustate) +void pic16c5x_device::CALCULATE_ADD_CARRY() { - if ((UINT8)(cpustate->old_data) > (UINT8)(cpustate->ALU)) { - SET(cpustate->STATUS, C_FLAG); + if ((UINT8)(m_old_data) > (UINT8)(m_ALU)) { + SET(STATUS, C_FLAG); } else { - CLR(cpustate->STATUS, C_FLAG); + CLR(STATUS, C_FLAG); } } -INLINE void CALCULATE_ADD_DIGITCARRY(pic16c5x_state *cpustate) +void pic16c5x_device::CALCULATE_ADD_DIGITCARRY() { - if (((UINT8)(cpustate->old_data) & 0x0f) > ((UINT8)(cpustate->ALU) & 0x0f)) { - SET(cpustate->STATUS, DC_FLAG); + if (((UINT8)(m_old_data) & 0x0f) > ((UINT8)(m_ALU) & 0x0f)) { + SET(STATUS, DC_FLAG); } else { - CLR(cpustate->STATUS, DC_FLAG); + CLR(STATUS, DC_FLAG); } } -INLINE void CALCULATE_SUB_CARRY(pic16c5x_state *cpustate) +void pic16c5x_device::CALCULATE_SUB_CARRY() { - if ((UINT8)(cpustate->old_data) < (UINT8)(cpustate->ALU)) { - CLR(cpustate->STATUS, C_FLAG); + if ((UINT8)(m_old_data) < (UINT8)(m_ALU)) { + CLR(STATUS, C_FLAG); } else { - SET(cpustate->STATUS, C_FLAG); + SET(STATUS, C_FLAG); } } -INLINE void CALCULATE_SUB_DIGITCARRY(pic16c5x_state *cpustate) +void pic16c5x_device::CALCULATE_SUB_DIGITCARRY() { - if (((UINT8)(cpustate->old_data) & 0x0f) < ((UINT8)(cpustate->ALU) & 0x0f)) { - CLR(cpustate->STATUS, DC_FLAG); + if (((UINT8)(m_old_data) & 0x0f) < ((UINT8)(m_ALU) & 0x0f)) { + CLR(STATUS, DC_FLAG); } else { - SET(cpustate->STATUS, DC_FLAG); + SET(STATUS, DC_FLAG); } } -INLINE UINT16 POP_STACK(pic16c5x_state *cpustate) +UINT16 pic16c5x_device::POP_STACK() { - UINT16 data = cpustate->STACK[1]; - cpustate->STACK[1] = cpustate->STACK[0]; + UINT16 data = m_STACK[1]; + m_STACK[1] = m_STACK[0]; return (data & ADDR_MASK); } -INLINE void PUSH_STACK(pic16c5x_state *cpustate, UINT16 data) +void pic16c5x_device::PUSH_STACK(UINT16 data) { - cpustate->STACK[0] = cpustate->STACK[1]; - cpustate->STACK[1] = (data & ADDR_MASK); + m_STACK[0] = m_STACK[1]; + m_STACK[1] = (data & ADDR_MASK); } -INLINE UINT8 GET_REGFILE(pic16c5x_state *cpustate, offs_t addr) /* Read from internal memory */ +UINT8 pic16c5x_device::GET_REGFILE(offs_t addr) /* Read from internal memory */ { UINT8 data; if (addr == 0) { /* Indirect addressing */ - addr = (cpustate->FSR & cpustate->picRAMmask); + addr = (FSR & m_picRAMmask); } - if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) { - addr |= (cpustate->FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */ + if ((m_picmodel == 0x16C57) || (m_picmodel == 0x16C58)) { + addr |= (FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */ } if ((addr & 0x10) == 0) addr &= 0x0f; @@ -303,21 +330,21 @@ INLINE UINT8 GET_REGFILE(pic16c5x_state *cpustate, offs_t addr) /* Read from int case 00: /* Not an actual register, so return 0 */ data = 0; break; - case 04: data = (cpustate->FSR | (UINT8)(~cpustate->picRAMmask)); + case 04: data = (FSR | (UINT8)(~m_picRAMmask)); break; case 05: data = P_IN(0); - data &= cpustate->TRISA; - data |= ((UINT8)(~cpustate->TRISA) & cpustate->PORTA); + data &= m_TRISA; + data |= ((UINT8)(~m_TRISA) & PORTA); data &= 0x0f; /* 4-bit port (only lower 4 bits used) */ break; case 06: data = P_IN(1); - data &= cpustate->TRISB; - data |= ((UINT8)(~cpustate->TRISB) & cpustate->PORTB); + data &= m_TRISB; + data |= ((UINT8)(~m_TRISB) & PORTB); break; - case 07: if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) { + case 07: if ((m_picmodel == 0x16C55) || (m_picmodel == 0x16C57)) { data = P_IN(2); - data &= cpustate->TRISC; - data |= ((UINT8)(~cpustate->TRISC) & cpustate->PORTC); + data &= m_TRISC; + data |= ((UINT8)(~m_TRISC) & PORTC); } else { /* PIC16C54, PIC16C56, PIC16C58 */ data = M_RDRAM(addr); @@ -329,14 +356,14 @@ INLINE UINT8 GET_REGFILE(pic16c5x_state *cpustate, offs_t addr) /* Read from int return data; } -INLINE void STORE_REGFILE(pic16c5x_state *cpustate, offs_t addr, UINT8 data) /* Write to internal memory */ +void pic16c5x_device::STORE_REGFILE(offs_t addr, UINT8 data) /* Write to internal memory */ { if (addr == 0) { /* Indirect addressing */ - addr = (cpustate->FSR & cpustate->picRAMmask); + addr = (FSR & m_picRAMmask); } - if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) { - addr |= (cpustate->FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */ + if ((m_picmodel == 0x16C57) || (m_picmodel == 0x16C58)) { + addr |= (FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */ } if ((addr & 0x10) == 0) addr &= 0x0f; @@ -345,25 +372,25 @@ INLINE void STORE_REGFILE(pic16c5x_state *cpustate, offs_t addr, UINT8 data) { case 00: /* Not an actual register, nothing to save */ break; - case 01: cpustate->delay_timer = 2; /* Timer starts after next two instructions */ - if (PSA == 0) cpustate->prescaler = 0; /* Must clear the Prescaler */ - cpustate->TMR0 = data; + case 01: m_delay_timer = 2; /* Timer starts after next two instructions */ + if (PSA == 0) m_prescaler = 0; /* Must clear the Prescaler */ + TMR0 = data; break; - case 02: cpustate->PCL = data; - cpustate->PC = ((cpustate->STATUS & PA_REG) << 4) | data; + case 02: PCL = data; + m_PC = ((STATUS & PA_REG) << 4) | data; break; - case 03: cpustate->STATUS &= (UINT8)(~PA_REG); cpustate->STATUS |= (data & PA_REG); + case 03: STATUS &= (UINT8)(~PA_REG); STATUS |= (data & PA_REG); break; - case 04: cpustate->FSR = (data | (UINT8)(~cpustate->picRAMmask)); + case 04: FSR = (data | (UINT8)(~m_picRAMmask)); break; case 05: data &= 0x0f; /* 4-bit port (only lower 4 bits used) */ - P_OUT(0,data & (UINT8)(~cpustate->TRISA)); cpustate->PORTA = data; + P_OUT(0,data & (UINT8)(~m_TRISA)); PORTA = data; break; - case 06: P_OUT(1,data & (UINT8)(~cpustate->TRISB)); cpustate->PORTB = data; + case 06: P_OUT(1,data & (UINT8)(~m_TRISB)); PORTB = data; break; - case 07: if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) { - P_OUT(2,data & (UINT8)(~cpustate->TRISC)); - cpustate->PORTC = data; + case 07: if ((m_picmodel == 0x16C55) || (m_picmodel == 0x16C57)) { + P_OUT(2,data & (UINT8)(~m_TRISC)); + PORTC = data; } else { /* PIC16C54, PIC16C56, PIC16C58 */ M_WRTRAM(addr, data); @@ -375,15 +402,15 @@ INLINE void STORE_REGFILE(pic16c5x_state *cpustate, offs_t addr, UINT8 data) } -INLINE void STORE_RESULT(pic16c5x_state *cpustate, offs_t addr, UINT8 data) +void pic16c5x_device::STORE_RESULT(offs_t addr, UINT8 data) { - if (cpustate->opcode.b.l & 0x20) + if (m_opcode.b.l & 0x20) { - STORE_REGFILE(cpustate, addr, data); + STORE_REGFILE(addr, data); } else { - cpustate->W = data; + m_W = data; } } @@ -396,274 +423,274 @@ INLINE void STORE_RESULT(pic16c5x_state *cpustate, offs_t addr, UINT8 data) /* the opcode call function. This function is never called. */ -static void illegal(pic16c5x_state *cpustate) +void pic16c5x_device::illegal() { - logerror("PIC16C5x: PC=%03x, Illegal opcode = %04x\n", (cpustate->PC-1), cpustate->opcode.w.l); + logerror("PIC16C5x: PC=%03x, Illegal opcode = %04x\n", (m_PC-1), m_opcode.w.l); } -static void addwf(pic16c5x_state *cpustate) +void pic16c5x_device::addwf() { - cpustate->old_data = GET_REGFILE(cpustate, ADDR); - cpustate->ALU = cpustate->old_data + cpustate->W; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); - CALCULATE_ADD_CARRY(cpustate); - CALCULATE_ADD_DIGITCARRY(cpustate); + m_old_data = GET_REGFILE(ADDR); + m_ALU = m_old_data + m_W; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); + CALCULATE_ADD_CARRY(); + CALCULATE_ADD_DIGITCARRY(); } -static void andwf(pic16c5x_state *cpustate) +void pic16c5x_device::andwf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) & cpustate->W; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR) & m_W; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void andlw(pic16c5x_state *cpustate) +void pic16c5x_device::andlw() { - cpustate->ALU = cpustate->opcode.b.l & cpustate->W; - cpustate->W = cpustate->ALU; - CALCULATE_Z_FLAG(cpustate); + m_ALU = m_opcode.b.l & m_W; + m_W = m_ALU; + CALCULATE_Z_FLAG(); } -static void bcf(pic16c5x_state *cpustate) +void pic16c5x_device::bcf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR); - cpustate->ALU &= bit_clr[POS]; - STORE_REGFILE(cpustate, ADDR, cpustate->ALU); + m_ALU = GET_REGFILE(ADDR); + m_ALU &= bit_clr[POS]; + STORE_REGFILE(ADDR, m_ALU); } -static void bsf(pic16c5x_state *cpustate) +void pic16c5x_device::bsf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR); - cpustate->ALU |= bit_set[POS]; - STORE_REGFILE(cpustate, ADDR, cpustate->ALU); + m_ALU = GET_REGFILE(ADDR); + m_ALU |= bit_set[POS]; + STORE_REGFILE(ADDR, m_ALU); } -static void btfss(pic16c5x_state *cpustate) +void pic16c5x_device::btfss() { - if ((GET_REGFILE(cpustate, ADDR) & bit_set[POS]) == bit_set[POS]) + if ((GET_REGFILE(ADDR) & bit_set[POS]) == bit_set[POS]) { - cpustate->PC++ ; - cpustate->PCL = cpustate->PC & 0xff; - cpustate->inst_cycles += 1; /* Add NOP cycles */ + m_PC++ ; + PCL = m_PC & 0xff; + m_inst_cycles += 1; /* Add NOP cycles */ } } -static void btfsc(pic16c5x_state *cpustate) +void pic16c5x_device::btfsc() { - if ((GET_REGFILE(cpustate, ADDR) & bit_set[POS]) == 0) + if ((GET_REGFILE(ADDR) & bit_set[POS]) == 0) { - cpustate->PC++ ; - cpustate->PCL = cpustate->PC & 0xff; - cpustate->inst_cycles += 1; /* Add NOP cycles */ + m_PC++ ; + PCL = m_PC & 0xff; + m_inst_cycles += 1; /* Add NOP cycles */ } } -static void call(pic16c5x_state *cpustate) +void pic16c5x_device::call() { - PUSH_STACK(cpustate, cpustate->PC); - cpustate->PC = ((cpustate->STATUS & PA_REG) << 4) | cpustate->opcode.b.l; - cpustate->PC &= 0x6ff; - cpustate->PCL = cpustate->PC & 0xff; + PUSH_STACK(m_PC); + m_PC = ((STATUS & PA_REG) << 4) | m_opcode.b.l; + m_PC &= 0x6ff; + PCL = m_PC & 0xff; } -static void clrw(pic16c5x_state *cpustate) +void pic16c5x_device::clrw() { - cpustate->W = 0; - SET(cpustate->STATUS, Z_FLAG); + m_W = 0; + SET(STATUS, Z_FLAG); } -static void clrf(pic16c5x_state *cpustate) +void pic16c5x_device::clrf() { - STORE_REGFILE(cpustate, ADDR, 0); - SET(cpustate->STATUS, Z_FLAG); + STORE_REGFILE(ADDR, 0); + SET(STATUS, Z_FLAG); } -static void clrwdt(pic16c5x_state *cpustate) +void pic16c5x_device::clrwdt() { - cpustate->WDT = 0; - if (PSA) cpustate->prescaler = 0; - SET(cpustate->STATUS, TO_FLAG); - SET(cpustate->STATUS, PD_FLAG); + m_WDT = 0; + if (PSA) m_prescaler = 0; + SET(STATUS, TO_FLAG); + SET(STATUS, PD_FLAG); } -static void comf(pic16c5x_state *cpustate) +void pic16c5x_device::comf() { - cpustate->ALU = (UINT8)(~(GET_REGFILE(cpustate, ADDR))); - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = (UINT8)(~(GET_REGFILE(ADDR))); + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void decf(pic16c5x_state *cpustate) +void pic16c5x_device::decf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) - 1; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR) - 1; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void decfsz(pic16c5x_state *cpustate) +void pic16c5x_device::decfsz() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) - 1; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - if (cpustate->ALU == 0) + m_ALU = GET_REGFILE(ADDR) - 1; + STORE_RESULT(ADDR, m_ALU); + if (m_ALU == 0) { - cpustate->PC++ ; - cpustate->PCL = cpustate->PC & 0xff; - cpustate->inst_cycles += 1; /* Add NOP cycles */ + m_PC++ ; + PCL = m_PC & 0xff; + m_inst_cycles += 1; /* Add NOP cycles */ } } -static void goto_op(pic16c5x_state *cpustate) +void pic16c5x_device::goto_op() { - cpustate->PC = ((cpustate->STATUS & PA_REG) << 4) | (cpustate->opcode.w.l & 0x1ff); - cpustate->PC &= ADDR_MASK; - cpustate->PCL = cpustate->PC & 0xff; + m_PC = ((STATUS & PA_REG) << 4) | (m_opcode.w.l & 0x1ff); + m_PC &= ADDR_MASK; + PCL = m_PC & 0xff; } -static void incf(pic16c5x_state *cpustate) +void pic16c5x_device::incf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) + 1; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR) + 1; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void incfsz(pic16c5x_state *cpustate) +void pic16c5x_device::incfsz() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) + 1; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - if (cpustate->ALU == 0) + m_ALU = GET_REGFILE(ADDR) + 1; + STORE_RESULT(ADDR, m_ALU); + if (m_ALU == 0) { - cpustate->PC++ ; - cpustate->PCL = cpustate->PC & 0xff; - cpustate->inst_cycles += 1; /* Add NOP cycles */ + m_PC++ ; + PCL = m_PC & 0xff; + m_inst_cycles += 1; /* Add NOP cycles */ } } -static void iorlw(pic16c5x_state *cpustate) +void pic16c5x_device::iorlw() { - cpustate->ALU = cpustate->opcode.b.l | cpustate->W; - cpustate->W = cpustate->ALU; - CALCULATE_Z_FLAG(cpustate); + m_ALU = m_opcode.b.l | m_W; + m_W = m_ALU; + CALCULATE_Z_FLAG(); } -static void iorwf(pic16c5x_state *cpustate) +void pic16c5x_device::iorwf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) | cpustate->W; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR) | m_W; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void movf(pic16c5x_state *cpustate) +void pic16c5x_device::movf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR); - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR); + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } -static void movlw(pic16c5x_state *cpustate) +void pic16c5x_device::movlw() { - cpustate->W = cpustate->opcode.b.l; + m_W = m_opcode.b.l; } -static void movwf(pic16c5x_state *cpustate) +void pic16c5x_device::movwf() { - STORE_REGFILE(cpustate, ADDR, cpustate->W); + STORE_REGFILE(ADDR, m_W); } -static void nop(pic16c5x_state *cpustate) +void pic16c5x_device::nop() { /* Do nothing */ } -static void option(pic16c5x_state *cpustate) +void pic16c5x_device::option() { - cpustate->OPTION = cpustate->W & (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG); + m_OPTION = m_W & (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG); } -static void retlw(pic16c5x_state *cpustate) +void pic16c5x_device::retlw() { - cpustate->W = cpustate->opcode.b.l; - cpustate->PC = POP_STACK(cpustate); - cpustate->PCL = cpustate->PC & 0xff; + m_W = m_opcode.b.l; + m_PC = POP_STACK(); + PCL = m_PC & 0xff; } -static void rlf(pic16c5x_state *cpustate) +void pic16c5x_device::rlf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR); - cpustate->ALU <<= 1; - if (cpustate->STATUS & C_FLAG) cpustate->ALU |= 1; - if (GET_REGFILE(cpustate, ADDR) & 0x80) SET(cpustate->STATUS, C_FLAG); - else CLR(cpustate->STATUS, C_FLAG); - STORE_RESULT(cpustate, ADDR, cpustate->ALU); + 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); + STORE_RESULT(ADDR, m_ALU); } -static void rrf(pic16c5x_state *cpustate) +void pic16c5x_device::rrf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR); - cpustate->ALU >>= 1; - if (cpustate->STATUS & C_FLAG) cpustate->ALU |= 0x80; - if (GET_REGFILE(cpustate, ADDR) & 1) SET(cpustate->STATUS, C_FLAG); - else CLR(cpustate->STATUS, C_FLAG); - STORE_RESULT(cpustate, ADDR, cpustate->ALU); + 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); + STORE_RESULT(ADDR, m_ALU); } -static void sleepic(pic16c5x_state *cpustate) +void pic16c5x_device::sleepic() { - if (WDTE) cpustate->WDT = 0; - if (PSA) cpustate->prescaler = 0; - SET(cpustate->STATUS, TO_FLAG); - CLR(cpustate->STATUS, PD_FLAG); + if (WDTE) m_WDT = 0; + if (PSA) m_prescaler = 0; + SET(STATUS, TO_FLAG); + CLR(STATUS, PD_FLAG); } -static void subwf(pic16c5x_state *cpustate) +void pic16c5x_device::subwf() { - cpustate->old_data = GET_REGFILE(cpustate, ADDR); - cpustate->ALU = cpustate->old_data - cpustate->W; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); - CALCULATE_SUB_CARRY(cpustate); - CALCULATE_SUB_DIGITCARRY(cpustate); + m_old_data = GET_REGFILE(ADDR); + m_ALU = m_old_data - m_W; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); + CALCULATE_SUB_CARRY(); + CALCULATE_SUB_DIGITCARRY(); } -static void swapf(pic16c5x_state *cpustate) +void pic16c5x_device::swapf() { - cpustate->ALU = ((GET_REGFILE(cpustate, ADDR) << 4) & 0xf0); - cpustate->ALU |= ((GET_REGFILE(cpustate, ADDR) >> 4) & 0x0f); - STORE_RESULT(cpustate, ADDR, cpustate->ALU); + m_ALU = ((GET_REGFILE(ADDR) << 4) & 0xf0); + m_ALU |= ((GET_REGFILE(ADDR) >> 4) & 0x0f); + STORE_RESULT(ADDR, m_ALU); } -static void tris(pic16c5x_state *cpustate) +void pic16c5x_device::tris() { - switch(cpustate->opcode.b.l & 0x7) + switch(m_opcode.b.l & 0x7) { - case 05: if (cpustate->TRISA == cpustate->W) break; - else { cpustate->TRISA = cpustate->W | 0xf0; P_OUT(0,cpustate->PORTA & (UINT8)(~cpustate->TRISA) & 0x0f); break; } - case 06: if (cpustate->TRISB == cpustate->W) break; - else { cpustate->TRISB = cpustate->W; P_OUT(1,cpustate->PORTB & (UINT8)(~cpustate->TRISB)); break; } - case 07: if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) { - if (cpustate->TRISC == cpustate->W) break; - else { cpustate->TRISC = cpustate->W; P_OUT(2,cpustate->PORTC & (UINT8)(~cpustate->TRISC)); break; } + case 05: if (m_TRISA == m_W) break; + else { m_TRISA = m_W | 0xf0; P_OUT(0,PORTA & (UINT8)(~m_TRISA) & 0x0f); break; } + case 06: if (m_TRISB == m_W) break; + else { m_TRISB = m_W; P_OUT(1,PORTB & (UINT8)(~m_TRISB)); break; } + case 07: if ((m_picmodel == 0x16C55) || (m_picmodel == 0x16C57)) { + if (m_TRISC == m_W) break; + else { m_TRISC = m_W; P_OUT(2,PORTC & (UINT8)(~m_TRISC)); break; } } else { - illegal(cpustate); break; + illegal(); break; } - default: illegal(cpustate); break; + default: illegal(); break; } } -static void xorlw(pic16c5x_state *cpustate) +void pic16c5x_device::xorlw() { - cpustate->ALU = cpustate->W ^ cpustate->opcode.b.l; - cpustate->W = cpustate->ALU; - CALCULATE_Z_FLAG(cpustate); + m_ALU = m_W ^ m_opcode.b.l; + m_W = m_ALU; + CALCULATE_Z_FLAG(); } -static void xorwf(pic16c5x_state *cpustate) +void pic16c5x_device::xorwf() { - cpustate->ALU = GET_REGFILE(cpustate, ADDR) ^ cpustate->W; - STORE_RESULT(cpustate, ADDR, cpustate->ALU); - CALCULATE_Z_FLAG(cpustate); + m_ALU = GET_REGFILE(ADDR) ^ m_W; + STORE_RESULT(ADDR, m_ALU); + CALCULATE_Z_FLAG(); } @@ -673,47 +700,81 @@ static void xorwf(pic16c5x_state *cpustate) * Opcode Table (Cycles, Instruction) ***********************************************************************/ -static const pic16c5x_opcode opcode_main[256]= +const pic16c5x_device::pic16c5x_opcode pic16c5x_device::s_opcode_main[256]= { -/*00*/ {1, nop },{0, illegal },{1, movwf },{1, movwf },{1, clrw },{0, illegal },{1, clrf },{1, clrf }, -/*08*/ {1, subwf },{1, subwf },{1, subwf },{1, subwf },{1, decf },{1, decf },{1, decf },{1, decf }, -/*10*/ {1, iorwf },{1, iorwf },{1, iorwf },{1, iorwf },{1, andwf },{1, andwf },{1, andwf },{1, andwf }, -/*18*/ {1, xorwf },{1, xorwf },{1, xorwf },{1, xorwf },{1, addwf },{1, addwf },{1, addwf },{1, addwf }, -/*20*/ {1, movf },{1, movf },{1, movf },{1, movf },{1, comf },{1, comf },{1, comf },{1, comf }, -/*28*/ {1, incf },{1, incf },{1, incf },{1, incf },{1, decfsz },{1, decfsz },{1, decfsz },{1, decfsz }, -/*30*/ {1, rrf },{1, rrf },{1, rrf },{1, rrf },{1, rlf },{1, rlf },{1, rlf },{1, rlf }, -/*38*/ {1, swapf },{1, swapf },{1, swapf },{1, swapf },{1, incfsz },{1, incfsz },{1, incfsz },{1, incfsz }, -/*40*/ {1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf }, -/*48*/ {1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf },{1, bcf }, -/*50*/ {1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf }, -/*58*/ {1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf },{1, bsf }, -/*60*/ {1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc }, -/*68*/ {1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc },{1, btfsc }, -/*70*/ {1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss }, -/*78*/ {1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss },{1, btfss }, -/*80*/ {2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw }, -/*88*/ {2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw },{2, retlw }, -/*90*/ {2, call },{2, call },{2, call },{2, call },{2, call },{2, call },{2, call },{2, call }, -/*98*/ {2, call },{2, call },{2, call },{2, call },{2, call },{2, call },{2, call },{2, call }, -/*A0*/ {2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op }, -/*A8*/ {2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op }, -/*B0*/ {2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op }, -/*B8*/ {2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op },{2, goto_op }, -/*C0*/ {1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw }, -/*C8*/ {1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw },{1, movlw }, -/*D0*/ {1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw }, -/*D8*/ {1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw },{1, iorlw }, -/*E0*/ {1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw }, -/*E8*/ {1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw },{1, andlw }, -/*F0*/ {1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw }, -/*F8*/ {1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw },{1, xorlw } +/*00*/ {1, &pic16c5x_device::nop },{0, &pic16c5x_device::illegal },{1, &pic16c5x_device::movwf },{1, &pic16c5x_device::movwf }, + {1, &pic16c5x_device::clrw },{0, &pic16c5x_device::illegal },{1, &pic16c5x_device::clrf },{1, &pic16c5x_device::clrf }, +/*08*/ {1, &pic16c5x_device::subwf },{1, &pic16c5x_device::subwf },{1, &pic16c5x_device::subwf },{1, &pic16c5x_device::subwf }, + {1, &pic16c5x_device::decf },{1, &pic16c5x_device::decf },{1, &pic16c5x_device::decf },{1, &pic16c5x_device::decf }, +/*10*/ {1, &pic16c5x_device::iorwf },{1, &pic16c5x_device::iorwf },{1, &pic16c5x_device::iorwf },{1, &pic16c5x_device::iorwf }, + {1, &pic16c5x_device::andwf },{1, &pic16c5x_device::andwf },{1, &pic16c5x_device::andwf },{1, &pic16c5x_device::andwf }, +/*18*/ {1, &pic16c5x_device::xorwf },{1, &pic16c5x_device::xorwf },{1, &pic16c5x_device::xorwf },{1, &pic16c5x_device::xorwf }, + {1, &pic16c5x_device::addwf },{1, &pic16c5x_device::addwf },{1, &pic16c5x_device::addwf },{1, &pic16c5x_device::addwf }, +/*20*/ {1, &pic16c5x_device::movf },{1, &pic16c5x_device::movf },{1, &pic16c5x_device::movf },{1, &pic16c5x_device::movf }, + {1, &pic16c5x_device::comf },{1, &pic16c5x_device::comf },{1, &pic16c5x_device::comf },{1, &pic16c5x_device::comf }, +/*28*/ {1, &pic16c5x_device::incf },{1, &pic16c5x_device::incf },{1, &pic16c5x_device::incf },{1, &pic16c5x_device::incf }, + {1, &pic16c5x_device::decfsz },{1, &pic16c5x_device::decfsz },{1, &pic16c5x_device::decfsz },{1, &pic16c5x_device::decfsz }, +/*30*/ {1, &pic16c5x_device::rrf },{1, &pic16c5x_device::rrf },{1, &pic16c5x_device::rrf },{1, &pic16c5x_device::rrf }, + {1, &pic16c5x_device::rlf },{1, &pic16c5x_device::rlf },{1, &pic16c5x_device::rlf },{1, &pic16c5x_device::rlf }, +/*38*/ {1, &pic16c5x_device::swapf },{1, &pic16c5x_device::swapf },{1, &pic16c5x_device::swapf },{1, &pic16c5x_device::swapf }, + {1, &pic16c5x_device::incfsz },{1, &pic16c5x_device::incfsz },{1, &pic16c5x_device::incfsz },{1, &pic16c5x_device::incfsz }, +/*40*/ {1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf }, + {1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf }, +/*48*/ {1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf }, + {1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf },{1, &pic16c5x_device::bcf }, +/*50*/ {1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf }, + {1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf }, +/*58*/ {1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf }, + {1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf },{1, &pic16c5x_device::bsf }, +/*60*/ {1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc }, + {1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc }, +/*68*/ {1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc }, + {1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc },{1, &pic16c5x_device::btfsc }, +/*70*/ {1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss }, + {1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss }, +/*78*/ {1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss }, + {1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss },{1, &pic16c5x_device::btfss }, +/*80*/ {2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw }, + {2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw }, +/*88*/ {2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw }, + {2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw },{2, &pic16c5x_device::retlw }, +/*90*/ {2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call }, + {2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call }, +/*98*/ {2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call }, + {2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call },{2, &pic16c5x_device::call }, +/*A0*/ {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, + {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, +/*A8*/ {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, + {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, +/*B0*/ {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, + {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, +/*B8*/ {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, + {2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op },{2, &pic16c5x_device::goto_op }, +/*C0*/ {1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw }, + {1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw }, +/*C8*/ {1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw }, + {1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw },{1, &pic16c5x_device::movlw }, +/*D0*/ {1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw }, + {1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw }, +/*D8*/ {1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw }, + {1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw },{1, &pic16c5x_device::iorlw }, +/*E0*/ {1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw }, + {1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw }, +/*E8*/ {1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw }, + {1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw },{1, &pic16c5x_device::andlw }, +/*F0*/ {1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw }, + {1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw }, +/*F8*/ {1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw }, + {1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw },{1, &pic16c5x_device::xorlw } }; -static const pic16c5x_opcode opcode_00x[16]= +const pic16c5x_device::pic16c5x_opcode pic16c5x_device::s_opcode_00x[16]= { -/*00*/ {1, nop },{0, illegal },{1, option },{1, sleepic },{1, clrwdt },{1, tris },{1, tris },{1, tris }, -/*08*/ {0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal },{0, illegal } +/*00*/ {1, &pic16c5x_device::nop },{0, &pic16c5x_device::illegal },{1, &pic16c5x_device::option },{1, &pic16c5x_device::sleepic }, + {1, &pic16c5x_device::clrwdt },{1, &pic16c5x_device::tris },{1, &pic16c5x_device::tris },{1, &pic16c5x_device::tris }, +/*08*/ {0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal }, + {0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal },{0, &pic16c5x_device::illegal } }; @@ -722,96 +783,190 @@ static const pic16c5x_opcode opcode_00x[16]= * Inits CPU emulation ****************************************************************************/ -static CPU_INIT( pic16c5x ) +void pic16c5x_device::device_start() { - pic16c5x_state *cpustate = get_safe_token(device); - - cpustate->device = device; - cpustate->program = &device->space(AS_PROGRAM); - cpustate->direct = &cpustate->program->direct(); - cpustate->data = &device->space(AS_DATA); - cpustate->io = &device->space(AS_IO); + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + m_data = &space(AS_DATA); + m_io = &space(AS_IO); /* ensure the internal ram pointers are set before get_info is called */ - update_internalram_ptr(cpustate); + update_internalram_ptr(); - device->save_item(NAME(cpustate->W)); - device->save_item(NAME(cpustate->ALU)); - device->save_item(NAME(cpustate->OPTION)); - device->save_item(NAME(cpustate->TMR0)); - device->save_item(NAME(cpustate->PCL)); - device->save_item(NAME(cpustate->STATUS)); - device->save_item(NAME(cpustate->FSR)); - device->save_item(NAME(cpustate->PORTA)); - device->save_item(NAME(cpustate->PORTB)); - device->save_item(NAME(cpustate->PORTC)); - device->save_item(NAME(cpustate->TRISA)); - device->save_item(NAME(cpustate->TRISB)); - device->save_item(NAME(cpustate->TRISC)); - device->save_item(NAME(cpustate->old_T0)); - device->save_item(NAME(cpustate->old_data)); - device->save_item(NAME(cpustate->picRAMmask)); - device->save_item(NAME(cpustate->WDT)); - device->save_item(NAME(cpustate->prescaler)); - device->save_item(NAME(cpustate->STACK[0])); - device->save_item(NAME(cpustate->STACK[1])); - device->save_item(NAME(cpustate->PC)); - device->save_item(NAME(cpustate->PREVPC)); - device->save_item(NAME(cpustate->CONFIG)); - device->save_item(NAME(cpustate->opcode.d)); - device->save_item(NAME(cpustate->delay_timer)); - device->save_item(NAME(cpustate->picmodel)); - device->save_item(NAME(cpustate->reset_vector)); + save_item(NAME(m_W)); + save_item(NAME(m_ALU)); + save_item(NAME(m_OPTION)); + save_item(NAME(TMR0)); + save_item(NAME(PCL)); + save_item(NAME(STATUS)); + save_item(NAME(FSR)); + save_item(NAME(PORTA)); + save_item(NAME(PORTB)); + save_item(NAME(PORTC)); + save_item(NAME(m_TRISA)); + save_item(NAME(m_TRISB)); + save_item(NAME(m_TRISC)); + 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[0])); + save_item(NAME(m_STACK[1])); + 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_delay_timer)); + save_item(NAME(m_picmodel)); + save_item(NAME(m_reset_vector)); - device->save_item(NAME(cpustate->icount)); - device->save_item(NAME(cpustate->temp_config)); - device->save_item(NAME(cpustate->inst_cycles)); + save_item(NAME(m_temp_config)); + save_item(NAME(m_inst_cycles)); + + state_add( PIC16C5x_PC, "PC", m_PC).mask(0xfff).formatstr("%03X"); + state_add( PIC16C5x_W, "W", m_W).formatstr("%02X"); + state_add( PIC16C5x_ALU, "ALU", m_ALU).formatstr("%02X"); + state_add( PIC16C5x_STR, "STR", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); + state_add( PIC16C5x_TMR0, "TMR", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); + state_add( PIC16C5x_WDT, "WDT", m_WDT).formatstr("%04X"); + state_add( PIC16C5x_OPT, "OPT", m_OPTION).formatstr("%02X"); + state_add( PIC16C5x_STK0, "STK0", m_STACK[0]).mask(0xfff).formatstr("%03X"); + state_add( PIC16C5x_STK1, "STK1", m_STACK[1]).mask(0xfff).formatstr("%03X"); + state_add( PIC16C5x_PRTA, "PRTA", m_debugger_temp).mask(0xf).callimport().callexport().formatstr("%01X"); + state_add( PIC16C5x_PRTB, "PRTB", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); + state_add( PIC16C5x_PRTC, "PRTC", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); + state_add( PIC16C5x_TRSA, "TRSA", m_TRISA).mask(0xf).formatstr("%01X"); + state_add( PIC16C5x_TRSB, "TRSB", m_TRISB).formatstr("%02X"); + state_add( PIC16C5x_TRSC, "TRSC", m_TRISC).formatstr("%02X"); + state_add( PIC16C5x_FSR, "FSR", m_debugger_temp).mask(0xff).callimport().callexport().formatstr("%02X"); + state_add( PIC16C5x_PSCL, "PSCL:%c%02X", m_debugger_temp).callimport().formatstr("%3s"); + + state_add( STATE_GENPC, "GENPC", m_PC).noshow(); + state_add( STATE_GENFLAGS, "GENFLAGS", m_OPTION).formatstr("%13s").noshow(); + state_add( STATE_GENPCBASE, "PREVPC", m_PREVPC).noshow(); + + m_icountptr = &m_icount; } +void pic16c5x_device::state_import(const device_state_entry &entry) +{ + switch (entry.index()) + { + case PIC16C5x_STR: + STATUS = m_debugger_temp; + break; + case PIC16C5x_TMR0: + TMR0 = m_debugger_temp; + break; + case PIC16C5x_PRTA: + PORTA = m_debugger_temp; + break; + case PIC16C5x_PRTB: + PORTB = m_debugger_temp; + break; + case PIC16C5x_PRTC: + PORTC = m_debugger_temp; + break; + case PIC16C5x_FSR: + FSR = ((m_debugger_temp & m_picRAMmask) | (UINT8)(~m_picRAMmask)); + break; + case PIC16C5x_PSCL: + m_prescaler = m_debugger_temp; + break; + } +} + +void pic16c5x_device::state_export(const device_state_entry &entry) +{ + switch (entry.index()) + { + case PIC16C5x_STR: + m_debugger_temp = STATUS; + break; + case PIC16C5x_TMR0: + m_debugger_temp = TMR0; + break; + case PIC16C5x_PRTA: + m_debugger_temp = PORTA & 0x0f; + break; + case PIC16C5x_PRTB: + m_debugger_temp = PORTB; + break; + case PIC16C5x_PRTC: + m_debugger_temp = PORTC; + break; + case PIC16C5x_FSR: + m_debugger_temp = ((FSR) & m_picRAMmask) | (UINT8)(~m_picRAMmask); + break; + } +} + +void pic16c5x_device::state_string_export(const device_state_entry &entry, astring &string) +{ + switch (entry.index()) + { + case PIC16C5x_PSCL: + string.printf("%c%02X", ((m_OPTION & 0x08) ? 'W':'T'), m_prescaler); + break; + + case STATE_GENFLAGS: + string.printf("%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_OPTION & 0x20 ? 'C':'T', /* Counter/Timer */ + m_OPTION & 0x10 ? 'N':'P', /* Negative/Positive */ + m_OPTION & 0x08 ? 'W':'T', /* WatchDog/Timer */ + m_OPTION & 0x08 ? (1<<(m_OPTION&7)) : (2<<(m_OPTION&7)) ); + break; + } +} + /**************************************************************************** * Reset registers to their initial values ****************************************************************************/ -static void pic16c5x_reset_regs(pic16c5x_state *cpustate) +void pic16c5x_device::pic16c5x_reset_regs() { - cpustate->PC = cpustate->reset_vector; - cpustate->CONFIG = cpustate->temp_config; - cpustate->TRISA = 0xff; - cpustate->TRISB = 0xff; - cpustate->TRISC = 0xff; - cpustate->OPTION = (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG); - cpustate->PCL = 0xff; - cpustate->FSR |= (UINT8)(~cpustate->picRAMmask); - cpustate->PORTA &= 0x0f; - cpustate->prescaler = 0; - cpustate->delay_timer = 0; - cpustate->old_T0 = 0; - cpustate->inst_cycles = 0; + m_PC = m_reset_vector; + m_CONFIG = m_temp_config; + m_TRISA = 0xff; + m_TRISB = 0xff; + m_TRISC = 0xff; + m_OPTION = (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG); + PCL = 0xff; + FSR |= (UINT8)(~m_picRAMmask); + PORTA &= 0x0f; + m_prescaler = 0; + m_delay_timer = 0; + m_old_T0 = 0; + m_inst_cycles = 0; } -static void pic16c5x_soft_reset(pic16c5x_state *cpustate) +void pic16c5x_device::pic16c5x_soft_reset() { - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG)); - pic16c5x_reset_regs(cpustate); + SET(STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG)); + pic16c5x_reset_regs(); } -void pic16c5x_set_config(device_t *cpu, int data) +void pic16c5x_device::pic16c5x_set_config(int data) { - pic16c5x_state *cpustate = get_safe_token(cpu); - logerror("Writing %04x to the PIC16C5x config register\n",data); - cpustate->temp_config = (data & 0xfff); + m_temp_config = (data & 0xfff); } -/**************************************************************************** - * Shut down CPU emulation - ****************************************************************************/ - -static CPU_EXIT( pic16c5x ) +void pic16c5x_device::device_reset() { - /* nothing to do */ + pic16c5x_reset_regs(); + CLR(STATUS, PA_REG); + SET(STATUS, (TO_FLAG | PD_FLAG)); } @@ -819,7 +974,7 @@ static CPU_EXIT( pic16c5x ) * WatchDog ****************************************************************************/ -static void pic16c5x_update_watchdog(pic16c5x_state *cpustate, int counts) +void pic16c5x_device::pic16c5x_update_watchdog(int counts) { /* WatchDog is set up to count 18,000 (0x464f hex) ticks to provide */ /* the timeout period of 0.018ms based on a 4MHz input clock. */ @@ -828,29 +983,29 @@ static void pic16c5x_update_watchdog(pic16c5x_state *cpustate, int counts) /* If the current instruction is CLRWDT or SLEEP, don't update the WDT */ - if ((cpustate->opcode.w.l != 3) && (cpustate->opcode.w.l != 4)) + if ((m_opcode.w.l != 3) && (m_opcode.w.l != 4)) { - UINT16 old_WDT = cpustate->WDT; + UINT16 old_WDT = m_WDT; - cpustate->WDT -= counts; + m_WDT -= counts; - if (cpustate->WDT > 0x464f) { - cpustate->WDT = 0x464f - (0xffff - cpustate->WDT); + if (m_WDT > 0x464f) { + m_WDT = 0x464f - (0xffff - m_WDT); } - if (((old_WDT != 0) && (old_WDT < cpustate->WDT)) || (cpustate->WDT == 0)) + if (((old_WDT != 0) && (old_WDT < m_WDT)) || (m_WDT == 0)) { if (PSA) { - cpustate->prescaler++; - if (cpustate->prescaler >= (1 << PS)) { /* Prescale values from 1 to 128 */ - cpustate->prescaler = 0; - CLR(cpustate->STATUS, TO_FLAG); - pic16c5x_soft_reset(cpustate); + m_prescaler++; + if (m_prescaler >= (1 << PS)) { /* Prescale values from 1 to 128 */ + m_prescaler = 0; + CLR(STATUS, TO_FLAG); + pic16c5x_soft_reset(); } } else { - CLR(cpustate->STATUS, TO_FLAG); - pic16c5x_soft_reset(cpustate); + CLR(STATUS, TO_FLAG); + pic16c5x_soft_reset(); } } } @@ -861,17 +1016,17 @@ static void pic16c5x_update_watchdog(pic16c5x_state *cpustate, int counts) * Update Timer ****************************************************************************/ -static void pic16c5x_update_timer(pic16c5x_state *cpustate, int counts) +void pic16c5x_device::pic16c5x_update_timer(int counts) { if (PSA == 0) { - cpustate->prescaler += counts; - if (cpustate->prescaler >= (2 << PS)) { /* Prescale values from 2 to 256 */ - cpustate->TMR0 += (cpustate->prescaler / (2 << PS)); - cpustate->prescaler %= (2 << PS); /* Overflow prescaler */ + m_prescaler += counts; + if (m_prescaler >= (2 << PS)) { /* Prescale values from 2 to 256 */ + TMR0 += (m_prescaler / (2 << PS)); + m_prescaler %= (2 << PS); /* Overflow prescaler */ } } else { - cpustate->TMR0 += counts; + TMR0 += counts; } } @@ -880,40 +1035,39 @@ static void pic16c5x_update_timer(pic16c5x_state *cpustate, int counts) * Execute IPeriod. Return 0 if emulation should be stopped ****************************************************************************/ -static CPU_EXECUTE( pic16c5x ) +void pic16c5x_device::execute_run() { - pic16c5x_state *cpustate = get_safe_token(device); UINT8 T0_in; - update_internalram_ptr(cpustate); + update_internalram_ptr(); do { if (PD == 0) /* Sleep Mode */ { - cpustate->inst_cycles = 1; - debugger_instruction_hook(device, cpustate->PC); + m_inst_cycles = 1; + debugger_instruction_hook(this, m_PC); if (WDTE) { - pic16c5x_update_watchdog(cpustate, 1); + pic16c5x_update_watchdog(1); } } else { - cpustate->PREVPC = cpustate->PC; + m_PREVPC = m_PC; - debugger_instruction_hook(device, cpustate->PC); + debugger_instruction_hook(this, m_PC); - cpustate->opcode.d = M_RDOP(cpustate->PC); - cpustate->PC++; - cpustate->PCL++; + m_opcode.d = M_RDOP(m_PC); + m_PC++; + PCL++; - if ((cpustate->opcode.w.l & 0xff0) != 0x000) { /* Do all opcodes except the 00? ones */ - cpustate->inst_cycles = opcode_main[((cpustate->opcode.w.l >> 4) & 0xff)].cycles; - (*opcode_main[((cpustate->opcode.w.l >> 4) & 0xff)].function)(cpustate); + if ((m_opcode.w.l & 0xff0) != 0x000) { /* Do all opcodes except the 00? ones */ + m_inst_cycles = s_opcode_main[((m_opcode.w.l >> 4) & 0xff)].cycles; + (this->*s_opcode_main[((m_opcode.w.l >> 4) & 0xff)].function)(); } else { /* Opcode 0x00? has many opcodes in its minor nibble */ - cpustate->inst_cycles = opcode_00x[(cpustate->opcode.b.l & 0x1f)].cycles; - (*opcode_00x[(cpustate->opcode.b.l & 0x1f)].function)(cpustate); + m_inst_cycles = s_opcode_00x[(m_opcode.b.l & 0x1f)].cycles; + (this->*s_opcode_00x[(m_opcode.b.l & 0x1f)].function)(); } if (T0CS) { /* Count mode */ @@ -921,477 +1075,31 @@ static CPU_EXECUTE( pic16c5x ) if (T0_in) T0_in = 1; if (T0SE) { /* Count falling edge T0 input */ if (FALLING_EDGE_T0) { - pic16c5x_update_timer(cpustate, 1); + pic16c5x_update_timer(1); } } else { /* Count rising edge T0 input */ if (RISING_EDGE_T0) { - pic16c5x_update_timer(cpustate, 1); + pic16c5x_update_timer(1); } } - cpustate->old_T0 = T0_in; + m_old_T0 = T0_in; } else { /* Timer mode */ - if (cpustate->delay_timer) { - cpustate->delay_timer--; + if (m_delay_timer) { + m_delay_timer--; } else { - pic16c5x_update_timer(cpustate, cpustate->inst_cycles); + pic16c5x_update_timer(m_inst_cycles); } } if (WDTE) { - pic16c5x_update_watchdog(cpustate, cpustate->inst_cycles); + pic16c5x_update_watchdog(m_inst_cycles); } } - cpustate->icount -= cpustate->inst_cycles; + m_icount -= m_inst_cycles; - } while (cpustate->icount > 0); + } while (m_icount > 0); } - - -/************************************************************************** - * Generic set_info - **************************************************************************/ - -static CPU_SET_INFO( pic16c5x ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - switch (state) - { - /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_PC: - case CPUINFO_INT_REGISTER + PIC16C5x_PC: cpustate->PC = info->i; cpustate->PCL = info->i & 0xff ;break; - /* This is actually not a stack pointer, but the stack contents */ - /* Stack is a 2 level First In Last Out stack */ - case CPUINFO_INT_SP: - case CPUINFO_INT_REGISTER + PIC16C5x_STK1: cpustate->STACK[1] = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_STK0: cpustate->STACK[0] = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_W: cpustate->W = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_ALU: cpustate->ALU = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_STR: cpustate->STATUS = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_OPT: cpustate->OPTION = info->i & (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG); break; - case CPUINFO_INT_REGISTER + PIC16C5x_TMR0: cpustate->TMR0 = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_WDT: cpustate->WDT = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PSCL: cpustate->prescaler = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTA: cpustate->PORTA = info->i & 0x0f; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTB: cpustate->PORTB = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTC: cpustate->PORTC = info->i; break; - case CPUINFO_INT_REGISTER + PIC16C5x_FSR: cpustate->FSR = ((info->i & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask)); break; - } -} - - - -/************************************************************************** - * Generic get_info - **************************************************************************/ - -static CPU_GET_INFO( pic16c5x ) -{ - pic16c5x_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; - - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(pic16c5x_state); break; - case CPUINFO_INT_INPUT_LINES: info->i = 1; break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; - case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 4; break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 2; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 9; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -1; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 5; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 5; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; - - case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->PREVPC; break; - - case CPUINFO_INT_PC: - case CPUINFO_INT_REGISTER + PIC16C5x_PC: info->i = cpustate->PC; break; - /* This is actually not a stack pointer, but the stack contents */ - case CPUINFO_INT_SP: - case CPUINFO_INT_REGISTER + PIC16C5x_STK1: info->i = cpustate->STACK[1]; break; - case CPUINFO_INT_REGISTER + PIC16C5x_STK0: info->i = cpustate->STACK[0]; break; - case CPUINFO_INT_REGISTER + PIC16C5x_W: info->i = cpustate->W; break; - case CPUINFO_INT_REGISTER + PIC16C5x_ALU: info->i = cpustate->ALU; break; - case CPUINFO_INT_REGISTER + PIC16C5x_STR: info->i = cpustate->STATUS; break; - case CPUINFO_INT_REGISTER + PIC16C5x_OPT: info->i = cpustate->OPTION; break; - case CPUINFO_INT_REGISTER + PIC16C5x_TMR0: info->i = cpustate->TMR0; break; - case CPUINFO_INT_REGISTER + PIC16C5x_WDT: info->i = cpustate->WDT; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PSCL: info->i = cpustate->prescaler; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTA: info->i = cpustate->PORTA; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTB: info->i = cpustate->PORTB; break; - case CPUINFO_INT_REGISTER + PIC16C5x_PRTC: info->i = cpustate->PORTC; break; - case CPUINFO_INT_REGISTER + PIC16C5x_FSR: info->i = ((cpustate->FSR & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask)); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(pic16c5x); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(pic16c5x); break; - case CPUINFO_FCT_RESET: /* set per-CPU */ break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(pic16c5x); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(pic16c5x); break; - case CPUINFO_FCT_BURN: info->burn = NULL; break; - case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(pic16c5x); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C5x"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c5x"); break; - case CPUINFO_STR_FAMILY: strcpy(info->s, "Microchip"); break; - case CPUINFO_STR_VERSION: strcpy(info->s, "1.14"); break; - case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Tony La Porta"); break; - - case CPUINFO_STR_FLAGS: - sprintf(info->s, "%01x%c%c%c%c%c %c%c%c%03x", - (cpustate->STATUS & 0xe0) >> 5, - cpustate->STATUS & 0x10 ? '.':'O', /* WDT Overflow */ - cpustate->STATUS & 0x08 ? 'P':'D', /* Power/Down */ - cpustate->STATUS & 0x04 ? 'Z':'.', /* Zero */ - cpustate->STATUS & 0x02 ? 'c':'b', /* Nibble Carry/Borrow */ - cpustate->STATUS & 0x01 ? 'C':'B', /* Carry/Borrow */ - - cpustate->OPTION & 0x20 ? 'C':'T', /* Counter/Timer */ - cpustate->OPTION & 0x10 ? 'N':'P', /* Negative/Positive */ - cpustate->OPTION & 0x08 ? 'W':'T', /* WatchDog/Timer */ - cpustate->OPTION & 0x08 ? (1<<(cpustate->OPTION&7)) : (2<<(cpustate->OPTION&7)) ); - break; - - case CPUINFO_STR_REGISTER + PIC16C5x_PC: sprintf(info->s, "PC:%03X", cpustate->PC); break; - case CPUINFO_STR_REGISTER + PIC16C5x_W: sprintf(info->s, "W:%02X", cpustate->W); break; - case CPUINFO_STR_REGISTER + PIC16C5x_ALU: sprintf(info->s, "ALU:%02X", cpustate->ALU); break; - case CPUINFO_STR_REGISTER + PIC16C5x_STR: sprintf(info->s, "STR:%02X", cpustate->STATUS); break; - case CPUINFO_STR_REGISTER + PIC16C5x_TMR0: sprintf(info->s, "TMR:%02X", cpustate->TMR0); break; - case CPUINFO_STR_REGISTER + PIC16C5x_WDT: sprintf(info->s, "WDT:%04X", cpustate->WDT); break; - case CPUINFO_STR_REGISTER + PIC16C5x_OPT: sprintf(info->s, "OPT:%02X", cpustate->OPTION); break; - case CPUINFO_STR_REGISTER + PIC16C5x_STK0: sprintf(info->s, "STK0:%03X", cpustate->STACK[0]); break; - case CPUINFO_STR_REGISTER + PIC16C5x_STK1: sprintf(info->s, "STK1:%03X", cpustate->STACK[1]); break; - case CPUINFO_STR_REGISTER + PIC16C5x_PRTA: sprintf(info->s, "PRTA:%01X", ((cpustate->PORTA) & 0x0f)); break; - case CPUINFO_STR_REGISTER + PIC16C5x_PRTB: sprintf(info->s, "PRTB:%02X", cpustate->PORTB); break; - case CPUINFO_STR_REGISTER + PIC16C5x_PRTC: sprintf(info->s, "PRTC:%02X", cpustate->PORTC); break; - case CPUINFO_STR_REGISTER + PIC16C5x_TRSA: sprintf(info->s, "TRSA:%01X", ((cpustate->TRISA) & 0x0f)); break; - case CPUINFO_STR_REGISTER + PIC16C5x_TRSB: sprintf(info->s, "TRSB:%02X", cpustate->TRISB); break; - case CPUINFO_STR_REGISTER + PIC16C5x_TRSC: sprintf(info->s, "TRSC:%02X", cpustate->TRISC); break; - case CPUINFO_STR_REGISTER + PIC16C5x_FSR: sprintf(info->s, "FSR:%02X", ((cpustate->FSR) & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask)); break; - case CPUINFO_STR_REGISTER + PIC16C5x_PSCL: sprintf(info->s, "PSCL:%c%02X", ((cpustate->OPTION & 0x08) ? 'W':'T'), cpustate->prescaler); break; - } -} - - - -/**************************************************************************** - * Internal Memory Map - ****************************************************************************/ - -static ADDRESS_MAP_START( pic16c54_rom, AS_PROGRAM, 16, legacy_cpu_device ) - AM_RANGE(0x000, 0x1ff) AM_ROM -ADDRESS_MAP_END - -static ADDRESS_MAP_START( pic16c54_ram, AS_DATA, 8, legacy_cpu_device ) - AM_RANGE(0x00, 0x07) AM_RAM - AM_RANGE(0x08, 0x0f) AM_RAM - AM_RANGE(0x10, 0x1f) AM_RAM -ADDRESS_MAP_END - - -/**************************************************************************** - * PIC16C54 Reset - ****************************************************************************/ - -static CPU_RESET( pic16c54 ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - update_internalram_ptr(cpustate); - - cpustate->picmodel = 0x16C54; - cpustate->picRAMmask = 0x1f; - cpustate->reset_vector = 0x1ff; - pic16c5x_reset_regs(cpustate); - CLR(cpustate->STATUS, PA_REG); - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG)); -} - - -/************************************************************************** - * CPU-specific get_info - **************************************************************************/ - -CPU_GET_INFO( pic16c54 ) -{ - switch (state) - { - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 9; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 5; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pic16c54); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(pic16c54_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(pic16c54_ram); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C54"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c54"); break; - - default: CPU_GET_INFO_CALL(pic16c5x); break; - } -} - - -/**************************************************************************** - * Internal Memory Map - ****************************************************************************/ - -static ADDRESS_MAP_START( pic16c55_rom, AS_PROGRAM, 16, legacy_cpu_device ) - AM_RANGE(0x000, 0x1ff) AM_ROM -ADDRESS_MAP_END - -static ADDRESS_MAP_START( pic16c55_ram, AS_DATA, 8, legacy_cpu_device ) - AM_RANGE(0x00, 0x07) AM_RAM - AM_RANGE(0x08, 0x0f) AM_RAM - AM_RANGE(0x10, 0x1f) AM_RAM -ADDRESS_MAP_END - - -/**************************************************************************** - * PIC16C55 Reset - ****************************************************************************/ - -static CPU_RESET( pic16c55 ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - update_internalram_ptr(cpustate); - - cpustate->picmodel = 0x16C55; - cpustate->picRAMmask = 0x1f; - cpustate->reset_vector = 0x1ff; - pic16c5x_reset_regs(cpustate); - CLR(cpustate->STATUS, PA_REG); - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG)); -} - - -/************************************************************************** - * CPU-specific get_info - **************************************************************************/ - -CPU_GET_INFO( pic16c55 ) -{ - switch (state) - { - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 9; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 5; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pic16c55); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(pic16c55_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(pic16c55_ram); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C55"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c55"); break; - - default: CPU_GET_INFO_CALL(pic16c5x); break; - } -} - - -/**************************************************************************** - * Internal Memory Map - ****************************************************************************/ - -static ADDRESS_MAP_START( pic16c56_rom, AS_PROGRAM, 16, legacy_cpu_device ) - AM_RANGE(0x000, 0x3ff) AM_ROM -ADDRESS_MAP_END - -static ADDRESS_MAP_START( pic16c56_ram, AS_DATA, 8, legacy_cpu_device ) - AM_RANGE(0x00, 0x07) AM_RAM - AM_RANGE(0x08, 0x0f) AM_RAM - AM_RANGE(0x10, 0x1f) AM_RAM -ADDRESS_MAP_END - - -/**************************************************************************** - * PIC16C56 Reset - ****************************************************************************/ - -static CPU_RESET( pic16c56 ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - update_internalram_ptr(cpustate); - - cpustate->picmodel = 0x16C56; - cpustate->picRAMmask = 0x1f; - cpustate->reset_vector = 0x3ff; - pic16c5x_reset_regs(cpustate); - CLR(cpustate->STATUS, PA_REG); - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG)); -} - - -/************************************************************************** - * CPU-specific get_info - **************************************************************************/ - -CPU_GET_INFO( pic16c56 ) -{ - switch (state) - { - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 10; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 5; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pic16c56); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(pic16c56_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(pic16c56_ram); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C56"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c56"); break; - - default: CPU_GET_INFO_CALL(pic16c5x); break; - } -} - - -/**************************************************************************** - * Internal Memory Map - ****************************************************************************/ - -static ADDRESS_MAP_START( pic16c57_rom, AS_PROGRAM, 16, legacy_cpu_device ) - AM_RANGE(0x000, 0x7ff) AM_ROM -ADDRESS_MAP_END - -static ADDRESS_MAP_START( pic16c57_ram, AS_DATA, 8, legacy_cpu_device ) - AM_RANGE(0x00, 0x07) AM_RAM AM_MIRROR(0x60) - AM_RANGE(0x08, 0x0f) AM_RAM AM_MIRROR(0x60) - AM_RANGE(0x10, 0x1f) AM_RAM - AM_RANGE(0x30, 0x3f) AM_RAM - AM_RANGE(0x50, 0x5f) AM_RAM - AM_RANGE(0x70, 0x7f) AM_RAM -ADDRESS_MAP_END - - -/**************************************************************************** - * PIC16C57 Reset - ****************************************************************************/ - -static CPU_RESET( pic16c57 ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - update_internalram_ptr(cpustate); - - cpustate->picmodel = 0x16C57; - cpustate->picRAMmask = 0x7f; - cpustate->reset_vector = 0x7ff; - pic16c5x_reset_regs(cpustate); - CLR(cpustate->STATUS, PA_REG); - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG)); -} - - -/************************************************************************** - * CPU-specific get_info - **************************************************************************/ - -CPU_GET_INFO( pic16c57 ) -{ - switch (state) - { - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 11; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 7; break; - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pic16c57); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(pic16c57_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(pic16c57_ram); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C57"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c57"); break; - - default: CPU_GET_INFO_CALL(pic16c5x); break; - } -} - - -/**************************************************************************** - * Internal Memory Map - ****************************************************************************/ - -static ADDRESS_MAP_START( pic16c58_rom, AS_PROGRAM, 16, legacy_cpu_device ) - AM_RANGE(0x000, 0x7ff) AM_ROM -ADDRESS_MAP_END - -static ADDRESS_MAP_START( pic16c58_ram, AS_DATA, 8, legacy_cpu_device ) - AM_RANGE(0x00, 0x07) AM_RAM AM_MIRROR(0x60) - AM_RANGE(0x08, 0x0f) AM_RAM AM_MIRROR(0x60) - AM_RANGE(0x10, 0x1f) AM_RAM - AM_RANGE(0x30, 0x3f) AM_RAM - AM_RANGE(0x50, 0x5f) AM_RAM - AM_RANGE(0x70, 0x7f) AM_RAM -ADDRESS_MAP_END - - -/**************************************************************************** - * PIC16C58 Reset - ****************************************************************************/ - -static CPU_RESET( pic16c58 ) -{ - pic16c5x_state *cpustate = get_safe_token(device); - - update_internalram_ptr(cpustate); - - cpustate->picmodel = 0x16C58; - cpustate->picRAMmask = 0x7f; - cpustate->reset_vector = 0x7ff; - pic16c5x_reset_regs(cpustate); - CLR(cpustate->STATUS, PA_REG); - SET(cpustate->STATUS, (TO_FLAG | PD_FLAG)); -} - - -/************************************************************************** - * CPU-specific get_info - **************************************************************************/ - -CPU_GET_INFO( pic16c58 ) -{ - switch (state) - { - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 11; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 7; break; - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pic16c58); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME(pic16c58_rom); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: info->internal_map8 = ADDRESS_MAP_NAME(pic16c58_ram); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "PIC16C58"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "pic16c58"); break; - - default: CPU_GET_INFO_CALL(pic16c5x); break; - } -} - -DEFINE_LEGACY_CPU_DEVICE(PIC16C54, pic16c54); -DEFINE_LEGACY_CPU_DEVICE(PIC16C55, pic16c55); -DEFINE_LEGACY_CPU_DEVICE(PIC16C56, pic16c56); -DEFINE_LEGACY_CPU_DEVICE(PIC16C57, pic16c57); -DEFINE_LEGACY_CPU_DEVICE(PIC16C58, pic16c58); diff --git a/src/emu/cpu/pic16c5x/pic16c5x.h b/src/emu/cpu/pic16c5x/pic16c5x.h index 9685e69b453..29fc0a00fb3 100644 --- a/src/emu/cpu/pic16c5x/pic16c5x.h +++ b/src/emu/cpu/pic16c5x/pic16c5x.h @@ -37,24 +37,195 @@ enum #define PIC16C5x_T0 0x10 -/**************************************************************************** - * Function to configure the CONFIG register. This is actually hard-wired - * during ROM programming, so should be called in the driver INIT, with - * the value if known (available in HEX dumps of the ROM). - */ - -void pic16c5x_set_config(device_t *cpu, int data); +extern const device_type PIC16C54; +extern const device_type PIC16C55; +extern const device_type PIC16C56; +extern const device_type PIC16C57; +extern const device_type PIC16C58; +class pic16c5x_device : public cpu_device +{ +public: + // construction/destruction + pic16c5x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, int program_width, int data_width, int picmodel); -DECLARE_LEGACY_CPU_DEVICE(PIC16C54, pic16c54); -DECLARE_LEGACY_CPU_DEVICE(PIC16C55, pic16c55); -DECLARE_LEGACY_CPU_DEVICE(PIC16C56, pic16c56); -DECLARE_LEGACY_CPU_DEVICE(PIC16C57, pic16c57); -DECLARE_LEGACY_CPU_DEVICE(PIC16C58, pic16c58); + /**************************************************************************** + * Function to configure the CONFIG register. This is actually hard-wired + * during ROM programming, so should be called in the driver INIT, with + * the value if known (available in HEX dumps of the ROM). + */ + void pic16c5x_set_config(int data); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 4 - 1) / 4; } + virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 4); } + virtual UINT32 execute_min_cycles() const { return 1; } + virtual UINT32 execute_max_cycles() const { return 2; } + virtual UINT32 execute_input_lines() const { return 1; } + virtual UINT32 execute_default_irq_vector() const { return 0; } + virtual void execute_run(); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const + { + return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : ( (spacenum == AS_DATA) ? &m_data_config : NULL ) ); + } + + // device_state_interface overrides + virtual void state_import(const device_state_entry &entry); + virtual void state_export(const device_state_entry &entry); + void state_string_export(const device_state_entry &entry, astring &string); + + // device_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const { return 2; } + virtual UINT32 disasm_max_opcode_bytes() const { return 2; } + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + +private: + address_space_config m_program_config; + address_space_config m_data_config; + address_space_config m_io_config; + + /******************** CPU Internal Registers *******************/ + UINT16 m_PC; + UINT16 m_PREVPC; /* previous program counter */ + UINT8 m_W; + UINT8 m_OPTION; + UINT16 m_CONFIG; + UINT8 m_ALU; + UINT16 m_WDT; + UINT8 m_TRISA; + UINT8 m_TRISB; + UINT8 m_TRISC; + UINT16 m_STACK[2]; + UINT16 m_prescaler; /* Note: this is really an 8-bit register */ + PAIR m_opcode; + UINT8 *m_internalram; + + int m_icount; + int m_reset_vector; + int m_picmodel; + int m_delay_timer; + UINT16 m_temp_config; + UINT8 m_old_T0; + INT8 m_old_data; + UINT8 m_picRAMmask; + int m_inst_cycles; + + address_space *m_program; + direct_read_data *m_direct; + address_space *m_data; + address_space *m_io; + + // For debugger + int m_debugger_temp; + + /* opcode table entry */ + typedef void (pic16c5x_device::*pic16c5x_ophandler)(); + struct pic16c5x_opcode + { + UINT8 cycles; + pic16c5x_ophandler function; + }; + static const pic16c5x_opcode s_opcode_main[256]; + static const pic16c5x_opcode s_opcode_00x[16]; + + void update_internalram_ptr(); + void CALCULATE_Z_FLAG(); + void CALCULATE_ADD_CARRY(); + void CALCULATE_ADD_DIGITCARRY(); + void CALCULATE_SUB_CARRY(); + void CALCULATE_SUB_DIGITCARRY(); + UINT16 POP_STACK(); + void PUSH_STACK(UINT16 data); + UINT8 GET_REGFILE(offs_t addr); + void STORE_REGFILE(offs_t addr, UINT8 data); + void STORE_RESULT(offs_t addr, UINT8 data); + void illegal(); + void addwf(); + void andwf(); + void andlw(); + void bcf(); + void bsf(); + void btfss(); + void btfsc(); + void call(); + void clrw(); + void clrf(); + void clrwdt(); + void comf(); + void decf(); + void decfsz(); + void goto_op(); + void incf(); + void incfsz(); + void iorlw(); + void iorwf(); + void movf(); + void movlw(); + void movwf(); + void nop(); + void option(); + void retlw(); + void rlf(); + void rrf(); + void sleepic(); + void subwf(); + void swapf(); + void tris(); + void xorlw(); + void xorwf(); + void pic16c5x_reset_regs(); + void pic16c5x_soft_reset(); + void pic16c5x_update_watchdog(int counts); + void pic16c5x_update_timer(int counts); + +}; -CPU_DISASSEMBLE( pic16c5x ); +class pic16c54_device : public pic16c5x_device +{ +public: + // construction/destruction + pic16c54_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; +class pic16c55_device : public pic16c5x_device +{ +public: + // construction/destruction + pic16c55_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class pic16c56_device : public pic16c5x_device +{ +public: + // construction/destruction + pic16c56_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class pic16c57_device : public pic16c5x_device +{ +public: + // construction/destruction + pic16c57_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + +class pic16c58_device : public pic16c5x_device +{ +public: + // construction/destruction + pic16c58_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + #endif /* __PIC16C5X_H__ */ diff --git a/src/mame/drivers/drgnmst.c b/src/mame/drivers/drgnmst.c index 02992184f20..a176f18a846 100644 --- a/src/mame/drivers/drgnmst.c +++ b/src/mame/drivers/drgnmst.c @@ -545,7 +545,7 @@ DRIVER_INIT_MEMBER(drgnmst_state,drgnmst) data_lo = drgnmst_asciitohex((drgnmst_PICROM_HEX[src_pos + 3])); data |= (data_hi << 12) | (data_lo << 8); - pic16c5x_set_config(m_audiocpu, data); + m_audiocpu->pic16c5x_set_config(data); src_pos = 0x7fff; /* Force Exit */ } diff --git a/src/mame/drivers/playmark.c b/src/mame/drivers/playmark.c index 029682a46e7..8f4bcdc6ba1 100644 --- a/src/mame/drivers/playmark.c +++ b/src/mame/drivers/playmark.c @@ -1781,7 +1781,7 @@ DRIVER_INIT_MEMBER(playmark_state,bigtwin) data_lo = playmark_asciitohex((playmark_PICROM_HEX[src_pos + 3])); data |= (data_hi << 12) | (data_lo << 8); - pic16c5x_set_config(m_audiocpu, data); + m_audiocpu->pic16c5x_set_config(data); src_pos = 0x7fff; /* Force Exit */ } diff --git a/src/mame/includes/drgnmst.h b/src/mame/includes/drgnmst.h index 2da0fedd27a..adab8235996 100644 --- a/src/mame/includes/drgnmst.h +++ b/src/mame/includes/drgnmst.h @@ -1,5 +1,6 @@ #include "sound/okim6295.h" +#include "cpu/pic16c5x/pic16c5x.h" class drgnmst_state : public driver_device { @@ -72,5 +73,5 @@ public: void draw_sprites( bitmap_ind16 &bitmap,const rectangle &cliprect ); UINT8 drgnmst_asciitohex( UINT8 data ); required_device m_maincpu; - required_device m_audiocpu; + required_device m_audiocpu; }; diff --git a/src/mame/includes/playmark.h b/src/mame/includes/playmark.h index a1bf4d14be7..6cc46a38a2c 100644 --- a/src/mame/includes/playmark.h +++ b/src/mame/includes/playmark.h @@ -1,5 +1,6 @@ #include "sound/okim6295.h" #include "machine/eepromser.h" +#include "cpu/pic16c5x/pic16c5x.h" class playmark_state : public driver_device { @@ -106,5 +107,5 @@ public: void draw_bitmap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ); UINT8 playmark_asciitohex(UINT8 data); required_device m_maincpu; - optional_device m_audiocpu; + optional_device m_audiocpu; };