diff options
Diffstat (limited to 'src/devices/cpu/gigatron/gigatron.cpp')
-rw-r--r-- | src/devices/cpu/gigatron/gigatron.cpp | 183 |
1 files changed, 159 insertions, 24 deletions
diff --git a/src/devices/cpu/gigatron/gigatron.cpp b/src/devices/cpu/gigatron/gigatron.cpp index b14fb25b68b..cbb26307ebf 100644 --- a/src/devices/cpu/gigatron/gigatron.cpp +++ b/src/devices/cpu/gigatron/gigatron.cpp @@ -1,5 +1,5 @@ -// license:BSD-3-Clause -// copyright-holders:Sterophonick +// license:BSD-2-Clause +// copyright-holders:Sterophonick, Phil Thomas /***************************************************************************** * * Skeleton device for Gigatron CPU Core @@ -13,7 +13,7 @@ #include "gigatrondasm.h" -DEFINE_DEVICE_TYPE(GTRON, gigatron_cpu_device, "gigatron_cpu", "Gigatron CPU Device") +DEFINE_DEVICE_TYPE(GTRON, gigatron_cpu_device, "gigatron_cpu", "Gigatron") /* FLAGS */ @@ -25,9 +25,11 @@ DEFINE_DEVICE_TYPE(GTRON, gigatron_cpu_device, "gigatron_cpu", "Gigatron CPU Dev #endif -#define gigatron_readop(A) m_program->read_dword(A) +#define gigatron_readop(A) m_program->read_word(A) #define gigatron_readmem16(A) m_data->read_dword(A) +#define gigatron_readmem8(A) m_data->read_byte(A) #define gigatron_writemem16(A,B) m_data->write_dword((A),B) +#define gigatron_writemem8(A,B) m_data->write_byte((A),B) /*********************************** @@ -54,7 +56,7 @@ void gigatron_cpu_device::execute_run() uint8_t op = (opcode >> 13) & 0x0007; uint8_t mode = (opcode >> 10) & 0x0007; uint8_t bus = (opcode >> 8) & 0x0003; - uint8_t d = (opcode >> 0) & 0x00ff; + uint16_t d = (opcode >> 0) & 0x00ff; switch( op) { @@ -76,7 +78,7 @@ void gigatron_cpu_device::execute_run() gigatron_illegal(); break; } - + m_icount--; } while( m_icount > 0 ); } @@ -95,6 +97,8 @@ void gigatron_cpu_device::init() m_x = 0; m_y = 0; m_pc = 0; + m_npc = (m_pc + 1); + m_inReg = 0xFF; state_add(GTRON_AC, "AC", m_ac); state_add(GTRON_X, "X", m_x); state_add(GTRON_Y, "Y", m_y); @@ -102,29 +106,172 @@ void gigatron_cpu_device::init() set_icountptr(m_icount); } -void gigatron_cpu_device::branchOp(int op, int mode, int bus, int d) +void gigatron_cpu_device::branchOp(uint8_t op, uint8_t mode, uint8_t bus, uint8_t d) { + const uint8_t ZERO = 0x80; + bool c = false; + uint8_t ac2 = m_ac ^ ZERO; + uint16_t base = m_pc & 0xff00; + switch (mode) { + case 0: + c = true; + base = m_y << 8; + break; + case 1: + c = (ac2 > ZERO); + break; + case 2: + c = (ac2 < ZERO); + break; + case 3: + c = (ac2 != ZERO); + break; + case 4: + c = (ac2 == ZERO); + break; + case 5: + c = (ac2 >= ZERO); + break; + case 6: + c = (ac2 <= ZERO); + break; + case 7: + c = true; + break; + } + + if (c) { + uint8_t b = offset(bus, d); + m_npc = base | b; + } } -void gigatron_cpu_device::aluOp(int op, int mode, int bus, int d) +void gigatron_cpu_device::aluOp(uint8_t op, uint8_t mode, uint8_t bus, uint16_t d) { - int b; - (void)b; + uint8_t b = 0; + //(void)b; switch(bus) { case 0: b = d; break; case 1: + b = gigatron_readmem8((uint16_t)(addr(mode, d) & m_ramMask)); + break; case 2: b = m_ac; break; case 3: + b = m_inReg; break; } + switch(op) { + case 1: + b = (m_ac & b); + break; + case 2: + b = (m_ac | b); + break; + case 3: + b = (m_ac ^ b); + break; + case 4: + b = (m_ac + b); + break; + case 5: + b = (m_ac - b); + break; + } + switch (mode) { + case 0: + case 1: + case 2: + case 3: + m_ac = b; + break; + case 4: + m_x = b; + break; + case 5: + m_y = b; + break; + case 6: + case 7: + uint16_t rising = ~(m_out & b); + if (rising & 0x40) { + m_outx = m_ac; + } + break; + + } +} + +uint16_t gigatron_cpu_device::addr(uint8_t mode, uint16_t d) +{ + switch (mode) { + case 0: + case 4: + case 5: + case 6: + return d; + case 1: + return m_x; + case 2: + return (m_y << 8) | d; + case 3: + return (m_y << 8) | m_x; + case 7: + uint16_t addr2 = (m_y << 8) | m_x; + m_x = (m_x + 1) & 0xff; + return addr2; + } + return 0; } -void gigatron_cpu_device::storeOp(int op, int mode, int bus, int d) +uint8_t gigatron_cpu_device::offset(uint8_t bus, uint16_t d) { + switch (bus) { + case 0: + return d; + case 1: + return gigatron_readmem8(d); + case 2: + return m_ac; + case 3: + return m_inReg; + } + return 0; +} + +void gigatron_cpu_device::storeOp(uint8_t op, uint8_t mode, uint8_t bus, uint16_t d) +{ + uint8_t b = 0; + switch (bus) { + case 0: + b = d; + break; + case 1: + b = 0; + logerror("UNDEFINED BEHAVIOR! 0x%04x\n", m_pc); + break; + case 2: + b = m_ac; + break; + case 3: + b = m_inReg; + break; + } + + u16 address = addr(mode, d) & m_ramMask; + gigatron_writemem8(address, b); + + switch (mode) { + case 4: + m_x = b; + break; + case 5: + m_y = b; + break; + } } void gigatron_cpu_device::device_reset() @@ -136,19 +283,7 @@ void gigatron_cpu_device::execute_set_input(int irqline, int state) #if 0 switch(irqline) { - case GTRON_INT_INTRM: // level-sensitive - m_intrm_pending = ((ASSERT_LINE == state) || (HOLD_LINE == state)); - m_intrm_state = (ASSERT_LINE == state); - break; - case GTRON_RESET: // edge-sensitive - if (CLEAR_LINE != state) - m_reset_pending = 1; - m_reset_state = (ASSERT_LINE == state); - break; - case GTRON_INT_INTR: // edge-sensitive - if (CLEAR_LINE != state) - m_intr_pending = 1; - m_intr_state = (ASSERT_LINE == state); + default: break; } #endif |