diff options
Diffstat (limited to 'src/emu/cpu/alph8201')
-rw-r--r-- | src/emu/cpu/alph8201/8201dasm.c | 261 | ||||
-rw-r--r-- | src/emu/cpu/alph8201/alph8201.c | 1013 | ||||
-rw-r--r-- | src/emu/cpu/alph8201/alph8201.h | 72 |
3 files changed, 1346 insertions, 0 deletions
diff --git a/src/emu/cpu/alph8201/8201dasm.c b/src/emu/cpu/alph8201/8201dasm.c new file mode 100644 index 00000000000..4555beac533 --- /dev/null +++ b/src/emu/cpu/alph8201/8201dasm.c @@ -0,0 +1,261 @@ +/**************************************************************************** + Alpha 8201/8301 Disassembler + + Copyright (C) 2006 Tatsuyuki Satoh + Originally written for the MAME project. + +****************************************************************************/ + +#include <ctype.h> + +#include "cpuintrf.h" + +typedef unsigned char byte; + +#define FMT(a,b) a, b +#define PTRS_PER_FORMAT 2 + +static const char *Formats[] = { + FMT("0000_0000", "NOP"), // 00 + FMT("0000_0001", "RRCA"), // 01 + FMT("0000_0010", "RLCA"), // 02 + FMT("0000_0011", "INC B"), // 03 : shougi $360 to $377 + FMT("0000_0100", "DEC B"), // 04 : not found + FMT("0000_0101", "INC A"), // 05 + FMT("0000_0110", "DEC A"), // 06 + FMT("0000_0111", "CPL A"), // 07 + FMT("0000_1aaa", "LD A,(IX0+%X)"),// 08-0F + FMT("0001_0aaa", "LD A,(IX1+%X)"),// 10-17 + FMT("0001_1aaa", "LD (IX2+%X),A"),// 18-1F + FMT("0010_0xxx", "LD [IX0+%X],B"), // 20-27 : shougi $360 to $377 + FMT("0010_1xxx", "ld [ix1+%X],b ?"),// 28-2f : not found + FMT("0011_0xxx", "ld b,[ix2+%X] ?"),// 30-37 : not found + FMT("0011_1aaa", "BIT R0.%d"), // 38-3f ZF = R0.a (bit test) + FMT("0100_aaa0", "LD A,R%X"), // 40-4E + FMT("0100_aaa1", "LD R%X,A"), // 41-4F + FMT("0101_aaa0", "ADD A,R%X"), // 50-5E + FMT("0101_aaa1", "SUB A,R%X"), // 51-5F + FMT("0110_aaa0", "AND A,R%X"), // 60-6E + FMT("0110_aaa1", "OR A,R%X"), // 61-6F + FMT("0111_aaaa", "ADD IX0,$%X"), // 70-7f + FMT("1000_aaaa", "ADD IX1,$%X"), // 80-8f + FMT("1001_aaaa", "ADD IX2,$%X"), // 90-9f + FMT("1010_0aaa", "LD RB,%X"), // A0-A7 +// FMT("1010_1xxx", "unknown"), // A8-AF : not found + FMT("1011_00aa", "LD MB,%X"), // B0-B3 + FMT("1011_0100", "HALT"), // B4 +// FMT("1011_0101", "unknown"), // B5 : not found +// FMT("1011_0110", "unknown"), // B6 : not found +// FMT("1011_0111", "unknown"), // B7 : not found +// FMT("1011_1xxx", "unknown"), // B8-BF : not found + FMT("1100_0000 I", "LD IX0,$%02X"),// C0 + FMT("1100_0001 I", "LD IX1,$%02X"),// C1 + FMT("1100_0010 I", "LD IX2,$%02X"),// C2 + FMT("1100_0011 I", "LD A,$%02X"), // C3 + FMT("1100_0100 I", "LD LP0,$%02X"),// C4 + FMT("1100_0101 I", "LD LP1,$%02X"),// C5 + FMT("1000_0110 I", "LD LP2,$%02X"),// C6 + FMT("1100_0111 I", "LD B,$%02X"), // C7 : shougi.c : please check with real chip ! + FMT("1100_1000 I", "ADD A,$%02X"), // C8 + FMT("1100_1001 I", "SUB A,$%02X"), // C9 + FMT("1100_1010 I", "AND A,$%02X"), // CA + FMT("1100_1011 I", "OR A,$%02X"), // CB + FMT("1100_1100 I", "DJNZ LP0,$%02X"),// CC + FMT("1100_1101 I", "DJNZ LP1,$%02X"),// CD + FMT("1100_1110 I", "DJNZ LP2,$%02X"),// CE + FMT("1100_1111 I", "JNZ $%02X"), // CF + FMT("1101_0000 I", "JC $%02X"), // D0 + FMT("1101_0001 I", "JZ $%02X"), // D1 + FMT("1101_0010 I", "J $%02X"), // D2 + FMT("1101_0011 I", "unk $%02X"), // D3 + FMT("1101_0100 I", "alu a,$%02X ?"), // D4 : 8031 , exctscc2 alu a,n ? + FMT("1101_0101 I", "alu a,$%02X ?"), // D5 : 8031 , exctscc2 alu a,n ? + FMT("1101_0110 I", "unk $%02X"), // D6 + FMT("1101_0111 I", "unk $%02X"), // D7 + FMT("1101_1000 I", "unk $%02X"), // D8 + FMT("1101_1001 I", "unk $%02X"), // D9 + FMT("1101_1010 I", "CMP A,$%02X"), // DA : 8301 + FMT("1101_1011 I", "unk $%02X"), // DB + FMT("1101_1100 I", "unk $%02X"), // DC + FMT("1101_1101 I", "unk $%02X"), // DD + FMT("1101_1110 I", "unk $%02X"), // DE + FMT("1101_1111 I", "CALL $%02X"), // DF : 8301 +// + FMT("1110_0000", "DEC IX0"), // E0 : 8301 +// FMT("1110_0001", "unknown"), // E1 +// FMT("1110_0010", "unknown"), // E2 + FMT("1110_0011", "ld a,b ?"), // E3 : 8301 +// FMT("1110_0100", "unknown"), // E4 +// FMT("1110_0101", "unknown"), // E5 +// FMT("1110_0110", "unknown"), // E6 : 8301 +// FMT("1110_0110", "unknown"), // E7 + FMT("1110_1000", "LD IX0,A"), // E8 : 8301 + FMT("1110_1001", "LD IX1,A ?"), // E9 : not found + FMT("1110_1010", "LD IX2,A"), // EA : 8301 + FMT("1110_1011", "ld b,a ?"), // EB : 8301 +// FMT("1110_1100", "unknown"), // EC +// FMT("1110_1100", "unknown"), // ED +// FMT("1110_1110", "unknown"), // EE : 8301 +// FMT("1110_1111", "unknown"), // EF +// FMT("1111_0000", "unknown"), // F0 + FMT("1111_0001", "LD IX2,IX0"), // F1 : 8301 +// FMT("1111_0010", "unknown"), // F2 : 8301 , alu a,[IXR] ? +// FMT("1111_0011", "unknown"), // F3 +// FMT("1111_0100", "unknown"), // F4 +// FMT("1111_0101", "unknown"), // F5 + FMT("1111_0110", "alu ?,a"), // F6 : 8301 , exctsccr, alu ?,a +// FMT("1111_0110", "unknown"), // F7 + FMT("1111_1000", "alu a,?"), // F8 : 8301 , exctsccr, alu b,a ? : ZF check + FMT("1111_1001", "alu a,?"), // F9 : 8301 , exctsccr, alu a,? + FMT("1111_1010", "ADD A,CF"), // FA : 8301 +// FMT("1111_1011", "unknown"), // FB + FMT("1111_1100", "tst a ?"), // FC : 8301 , ZF = (A==0) ? + FMT("1111_1101", "CLR A"), // FD : 8301 + FMT("1111_1110", "LD A,(IX0+A)"), // FE : 8301 + FMT("1111_1111", "RET"), // FF : 8301 + NULL +}; + +#define MAX_OPS (((sizeof(Formats) / sizeof(Formats[0])) - 1) / PTRS_PER_FORMAT) + +typedef struct opcode { + byte mask; + byte bits; + byte type; + byte pmask; + byte pdown; + const char *fmt; +} AD8201Opcode; + +static AD8201Opcode Op[MAX_OPS+1]; +static int OpInizialized = 0; + +static void InitDasm8201(void) +{ + const char *p; + byte mask, bits; + int bit; + int i; + char chr , type; + int pmask , pdown; + + for(i=0;(p=Formats[i*2])!=NULL;i++) + { + mask = 0; + bits = 0; + pmask = 0; + pdown = 0; + type = 0; + bit = 7; + while ( (chr=*p) && bit >= 0) { + p++; + switch (chr) { + case '1': bits |= 1<<bit; + case '0': mask |= 1<<bit; bit--; break; +/* + case 'b': + type |= 0x80; +*/ + case 'a': + pmask |= 1<<bit; + pdown = bit; + case 'x': + bit --; + break; + case '_': + continue; + default: + fatalerror("Invalid instruction encoding '%s %s'\n", Formats[i*2],Formats[i*2+1]); + } + } + if (bit != -1 ) { + fatalerror("not enough bits in encoding '%s %s' %d\n", Formats[i*2],Formats[i*2+1],bit); + } + + Op[i].mask = mask; + Op[i].bits = bits; + Op[i].pmask = pmask; + Op[i].pdown = pdown; + Op[i].fmt = Formats[i*2+1]; + Op[i].type = type; + + /* 2 byte code ? */ + while (isspace(*p)) p++; + if( (*p) ) + Op[i].type |= 0x10; + /* number of param */ + if( (p=strchr(Op[i].fmt,'%'))!=NULL ) + { + Op[i].type |= 0x01; /* single param */ + if(strchr(p+1,'%') ) + Op[i].type |= 0x02; /* double param */ + } + } + + OpInizialized = 1; +} + +offs_t ALPHA8201_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) +{ + offs_t dasmflags = 0; + int i; + int op; + int cnt = 1; + int code , disp; + + if (!OpInizialized) InitDasm8201(); + + code = oprom[0]; + op = -1; /* no matching opcode */ + for ( i = 0; i < MAX_OPS; i++) + { + if( (code & Op[i].mask) == Op[i].bits ) + { + if (op != -1) + { + fprintf(stderr, "Error: opcode %02X matches %d (%s) and %d (%s)\n", + code,i,Op[i].fmt,op,Op[op].fmt); + } + op = i; + } + } + + if (op == -1) + { + sprintf(buffer,"db %2.2x",code); + return cnt; + } + + if (Op[op].type & 0x10) + { + disp = opram[1]; + cnt++; + } + else + { + disp = (code & Op[op].pmask) >> Op[op].pdown; + } + + if (Op[op].type & 0x02) + sprintf(buffer, Op[op].fmt,disp,disp); + else if (Op[op].type & 0x01) + sprintf(buffer, Op[op].fmt,disp); + else + sprintf(buffer, "%s",Op[op].fmt); + + switch (code) + { + case 0xcc: + case 0xcd: + case 0xce: + case 0xdf: + dasmflags = DASMFLAG_STEP_OVER; + break; + + case 0xff: + dasmflags = DASMFLAG_STEP_OUT; + break; + } + + return cnt | dasmflags | DASMFLAG_SUPPORTED; +} diff --git a/src/emu/cpu/alph8201/alph8201.c b/src/emu/cpu/alph8201/alph8201.c new file mode 100644 index 00000000000..53b8db87c9a --- /dev/null +++ b/src/emu/cpu/alph8201/alph8201.c @@ -0,0 +1,1013 @@ +/**************************************************************************** + Alpha8201 Emulator + + Copyright (C) 2006 Tatsuyuki Satoh + Originally written for the MAME project. + + Notes : + + tested with champbas.c , talbot.c , shougi.c + + This MCU looks too slow speed, + but fast execution don't work to champbb2, champbbj, talbot. + + some unknown instruction are not emulation (used by shougi). + + Because there was no information, opcode-syntax was created. + + TODO: + verify with real chip or analyze more. + -call/ret stack point (8301). + -A lot of 8301 opcode. + -memory address 000 specification + -memory address 001 bit 7-5 specification + -write value after HALT operation to ODD of vector memory. + -operation cycle(execution speed). + History: + +060327: + IXR changes to Breg. + The addition of Memory Access of Breg and IX0 + +060326: + Added ALPHA 8301 I/F and emulation + +060324: + Archtectore Created by compare code no-MCU Z80 code and MCU version code. + and check talbot and shougi.c. + +****************************************************************************/ + +/**************************************************************************** + +----------------------- +package / pin assign +----------------------- +ALPHA 8201 DIP 42 + + 1 -WR (or -RD) + 2-4 : ? NC + 5-7 : ? GND to shougi , NC to champbas + 8-14: ? NC + 15 : RESET + 16 : GND + 17 : CLK (champbas=768KHz) + 18 : ? NC + 19-21: to VCC + 22-25: DB4-DB7 + 26-29: DB0-DB3 + 30 : HALT (input) + 31 : ? NC + 32-35: A4-A7 + 36-39: A0-A3 + 40-41: A8-A9 + 42 : -RD (or -WR) + +ALPHA 8301 seems to be 8201 upper compatibility IC. +The package of ALPHA8301 is unknown. + +----------------------- +Register Set +----------------------- + +PC : 10bit Program Pointer + A lower 8bits are loaded from the immidate. + A higher 2bits are loaded from the MB register. + +MB : 2bit memory bank register, load PC[9:8] after branch + load high to higher 2bit of PC after branch. + +RB : 3bit register bank select register + +R0-R7 : internal? RAM register 8bitx8 (x8 bank) + +A : 8bit + +IX0/1 : memory indirect 'read' access pointer + +IX2 : memory indirect 'write' access pointer + +RXB : unknown , looks index register + +LP0/1/2 : loop count register used by DJNZ operation + +CF : carry flag +ZF : zero flag + +----------------------- +Memoy Space +----------------------- + +000 : unknown ... +001 : bit4..0 = pointer of current entry , bit7..6 = unknown +002-003 : entrypoint1 vector +004-005 : entrypoint2 vector +006-007 : entrypoint3 vector +008-009 : entrypoint4 vector +00A-00B : entrypoint5 vector +00C-00D : entrypoint6 vector +00E-00F : entrypoint7 vector +010-011 : entrypoint8 vector +012-013 : entrypoint9 vector +014-015 : entrypoint10 vector +016-017 : entrypoint11 vector +018-019 : entrypoint12 vector +01A-01B : entrypoint13 vector +01C-01D : entrypoint14 vector +01E-01F : entrypoint15 vector +020-0FF : bank 0, program / data memory +100-1FF : bank 1, program / data memory +200-2FF : bank 2, program / data memory +300-3FF : bank 3, program / data memory + +The even address is the lower byte of the entry address. +The odd-address of entry point is a MB and status. + Bit 0 and 1 are a memory bank. + Bit 2 is HALT.At the time of set, it doesn't execute entry address. + After EXIT operation, Bit2 is set. + +----------------------- +Timming +----------------------- + +****************************************************************************/ + +#include "debugger.h" +#include "alph8201.h" + +/* instruction cycle count */ +#define C1 16 +#define C2 32 + +/* debug option */ +#define TRACE_PC 0 +#define SHOW_ENTRY_POINT 0 +#define SHOW_MESSAGE_CONSOLE 0 + +/* MAME is unnecessary */ +#define HANDLE_HALT_LINE 0 + +#define M_RDMEM(A) ALPHA8201_RDMEM(A) +#define M_WRMEM(A,V) ALPHA8201_WRMEM(A,V) +#define M_RDOP(A) ALPHA8201_RDOP(A) +#define M_RDOP_ARG(A) ALPHA8201_RDOP_ARG(A) + +typedef struct +{ + UINT8 RAM[8*8]; /* internal GP register 8 * 8bank */ + unsigned PREVPC; + PAIR retptr; /* for 8301, return address stack of CALL */ + PAIR pc; /* 2bit+8bit program counter */ + UINT8 regPtr; /* RB register base */ + UINT8 mb; /* MB memory bank reg. latch after Branch */ + UINT8 cf; /* C flag */ + UINT8 zf; /* Z flag */ +// + PAIR ix0; /* 8bit memory read index reg. */ + PAIR ix1; /* 8bitmemory read index reg. */ + PAIR ix2; /* 8bitmemory write index reg. */ + UINT8 lp0; /* 8bit loop reg. */ + UINT8 lp1; /* 8bit loop reg. */ + UINT8 lp2; /* 8bit loop reg. */ + UINT8 A; /* 8bit accumerator */ + UINT8 B; /* 8bit regiser */ +// +#if HANDLE_HALT_LINE + UINT8 halt; /* halt input line */ +#endif +} ALPHA8201_Regs; + +/* The opcode table now is a combination of cycle counts and function pointers */ +typedef struct { + unsigned cycles; + void (*function) (void); +} s_opcode; + +static ALPHA8201_Regs R; +int ALPHA8201_ICount; +static int inst_cycles; + +#define intRAM R.RAM +#define regPTR R.regPtr + +#define PC R.pc.w.l +#define PCL R.pc.b.l +#define R0 intRAM[regPTR ] +#define R1 intRAM[regPTR+1] +#define R2 intRAM[regPTR+2] +#define R3 intRAM[regPTR+3] +#define R4 intRAM[regPTR+4] +#define R5 intRAM[regPTR+5] +#define R6 intRAM[regPTR+6] +#define R7 intRAM[regPTR+7] +#define ZF R.zf +#define CF R.cf +#define IX0 R.ix0.b.l +#define IX1 R.ix1.b.l +#define IX2 R.ix2.b.l +#define BIX0 R.ix0.w.l +#define BIX1 R.ix1.w.l +#define BIX2 R.ix2.w.l +#define LP0 R.lp0 +#define LP1 R.lp1 +#define LP2 R.lp2 + +/* Get next opcode argument and increment program counter */ +INLINE unsigned M_RDMEM_OPCODE (void) +{ + unsigned retval; + retval=M_RDOP_ARG(PC); + PCL++; + return retval; +} + +INLINE void M_ADD(UINT8 dat) +{ + UINT16 temp = R.A + dat; + R.A = temp & 0xff; + ZF = (R.A==0); + CF = temp>>8; +} + +INLINE void M_SUB(UINT8 dat) +{ + CF = (R.A<dat); + R.A -= dat; + ZF = (R.A==0); +} + +INLINE void M_ADDB(UINT8 dat) +{ + UINT16 temp = R.B + dat; + R.B = temp & 0xff; + ZF = (R.B==0); + CF = temp>>8; +} + +INLINE void M_SUBB(UINT8 dat) +{ + CF = (R.B<dat); + R.B -= dat; + ZF = (R.B==0); +} + +INLINE void M_AND(UINT8 dat) +{ + R.A &= dat; + ZF = (R.A==0); + CF = 0; +} + +INLINE void M_OR(UINT8 dat) +{ + R.A |= dat; + ZF = (R.A==0); + CF = 0; +} + +INLINE void M_JMP(UINT8 dat) +{ + PCL = dat; + /* update pc page */ + R.pc.b.h = R.ix0.b.h = R.ix1.b.h = R.ix2.b.h = R.mb & 3; + change_pc(PC); +} + +INLINE void M_UNDEFINED(void) +{ + logerror("ALPHA8201: PC = %03x, Unimplemented opcode = %02x\n", PC-1, M_RDMEM(PC-1)); +#if SHOW_MESSAGE_CONSOLE + mame_printf_debug("ALPHA8201: PC = %03x, Unimplemented opcode = %02x\n", PC-1, M_RDMEM(PC-1)); +#endif +} + +INLINE void M_UNDEFINED2(void) +{ + UINT8 op = M_RDOP(PC-1); + UINT8 imm = M_RDMEM_OPCODE(); + logerror("ALPHA8201: PC = %03x, Unimplemented opcode = %02x,%02x\n", PC-2, op,imm); +#if SHOW_MESSAGE_CONSOLE + mame_printf_debug("ALPHA8201: PC = %03x, Unimplemented opcode = %02x,%02x\n", PC-2, op,imm); +#endif +} + +static void undefined(void) { M_UNDEFINED(); } +static void undefined2(void) { M_UNDEFINED2(); } + +static void need_verify(const char *s) +{ + UINT8 op = M_RDOP(PC-1); + logerror("ALPHA8201: PC = %03x, unknown opcode = %02x is '%s' ??\n",PC-1, op,s); +#if SHOW_MESSAGE_CONSOLE + mame_printf_debug("ALPHA8201: PC = %03x, unknown opcode = %02x is '%s' ??\n",PC-1, op,s); +#endif +} + +static void nop(void) { } +static void rlca(void) { CF = (R.A>>7)&1; R.A = (R.A<<1) | (R.A>>7); ZF = (R.A==0); } +static void rrca(void) { CF = R.A &1; R.A = (R.A>>1) | (R.A<<7); ZF = (R.A==0); } +static void inc_b(void) { M_ADDB(1); } +static void dec_b(void) { M_SUBB(1); }; +static void inc_a(void) { M_ADD(1); } +static void dec_a(void) { M_SUB(1); } +static void cpl(void) { R.A = R.A^0xff; ZF = (R.A==0); }; + +static void ld_a_ix0_0(void) { R.A = M_RDMEM(BIX0+0); } +static void ld_a_ix0_1(void) { R.A = M_RDMEM(BIX0+1); } +static void ld_a_ix0_2(void) { R.A = M_RDMEM(BIX0+2); } +static void ld_a_ix0_3(void) { R.A = M_RDMEM(BIX0+3); } +static void ld_a_ix0_4(void) { R.A = M_RDMEM(BIX0+4); } +static void ld_a_ix0_5(void) { R.A = M_RDMEM(BIX0+5); } +static void ld_a_ix0_6(void) { R.A = M_RDMEM(BIX0+6); } +static void ld_a_ix0_7(void) { R.A = M_RDMEM(BIX0+7); } + +static void ld_a_ix1_0(void) { R.A = M_RDMEM(BIX1+0); } +static void ld_a_ix1_1(void) { R.A = M_RDMEM(BIX1+1); } +static void ld_a_ix1_2(void) { R.A = M_RDMEM(BIX1+2); } +static void ld_a_ix1_3(void) { R.A = M_RDMEM(BIX1+3); } +static void ld_a_ix1_4(void) { R.A = M_RDMEM(BIX1+4); } +static void ld_a_ix1_5(void) { R.A = M_RDMEM(BIX1+5); } +static void ld_a_ix1_6(void) { R.A = M_RDMEM(BIX1+6); } +static void ld_a_ix1_7(void) { R.A = M_RDMEM(BIX1+7); } + +static void ld_ix2_0_a(void) { M_WRMEM(BIX2+0,R.A); } +static void ld_ix2_1_a(void) { M_WRMEM(BIX2+1,R.A); } +static void ld_ix2_2_a(void) { M_WRMEM(BIX2+2,R.A); } +static void ld_ix2_3_a(void) { M_WRMEM(BIX2+3,R.A); } +static void ld_ix2_4_a(void) { M_WRMEM(BIX2+4,R.A); } +static void ld_ix2_5_a(void) { M_WRMEM(BIX2+5,R.A); } +static void ld_ix2_6_a(void) { M_WRMEM(BIX2+6,R.A); } +static void ld_ix2_7_a(void) { M_WRMEM(BIX2+7,R.A); } + +static void ld_ix0_0_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_1_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_2_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_3_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_4_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_5_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_6_b(void) { M_WRMEM(BIX0+0,R.B); } +static void ld_ix0_7_b(void) { M_WRMEM(BIX0+0,R.B); } + +static void ld_ix1_0_b(void) { M_WRMEM(BIX1+0,R.B); need_verify("LD (IX1+0),B"); } +static void ld_ix1_1_b(void) { M_WRMEM(BIX1+1,R.B); need_verify("LD (IX1+1),B"); } +static void ld_ix1_2_b(void) { M_WRMEM(BIX1+2,R.B); need_verify("LD (IX1+2),B"); } +static void ld_ix1_3_b(void) { M_WRMEM(BIX1+3,R.B); need_verify("LD (IX1+3),B"); } +static void ld_ix1_4_b(void) { M_WRMEM(BIX1+4,R.B); need_verify("LD (IX1+4),B"); } +static void ld_ix1_5_b(void) { M_WRMEM(BIX1+5,R.B); need_verify("LD (IX1+5),B"); } +static void ld_ix1_6_b(void) { M_WRMEM(BIX1+6,R.B); need_verify("LD (IX1+6),B"); } +static void ld_ix1_7_b(void) { M_WRMEM(BIX1+7,R.B); need_verify("LD (IX1+7),B"); } + +static void ld_b_ix2_0(void) { R.B = M_RDMEM(BIX2+0); need_verify("LD B,(IX2+0)"); } +static void ld_b_ix2_1(void) { R.B = M_RDMEM(BIX2+1); need_verify("LD B,(IX2+1)"); } +static void ld_b_ix2_2(void) { R.B = M_RDMEM(BIX2+2); need_verify("LD B,(IX2+2)"); } +static void ld_b_ix2_3(void) { R.B = M_RDMEM(BIX2+3); need_verify("LD B,(IX2+3)"); } +static void ld_b_ix2_4(void) { R.B = M_RDMEM(BIX2+4); need_verify("LD B,(IX2+4)"); } +static void ld_b_ix2_5(void) { R.B = M_RDMEM(BIX2+5); need_verify("LD B,(IX2+5)"); } +static void ld_b_ix2_6(void) { R.B = M_RDMEM(BIX2+6); need_verify("LD B,(IX2+6)"); } +static void ld_b_ix2_7(void) { R.B = M_RDMEM(BIX2+7); need_verify("LD B,(IX2+7)"); } + +static void bit_r0_0(void) { R.zf = R0&(1<<0)?0:1; } +static void bit_r0_1(void) { R.zf = R0&(1<<1)?0:1; } +static void bit_r0_2(void) { R.zf = R0&(1<<2)?0:1; } +static void bit_r0_3(void) { R.zf = R0&(1<<3)?0:1; } +static void bit_r0_4(void) { R.zf = R0&(1<<4)?0:1; } +static void bit_r0_5(void) { R.zf = R0&(1<<5)?0:1; } +static void bit_r0_6(void) { R.zf = R0&(1<<6)?0:1; } +static void bit_r0_7(void) { R.zf = R0&(1<<7)?0:1; } + +static void ld_a_n(void) { R.A = M_RDMEM_OPCODE(); } +static void ld_a_r0(void) { R.A = R0; } +static void ld_a_r1(void) { R.A = R1; } +static void ld_a_r2(void) { R.A = R2; } +static void ld_a_r3(void) { R.A = R3; } +static void ld_a_r4(void) { R.A = R4; } +static void ld_a_r5(void) { R.A = R5; } +static void ld_a_r6(void) { R.A = R6; } +static void ld_a_r7(void) { R.A = R7; } + +static void ld_r0_a(void) { R0 = R.A; } +static void ld_r1_a(void) { R1 = R.A; } +static void ld_r2_a(void) { R2 = R.A; } +static void ld_r3_a(void) { R3 = R.A; } +static void ld_r4_a(void) { R4 = R.A; } +static void ld_r5_a(void) { R5 = R.A; } +static void ld_r6_a(void) { R6 = R.A; } +static void ld_r7_a(void) { R7 = R.A; } + +static void add_a_n(void) { M_ADD(M_RDMEM_OPCODE()); } +static void add_a_r0(void) { M_ADD(R0); } +static void add_a_r1(void) { M_ADD(R1); } +static void add_a_r2(void) { M_ADD(R2); } +static void add_a_r3(void) { M_ADD(R3); } +static void add_a_r4(void) { M_ADD(R4); } +static void add_a_r5(void) { M_ADD(R5); } +static void add_a_r6(void) { M_ADD(R6); } +static void add_a_r7(void) { M_ADD(R7); } + +static void sub_a_n(void) { M_SUB(M_RDMEM_OPCODE()); } +static void sub_a_r0(void) { M_SUB(R0); } +static void sub_a_r1(void) { M_SUB(R1); } +static void sub_a_r2(void) { M_SUB(R2); } +static void sub_a_r3(void) { M_SUB(R3); } +static void sub_a_r4(void) { M_SUB(R4); } +static void sub_a_r5(void) { M_SUB(R5); } +static void sub_a_r6(void) { M_SUB(R6); } +static void sub_a_r7(void) { M_SUB(R7); } + +static void and_a_n(void) { M_AND(M_RDMEM_OPCODE()); } +static void and_a_r0(void) { M_AND(R0); } +static void and_a_r1(void) { M_AND(R1); } +static void and_a_r2(void) { M_AND(R2); } +static void and_a_r3(void) { M_AND(R3); } +static void and_a_r4(void) { M_AND(R4); } +static void and_a_r5(void) { M_AND(R5); } +static void and_a_r6(void) { M_AND(R6); } +static void and_a_r7(void) { M_AND(R7); } + +static void or_a_n(void) { M_OR(M_RDMEM_OPCODE()); } +static void or_a_r0(void) { M_OR(R0); } +static void or_a_r1(void) { M_OR(R1); } +static void or_a_r2(void) { M_OR(R2); } +static void or_a_r3(void) { M_OR(R3); } +static void or_a_r4(void) { M_OR(R4); } +static void or_a_r5(void) { M_OR(R5); } +static void or_a_r6(void) { M_OR(R6); } +static void or_a_r7(void) { M_OR(R7); } + +static void add_ix0_0(void) {} +static void add_ix0_1(void) { IX0 += 1; } +static void add_ix0_2(void) { IX0 += 2; } +static void add_ix0_3(void) { IX0 += 3; } +static void add_ix0_4(void) { IX0 += 4; } +static void add_ix0_5(void) { IX0 += 5; } +static void add_ix0_6(void) { IX0 += 6; } +static void add_ix0_7(void) { IX0 += 7; } +static void add_ix0_8(void) { IX0 += 8; } +static void add_ix0_9(void) { IX0 += 9; } +static void add_ix0_a(void) { IX0 += 10; } +static void add_ix0_b(void) { IX0 += 11; } +static void add_ix0_c(void) { IX0 += 12; } +static void add_ix0_d(void) { IX0 += 13; } +static void add_ix0_e(void) { IX0 += 14; } +static void add_ix0_f(void) { IX0 += 15; } + +static void add_ix1_0(void) {} +static void add_ix1_1(void) { IX1 += 1; } +static void add_ix1_2(void) { IX1 += 2; } +static void add_ix1_3(void) { IX1 += 3; } +static void add_ix1_4(void) { IX1 += 4; } +static void add_ix1_5(void) { IX1 += 5; } +static void add_ix1_6(void) { IX1 += 6; } +static void add_ix1_7(void) { IX1 += 7; } +static void add_ix1_8(void) { IX1 += 8; } +static void add_ix1_9(void) { IX1 += 9; } +static void add_ix1_a(void) { IX1 += 10; } +static void add_ix1_b(void) { IX1 += 11; } +static void add_ix1_c(void) { IX1 += 12; } +static void add_ix1_d(void) { IX1 += 13; } +static void add_ix1_e(void) { IX1 += 14; } +static void add_ix1_f(void) { IX1 += 15; } + +static void add_ix2_0(void) {} +static void add_ix2_1(void) { IX2 += 1; } +static void add_ix2_2(void) { IX2 += 2; } +static void add_ix2_3(void) { IX2 += 3; } +static void add_ix2_4(void) { IX2 += 4; } +static void add_ix2_5(void) { IX2 += 5; } +static void add_ix2_6(void) { IX2 += 6; } +static void add_ix2_7(void) { IX2 += 7; } +static void add_ix2_8(void) { IX2 += 8; } +static void add_ix2_9(void) { IX2 += 9; } +static void add_ix2_a(void) { IX2 += 10; } +static void add_ix2_b(void) { IX2 += 11; } +static void add_ix2_c(void) { IX2 += 12; } +static void add_ix2_d(void) { IX2 += 13; } +static void add_ix2_e(void) { IX2 += 14; } +static void add_ix2_f(void) { IX2 += 15; } + +static void ld_base_0(void) { regPTR = 0<<3; } +static void ld_base_1(void) { regPTR = 1<<3; } +static void ld_base_2(void) { regPTR = 2<<3; } +static void ld_base_3(void) { regPTR = 3<<3; } +static void ld_base_4(void) { regPTR = 4<<3; } +static void ld_base_5(void) { regPTR = 5<<3; } +static void ld_base_6(void) { regPTR = 6<<3; } +static void ld_base_7(void) { regPTR = 7<<3; } + +static void ld_bank_0(void) { R.mb = 0; } +static void ld_bank_1(void) { R.mb = 1; } +static void ld_bank_2(void) { R.mb = 2; } +static void ld_bank_3(void) { R.mb = 3; } + +static void halt(void) +{ + UINT8 pcptr = M_RDMEM(0x001) & 0x1f; + M_WRMEM(pcptr,0x08); /* mark entry point ODD to HALT */ + R.mb |= 0x08; /* mark internal HALT state */ +} + +static void ld_ix0_n(void) { IX0 = M_RDMEM_OPCODE(); } +static void ld_ix1_n(void) { IX1 = M_RDMEM_OPCODE(); } +static void ld_ix2_n(void) { IX2 = M_RDMEM_OPCODE(); } +static void ld_lp0_n(void) { LP0 = M_RDMEM_OPCODE(); } +static void ld_lp1_n(void) { LP1 = M_RDMEM_OPCODE(); } +static void ld_lp2_n(void) { LP2 = M_RDMEM_OPCODE(); } +static void ld_b_n(void) { R.B = M_RDMEM_OPCODE(); } + +static void djnz_lp0(void) { UINT8 i=M_RDMEM_OPCODE(); LP0--; if (LP0 != 0) M_JMP(i); } +static void djnz_lp1(void) { UINT8 i=M_RDMEM_OPCODE(); LP1--; if (LP1 != 0) M_JMP(i); } +static void djnz_lp2(void) { UINT8 i=M_RDMEM_OPCODE(); LP2--; if (LP2 != 0) M_JMP(i); } +static void jnz(void) { UINT8 i=M_RDMEM_OPCODE(); if (!R.zf) M_JMP(i); } +static void jc(void) { UINT8 i=M_RDMEM_OPCODE(); if ( R.cf) M_JMP(i); } +static void jz(void) { UINT8 i=M_RDMEM_OPCODE(); if ( R.zf) M_JMP(i); } +static void jmp(void) { M_JMP( M_RDMEM_OPCODE() ); } + +#if (HAS_ALPHA8201) +static const s_opcode opcode_8201[256]= +{ + {C1, nop },{C1,rrca },{C1, rlca },{C1,inc_b },{C1, dec_b },{C1, inc_a },{C1, dec_a },{C1, cpl }, + {C2,ld_a_ix0_0 },{C2,ld_a_ix0_1},{C2, ld_a_ix0_2},{C2,ld_a_ix0_3},{C2,ld_a_ix0_4},{C2,ld_a_ix0_5},{C2,ld_a_ix0_6},{C2,ld_a_ix0_7}, + {C2,ld_a_ix1_0 },{C2,ld_a_ix1_1},{C2, ld_a_ix1_2},{C2,ld_a_ix1_3},{C2,ld_a_ix1_4},{C2,ld_a_ix1_5},{C2,ld_a_ix1_6},{C2,ld_a_ix1_7}, + {C2,ld_ix2_0_a },{C2,ld_ix2_1_a},{C2, ld_ix2_2_a},{C2,ld_ix2_3_a},{C2,ld_ix2_4_a},{C2,ld_ix2_5_a},{C2,ld_ix2_6_a},{C2,ld_ix2_7_a}, +/* 20 */ + {C2,ld_ix0_0_b },{C2,ld_ix0_1_b},{C2, ld_ix0_2_b},{C2,ld_ix0_3_b},{C2,ld_ix0_4_b},{C2,ld_ix0_5_b},{C2,ld_ix0_6_b},{C2,ld_ix0_7_b}, + {C2,ld_ix1_0_b },{C2,ld_ix1_1_b},{C2, ld_ix1_2_b},{C2,ld_ix1_3_b},{C2,ld_ix1_4_b},{C2,ld_ix1_5_b},{C2,ld_ix1_6_b},{C2,ld_ix1_7_b}, + {C2,ld_b_ix2_0 },{C2,ld_b_ix2_1},{C2, ld_b_ix2_2},{C2,ld_b_ix2_3},{C2,ld_b_ix2_4},{C2,ld_b_ix2_5},{C2,ld_b_ix2_6},{C2,ld_b_ix2_7}, + {C2,bit_r0_0 },{C2,bit_r0_1 },{C2, bit_r0_2 },{C2, bit_r0_3 },{C2, bit_r0_4 },{C2, bit_r0_5 },{C2, bit_r0_6 },{C2, bit_r0_7 }, +/* 40 : 8201 */ + {C2, ld_a_r0 },{C2, ld_r0_a },{C2, ld_a_r1 },{C2, ld_r1_a },{C2, ld_a_r2 },{C2, ld_r2_a },{C2, ld_a_r3 },{C2, ld_r3_a }, + {C2, ld_a_r4 },{C2, ld_r4_a },{C2, ld_a_r5 },{C2, ld_r5_a },{C2, ld_a_r6 },{C2, ld_r6_a },{C2, ld_a_r7 },{C2, ld_r7_a }, + {C1, add_a_r0 },{C1, sub_a_r0 },{C1, add_a_r1 },{C1, sub_a_r1 },{C1, add_a_r2 },{C1, sub_a_r2 },{C1, add_a_r3 },{C1, sub_a_r3 }, + {C1, add_a_r4 },{C1, sub_a_r4 },{C1, add_a_r5 },{C1, sub_a_r5 },{C1, add_a_r6 },{C1, sub_a_r6 },{C1, add_a_r7 },{C1, sub_a_r7 }, + {C1, and_a_r0 },{C1, or_a_r0 },{C1, and_a_r1 },{C1, or_a_r1 },{C1, and_a_r2 },{C1, or_a_r2 },{C1, and_a_r3 },{C1, or_a_r3 }, + {C1, and_a_r4 },{C1, or_a_r4 },{C1, and_a_r5 },{C1, or_a_r5 },{C1, and_a_r6 },{C1, or_a_r6 },{C1, and_a_r7 },{C1, or_a_r7 }, + {C1, add_ix0_0 },{C1, add_ix0_1},{C1, add_ix0_2},{C1, add_ix0_3},{C1, add_ix0_4},{C1, add_ix0_5},{C1, add_ix0_6},{C1, add_ix0_7}, + {C1, add_ix0_8 },{C1, add_ix0_9},{C1, add_ix0_a},{C1, add_ix0_b},{C1, add_ix0_c},{C1, add_ix0_d},{C1, add_ix0_e},{C1, add_ix0_f}, +/* 80 : 8201 */ + {C1, add_ix1_0 },{C1, add_ix1_1},{C1, add_ix1_2},{C1, add_ix1_3},{C1, add_ix1_4},{C1, add_ix1_5},{C1, add_ix1_6},{C1, add_ix1_7}, + {C1, add_ix1_8 },{C1, add_ix1_9},{C1, add_ix1_a},{C1, add_ix1_b},{C1, add_ix1_c},{C1, add_ix1_d},{C1, add_ix1_e},{C1, add_ix1_f}, + {C1, add_ix2_0 },{C1, add_ix2_1},{C1, add_ix2_2},{C1, add_ix2_3},{C1, add_ix2_4},{C1, add_ix2_5},{C1, add_ix2_6},{C1, add_ix2_7}, + {C1, add_ix2_8 },{C1, add_ix2_9},{C1, add_ix2_a},{C1, add_ix2_b},{C1, add_ix2_c},{C1, add_ix2_d},{C1, add_ix2_e},{C1, add_ix2_f}, + {C1, ld_base_0 },{C1, ld_base_1},{C1, ld_base_2},{C1, ld_base_3},{C1, ld_base_4},{C1, ld_base_5},{C1, ld_base_6},{C1, ld_base_7}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, ld_bank_0 },{C1, ld_bank_1},{C1, ld_bank_2},{C1, ld_bank_3},{C2, halt },{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, +/* c0 : 8201 */ + {C2, ld_ix0_n },{C2, ld_ix1_n },{C2, ld_ix2_n },{C2, ld_a_n },{C2, ld_lp0_n },{C2, ld_lp1_n },{C2, ld_lp2_n },{C2, ld_b_n }, + {C2, add_a_n },{C2, sub_a_n },{C2, and_a_n },{C2, or_a_n },{C2, djnz_lp0 },{C2, djnz_lp1 },{C2, djnz_lp2 },{C2, jnz }, + {C2, jc },{C2, jz },{C2, jmp },{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2, undefined2}, + {C2, undefined2 },{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2, undefined2}, +/* E0 : 8201*/ + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined } +}; +#endif + +#if (HAS_ALPHA8301) + +/* ALPHA 8301 : added instruction */ +static void dec_ix0(void) { IX0--; } /* OK */ + +static void ld_a_b(void) { R.A = R.B; } +static void ld_b_a(void) { R.B = R.A; } + +static void ld_ix0_a(void) { IX0 = R.A; } /* maybe OK */ +static void ld_ix1_a(void) { IX1 = R.A; need_verify("LD IX1,A"); } /* not found */ +static void ld_ix2_a(void) { IX2 = R.A; } /* maybe OK */ + +static void ld_ix2_ix0(void) { IX2 = IX0; } /* OK */ + +/* used by exctscc2 initialize routine */ +/* A=2 , D5 01 , D4 00 -> R=5 */ +/* A=5 , D4 01 -> R=2 */ +/* +300: DA 02 CMP A,$02 ; A is 2 +302: CF 00 JNZ $00 +304: A7 LD RB,7 +305: 41 LD R0,A +306: 4F LD R7,A +307: D5 01 -------------- +309: D4 00 -------------- +30B: DA 05 CMP A,$05 ; A must be set 5 +30D: CF 00 JNZ $00 +30F: D4 01 -------------- +311: DA 02 CMP A,$02 ; A must be set 5 +313: CF 00 JNZ $00 +315: FD clr a ? +*/ +static void op_d4(void) { undefined2(); } +static void op_d5(void) { undefined2(); } + +/* used by exctsccr/exctscc2 ROM check sum routine (382-3cf) */ +/* ZF = 0 in op_f8 are patch for bypass exctsccr and exctscc2 check sum error */ +static void op_f6(void) { logerror("ALPHA-8301 Unknown OP-code PC = %03x, opcode = 0xf6: alu ?,a ??\n",PC-1); } +static void op_f8(void) { ZF = 1; logerror("ALPHA-8301 Unknown OP-code PC = %03x, opcode = 0xf8: alu ?,a ??\n",PC-1); } +static void op_f9(void) { logerror("ALPHA-8301 Unknown OP-code PC = %03x, opcode = 0xf9: alu a,? ??\n",PC-1); } + +static void add_a_cf(void) { R.A += CF; CF = 0; ZF = (R.A==0); } /* OK */ +static void tst_a(void) { ZF = (R.A==0); } /* maybe OK */ +static void clr_a(void) { R.A = 0; ZF = (R.A==0); } /* maybe OK */ +static void cmp_a_n(void) { UINT8 i=M_RDMEM_OPCODE(); ZF = (R.A==i); CF = (R.A<i); } +static void call(void) { UINT8 i=M_RDMEM_OPCODE(); R.retptr.w.l = PC; M_JMP(i); }; /* OK , but stack is unknown */ +static void ld_a_ix0_a(void) { R.A = M_RDMEM(BIX0+R.A); } /* maybe OK */ +static void ret(void) { R.mb = R.retptr.b.h; M_JMP( R.retptr.b.l ); }; /* OK , but stack is unknown */ + +static const s_opcode opcode_8301[256]= +{ + {C1, nop },{C1,rrca },{C1, rlca },{C1,inc_b },{C1, dec_b },{C1, inc_a },{C1, dec_a },{C1, cpl }, + {C2,ld_a_ix0_0 },{C2,ld_a_ix0_1},{C2, ld_a_ix0_2},{C2,ld_a_ix0_3},{C2,ld_a_ix0_4},{C2,ld_a_ix0_5},{C2,ld_a_ix0_6},{C2,ld_a_ix0_7}, + {C2,ld_a_ix1_0 },{C2,ld_a_ix1_1},{C2, ld_a_ix1_2},{C2,ld_a_ix1_3},{C2,ld_a_ix1_4},{C2,ld_a_ix1_5},{C2,ld_a_ix1_6},{C2,ld_a_ix1_7}, + {C2,ld_ix2_0_a },{C2,ld_ix2_1_a},{C2, ld_ix2_2_a},{C2,ld_ix2_3_a},{C2,ld_ix2_4_a},{C2,ld_ix2_5_a},{C2,ld_ix2_6_a},{C2,ld_ix2_7_a}, +/* 20 : 8301 */ + {C2,ld_ix0_0_b },{C2,ld_ix0_1_b},{C2, ld_ix0_2_b},{C2,ld_ix0_3_b},{C2,ld_ix0_4_b},{C2,ld_ix0_5_b},{C2,ld_ix0_6_b},{C2,ld_ix0_7_b}, + {C2,ld_ix1_0_b },{C2,ld_ix1_1_b},{C2, ld_ix1_2_b},{C2,ld_ix1_3_b},{C2,ld_ix1_4_b},{C2,ld_ix1_5_b},{C2,ld_ix1_6_b},{C2,ld_ix1_7_b}, + {C2,ld_b_ix2_0 },{C2,ld_b_ix2_1},{C2, ld_b_ix2_2},{C2,ld_b_ix2_3},{C2,ld_b_ix2_4},{C2,ld_b_ix2_5},{C2,ld_b_ix2_6},{C2,ld_b_ix2_7}, + {C2,bit_r0_0 },{C2,bit_r0_1 },{C2, bit_r0_2 },{C2, bit_r0_3 },{C2, bit_r0_4 },{C2, bit_r0_5 },{C2, bit_r0_6 },{C2, bit_r0_7 }, +/* 40 : 8301 */ + {C2, ld_a_r0 },{C2, ld_r0_a },{C2, ld_a_r1 },{C2, ld_r1_a },{C2, ld_a_r2 },{C2, ld_r2_a },{C2, ld_a_r3 },{C2, ld_r3_a }, + {C2, ld_a_r4 },{C2, ld_r4_a },{C2, ld_a_r5 },{C2, ld_r5_a },{C2, ld_a_r6 },{C2, ld_r6_a },{C2, ld_a_r7 },{C2, ld_r7_a }, + {C1, add_a_r0 },{C1, sub_a_r0 },{C1, add_a_r1 },{C1, sub_a_r1 },{C1, add_a_r2 },{C1, sub_a_r2 },{C1, add_a_r3 },{C1, sub_a_r3 }, + {C1, add_a_r4 },{C1, sub_a_r4 },{C1, add_a_r5 },{C1, sub_a_r5 },{C1, add_a_r6 },{C1, sub_a_r6 },{C1, add_a_r7 },{C1, sub_a_r7 }, +/* 60 : 8301 */ + {C1, and_a_r0 },{C1, or_a_r0 },{C1, and_a_r1 },{C1, or_a_r1 },{C1, and_a_r2 },{C1, or_a_r2 },{C1, and_a_r3 },{C1, or_a_r3 }, + {C1, and_a_r4 },{C1, or_a_r4 },{C1, and_a_r5 },{C1, or_a_r5 },{C1, and_a_r6 },{C1, or_a_r6 },{C1, and_a_r7 },{C1, or_a_r7 }, + {C1, add_ix0_0 },{C1, add_ix0_1},{C1, add_ix0_2},{C1, add_ix0_3},{C1, add_ix0_4},{C1, add_ix0_5},{C1, add_ix0_6},{C1, add_ix0_7}, + {C1, add_ix0_8 },{C1, add_ix0_9},{C1, add_ix0_a},{C1, add_ix0_b},{C1, add_ix0_c},{C1, add_ix0_d},{C1, add_ix0_e},{C1, add_ix0_f}, +/* 80 : 8301 */ + {C1, add_ix1_0 },{C1, add_ix1_1},{C1, add_ix1_2},{C1, add_ix1_3},{C1, add_ix1_4},{C1, add_ix1_5},{C1, add_ix1_6},{C1, add_ix1_7}, + {C1, add_ix1_8 },{C1, add_ix1_9},{C1, add_ix1_a},{C1, add_ix1_b},{C1, add_ix1_c},{C1, add_ix1_d},{C1, add_ix1_e},{C1, add_ix1_f}, + {C1, add_ix2_0 },{C1, add_ix2_1},{C1, add_ix2_2},{C1, add_ix2_3},{C1, add_ix2_4},{C1, add_ix2_5},{C1, add_ix2_6},{C1, add_ix2_7}, + {C1, add_ix2_8 },{C1, add_ix2_9},{C1, add_ix2_a},{C1, add_ix2_b},{C1, add_ix2_c},{C1, add_ix2_d},{C1, add_ix2_e},{C1, add_ix2_f}, +/* A0 : 8301 */ + {C1, ld_base_0 },{C1, ld_base_1},{C1, ld_base_2},{C1, ld_base_3},{C1, ld_base_4},{C1, ld_base_5},{C1, ld_base_6},{C1, ld_base_7}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, ld_bank_0 },{C1, ld_bank_1},{C1, ld_bank_2},{C1, ld_bank_3},{C2, halt },{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, +/* c0 : 8301 */ + {C2, ld_ix0_n },{C2, ld_ix1_n },{C2, ld_ix2_n },{C2, ld_a_n },{C2, ld_lp0_n },{C2, ld_lp1_n },{C2, ld_lp2_n },{C2, ld_b_n }, + {C2, add_a_n },{C2, sub_a_n },{C2, and_a_n },{C2, or_a_n },{C2, djnz_lp0 },{C2, djnz_lp1 },{C2, djnz_lp2 },{C2, jnz }, + {C2, jc },{C2, jz },{C2, jmp },{C2,undefined2},{C2, op_d4 },{C2, op_d5 },{C2,undefined2},{C2, undefined2}, + {C2, undefined2 },{C2,undefined2},{C2,cmp_a_n },{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2,undefined2},{C2, call}, +/* E0 : 8301 */ + {C1, dec_ix0 },{C1, undefined},{C1, undefined},{C1, ld_a_b },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, ld_ix0_a },{C1, ld_ix1_a },{C1, ld_ix2_a },{C1, ld_b_a },{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined}, + {C1, undefined },{C1,ld_ix2_ix0},{C1, undefined},{C1, undefined},{C1, undefined},{C1, undefined},{C1, op_f6 },{C1, undefined}, + {C1, op_f8 },{C1, op_f9 },{C1, add_a_cf },{C1, undefined},{C1, tst_a },{C1, clr_a },{C1,ld_a_ix0_a},{C1, ret } +}; +#endif + +/**************************************************************************** + * Initialize emulation + ****************************************************************************/ +static void ALPHA8201_init (int index, int clock, const void *config, int (*irqcallback)(int)) +{ + state_save_register_item_array("ALPHA8201", index, R.RAM); + state_save_register_item("ALPHA8201", index, R.PREVPC); + state_save_register_item("ALPHA8201", index, PC); + state_save_register_item("ALPHA8201", index, regPTR); + state_save_register_item("ALPHA8201", index, R.zf); + state_save_register_item("ALPHA8201", index, R.cf); + state_save_register_item("ALPHA8201", index, R.mb); +#if HANDLE_HALT_LINE + state_save_register_item("ALPHA8201", index, R.halt); +#endif + state_save_register_item("ALPHA8201", index, IX0); + state_save_register_item("ALPHA8201", index, IX1); + state_save_register_item("ALPHA8201", index, IX2); + state_save_register_item("ALPHA8201", index, LP0); + state_save_register_item("ALPHA8201", index, LP1); + state_save_register_item("ALPHA8201", index, LP2); + state_save_register_item("ALPHA8201", index, R.A); + state_save_register_item("ALPHA8201", index, R.B); +} +/**************************************************************************** + * Reset registers to their initial values + ****************************************************************************/ +static void ALPHA8201_reset (void) +{ + PC = 0; + regPTR = 0; + ZF = 0; + CF = 0; + R.mb = 0; + BIX0 = 0; + BIX1 = 0; + BIX2 = 0; + LP0 = 0; + LP1 = 0; + LP2 = 0; + R.A = 0; + R.B = 0; +#if HANDLE_HALT_LINE + R.halt = 0; +#endif +/* memset(R.RAM, 0, sizeof(R.RAM)); */ +} + +/**************************************************************************** + * Shut down CPU emulation + ****************************************************************************/ +static void ALPHA8201_exit (void) +{ + /* nothing to do ? */ +} + +/**************************************************************************** + * Execute cycles CPU cycles. Return number of cycles really executed + ****************************************************************************/ + +static int alpha8xxx_execute(const s_opcode *op_map,int cycles) +{ + unsigned opcode; + UINT8 pcptr; + + ALPHA8201_ICount = cycles; + +#if HANDLE_HALT_LINE + if(R.halt) + return cycles; +#endif + + /* setup address bank & fall safe */ + R.ix0.b.h = + R.ix1.b.h = + R.ix2.b.h = (R.pc.b.h &= 3); + + /* reset start hack */ + if(PC<0x20) + R.mb |= 0x08; + + do + { + if(R.mb & 0x08) + { + pcptr = M_RDMEM(0x001) & 0x1f; /* pointer of entry point */ + ALPHA8201_ICount -= C1; + + /* entry point scan phase */ + if( (pcptr&1) == 0) + { + /* EVEN , get PC low */ + R.pc.b.l = M_RDMEM(pcptr); +//mame_printf_debug("ALPHA8201 load PCL ENTRY=%02X PCL=%02X\n",pcptr, R.pc.b.l); + ALPHA8201_ICount -= C1; + M_WRMEM(0x001,pcptr+1); + continue; + } + + /* ODD , check HALT flag */ + R.mb = M_RDMEM(pcptr) & (0x08|0x03); + ALPHA8201_ICount -= C1; + + /* not entryaddress 000,001 */ + if(pcptr<2) R.mb |= 0x08; + + if(R.mb & 0x08) + { + /* HALTED current entry point . next one */ + pcptr = (pcptr+1)&0x1f; + M_WRMEM(0x001,pcptr); + ALPHA8201_ICount -= C1; + continue; + } + + /* goto run phase */ + M_JMP(R.pc.b.l); + +#if SHOW_ENTRY_POINT +logerror("ALPHA8201 START ENTRY=%02X PC=%03X\n",pcptr,PC); +mame_printf_debug("ALPHA8201 START ENTRY=%02X PC=%03X\n",pcptr,PC); +#endif + } + + /* run */ + R.PREVPC = PC; + CALL_MAME_DEBUG; + opcode =M_RDOP(PC); +#if TRACE_PC +mame_printf_debug("ALPHA8201: PC = %03x, opcode = %02x\n", PC, opcode); +#endif + PCL++; + inst_cycles = op_map[opcode].cycles; + (*(op_map[opcode].function))(); + ALPHA8201_ICount -= inst_cycles; + } while (ALPHA8201_ICount>0); + + return cycles - ALPHA8201_ICount; +} + +#if (HAS_ALPHA8201) +static int ALPHA8201_execute(int cycles) { return alpha8xxx_execute(opcode_8201,cycles); } +#endif + +#if (HAS_ALPHA8301) +static int ALPHA8301_execute(int cycles) { return alpha8xxx_execute(opcode_8301,cycles); } +#endif + +/**************************************************************************** + * Get all registers in given buffer + ****************************************************************************/ +static void ALPHA8201_get_context (void *dst) +{ + if( dst ) + *(ALPHA8201_Regs*)dst = R; +} + +/**************************************************************************** + * Set all registers to given values + ****************************************************************************/ +static void ALPHA8201_set_context (void *src) +{ + if( src ) + R = *(ALPHA8201_Regs*)src; +} + +/**************************************************************************** + * Set IRQ line state + ****************************************************************************/ +#if HANDLE_HALT_LINE +static void set_irq_line(int irqline, int state) +{ + if(irqline == INPUT_LINE_HALT) + { + R.halt = (state==ASSERT_LINE) ? 1 : 0; +/* mame_printf_debug("ALPHA8201 HALT %d\n",R.halt); */ + change_pc(PC); + } +} +#endif + +/************************************************************************** + * Generic set_info + **************************************************************************/ + +static void ALPHA8201_set_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { +#if HANDLE_HALT_LINE + case CPUINFO_INT_INPUT_STATE + INPUT_LINE_HALT: set_irq_line(INPUT_LINE_HALT, info->i); break; +#endif + case CPUINFO_INT_PC: + case CPUINFO_INT_REGISTER + ALPHA8201_PC: PC = info->i; break; + case CPUINFO_INT_SP: + case CPUINFO_INT_REGISTER + ALPHA8201_SP: M_WRMEM(0x001,info->i); break; + case CPUINFO_INT_REGISTER + ALPHA8201_RB: regPTR = (info->i & 7)<<3; break; + case CPUINFO_INT_REGISTER + ALPHA8201_MB: R.mb = info->i & 0x03; break; +#if 0 + case CPUINFO_INT_REGISTER + ALPHA8201_ZF: R.zf= info->i & 0x01; break; + case CPUINFO_INT_REGISTER + ALPHA8201_CF: R.cf= info->i & 0x01; break; +#endif + case CPUINFO_INT_REGISTER + ALPHA8201_IX0: IX0 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_IX1: IX1 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_IX2: IX2 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP0: LP0 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP1: LP1 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP2: LP2 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_A: R.A = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_B: R.B = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R0: R0 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R1: R1 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R2: R2 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R3: R3 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R4: R4 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R5: R5 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R6: R6 = info->i; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R7: R7 = info->i; break; + } +} + + + +/************************************************************************** + * Generic get_info + **************************************************************************/ + +/* 8201 and 8301 */ +static void alpha8xxx_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(R); 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_LE; break; + case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break; + case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; + case CPUINFO_INT_MAX_CYCLES: info->i = 16; break; + + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; 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 = 8; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 6; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; +#if HANDLE_HALT_LINE + case CPUINFO_INT_INPUT_STATE + INPUT_LINE_HALT: info->i = R.halt ? ASSERT_LINE : CLEAR_LINE; break; +#endif + case CPUINFO_INT_PREVIOUSPC: info->i = R.PREVPC; break; + case CPUINFO_INT_PC: + case CPUINFO_INT_REGISTER + ALPHA8201_PC: info->i = PC & 0x3ff; break; + case CPUINFO_INT_SP: + case CPUINFO_INT_REGISTER + ALPHA8201_SP: info->i = M_RDMEM(0x001); break; + case CPUINFO_INT_REGISTER + ALPHA8201_RB: info->i = regPTR; break; + case CPUINFO_INT_REGISTER + ALPHA8201_MB: info->i = R.mb; break; + case CPUINFO_INT_REGISTER + ALPHA8201_ZF: info->i = ZF; break; + case CPUINFO_INT_REGISTER + ALPHA8201_CF: info->i = CF; break; + case CPUINFO_INT_REGISTER + ALPHA8201_IX0: info->i = IX0; break; + case CPUINFO_INT_REGISTER + ALPHA8201_IX1: info->i = IX1; break; + case CPUINFO_INT_REGISTER + ALPHA8201_IX2: info->i = IX2; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP0: info->i = LP0; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP1: info->i = LP1; break; + case CPUINFO_INT_REGISTER + ALPHA8201_LP2: info->i = LP2; break; + case CPUINFO_INT_REGISTER + ALPHA8201_A: info->i = R.A; break; + case CPUINFO_INT_REGISTER + ALPHA8201_B: info->i = R.B; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R0: info->i = R0; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R1: info->i = R1; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R2: info->i = R2; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R3: info->i = R3; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R4: info->i = R4; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R5: info->i = R5; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R6: info->i = R6; break; + case CPUINFO_INT_REGISTER + ALPHA8201_R7: info->i = R7; break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case CPUINFO_PTR_SET_INFO: info->setinfo = ALPHA8201_set_info; break; + case CPUINFO_PTR_GET_CONTEXT: info->getcontext = ALPHA8201_get_context; break; + case CPUINFO_PTR_SET_CONTEXT: info->setcontext = ALPHA8201_set_context; break; + case CPUINFO_PTR_INIT: info->init = ALPHA8201_init; break; + case CPUINFO_PTR_RESET: info->reset = ALPHA8201_reset; break; + case CPUINFO_PTR_EXIT: info->exit = ALPHA8201_exit; break; + case CPUINFO_PTR_BURN: info->burn = NULL; break; +#ifdef MAME_DEBUG + case CPUINFO_PTR_DISASSEMBLE: info->disassemble = ALPHA8201_dasm; break; +#endif /* MAME_DEBUG */ + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ALPHA8201_ICount; break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "AlphaDenshi MCU"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "0.1"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright (C) 2006 by Tatsuyuki Satoh"); break; + case CPUINFO_STR_FLAGS: sprintf(info->s, "%c%c", CF?'C':'.',ZF?'Z':'.'); break; + case CPUINFO_STR_REGISTER + ALPHA8201_PC: sprintf(info->s, "PC:%03X", PC); break; + case CPUINFO_STR_REGISTER + ALPHA8201_SP: sprintf(info->s, "SP:%02X", M_RDMEM(0x001) ); break; + case CPUINFO_STR_REGISTER + ALPHA8201_RB: sprintf(info->s, "RB:%02X", regPTR>>3); break; + case CPUINFO_STR_REGISTER + ALPHA8201_MB: sprintf(info->s, "MB:%X", R.mb); break; +#if 0 + case CPUINFO_STR_REGISTER + ALPHA8201_ZF: sprintf(info->s, "ZF:%X", R.zf); break; + case CPUINFO_STR_REGISTER + ALPHA8201_CF: sprintf(info->s, "CF:%X", R.cf); break; +#endif + case CPUINFO_STR_REGISTER + ALPHA8201_IX0: sprintf(info->s, "IX0:%02X", IX0); break; + case CPUINFO_STR_REGISTER + ALPHA8201_IX1: sprintf(info->s, "IX1:%02X", IX1); break; + case CPUINFO_STR_REGISTER + ALPHA8201_IX2: sprintf(info->s, "IX2:%02X", IX2); break; + case CPUINFO_STR_REGISTER + ALPHA8201_LP0: sprintf(info->s, "LP0:%02X", LP0); break; + case CPUINFO_STR_REGISTER + ALPHA8201_LP1: sprintf(info->s, "LP1:%02X", LP1); break; + case CPUINFO_STR_REGISTER + ALPHA8201_LP2: sprintf(info->s, "LP2:%02X", LP2); break; + case CPUINFO_STR_REGISTER + ALPHA8201_A: sprintf(info->s, "A:%02X", R.A); break; + case CPUINFO_STR_REGISTER + ALPHA8201_B: sprintf(info->s, "B:%02X", R.B); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R0: sprintf(info->s, "R0:%02X", R0); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R1: sprintf(info->s, "R1:%02X", R1); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R2: sprintf(info->s, "R2:%02X", R2); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R3: sprintf(info->s, "R3:%02X", R3); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R4: sprintf(info->s, "R4:%02X", R4); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R5: sprintf(info->s, "R5:%02X", R5); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R6: sprintf(info->s, "R6:%02X", R6); break; + case CPUINFO_STR_REGISTER + ALPHA8201_R7: sprintf(info->s, "R7:%02X", R7); break; + } +} +#if (HAS_ALPHA8201) +void alpha8201_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_STR_NAME: strcpy(info->s, "ALPHA-8201"); break; + case CPUINFO_PTR_EXECUTE: info->execute = ALPHA8201_execute; break; + default: + /* 8201 / 8301 */ + alpha8xxx_get_info(state,info); + } +} +#endif + +#if (HAS_ALPHA8301) +void alpha8301_get_info(UINT32 state, cpuinfo *info) +{ + switch (state) + { + case CPUINFO_STR_NAME: strcpy(info->s, "ALPHA-8301"); break; + case CPUINFO_PTR_EXECUTE: info->execute = ALPHA8301_execute; break; + default: + /* 8201 / 8301 */ + alpha8xxx_get_info(state,info); + } +} +#endif diff --git a/src/emu/cpu/alph8201/alph8201.h b/src/emu/cpu/alph8201/alph8201.h new file mode 100644 index 00000000000..0457ea42ac8 --- /dev/null +++ b/src/emu/cpu/alph8201/alph8201.h @@ -0,0 +1,72 @@ + /**************************************************************************\ + * Alpha8201 Emulator * + * * + * Copyright (C) 2006 Tatsuyuki Satoh * + * Originally written for the MAME project. * + * * + * * + \**************************************************************************/ + +#ifndef _ALPH8202_H +#define _ALPH8202_H + +#ifndef INLINE +#define INLINE static inline +#endif + +#include "cpuintrf.h" + +enum { + ALPHA8201_PC=1, + ALPHA8201_SP, + ALPHA8201_RB, + ALPHA8201_MB, +// + ALPHA8201_CF, + ALPHA8201_ZF, +// + ALPHA8201_IX0, + ALPHA8201_IX1, + ALPHA8201_IX2, + ALPHA8201_LP0, + ALPHA8201_LP1, + ALPHA8201_LP2, + ALPHA8201_A, + ALPHA8201_B, +// + ALPHA8201_R0,ALPHA8201_R1,ALPHA8201_R2,ALPHA8201_R3, + ALPHA8201_R4,ALPHA8201_R5,ALPHA8201_R6,ALPHA8201_R7 +}; + +extern void ALPHA8201_get_info(UINT32 state, cpuinfo *info); +extern void ALPHA8301_get_info(UINT32 state, cpuinfo *info); + +/* + * Read a UINT8 from given memory location + */ +#define ALPHA8201_RDMEM(A) ((unsigned)program_read_byte_8(A)) + +/* + * Write a UINT8 to given memory location + */ +#define ALPHA8201_WRMEM(A,V) (program_write_byte_8(A,V)) + +/* + * ALPHA8201_RDOP() is identical to ALPHA8201_RDMEM() except it is used for reading + * opcodes. In case of system with memory mapped I/O, this function can be + * used to greatly speed up emulation + */ +#define ALPHA8201_RDOP(A) ((unsigned)cpu_readop(A)) + +/* + * ALPHA8201_RDOP_ARG() is identical to ALPHA8201_RDOP() except it is used for reading + * opcode arguments. This difference can be used to support systems that + * use different encoding mechanisms for opcodes and opcode arguments + */ +#define ALPHA8201_RDOP_ARG(A) ((unsigned)cpu_readop_arg(A)) + +#ifdef MAME_DEBUG +offs_t ALPHA8201_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram); +#endif + +#endif /* _ALPHA8201_H */ |