summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/sc61860
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2007-12-17 15:19:59 +0000
committer Aaron Giles <aaron@aarongiles.com>2007-12-17 15:19:59 +0000
commit7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch)
tree19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/emu/cpu/sc61860
parent3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff)
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/emu/cpu/sc61860')
-rw-r--r--src/emu/cpu/sc61860/readpc.c195
-rw-r--r--src/emu/cpu/sc61860/sc.h34
-rw-r--r--src/emu/cpu/sc61860/sc61860.c255
-rw-r--r--src/emu/cpu/sc61860/sc61860.h58
-rw-r--r--src/emu/cpu/sc61860/scdasm.c220
-rw-r--r--src/emu/cpu/sc61860/scops.c734
-rw-r--r--src/emu/cpu/sc61860/sctable.c144
7 files changed, 1640 insertions, 0 deletions
diff --git a/src/emu/cpu/sc61860/readpc.c b/src/emu/cpu/sc61860/readpc.c
new file mode 100644
index 00000000000..b3808bc4880
--- /dev/null
+++ b/src/emu/cpu/sc61860/readpc.c
@@ -0,0 +1,195 @@
+#if 0
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/io.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <dos.h>
+
+// gcc -O
+// important because of inb, outb
+
+/*
+ dumps data sent form sharp pc1401 into file
+ at sharp the following program must be started after
+ this dos program was started
+ simple dos utility
+ first arg (filename of file to be written) must be specified
+
+ ct eprop needed
+ changing to parallel port should be easy
+
+nearly all sharp pocket pc's system roms should be readable
+this way.
+
+for some early pocket pc's it would be neccessary to load
+this program into memory.
+(they don't have poke/peek/call instructions,
+so this program can't be typed in)
+
+adapter sharp - cteprommer
+
+1
+2 6v
+3 gnd 8 bit textool gnd pin 20
+4 f0 data--> 8 bit textool data 0 pin 17
+5 f1 handshake --> 8 bit textool data 1 pin 18
+6 save
+7 load
+8 ib7 <--handshake 8 bit textool adress 0 pin 16
+9 ib9
+10
+11
+
+problems with the handshake in at the sharp
+so I didn't use the handshake in the sharp side
+but the pc side must not be interrupted with interrupt
+(pure dos needed?)
+
+*/
+
+
+#define outb(v,adr) outportb(adr,v)
+#define inb(adr) inportb(adr)
+
+#if 0
+ /* this routine dump the memory (start 0)
+ in an endless loop,
+ the pc side must be started before this
+ actual version should be in mess/machine/pocketc.c
+ */
+
+1 restore: for i=16384 to 16455:read a: poke i,a: next i
+10 call 16384
+100 data
+#if 1
+ 18,4,//lip xl
+ 2,0,//lia 0 startaddress low
+ 219,//exam
+ 18,5,//lip xh
+ 2,0,//lia 0 startaddress high
+ 219,//exam
+//400f x:
+ // dump internal rom
+ 18,5,//lip 4
+ 89,//ldm
+ 218,//exab
+ 18,4,//lip 5
+ 89,//ldm
+ 4,//ix for increasing x
+ 0,0,//lii,0
+ 18,20,//lip 20
+ 53, //
+ 18,20,// lip 20
+ 219,//exam
+#else
+ 18,4,//lip xl
+ 2,255,//lia 0
+ 219,//exam
+ 18,5,//lip xh
+ 2,255,//lia 0
+ 219,//exam
+//400f x:
+ // dump external memory
+ 4, //ix
+ 87,// ldd
+#endif
+ 218,//exab
+
+
+
+ 0,4,//lii 4
+
+ //a:
+ 218,// exab
+ 90,// sl
+ 218,// exab
+ 18,94,// lip 94
+ 96,252,// anma 252
+ 2,2, //lia 2
+ 196,// adcm
+ 95,// outf
+ //b:
+ 204,//inb
+ 102,128,//tsia 0x80
+#if 0
+ 41,4,// jnzm b
+#else
+ // input not working reliable!
+ // so handshake removed, PC side must run with disabled
+ // interrupt to not lose data
+ 78,20, //wait 20
+#endif
+
+ 218,// exab
+ 90,// sl
+ 218,// exab
+ 18,94,// lip 94
+ 96,252,//anma 252
+ 2,0,// lia 0
+ 196,//adcm
+ 95,// outf
+ //c:
+ 204,//inb
+ 102,128,//tsia 0x80
+#if 0
+ 57,4,// jzm c
+#else
+ 78,20, //wait 20
+#endif
+
+ 65,//deci
+ 41,34,//jnzm a
+
+ 41,41,//jnzm x:
+
+ 55,// rtn
+// fill up with several 55
+// so you don't have to calculate the exact end in the loop
+#endif
+
+#define PORT_BASE 0x3e0
+
+int main(int argc, char *argv[])
+{
+ unsigned i,v,j,a;
+ char buffer[32768];
+ FILE *out=fopen(argv[1],"wb");
+
+#if 0
+ ioperm(PORT_BASE,8,1);
+ nice(-256);
+#endif
+ asm { cli }
+
+ outb(0x18,PORT_BASE+3); // VCC ON
+ outb(0xc0, PORT_BASE+2);
+ outb(7,PORT_BASE+6); // VPP 12.5, reset off
+
+ outb(0,PORT_BASE);
+ for(j=0;j<0x8000;j++) {
+ for (i=0,v=0;i<4;i++) {
+ for(;((a=inb(PORT_BASE+4))&2)==0; ) ;
+ v=(v<<1)|(a&1);
+ outb(1,PORT_BASE);
+ for(;((a=inb(PORT_BASE+4))&2)!=0; ) ;
+ v=(v<<1)|(a&1);
+ outb(0,PORT_BASE);
+ }
+ buffer[j]=v;
+// printf("%.2x\n",v);
+ }
+ asm { sti }
+ fwrite(buffer,2,0x4000,out);
+ fclose(out);
+
+#if 0
+ outb(8,PORT_BASE+2); // led off
+ outb(0,PORT_BASE+3); //VCC off
+ outb(0,PORT_BASE+6); //VPP off
+#endif
+ return 0;
+}
+
diff --git a/src/emu/cpu/sc61860/sc.h b/src/emu/cpu/sc61860/sc.h
new file mode 100644
index 00000000000..8f7d843a365
--- /dev/null
+++ b/src/emu/cpu/sc61860/sc.h
@@ -0,0 +1,34 @@
+#define I 0
+#define J 1
+#define A 2
+#define B 3
+#define XL 4
+#define XH 5
+#define YL 6
+#define YH 7
+#define K 8
+#define L 9
+#define V 10 // some docus m
+#define W 11 // some docus n
+#define IA 92
+#define IB 93
+#define F0 94
+#define C 95
+
+enum {
+ SC61860_PC=1, SC61860_DP,
+ SC61860_P, SC61860_Q, SC61860_R,
+ SC61860_CARRY,
+ SC61860_ZERO,
+ // the following are in the internal ram!
+ SC61860_BA,
+ SC61860_X, SC61860_Y,
+ SC61860_I, SC61860_J, SC61860_K, SC61860_L, SC61860_V, SC61860_W,
+ SC61860_H
+
+// SC61860_NMI_STATE,
+// SC61860_IRQ_STATE
+};
+
+#define PEEK_OP(pc) cpu_readop(pc)
+#define PEEK_NIBBLE(adr) cpu_readmem_16(adr)
diff --git a/src/emu/cpu/sc61860/sc61860.c b/src/emu/cpu/sc61860/sc61860.c
new file mode 100644
index 00000000000..ef62727d1ad
--- /dev/null
+++ b/src/emu/cpu/sc61860/sc61860.c
@@ -0,0 +1,255 @@
+/*****************************************************************************
+ *
+ * sc61860.c
+ * portable sharp 61860 emulator interface
+ * (sharp pocket computers)
+ *
+ * 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.
+ *
+ * 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 "cpuintrf.h"
+#include "debugger.h"
+
+#include "sc61860.h"
+#include "sc.h"
+
+#define VERBOSE 0
+
+#if VERBOSE
+#define LOG(x) logerror x
+#else
+#define LOG(x)
+#endif
+
+
+/****************************************************************************
+ * The 61860 registers.
+ ****************************************************************************/
+typedef struct
+{
+ SC61860_CONFIG *config;
+ UINT8 ram[0x60]; // internal special ram
+ 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;
+} SC61860_Regs;
+
+static int sc61860_ICount = 0;
+
+static SC61860_Regs sc61860;
+
+UINT8 *sc61860_internal_ram(void) { return sc61860.ram; }
+
+static TIMER_CALLBACK(sc61860_2ms_tick)
+{
+ if (--sc61860.timer.count == 0)
+ {
+ sc61860.timer.count = 128;
+ sc61860.timer.t512ms = !sc61860.timer.t512ms;
+ }
+ sc61860.timer.t2ms = !sc61860.timer.t2ms;
+}
+
+/***************************************************************
+ * include the opcode macros, functions and tables
+ ***************************************************************/
+#include "scops.c"
+#include "sctable.c"
+
+static void sc61860_reset(void)
+{
+ sc61860.timer.t2ms=0;
+ sc61860.timer.t512ms=0;
+ sc61860.timer.count=256;
+ sc61860.pc=0;
+ change_pc(sc61860.pc);
+}
+
+static void sc61860_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ sc61860.config = (SC61860_CONFIG *) config;
+ timer_pulse(ATTOTIME_IN_HZ(500), 0, sc61860_2ms_tick);
+}
+
+static void sc61860_get_context (void *dst)
+{
+ if( dst )
+ *(SC61860_Regs*)dst = sc61860;
+}
+
+static void sc61860_set_context (void *src)
+{
+ if( src )
+ {
+ sc61860 = *(SC61860_Regs*)src;
+ change_pc(sc61860.pc);
+ }
+}
+
+static int sc61860_execute(int cycles)
+{
+ sc61860_ICount = cycles;
+
+ change_pc(sc61860.pc);
+
+ do
+ {
+ sc61860.oldpc = sc61860.pc;
+
+ CALL_MAME_DEBUG;
+
+ sc61860_instruction();
+
+ /* Are we in HLT-mode? */
+ /*if (sc61860.c & 4)
+ {
+ if ((sc61860.config && sc61860.config->ina && (sc61860.config->ina()!=0)) || sc61860.timer.t512ms)
+ {
+ sc61860.c&=0xfb;
+ if (sc61860.config->outc) sc61860.config->outc(sc61860.c);
+ }
+ sc61860_ICount-=4;
+ }
+ else if(sc61860.c & 8) {}
+
+ else sc61860_instruction();*/
+
+ } while (sc61860_ICount > 0);
+
+ return cycles - sc61860_ICount;
+}
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void sc61860_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + SC61860_PC: sc61860.pc = info->i; change_pc(sc61860.pc); break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + SC61860_R: sc61860.r = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_DP: sc61860.dp = info->i; break;
+ case CPUINFO_INT_REGISTER + SC61860_P: sc61860.p = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_Q: sc61860.q = info->i & 0x7F; break;
+ case CPUINFO_INT_REGISTER + SC61860_CARRY: sc61860.carry = info->i; break;
+ case CPUINFO_INT_REGISTER + SC61860_ZERO: sc61860.zero = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void sc61860_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(sc61860); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; 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 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_PREVIOUSPC: info->i = sc61860.oldpc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + SC61860_PC: info->i = sc61860.pc; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + SC61860_R: info->i = sc61860.r; break;
+ case CPUINFO_INT_REGISTER + SC61860_DP: info->i = sc61860.dp; break;
+ case CPUINFO_INT_REGISTER + SC61860_P: info->i = sc61860.p; break;
+ case CPUINFO_INT_REGISTER + SC61860_Q: info->i = sc61860.q; break;
+ case CPUINFO_INT_REGISTER + SC61860_CARRY: info->i = sc61860.carry; break;
+ case CPUINFO_INT_REGISTER + SC61860_ZERO: info->i = sc61860.zero; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = sc61860_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = sc61860_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = sc61860_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = sc61860_init; break;
+ case CPUINFO_PTR_RESET: info->reset = sc61860_reset; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = sc61860_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = sc61860_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &sc61860_ICount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "SC61860"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s = cpuintrf_temp_str(), "SC61860"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s = cpuintrf_temp_str(), "1.0beta"); 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,2001 Peter Trauner, all rights reserved."); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s = cpuintrf_temp_str(), "%c%c", sc61860.zero?'Z':'.', sc61860.carry ? 'C':'.');
+ break;
+
+ case CPUINFO_STR_REGISTER + SC61860_PC: sprintf(info->s = cpuintrf_temp_str(), "PC:%.4x", sc61860.pc);break;
+ case CPUINFO_STR_REGISTER + SC61860_DP: sprintf(info->s = cpuintrf_temp_str(), "DP:%.4x", sc61860.dp);break;
+ case CPUINFO_STR_REGISTER + SC61860_P: sprintf(info->s = cpuintrf_temp_str(), "P:%.2x", sc61860.p);break;
+ case CPUINFO_STR_REGISTER + SC61860_Q: sprintf(info->s = cpuintrf_temp_str(), "Q:%.2x", sc61860.q);break;
+ case CPUINFO_STR_REGISTER + SC61860_R: sprintf(info->s = cpuintrf_temp_str(), "R:%.2x", sc61860.r);break;
+ case CPUINFO_STR_REGISTER + SC61860_I: sprintf(info->s = cpuintrf_temp_str(), "I:%.2x", sc61860.ram[I]);break;
+ case CPUINFO_STR_REGISTER + SC61860_J: sprintf(info->s = cpuintrf_temp_str(), "J:%.2x", sc61860.ram[J]);break;
+ case CPUINFO_STR_REGISTER + SC61860_K: sprintf(info->s = cpuintrf_temp_str(), "K:%.2x", sc61860.ram[K]);break;
+ case CPUINFO_STR_REGISTER + SC61860_L: sprintf(info->s = cpuintrf_temp_str(), "L:%.2x", sc61860.ram[L]);break;
+ case CPUINFO_STR_REGISTER + SC61860_V: sprintf(info->s = cpuintrf_temp_str(), "V:%.2x", sc61860.ram[V]);break;
+ case CPUINFO_STR_REGISTER + SC61860_W: sprintf(info->s = cpuintrf_temp_str(), "W:%.2x", sc61860.ram[W]);break;
+ case CPUINFO_STR_REGISTER + SC61860_H: sprintf(info->s = cpuintrf_temp_str(), "W:%.2x", sc61860.h);break;
+ case CPUINFO_STR_REGISTER + SC61860_BA: sprintf(info->s = cpuintrf_temp_str(), "BA:%.2x%.2x", sc61860.ram[B], sc61860.ram[A]);break;
+ case CPUINFO_STR_REGISTER + SC61860_X: sprintf(info->s = cpuintrf_temp_str(), "X: %.2x%.2x", sc61860.ram[XH], sc61860.ram[XL]);break;
+ case CPUINFO_STR_REGISTER + SC61860_Y: sprintf(info->s = cpuintrf_temp_str(), "Y: %.2x%.2x", sc61860.ram[YH], sc61860.ram[YL]);break;
+ case CPUINFO_STR_REGISTER + SC61860_CARRY: sprintf(info->s = cpuintrf_temp_str(), "Carry: %d", sc61860.carry);break;
+ case CPUINFO_STR_REGISTER + SC61860_ZERO: sprintf(info->s = cpuintrf_temp_str(), "Zero: %d", sc61860.zero);break;
+ }
+}
diff --git a/src/emu/cpu/sc61860/sc61860.h b/src/emu/cpu/sc61860/sc61860.h
new file mode 100644
index 00000000000..2da8cb00648
--- /dev/null
+++ b/src/emu/cpu/sc61860/sc61860.h
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ *
+ * sc61860.h
+ * portable sharp 61860 emulator interface
+ * (sharp pocket computers)
+ *
+ * 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.
+ *
+ *****************************************************************************/
+#ifndef _SC61860_H
+#define _SC61860_H
+
+/*
+ official names seam to be
+ ESR-H, ESR-J
+ (ESR-L SC62015 ist complete different)
+ */
+
+/* unsolved problems
+ the processor has 8 kbyte internal rom
+ only readable with special instructions and program execution
+ 64 kb external ram (first 8kbyte not seen for program execution?) */
+
+#include "cpuintrf.h"
+
+typedef struct {
+ int (*reset)(void);
+ int (*brk)(void);
+ int (*x)(void);
+ int (*ina)(void);
+ void (*outa)(int);
+ int (*inb)(void);
+ void (*outb)(int);
+ void (*outc)(int);
+} SC61860_CONFIG;
+
+#ifdef MAME_DEBUG
+unsigned sc61860_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
+#endif /* MAME_DEBUG */
+
+/* this is though for power on/off of the sharps */
+UINT8 *sc61860_internal_ram(void);
+
+void sc61860_get_info(UINT32 state, cpuinfo *info);
+
+#endif
diff --git a/src/emu/cpu/sc61860/scdasm.c b/src/emu/cpu/sc61860/scdasm.c
new file mode 100644
index 00000000000..5111ddcf56f
--- /dev/null
+++ b/src/emu/cpu/sc61860/scdasm.c
@@ -0,0 +1,220 @@
+/*****************************************************************************
+ *
+ * scdasm.c
+ * portable sharp 61860 emulator interface
+ * (sharp pocket computers)
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include "cpuintrf.h"
+#include "debugger.h"
+
+#include "sc61860.h"
+#include "sc.h"
+
+/*
+ new:
+ clra 0x23
+ nopt 0x33
+ nopt 0x68
+ nopt 0x6a
+ rz n 0x72, 0x73, 0x76, 0x77
+ tsma 0xc6
+ nopw 0xcd
+ nopw 0xd3
+ sz n 0xd7
+ nopw 0xda
+
+! writ 211 nopw?
+*/
+
+/* explanations for the sharp mnemonics
+ d data: external memory
+ m memory: internal memory (address in p register)
+ p register (internal memory adress)
+ q register (internal memory adress), internally used in several opcodes!?
+ r stack pointer (internal memory)
+ c carry flag
+ z zero flag
+
+ the following are special internal memory registers
+ a akkumulator: (2)
+ b b register: (3)
+ i,j,k,l,v,w counter
+ x external memory address
+ y external memory address
+ ia input/output (92)
+ ib input/output (93)
+ f0 output (94)
+ c output(95)
+
+ li load immediate
+ ld load accu
+ st store accu
+ or
+ an and
+ inc
+ dec
+ ad add
+ sb sub
+ cp compare
+ jr jump relativ
+ jp jump absolut
+ mv move
+ ex exchange
+*/
+
+
+typedef enum {
+ Ill,
+ Imp,
+ Imm, ImmW,
+ RelP, RelM,
+ Abs,
+ Ptc,
+ Etc,
+ Cal,
+ Lp
+} Adr;
+
+static const struct { const char *mnemonic; Adr adr; } table[]={
+ { "LII", Imm }, { "LIJ", Imm }, { "LIA", Imm }, { "LIB", Imm },
+ { "IX", Imp }, { "DX", Imp }, { "IY", Imp }, { "DY", Imp },
+ { "MVW", Imp }, { "EXW", Imp }, { "MVB", Imp }, { "EXB", Imp },
+ { "ADN", Imp }, { "SBN", Imp }, { "ADW", Imp }, { "SBW", Imp },
+
+ { "LIDP", ImmW}, { "LIDL", Imm }, { "LIP", Imm }, { "LIQ", Imm },
+ { "ADB", Imp }, { "SBB", Imp }, { "LIDP", ImmW}, { "LIDL", Imm },
+ { "MVWD", Imp }, { "EXWD", Imp }, { "MVBD", Imp }, { "EXBD", Imp },
+ { "SRW", Imp }, { "SLW", Imp }, { "FILM", Imp }, { "FILD", Imp },
+
+ { "LDP", Imp }, { "LPQ", Imp }, { "LPR", Imp }, { 0, Ill },
+ { "IXL", Imp }, { "DXL", Imp }, { "IYS", Imp }, { "DYS", Imp },
+ { "JRNZP", RelP}, { "JRNZM", RelM}, { "JRNCP", RelP}, { "JRNCM", RelM},
+ { "JRP", RelP}, { "JRM", RelM}, { 0, Ill }, { "LOOP", RelM},
+
+ { "STP", Imp }, { "STQ", Imp }, { "STR", Imp }, { 0, Ill },
+ { "PUSH", Imp }, { "DATA", Imp }, { 0, Ill }, { "RTN", Imp },
+ { "JRZP", RelP}, { "JRZM", RelM}, { "JRCP", RelP}, { "JRCM", RelM},
+ { 0, Ill }, { 0, Ill }, { 0, Ill }, { 0, Ill },
+
+ { "INCI", Imp }, { "DECI", Imp }, { "INCA", Imp }, { "DECA", Imp },
+ { "ADM", Imp }, { "SBM", Imp }, { "ANMA", Imp }, { "ORMA", Imp },
+ { "INCK", Imp }, { "DECK", Imp }, { "INCV", Imp }, { "DECV", Imp },
+ { "INA", Imp }, { "NOPW", Imp }, { "WAIT", Imm }, { "IPXL"/*CDN, lxn*/, Imp },
+
+ { "INCP", Imp }, { "DECP", Imp }, { "STD", Imp }, { "MVDM", Imp },
+ { "READM",/*mvmp*/ Imp }, { "MVMD", Imp }, { "READ"/*ldpc*/, Imp }, { "LDD", Imp },
+ { "SWP", Imp }, { "LDM", Imp }, { "SL", Imp }, { "POP", Imp },
+ { 0, Ill }, { "OUTA", Imp }, { 0, Ill }, { "OUTF", Imp },
+
+ { "ANIM", Imm }, { "ORIM", Imm }, { "TSIM", Imm }, { "CPIM", Imm },
+ { "ANIA", Imm }, { "ORIA", Imm }, { "TSIA", Imm }, { "CPIA", Imm },
+ { 0, Ill }, { "ETC", Etc }, { 0, Ill }, { "TEST", Imm },
+ { 0, Ill }, { 0, Ill }, { 0, Ill }, { "IPXH"/*CDN,lxp*/, Imp },
+
+ { "ADIM", Imm }, { "SBIM", Imm }, { 0, Ill }, { 0, Ill },
+ { "ADIA", Imm }, { "SBIA", Imm }, { 0, Ill }, { 0, Ill },
+ { "CALL", Abs }, { "JP", Abs }, { "PTC", Ptc }, { 0, Ill },
+ { "JPNZ", Abs }, { "JPNC", Abs }, { "JPZ", Abs }, { "JPC", Abs },
+
+
+ { "LP", Lp }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { "INCJ", Imp }, { "DECJ", Imp }, { "INCB", Imp }, { "DECB", Imp },
+ { "ACDM", Imp }, { "SBCM", Imp }, { 0, Ill }, { "CPMA", Imp },
+ { "INCL", Imp }, { "DECL", Imp }, { "INCW", Imp }, { "DECW", Imp },
+ { "INB", Imp }, { 0, Ill }, { "NOPT", Imp }, { 0, Ill },
+
+ { "SC", Imp }, { "RC", Imp }, { "SR", Imp }, { 0, Ill },
+ { "ANID", Imm }, { "ORID", Imm }, { "TSID", Imm }, { 0, Ill },
+ { "LEAVE", Imp }, { 0, Ill }, { "EXAB", Imp }, { "EXAM", Imp },
+ { 0, Ill }, { "OUTB", Imp }, { 0, Ill }, { "OUTC", Imp },
+
+ { "CAL", Imp }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+};
+
+unsigned sc61860_dasm(char *dst, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ const UINT8 *base_oprom = oprom;
+ int oper=*(oprom++);
+ int t;
+ UINT16 adr;
+
+ switch(oper&0xc0) {
+ case 0x80:
+ sprintf(dst,"%-6s%.2x",table[oper&0x80].mnemonic, oper&0x3f);
+ break;
+ default:
+ switch(oper&0xe0) {
+ case 0xe0:
+ sprintf(dst,"%-6s%.4x",table[oper&0xe0].mnemonic,
+ *(oprom++)|((oper&0x1f)<<8));
+ break;
+ default:
+ switch (table[oper].adr) {
+ case Ill: sprintf(dst,"?%.2x",oper);break;
+ case Imp: sprintf(dst,"%s",table[oper].mnemonic); break;
+ case Imm: sprintf(dst,"%-6s%.2x",table[oper].mnemonic, *(oprom++)); break;
+ case ImmW:
+ adr=(oprom[0]<<8)|oprom[1];oprom+=2;
+ sprintf(dst,"%-6s%.4x",table[oper].mnemonic, adr);
+ break;
+ case Abs:
+ adr=(oprom[0]<<8)|oprom[1];oprom+=2;
+ sprintf(dst,"%-6s%.4x",table[oper].mnemonic, adr);
+ break;
+ case RelM:
+ adr=pc-*(oprom++);
+ sprintf(dst,"%-6s%.4x",table[oper].mnemonic, adr&0xffff);
+ break;
+ case RelP:
+ adr=pc+*(oprom++);
+ sprintf(dst,"%-6s%.4x",table[oper].mnemonic, adr&0xffff);
+ break;
+ case Ptc:
+ t=*(oprom++);
+ adr=(oprom[0]<<8)|oprom[1];oprom+=2;
+ sprintf(dst,"%-6s%.2x,%.4x",table[oper].mnemonic,t, adr);
+ break;
+ case Etc:
+ sprintf(dst,"%-6s",table[oper].mnemonic);
+ /*H imm, abs */
+ /* abs */
+ break;
+ case Cal: case Lp: break;
+ }
+ break;
+ }
+ break;
+ }
+ return oprom - base_oprom;
+}
diff --git a/src/emu/cpu/sc61860/scops.c b/src/emu/cpu/sc61860/scops.c
new file mode 100644
index 00000000000..889dd56f6f6
--- /dev/null
+++ b/src/emu/cpu/sc61860/scops.c
@@ -0,0 +1,734 @@
+/*****************************************************************************
+ *
+ * scops.c
+ * portable sharp 61860 emulator interface
+ * (sharp pocket computers)
+ *
+ * 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.
+ *
+ * History of changes:
+ * 21.07.2001 Several changes listed below were made by Mario Konegger
+ * (konegger@itp.tu-graz.ac.at)
+ * replaced buggy BCD-commands add_bcd, sub_bcd, add_bcd_a,
+ * sub_bcd_a and changed out_c, to implement HLT-mode of the CPU.
+ *
+ *****************************************************************************/
+
+INLINE UINT8 READ_OP(void)
+{
+ return cpu_readop(sc61860.pc++);
+}
+
+INLINE UINT8 READ_OP_ARG(void)
+{
+ return cpu_readop_arg(sc61860.pc++);
+}
+
+INLINE UINT16 READ_OP_ARG_WORD(void)
+{
+ UINT16 t=cpu_readop(sc61860.pc++)<<8;
+ t|=cpu_readop(sc61860.pc++);
+ return t;
+}
+
+INLINE UINT8 READ_BYTE(UINT16 adr)
+{
+ return program_read_byte(adr);
+}
+
+INLINE void WRITE_BYTE(UINT16 a,UINT8 v)
+{
+ program_write_byte(a,v);
+}
+
+#define PUSH(v) sc61860.ram[--sc61860.r]=v
+#define POP() sc61860.ram[sc61860.r++]
+
+INLINE void sc61860_load_imm(int r, UINT8 v)
+{
+ sc61860.ram[r]=v;
+}
+
+INLINE void sc61860_load(void)
+{
+ sc61860.ram[A]=sc61860.ram[sc61860.p];
+}
+
+INLINE void sc61860_load_imm_p(UINT8 v)
+{
+ sc61860.p=v&0x7f;
+}
+
+INLINE void sc61860_load_imm_q(UINT8 v)
+{
+ sc61860.q=v&0x7f;
+}
+
+INLINE void sc61860_load_r(void)
+{
+ sc61860.r=sc61860.ram[A]&0x7f;
+}
+
+INLINE void sc61860_load_ext(int r)
+{
+ sc61860.ram[r]=READ_BYTE(sc61860.dp);
+}
+
+INLINE void sc61860_load_dp(void)
+{
+ sc61860.dp=READ_OP_ARG_WORD();
+}
+
+INLINE void sc61860_load_dl(void)
+{
+ sc61860.dp=(sc61860.dp&~0xff)|READ_OP_ARG();
+}
+
+INLINE void sc61860_store_p(void)
+{
+ sc61860.ram[A]=sc61860.p;
+}
+
+INLINE void sc61860_store_q(void)
+{
+ sc61860.ram[A]=sc61860.q;
+}
+
+INLINE void sc61860_store_r(void)
+{
+ sc61860.ram[A]=sc61860.r;
+}
+
+INLINE void sc61860_store_ext(int r)
+{
+ WRITE_BYTE(sc61860.dp, sc61860.ram[r]);
+}
+
+INLINE void sc61860_exam(int a, int b)
+{
+ UINT8 t=sc61860.ram[a];
+ sc61860.ram[a]=sc61860.ram[b];
+ sc61860.ram[b]=t;
+}
+
+INLINE void sc61860_test(int reg, UINT8 value)
+{
+ sc61860.zero=(sc61860.ram[reg]&value)==0;
+}
+
+INLINE void sc61860_test_ext(void)
+{
+ sc61860.zero=(READ_BYTE(sc61860.dp)&READ_OP_ARG())==0;
+}
+
+INLINE void sc61860_and(int reg, UINT8 value)
+{
+ sc61860.zero=(sc61860.ram[reg]&=value)==0;
+}
+
+INLINE void sc61860_and_ext(void)
+{
+ UINT8 t=READ_BYTE(sc61860.dp)&READ_OP_ARG();
+ sc61860.zero=t==0;
+ WRITE_BYTE(sc61860.dp,t);
+}
+
+INLINE void sc61860_or(int reg, UINT8 value)
+{
+ sc61860.zero=(sc61860.ram[reg]|=value)==0;
+}
+
+INLINE void sc61860_or_ext(void)
+{
+ UINT8 t=READ_BYTE(sc61860.dp)|READ_OP_ARG();
+ sc61860.zero=t==0;
+ WRITE_BYTE(sc61860.dp,t);
+}
+
+INLINE void sc61860_rotate_right(void)
+{
+ int t=sc61860.ram[A];
+ if (sc61860.carry) t|=0x100;
+ sc61860.carry=t&1;
+ sc61860.ram[A]=t>>1;
+}
+
+INLINE void sc61860_rotate_left(void)
+{
+ int t=sc61860.ram[A]<<1;
+ if (sc61860.carry) t|=1;
+ sc61860.carry=t&0x100;
+ sc61860.ram[A]=t;
+}
+
+INLINE void sc61860_swap(void)
+{
+ int t=sc61860.ram[A];
+ sc61860.ram[A]=(t<<4)|((t>>4)&0xf);
+}
+
+// q=reg sideeffect
+INLINE void sc61860_inc(int reg)
+{
+ sc61860.q=reg;
+ sc61860.ram[reg]++;
+ sc61860.zero=sc61860.carry=sc61860.ram[reg]==0;
+}
+
+INLINE void sc61860_inc_p(void)
+{
+ sc61860.p++;
+}
+
+// q=reg sideeffect
+INLINE void sc61860_dec(int reg)
+{
+ sc61860.q=reg;
+ sc61860.ram[reg]--;
+ sc61860.zero=sc61860.ram[reg]==0;
+ sc61860.carry=sc61860.ram[reg]==0xff;
+}
+
+INLINE void sc61860_dec_p(void)
+{
+ sc61860.p--;
+}
+
+INLINE void sc61860_add(int reg, UINT8 value)
+{
+ int t=sc61860.ram[reg]+value;
+ sc61860.zero=(sc61860.ram[reg]=t)==0;
+ sc61860.carry=t>=0x100;
+}
+
+INLINE void sc61860_add_carry(void)
+{
+ int t=sc61860.ram[sc61860.p]+sc61860.ram[A];
+ if (sc61860.carry) t++;
+ sc61860.zero=(sc61860.ram[sc61860.p]=t)==0;
+ sc61860.carry=t>=0x100;
+}
+
+// p++ sideeffect
+INLINE void sc61860_add_word(void)
+{
+ int t=sc61860.ram[sc61860.p]+sc61860.ram[A],t2;
+ sc61860.ram[sc61860.p]=t;
+ sc61860.p++;
+ t2=sc61860.ram[sc61860.p]+sc61860.ram[B];
+ if (t>=0x100) t2++;
+ sc61860.ram[sc61860.p]=t2;
+ sc61860.zero=(t2&0xff)==0 &&(t&0xff)==0;
+ sc61860.carry=t2>=0x100;
+}
+
+
+INLINE void sc61860_sub(int reg, UINT8 value)
+{
+ int t=sc61860.ram[reg]-value;
+ sc61860.zero=(sc61860.ram[reg]=t)==0;
+ sc61860.carry=t<0;
+}
+
+INLINE void sc61860_sub_carry(void)
+{
+ int t=sc61860.ram[sc61860.p]-sc61860.ram[A];
+ if (sc61860.carry) t--;
+ sc61860.zero=(sc61860.ram[sc61860.p]=t)==0;
+ sc61860.carry=t<0;
+}
+
+
+// p++ sideeffect
+INLINE void sc61860_sub_word(void)
+{
+ int t=sc61860.ram[sc61860.p]-sc61860.ram[A],t2;
+ sc61860.ram[sc61860.p]=t;
+ sc61860.p++;
+ t2=sc61860.ram[sc61860.p]-sc61860.ram[B];
+ if (t<0) t2--;
+ sc61860.ram[sc61860.p]=t2;
+ sc61860.zero=(t2&0xff)==0 && (t&0xff)==0;
+ sc61860.carry=t2<0;
+}
+
+INLINE void sc61860_cmp(int reg, UINT8 value)
+{
+ int t=sc61860.ram[reg]-value;
+ sc61860.zero=t==0;
+ sc61860.carry=t<0;
+}
+
+INLINE void sc61860_pop(void)
+{
+ sc61860.ram[A]=POP();
+}
+
+INLINE void sc61860_push(void)
+{
+ PUSH(sc61860.ram[A]);
+}
+
+INLINE void sc61860_prepare_table_call(void)
+{
+ int adr;
+ sc61860.h=READ_OP();
+ adr=READ_OP_ARG_WORD();
+ PUSH(adr>>8);
+ PUSH(adr&0xff);
+}
+
+INLINE void sc61860_execute_table_call(void)
+{
+ int i, v, adr;
+ for (i=0; i<sc61860.h; i++) {
+ v=READ_OP();
+ adr=READ_OP_ARG_WORD();
+ sc61860.zero=v==sc61860.ram[A];
+ if (sc61860.zero) {
+ sc61860.pc=adr;
+ change_pc(sc61860.pc);
+ return;
+ }
+ }
+ sc61860.pc=READ_OP_ARG_WORD();
+ change_pc(sc61860.pc);
+}
+
+
+INLINE void sc61860_call(UINT16 adr)
+{
+ PUSH(sc61860.pc>>8);
+ PUSH(sc61860.pc&0xff);
+ sc61860.pc=adr;
+ change_pc(sc61860.pc);
+}
+
+INLINE void sc61860_return(void)
+{
+ UINT16 t=POP();
+ t|=POP()<<8;
+ sc61860.pc=t;
+ change_pc(sc61860.pc);
+}
+
+INLINE void sc61860_jump(int yes)
+{
+ UINT16 adr=READ_OP_ARG_WORD();
+ if (yes) {
+ sc61860.pc=adr;
+ change_pc(sc61860.pc);
+ }
+}
+
+INLINE void sc61860_jump_rel_plus(int yes)
+{
+ UINT16 adr=sc61860.pc;
+ adr+=READ_OP_ARG();
+ if (yes) {
+ sc61860.pc=adr;
+ change_pc(sc61860.pc);
+ sc61860_ICount-=3;
+ }
+}
+
+INLINE void sc61860_jump_rel_minus(int yes)
+{
+ UINT16 adr=sc61860.pc;
+ adr-=READ_OP_ARG();
+ if (yes) {
+ sc61860.pc=adr;
+ change_pc(sc61860.pc);
+ sc61860_ICount-=3;
+ }
+}
+
+INLINE void sc61860_loop(void)
+{
+ UINT16 adr=sc61860.pc;
+ adr-=READ_OP_ARG();
+ sc61860.ram[sc61860.r]--;
+ sc61860.zero=sc61860.ram[sc61860.r]==0;
+ sc61860.carry=sc61860.ram[sc61860.r]==0xff;
+ if (!sc61860.carry) {
+ sc61860.pc=adr;
+ adr=POP();
+ change_pc(sc61860.pc);
+ sc61860_ICount-=3;
+ }
+}
+
+INLINE void sc61860_leave(void)
+{
+ sc61860.ram[sc61860.r]=0;
+}
+
+INLINE void sc61860_wait(void)
+{
+ int t=READ_OP();
+ sc61860_ICount-=t;
+ sc61860_ICount-=t;
+ sc61860_ICount-=3;
+}
+
+INLINE void sc61860_set_carry(void)
+{
+ sc61860.carry=1;
+ sc61860.zero=1;
+}
+
+INLINE void sc61860_reset_carry(void)
+{
+ sc61860.carry=0;
+ sc61860.zero=1;
+}
+
+INLINE void sc61860_out_a(void)
+{
+ sc61860.q=IA;
+ if (sc61860.config&&sc61860.config->outa)
+ sc61860.config->outa(sc61860.ram[IA]);
+}
+
+INLINE void sc61860_out_b(void)
+{
+ sc61860.q=IB;
+ if (sc61860.config&&sc61860.config->outb)
+ sc61860.config->outb(sc61860.ram[IB]);
+}
+
+INLINE void sc61860_out_f(void)
+{
+ sc61860.q=F0;
+ /*sc61860.ram[F0]; */
+}
+
+
+/* c0 display on
+ c1 counter reset
+ c2 cpu halt
+ c3 computer off
+ c4 beeper frequency (1 4khz, 0 2khz), or (c5=0) membran pos1/pos2
+ c5 beeper on
+ c6 beeper steuerung*/
+INLINE void sc61860_out_c(void)
+{
+ sc61860.q=C;
+ if (sc61860.config&&sc61860.config->outc)
+ sc61860.config->outc(sc61860.ram[C]);
+ sc61860.c=sc61860.ram[C];
+}
+
+INLINE void sc61860_in_a(void)
+{
+ int data=0;
+ if (sc61860.config&&sc61860.config->ina) data=sc61860.config->ina();
+ sc61860.ram[A]=data;
+ sc61860.zero=data==0;
+}
+
+INLINE void sc61860_in_b(void)
+{
+ int data=0;
+ if (sc61860.config&&sc61860.config->inb) data=sc61860.config->inb();
+ sc61860.ram[A]=data;
+ sc61860.zero=data==0;
+}
+
+/* 0 systemclock 512ms
+ 1 systemclock 2ms
+ 2 ?
+ 3 brk/on key
+ 4 ?
+ 5 ?
+ 6 reset
+ 7 cassette input */
+INLINE void sc61860_test_special(void)
+{
+ int t=0;
+ if (sc61860.timer.t512ms) t|=1;
+ if (sc61860.timer.t2ms) t|=2;
+ if (sc61860.config&&sc61860.config->brk&&sc61860.config->brk()) t|=8;
+ if (sc61860.config&&sc61860.config->reset&&sc61860.config->reset()) t|=0x40;
+ if (sc61860.config&&sc61860.config->x&&sc61860.config->x()) t|=0x80;
+
+ sc61860.zero=(t&READ_OP())==0;
+}
+
+/************************************************************************************
+ "string" operations
+***********************************************************************************/
+
+// p-=I+1 sideeffect
+INLINE void sc61860_add_bcd_a(void)
+{
+ UINT8 help = sc61860.ram[A];
+ int i, hlp, hlp1 = 0; sc61860.zero=1;
+ for ( i=0; i <= sc61860.ram[I]; i++)
+ {
+ hlp1 = (sc61860.ram[sc61860.p] & 0x0f) + (help & 0x0f ) + hlp1;
+ if (hlp1 > 9) { hlp = hlp1 - 0x0a; hlp1 = 0x10; }
+ else {hlp = hlp1; hlp1 = 0x00;}
+ hlp1 = (sc61860.ram[sc61860.p] & 0xf0) + (help & 0xf0) + hlp1;
+ if (hlp1 > 0x90) { sc61860.ram[sc61860.p] = hlp1 - 0xa0 + hlp; hlp1 = 1; }
+ else {sc61860.ram[sc61860.p] = hlp1 + hlp; hlp1 = 0;}
+ if ( sc61860.ram[sc61860.p--] != 0 ) sc61860.zero = 0;
+ help = 0;
+ }
+ sc61860.carry= ( hlp1 ) ? 1 : 0;
+ sc61860_ICount-=3*(sc61860.ram[I]+1);
+}
+
+
+// p-=I+1, q-=I+2 sideeffect
+INLINE void sc61860_add_bcd(void)
+{
+ int i, hlp, hlp1 = 0; sc61860.zero=1;
+ for ( i=0; i <= sc61860.ram[I]; i++)
+ {
+ hlp1 = (sc61860.ram[sc61860.p] & 0x0f) + (sc61860.ram[sc61860.q] & 0x0f ) +
+hlp1;
+ if (hlp1 > 9) { hlp = hlp1 - 0x0a; hlp1 = 0x10; }
+ else {hlp = hlp1; hlp1 = 0x00;}
+ hlp1 = (sc61860.ram[sc61860.p] & 0xf0) + (sc61860.ram[sc61860.q--] & 0xf0) +
+hlp1;
+ if (hlp1 > 0x90) { sc61860.ram[sc61860.p] = hlp1 - 0xa0 + hlp; hlp1 = 1; }
+ else {sc61860.ram[sc61860.p] = hlp1 + hlp; hlp1 = 0;}
+ if ( sc61860.ram[sc61860.p--] != 0 ) sc61860.zero = 0;
+ }
+ sc61860.carry= ( hlp1 ) ? 1 : 0;
+ sc61860_ICount-=3*(sc61860.ram[I]+1);
+ sc61860.q--;
+}
+
+
+// p-=I+1 sideeffect
+INLINE void sc61860_sub_bcd_a(void)
+{
+ UINT8 help = sc61860.ram[A];
+ int i, hlp, hlp1 = 0; sc61860.zero=1;
+ for ( i=0; i <= sc61860.ram[I]; i++)
+ {
+ hlp1 = (sc61860.ram[sc61860.p]&0x0f) - (help&0x0f) - hlp1;
+ if ( hlp1 < 0 ) { hlp = hlp1 + 0x0a; hlp1 = 0x10;}
+ else { hlp = hlp1; hlp1 = 0x00;}
+ hlp1 = (sc61860.ram[sc61860.p]&0xf0) - (help&0xf0) - hlp1;
+ if ( hlp1 < 0 ) { sc61860.ram[sc61860.p] = hlp1 + 0xa0 + hlp; hlp1 = 1;}
+ else {sc61860.ram[sc61860.p] = hlp1 + hlp; hlp1 = 0;}
+ if ( sc61860.ram[sc61860.p--] != 0 ) sc61860.zero = 0;
+ help = 0;
+ }
+ sc61860.carry= ( hlp1 ) ? 1 : 0;
+ sc61860_ICount-=3*(sc61860.ram[I]+1);
+}
+
+
+// p-=I+1, q-=I+2 sideeffect
+INLINE void sc61860_sub_bcd(void)
+{
+ int i, hlp, hlp1 = 0; sc61860.zero=1;
+ for ( i=0; i <= sc61860.ram[I]; i++)
+ {
+ hlp1 = (sc61860.ram[sc61860.p]&0x0f) - (sc61860.ram[sc61860.q]&0x0f) - hlp1;
+ if ( hlp1 < 0 ) { hlp = hlp1 + 0x0a; hlp1 = 0x10;}
+ else { hlp = hlp1; hlp1 = 0x00;}
+ hlp1 = (sc61860.ram[sc61860.p]&0xf0) - (sc61860.ram[sc61860.q--]&0xf0) -
+hlp1;
+ if ( hlp1 < 0 ) { sc61860.ram[sc61860.p] = hlp1 + 0xa0 + hlp; hlp1 = 1;}
+ else {sc61860.ram[sc61860.p] = hlp1 + hlp; hlp1 = 0;}
+ if ( sc61860.ram[sc61860.p--] != 0 ) sc61860.zero = 0;
+ }
+ sc61860.carry= ( hlp1 ) ? 1 : 0;
+ sc61860_ICount-=3*(sc61860.ram[I]+1);
+ sc61860.q--;
+}
+
+/* side effect p-i-1 -> p correct! */
+INLINE void sc61860_shift_left_nibble(void)
+{
+ int i,t=0;
+ for (i=0; i<=sc61860.ram[I]; i++) {
+ t|=sc61860.ram[sc61860.p]<<4;
+ sc61860.ram[sc61860.p--]=t;
+ t>>=8;
+ sc61860_ICount--;
+ }
+}
+
+/* side effect p+i+1 -> p correct! */
+INLINE void sc61860_shift_right_nibble(void)
+{
+ int i,t=0;
+ for (i=0; i<=sc61860.ram[I]; i++) {
+ t|=sc61860.ram[sc61860.p];
+ sc61860.ram[sc61860.p++]=t>>4;
+ t=(t<<8)&0xf00;
+ sc61860_ICount--;
+ }
+}
+
+// q=reg+1 sideeffect
+INLINE void sc61860_inc_load_dp(int reg)
+{
+ if (++sc61860.ram[reg]==0) sc61860.ram[reg+1]++;
+ sc61860.dp=sc61860.ram[reg]|(sc61860.ram[reg+1]<<8);
+ sc61860.q=reg+1;
+}
+
+// q=reg+1 sideeffect
+INLINE void sc61860_dec_load_dp(int reg)
+{
+ if (--sc61860.ram[reg]==0xff) sc61860.ram[reg+1]--;
+ sc61860.dp=sc61860.ram[reg]|(sc61860.ram[reg+1]<<8);
+ sc61860.q=reg+1;
+}
+
+// q=XH sideeffect
+INLINE void sc61860_inc_load_dp_load(void)
+{
+ if (++sc61860.ram[XL]==0) sc61860.ram[XH]++;
+ sc61860.dp=sc61860.ram[XL]|(sc61860.ram[XH]<<8);
+ sc61860.q=XH; // hopefully correct before real read
+ sc61860.ram[A]=READ_BYTE(sc61860.dp);
+}
+
+// q=XH sideeffect
+INLINE void sc61860_dec_load_dp_load(void)
+{
+ if (--sc61860.ram[XL]==0xff) sc61860.ram[XH]--;
+ sc61860.dp=sc61860.ram[XL]|(sc61860.ram[XH]<<8);
+ sc61860.q=XH; // hopefully correct before real read
+ sc61860.ram[A]=READ_BYTE(sc61860.dp);
+}
+
+// q=YH sideeffect
+INLINE void sc61860_inc_load_dp_store(void)
+{
+ if (++sc61860.ram[YL]==0) sc61860.ram[YH]++;
+ sc61860.dp=sc61860.ram[YL]|(sc61860.ram[YH]<<8);
+ sc61860.q=YH; // hopefully correct before real write!
+ WRITE_BYTE(sc61860.dp,sc61860.ram[A]);
+}
+
+// q=YH sideeffect
+INLINE void sc61860_dec_load_dp_store(void)
+{
+ if (--sc61860.ram[YL]==0xff) sc61860.ram[YH]--;
+ sc61860.dp=sc61860.ram[YL]|(sc61860.ram[YH]<<8);
+ sc61860.q=XH; // hopefully correct before real write!
+ WRITE_BYTE(sc61860.dp,sc61860.ram[A]);
+}
+
+INLINE void sc61860_fill(void)
+{
+ int i;
+ for (i=0;i<=sc61860.ram[I];i++) {
+ sc61860.ram[sc61860.p++]=sc61860.ram[A]; /* could be overwritten? */
+ sc61860_ICount--;
+ }
+}
+
+INLINE void sc61860_fill_ext(void)
+{
+ int i;
+ for (i=0;i<=sc61860.ram[I];i++) {
+ WRITE_BYTE(sc61860.dp, sc61860.ram[A]);
+ if (i!=sc61860.ram[I]) sc61860.dp++;
+ sc61860_ICount-=3;
+ }
+}
+
+// p+=count+1, q+=count+1 sideeffects
+INLINE void sc61860_copy(int count)
+{
+ int i;
+ for (i=0; i<=count; i++) {
+ sc61860.ram[sc61860.p++]=sc61860.ram[sc61860.q++];
+ sc61860_ICount-=2;
+ }
+
+}
+
+// p+=count+1, dp+=count sideeffects
+INLINE void sc61860_copy_ext(int count)
+{
+ int i;
+ for (i=0; i<=count; i++) {
+ sc61860.ram[sc61860.p++]=READ_BYTE(sc61860.dp);
+ if (i!=count) sc61860.dp++;
+ sc61860_ICount-=4;
+ }
+}
+
+INLINE void sc61860_copy_int(int count)
+{
+ int i;
+ for (i=0; i<=count; i++) {
+ sc61860.ram[sc61860.p++]=
+ READ_BYTE((sc61860.ram[A]|(sc61860.ram[B]<<8)) ); /* internal rom! */
+ if (i!=count) {
+ if (++sc61860.ram[A]==0) sc61860.ram[B]++;
+ }
+ sc61860_ICount-=4;
+ }
+}
+
+INLINE void sc61860_exchange(int count)
+{
+ int i;
+ UINT8 t;
+ for (i=0; i<=count; i++) {
+ t=sc61860.ram[sc61860.p];
+ sc61860.ram[sc61860.p++]=sc61860.ram[sc61860.q];
+ sc61860.ram[sc61860.q++]=t;
+ sc61860_ICount-=3;
+ }
+}
+
+INLINE void sc61860_exchange_ext(int count)
+{
+ int i;
+ UINT8 t;
+ for (i=0; i<=count; i++) {
+ t=sc61860.ram[sc61860.p];
+ sc61860.ram[sc61860.p++]=READ_BYTE(sc61860.dp);
+ WRITE_BYTE(sc61860.dp, t);
+ if (i!=count) sc61860.dp++;
+ sc61860_ICount-=6;
+ }
+}
+
+// undocumented
+// only 1 opcode working in pc1403
+// both opcodes working in pc1350
+INLINE void sc61860_wait_x(int level)
+{
+ int c;
+ sc61860.zero=level;
+
+ if (sc61860.config&&sc61860.config->x) {
+ for (c=sc61860.ram[I]; c>=0; c--) {
+// sc61860.ram[sc61860.p]=(sc61860.ram[sc61860.p]+1)%0x60;
+ sc61860.ram[sc61860.p]=(sc61860.ram[sc61860.p]+1)&0x7f;
+ sc61860.zero=sc61860.config->x();
+ sc61860_ICount-=4;
+ if ( level != sc61860.zero) break;
+ }
+ }
+}
+
+
+
+
diff --git a/src/emu/cpu/sc61860/sctable.c b/src/emu/cpu/sc61860/sctable.c
new file mode 100644
index 00000000000..38d42bc168c
--- /dev/null
+++ b/src/emu/cpu/sc61860/sctable.c
@@ -0,0 +1,144 @@
+
+static void sc61860_instruction(void)
+{
+ int oper=READ_OP();
+ if ((oper&0xc0)==0x80) {
+ sc61860_load_imm_p(oper&0x3f);sc61860_ICount-=2;
+ } else if ((oper&0xe0)==0xe0) {
+ sc61860_call(READ_OP()|((oper&0x1f)<<8));sc61860_ICount-=7;
+ } else {
+ switch(oper) {
+ case 0: sc61860_load_imm(I, READ_OP());sc61860_ICount-=4;break;
+ case 1: sc61860_load_imm(J, READ_OP());sc61860_ICount-=4;break;
+ case 2: sc61860_load_imm(A, READ_OP());sc61860_ICount-=4;break;
+ case 3: sc61860_load_imm(B, READ_OP());sc61860_ICount-=4;break;
+ case 4: sc61860_inc_load_dp(XL);sc61860_ICount-=6;break;
+ case 5: sc61860_dec_load_dp(XL);sc61860_ICount-=6;break;
+ case 6: sc61860_inc_load_dp(YL);sc61860_ICount-=6;break;
+ case 7: sc61860_dec_load_dp(YL);sc61860_ICount-=6;break;
+ case 8: sc61860_copy(sc61860.ram[I]);break;
+ case 9: sc61860_exchange(sc61860.ram[I]);break;
+ case 10: sc61860_copy(sc61860.ram[J]);break;
+ case 11: sc61860_exchange(sc61860.ram[J]);break;
+ case 12: sc61860_add_bcd_a();sc61860_ICount-=7;break;
+ case 13: sc61860_sub_bcd_a();sc61860_ICount-=7;break;
+ case 14: sc61860_add_bcd();sc61860_ICount-=7;break;
+ case 15: sc61860_sub_bcd();sc61860_ICount-=7;break;
+ case 16: sc61860_load_dp();sc61860_ICount-=8;break;
+ case 17: sc61860_load_dl();sc61860_ICount-=5;break;
+ case 18: sc61860_load_imm_p(READ_OP());sc61860_ICount-=4;break;
+ case 19: sc61860_load_imm_q(READ_OP());sc61860_ICount-=4;break;
+ case 20: sc61860_add_word();sc61860_ICount-=5;break;
+ case 21: sc61860_sub_word();sc61860_ICount-=5;break;
+ case 24: sc61860_copy_ext(sc61860.ram[I]);break;
+ case 25: sc61860_exchange_ext(sc61860.ram[I]);break;
+ case 26: sc61860_copy_ext(sc61860.ram[J]);break;
+ case 27: sc61860_exchange_ext(sc61860.ram[J]);break;
+ case 28: sc61860_shift_right_nibble();sc61860_ICount-=5;break;
+ case 29: sc61860_shift_left_nibble();sc61860_ICount-=5;break;
+ case 30: sc61860_fill();sc61860_ICount-=5;break;
+ case 31: sc61860_fill_ext();sc61860_ICount-=4;break;
+ case 32: sc61860_store_p();sc61860_ICount-=2;break;
+ case 33: sc61860_store_q();sc61860_ICount-=2;break;
+ case 34: sc61860_store_r();sc61860_ICount-=2;break;
+ case 36: sc61860_inc_load_dp_load();sc61860_ICount-=7;break;
+ case 37: sc61860_dec_load_dp_load();sc61860_ICount-=7;break;
+ case 38: sc61860_inc_load_dp_store();sc61860_ICount-=7;break;
+ case 39: sc61860_dec_load_dp_store();sc61860_ICount-=7;break;
+ case 40: sc61860_jump_rel_plus(!sc61860.zero);sc61860_ICount-=4;break;
+ case 41: sc61860_jump_rel_minus(!sc61860.zero);sc61860_ICount-=4;break;
+ case 42: sc61860_jump_rel_plus(!sc61860.carry);sc61860_ICount-=4;break;
+ case 43: sc61860_jump_rel_minus(!sc61860.carry);sc61860_ICount-=4;break;
+ case 44: sc61860_jump_rel_plus(TRUE);sc61860_ICount-=4;break;
+ case 45: sc61860_jump_rel_minus(TRUE);sc61860_ICount-=4;break;
+ case 47: sc61860_loop();sc61860_ICount-=7;break;
+ case 48: sc61860_load_imm_p(sc61860.ram[A]);sc61860_ICount-=2;break;
+ case 49: sc61860_load_imm_q(sc61860.ram[A]);sc61860_ICount-=2;break;
+ case 50: sc61860_load_r();sc61860_ICount-=2;break;
+ case 52: sc61860_push();sc61860_ICount-=3;break;
+ case 53: sc61860_copy_int(sc61860.ram[I]);break;
+ case 55: sc61860_return();sc61860_ICount-=4;break;
+ case 56: sc61860_jump_rel_plus(sc61860.zero);sc61860_ICount-=4;break;
+ case 57: sc61860_jump_rel_minus(sc61860.zero);sc61860_ICount-=4;break;
+ case 58: sc61860_jump_rel_plus(sc61860.carry);sc61860_ICount-=4;break;
+ case 59: sc61860_jump_rel_minus(sc61860.carry);sc61860_ICount-=4;break;
+ case 64: sc61860_inc(I);sc61860_ICount-=4;break;
+ case 65: sc61860_dec(I);sc61860_ICount-=4;break;
+ case 66: sc61860_inc(A);sc61860_ICount-=4;break;
+ case 67: sc61860_dec(A);sc61860_ICount-=4;break;
+ case 68: sc61860_add(sc61860.p,sc61860.ram[A]);sc61860_ICount-=3;break;
+ case 69: sc61860_sub(sc61860.p,sc61860.ram[A]);sc61860_ICount-=3;break;
+ case 70: sc61860_and(sc61860.p,sc61860.ram[A]);sc61860_ICount-=3;break;
+ case 71: sc61860_or(sc61860.p,sc61860.ram[A]);sc61860_ICount-=3;break;
+ case 72: sc61860_inc(K);sc61860_ICount-=4;break;
+ case 73: sc61860_dec(K);sc61860_ICount-=4;break;
+ case 74: sc61860_inc(V);sc61860_ICount-=4;break;
+ case 75: sc61860_dec(V);sc61860_ICount-=4;break;
+ case 76: sc61860_in_a();sc61860_ICount-=2;break;
+ case 77: /*nopw*/;sc61860_ICount-=2;break;
+ case 78: sc61860_wait();sc61860_ICount-=6;break;
+ case 79: sc61860_wait_x(FALSE);sc61860_ICount-=1;break;
+ case 80: sc61860_inc_p();sc61860_ICount-=2;break;
+ case 81: sc61860_dec_p();sc61860_ICount-=2;break;
+ case 82: sc61860_store_ext(A);sc61860_ICount-=2;break;
+ case 83: sc61860_store_ext(sc61860.p);sc61860_ICount-=2;break;
+ case 84: sc61860_load_imm(sc61860.p, READ_OP());sc61860_ICount-=3/*?*/;break; // undocumented
+ case 85: sc61860_load_ext(sc61860.p);sc61860_ICount-=3;break;
+ case 86: sc61860_load_imm(sc61860.p, READ_OP());sc61860_ICount-=3/*?*/;break; // undocumented
+ case 87: sc61860_load_ext(A);sc61860_ICount-=3;break;
+ case 88: sc61860_swap();sc61860_ICount-=2;break;
+ case 89: sc61860_load();sc61860_ICount-=2;break;
+ case 90: sc61860_rotate_left();sc61860_ICount-=2;break;
+ case 91: sc61860_pop();sc61860_ICount-=2;break;
+ case 93: sc61860_out_a();sc61860_ICount-=3;break;
+ case 95: sc61860_out_f();sc61860_ICount-=3;break;
+ case 96: sc61860_and(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 97: sc61860_or(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 98: sc61860_test(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 99: sc61860_cmp(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 100: sc61860_and(A,READ_OP());sc61860_ICount-=4;break;
+ case 101: sc61860_or(A,READ_OP());sc61860_ICount-=4;break;
+ case 102: sc61860_test(A,READ_OP());sc61860_ICount-=4;break;
+ case 103: sc61860_cmp(A,READ_OP());sc61860_ICount-=4;break;
+ case 105: sc61860_execute_table_call();sc61860_ICount-=3;break;
+ case 107: sc61860_test_special();sc61860_ICount-=4;break;
+ case 111: sc61860_wait_x(TRUE);sc61860_ICount-=1;break;
+ case 112: sc61860_add(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 113: sc61860_sub(sc61860.p,READ_OP());sc61860_ICount-=4;break;
+ case 116: sc61860_add(A,READ_OP());sc61860_ICount-=4;break;
+ case 117: sc61860_sub(A,READ_OP());sc61860_ICount-=4;break;
+ case 120: sc61860_call(READ_OP_ARG_WORD());sc61860_ICount-=8;break;
+ case 121: sc61860_jump(1);sc61860_ICount-=6;break;
+ case 122: sc61860_prepare_table_call();sc61860_ICount-=9;break;
+ case 124: sc61860_jump(!sc61860.zero);sc61860_ICount-=6;break;
+ case 125: sc61860_jump(!sc61860.carry);sc61860_ICount-=6;break;
+ case 126: sc61860_jump(sc61860.zero);sc61860_ICount-=6;break;
+ case 127: sc61860_jump(sc61860.carry);sc61860_ICount-=6;break;
+ case 192: sc61860_inc(J);sc61860_ICount-=4;break;
+ case 193: sc61860_dec(J);sc61860_ICount-=4;break;
+ case 194: sc61860_inc(B);sc61860_ICount-=4;break;
+ case 195: sc61860_dec(B);sc61860_ICount-=4;break;
+ case 196: sc61860_add_carry();sc61860_ICount-=3;break;
+ case 197: sc61860_sub_carry();sc61860_ICount-=3;break;
+ case 199: sc61860_cmp(sc61860.p,sc61860.ram[A]);sc61860_ICount-=3;break;
+ case 200: sc61860_inc(L);sc61860_ICount-=4;break;
+ case 201: sc61860_dec(L);sc61860_ICount-=4;break;
+ case 202: sc61860_inc(W);sc61860_ICount-=4;break;
+ case 203: sc61860_dec(W);sc61860_ICount-=4;break;
+ case 204: sc61860_in_b();sc61860_ICount-=2;break;
+ case 206: /*nopt*/;sc61860_ICount-=3;break;
+ case 208: sc61860_set_carry();sc61860_ICount-=2;break;
+ case 209: sc61860_reset_carry();sc61860_ICount-=4;break;
+ case 210: sc61860_rotate_right();sc61860_ICount-=2;break;
+ case 212: sc61860_and_ext();sc61860_ICount-=6;break;
+ case 213: sc61860_or_ext();sc61860_ICount-=6;break;
+ case 214: sc61860_test_ext();sc61860_ICount-=6;break;
+ case 216: sc61860_leave();sc61860_ICount-=2;break;
+ case 218: sc61860_exam(A, B);sc61860_ICount-=3;break;
+ case 219: sc61860_exam(A, sc61860.p);sc61860_ICount-=3;break;
+ case 221: sc61860_out_b();sc61860_ICount-=2;break;
+ case 223: sc61860_out_c();sc61860_ICount-=2;break;
+ default: logerror("sc61860 illegal opcode at %.4x %.2x\n",sc61860.pc-1, oper);
+ }
+ }
+}