summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/lh5801/lh5801.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/lh5801/lh5801.c')
-rw-r--r--src/emu/cpu/lh5801/lh5801.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/emu/cpu/lh5801/lh5801.c b/src/emu/cpu/lh5801/lh5801.c
new file mode 100644
index 00000000000..223a2dee576
--- /dev/null
+++ b/src/emu/cpu/lh5801/lh5801.c
@@ -0,0 +1,281 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2000 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.
+ *
+ * based on info found on an artikel for the tandy trs80 pc2
+ *
+ *****************************************************************************/
+#include "cpuintrf.h"
+#include "debugger.h"
+
+#include "lh5801.h"
+
+//typedef int bool;
+
+#define VERBOSE 0
+
+#if VERBOSE
+#define LOG(x) logerror x
+#else
+#define LOG(x)
+#endif
+
+enum {
+ LH5801_T=1,
+ LH5801_P,
+ LH5801_S,
+ LH5801_U,
+ LH5801_X,
+ LH5801_Y,
+ LH5801_A,
+
+ LH5801_TM,
+ LH5801_IN,
+ LH5801_BF,
+ LH5801_PU,
+ LH5801_PV,
+ LH5801_DP,
+ LH5801_IRQ_STATE
+};
+
+typedef struct
+{
+ const LH5801_CONFIG *config;
+
+ PAIR s, p, u, x, y;
+ int tm; //9 bit
+
+ UINT8 t, a;
+
+ int bf, dp, pu, pv;
+
+ UINT16 oldpc;
+
+ int irq_state;
+
+ int idle;
+} LH5801_Regs;
+
+static int lh5801_icount = 0;
+
+static LH5801_Regs lh5801= { 0 };
+
+#define P lh5801.p.w.l
+#define S lh5801.s.w.l
+#define U lh5801.u.w.l
+#define UL lh5801.u.b.l
+#define UH lh5801.u.b.h
+#define X lh5801.x.w.l
+#define XL lh5801.x.b.l
+#define XH lh5801.x.b.h
+#define Y lh5801.y.w.l
+#define YL lh5801.y.b.l
+#define YH lh5801.y.b.h
+
+#define C 0x01
+#define IE 0x02
+#define Z 0x04
+#define V 0x08
+#define H 0x10
+
+/***************************************************************
+ * include the opcode macros, functions and tables
+ ***************************************************************/
+#include "5801tbl.c"
+
+static void lh5801_init(int cpu, int clock, const void *config, int (*irqcallback)(int))
+{
+ memset(&lh5801, 0, sizeof(lh5801));
+ lh5801.config = (const LH5801_CONFIG *) config;
+}
+
+static void lh5801_reset(void)
+{
+ P = (program_read_byte(0xfffe)<<8) | program_read_byte(0xffff);
+
+ change_pc(P);
+
+ lh5801.idle=0;
+}
+
+static void lh5801_get_context (void *dst)
+{
+ if( dst )
+ *(LH5801_Regs*)dst = lh5801;
+}
+
+static void lh5801_set_context (void *src)
+{
+ if( src )
+ {
+ lh5801 = *(LH5801_Regs*)src;
+ change_pc(P);
+ }
+}
+
+static int lh5801_execute(int cycles)
+{
+ lh5801_icount = cycles;
+
+ change_pc(P);
+
+ if (lh5801.idle) {
+ lh5801_icount=0;
+ } else {
+ do
+ {
+ lh5801.oldpc = P;
+
+ CALL_MAME_DEBUG;
+ lh5801_instruction();
+
+ } while (lh5801_icount > 0);
+ }
+
+ return cycles - lh5801_icount;
+}
+
+static void set_irq_line(int irqline, int state)
+{
+ lh5801.idle=0;
+}
+
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void lh5801_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE: set_irq_line(0, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + LH5801_P: P = info->i; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + LH5801_S: S = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_U: U = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_X: X = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_Y: Y = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_T: lh5801.t = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_TM: lh5801.tm = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_BF: lh5801.bf = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_PV: lh5801.pv = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_PU: lh5801.pu = info->i; break;
+ case CPUINFO_INT_REGISTER + LH5801_DP: lh5801.dp = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void lh5801_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(lh5801); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 2; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; 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 = 2; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 19; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE: info->i = lh5801.irq_state; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = lh5801.oldpc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + LH5801_P: info->i = P; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + LH5801_S: info->i = S; break;
+ case CPUINFO_INT_REGISTER + LH5801_U: info->i = U; break;
+ case CPUINFO_INT_REGISTER + LH5801_X: info->i = X; break;
+ case CPUINFO_INT_REGISTER + LH5801_Y: info->i = Y; break;
+ case CPUINFO_INT_REGISTER + LH5801_T: info->i = lh5801.t; break;
+ case CPUINFO_INT_REGISTER + LH5801_TM: info->i = lh5801.tm; break;
+ case CPUINFO_INT_REGISTER + LH5801_IN: info->i = lh5801.config->in(); break;
+ case CPUINFO_INT_REGISTER + LH5801_BF: info->i = lh5801.bf; break;
+ case CPUINFO_INT_REGISTER + LH5801_PV: info->i = lh5801.pv; break;
+ case CPUINFO_INT_REGISTER + LH5801_PU: info->i = lh5801.pu; break;
+ case CPUINFO_INT_REGISTER + LH5801_DP: info->i = lh5801.dp; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = lh5801_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = lh5801_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = lh5801_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = lh5801_init; break;
+ case CPUINFO_PTR_RESET: info->reset = lh5801_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = NULL; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = lh5801_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = lh5801_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &lh5801_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "LH5801"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s = cpuintrf_temp_str(), "LH5801"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s = cpuintrf_temp_str(), "1.0alpha"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s = cpuintrf_temp_str(), __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s = cpuintrf_temp_str(), "Copyright (c) 2000 Peter Trauner, all rights reserved."); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s = cpuintrf_temp_str(), "%s%s%s%s%s%s%s%s",
+ lh5801.t&0x80?"1":"0",
+ lh5801.t&0x40?"1":"0",
+ lh5801.t&0x20?"1":"0",
+ lh5801.t&0x10?"H":".",
+ lh5801.t&8?"V":".",
+ lh5801.t&4?"Z":".",
+ lh5801.t&2?"I":".",
+ lh5801.t&1?"C":".");
+ break;
+
+ case CPUINFO_STR_REGISTER + LH5801_P: sprintf(info->s = cpuintrf_temp_str(), "P:%04X", lh5801.p.w.l); break;
+ case CPUINFO_STR_REGISTER + LH5801_S: sprintf(info->s = cpuintrf_temp_str(), "S:%04X", lh5801.s.w.l); break;
+ case CPUINFO_STR_REGISTER + LH5801_U: sprintf(info->s = cpuintrf_temp_str(), "U:%04X", lh5801.u.w.l); break;
+ case CPUINFO_STR_REGISTER + LH5801_X: sprintf(info->s = cpuintrf_temp_str(), "X:%04X", lh5801.x.w.l); break;
+ case CPUINFO_STR_REGISTER + LH5801_Y: sprintf(info->s = cpuintrf_temp_str(), "Y:%04X", lh5801.y.w.l); break;
+ case CPUINFO_STR_REGISTER + LH5801_T: sprintf(info->s = cpuintrf_temp_str(), "T:%02X", lh5801.t); break;
+ case CPUINFO_STR_REGISTER + LH5801_A: sprintf(info->s = cpuintrf_temp_str(), "A:%02X", lh5801.a); break;
+ case CPUINFO_STR_REGISTER + LH5801_TM: sprintf(info->s = cpuintrf_temp_str(), "TM:%03X", lh5801.tm); break;
+ case CPUINFO_STR_REGISTER + LH5801_IN: sprintf(info->s = cpuintrf_temp_str(), "IN:%02X", lh5801.config->in()); break;
+ case CPUINFO_STR_REGISTER + LH5801_PV: sprintf(info->s = cpuintrf_temp_str(), "PV:%04X", lh5801.pv); break;
+ case CPUINFO_STR_REGISTER + LH5801_PU: sprintf(info->s = cpuintrf_temp_str(), "PU:%04X", lh5801.pu); break;
+ case CPUINFO_STR_REGISTER + LH5801_BF: sprintf(info->s = cpuintrf_temp_str(), "BF:%04X", lh5801.bf); break;
+ case CPUINFO_STR_REGISTER + LH5801_DP: sprintf(info->s = cpuintrf_temp_str(), "DP:%04X", lh5801.dp); break;
+ }
+}