summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/capricorn/capricorn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/capricorn/capricorn.cpp')
-rw-r--r--src/devices/cpu/capricorn/capricorn.cpp62
1 files changed, 41 insertions, 21 deletions
diff --git a/src/devices/cpu/capricorn/capricorn.cpp b/src/devices/cpu/capricorn/capricorn.cpp
index cb2b58c1a37..8a55dd7bfbd 100644
--- a/src/devices/cpu/capricorn/capricorn.cpp
+++ b/src/devices/cpu/capricorn/capricorn.cpp
@@ -8,7 +8,6 @@
#include "emu.h"
#include "capricorn.h"
#include "capricorn_dasm.h"
-#include "debugger.h"
// Register indexes
// GP registers are named "R" & the octal representation of the index (00-77)
@@ -139,9 +138,12 @@ static constexpr uint8_t E_MASK = 0xf;
DEFINE_DEVICE_TYPE(HP_CAPRICORN , capricorn_cpu_device , "capricorn" , "HP-Capricorn")
-capricorn_cpu_device::capricorn_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cpu_device(mconfig, HP_CAPRICORN, tag, owner, clock),
- m_program_config("program" , ENDIANNESS_LITTLE , 8 , 16)
+capricorn_cpu_device::capricorn_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ cpu_device(mconfig, HP_CAPRICORN, tag, owner, clock),
+ m_program_config("program" , ENDIANNESS_LITTLE , 8 , 16),
+ m_opcode_func(*this),
+ m_lma_out(*this),
+ m_intack_in(*this, 0)
{
}
@@ -169,8 +171,8 @@ void capricorn_cpu_device::device_start()
// Flags
state_add(STATE_GENFLAGS , "GENFLAGS" , m_flags).noshow().formatstr("%9s");
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
+ space(AS_PROGRAM).cache(m_cache);
+ space(AS_PROGRAM).specific(m_program);
save_item(NAME(m_reg));
save_item(NAME(m_arp));
@@ -204,6 +206,7 @@ void capricorn_cpu_device::execute_run()
debugger_instruction_hook(m_genpc);
uint8_t opcode = fetch();
+ m_opcode_func(opcode);
execute_one(opcode);
offset_pc(1);
}
@@ -243,18 +246,21 @@ std::unique_ptr<util::disasm_interface> capricorn_cpu_device::create_disassemble
return std::make_unique<capricorn_disassembler>();
}
-void capricorn_cpu_device::start_mem_burst(ea_addr_t addr)
+void capricorn_cpu_device::start_mem_burst(ea_addr_t addr , bool lmard)
{
m_flatten = false;
- // Only relevant for memory access (not for internal registers)
- m_start_addr = (uint16_t)(addr & ADDR_MASK);
+ if (!BIT(addr , GP_REG_BIT)) {
+ // Only relevant for memory access (not for internal registers)
+ m_start_addr = (uint16_t)(addr & ADDR_MASK);
+ m_lma_out(lmard);
+ }
}
-uint16_t capricorn_cpu_device::read_u16(ea_addr_t addr)
+uint16_t capricorn_cpu_device::read_u16(ea_addr_t addr , bool lmard)
{
PAIR16 tmp;
- start_mem_burst(addr);
+ start_mem_burst(addr , lmard);
tmp.b.l = RM(addr);
tmp.b.h = RM(addr);
return tmp.w;
@@ -279,7 +285,7 @@ uint8_t capricorn_cpu_device::RM(ea_addr_t& addr)
res = m_reg[ addr & ARP_DRP_MASK ];
} else {
m_curr_addr = (uint16_t)(addr & ADDR_MASK);
- res = m_program->read_byte(m_flatten ? m_start_addr : m_curr_addr);
+ res = m_program.read_byte(m_flatten ? m_start_addr : m_curr_addr);
}
addr++;
return res;
@@ -291,7 +297,7 @@ void capricorn_cpu_device::WM(ea_addr_t& addr , uint8_t v)
m_reg[ addr & ARP_DRP_MASK ] = v;
} else {
m_curr_addr = (uint16_t)(addr & ADDR_MASK);
- m_program->write_byte(m_flatten ? m_start_addr : m_curr_addr , v);
+ m_program.write_byte(m_flatten ? m_start_addr : m_curr_addr , v);
}
addr++;
}
@@ -299,7 +305,8 @@ void capricorn_cpu_device::WM(ea_addr_t& addr , uint8_t v)
uint8_t capricorn_cpu_device::fetch()
{
m_genpc = read_u16(REG_PC | GP_REG_MASK);
- return m_cache->read_byte(m_genpc);
+ start_mem_burst(m_genpc , false);
+ return m_cache.read_byte(m_genpc);
}
void capricorn_cpu_device::offset_pc(uint16_t offset)
@@ -416,12 +423,22 @@ capricorn_cpu_device::ea_addr_t capricorn_cpu_device::get_ea_idx_dir()
// Indexed direct addressing mode
m_icount -= 3;
offset_pc(1);
- uint16_t res = read_u16(m_genpc) + read_u16(m_arp | GP_REG_MASK);
+ uint16_t res = read_u16(m_genpc , false) + read_u16(m_arp | GP_REG_MASK);
offset_pc(1);
write_u16(REG_INDEX_SCRATCH | GP_REG_MASK, res);
return res;
}
+capricorn_cpu_device::ea_addr_t capricorn_cpu_device::get_ea_jsbx()
+{
+ // Indexed direct addressing mode in JSBX instruction
+ m_icount -= 3;
+ offset_pc(1);
+ uint16_t res = read_u16(m_genpc) + read_u16(m_arp | GP_REG_MASK);
+ offset_pc(1);
+ return res;
+}
+
capricorn_cpu_device::ea_addr_t capricorn_cpu_device::get_ea_lit_indir()
{
// Literal indirect addressing mode
@@ -437,7 +454,7 @@ capricorn_cpu_device::ea_addr_t capricorn_cpu_device::get_ea_idx_indir()
// Indexed indirect addressing mode
m_icount -= 5;
offset_pc(1);
- uint16_t res = read_u16(m_genpc) + read_u16(m_arp | GP_REG_MASK);
+ uint16_t res = read_u16(m_genpc , false) + read_u16(m_arp | GP_REG_MASK);
offset_pc(1);
write_u16(REG_INDEX_SCRATCH | GP_REG_MASK, res);
return read_u16(res);
@@ -975,11 +992,11 @@ void capricorn_cpu_device::do_PAD_op()
byte = RM(ea);
m_arp = byte & ARP_DRP_MASK;
COPY_BIT(BIT(byte , 6), m_flags, FLAGS_CY_BIT);
- COPY_BIT(BIT(byte , 7), m_flags, FLAGS_OVF_BIT);
byte = RM(ea);
m_drp = byte & ARP_DRP_MASK;
COPY_BIT(BIT(byte , 6), m_flags, FLAGS_DCM_BIT);
+ COPY_BIT(BIT(byte , 7), m_flags, FLAGS_OVF_BIT);
byte = RM(ea);
COPY_BIT(BIT(byte , 0), m_flags, FLAGS_LSB_BIT);
@@ -1163,7 +1180,7 @@ void capricorn_cpu_device::execute_one(uint8_t opcode)
case 0xc6:
// JSB
- do_JSB_op(get_ea_idx_dir());
+ do_JSB_op(get_ea_jsbx());
break;
case 0xc7:
@@ -1511,9 +1528,12 @@ void capricorn_cpu_device::execute_one(uint8_t opcode)
void capricorn_cpu_device::take_interrupt()
{
- // According to O. De Smet emulator interrupt handling takes 15 cycles
- m_icount -= 15;
+ // Int. ack sequence takes 9 cycles
+ // Microcode FSM runs through this state sequence (see patent):
+ // 31-15-26-13-23-22-30-16-20
+ standard_irq_callback(0, m_genpc);
+ m_icount -= 9;
push_pc();
- uint8_t vector = (uint8_t)standard_irq_callback(0);
+ uint8_t vector = m_intack_in();
vector_to_pc(vector);
}