summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/sc61860/sc61860.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/sc61860/sc61860.c')
-rw-r--r--trunk/src/emu/cpu/sc61860/sc61860.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/sc61860/sc61860.c b/trunk/src/emu/cpu/sc61860/sc61860.c
new file mode 100644
index 00000000000..b943bbef7d6
--- /dev/null
+++ b/trunk/src/emu/cpu/sc61860/sc61860.c
@@ -0,0 +1,252 @@
+/*****************************************************************************
+ *
+ * sc61860.c
+ * portable sharp 61860 emulator interface
+ * (sharp pocket computers)
+ *
+ * Copyright Peter Trauner, all rights reserved.
+ *
+ * - This source code is released as freeware for non-commercial purposes.
+ * - You are free to use and redistribute this code in modified or
+ * unmodified form, provided you list me in the credits.
+ * - If you modify this source code, you must add a notice to each modified
+ * source file that it has been changed. If you're a nice person, you
+ * will clearly mark each change too. :)
+ * - If you wish to use this for commercial purposes, please contact me at
+ * peter.trauner@jk.uni-linz.ac.at
+ * - The author of this copywritten work reserves the right to change the
+ * terms of its usage and license at any time, including retroactively
+ * - This entire notice must remain in the source code.
+ *
+ * History of changes:
+ * 29.7.2001 Several changes listed below taken by Mario Konegger
+ * (konegger@itp.tu-graz.ac.at)
+ * Added 0x7f to set_reg, to prevent p,q,r, overflow.
+ * Changed 512ms timerinterval from 256 to 128, thus the
+ * duration of one period is 512ms.
+ * Extended execute procudure with HLT-mode of CPU.
+ *****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+
+#include "sc61860.h"
+#include "sc.h"
+
+#define VERBOSE 0
+
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+
+/****************************************************************************
+ * The 61860 registers.
+ ****************************************************************************/
+typedef struct _sc61860_state sc61860_state;
+struct _sc61860_state
+{
+ sc61860_cpu_core *config;
+ UINT8 p, q, r; //7 bits only?
+
+ UINT8 c; // port c, used for HLT.
+ UINT8 d, h;
+ UINT16 oldpc, pc, dp;
+
+ int carry, zero;
+
+ struct { int t2ms, t512ms; int count; } timer;
+
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ int icount;
+ UINT8 ram[0x100]; // internal special ram, should be 0x60, 0x100 to avoid memory corruption for now
+};
+
+INLINE sc61860_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == SC61860);
+ return (sc61860_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+UINT8 *sc61860_internal_ram(device_t *device)
+{
+ sc61860_state *cpustate = get_safe_token(device);
+ return cpustate->ram;
+}
+
+static TIMER_CALLBACK(sc61860_2ms_tick)
+{
+ sc61860_state *cpustate = (sc61860_state *)ptr;
+ if (--cpustate->timer.count == 0)
+ {
+ cpustate->timer.count = 128;
+ cpustate->timer.t512ms = !cpustate->timer.t512ms;
+ }
+ cpustate->timer.t2ms = !cpustate->timer.t2ms;
+}
+
+/***************************************************************
+ * include the opcode macros, functions and tables
+ ***************************************************************/
+#include "scops.c"
+#include "sctable.c"
+
+static CPU_RESET( sc61860 )
+{
+ sc61860_state *cpustate = get_safe_token(device);
+ cpustate->timer.t2ms=0;
+ cpustate->timer.t512ms=0;
+ cpustate->timer.count=256;
+ cpustate->pc=0;
+}
+
+static CPU_INIT( sc61860 )
+{
+ sc61860_state *cpustate = get_safe_token(device);
+ cpustate->config = (sc61860_cpu_core *) device->static_config();
+ device->machine().scheduler().timer_pulse(attotime::from_hz(500), FUNC(sc61860_2ms_tick), 0, cpustate);
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+}
+
+static CPU_EXECUTE( sc61860 )
+{
+ sc61860_state *cpustate = get_safe_token(device);
+
+ do
+ {
+ cpustate->oldpc = cpustate->pc;
+
+ debugger_instruction_hook(device, cpustate->pc);
+
+ sc61860_instruction(cpustate);
+
+#if 0
+ /* Are we in HLT-mode? */
+ if (cpustate->c & 4)
+ {
+ if ((cpustate->config && cpustate->config->ina && (cpustate->config->ina(cpustate)!=0)) || cpustate->timer.t512ms)
+ {
+ cpustate->c&=0xfb;
+ if (cpustate->config->outc) cpustate->config->outc(cpustate->c);
+ }
+ cpustate->icount-=4;
+ }
+ else if(cpustate->c & 8) {}
+
+ else sc61860_instruction(cpustate);
+#endif
+
+ } while (cpustate->icount > 0);
+}
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( sc61860 )
+{
+ sc61860_state *cpustate = get_safe_token(device);
+ switch (state)
+ {
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + SC61860_PC: cpustate->pc = info->i; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + SC61860_R: cpustate->r = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_DP: cpustate->dp = info->i; break;
+ case CPUINFO_INT_REGISTER + SC61860_P: cpustate->p = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_Q: cpustate->q = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_CARRY: cpustate->carry = info->i; break;
+ case CPUINFO_INT_REGISTER + SC61860_ZERO: cpustate->zero = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+CPU_GET_INFO( sc61860 )
+{
+ sc61860_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(sc61860_state); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; 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 = 4; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 2; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 4; 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_PREVIOUSPC: info->i = cpustate->oldpc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + SC61860_PC: info->i = cpustate->pc; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + SC61860_R: info->i = cpustate->r; break;
+ case CPUINFO_INT_REGISTER + SC61860_DP: info->i = cpustate->dp; break;
+ case CPUINFO_INT_REGISTER + SC61860_P: info->i = cpustate->p; break;
+ case CPUINFO_INT_REGISTER + SC61860_Q: info->i = cpustate->q; break;
+ case CPUINFO_INT_REGISTER + SC61860_CARRY: info->i = cpustate->carry; break;
+ case CPUINFO_INT_REGISTER + SC61860_ZERO: info->i = cpustate->zero; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(sc61860); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(sc61860); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(sc61860); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(sc61860); break;
+ case CPUINFO_FCT_BURN: info->burn = NULL; break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(sc61860); break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "SC61860"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "SC61860"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0beta"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Peter Trauner, all rights reserved."); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%c%c", cpustate->zero?'Z':'.', cpustate->carry ? 'C':'.');
+ break;
+
+ case CPUINFO_STR_REGISTER + SC61860_PC: sprintf(info->s, "PC:%.4x", cpustate->pc);break;
+ case CPUINFO_STR_REGISTER + SC61860_DP: sprintf(info->s, "DP:%.4x", cpustate->dp);break;
+ case CPUINFO_STR_REGISTER + SC61860_P: sprintf(info->s, "P:%.2x", cpustate->p);break;
+ case CPUINFO_STR_REGISTER + SC61860_Q: sprintf(info->s, "Q:%.2x", cpustate->q);break;
+ case CPUINFO_STR_REGISTER + SC61860_R: sprintf(info->s, "R:%.2x", cpustate->r);break;
+ case CPUINFO_STR_REGISTER + SC61860_I: sprintf(info->s, "I:%.2x", cpustate->ram[I]);break;
+ case CPUINFO_STR_REGISTER + SC61860_J: sprintf(info->s, "J:%.2x", cpustate->ram[J]);break;
+ case CPUINFO_STR_REGISTER + SC61860_K: sprintf(info->s, "K:%.2x", cpustate->ram[K]);break;
+ case CPUINFO_STR_REGISTER + SC61860_L: sprintf(info->s, "L:%.2x", cpustate->ram[L]);break;
+ case CPUINFO_STR_REGISTER + SC61860_V: sprintf(info->s, "V:%.2x", cpustate->ram[V]);break;
+ case CPUINFO_STR_REGISTER + SC61860_W: sprintf(info->s, "W:%.2x", cpustate->ram[W]);break;
+ case CPUINFO_STR_REGISTER + SC61860_H: sprintf(info->s, "W:%.2x", cpustate->h);break;
+ case CPUINFO_STR_REGISTER + SC61860_BA: sprintf(info->s, "BA:%.2x%.2x", cpustate->ram[B], cpustate->ram[A]);break;
+ case CPUINFO_STR_REGISTER + SC61860_X: sprintf(info->s, "X: %.2x%.2x", cpustate->ram[XH], cpustate->ram[XL]);break;
+ case CPUINFO_STR_REGISTER + SC61860_Y: sprintf(info->s, "Y: %.2x%.2x", cpustate->ram[YH], cpustate->ram[YL]);break;
+ case CPUINFO_STR_REGISTER + SC61860_CARRY: sprintf(info->s, "Carry: %d", cpustate->carry);break;
+ case CPUINFO_STR_REGISTER + SC61860_ZERO: sprintf(info->s, "Zero: %d", cpustate->zero);break;
+ }
+}
+
+DEFINE_LEGACY_CPU_DEVICE(SC61860, sc61860);