diff options
author | 2007-12-17 15:19:59 +0000 | |
---|---|---|
committer | 2007-12-17 15:19:59 +0000 | |
commit | 7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch) | |
tree | 19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/emu/cpu/sc61860 | |
parent | 3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff) |
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/emu/cpu/sc61860')
-rw-r--r-- | src/emu/cpu/sc61860/readpc.c | 195 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/sc.h | 34 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/sc61860.c | 255 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/sc61860.h | 58 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/scdasm.c | 220 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/scops.c | 734 | ||||
-rw-r--r-- | src/emu/cpu/sc61860/sctable.c | 144 |
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); + } + } +} |