summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z8/z8.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/z8/z8.cpp')
-rw-r--r--src/devices/cpu/z8/z8.cpp65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/devices/cpu/z8/z8.cpp b/src/devices/cpu/z8/z8.cpp
index 0926923de2c..4a632ecad8a 100644
--- a/src/devices/cpu/z8/z8.cpp
+++ b/src/devices/cpu/z8/z8.cpp
@@ -91,7 +91,7 @@ enum
#define Z8_P01M_P0L_MODE_MASK 0x03
#define Z8_P01M_P0L_MODE_OUTPUT 0x00
#define Z8_P01M_P0L_MODE_INPUT 0x01
-#define Z8_P01M_P0L_MODE_A8_A11 0x02 /* not supported */
+#define Z8_P01M_P0L_MODE_A8_A11 0x02
#define Z8_P01M_INTERNAL_STACK 0x04
#define Z8_P01M_P1_MODE_MASK 0x18
#define Z8_P01M_P1_MODE_OUTPUT 0x00
@@ -102,7 +102,7 @@ enum
#define Z8_P01M_P0H_MODE_MASK 0xc0
#define Z8_P01M_P0H_MODE_OUTPUT 0x00
#define Z8_P01M_P0H_MODE_INPUT 0x40
-#define Z8_P01M_P0H_MODE_A12_A15 0x80 /* not supported */
+#define Z8_P01M_P0H_MODE_A12_A15 0x80
#define Z8_P3M_P2_ACTIVE_PULLUPS 0x01 /* not supported */
#define Z8_P3M_P0_STROBED 0x04 /* not supported */
@@ -234,9 +234,30 @@ device_memory_interface::space_config_vector z8_device::memory_space_config() co
INLINE FUNCTIONS
***************************************************************************/
+uint16_t z8_device::mask_external_address(uint16_t addr)
+{
+ switch (P01M & (Z8_P01M_P0L_MODE_A8_A11 | Z8_P01M_P0H_MODE_A12_A15))
+ {
+ case 0:
+ addr = (addr & 0x00ff) | register_read(Z8_REGISTER_P0) << 8;
+ break;
+
+ case Z8_P01M_P0L_MODE_A8_A11:
+ addr = (addr & 0x0fff) | (register_read(Z8_REGISTER_P0) & 0xf0) << 8;
+ break;
+
+ case Z8_P01M_P0H_MODE_A12_A15:
+ addr = (addr & 0xf0ff) | (register_read(Z8_REGISTER_P0) & 0x0f) << 8;
+ break;
+ }
+ return addr;
+}
+
+
uint8_t z8_device::fetch()
{
- uint8_t data = m_direct->read_byte(m_pc);
+ uint16_t real_pc = (m_pc < m_rom_size) ? m_pc : mask_external_address(m_pc);
+ uint8_t data = m_direct->read_byte(real_pc);
m_pc++;
@@ -244,6 +265,29 @@ uint8_t z8_device::fetch()
}
+uint8_t z8_device::fetch_opcode()
+{
+ m_ppc = (m_pc < m_rom_size) ? m_pc : mask_external_address(m_pc);
+ debugger_instruction_hook(this, m_ppc);
+
+ uint8_t data = m_direct->read_byte(m_ppc);
+
+ m_pc++;
+
+ return data;
+}
+
+
+uint16_t z8_device::fetch_word()
+{
+ // ensure correct order of operations by using separate instructions
+ uint16_t data = fetch() << 8;
+ data |= fetch();
+
+ return data;
+}
+
+
uint8_t z8_device::register_read(uint8_t offset)
{
uint8_t data = 0xff;
@@ -709,7 +753,7 @@ void z8_device::device_start()
{
state_add(Z8_PC, "PC", m_pc);
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
- state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow();
state_add(Z8_SP, "SP", m_fake_sp).callimport().callexport();
state_add(STATE_GENSP, "GENSP", m_fake_sp).callimport().callexport().noshow();
state_add(Z8_RP, "RP", m_r[Z8_REGISTER_RP]);
@@ -773,17 +817,12 @@ void z8_device::execute_run()
{
do
{
- uint8_t opcode;
- int cycles;
-
- debugger_instruction_hook(this, m_pc);
-
/* TODO: sample interrupts */
m_input[3] = m_input_cb[3]();
/* fetch opcode */
- opcode = fetch();
- cycles = Z8601_OPCODE_MAP[opcode].execution_cycles;
+ uint8_t opcode = fetch_opcode();
+ int cycles = Z8601_OPCODE_MAP[opcode].execution_cycles;
/* execute instruction */
(this->*(Z8601_OPCODE_MAP[opcode].function))(opcode, &cycles);
@@ -801,10 +840,6 @@ void z8_device::device_reset()
{
m_pc = 0x000c;
- // crude hack for Z8681
- if (m_rom_size == 0)
- m_pc |= m_input_cb[0]() << 8;
-
register_write(Z8_REGISTER_TMR, 0x00);
register_write(Z8_REGISTER_PRE1, PRE1 & 0xfc);
register_write(Z8_REGISTER_PRE0, PRE0 & 0xfe);