pic16c5x: statusreg high bits are 1 on old GI PIC

This commit is contained in:
hap 2023-01-07 21:18:25 +01:00
parent e5cf5f93fa
commit 63512d1917
5 changed files with 117 additions and 103 deletions

View File

@ -285,7 +285,6 @@ void f8_cpu_device::ROMC_00(int insttim)
* code addressed by PC0; then all devices increment the contents
* of PC0.
*/
m_dbus = m_program.read_byte(m_pc0);
m_pc0 += 1;
m_icount -= insttim; /* ROMC00 is usually short, not short+long, but DS is long */

View File

@ -201,10 +201,15 @@ void mcs48_cpu_device::data_8bit(address_map &map)
mcs48_cpu_device::mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size, uint8_t feature_mask, const mcs48_cpu_device::mcs48_ophandler *opcode_table)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & MB_FEATURE) != 0 ? 12 : 11, 0
, (rom_size == 1024) ? address_map_constructor(FUNC(mcs48_cpu_device::program_10bit), this) : (rom_size == 2048) ? address_map_constructor(FUNC(mcs48_cpu_device::program_11bit), this) : (rom_size == 4096) ? address_map_constructor(FUNC(mcs48_cpu_device::program_12bit), this) : address_map_constructor())
, m_data_config("data", ENDIANNESS_LITTLE, 8, ( ( ram_size == 64 ) ? 6 : ( ( ram_size == 128 ) ? 7 : 8 ) ), 0
, (ram_size == 64) ? address_map_constructor(FUNC(mcs48_cpu_device::data_6bit), this) : (ram_size == 128) ? address_map_constructor(FUNC(mcs48_cpu_device::data_7bit), this) : address_map_constructor(FUNC(mcs48_cpu_device::data_8bit), this))
, m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & MB_FEATURE) != 0 ? 12 : 11, 0,
(rom_size == 1024) ? address_map_constructor(FUNC(mcs48_cpu_device::program_10bit), this) :
(rom_size == 2048) ? address_map_constructor(FUNC(mcs48_cpu_device::program_11bit), this) :
(rom_size == 4096) ? address_map_constructor(FUNC(mcs48_cpu_device::program_12bit), this) :
address_map_constructor())
, m_data_config("data", ENDIANNESS_LITTLE, 8, ((ram_size == 64) ? 6 : ((ram_size == 128) ? 7 : 8)), 0,
(ram_size == 64) ? address_map_constructor(FUNC(mcs48_cpu_device::data_6bit), this) :
(ram_size == 128) ? address_map_constructor(FUNC(mcs48_cpu_device::data_7bit), this) :
address_map_constructor(FUNC(mcs48_cpu_device::data_8bit), this))
, m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0)
, m_port_in_cb(*this)
, m_port_out_cb(*this)

View File

