summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/sm8500/sm8500.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/sm8500/sm8500.c')
-rw-r--r--trunk/src/emu/cpu/sm8500/sm8500.c601
1 files changed, 601 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/sm8500/sm8500.c b/trunk/src/emu/cpu/sm8500/sm8500.c
new file mode 100644
index 00000000000..19b7ab3b245
--- /dev/null
+++ b/trunk/src/emu/cpu/sm8500/sm8500.c
@@ -0,0 +1,601 @@
+/*
+ Implementation for Sharp sm8500 cpu. There is hardly any information available
+ on this cpu. Currently we've only found documentation on the microcontroller
+ parts of the cpu, but nothing on the cpu itself.
+
+ Through looking at binary data we have attempted to figure out the opcodes for
+ this cpu, and made educated guesses on the number of cycles for each instruction.
+
+ Code by Wilbert Pol
+
+
+There is some internal ram for the main cpu registers. They are offset by an index value.
+The address is (PS0 & 0xF8) + register number. It is not known what happens when PS0 >= F8.
+The assumption is that F8 to 107 is used, but it might wrap around instead.
+The registers also mirror out to main RAM, appearing at 0000 to 000F regardless of where
+they are internally.
+
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "sm8500.h"
+
+#define FLAG_C 0x80
+#define FLAG_Z 0x40
+#define FLAG_S 0x20
+#define FLAG_V 0x10
+#define FLAG_D 0x08
+#define FLAG_H 0x04
+#define FLAG_B 0x02
+#define FLAG_I 0x01
+
+typedef struct _sm8500_state sm8500_state;
+struct _sm8500_state
+{
+ SM8500_CONFIG config;
+ UINT16 PC;
+ UINT8 IE0;
+ UINT8 IE1;
+ UINT8 IR0;
+ UINT8 IR1;
+ UINT8 SYS;
+ UINT8 CKC;
+ UINT8 clock_changed;
+ UINT16 SP;
+ UINT8 PS0;
+ UINT8 PS1;
+ UINT16 IFLAGS;
+ UINT8 CheckInterrupts;
+ int halted;
+ int icount;
+ device_irq_acknowledge_callback irq_callback;
+ legacy_cpu_device *device;
+ address_space *program;
+ UINT16 oldpc;
+ UINT8 register_ram[0x108];
+};
+
+INLINE sm8500_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == SM8500);
+ return (sm8500_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+static const UINT8 sm8500_b2w[8] = {
+ 0, 8, 2, 10, 4, 12, 6, 14
+};
+
+INLINE void sm8500_get_sp( sm8500_state *cpustate )
+{
+ UINT16 data = cpustate->program->read_byte(0x1c) << 8;
+ cpustate->SP = cpustate->program->read_byte(0x1d);
+ if (cpustate->SYS&0x40) cpustate->SP |= data;
+}
+
+static UINT8 sm85cpu_mem_readbyte( sm8500_state *cpustate, UINT32 offset )
+{
+ offset &= 0xffff;
+ return (offset < 0x10) ? cpustate->register_ram[offset + (cpustate->PS0 & 0xF8)]
+ : cpustate->program->read_byte( offset );
+}
+
+static void sm85cpu_mem_writebyte( sm8500_state *cpustate, UINT32 offset, UINT8 data )
+{
+ UINT8 i;
+ offset &= 0xffff;
+ if (offset < 0x10)
+ cpustate->register_ram[offset + (cpustate->PS0 & 0xF8)] = data;
+
+ cpustate->program->write_byte ( offset, data );
+
+ switch (offset)
+ {
+ case 0x10: cpustate->IE0 = data; break;
+ case 0x11: cpustate->IE1 = data; break;
+ case 0x12: cpustate->IR0 = data; break;
+ case 0x13: cpustate->IR1 = data; break;
+ case 0x19: cpustate->SYS = data; break;
+ case 0x1a: cpustate->CKC = data; break;
+ case 0x1c:
+ case 0x1d: sm8500_get_sp(cpustate); break;
+ case 0x1e: cpustate->PS0 = data;
+ for (i = 0; i < 16; i++) // refresh register contents in debugger
+ cpustate->program->write_byte(i, sm85cpu_mem_readbyte(cpustate, i)); break;
+ case 0x1f: cpustate->PS1 = data; break;
+ }
+}
+
+
+INLINE UINT16 sm85cpu_mem_readword( sm8500_state *cpustate, UINT32 address )
+{
+ return (sm85cpu_mem_readbyte( cpustate, address ) << 8) | (sm85cpu_mem_readbyte( cpustate, address+1 ));
+}
+
+INLINE void sm85cpu_mem_writeword( sm8500_state *cpustate, UINT32 address, UINT16 value )
+{
+ sm85cpu_mem_writebyte( cpustate, address, value >> 8 );
+ sm85cpu_mem_writebyte( cpustate, address+1, value );
+}
+
+static CPU_INIT( sm8500 )
+{
+ sm8500_state *cpustate = get_safe_token(device);
+
+ cpustate->irq_callback = irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ if ( device->static_config() != NULL ) {
+ cpustate->config.handle_dma = ((SM8500_CONFIG *)device->static_config())->handle_dma;
+ cpustate->config.handle_timers = ((SM8500_CONFIG *)device->static_config())->handle_timers;
+ } else {
+ cpustate->config.handle_dma = NULL;
+ cpustate->config.handle_timers = NULL;
+ }
+}
+
+static CPU_RESET( sm8500 )
+{
+ sm8500_state *cpustate = get_safe_token(device);
+
+ cpustate->PC = 0x1020;
+ cpustate->clock_changed = 0;
+ cpustate->halted = 0;
+ sm85cpu_mem_writeword(cpustate, 0x10, 0); // IE0, IE1
+ sm85cpu_mem_writeword(cpustate, 0x12, 0); // IR0, IR1
+ sm85cpu_mem_writeword(cpustate, 0x14, 0xffff); // P0, P1
+ sm85cpu_mem_writeword(cpustate, 0x16, 0xff00); // P2, P3
+ sm85cpu_mem_writebyte(cpustate, 0x19, 0); // SYS
+ sm85cpu_mem_writebyte(cpustate, 0x1a, 0); // CKC
+ sm85cpu_mem_writebyte(cpustate, 0x1f, 0); // PS1
+ sm85cpu_mem_writebyte(cpustate, 0x2b, 0xff); // URTT
+ sm85cpu_mem_writebyte(cpustate, 0x2d, 0x42); // URTS
+ sm85cpu_mem_writebyte(cpustate, 0x5f, 0x38); // WDTC
+}
+
+static CPU_EXIT( sm8500 )
+{
+}
+
+#define PUSH_BYTE(X) cpustate->SP--; \
+ if ( ( cpustate->SYS & 0x40 ) == 0 ) cpustate->SP &= 0xFF; \
+ sm85cpu_mem_writebyte( cpustate, cpustate->SP, X );
+
+INLINE void sm8500_do_interrupt(sm8500_state *cpustate, UINT16 vector) {
+ /* Get regs from ram */
+ sm8500_get_sp(cpustate);
+ cpustate->SYS = cpustate->program->read_byte(0x19);
+ cpustate->PS1 = cpustate->program->read_byte(0x1f);
+ /* Push PC */
+ PUSH_BYTE( cpustate->PC & 0xFF );
+ PUSH_BYTE( cpustate->PC >> 8 );
+ /* Push PS1 */
+ PUSH_BYTE( cpustate->PS1 );
+ /* Clear I flag */
+ cpustate->PS1 &= ~ 0x01;
+ /* save regs to ram */
+ cpustate->program->write_byte (0x1f, cpustate->PS1);
+ cpustate->program->write_byte (0x1d, cpustate->SP&0xFF);
+ if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c, cpustate->SP>>8);
+ /* Change PC to address stored at "vector" */
+ cpustate->PC = sm85cpu_mem_readword( cpustate, vector );
+}
+
+INLINE void sm8500_process_interrupts(sm8500_state *cpustate) {
+ if ( cpustate->CheckInterrupts ) {
+ int irqline = 0;
+ while( irqline < 11 ) {
+ if ( cpustate->IFLAGS & ( 1 << irqline ) ) {
+ cpustate->halted = 0;
+ cpustate->IE0 = cpustate->program->read_byte(0x10);
+ cpustate->IE1 = cpustate->program->read_byte(0x11);
+ cpustate->IR0 = cpustate->program->read_byte(0x12);
+ cpustate->IR1 = cpustate->program->read_byte(0x13);
+ cpustate->PS0 = cpustate->program->read_byte(0x1e);
+ cpustate->PS1 = cpustate->program->read_byte(0x1f);
+ switch( irqline ) {
+ case WDT_INT:
+ sm8500_do_interrupt( cpustate, 0x101C );
+ break;
+ case ILL_INT:
+ case NMI_INT:
+ sm8500_do_interrupt( cpustate, 0x101E );
+ break;
+ case DMA_INT:
+ cpustate->IR0 |= 0x80;
+ if ( ( cpustate->IE0 & 0x80 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1000 );
+ }
+ break;
+ case TIM0_INT:
+ cpustate->IR0 |= 0x40;
+ if ( ( cpustate->IE0 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1002 );
+ }
+ break;
+ case EXT_INT:
+ cpustate->IR0 |= 0x10;
+ if ( ( cpustate->IE0 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 7 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1006 );
+ }
+ break;
+ case UART_INT:
+ cpustate->IR0 |= 0x08;
+ if ( ( cpustate->IE0 & 0x08 ) && ( ( cpustate->PS0 & 0x07 ) < 6 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1008 );
+ }
+ break;
+ case LCDC_INT:
+ cpustate->IR0 |= 0x01;
+ if ( ( cpustate->IE0 & 0x01 ) && ( ( cpustate->PS0 & 0x07 ) < 5 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x100E );
+ }
+ break;
+ case TIM1_INT:
+ cpustate->IR1 |= 0x40;
+ if ( ( cpustate->IE1 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 4 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1012 );
+ }
+ break;
+ case CK_INT:
+ cpustate->IR1 |= 0x10;
+ if ( ( cpustate->IE1 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 3 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x1016 );
+ }
+ break;
+ case PIO_INT:
+ cpustate->IR1 |= 0x04;
+ if ( ( cpustate->IE1 & 0x04 ) && ( ( cpustate->PS0 & 0x07 ) < 2 ) && ( cpustate->PS1 & 0x01 ) ) {
+ sm8500_do_interrupt( cpustate, 0x101A );
+ }
+ break;
+ }
+ cpustate->IFLAGS &= ~ ( 1 << irqline );
+ cpustate->program->write_byte(0x12, cpustate->IR0);
+ cpustate->program->write_byte(0x13, cpustate->IR1);
+ }
+ irqline++;
+ }
+ }
+}
+
+static CPU_EXECUTE( sm8500 )
+{
+ sm8500_state *cpustate = get_safe_token(device);
+ UINT8 op;
+ int mycycles;
+
+ do
+ {
+ UINT8 r1,r2;
+ UINT16 s1,s2;
+ UINT32 d1,d2;
+ UINT32 res;
+
+ debugger_instruction_hook(device, cpustate->PC);
+ cpustate->oldpc = cpustate->PC;
+ mycycles = 0;
+ sm8500_process_interrupts(cpustate);
+ if ( !cpustate->halted ) {
+ op = sm85cpu_mem_readbyte( cpustate, cpustate->PC++ );
+ cpustate->SYS = cpustate->program->read_byte(0x19);
+ cpustate->PS0 = cpustate->program->read_byte(0x1e);
+ cpustate->PS1 = cpustate->program->read_byte(0x1f);
+ sm8500_get_sp(cpustate);
+ switch( op )
+ {
+#include "sm85ops.h"
+ }
+ if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c,cpustate->SP>>8);
+ cpustate->program->write_byte(0x1d,cpustate->SP&0xFF);
+ sm85cpu_mem_writebyte(cpustate,0x1e,cpustate->PS0); // need to update debugger
+ cpustate->program->write_byte(0x1f,cpustate->PS1);
+ } else {
+ mycycles = 4;
+ if ( cpustate->config.handle_dma ) {
+ cpustate->config.handle_dma( device, mycycles );
+ }
+ }
+ if ( cpustate->config.handle_timers ) {
+ cpustate->config.handle_timers( device, mycycles );
+ }
+ cpustate->icount -= mycycles;
+ } while ( cpustate->icount > 0 );
+}
+
+static CPU_BURN( sm8500 )
+{
+ sm8500_state *cpustate = get_safe_token(device);
+
+ if ( cycles > 0 ) {
+ /* burn a number of 4 cycles */
+ int n = ( cycles + 3 ) / 4;
+ cpustate->icount -= 4 * n;
+ }
+}
+
+static unsigned sm8500_get_reg( sm8500_state *cpustate, int regnum )
+{
+ switch( regnum )
+ {
+ case STATE_GENPC:
+ case SM8500_PC: return cpustate->PC;
+ case STATE_GENSP:
+ case SM8500_SP: return cpustate->SP;
+ case SM8500_PS: return sm85cpu_mem_readword( cpustate, 0x1e );
+ case SM8500_SYS16: return cpustate->SYS;
+ case SM8500_RR0: return sm85cpu_mem_readword( cpustate, 0x00 );
+ case SM8500_RR2: return sm85cpu_mem_readword( cpustate, 0x02 );
+ case SM8500_RR4: return sm85cpu_mem_readword( cpustate, 0x04 );
+ case SM8500_RR6: return sm85cpu_mem_readword( cpustate, 0x06 );
+ case SM8500_RR8: return sm85cpu_mem_readword( cpustate, 0x08 );
+ case SM8500_RR10: return sm85cpu_mem_readword( cpustate, 0x0A );
+ case SM8500_RR12: return sm85cpu_mem_readword( cpustate, 0x0C );
+ case SM8500_RR14: return sm85cpu_mem_readword( cpustate, 0x0E );
+ case SM8500_IE0: return sm85cpu_mem_readbyte( cpustate, 0x10 );
+ case SM8500_IE1: return sm85cpu_mem_readbyte( cpustate, 0x11 );
+ case SM8500_IR0: return sm85cpu_mem_readbyte( cpustate, 0x12 );
+ case SM8500_IR1: return sm85cpu_mem_readbyte( cpustate, 0x13 );
+ case SM8500_P0: return sm85cpu_mem_readbyte( cpustate, 0x14 );
+ case SM8500_P1: return sm85cpu_mem_readbyte( cpustate, 0x15 );
+ case SM8500_P2: return sm85cpu_mem_readbyte( cpustate, 0x16 );
+ case SM8500_P3: return sm85cpu_mem_readbyte( cpustate, 0x17 );
+ case SM8500_SYS: return sm85cpu_mem_readbyte( cpustate, 0x19 );
+ case SM8500_CKC: return sm85cpu_mem_readbyte( cpustate, 0x1a );
+ case SM8500_SPH: return sm85cpu_mem_readbyte( cpustate, 0x1c );
+ case SM8500_SPL: return sm85cpu_mem_readbyte( cpustate, 0x1d );
+ case SM8500_PS0: return sm85cpu_mem_readbyte( cpustate, 0x1e );
+ case SM8500_PS1: return sm85cpu_mem_readbyte( cpustate, 0x1f );
+ case SM8500_P0C: return sm85cpu_mem_readbyte( cpustate, 0x20 );
+ case SM8500_P1C: return sm85cpu_mem_readbyte( cpustate, 0x21 );
+ case SM8500_P2C: return sm85cpu_mem_readbyte( cpustate, 0x22 );
+ case SM8500_P3C: return sm85cpu_mem_readbyte( cpustate, 0x23 );
+ }
+ return 0;
+}
+
+static void sm8500_set_reg( sm8500_state *cpustate, int regnum, unsigned val )
+{
+ switch( regnum )
+ {
+ case STATE_GENPC:
+ case SM8500_PC: cpustate->PC = val; break;
+ case STATE_GENSP:
+ case SM8500_SP: cpustate->SP = val; cpustate->program->write_byte(0x1d, val&0xff); if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c, val>>8); break;
+ case SM8500_PS: sm85cpu_mem_writeword( cpustate, 0x1e, val); break;
+ case SM8500_SYS16: val&=0xff; sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
+ case SM8500_RR0: sm85cpu_mem_writeword( cpustate, 0x00, val); break;
+ case SM8500_RR2: sm85cpu_mem_writeword( cpustate, 0x02, val); break;
+ case SM8500_RR4: sm85cpu_mem_writeword( cpustate, 0x04, val); break;
+ case SM8500_RR6: sm85cpu_mem_writeword( cpustate, 0x06, val); break;
+ case SM8500_RR8: sm85cpu_mem_writeword( cpustate, 0x08, val); break;
+ case SM8500_RR10: sm85cpu_mem_writeword( cpustate, 0x0A, val); break;
+ case SM8500_RR12: sm85cpu_mem_writeword( cpustate, 0x0C, val); break;
+ case SM8500_RR14: sm85cpu_mem_writeword( cpustate, 0x0E, val); break;
+ case SM8500_IE0: sm85cpu_mem_writebyte( cpustate, 0x10, val); break;
+ case SM8500_IE1: sm85cpu_mem_writebyte( cpustate, 0x11, val); break;
+ case SM8500_IR0: sm85cpu_mem_writebyte( cpustate, 0x12, val); break;
+ case SM8500_IR1: sm85cpu_mem_writebyte( cpustate, 0x13, val); break;
+ case SM8500_P0: sm85cpu_mem_writebyte( cpustate, 0x14, val); break;
+ case SM8500_P1: sm85cpu_mem_writebyte( cpustate, 0x15, val); break;
+ case SM8500_P2: sm85cpu_mem_writebyte( cpustate, 0x16, val); break;
+ case SM8500_P3: sm85cpu_mem_writebyte( cpustate, 0x17, val); break;
+ case SM8500_SYS: sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
+ case SM8500_CKC: sm85cpu_mem_writebyte( cpustate, 0x1a, val); if ( val & 0x80 ) { cpustate->clock_changed = 1; }; break;
+ case SM8500_SPH: sm85cpu_mem_writebyte( cpustate, 0x1c, val); break;
+ case SM8500_SPL: sm85cpu_mem_writebyte( cpustate, 0x1d, val); break;
+ case SM8500_PS0: sm85cpu_mem_writebyte( cpustate, 0x1e, val); break;
+ case SM8500_PS1: sm85cpu_mem_writebyte( cpustate, 0x1f, val); break;
+ case SM8500_P0C: sm85cpu_mem_writebyte( cpustate, 0x20, val); break;
+ case SM8500_P1C: sm85cpu_mem_writebyte( cpustate, 0x21, val); break;
+ case SM8500_P2C: sm85cpu_mem_writebyte( cpustate, 0x22, val); break;
+ case SM8500_P3C: sm85cpu_mem_writebyte( cpustate, 0x23, val); break;
+ }
+}
+
+static void sm8500_set_irq_line( sm8500_state *cpustate, int irqline, int state )
+{
+ cpustate->IR0 = cpustate->program->read_byte(0x12);
+ cpustate->IR1 = cpustate->program->read_byte(0x13);
+ if ( state == ASSERT_LINE ) {
+ cpustate->IFLAGS |= ( 0x01 << irqline );
+ cpustate->CheckInterrupts = 1;
+ switch( irqline ) {
+ case DMA_INT: cpustate->IR0 |= 0x80; break;
+ case TIM0_INT: cpustate->IR0 |= 0x40; break;
+ case EXT_INT: cpustate->IR0 |= 0x10; break;
+ case UART_INT: cpustate->IR0 |= 0x08; break;
+ case LCDC_INT: cpustate->IR0 |= 0x01; break;
+ case TIM1_INT: cpustate->IR1 |= 0x40; break;
+ case CK_INT: cpustate->IR1 |= 0x10; break;
+ case PIO_INT: cpustate->IR1 |= 0x04; break;
+ }
+ } else {
+ cpustate->IFLAGS &= ~( 0x01 << irqline );
+ switch( irqline ) {
+ case DMA_INT: cpustate->IR0 &= ~0x80; break;
+ case TIM0_INT: cpustate->IR0 &= ~0x40; break;
+ case EXT_INT: cpustate->IR0 &= ~0x10; break;
+ case UART_INT: cpustate->IR0 &= ~0x08; break;
+ case LCDC_INT: cpustate->IR0 &= ~0x01; break;
+ case TIM1_INT: cpustate->IR1 &= ~0x40; break;
+ case CK_INT: cpustate->IR1 &= ~0x10; break;
+ case PIO_INT: cpustate->IR1 &= ~0x04; break;
+ }
+ if ( 0 == cpustate->IFLAGS ) {
+ cpustate->CheckInterrupts = 0;
+ }
+ }
+ cpustate->program->write_byte(0x12, cpustate->IR0);
+ cpustate->program->write_byte(0x13, cpustate->IR1);
+}
+
+static CPU_SET_INFO( sm8500 )
+{
+ sm8500_state *cpustate = get_safe_token(device);
+
+ switch(state)
+ {
+ case CPUINFO_INT_INPUT_STATE + 0:
+ case CPUINFO_INT_INPUT_STATE + 1:
+ case CPUINFO_INT_INPUT_STATE + 2:
+ case CPUINFO_INT_INPUT_STATE + 3:
+ case CPUINFO_INT_INPUT_STATE + 4:
+ case CPUINFO_INT_INPUT_STATE + 5:
+ case CPUINFO_INT_INPUT_STATE + 6:
+ case CPUINFO_INT_INPUT_STATE + 7:
+ case CPUINFO_INT_INPUT_STATE + 8:
+ case CPUINFO_INT_INPUT_STATE + 9:
+ case CPUINFO_INT_INPUT_STATE + 10:
+ sm8500_set_irq_line( cpustate, state - CPUINFO_INT_INPUT_STATE, info->i ); break;
+
+ case CPUINFO_INT_REGISTER + SM8500_RR0:
+ case CPUINFO_INT_REGISTER + SM8500_RR2:
+ case CPUINFO_INT_REGISTER + SM8500_RR4:
+ case CPUINFO_INT_REGISTER + SM8500_RR6:
+ case CPUINFO_INT_REGISTER + SM8500_RR8:
+ case CPUINFO_INT_REGISTER + SM8500_RR10:
+ case CPUINFO_INT_REGISTER + SM8500_RR12:
+ case CPUINFO_INT_REGISTER + SM8500_RR14:
+ case CPUINFO_INT_REGISTER + SM8500_PC:
+ case CPUINFO_INT_REGISTER + SM8500_SP:
+ case CPUINFO_INT_REGISTER + SM8500_PS:
+ case CPUINFO_INT_REGISTER + SM8500_SYS16:
+ case CPUINFO_INT_REGISTER + SM8500_SYS:
+ case CPUINFO_INT_REGISTER + SM8500_IE0:
+ case CPUINFO_INT_REGISTER + SM8500_IE1:
+ case CPUINFO_INT_REGISTER + SM8500_IR0:
+ case CPUINFO_INT_REGISTER + SM8500_IR1:
+ case CPUINFO_INT_REGISTER + SM8500_P0:
+ case CPUINFO_INT_REGISTER + SM8500_P1:
+ case CPUINFO_INT_REGISTER + SM8500_P2:
+ case CPUINFO_INT_REGISTER + SM8500_P3:
+ case CPUINFO_INT_REGISTER + SM8500_CKC:
+ case CPUINFO_INT_REGISTER + SM8500_SPH:
+ case CPUINFO_INT_REGISTER + SM8500_SPL:
+ case CPUINFO_INT_REGISTER + SM8500_PS0:
+ case CPUINFO_INT_REGISTER + SM8500_PS1:
+ case CPUINFO_INT_REGISTER + SM8500_P0C:
+ case CPUINFO_INT_REGISTER + SM8500_P1C:
+ case CPUINFO_INT_REGISTER + SM8500_P2C:
+ case CPUINFO_INT_REGISTER + SM8500_P3C:
+ sm8500_set_reg( cpustate, state - CPUINFO_INT_REGISTER, info->i ); break;
+
+ }
+}
+
+CPU_GET_INFO( sm8500 )
+{
+ sm8500_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch(state)
+ {
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(sm8500_state); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 8; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 5; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 16; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
+ case CPUINFO_INT_INPUT_STATE + 0:
+ case CPUINFO_INT_INPUT_STATE + 1:
+ case CPUINFO_INT_INPUT_STATE + 2:
+ case CPUINFO_INT_INPUT_STATE + 3:
+ case CPUINFO_INT_INPUT_STATE + 4:
+ case CPUINFO_INT_INPUT_STATE + 5:
+ case CPUINFO_INT_INPUT_STATE + 6:
+ case CPUINFO_INT_INPUT_STATE + 7:
+ case CPUINFO_INT_INPUT_STATE + 8:
+ case CPUINFO_INT_INPUT_STATE + 9:
+ case CPUINFO_INT_INPUT_STATE + 10: info->i = cpustate->IFLAGS & ( 1 << (state - CPUINFO_INT_INPUT_STATE)); break;
+ case CPUINFO_INT_REGISTER + SM8500_RR0:
+ case CPUINFO_INT_REGISTER + SM8500_RR2:
+ case CPUINFO_INT_REGISTER + SM8500_RR4:
+ case CPUINFO_INT_REGISTER + SM8500_RR6:
+ case CPUINFO_INT_REGISTER + SM8500_RR8:
+ case CPUINFO_INT_REGISTER + SM8500_RR10:
+ case CPUINFO_INT_REGISTER + SM8500_RR12:
+ case CPUINFO_INT_REGISTER + SM8500_RR14:
+ case CPUINFO_INT_REGISTER + SM8500_PC:
+ case CPUINFO_INT_REGISTER + SM8500_SP:
+ case CPUINFO_INT_REGISTER + SM8500_PS:
+ case CPUINFO_INT_REGISTER + SM8500_SYS16:
+ case CPUINFO_INT_REGISTER + SM8500_SYS:
+ case CPUINFO_INT_REGISTER + SM8500_IE0:
+ case CPUINFO_INT_REGISTER + SM8500_IE1:
+ case CPUINFO_INT_REGISTER + SM8500_IR0:
+ case CPUINFO_INT_REGISTER + SM8500_IR1:
+ case CPUINFO_INT_REGISTER + SM8500_P0:
+ case CPUINFO_INT_REGISTER + SM8500_P1:
+ case CPUINFO_INT_REGISTER + SM8500_P2:
+ case CPUINFO_INT_REGISTER + SM8500_P3:
+ case CPUINFO_INT_REGISTER + SM8500_CKC:
+ case CPUINFO_INT_REGISTER + SM8500_SPH:
+ case CPUINFO_INT_REGISTER + SM8500_SPL:
+ case CPUINFO_INT_REGISTER + SM8500_PS0:
+ case CPUINFO_INT_REGISTER + SM8500_PS1:
+ case CPUINFO_INT_REGISTER + SM8500_P0C:
+ case CPUINFO_INT_REGISTER + SM8500_P1C:
+ case CPUINFO_INT_REGISTER + SM8500_P2C:
+ case CPUINFO_INT_REGISTER + SM8500_P3C:
+ info->i = sm8500_get_reg( cpustate, state - CPUINFO_INT_REGISTER ); break;
+ case CPUINFO_INT_REGISTER + STATE_GENPC: info->i = sm8500_get_reg( cpustate, SM8500_PC ); break;
+ case CPUINFO_INT_REGISTER + STATE_GENSP: info->i = sm8500_get_reg( cpustate, SM8500_SP ); break;
+ case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->oldpc; break;
+
+
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(sm8500); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(sm8500); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(sm8500); break;
+ case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(sm8500); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(sm8500); break;
+ case CPUINFO_FCT_BURN: info->burn = CPU_BURN_NAME(sm8500); break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(sm8500); break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+
+ case DEVINFO_STR_NAME: strcpy( info->s, "sm8500" ); break;
+ case DEVINFO_STR_FAMILY: strcpy( info->s, "Sharp SM8500" ); break;
+ case DEVINFO_STR_VERSION: strcpy( info->s, "0.1" ); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy( info->s, __FILE__ ); break;
+ case DEVINFO_STR_CREDITS: strcpy( info->s, "Copyright The MESS Team." ); break;
+ case CPUINFO_STR_FLAGS:
+ sprintf( info->s, "%c%c%c%c%c%c%c%c",
+ cpustate->PS1 & FLAG_C ? 'C' : '.',
+ cpustate->PS1 & FLAG_Z ? 'Z' : '.',
+ cpustate->PS1 & FLAG_S ? 'S' : '.',
+ cpustate->PS1 & FLAG_V ? 'V' : '.',
+ cpustate->PS1 & FLAG_D ? 'D' : '.',
+ cpustate->PS1 & FLAG_H ? 'H' : '.',
+ cpustate->PS1 & FLAG_B ? 'B' : '.',
+ cpustate->PS1 & FLAG_I ? 'I' : '.' );
+ break;
+ case CPUINFO_STR_REGISTER + SM8500_RR0: sprintf(info->s, "RR0:%04X", sm85cpu_mem_readword( cpustate, 0x00 ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR2: sprintf(info->s, "RR2:%04X", sm85cpu_mem_readword( cpustate, 0x02 ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR4: sprintf(info->s, "RR4:%04X", sm85cpu_mem_readword( cpustate, 0x04 ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR6: sprintf(info->s, "RR6:%04X", sm85cpu_mem_readword( cpustate, 0x06 ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR8: sprintf(info->s, "RR8:%04X", sm85cpu_mem_readword( cpustate, 0x08 ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR10: sprintf(info->s, "RR10:%04X", sm85cpu_mem_readword( cpustate, 0x0A ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR12: sprintf(info->s, "RR12:%04X", sm85cpu_mem_readword( cpustate, 0x0C ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_RR14: sprintf(info->s, "RR14:%04X", sm85cpu_mem_readword( cpustate, 0x0E ) ); break;
+ case CPUINFO_STR_REGISTER + SM8500_PC: sprintf(info->s, "PC:%04X", cpustate->PC); break;
+ case CPUINFO_STR_REGISTER + SM8500_SP: sprintf(info->s, "SP:%04X", cpustate->SP); break;
+ case CPUINFO_STR_REGISTER + SM8500_PS: sprintf(info->s, "PS:%04X", ( cpustate->PS0 << 8 ) | cpustate->PS1 ); break;
+ case CPUINFO_STR_REGISTER + SM8500_SYS16: sprintf(info->s, "SYS:%02X", cpustate->SYS ); break;
+ }
+}
+
+
+DEFINE_LEGACY_CPU_DEVICE(SM8500, sm8500);