@ -98,11 +98,6 @@ void pic16c5x_device::rom_9(address_map &map)
map(0x000, 0x1ff).rom();
}
void pic16c5x_device::ram_5(address_map &map)
{
map(0x00, 0x1f).ram();
}
void pic16c5x_device::rom_10(address_map &map)
{
map(0x000, 0x3ff).rom();
@ -113,6 +108,11 @@ void pic16c5x_device::rom_11(address_map &map)
map(0x000, 0x7ff).rom();
}
void pic16c5x_device::ram_5(address_map &map)
{
map(0x00, 0x1f).ram();
}
void pic16c5x_device::ram_7(address_map &map)
{
map(0x00, 0x0f).ram().mirror(0x60);
@ -133,11 +133,10 @@ pic16c5x_device::pic16c5x_device(const machine_config &mconfig, device_type type
((data_width == 5) ? address_map_constructor(FUNC(pic16c5x_device::ram_5), this) :
address_map_constructor(FUNC(pic16c5x_device::ram_7), this)))
, m_internalram(nullptr)
, m_reset_vector((program_width == 9) ? 0x1ff : ((program_width == 10) ? 0x3ff : 0x7ff))
, m_picmodel(picmodel)
, m_data_width(data_width)
, m_program_width(program_width)
, m_temp_config(0)
, m_rtcc(0)
, m_picRAMmask((data_width == 5) ? 0x1f : 0x7f)
, m_read_a(*this)
, m_read_b(*this)
, m_read_c(*this)
@ -211,16 +210,6 @@ void pic16c5x_device::update_internalram_ptr()
#define PIC16C5x_RDOP(A) (m_program.read_word(A))
#define PIC16C5x_RAM_RDMEM(A) ((uint8_t)m_data.read_byte(A))
#define PIC16C5x_RAM_WRMEM(A,V) (m_data.write_byte(A,V))
#define M_RDRAM(A) (((A) < 9) ? m_internalram[A] : PIC16C5x_RAM_RDMEM(A))
#define M_WRTRAM(A,V) do { if ((A) < 9) m_internalram[A] = (V); else PIC16C5x_RAM_WRMEM(A,V); } while (0)
#define M_RDOP(A) PIC16C5x_RDOP(A)
#define ADDR_MASK 0x7ff
#define TMR0 m_internalram[1]
#define PCL m_internalram[2]
#define STATUS m_internalram[3]
@ -229,10 +218,6 @@ void pic16c5x_device::update_internalram_ptr()
#define PORTB m_internalram[6]
#define PORTC m_internalram[7]
#define PORTD m_internalram[8]
#define INDF M_RDRAM(FSR)
#define ADDR (m_opcode.b.l & 0x1f)
#define BITPOS ((m_opcode.b.l >> 5) & 7)
// ******** The following is the Status Flag register definition. ********
@ -282,8 +267,14 @@ void pic16c5x_device::update_internalram_ptr()
* Shortcuts
************************************************************************/
#define CLR(flagreg, flag) ( flagreg &= uint8_t(~flag) )
#define SET(flagreg, flag) ( flagreg |= flag )
#define M_RDRAM(A) (((A) < 9) ? m_internalram[A] : m_data.read_byte(A))
#define M_WRTRAM(A,V) do { if ((A) < 9) m_internalram[A] = (V); else m_data.write_byte(A,V); } while (0)
#define CLR(flagreg, flag) (flagreg &= uint8_t(~flag))
#define SET(flagreg, flag) (flagreg |= (flag))
#define ADDR (m_opcode.b.l & 0x1f)
#define BITPOS ((m_opcode.b.l >> 5) & 7)
@ -295,7 +286,7 @@ void pic16c5x_device::CALCULATE_Z_FLAG()
void pic16c5x_device::CALCULATE_ADD_CARRY()
{
if (uint8_t(m_old_data) > uint8_t(m_ALU)) {
if (m_old_data > m_ALU) {
SET(STATUS, C_FLAG);
}
else {
@ -305,7 +296,7 @@ void pic16c5x_device::CALCULATE_ADD_CARRY()
void pic16c5x_device::CALCULATE_ADD_DIGITCARRY()
{
if ((uint8_t(m_old_data) & 0x0f) > (uint8_t(m_ALU) & 0x0f)) {
if ((m_old_data & 0x0f) > (m_ALU & 0x0f)) {
SET(STATUS, DC_FLAG);
}
else {
@ -315,7 +306,7 @@ void pic16c5x_device::CALCULATE_ADD_DIGITCARRY()
void pic16c5x_device::CALCULATE_SUB_CARRY()
{
if (uint8_t(m_old_data) < uint8_t(m_ALU)) {
if (m_old_data < m_ALU) {
CLR(STATUS, C_FLAG);
}
else {
@ -325,7 +316,7 @@ void pic16c5x_device::CALCULATE_SUB_CARRY()
void pic16c5x_device::CALCULATE_SUB_DIGITCARRY()
{
if ((uint8_t(m_old_data) & 0x0f) < (uint8_t(m_ALU) & 0x0f)) {
if ((m_old_data & 0x0f) < (m_ALU & 0x0f)) {
CLR(STATUS, DC_FLAG);
}
else {
@ -335,17 +326,23 @@ void pic16c5x_device::CALCULATE_SUB_DIGITCARRY()
void pic16c5x_device::SET_PC(offs_t addr)
{
m_PC = addr & m_program_mask;
PCL = m_PC & 0xff;
}
uint16_t pic16c5x_device::POP_STACK()
{
uint16_t data = m_STACK[1];
m_STACK[1] = m_STACK[0];
return (data & ADDR_MASK);
return data & m_program_mask;
}
void pic16c5x_device::PUSH_STACK(uint16_t data)
{
m_STACK[0] = m_STACK[1];
m_STACK[1] = (data & ADDR_MASK);
m_STACK[1] = data & m_program_mask;
}
@ -355,7 +352,7 @@ uint8_t pic16c5x_device::GET_REGFILE(offs_t addr) // Read from internal memory
uint8_t data = 0;
if (addr == 0) { // Indirect addressing
addr = (FSR & m_picRAMmask);
addr = FSR & m_data_mask;
}
if ((m_picmodel == 0x16C57) || (m_picmodel == 0x16C58)) {
@ -364,17 +361,13 @@ uint8_t pic16c5x_device::GET_REGFILE(offs_t addr) // Read from internal memory
if ((addr & 0x10) == 0) addr &= 0x0f;
switch(addr)
switch (addr)
{
case 0:
// Not an actual register, so return 0
// Not an actual register, reading indirectly (FSR=0) returns 0
data = 0;
break;
case 4:
data = (FSR | uint8_t(~m_picRAMmask));
break;
case 5:
// read port A
if ((m_picmodel == 0x1650) || (m_picmodel == 0x1654)) {
@ -438,7 +431,7 @@ uint8_t pic16c5x_device::GET_REGFILE(offs_t addr) // Read from internal memory
void pic16c5x_device::STORE_REGFILE(offs_t addr, uint8_t data) // Write to internal memory
{
if (addr == 0) { // Indirect addressing
addr = (FSR & m_picRAMmask);
addr = FSR & m_data_mask;
}
if ((m_picmodel == 0x16C57) || (m_picmodel == 0x16C58)) {
@ -447,7 +440,7 @@ void pic16c5x_device::STORE_REGFILE(offs_t addr, uint8_t data) // Write to inter
if ((addr & 0x10) == 0) addr &= 0x0f;
switch(addr)
switch (addr)
{
case 0:
// Not an actual register, nothing to save
@ -460,16 +453,20 @@ void pic16c5x_device::STORE_REGFILE(offs_t addr, uint8_t data) // Write to inter
break;
case 2:
PCL = data;
m_PC = ((STATUS & PA_REG) << 4) | data;
SET_PC(((STATUS & PA_REG) << 4) | data);
break;
case 3:
STATUS = (STATUS & (TO_FLAG | PD_FLAG)) | (data & uint8_t(~(TO_FLAG | PD_FLAG)));
// on GI PIC165x, high bits are 1
if (m_picmodel == 0x1650 || m_picmodel == 0x1654 || m_picmodel == 0x1655)
STATUS = data | uint8_t(~m_status_mask);
else
STATUS = (STATUS & (TO_FLAG | PD_FLAG)) | (data & uint8_t(~(TO_FLAG | PD_FLAG)));
break;
case 4:
FSR = (data | uint8_t(~m_picRAMmask));
// high bits are 1
FSR = data | uint8_t(~m_data_mask);
break;
case 5:
@ -536,7 +533,7 @@ void pic16c5x_device::STORE_RESULT(offs_t addr, uint8_t data)
void pic16c5x_device::illegal()
{
logerror("PIC16C5x: PC=%03x, Illegal opcode = %04x\n", (m_PC-1), m_opcode.w.l);
logerror("PIC16C5x: PC=%03x, Illegal opcode = %04x\n", m_PREVPC, m_opcode.w.l);
}
/*
@ -589,8 +586,7 @@ void pic16c5x_device::bsf()
void pic16c5x_device::btfss()
{
if (BIT(GET_REGFILE(ADDR), BITPOS)) {
m_PC++;
PCL = m_PC & 0xff;
SET_PC(m_PC + 1);
m_inst_cycles += 1; // Add NOP cycles
}
}
@ -598,8 +594,7 @@ void pic16c5x_device::btfss()
void pic16c5x_device::btfsc()
{
if (!BIT(GET_REGFILE(ADDR), BITPOS)) {
m_PC++;
PCL = m_PC & 0xff;
SET_PC(m_PC + 1);
m_inst_cycles += 1; // Add NOP cycles
}
}
@ -607,9 +602,7 @@ void pic16c5x_device::btfsc()
void pic16c5x_device::call()
{
PUSH_STACK(m_PC);
m_PC = ((STATUS & PA_REG) << 4) | m_opcode.b.l;
m_PC &= 0x6ff;
PCL = m_PC & 0xff;
SET_PC((((STATUS & PA_REG) << 4) | m_opcode.b.l) & 0x6ff);
}
void pic16c5x_device::clrw()
@ -651,17 +644,14 @@ void pic16c5x_device::decfsz()
m_ALU = GET_REGFILE(ADDR) - 1;
STORE_RESULT(ADDR, m_ALU);
if (m_ALU == 0) {
m_PC++;
PCL = m_PC & 0xff;
SET_PC(m_PC + 1);
m_inst_cycles += 1; // Add NOP cycles
}
}
void pic16c5x_device::goto_op()
{
m_PC = ((STATUS & PA_REG) << 4) | (m_opcode.w.l & 0x1ff);
m_PC &= ADDR_MASK;
PCL = m_PC & 0xff;
SET_PC(((STATUS & PA_REG) << 4) | (m_opcode.w.l & 0x1ff));
}
void pic16c5x_device::incf()
@ -676,8 +666,7 @@ void pic16c5x_device::incfsz()
m_ALU = GET_REGFILE(ADDR) + 1;
STORE_RESULT(ADDR, m_ALU);
if (m_ALU == 0) {
m_PC++;
PCL = m_PC & 0xff;
SET_PC(m_PC + 1);
m_inst_cycles += 1; // Add NOP cycles
}
}
@ -726,8 +715,7 @@ void pic16c5x_device::option()
void pic16c5x_device::retlw()
{
m_W = m_opcode.b.l;
m_PC = POP_STACK();
PCL = m_PC & 0xff;
SET_PC(POP_STACK());
}
void pic16c5x_device::rlf()
@ -940,33 +928,50 @@ void pic16c5x_device::device_start()
m_write_c.resolve_safe();
m_write_d.resolve_safe();
// ensure the internal ram pointers are set before get_info is called
m_program_mask = (1 << m_program_width) - 1;
m_data_mask = (1 << m_data_width) - 1;
m_status_mask = (m_picmodel == 0x1650 || m_picmodel == 0x1654 || m_picmodel == 0x1655) ? 0x07 : 0xff;
update_internalram_ptr();
m_PC = 0;
m_PREVPC = 0;
m_W = 0;
m_OPTION = 0;
m_CONFIG = 0;
m_ALU = 0;
m_WDT = 0;
memset(m_STACK, 0, sizeof(m_STACK));
m_prescaler = 0;
m_opcode.d = 0;
m_delay_timer = 0;
m_rtcc = 0;
m_count_pending = false;
m_inst_cycles = 0;
// save states
save_item(NAME(m_PC));
save_item(NAME(m_PREVPC));
save_item(NAME(m_W));
save_item(NAME(m_ALU));
save_item(NAME(m_OPTION));
save_item(NAME(m_CONFIG));
save_item(NAME(m_ALU));
save_item(NAME(m_WDT));
save_item(NAME(m_TRISA));
save_item(NAME(m_TRISB));
save_item(NAME(m_TRISC));
save_item(NAME(m_STACK));
save_item(NAME(m_prescaler));
save_item(NAME(m_opcode.d));
save_item(NAME(m_delay_timer));
save_item(NAME(m_temp_config));
save_item(NAME(m_rtcc));
save_item(NAME(m_count_pending));
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_delay_timer));
save_item(NAME(m_picmodel));
save_item(NAME(m_reset_vector));
save_item(NAME(m_temp_config));
save_item(NAME(m_inst_cycles));
// debugger
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");
@ -999,7 +1004,7 @@ void pic16c5x_device::state_import(const device_state_entry &entry)
switch (entry.index())
{
case PIC16C5x_STR:
STATUS = m_debugger_temp;
STATUS = m_debugger_temp | uint8_t(~m_status_mask);
break;
case PIC16C5x_TMR0:
TMR0 = m_debugger_temp;
@ -1017,7 +1022,7 @@ void pic16c5x_device::state_import(const device_state_entry &entry)
PORTD = m_debugger_temp;
break;
case PIC16C5x_FSR:
FSR = ((m_debugger_temp & m_picRAMmask) | uint8_t(~m_picRAMmask));
FSR = m_debugger_temp | uint8_t(~m_data_mask);
break;
case PIC16C5x_PSCL:
m_prescaler = m_debugger_temp;
@ -1030,7 +1035,7 @@ void pic16c5x_device::state_export(const device_state_entry &entry)
switch (entry.index())
{
case PIC16C5x_STR:
m_debugger_temp = STATUS;
m_debugger_temp = STATUS | uint8_t(~m_status_mask);
break;
case PIC16C5x_TMR0:
m_debugger_temp = TMR0;
@ -1048,7 +1053,7 @@ void pic16c5x_device::state_export(const device_state_entry &entry)
m_debugger_temp = PORTD;
break;
case PIC16C5x_FSR:
m_debugger_temp = ((FSR) & m_picRAMmask) | uint8_t(~m_picRAMmask);
m_debugger_temp = FSR | uint8_t(~m_data_mask);
break;
}
}
@ -1085,14 +1090,14 @@ void pic16c5x_device::state_string_export(const device_state_entry &entry, std::
void pic16c5x_device::pic16c5x_reset_regs()
{
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_t(~m_picRAMmask);
m_OPTION = T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG;
SET_PC(m_program_mask);
m_PREVPC = m_PC;
m_prescaler = 0;
m_delay_timer = 0;
m_inst_cycles = 0;
@ -1101,7 +1106,7 @@ void pic16c5x_device::pic16c5x_reset_regs()
void pic16c5x_device::pic16c5x_soft_reset()
{
SET(STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG));
SET(STATUS, TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG);
pic16c5x_reset_regs();
}
@ -1116,7 +1121,9 @@ void pic16c5x_device::device_reset()
{
pic16c5x_reset_regs();
CLR(STATUS, PA_REG);
SET(STATUS, (TO_FLAG | PD_FLAG));
SET(STATUS, TO_FLAG | PD_FLAG);
STORE_REGFILE(3, STATUS);
STORE_REGFILE(4, FSR);
}
@ -1226,9 +1233,8 @@ void pic16c5x_device::execute_run()
debugger_instruction_hook(m_PC);
m_opcode.d = M_RDOP(m_PC);
m_PC++;
PCL++;
m_opcode.d = m_program.read_word(m_PC);
SET_PC(m_PC + 1);
if (m_picmodel == 0x1650 || m_picmodel == 0x1654 || m_picmodel == 0x1655 || (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;

View File

@ -135,14 +135,17 @@ private:
uint8_t *m_internalram;
int m_icount;
int m_reset_vector;
int m_picmodel;
int m_data_width;
int m_program_width;
int m_delay_timer;
uint16_t m_temp_config;
int m_rtcc;
bool m_count_pending;
int8_t m_old_data;
uint8_t m_picRAMmask;
uint8_t m_old_data;
uint8_t m_data_mask;
uint16_t m_program_mask;
uint8_t m_status_mask;
int m_inst_cycles;
memory_access<11, 1, -1, ENDIANNESS_LITTLE>::cache m_program;
@ -179,6 +182,7 @@ private:
void CALCULATE_SUB_DIGITCARRY();
uint16_t POP_STACK();
void PUSH_STACK(uint16_t data);
void SET_PC(offs_t addr);
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);

View File

@ -4,7 +4,7 @@ license:CC0-1.0
-->
<mamelayout version="2">
<!-- define elements -->
<!-- define elements -->
<element name="but">
<rect><bounds x="0" y="0" width="1" height="1"/><color red="0.85" green="0.85" blue="0.85" /></rect>
@ -12,10 +12,10 @@ license:CC0-1.0
</element>
<element name="hl" defstate="0">
<text string=" ">
<disk>
<bounds x="0.0" y="0.0" width="1.0" height="1.0" />
<color red="0.0" green="0.0" blue="0.0" />
</text>
<color alpha="0" />
</disk>
<disk state="1">
<bounds x="0.07" y="0.07" width="0.86" height="0.86" />
<color red="0.0" green="0.0" blue="0.0" />
@ -23,11 +23,11 @@ license:CC0-1.0
</element>
<element name="digit" defstate="0">
<led7seg><color red="1.0" green="0.2" blue="0.23" /></led7seg>
<led7seg><color red="1.0" green="0.1" blue="0.15" /></led7seg>
</element>
<!-- build screen -->
<!-- build screen -->
<view name="Internal Layout">
<bounds left="7" right="53" top="7" bottom="48" />