/******************************************************************** Hyperstone cpu emulator written by Pierpaolo Prazzoli All the types are compatible, but they have different IRAM size and cycles Hyperstone models: 16 bits - E1-16T - E1-16XT - E1-16XS - E1-16XSR 32bits - E1-32N or E1-32T - E1-32XN or E1-32XT - E1-32XS - E1-32XSR Hynix models: 16 bits - GMS30C2116 - GMS30C2216 32bits - GMS30C2132 - GMS30C2232 TODO: - some wrong cycle counts CHANGELOG: Pierpaolo Prazzoli - Fixed LDxx.N/P/S opcodes not to increment the destination register when it's the same as the source or "next source" one. Pierpaolo Prazzoli - Removed nested delays - Added better delay branch support - Fixed PC seen by a delay instruction, because a delay instruction should use the delayed PC (thus allowing the execution of software opcodes too) Tomasz Slanina - Fixed delayed branching for delay instructions longer than 2 bytes Pierpaolo Prazzoli - Added and fixed Timer without hack Tomasz Slanina - Fixed MULU/MULS - Fixed Carry in ADDC/SUBC Pierpaolo Prazzoli - Fixed software opcodes used as delay instructions - Added nested delays Tomasz Slanina - Added "undefined" C flag to shift left instructions Pierpaolo Prazzoli - Added interrupts-block for delay instructions - Fixed get_emu_code_addr - Added LDW.S and STW.S instructions - Fixed floating point opcodes Tomasz Slanina - interrputs after call and before frame are prohibited now - emulation of FCR register - Floating point opcodes (preliminary) - Fixed stack addressing in RET/FRAME opcodes - Fixed bug in SET_RS macro - Fixed bug in return opcode (S flag) - Added C/N flags calculation in add/adc/addi/adds/addsi and some shift opcodes - Added writeback to ROL - Fixed ROL/SAR/SARD/SHR/SHRD/SHL/SHLD opcode decoding (Local/Global regs) - Fixed I and T flag in RET opcode - Fixed XX/XM opcodes - Fixed MOV opcode, when RD = PC - Fixed execute_trap() - Fixed ST opcodes, when when RS = SR - Added interrupts - Fixed I/O addressing Pierpaolo Prazzoli - Fixed fetch - Fixed decode of hyperstone_xm opcode - Fixed 7 bits difference number in FRAME / RET instructions - Some debbugger fixes - Added generic registers decode function - Some other little fixes. MooglyGuy 29/03/2004 - Changed MOVI to use unsigned values instead of signed, correcting an ugly glitch when loading 32-bit immediates. Pierpaolo Prazzoli - Same fix in get_const MooglyGuy - 02/27/04 - Fixed delayed branching - const_val for CALL should always have bit 0 clear Pierpaolo Prazzoli - 02/25/04 - Fixed some wrong addresses to address local registers instead of memory - Fixed FRAME and RET instruction - Added preliminary I/O space - Fixed some load / store instructions Pierpaolo Prazzoli - 02/20/04 - Added execute_exception function - Added FL == 0 always interpreted as 16 Pierpaolo Prazzoli - 02/19/04 - Changed the reset to use the execute_trap(reset) which should be right to set the initiale state of the cpu - Added Trace exception - Set of T flag in RET instruction - Set I flag in interrupts entries and resetted by a RET instruction - Added correct set instruction for SR Pierpaolo Prazzoli - 10/26/03 - Changed get_lrconst to get_const and changed it to use the removed GET_CONST_RR macro. - Removed the High flag used in some opcodes, it should be used only in MOV and MOVI instruction. - Fixed MOV and MOVI instruction. - Set to 1 FP is SR register at reset. (From the doc: A Call, Trap or Software instruction increments the FP and sets FL to 6, thus creating a new stack frame with the length of 6 registers). MooglyGuy - 10/25/03 - Fixed CALL enough that it at least jumps to the right address, no word yet as to whether or not it's working enough to return. - Added get_lrconst() to get the const value for the CALL operand, since apparently using immediate_value() was wrong. The code is ugly, but it works properly. Vampire 1/2 now gets far enough to try to test its RAM. - Just from looking at it, CALL apparently doesn't frame properly. I'm not sure about FRAME, but perhaps it doesn't work properly - I'm not entirely positive. The return address when vamphalf's memory check routine is called at FFFFFD7E is stored in register L8, and then the RET instruction at the end of the routine uses L1 as the return address, so that might provide some clues as to how it works. - I'd almost be willing to bet money that there's no framing at all since the values in L0 - L15 as displayed by the debugger would change during a CALL or FRAME operation. I'll look when I'm in the mood. - The mood struck me, and I took a look at SET_L_REG and GET_L_REG. Apparently no matter what the current frame pointer is they'll always use local_regs[0] through local_regs[15]. MooglyGuy - 08/20/03 - Added H flag support for MOV and MOVI - Changed init routine to set S flag on boot. Apparently the CPU defaults to supervisor mode as opposed to user mode when it powers on, as shown by the vamphalf power-on routines. Makes sense, too, since if the machine booted in user mode, it would be impossible to get into supervisor mode. Pierpaolo Prazzoli - 08/19/03 - Added check for D_BIT and S_BIT where PC or SR must or must not be denoted. (movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul call, chk) MooglyGuy - 08/17/03 - Working on support for H flag, nothing quite done yet - Added trap Range Error for CHK PC, PC - Fixed relative jumps, they have to be taken from the opcode following the jump minstead of the jump opcode itself. Pierpaolo Prazzoli - 08/17/03 - Fixed get_pcrel() when OP & 0x80 is set. - Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if D_BIT is not set. (when pc is changed they are implicit branch) MooglyGuy - 08/17/03 - Implemented a crude hack to set FL in the SR to 6, since according to the docs that's supposed to happen each time a trap occurs, apparently including when the processor starts up. The 3rd opcode executed in vamphalf checks to see if the FL flag in SR 6, so it's apparently the "correct" behaviour despite the docs not saying anything on it. If FL is not 6, the branch falls through and encounters a CHK PC, L2, which at that point will always throw a range trap. The range trap vector contains 00000000 (CHK PC, PC), which according to the docs will always throw a range trap (which would effectively lock the system). This revealed a bug: CHK PC, PC apparently does not throw a range trap, which needs to be fixed. Now that the "correct" behaviour is hacked in with the FL flags, it reveals yet another bug in that the branch is interpreted as being +0x8700. This means that the PC then wraps around to 000082B0, give or take a few bytes. While it does indeed branch to valid code, I highly doubt that this is the desired effect. Check for signed/unsigned relative branch, maybe? MooglyGuy - 08/16/03 - Fixed the debugger at least somewhat so that it displays hex instead of decimal, and so that it disassembles opcodes properly. - Fixed hyperstone_execute() to increment PC *after* executing the opcode instead of before. This is probably why vamphalf was booting to fffffff8, but executing at fffffffa instead. - Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped after a trap - Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped after a branch - Changed hyperstone_movi to decrement PC by 2 when G0 (PC) is modified so that the next opcode isn't skipped after a branch - Changed hyperstone_movi to default to a UINT32 being moved into the register as opposed to a UINT8. This is wrong, the bit width is quite likely to be dependent on the n field in the Rimm instruction type. However, vamphalf uses MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode. What kind of CPU is this that it doesn't have an absolute jump in its branch instructions and you have to use an immediate MOV to do an abs. jump!? - Replaced usage of logerror() with smf's verboselog() *********************************************************************/ #include "debugger.h" #include "e132xs.h" #include "osd_cpu.h" static UINT8 (*hyp_cpu_read_byte)(offs_t address); static UINT16 (*hyp_cpu_read_half_word)(offs_t address); static UINT32 (*hyp_cpu_read_word)(offs_t address); static UINT32 (*hyp_cpu_read_io_word)(offs_t address); static void (*hyp_cpu_write_byte)(offs_t address, UINT8 data); static void (*hyp_cpu_write_half_word)(offs_t address, UINT16 data); static void (*hyp_cpu_write_word)(offs_t address, UINT32 data); static void (*hyp_cpu_write_io_word)(offs_t address, UINT32 data); int hyp_type_16bit; // set C in adds/addsi/subs/sums #define SETCARRYS 0 #define MISSIONCRAFT_FLAGS 1 static int hyperstone_ICount; static void hyperstone_chk(void); static void hyperstone_movd(void); static void hyperstone_divu(void); static void hyperstone_divs(void); static void hyperstone_xm(void); static void hyperstone_mask(void); static void hyperstone_sum(void); static void hyperstone_sums(void); static void hyperstone_cmp(void); static void hyperstone_mov(void); static void hyperstone_add(void); static void hyperstone_adds(void); static void hyperstone_cmpb(void); static void hyperstone_andn(void); static void hyperstone_or(void); static void hyperstone_xor(void); static void hyperstone_subc(void); static void hyperstone_not(void); static void hyperstone_sub(void); static void hyperstone_subs(void); static void hyperstone_addc(void); static void hyperstone_and(void); static void hyperstone_neg(void); static void hyperstone_negs(void); static void hyperstone_cmpi(void); static void hyperstone_movi(void); static void hyperstone_addi(void); static void hyperstone_addsi(void); static void hyperstone_cmpbi(void); static void hyperstone_andni(void); static void hyperstone_ori(void); static void hyperstone_xori(void); static void hyperstone_shrdi(void); static void hyperstone_shrd(void); static void hyperstone_shr(void); static void hyperstone_sardi(void); static void hyperstone_sard(void); static void hyperstone_sar(void); static void hyperstone_shldi(void); static void hyperstone_shld(void); static void hyperstone_shl(void); static void reserved(void); static void hyperstone_testlz(void); static void hyperstone_rol(void); static void hyperstone_ldxx1(void); static void hyperstone_ldxx2(void); static void hyperstone_stxx1(void); static void hyperstone_stxx2(void); static void hyperstone_shri(void); static void hyperstone_sari(void); static void hyperstone_shli(void); static void hyperstone_mulu(void); static void hyperstone_muls(void); static void hyperstone_set(void); static void hyperstone_mul(void); static void hyperstone_fadd(void); static void hyperstone_faddd(void); static void hyperstone_fsub(void); static void hyperstone_fsubd(void); static void hyperstone_fmul(void); static void hyperstone_fmuld(void); static void hyperstone_fdiv(void); static void hyperstone_fdivd(void); static void hyperstone_fcmp(void); static void hyperstone_fcmpd(void); static void hyperstone_fcmpu(void); static void hyperstone_fcmpud(void); static void hyperstone_fcvt(void); static void hyperstone_fcvtd(void); static void hyperstone_extend(void); static void hyperstone_do(void); static void hyperstone_ldwr(void); static void hyperstone_lddr(void); static void hyperstone_ldwp(void); static void hyperstone_lddp(void); static void hyperstone_stwr(void); static void hyperstone_stdr(void); static void hyperstone_stwp(void); static void hyperstone_stdp(void); static void hyperstone_dbv(void); static void hyperstone_dbnv(void); static void hyperstone_dbe(void); static void hyperstone_dbne(void); static void hyperstone_dbc(void); static void hyperstone_dbnc(void); static void hyperstone_dbse(void); static void hyperstone_dbht(void); static void hyperstone_dbn(void); static void hyperstone_dbnn(void); static void hyperstone_dble(void); static void hyperstone_dbgt(void); static void hyperstone_dbr(void); static void hyperstone_frame(void); static void hyperstone_call(void); static void hyperstone_bv(void); static void hyperstone_bnv(void); static void hyperstone_be(void); static void hyperstone_bne(void); static void hyperstone_bc(void); static void hyperstone_bnc(void); static void hyperstone_bse(void); static void hyperstone_bht(void); static void hyperstone_bn(void); static void hyperstone_bnn(void); static void hyperstone_ble(void); static void hyperstone_bgt(void); static void hyperstone_br(void); static void hyperstone_trap(void); /* Registers */ enum { E132XS_PC = 1, E132XS_SR, E132XS_FER, E132XS_G3, E132XS_G4, E132XS_G5, E132XS_G6, E132XS_G7, E132XS_G8, E132XS_G9, E132XS_G10, E132XS_G11, E132XS_G12, E132XS_G13, E132XS_G14, E132XS_G15, E132XS_G16, E132XS_G17, E132XS_SP, E132XS_UB, E132XS_BCR, E132XS_TPR, E132XS_TCR, E132XS_TR, E132XS_WCR, E132XS_ISR, E132XS_FCR, E132XS_MCR, E132XS_G28, E132XS_G29, E132XS_G30, E132XS_G31, E132XS_CL0, E132XS_CL1, E132XS_CL2, E132XS_CL3, E132XS_CL4, E132XS_CL5, E132XS_CL6, E132XS_CL7, E132XS_CL8, E132XS_CL9, E132XS_CL10,E132XS_CL11, E132XS_CL12,E132XS_CL13,E132XS_CL14,E132XS_CL15, E132XS_L0, E132XS_L1, E132XS_L2, E132XS_L3, E132XS_L4, E132XS_L5, E132XS_L6, E132XS_L7, E132XS_L8, E132XS_L9, E132XS_L10, E132XS_L11, E132XS_L12, E132XS_L13, E132XS_L14, E132XS_L15, E132XS_L16, E132XS_L17, E132XS_L18, E132XS_L19, E132XS_L20, E132XS_L21, E132XS_L22, E132XS_L23, E132XS_L24, E132XS_L25, E132XS_L26, E132XS_L27, E132XS_L28, E132XS_L29, E132XS_L30, E132XS_L31, E132XS_L32, E132XS_L33, E132XS_L34, E132XS_L35, E132XS_L36, E132XS_L37, E132XS_L38, E132XS_L39, E132XS_L40, E132XS_L41, E132XS_L42, E132XS_L43, E132XS_L44, E132XS_L45, E132XS_L46, E132XS_L47, E132XS_L48, E132XS_L49, E132XS_L50, E132XS_L51, E132XS_L52, E132XS_L53, E132XS_L54, E132XS_L55, E132XS_L56, E132XS_L57, E132XS_L58, E132XS_L59, E132XS_L60, E132XS_L61, E132XS_L62, E132XS_L63 }; /* Delay information */ struct _delay { INT32 delay_cmd; UINT32 delay_pc; }; /* Internal registers */ typedef struct { UINT32 global_regs[32]; UINT32 local_regs[64]; /* internal stuff */ UINT32 ppc; // previous pc UINT16 op; // opcode UINT32 trap_entry; // entry point to get trap address UINT8 n; INT32 delay_timer; int timer_clocks; struct _delay delay; int (*irq_callback)(int irqline); INT32 h_clear; INT32 instruction_length; INT32 intblock; } hyperstone_regs; static hyperstone_regs hyperstone; static struct regs_decode { UINT8 src, dst; // destination and source register code UINT32 src_value; // current source register value UINT32 next_src_value; // current next source register value UINT32 dst_value; // current destination register value UINT32 next_dst_value; // current next destination register value UINT8 sub_type; // sub type opcode (for DD and X_CODE bits) union { UINT32 u; INT32 s; } extra; // extra value such as immediate value, const, pcrel, ... void (*set_src_register)(UINT8 reg, UINT32 data); // set local / global source register void (*set_dst_register)(UINT8 reg, UINT32 data); // set local / global destination register UINT8 src_is_pc; UINT8 dst_is_pc; UINT8 src_is_sr; UINT8 dst_is_sr; UINT8 same_src_dst; UINT8 same_src_dstf; UINT8 same_srcf_dst; } current_regs; #define SREG current_regs.src_value #define SREGF current_regs.next_src_value #define DREG current_regs.dst_value #define DREGF current_regs.next_dst_value #define EXTRA_U current_regs.extra.u #define EXTRA_S current_regs.extra.s #define SET_SREG( _data_ ) (*current_regs.set_src_register)(current_regs.src, _data_) #define SET_SREGF( _data_ ) (*current_regs.set_src_register)(current_regs.src + 1, _data_) #define SET_DREG( _data_ ) (*current_regs.set_dst_register)(current_regs.dst, _data_) #define SET_DREGF( _data_ ) (*current_regs.set_dst_register)(current_regs.dst + 1, _data_) #define SRC_IS_PC current_regs.src_is_pc #define DST_IS_PC current_regs.dst_is_pc #define SRC_IS_SR current_regs.src_is_sr #define DST_IS_SR current_regs.dst_is_sr #define SAME_SRC_DST current_regs.same_src_dst #define SAME_SRC_DSTF current_regs.same_src_dstf #define SAME_SRCF_DST current_regs.same_srcf_dst #if (HAS_E116T || HAS_E116XT || HAS_E116XS || HAS_E116XSR || HAS_GMS30C2116 || HAS_GMS30C2216) static UINT32 program_read_dword_16be(offs_t address) { return (program_read_word_16be(address & ~1) << 16) | program_read_word_16be((address & ~1) + 2); } static void program_write_dword_16be(offs_t address, UINT32 data) { program_write_word_16be(address & ~1, (data & 0xffff0000)>>16); program_write_word_16be((address & ~1)+2, data & 0xffff); } static UINT32 io_read_dword_16be(offs_t address) { return (io_read_word_16be(address & ~1)<< 16) | io_read_word_16be((address & ~1) + 2); } static void io_write_dword_16be(offs_t address, UINT32 data) { io_write_word_16be(address & ~1, (data & 0xffff0000)>>16); io_write_word_16be((address & ~1)+2, data & 0xffff); } #endif /* Opcodes table */ static void (*hyperstone_op[0x100])(void) = { hyperstone_chk, hyperstone_chk, hyperstone_chk, hyperstone_chk, /* CHK - CHKZ - NOP */ hyperstone_movd, hyperstone_movd, hyperstone_movd, hyperstone_movd, /* MOVD - RET */ hyperstone_divu, hyperstone_divu, hyperstone_divu, hyperstone_divu, /* DIVU */ hyperstone_divs, hyperstone_divs, hyperstone_divs, hyperstone_divs, /* DIVS */ hyperstone_xm, hyperstone_xm, hyperstone_xm, hyperstone_xm, /* XMx - XXx */ hyperstone_mask, hyperstone_mask, hyperstone_mask, hyperstone_mask, /* MASK */ hyperstone_sum, hyperstone_sum, hyperstone_sum, hyperstone_sum, /* SUM */ hyperstone_sums, hyperstone_sums, hyperstone_sums, hyperstone_sums, /* SUMS */ hyperstone_cmp, hyperstone_cmp, hyperstone_cmp, hyperstone_cmp, /* CMP */ hyperstone_mov, hyperstone_mov, hyperstone_mov, hyperstone_mov, /* MOV */ hyperstone_add, hyperstone_add, hyperstone_add, hyperstone_add, /* ADD */ hyperstone_adds, hyperstone_adds, hyperstone_adds, hyperstone_adds, /* ADDS */ hyperstone_cmpb, hyperstone_cmpb, hyperstone_cmpb, hyperstone_cmpb, /* CMPB */ hyperstone_andn, hyperstone_andn, hyperstone_andn, hyperstone_andn, /* ANDN */ hyperstone_or, hyperstone_or, hyperstone_or, hyperstone_or, /* OR */ hyperstone_xor, hyperstone_xor, hyperstone_xor, hyperstone_xor, /* XOR */ hyperstone_subc, hyperstone_subc, hyperstone_subc, hyperstone_subc, /* SUBC */ hyperstone_not, hyperstone_not, hyperstone_not, hyperstone_not, /* NOT */ hyperstone_sub, hyperstone_sub, hyperstone_sub, hyperstone_sub, /* SUB */ hyperstone_subs, hyperstone_subs, hyperstone_subs, hyperstone_subs, /* SUBS */ hyperstone_addc, hyperstone_addc, hyperstone_addc, hyperstone_addc, /* ADDC */ hyperstone_and, hyperstone_and, hyperstone_and, hyperstone_and, /* AND */ hyperstone_neg, hyperstone_neg, hyperstone_neg, hyperstone_neg, /* NEG */ hyperstone_negs, hyperstone_negs, hyperstone_negs, hyperstone_negs, /* NEGS */ hyperstone_cmpi, hyperstone_cmpi, hyperstone_cmpi, hyperstone_cmpi, /* CMPI */ hyperstone_movi, hyperstone_movi, hyperstone_movi, hyperstone_movi, /* MOVI */ hyperstone_addi, hyperstone_addi, hyperstone_addi, hyperstone_addi, /* ADDI */ hyperstone_addsi,hyperstone_addsi,hyperstone_addsi, hyperstone_addsi, /* ADDSI */ hyperstone_cmpbi,hyperstone_cmpbi,hyperstone_cmpbi, hyperstone_cmpbi, /* CMPBI */ hyperstone_andni,hyperstone_andni,hyperstone_andni, hyperstone_andni, /* ANDNI */ hyperstone_ori, hyperstone_ori, hyperstone_ori, hyperstone_ori, /* ORI */ hyperstone_xori, hyperstone_xori, hyperstone_xori, hyperstone_xori, /* XORI */ hyperstone_shrdi,hyperstone_shrdi,hyperstone_shrd, hyperstone_shr, /* SHRDI, SHRD, SHR */ hyperstone_sardi,hyperstone_sardi,hyperstone_sard, hyperstone_sar, /* SARDI, SARD, SAR */ hyperstone_shldi,hyperstone_shldi,hyperstone_shld, hyperstone_shl, /* SHLDI, SHLD, SHL */ reserved, reserved, hyperstone_testlz,hyperstone_rol, /* RESERVED, TESTLZ, ROL */ hyperstone_ldxx1,hyperstone_ldxx1,hyperstone_ldxx1, hyperstone_ldxx1, /* LDxx.D/A/IOD/IOA */ hyperstone_ldxx2,hyperstone_ldxx2,hyperstone_ldxx2, hyperstone_ldxx2, /* LDxx.N/S */ hyperstone_stxx1,hyperstone_stxx1,hyperstone_stxx1, hyperstone_stxx1, /* STxx.D/A/IOD/IOA */ hyperstone_stxx2,hyperstone_stxx2,hyperstone_stxx2, hyperstone_stxx2, /* STxx.N/S */ hyperstone_shri, hyperstone_shri, hyperstone_shri, hyperstone_shri, /* SHRI */ hyperstone_sari, hyperstone_sari, hyperstone_sari, hyperstone_sari, /* SARI */ hyperstone_shli, hyperstone_shli, hyperstone_shli, hyperstone_shli, /* SHLI */ reserved, reserved, reserved, reserved, /* RESERVED */ hyperstone_mulu, hyperstone_mulu, hyperstone_mulu, hyperstone_mulu, /* MULU */ hyperstone_muls, hyperstone_muls, hyperstone_muls, hyperstone_muls, /* MULS */ hyperstone_set, hyperstone_set, hyperstone_set, hyperstone_set, /* SETxx - SETADR - FETCH */ hyperstone_mul, hyperstone_mul, hyperstone_mul, hyperstone_mul, /* MUL */ hyperstone_fadd, hyperstone_faddd,hyperstone_fsub, hyperstone_fsubd, /* FADD, FADDD, FSUB, FSUBD */ hyperstone_fmul, hyperstone_fmuld,hyperstone_fdiv, hyperstone_fdivd, /* FMUL, FMULD, FDIV, FDIVD */ hyperstone_fcmp, hyperstone_fcmpd,hyperstone_fcmpu, hyperstone_fcmpud, /* FCMP, FCMPD, FCMPU, FCMPUD */ hyperstone_fcvt, hyperstone_fcvtd,hyperstone_extend,hyperstone_do, /* FCVT, FCVTD, EXTEND, DO */ hyperstone_ldwr, hyperstone_ldwr, hyperstone_lddr, hyperstone_lddr, /* LDW.R, LDD.R */ hyperstone_ldwp, hyperstone_ldwp, hyperstone_lddp, hyperstone_lddp, /* LDW.P, LDD.P */ hyperstone_stwr, hyperstone_stwr, hyperstone_stdr, hyperstone_stdr, /* STW.R, STD.R */ hyperstone_stwp, hyperstone_stwp, hyperstone_stdp, hyperstone_stdp, /* STW.P, STD.P */ hyperstone_dbv, hyperstone_dbnv, hyperstone_dbe, hyperstone_dbne, /* DBV, DBNV, DBE, DBNE */ hyperstone_dbc, hyperstone_dbnc, hyperstone_dbse, hyperstone_dbht, /* DBC, DBNC, DBSE, DBHT */ hyperstone_dbn, hyperstone_dbnn, hyperstone_dble, hyperstone_dbgt, /* DBN, DBNN, DBLE, DBGT */ hyperstone_dbr, hyperstone_frame,hyperstone_call, hyperstone_call, /* DBR, FRAME, CALL */ hyperstone_bv, hyperstone_bnv, hyperstone_be, hyperstone_bne, /* BV, BNV, BE, BNE */ hyperstone_bc, hyperstone_bnc, hyperstone_bse, hyperstone_bht, /* BC, BNC, BSE, BHT */ hyperstone_bn, hyperstone_bnn, hyperstone_ble, hyperstone_bgt, /* BN, BNN, BLE, BGT */ hyperstone_br, hyperstone_trap, hyperstone_trap, hyperstone_trap /* BR, TRAPxx - TRAP */ }; // 4Kb IRAM (On-Chip Memory) #if (HAS_E116T || HAS_GMS30C2116) static ADDRESS_MAP_START( e116_4k_iram_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0xc0000000, 0xc0000fff) AM_RAM AM_MIRROR(0x1ffff000) ADDRESS_MAP_END #endif #if (HAS_E132N || HAS_E132T || HAS_GMS30C2132) static ADDRESS_MAP_START( e132_4k_iram_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0xc0000000, 0xc0000fff) AM_RAM AM_MIRROR(0x1ffff000) ADDRESS_MAP_END #endif // 8Kb IRAM (On-Chip Memory) #if (HAS_E116XT || HAS_GMS30C2216) static ADDRESS_MAP_START( e116_8k_iram_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0xc0000000, 0xc0001fff) AM_RAM AM_MIRROR(0x1fffe000) ADDRESS_MAP_END #endif #if (HAS_E132XN || HAS_E132XT || HAS_GMS30C2232) static ADDRESS_MAP_START( e132_8k_iram_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0xc0000000, 0xc0001fff) AM_RAM AM_MIRROR(0x1fffe000) ADDRESS_MAP_END #endif // 16Kb IRAM (On-Chip Memory) #if (HAS_E116XS || HAS_E116XSR) static ADDRESS_MAP_START( e116_16k_iram_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0xc0000000, 0xc0003fff) AM_RAM AM_MIRROR(0x1fffc000) ADDRESS_MAP_END #endif #if (HAS_E132XS || HAS_E132XSR) static ADDRESS_MAP_START( e132_16k_iram_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0xc0000000, 0xc0003fff) AM_RAM AM_MIRROR(0x1fffc000) ADDRESS_MAP_END #endif /* Return the entry point for a determinated trap */ static UINT32 get_trap_addr(UINT8 trapno) { UINT32 addr; if( hyperstone.trap_entry == 0xffffff00 ) /* @ MEM3 */ { addr = trapno * 4; } else { addr = (63 - trapno) * 4; } addr |= hyperstone.trap_entry; return addr; } /* Return the entry point for a determinated emulated code (the one for "extend" opcode is reserved) */ static UINT32 get_emu_code_addr(UINT8 num) /* num is OP */ { UINT32 addr; if( hyperstone.trap_entry == 0xffffff00 ) /* @ MEM3 */ { addr = (hyperstone.trap_entry - 0x100) | ((num & 0xf) << 4); } else { addr = hyperstone.trap_entry | (0x10c | ((0xcf - num) << 4)); } return addr; } static void hyperstone_set_trap_entry(int which) { switch( which ) { case E132XS_ENTRY_MEM0: hyperstone.trap_entry = 0x00000000; break; case E132XS_ENTRY_MEM1: hyperstone.trap_entry = 0x40000000; break; case E132XS_ENTRY_MEM2: hyperstone.trap_entry = 0x80000000; break; case E132XS_ENTRY_MEM3: hyperstone.trap_entry = 0xffffff00; break; case E132XS_ENTRY_IRAM: hyperstone.trap_entry = 0xc0000000; break; default: logerror("Set entry point to a reserved value: %d\n", which); break; } } #define OP hyperstone.op #define PPC hyperstone.ppc //previous pc #define PC hyperstone.global_regs[0] //Program Counter #define SR hyperstone.global_regs[1] //Status Register #define FER hyperstone.global_regs[2] //Floating-Point Exception Register // 03 - 15 General Purpose Registers // 16 - 17 Reserved #define SP hyperstone.global_regs[18] //Stack Pointer #define UB hyperstone.global_regs[19] //Upper Stack Bound #define BCR hyperstone.global_regs[20] //Bus Control Register #define TPR hyperstone.global_regs[21] //Timer Prescaler Register #define TCR hyperstone.global_regs[22] //Timer Compare Register #define TR hyperstone.global_regs[23] //Timer Register #define WCR hyperstone.global_regs[24] //Watchdog Compare Register #define ISR hyperstone.global_regs[25] //Input Status Register #define FCR hyperstone.global_regs[26] //Function Control Register #define MCR hyperstone.global_regs[27] //Memory Control Register // 28 - 31 Reserved /* SR flags */ #define GET_C ( SR & 0x00000001) // bit 0 //CARRY #define GET_Z ((SR & 0x00000002)>>1) // bit 1 //ZERO #define GET_N ((SR & 0x00000004)>>2) // bit 2 //NEGATIVE #define GET_V ((SR & 0x00000008)>>3) // bit 3 //OVERFLOW #define GET_M ((SR & 0x00000010)>>4) // bit 4 //CACHE-MODE #define GET_H ((SR & 0x00000020)>>5) // bit 5 //HIGHGLOBAL // bit 6 RESERVED (always 0) #define GET_I ((SR & 0x00000080)>>7) // bit 7 //INTERRUPT-MODE #define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable #define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode #define GET_L ((SR & 0x00008000)>>15) // bit 15 //INTERRUPT-LOCK #define GET_T ((SR & 0x00010000)>>16) // bit 16 //TRACE-MODE #define GET_P ((SR & 0x00020000)>>17) // bit 17 //TRACE PENDING #define GET_S ((SR & 0x00040000)>>18) // bit 18 //SUPERVISOR STATE #define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH /* if FL is zero it is always interpreted as 16 */ #define GET_FL ((SR & 0x01e00000) ? ((SR & 0x01e00000)>>21) : 16) // bits 24 - 21 //FRAME LENGTH #define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER #define SET_C(val) (SR = (SR & ~0x00000001) | (val)) #define SET_Z(val) (SR = (SR & ~0x00000002) | ((val) << 1)) #define SET_N(val) (SR = (SR & ~0x00000004) | ((val) << 2)) #define SET_V(val) (SR = (SR & ~0x00000008) | ((val) << 3)) #define SET_M(val) (SR = (SR & ~0x00000010) | ((val) << 4)) #define SET_H(val) (SR = (SR & ~0x00000020) | ((val) << 5)) #define SET_I(val) (SR = (SR & ~0x00000080) | ((val) << 7)) #define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8)) #define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13)) #define SET_L(val) (SR = (SR & ~0x00008000) | ((val) << 15)) #define SET_T(val) (SR = (SR & ~0x00010000) | ((val) << 16)) #define SET_P(val) (SR = (SR & ~0x00020000) | ((val) << 17)) #define SET_S(val) (SR = (SR & ~0x00040000) | ((val) << 18)) #define SET_ILC(val) (SR = (SR & ~0x00180000) | ((val) << 19)) #define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21)) #define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25)) #define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0 #define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0 #define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0 #define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed #define CHECK_C(x) (SR = (SR & ~0x00000001) | (((x) & (((UINT64)1) << 32)) ? 1 : 0 )) #define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) ? 8: 0)) #define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) ? 8: 0)) #define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? 8: 0)) /* FER flags */ #define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions #define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions //other bits are reversed, in particular 7 - 5 for the operating system. //the user program can only changes the above 2 flags static UINT32 get_global_register(UINT8 code) { /* if( code >= 16 ) { switch( code ) { case 16: case 17: case 28: case 29: case 30: case 31: mame_printf_debug("read _Reserved_ Global Register %d @ %08X\n",code,PC); break; case BCR_REGISTER: mame_printf_debug("read write-only BCR register @ %08X\n",PC); return 0; case TPR_REGISTER: mame_printf_debug("read write-only TPR register @ %08X\n",PC); return 0; case FCR_REGISTER: mame_printf_debug("read write-only FCR register @ %08X\n",PC); return 0; case MCR_REGISTER: mame_printf_debug("read write-only MCR register @ %08X\n",PC); return 0; } } */ return hyperstone.global_regs[code]; } static void set_global_register(UINT8 code, UINT32 val) { //TODO: add correct FER set instruction if( code == PC_REGISTER ) { SET_PC(val); change_pc(PC); } else if( code == SR_REGISTER ) { SET_LOW_SR(val); // only a RET instruction can change the full content of SR SR &= ~0x40; //reserved bit 6 always zero } else { if( code != ISR_REGISTER ) hyperstone.global_regs[code] = val; else logerror("Written to ISR register. PC = %08X\n", PC); //are these set only when privilege bit is set? if( code >= 16 ) { switch( code ) { case 18: SET_SP(val); break; case 19: SET_UB(val); break; /* case ISR_REGISTER: mame_printf_debug("written %08X to read-only ISR register\n",val); break; case 22: // mame_printf_debug("written %08X to TCR register\n",val); break; case 23: // mame_printf_debug("written %08X to TR register\n",val); break; case 24: // mame_printf_debug("written %08X to WCR register\n",val); break; case 16: case 17: case 28: case 29: case 30: case 31: mame_printf_debug("written %08X to _Reserved_ Global Register %d\n",val,code); break; case BCR_REGISTER: break; */ case TPR_REGISTER: hyperstone.n = (val & 0xff0000) >> 16; if(!(val & 0x80000000)) /* change immediately */ { hyperstone.delay_timer = 0; hyperstone.timer_clocks = hyperstone.n + 2; } else { hyperstone.delay_timer = 1; } break; /* case FCR_REGISTER: switch((val & 0x3000)>>12) { case 0: mame_printf_debug("IO3 interrupt mode\n"); break; case 1: mame_printf_debug("IO3 timing mode\n"); break; case 2: mame_printf_debug("watchdog mode\n"); break; case 3: // IO3 standard mode break; } break; */ case MCR_REGISTER: // bits 14..12 EntryTableMap hyperstone_set_trap_entry((val & 0x7000) >> 12); break; } } } } static void set_local_register(UINT8 code, UINT32 val) { UINT8 new_code = (code + GET_FP) % 64; hyperstone.local_regs[new_code] = val; } #define GET_ABS_L_REG(code) hyperstone.local_regs[code] #define SET_L_REG(code, val) set_local_register(code, val) #define SET_ABS_L_REG(code, val) hyperstone.local_regs[code] = val #define GET_G_REG(code) get_global_register(code) #define SET_G_REG(code, val) set_global_register(code, val) #define S_BIT ((OP & 0x100) >> 8) #define N_BIT S_BIT #define D_BIT ((OP & 0x200) >> 9) #define N_VALUE ((N_BIT << 4) | (OP & 0x0f)) #define DST_CODE ((OP & 0xf0) >> 4) #define SRC_CODE (OP & 0x0f) #define SIGN_BIT(val) ((val & 0x80000000) >> 31) #define LOCAL 1 static void decode_source(int local, int hflag) { if(local) { UINT8 code = current_regs.src; current_regs.set_src_register = set_local_register; code = (current_regs.src + GET_FP) % 64; // registers offset by frame pointer SREG = hyperstone.local_regs[code]; code = (current_regs.src + 1 + GET_FP) % 64; SREGF = hyperstone.local_regs[code]; } else { current_regs.set_src_register = set_global_register; if(hflag) current_regs.src += hflag * 16; SREG = hyperstone.global_regs[current_regs.src]; /* bound safe */ if(current_regs.src != 15 && current_regs.src != 31) SREGF = hyperstone.global_regs[current_regs.src + 1]; if(current_regs.src == PC_REGISTER) SRC_IS_PC = 1; else if(current_regs.src == SR_REGISTER) SRC_IS_SR = 1; else if( current_regs.src == BCR_REGISTER || current_regs.src == TPR_REGISTER || current_regs.src == FCR_REGISTER || current_regs.src == MCR_REGISTER ) { SREG = 0; // write-only registers } else if( current_regs.src == ISR_REGISTER ) mame_printf_debug("read src ISR. PC = %08X\n",PPC); } } static void decode_dest(int local, int hflag) { if(local) { UINT8 code = current_regs.dst; current_regs.set_dst_register = set_local_register; code = (current_regs.dst + GET_FP) % 64; // registers offset by frame pointer DREG = hyperstone.local_regs[code]; code = (current_regs.dst + 1 + GET_FP) % 64; DREGF = hyperstone.local_regs[code]; } else { current_regs.set_dst_register = set_global_register; if(hflag) current_regs.dst += hflag * 16; DREG = hyperstone.global_regs[current_regs.dst]; /* bound safe */ if(current_regs.dst != 15 && current_regs.dst != 31) DREGF = hyperstone.global_regs[current_regs.dst + 1]; if(current_regs.dst == PC_REGISTER) DST_IS_PC = 1; else if(current_regs.dst == SR_REGISTER) DST_IS_SR = 1; else if( current_regs.src == ISR_REGISTER ) mame_printf_debug("read dst ISR. PC = %08X\n",PPC); } } INLINE void decode_RR(void) { current_regs.src = SRC_CODE; current_regs.dst = DST_CODE; decode_source(S_BIT, 0); decode_dest(D_BIT, 0); if( SRC_CODE == DST_CODE && S_BIT == D_BIT ) SAME_SRC_DST = 1; if( S_BIT == LOCAL && D_BIT == LOCAL ) { if( SRC_CODE == ((DST_CODE + 1) % 64) ) SAME_SRC_DSTF = 1; if( ((SRC_CODE + 1) % 64) == DST_CODE ) SAME_SRCF_DST = 1; } else if( S_BIT == 0 && D_BIT == 0 ) { if( SRC_CODE == (DST_CODE + 1) ) SAME_SRC_DSTF = 1; if( (SRC_CODE + 1) == DST_CODE ) SAME_SRCF_DST = 1; } } INLINE void decode_LL(void) { current_regs.src = SRC_CODE; current_regs.dst = DST_CODE; decode_source(LOCAL, 0); decode_dest(LOCAL, 0); if( SRC_CODE == DST_CODE ) SAME_SRC_DST = 1; if( SRC_CODE == ((DST_CODE + 1) % 64) ) SAME_SRC_DSTF = 1; } INLINE void decode_LR(void) { current_regs.src = SRC_CODE; current_regs.dst = DST_CODE; decode_source(S_BIT, 0); decode_dest(LOCAL, 0); if( ((SRC_CODE + 1) % 64) == DST_CODE && S_BIT == LOCAL ) SAME_SRCF_DST = 1; } INLINE void check_delay_PC(void) { // if PC is used in a delay instruction, the delayed PC should be used if( hyperstone.delay.delay_cmd == DELAY_EXECUTE ) { PC = hyperstone.delay.delay_pc; hyperstone.delay.delay_cmd = NO_DELAY; } } INLINE void decode_immediate(void) { switch( N_VALUE ) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: EXTRA_U = N_VALUE; break; case 17: hyperstone.instruction_length = 3; EXTRA_U = (READ_OP(PC) << 16) | READ_OP(PC + 2); PC += 4; break; case 18: hyperstone.instruction_length = 2; EXTRA_U = READ_OP(PC); PC += 2; break; case 19: hyperstone.instruction_length = 2; EXTRA_U = 0xffff0000 | READ_OP(PC); PC += 2; break; case 20: EXTRA_U = 32; // bit 5 = 1, others = 0 break; case 21: EXTRA_U = 64; // bit 6 = 1, others = 0 break; case 22: EXTRA_U = 128; // bit 7 = 1, others = 0 break; case 23: EXTRA_U = 0x80000000; // bit 31 = 1, others = 0 (2 at the power of 31) break; case 24: EXTRA_U = -8; break; case 25: EXTRA_U = -7; break; case 26: EXTRA_U = -6; break; case 27: EXTRA_U = -5; break; case 28: EXTRA_U = -4; break; case 29: EXTRA_U = -3; break; case 30: EXTRA_U = -2; break; case 31: EXTRA_U = -1; break; } } INLINE void decode_const(void) { UINT16 imm_1 = READ_OP(PC); PC += 2; hyperstone.instruction_length = 2; if( E_BIT(imm_1) ) { UINT16 imm_2 = READ_OP(PC); PC += 2; hyperstone.instruction_length = 3; EXTRA_S = imm_2; EXTRA_S |= ((imm_1 & 0x3fff) << 16); if( S_BIT_CONST(imm_1) ) { EXTRA_S |= 0xc0000000; } } else { EXTRA_S = imm_1 & 0x3fff; if( S_BIT_CONST(imm_1) ) { EXTRA_S |= 0xffffc000; } } } INLINE void decode_pcrel(void) { if( OP & 0x80 ) { UINT16 next = READ_OP(PC); PC += 2; hyperstone.instruction_length = 2; EXTRA_S = (OP & 0x7f) << 16; EXTRA_S |= (next & 0xfffe); if( next & 1 ) EXTRA_S |= 0xff800000; } else { EXTRA_S = OP & 0x7e; if( OP & 1 ) EXTRA_S |= 0xffffff80; } } INLINE void decode_dis(void) { UINT16 next_1 = READ_OP(PC); PC += 2; hyperstone.instruction_length = 2; current_regs.sub_type = DD(next_1); if( E_BIT(next_1) ) { UINT16 next_2 = READ_OP(PC); PC += 2; hyperstone.instruction_length = 3; EXTRA_S = next_2; EXTRA_S |= ((next_1 & 0xfff) << 16); if( S_BIT_CONST(next_1) ) { EXTRA_S |= 0xf0000000; } } else { EXTRA_S = next_1 & 0xfff; if( S_BIT_CONST(next_1) ) { EXTRA_S |= 0xfffff000; } } } INLINE void decode_lim(void) { UINT32 next = READ_OP(PC); PC += 2; hyperstone.instruction_length = 2; current_regs.sub_type = X_CODE(next); if( E_BIT(next) ) { EXTRA_U = ((next & 0xfff) << 16) | READ_OP(PC); PC += 2; hyperstone.instruction_length = 3; } else { EXTRA_U = next & 0xfff; } } /* used in the jumptable */ INLINE void RRdecode(void) { check_delay_PC(); decode_RR(); } INLINE void RRlimdecode(void) { decode_lim(); check_delay_PC(); decode_RR(); } INLINE void RRconstdecode(void) { decode_const(); check_delay_PC(); decode_RR(); } INLINE void RRdisdecode(void) { decode_dis(); check_delay_PC(); decode_RR(); } INLINE void RRdecodewithHflag(void) { check_delay_PC(); current_regs.src = SRC_CODE; current_regs.dst = DST_CODE; decode_source(S_BIT, GET_H); decode_dest(D_BIT, GET_H); if(GET_H) if(S_BIT == 0 && D_BIT == 0) popmessage("MOV with hflag and 2 GRegs! PC = %08X\n",PPC); } INLINE void Rimmdecode(void) { decode_immediate(); check_delay_PC(); current_regs.dst = DST_CODE; decode_dest(D_BIT, 0); } INLINE void Rndecode(void) { check_delay_PC(); current_regs.dst = DST_CODE; decode_dest(D_BIT, 0); } INLINE void RimmdecodewithHflag(void) { decode_immediate(); check_delay_PC(); current_regs.dst = DST_CODE; decode_dest(D_BIT, GET_H); } INLINE void Lndecode(void) { check_delay_PC(); current_regs.dst = DST_CODE; decode_dest(LOCAL, 0); } INLINE void LLdecode(void) { check_delay_PC(); decode_LL(); } INLINE void LLextdecode(void) { hyperstone.instruction_length = 2; EXTRA_U = READ_OP(PC); PC += 2; check_delay_PC(); decode_LL(); } INLINE void LRdecode(void) { check_delay_PC(); decode_LR(); } INLINE void LRconstdecode(void) { decode_const(); check_delay_PC(); decode_LR(); } INLINE void PCreldecode(void) { decode_pcrel(); check_delay_PC(); } INLINE void PCadrdecode(void) { check_delay_PC(); } INLINE void no_decode(void) { } /* Decode helper table */ static void (*hyperstone_decode[0x100])(void) = { /*00*/ RRdecode, RRdecode, RRdecode, RRdecode, /* CHK - CHKZ - NOP */ /*04*/ RRdecode, RRdecode, RRdecode, RRdecode, /* MOVD - RET */ /*08*/ RRdecode, RRdecode, RRdecode, RRdecode, /* DIVU */ /*0c*/ RRdecode, RRdecode, RRdecode, RRdecode, /* DIVS */ /*10*/ RRlimdecode, RRlimdecode, RRlimdecode, RRlimdecode, /* XMx - XXx */ /*14*/ RRconstdecode, RRconstdecode, RRconstdecode, RRconstdecode, /* MASK */ /*18*/ RRconstdecode, RRconstdecode, RRconstdecode, RRconstdecode, /* SUM */ /*1c*/ RRconstdecode, RRconstdecode, RRconstdecode, RRconstdecode, /* SUMS */ /*20*/ RRdecode, RRdecode, RRdecode, RRdecode, /* CMP */ /*24*/ RRdecodewithHflag, RRdecodewithHflag, RRdecodewithHflag, RRdecodewithHflag, /* MOV */ /*28*/ RRdecode, RRdecode, RRdecode, RRdecode, /* ADD */ /*2c*/ RRdecode, RRdecode, RRdecode, RRdecode, /* ADDS */ /*30*/ RRdecode, RRdecode, RRdecode, RRdecode, /* CMPB */ /*34*/ RRdecode, RRdecode, RRdecode, RRdecode, /* ANDN */ /*38*/ RRdecode, RRdecode, RRdecode, RRdecode, /* OR */ /*3c*/ RRdecode, RRdecode, RRdecode, RRdecode, /* XOR */ /*40*/ RRdecode, RRdecode, RRdecode, RRdecode, /* SUBC */ /*44*/ RRdecode, RRdecode, RRdecode, RRdecode, /* NOT */ /*48*/ RRdecode, RRdecode, RRdecode, RRdecode, /* SUB */ /*4c*/ RRdecode, RRdecode, RRdecode, RRdecode, /* SUBS */ /*50*/ RRdecode, RRdecode, RRdecode, RRdecode, /* ADDC */ /*54*/ RRdecode, RRdecode, RRdecode, RRdecode, /* AND */ /*58*/ RRdecode, RRdecode, RRdecode, RRdecode, /* NEG */ /*5c*/ RRdecode, RRdecode, RRdecode, RRdecode, /* NEGS */ /*60*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* CMPI */ /*64*/ RimmdecodewithHflag, RimmdecodewithHflag, RimmdecodewithHflag, RimmdecodewithHflag, /* MOVI */ /*68*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* ADDI */ /*6c*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* ADDSI */ /*70*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* CMPBI */ /*74*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* ANDNI */ /*78*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* ORI */ /*7c*/ Rimmdecode, Rimmdecode, Rimmdecode, Rimmdecode, /* XORI */ /*80*/ Lndecode, Lndecode, LLdecode, LLdecode, /* SHRDI, SHRD, SHR */ /*84*/ Lndecode, Lndecode, LLdecode, LLdecode, /* SARDI, SARD, SAR */ /*88*/ Lndecode, Lndecode, LLdecode, LLdecode, /* SHLDI, SHLD, SHL */ /*8c*/ no_decode, no_decode, LLdecode, LLdecode, /* RESERVED, TESTLZ, ROL */ /*90*/ RRdisdecode, RRdisdecode, RRdisdecode, RRdisdecode, /* LDxx.D/A/IOD/IOA */ /*94*/ RRdisdecode, RRdisdecode, RRdisdecode, RRdisdecode, /* LDxx.N/S */ /*98*/ RRdisdecode, RRdisdecode, RRdisdecode, RRdisdecode, /* STxx.D/A/IOD/IOA */ /*9c*/ RRdisdecode, RRdisdecode, RRdisdecode, RRdisdecode, /* STxx.N/S */ /*a0*/ Rndecode, Rndecode, Rndecode, Rndecode, /* SHRI */ /*a4*/ Rndecode, Rndecode, Rndecode, Rndecode, /* SARI */ /*a8*/ Rndecode, Rndecode, Rndecode, Rndecode, /* SHLI */ /*ac*/ no_decode, no_decode, no_decode, no_decode, /* RESERVED */ /*b0*/ RRdecode, RRdecode, RRdecode, RRdecode, /* MULU */ /*b4*/ RRdecode, RRdecode, RRdecode, RRdecode, /* MULS */ /*b8*/ Rndecode, Rndecode, Rndecode, Rndecode, /* SETxx - SETADR - FETCH */ /*bc*/ RRdecode, RRdecode, RRdecode, RRdecode, /* MUL */ /*c0*/ LLdecode, LLdecode, LLdecode, LLdecode, /* FADD, FADDD, FSUB, FSUBD */ /*c4*/ LLdecode, LLdecode, LLdecode, LLdecode, /* FMUL, FMULD, FDIV, FDIVD */ /*c8*/ LLdecode, LLdecode, LLdecode, LLdecode, /* FCMP, FCMPD, FCMPU, FCMPUD */ /*cc*/ LLdecode, LLdecode, LLextdecode, LLdecode, /* FCVT, FCVTD, EXTEND, DO */ /*d0*/ LRdecode, LRdecode, LRdecode, LRdecode, /* LDW.R, LDD.R */ /*d4*/ LRdecode, LRdecode, LRdecode, LRdecode, /* LDW.P, LDD.P */ /*d8*/ LRdecode, LRdecode, LRdecode, LRdecode, /* STW.R, STD.R */ /*dc*/ LRdecode, LRdecode, LRdecode, LRdecode, /* STW.P, STD.P */ /*e0*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* DBV, DBNV, DBE, DBNE */ /*e4*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* DBC, DBNC, DBSE, DBHT */ /*e8*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* DBN, DBNN, DBLE, DBGT */ /*ec*/ PCreldecode, LLdecode, LRconstdecode, LRconstdecode, /* DBR, FRAME, CALL */ /*f0*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* BV, BNV, BE, BNE */ /*f4*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* BC, BNC, BSE, BHT */ /*f8*/ PCreldecode, PCreldecode, PCreldecode, PCreldecode, /* BN, BNN, BLE, BGT */ /*fc*/ PCreldecode, PCadrdecode, PCadrdecode, PCadrdecode /* BR, TRAPxx - TRAP */ }; INLINE void execute_br(void) { PPC = PC; PC += EXTRA_S; change_pc(PC); SET_M(0); hyperstone_ICount -= 2; } INLINE void execute_dbr(void) { hyperstone.delay.delay_cmd = DELAY_TAKEN; hyperstone.delay.delay_pc = PC + EXTRA_S; hyperstone.intblock = 3; } static void execute_trap(UINT32 addr) { UINT8 reg; UINT32 oldSR; reg = GET_FP + GET_FL; SET_ILC(hyperstone.instruction_length & 3); oldSR = SR; SET_FL(6); SET_FP(reg); SET_L_REG(0, (PC & 0xfffffffe) | GET_S); SET_L_REG(1, oldSR); SET_M(0); SET_T(0); SET_L(1); SET_S(1); PPC = PC; PC = addr; change_pc(PC); hyperstone_ICount -= 2; } static void execute_int(UINT32 addr) { UINT8 reg; UINT32 oldSR; reg = GET_FP + GET_FL; SET_ILC(hyperstone.instruction_length & 3); oldSR = SR; SET_FL(2); SET_FP(reg); SET_L_REG(0, (PC & 0xfffffffe) | GET_S); SET_L_REG(1, oldSR); SET_M(0); SET_T(0); SET_L(1); SET_S(1); SET_I(1); PPC = PC; PC = addr; change_pc(PC); hyperstone_ICount -= 2; } /* TODO: mask Parity Error and Extended Overflow exceptions */ static void execute_exception(UINT32 addr) { UINT8 reg; UINT32 oldSR; reg = GET_FP + GET_FL; SET_ILC(hyperstone.instruction_length & 3); oldSR = SR; SET_FP(reg); SET_FL(2); SET_L_REG(0, (PC & 0xfffffffe) | GET_S); SET_L_REG(1, oldSR); SET_M(0); SET_T(0); SET_L(1); SET_S(1); PPC = PC; PC = addr; change_pc(PC); mame_printf_debug("EXCEPTION! PPC = %08X PC = %08X\n",PPC-2,PC-2); hyperstone_ICount -= 2; } static void execute_software(void) { UINT8 reg; UINT32 oldSR; UINT32 addr; UINT32 stack_of_dst; SET_ILC(1); addr = get_emu_code_addr((OP & 0xff00) >> 8); reg = GET_FP + GET_FL; //since it's sure the register is in the register part of the stack, //set the stack address to a value above the highest address //that can be set by a following frame instruction stack_of_dst = (SP & ~0xff) + 64*4 + (((GET_FP + current_regs.dst) % 64) * 4); //converted to 32bits offset oldSR = SR; SET_FL(6); SET_FP(reg); SET_L_REG(0, stack_of_dst); SET_L_REG(1, SREG); SET_L_REG(2, SREGF); SET_L_REG(3, (PC & 0xfffffffe) | GET_S); SET_L_REG(4, oldSR); SET_M(0); SET_T(0); SET_L(1); PPC = PC; PC = addr; change_pc(PC); } /* IRQ lines : 0 - IO2 (trap 48) 1 - IO1 (trap 49) 2 - INT4 (trap 50) 3 - INT3 (trap 51) 4 - INT2 (trap 52) 5 - INT1 (trap 53) 6 - IO3 (trap 54) 7 - TIMER (trap 55) */ static void set_irq_line(int irqline, int state) { /* Interrupt-Lock flag isn't set */ if(hyperstone.intblock) return; if( !GET_L && state ) { int execint=0; switch(irqline) { case 0: if( (FCR&(1<<6)) && (!(FCR&(1<<4))) ) execint=1; // IO2 break; case 1: if( (FCR&(1<<2)) && (!(FCR&(1<<0))) ) execint=1; // IO1 break; case 2: if( !(FCR&(1<<31)) ) execint=1; // int 4 break; case 3: if( !(FCR&(1<<30)) ) execint=1; // int 3 break; case 4: if( !(FCR&(1<<29)) ) execint=1; // int 2 break; case 5: if( !(FCR&(1<<28)) ) execint=1; // int 1 break; case 6: if( (FCR&(1<<10)) && (!(FCR&(1<<8))) ) execint=1; // IO3 break; case 7: if( !(FCR&(1<<23)) ) execint=1; // timer break; } /* if( (FCR&(1<<6)) && (!(FCR&(1<<4))) ) mame_printf_debug("IO2 en\n"); // IO2 if( (FCR&(1<<2)) && (!(FCR&(1<<0))) ) mame_printf_debug("IO1 en\n"); // IO1 if( !(FCR&(1<<31)) ) mame_printf_debug("int4 en\n"); // int 4 if( !(FCR&(1<<30)) ) mame_printf_debug("int3 en\n"); // int 3 if( !(FCR&(1<<29)) ) mame_printf_debug("int2 en\n"); // int 2 if( !(FCR&(1<<28)) ) mame_printf_debug("int1 en\n"); // int 1 if( (FCR&(1<<10)) && (!(FCR&(1<<8))) ) mame_printf_debug("IO3 en\n"); // IO3 // if( !(FCR&(1<<23)) ) mame_printf_debug("timer irq!\n"); // timer */ if(execint) { execute_int(get_trap_addr(irqline + 48)); (*hyperstone.irq_callback)(irqline); } } } static void hyperstone_init(int index, int clock, const void *config, int (*irqcallback)(int)) { state_save_register_item_array("E132XS", index, hyperstone.global_regs); state_save_register_item_array("E132XS", index, hyperstone.local_regs); state_save_register_item("E132XS", index, hyperstone.ppc); state_save_register_item("E132XS", index, hyperstone.trap_entry); state_save_register_item("E132XS", index, hyperstone.delay.delay_pc); state_save_register_item("E132XS", index, hyperstone.op); state_save_register_item("E132XS", index, hyperstone.n); state_save_register_item("E132XS", index, hyperstone.h_clear); state_save_register_item("E132XS", index, hyperstone.instruction_length); state_save_register_item("E132XS", index, hyperstone.intblock); state_save_register_item("E132XS", index, hyperstone.delay_timer); state_save_register_item("E132XS", index, hyperstone.delay.delay_cmd); state_save_register_item("E132XS", index, hyperstone.timer_clocks); hyperstone.irq_callback = irqcallback; } #if (HAS_E116T || HAS_E116XT || HAS_E116XS || HAS_E116XSR || HAS_GMS30C2116 || HAS_GMS30C2216) static void e116_init(int index, int clock, const void *config, int (*irqcallback)(int)) { hyp_cpu_read_byte = program_read_byte_16be; hyp_cpu_read_half_word = program_read_word_16be; hyp_cpu_read_word = program_read_dword_16be; hyp_cpu_read_io_word = io_read_dword_16be; hyp_cpu_write_byte = program_write_byte_16be; hyp_cpu_write_half_word = program_write_word_16be; hyp_cpu_write_word = program_write_dword_16be; hyp_cpu_write_io_word = io_write_dword_16be; hyp_type_16bit = 1; hyperstone_init(index, clock, config, irqcallback); } #endif #if (HAS_E132N || HAS_E132T || HAS_E132XN || HAS_E132XT || HAS_E132XS || HAS_E132XSR || HAS_GMS30C2132 || HAS_GMS30C2232) static void e132_init(int index, int clock, const void *config, int (*irqcallback)(int)) { hyp_cpu_read_byte = program_read_byte_32be; hyp_cpu_read_half_word = program_read_word_32be; hyp_cpu_read_word = program_read_dword_32be; hyp_cpu_read_io_word = io_read_dword_32be; hyp_cpu_write_byte = program_write_byte_32be; hyp_cpu_write_half_word = program_write_word_32be; hyp_cpu_write_word = program_write_dword_32be; hyp_cpu_write_io_word = io_write_dword_32be; hyp_type_16bit = 0; hyperstone_init(index, clock, config, irqcallback); } #endif static void hyperstone_reset(void) { //TODO: Add different reset initializations for BCR, MCR, FCR, TPR int (*save_irqcallback)(int); save_irqcallback = hyperstone.irq_callback; memset(&hyperstone, 0, sizeof(hyperstone_regs)); hyperstone.irq_callback = save_irqcallback; hyperstone.h_clear = 0; hyperstone.instruction_length = 0; hyperstone_set_trap_entry(E132XS_ENTRY_MEM3); /* default entry point @ MEM3 */ set_global_register(BCR_REGISTER, ~0); set_global_register(MCR_REGISTER, ~0); set_global_register(FCR_REGISTER, ~0); set_global_register(TPR_REGISTER, 0xc000000); PC = get_trap_addr(RESET); change_pc(PC); SET_FP(0); SET_FL(2); SET_M(0); SET_T(0); SET_L(1); SET_S(1); SET_L_REG(0, (PC & 0xfffffffe) | GET_S); SET_L_REG(1, SR); hyperstone_ICount -= 2; } static void hyperstone_exit(void) { // nothing to do } /* Handle the timer, increasing its value after "timer_clocks" clocks and returning the new icount base that needs to be used for the next check */ static int handle_timers(int current_icount, int previous_icount) { int diff = previous_icount - current_icount; int new_icount_base; if(diff >= hyperstone.timer_clocks) { TR++; // wrap around to 0 modulo 32 bits if( hyperstone.delay_timer ) { hyperstone.delay_timer = 0; hyperstone.timer_clocks = hyperstone.n + 2; } new_icount_base = current_icount + (diff - hyperstone.timer_clocks); } else { new_icount_base = previous_icount; } if(!hyperstone.intblock) { if( !((TR - TCR) & 0x80000000) ) { /* generate a timer interrupt */ set_irq_line(7, PULSE_LINE); } } return new_icount_base; } static int hyperstone_execute(int cycles) { int old_icount = cycles; hyperstone_ICount = cycles; do { PPC = PC; /* copy PC to previous PC */ CALL_MAME_DEBUG; OP = READ_OP(PC); PC += 2; if(GET_H) { hyperstone.h_clear = 1; } hyperstone.instruction_length = 1; /* clear 'current regs / flags' */ current_regs.src = 0; current_regs.dst = 0; current_regs.src_value = 0; current_regs.next_src_value = 0; current_regs.dst_value = 0; current_regs.next_dst_value = 0; current_regs.sub_type = 0; current_regs.extra.u = 0; current_regs.extra.s = 0; current_regs.set_src_register = NULL; current_regs.set_dst_register = NULL; current_regs.src_is_pc = 0; current_regs.dst_is_pc = 0; current_regs.src_is_sr = 0; current_regs.dst_is_sr = 0; current_regs.same_src_dst = 0; current_regs.same_src_dstf = 0; current_regs.same_srcf_dst = 0; /* decode current opcode details into current regs */ hyperstone_decode[(OP & 0xff00) >> 8](); /* execute opcode */ hyperstone_op[(OP & 0xff00) >> 8](); SET_ILC(hyperstone.instruction_length & 3); old_icount = handle_timers(hyperstone_ICount, old_icount); if(hyperstone.h_clear) { SET_H(0); hyperstone.h_clear = 0; } if( GET_T && GET_P && hyperstone.delay.delay_cmd == NO_DELAY ) /* Not in a Delayed Branch instructions */ { UINT32 addr = get_trap_addr(TRACE_EXCEPTION); execute_exception(addr); } if( hyperstone.delay.delay_cmd == DELAY_TAKEN ) { hyperstone.delay.delay_cmd = DELAY_EXECUTE; } if(hyperstone.intblock > 0) { hyperstone.intblock--; } } while( hyperstone_ICount > 0 ); return cycles - hyperstone_ICount; } static void hyperstone_get_context(void *regs) { /* copy the context */ if( regs ) *(hyperstone_regs *)regs = hyperstone; } static void hyperstone_set_context(void *regs) { /* copy the context */ if (regs) hyperstone = *(hyperstone_regs *)regs; } #ifdef MAME_DEBUG static offs_t hyperstone_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) { return dasm_hyperstone( buffer, pc, oprom, GET_H, GET_FP ); } #endif /* MAME_DEBUG */ /* Opcodes */ static void hyperstone_chk(void) { UINT32 addr = get_trap_addr(RANGE_ERROR); if( SRC_IS_SR ) { if( DREG == 0 ) execute_exception(addr); } else { if( SRC_IS_PC ) { if( DREG >= SREG ) execute_exception(addr); } else { if( DREG > SREG ) execute_exception(addr); } } hyperstone_ICount -= 1; } static void hyperstone_movd(void) { if( DST_IS_PC ) // Rd denotes PC { // RET instruction UINT8 old_s, old_l; INT8 difference; // really it's 7 bits if( SRC_IS_PC || SRC_IS_SR ) { logerror("Denoted PC or SR in RET instruction. PC = %08X\n", PC); } else { old_s = GET_S; old_l = GET_L; PPC = PC; PC = SET_PC(SREG); change_pc(PC); SR = (SREGF & 0xffe00000) | ((SREG & 0x01) << 18 ) | (SREGF & 0x3ffff); hyperstone.instruction_length = 0; // undefined if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L)) { UINT32 addr = get_trap_addr(PRIVILEGE_ERROR); execute_exception(addr); } difference = GET_FP - ((SP & 0x1fc) >> 2); /* convert to 8 bits */ if(difference > 63) difference = (INT8)(difference|0x80); else if( difference < -64 ) difference = difference & 0x7f; if( difference < 0 ) //else it's finished { do { SP -= 4; SET_ABS_L_REG(((SP & 0xfc) >> 2), READ_W(SP)); difference++; } while(difference != 0); } } //TODO: no 1! hyperstone_ICount -= 1; } else if( SRC_IS_SR ) // Rd doesn't denote PC and Rs denotes SR { SET_DREG(0); SET_DREGF(0); SET_Z(1); SET_N(0); hyperstone_ICount -= 2; } else // Rd doesn't denote PC and Rs doesn't denote SR { UINT64 tmp; SET_DREG(SREG); SET_DREGF(SREGF); tmp = COMBINE_U64_U32_U32(SREG, SREGF); SET_Z( tmp == 0 ? 1 : 0 ); SET_N( SIGN_BIT(SREG) ); hyperstone_ICount -= 2; } } static void hyperstone_divu(void) { if( SAME_SRC_DST || SAME_SRC_DSTF ) { logerror("Denoted the same register code in hyperstone_divu instruction. PC = %08X\n", PC); } else { if( SRC_IS_PC || SRC_IS_SR ) { logerror("Denoted PC or SR as source register in hyperstone_divu instruction. PC = %08X\n", PC); } else { UINT64 dividend; dividend = COMBINE_U64_U32_U32(DREG, DREGF); if( SREG == 0 ) { //Rd//Rdf -> undefined //Z -> undefined //N -> undefined UINT32 addr; SET_V(1); addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } else { UINT32 quotient, remainder; /* TODO: add quotient overflow */ quotient = dividend / SREG; remainder = dividend % SREG; SET_DREG(remainder); SET_DREGF(quotient); SET_Z( quotient == 0 ? 1 : 0 ); SET_N( SIGN_BIT(quotient) ); SET_V(0); } } } hyperstone_ICount -= 36; } static void hyperstone_divs(void) { if( SAME_SRC_DST || SAME_SRC_DSTF ) { logerror("Denoted the same register code in hyperstone_divs instruction. PC = %08X\n", PC); } else { if( SRC_IS_PC || SRC_IS_SR ) { logerror("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC); } else { INT64 dividend; dividend = (INT64) COMBINE_64_32_32(DREG, DREGF); if( SREG == 0 || (DREG & 0x80000000) ) { //Rd//Rdf -> undefined //Z -> undefined //N -> undefined UINT32 addr; SET_V(1); addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } else { INT32 quotient, remainder; /* TODO: add quotient overflow */ quotient = dividend / ((INT32)(SREG)); remainder = dividend % ((INT32)(SREG)); SET_DREG(remainder); SET_DREGF(quotient); SET_Z( quotient == 0 ? 1 : 0 ); SET_N( SIGN_BIT(quotient) ); SET_V(0); } } } hyperstone_ICount -= 36; } static void hyperstone_xm(void) { if( SRC_IS_SR || DST_IS_SR || DST_IS_PC ) { logerror("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC); } else { switch( current_regs.sub_type ) // x_code { case 0: case 1: case 2: case 3: if( !SRC_IS_PC && (SREG > EXTRA_U) ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } else if( SRC_IS_PC && (SREG >= EXTRA_U) ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } else { SREG <<= current_regs.sub_type; } break; case 4: case 5: case 6: case 7: current_regs.sub_type -= 4; SREG <<= current_regs.sub_type; break; } SET_DREG(SREG); } hyperstone_ICount -= 1; } static void hyperstone_mask(void) { DREG = SREG & EXTRA_U; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_sum(void) { UINT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (UINT64)(SREG) + (UINT64)(EXTRA_U); CHECK_C(tmp); CHECK_VADD(SREG,EXTRA_U,tmp); DREG = SREG + EXTRA_U; SET_DREG(DREG); if( DST_IS_PC ) SET_M(0); SET_Z( DREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_sums(void) { INT32 res; INT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (INT64)((INT32)(SREG)) + (INT64)(EXTRA_S); CHECK_VADD(SREG,EXTRA_S,tmp); //#if SETCARRYS // CHECK_C(tmp); //#endif res = (INT32)(SREG) + EXTRA_S; SET_DREG(res); SET_Z( res == 0 ? 1 : 0 ); SET_N( SIGN_BIT(res) ); hyperstone_ICount -= 1; if( GET_V && !SRC_IS_SR ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } } static void hyperstone_cmp(void) { UINT64 tmp; if( SRC_IS_SR ) SREG = GET_C; if( DREG == SREG ) SET_Z(1); else SET_Z(0); if( (INT32) DREG < (INT32) SREG ) SET_N(1); else SET_N(0); tmp = (UINT64)(DREG) - (UINT64)(SREG); CHECK_VSUB(SREG,DREG,tmp); if( DREG < SREG ) SET_C(1); else SET_C(0); hyperstone_ICount -= 1; } static void hyperstone_mov(void) { if( !GET_S && current_regs.dst >= 16 ) { UINT32 addr = get_trap_addr(PRIVILEGE_ERROR); execute_exception(addr); } SET_DREG(SREG); if( DST_IS_PC ) SET_M(0); SET_Z( SREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(SREG) ); hyperstone_ICount -= 1; } static void hyperstone_add(void) { UINT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (UINT64)(SREG) + (UINT64)(DREG); CHECK_C(tmp); CHECK_VADD(SREG,DREG,tmp); DREG = SREG + DREG; SET_DREG(DREG); if( DST_IS_PC ) SET_M(0); SET_Z( DREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_adds(void) { INT32 res; INT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (INT64)((INT32)(SREG)) + (INT64)((INT32)(DREG)); CHECK_VADD(SREG,DREG,tmp); //#if SETCARRYS // CHECK_C(tmp); //#endif res = (INT32)(SREG) + (INT32)(DREG); SET_DREG(res); SET_Z( res == 0 ? 1 : 0 ); SET_N( SIGN_BIT(res) ); hyperstone_ICount -= 1; if( GET_V ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } } static void hyperstone_cmpb(void) { SET_Z( (DREG & SREG) == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_andn(void) { DREG = DREG & ~SREG; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_or(void) { DREG = DREG | SREG; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_xor(void) { DREG = DREG ^ SREG; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_subc(void) { UINT64 tmp; if( SRC_IS_SR ) { tmp = (UINT64)(DREG) - (UINT64)(GET_C); CHECK_VSUB(GET_C,DREG,tmp); } else { tmp = (UINT64)(DREG) - ((UINT64)(SREG) + (UINT64)(GET_C)); //CHECK! CHECK_VSUB(SREG + GET_C,DREG,tmp); } if( SRC_IS_SR ) { DREG = DREG - GET_C; } else { DREG = DREG - (SREG + GET_C); } CHECK_C(tmp); SET_DREG(DREG); SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_not(void) { SET_DREG(~SREG); SET_Z( ~SREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_sub(void) { UINT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (UINT64)(DREG) - (UINT64)(SREG); CHECK_C(tmp); CHECK_VSUB(SREG,DREG,tmp); DREG = DREG - SREG; SET_DREG(DREG); if( DST_IS_PC ) SET_M(0); SET_Z( DREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_subs(void) { INT32 res; INT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = (INT64)((INT32)(DREG)) - (INT64)((INT32)(SREG)); //#ifdef SETCARRYS // CHECK_C(tmp); //#endif CHECK_VSUB(SREG,DREG,tmp); res = (INT32)(DREG) - (INT32)(SREG); SET_DREG(res); SET_Z( res == 0 ? 1 : 0 ); SET_N( SIGN_BIT(res) ); hyperstone_ICount -= 1; if( GET_V ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } } static void hyperstone_addc(void) { UINT64 tmp; if( SRC_IS_SR ) { tmp = (UINT64)(DREG) + (UINT64)(GET_C); CHECK_VADD(DREG,GET_C,tmp); } else { tmp = (UINT64)(SREG) + (UINT64)(DREG) + (UINT64)(GET_C); //CHECK! //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1); //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C) /* check if DREG + GET_C overflows */ // if( (DREG == 0x7FFFFFFF) && (GET_C == 1) ) // SET_V(1); // else // CHECK_VADD(SREG,DREG + GET_C,tmp); CHECK_VADD3(SREG,DREG,GET_C,tmp); } if( SRC_IS_SR ) DREG = DREG + GET_C; else DREG = SREG + DREG + GET_C; CHECK_C(tmp); SET_DREG(DREG); SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_and(void) { DREG = DREG & SREG; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_neg(void) { UINT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = -(UINT64)(SREG); CHECK_C(tmp); CHECK_VSUB(SREG,0,tmp); DREG = -SREG; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_negs(void) { INT32 res; INT64 tmp; if( SRC_IS_SR ) SREG = GET_C; tmp = -(INT64)((INT32)(SREG)); CHECK_VSUB(SREG,0,tmp); //#if SETCARRYS // CHECK_C(tmp); //#endif res = -(INT32)(SREG); SET_DREG(res); SET_Z( res == 0 ? 1 : 0 ); SET_N( SIGN_BIT(res) ); hyperstone_ICount -= 1; if( GET_V && !SRC_IS_SR ) //trap doesn't occur when source is SR { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } } static void hyperstone_cmpi(void) { UINT64 tmp; tmp = (UINT64)(DREG) - (UINT64)(EXTRA_U); CHECK_VSUB(EXTRA_U,DREG,tmp); if( DREG == EXTRA_U ) SET_Z(1); else SET_Z(0); if( (INT32) DREG < (INT32) EXTRA_U ) SET_N(1); else SET_N(0); if( DREG < EXTRA_U ) SET_C(1); else SET_C(0); hyperstone_ICount -= 1; } static void hyperstone_movi(void) { if( !GET_S && current_regs.dst >= 16 ) { UINT32 addr = get_trap_addr(PRIVILEGE_ERROR); execute_exception(addr); } SET_DREG(EXTRA_U); if( DST_IS_PC ) SET_M(0); SET_Z( EXTRA_U == 0 ? 1 : 0 ); SET_N( SIGN_BIT(EXTRA_U) ); #if MISSIONCRAFT_FLAGS SET_V(0); // or V undefined ? #endif hyperstone_ICount -= 1; } static void hyperstone_addi(void) { UINT32 imm; UINT64 tmp; if( N_VALUE ) imm = EXTRA_U; else imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); tmp = (UINT64)(imm) + (UINT64)(DREG); CHECK_C(tmp); CHECK_VADD(imm,DREG,tmp); DREG = imm + DREG; SET_DREG(DREG); if( DST_IS_PC ) SET_M(0); SET_Z( DREG == 0 ? 1 : 0 ); SET_N( SIGN_BIT(DREG) ); hyperstone_ICount -= 1; } static void hyperstone_addsi(void) { INT32 imm, res; INT64 tmp; if( N_VALUE ) imm = EXTRA_S; else imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); tmp = (INT64)(imm) + (INT64)((INT32)(DREG)); CHECK_VADD(imm,DREG,tmp); //#if SETCARRYS // CHECK_C(tmp); //#endif res = imm + (INT32)(DREG); SET_DREG(res); SET_Z( res == 0 ? 1 : 0 ); SET_N( SIGN_BIT(res) ); hyperstone_ICount -= 1; if( GET_V ) { UINT32 addr = get_trap_addr(RANGE_ERROR); execute_exception(addr); } } static void hyperstone_cmpbi(void) { UINT32 imm; if( N_VALUE ) { if( N_VALUE == 31 ) { imm = 0x7fffffff; // bit 31 = 0, others = 1 } else { imm = EXTRA_U; } SET_Z( (DREG & imm) == 0 ? 1 : 0 ); } else { if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 || (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 ) SET_Z(1); else SET_Z(0); } hyperstone_ICount -= 1; } static void hyperstone_andni(void) { UINT32 imm; if( N_VALUE == 31 ) imm = 0x7fffffff; // bit 31 = 0, others = 1 else imm = EXTRA_U; DREG = DREG & ~imm; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_ori(void) { DREG = DREG | EXTRA_U; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_xori(void) { DREG = DREG ^ EXTRA_U; SET_DREG(DREG); SET_Z( DREG == 0 ? 1 : 0 ); hyperstone_ICount -= 1; } static void hyperstone_shrdi(void) { UINT32 low_order, high_order; UINT64 val; high_order = DREG; low_order = DREGF; val = COMBINE_U64_U32_U32(high_order, low_order); if( N_VALUE ) SET_C((val >> (N_VALUE - 1)) & 1); else SET_C(0); val >>= N_VALUE; high_order = HI32_32_64(val); low_order = LO32_32_64(val); SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); hyperstone_ICount -= 2; } static void hyperstone_shrd(void) { UINT32 low_order, high_order; UINT64 val; UINT8 n = SREG & 0x1f; // result undefined if Ls denotes the same register as Ld or Ldf if( SAME_SRC_DST || SAME_SRC_DSTF ) { logerror("Denoted same registers in hyperstone_shrd. PC = %08X\n", PC); } else { high_order = DREG; low_order = DREGF; val = COMBINE_U64_U32_U32(high_order, low_order); if( n ) SET_C((val >> (n - 1)) & 1); else SET_C(0); val >>= n; high_order = HI32_32_64(val); low_order = LO32_32_64(val); SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); } hyperstone_ICount -= 2; } static void hyperstone_shr(void) { UINT32 ret; UINT8 n; n = SREG & 0x1f; ret = DREG; if( n ) SET_C((ret >> (n - 1)) & 1); else SET_C(0); ret >>= n; SET_DREG(ret); SET_Z( ret == 0 ? 1 : 0 ); SET_N( SIGN_BIT(ret) ); hyperstone_ICount -= 1; } static void hyperstone_sardi(void) { UINT32 low_order, high_order; UINT64 val; UINT8 sign_bit; high_order = DREG; low_order = DREGF; val = COMBINE_64_32_32(high_order, low_order); if( N_VALUE ) SET_C((val >> (N_VALUE - 1)) & 1); else SET_C(0); sign_bit = val >> 63; val >>= N_VALUE; if( sign_bit ) { int i; for( i = 0; i < N_VALUE; i++ ) { val |= (U64(0x8000000000000000) >> i); } } high_order = val >> 32; low_order = val & 0xffffffff; SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); hyperstone_ICount -= 2; } static void hyperstone_sard(void) { UINT32 low_order, high_order; UINT64 val; UINT8 n, sign_bit; n = SREG & 0x1f; // result undefined if Ls denotes the same register as Ld or Ldf if( SAME_SRC_DST || SAME_SRC_DSTF ) { logerror("Denoted same registers in hyperstone_sard. PC = %08X\n", PC); } else { high_order = DREG; low_order = DREGF; val = COMBINE_64_32_32(high_order, low_order); if( n ) SET_C((val >> (n - 1)) & 1); else SET_C(0); sign_bit = val >> 63; val >>= n; if( sign_bit ) { int i; for( i = 0; i < n; i++ ) { val |= (U64(0x8000000000000000) >> i); } } high_order = val >> 32; low_order = val & 0xffffffff; SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); } hyperstone_ICount -= 2; } static void hyperstone_sar(void) { UINT32 ret; UINT8 n, sign_bit; n = SREG & 0x1f; ret = DREG; sign_bit = (ret & 0x80000000) >> 31; if( n ) SET_C((ret >> (n - 1)) & 1); else SET_C(0); ret >>= n; if( sign_bit ) { int i; for( i = 0; i < n; i++ ) { ret |= (0x80000000 >> i); } } SET_DREG(ret); SET_Z( ret == 0 ? 1 : 0 ); SET_N( SIGN_BIT(ret) ); hyperstone_ICount -= 1; } static void hyperstone_shldi(void) { UINT32 low_order, high_order, tmp; UINT64 val, mask; high_order = DREG; low_order = DREGF; val = COMBINE_U64_U32_U32(high_order, low_order); SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&U64(0x8000000000000000))?1:0):0); mask = ((((UINT64)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; tmp = high_order << N_VALUE; if( ((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) SET_V(1); else SET_V(0); val <<= N_VALUE; high_order = HI32_32_64(val); low_order = LO32_32_64(val); SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); hyperstone_ICount -= 2; } static void hyperstone_shld(void) { UINT32 low_order, high_order, tmp, n; UINT64 val, mask; n = SREG & 0x1f; // result undefined if Ls denotes the same register as Ld or Ldf if( SAME_SRC_DST || SAME_SRC_DSTF ) { logerror("Denoted same registers in hyperstone_shld. PC = %08X\n", PC); } else { high_order = DREG; low_order = DREGF; mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff; val = COMBINE_U64_U32_U32(high_order, low_order); SET_C( (n)?(((val<<(n-1))&U64(0x8000000000000000))?1:0):0); tmp = high_order << n; if( ((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) SET_V(1); else SET_V(0); val <<= n; high_order = HI32_32_64(val); low_order = LO32_32_64(val); SET_DREG(high_order); SET_DREGF(low_order); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); } hyperstone_ICount -= 2; } static void hyperstone_shl(void) { UINT32 base, ret, n; UINT64 mask; n = SREG & 0x1f; base = DREG; mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff; SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0); ret = base << n; if( ((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)) ) SET_V(1); else SET_V(0); SET_DREG(ret); SET_Z( ret == 0 ? 1 : 0 ); SET_N( SIGN_BIT(ret) ); hyperstone_ICount -= 1; } static void reserved(void) { logerror("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP); } static void hyperstone_testlz(void) { UINT8 zeros = 0; UINT32 mask; for( mask = 0x80000000; ; mask >>= 1 ) { if( SREG & mask ) break; else zeros++; if( zeros == 32 ) break; } SET_DREG(zeros); hyperstone_ICount -= 2; } static void hyperstone_rol(void) { UINT32 val, base; UINT8 n; UINT64 mask; n = SREG & 0x1f; val = base = DREG; mask = ((((UINT64)1) << (32 - n)) - 1) ^ 0xffffffff; while( n > 0 ) { val = (val << 1) | ((val & 0x80000000) >> 31); n--; } #ifdef MISSIONCRAFT_FLAGS if( ((base & mask) && (!(val & 0x80000000))) || (((base & mask) ^ mask) && (val & 0x80000000)) ) SET_V(1); else SET_V(0); #endif SET_DREG(val); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(val) ); hyperstone_ICount -= 1; } //TODO: add trap error static void hyperstone_ldxx1(void) { UINT32 load; if( DST_IS_SR ) { switch( current_regs.sub_type ) { case 0: // LDBS.A load = READ_B(EXTRA_S); load |= (load & 0x80) ? 0xffffff00 : 0; SET_SREG(load); break; case 1: // LDBU.A load = READ_B(EXTRA_S); SET_SREG(load); break; case 2: load = READ_HW(EXTRA_S & ~1); if( EXTRA_S & 1 ) // LDHS.A { load |= (load & 0x8000) ? 0xffff0000 : 0; } /* else // LDHU.A { // nothing more } */ SET_SREG(load); break; case 3: if( (EXTRA_S & 3) == 3 ) // LDD.IOA { load = IO_READ_W(EXTRA_S & ~3); SET_SREG(load); load = IO_READ_W((EXTRA_S & ~3) + 4); SET_SREGF(load); hyperstone_ICount -= 1; // extra cycle } else if( (EXTRA_S & 3) == 2 ) // LDW.IOA { load = IO_READ_W(EXTRA_S & ~3); SET_SREG(load); } else if( (EXTRA_S & 3) == 1 ) // LDD.A { load = READ_W(EXTRA_S & ~1); SET_SREG(load); load = READ_W((EXTRA_S & ~1) + 4); SET_SREGF(load); hyperstone_ICount -= 1; // extra cycle } else // LDW.A { load = READ_W(EXTRA_S & ~1); SET_SREG(load); } break; } } else { switch( current_regs.sub_type ) { case 0: // LDBS.D load = READ_B(DREG + EXTRA_S); load |= (load & 0x80) ? 0xffffff00 : 0; SET_SREG(load); break; case 1: // LDBU.D load = READ_B(DREG + EXTRA_S); SET_SREG(load); break; case 2: load = READ_HW(DREG + (EXTRA_S & ~1)); if( EXTRA_S & 1 ) // LDHS.D { load |= (load & 0x8000) ? 0xffff0000 : 0; } /* else // LDHU.D { // nothing more } */ SET_SREG(load); break; case 3: if( (EXTRA_S & 3) == 3 ) // LDD.IOD { load = IO_READ_W(DREG + (EXTRA_S & ~3)); SET_SREG(load); load = IO_READ_W(DREG + (EXTRA_S & ~3) + 4); SET_SREGF(load); hyperstone_ICount -= 1; // extra cycle } else if( (EXTRA_S & 3) == 2 ) // LDW.IOD { load = IO_READ_W(DREG + (EXTRA_S & ~3)); SET_SREG(load); } else if( (EXTRA_S & 3) == 1 ) // LDD.D { load = READ_W(DREG + (EXTRA_S & ~1)); SET_SREG(load); load = READ_W(DREG + (EXTRA_S & ~1) + 4); SET_SREGF(load); hyperstone_ICount -= 1; // extra cycle } else // LDW.D { load = READ_W(DREG + (EXTRA_S & ~1)); SET_SREG(load); } break; } } hyperstone_ICount -= 1; } static void hyperstone_ldxx2(void) { UINT32 load; if( DST_IS_PC || DST_IS_SR ) { logerror("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC); } else { switch( current_regs.sub_type ) { case 0: // LDBS.N if(SAME_SRC_DST) popmessage("LDBS.N denoted same regs @ %08X",PPC); load = READ_B(DREG); load |= (load & 0x80) ? 0xffffff00 : 0; SET_SREG(load); if(!SAME_SRC_DST) SET_DREG(DREG + EXTRA_S); break; case 1: // LDBU.N if(SAME_SRC_DST) popmessage("LDBU.N denoted same regs @ %08X",PPC); load = READ_B(DREG); SET_SREG(load); if(!SAME_SRC_DST) SET_DREG(DREG + EXTRA_S); break; case 2: load = READ_HW(DREG); if( EXTRA_S & 1 ) // LDHS.N { load |= (load & 0x8000) ? 0xffff0000 : 0; if(SAME_SRC_DST) popmessage("LDHS.N denoted same regs @ %08X",PPC); } /* else // LDHU.N { // nothing more } */ SET_SREG(load); if(!SAME_SRC_DST) SET_DREG(DREG + (EXTRA_S & ~1)); break; case 3: if( (EXTRA_S & 3) == 3 ) // LDW.S { if(SAME_SRC_DST) popmessage("LDW.S denoted same regs @ %08X",PPC); if(DREG < SP) SET_SREG(READ_W(DREG)); else SET_SREG(GET_ABS_L_REG((DREG & 0xfc) >> 2)); if(!SAME_SRC_DST) SET_DREG(DREG + (EXTRA_S & ~3)); hyperstone_ICount -= 2; // extra cycles } else if( (EXTRA_S & 3) == 2 ) // Reserved { logerror("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC); } else if( (EXTRA_S & 3) == 1 ) // LDD.N { if(SAME_SRC_DST || SAME_SRCF_DST) popmessage("LDD.N denoted same regs @ %08X",PPC); load = READ_W(DREG); SET_SREG(load); load = READ_W(DREG + 4); SET_SREGF(load); if(!SAME_SRC_DST && !SAME_SRCF_DST) SET_DREG(DREG + (EXTRA_S & ~1)); hyperstone_ICount -= 1; // extra cycle } else // LDW.N { if(SAME_SRC_DST) popmessage("LDW.N denoted same regs @ %08X",PPC); load = READ_W(DREG); SET_SREG(load); if(!SAME_SRC_DST) SET_DREG(DREG + (EXTRA_S & ~1)); } break; } } hyperstone_ICount -= 1; } //TODO: add trap error static void hyperstone_stxx1(void) { if( SRC_IS_SR ) SREG = SREGF = 0; if( DST_IS_SR ) { switch( current_regs.sub_type ) { case 0: // STBS.A /* TODO: missing trap on range error */ WRITE_B(EXTRA_S, SREG & 0xff); break; case 1: // STBU.A WRITE_B(EXTRA_S, SREG & 0xff); break; case 2: WRITE_HW(EXTRA_S & ~1, SREG & 0xffff); /* if( EXTRA_S & 1 ) // STHS.A { // TODO: missing trap on range error } else // STHU.A { // nothing more } */ break; case 3: if( (EXTRA_S & 3) == 3 ) // STD.IOA { IO_WRITE_W(EXTRA_S & ~3, SREG); IO_WRITE_W((EXTRA_S & ~3) + 4, SREGF); hyperstone_ICount -= 1; // extra cycle } else if( (EXTRA_S & 3) == 2 ) // STW.IOA { IO_WRITE_W(EXTRA_S & ~3, SREG); } else if( (EXTRA_S & 3) == 1 ) // STD.A { WRITE_W(EXTRA_S & ~1, SREG); WRITE_W((EXTRA_S & ~1) + 4, SREGF); hyperstone_ICount -= 1; // extra cycle } else // STW.A { WRITE_W(EXTRA_S & ~1, SREG); } break; } } else { switch( current_regs.sub_type ) { case 0: // STBS.D /* TODO: missing trap on range error */ WRITE_B(DREG + EXTRA_S, SREG & 0xff); break; case 1: // STBU.D WRITE_B(DREG + EXTRA_S, SREG & 0xff); break; case 2: WRITE_HW(DREG + (EXTRA_S & ~1), SREG & 0xffff); /* if( EXTRA_S & 1 ) // STHS.D { // TODO: missing trap on range error } else // STHU.D { // nothing more } */ break; case 3: if( (EXTRA_S & 3) == 3 ) // STD.IOD { IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); IO_WRITE_W(DREG + (EXTRA_S & ~3) + 4, SREGF); hyperstone_ICount -= 1; // extra cycle } else if( (EXTRA_S & 3) == 2 ) // STW.IOD { IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); } else if( (EXTRA_S & 3) == 1 ) // STD.D { WRITE_W(DREG + (EXTRA_S & ~1), SREG); WRITE_W(DREG + (EXTRA_S & ~1) + 4, SREGF); hyperstone_ICount -= 1; // extra cycle } else // STW.D { WRITE_W(DREG + (EXTRA_S & ~1), SREG); } break; } } hyperstone_ICount -= 1; } static void hyperstone_stxx2(void) { if( SRC_IS_SR ) SREG = SREGF = 0; if( DST_IS_PC || DST_IS_SR ) { logerror("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC); } else { switch( current_regs.sub_type ) { case 0: // STBS.N /* TODO: missing trap on range error */ WRITE_B(DREG, SREG & 0xff); SET_DREG(DREG + EXTRA_S); break; case 1: // STBU.N WRITE_B(DREG, SREG & 0xff); SET_DREG(DREG + EXTRA_S); break; case 2: WRITE_HW(DREG, SREG & 0xffff); SET_DREG(DREG + (EXTRA_S & ~1)); /* if( EXTRA_S & 1 ) // STHS.N { // TODO: missing trap on range error } else // STHU.N { // nothing more } */ break; case 3: if( (EXTRA_S & 3) == 3 ) // STW.S { if(DREG < SP) WRITE_W(DREG, SREG); else { if(((DREG & 0xfc) >> 2) == ((current_regs.src + GET_FP) % 64) && S_BIT == LOCAL) popmessage("STW.S denoted the same local register @ %08X\n",PPC); SET_ABS_L_REG((DREG & 0xfc) >> 2,SREG); } SET_DREG(DREG + (EXTRA_S & ~3)); hyperstone_ICount -= 2; // extra cycles } else if( (EXTRA_S & 3) == 2 ) // Reserved { logerror("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC); } else if( (EXTRA_S & 3) == 1 ) // STD.N { WRITE_W(DREG, SREG); SET_DREG(DREG + (EXTRA_S & ~1)); if( SAME_SRCF_DST ) WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented else WRITE_W(DREG + 4, SREGF); hyperstone_ICount -= 1; // extra cycle } else // STW.N { WRITE_W(DREG, SREG); SET_DREG(DREG + (EXTRA_S & ~1)); } break; } } hyperstone_ICount -= 1; } static void hyperstone_shri(void) { UINT32 val; val = DREG; if( N_VALUE ) SET_C((val >> (N_VALUE - 1)) & 1); else SET_C(0); val >>= N_VALUE; SET_DREG(val); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(val) ); hyperstone_ICount -= 1; } static void hyperstone_sari(void) { UINT32 val; UINT8 sign_bit; val = DREG; sign_bit = (val & 0x80000000) >> 31; if( N_VALUE ) SET_C((val >> (N_VALUE - 1)) & 1); else SET_C(0); val >>= N_VALUE; if( sign_bit ) { int i; for( i = 0; i < N_VALUE; i++ ) { val |= (0x80000000 >> i); } } SET_DREG(val); SET_Z( val == 0 ? 1 : 0 ); SET_N( SIGN_BIT(val) ); hyperstone_ICount -= 1; } static void hyperstone_shli(void) { UINT32 val, val2; UINT64 mask; val = DREG; SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x80000000)?1:0):0); mask = ((((UINT64)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; val2 = val << N_VALUE; if( ((val & mask) && (!(val2 & 0x80000000))) || (((val & mask) ^ mask) && (val2 & 0x80000000)) ) SET_V(1); else SET_V(0); SET_DREG(val2); SET_Z( val2 == 0 ? 1 : 0 ); SET_N( SIGN_BIT(val2) ); hyperstone_ICount -= 1; } static void hyperstone_mulu(void) { UINT32 low_order, high_order; UINT64 double_word; // PC or SR aren't denoted, else result is undefined if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) { logerror("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC); } else { double_word = (UINT64)SREG *(UINT64)DREG; low_order = double_word & 0xffffffff; high_order = double_word >> 32; SET_DREG(high_order); SET_DREGF(low_order); SET_Z( double_word == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); } if(SREG <= 0xffff && DREG <= 0xffff) hyperstone_ICount -= 4; else hyperstone_ICount -= 6; } static void hyperstone_muls(void) { UINT32 low_order, high_order; INT64 double_word; // PC or SR aren't denoted, else result is undefined if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) { logerror("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC); } else { double_word = (INT64)(INT32)(SREG) * (INT64)(INT32)(DREG); low_order = double_word & 0xffffffff; high_order = double_word >> 32; SET_DREG(high_order); SET_DREGF(low_order); SET_Z( double_word == 0 ? 1 : 0 ); SET_N( SIGN_BIT(high_order) ); } if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) hyperstone_ICount -= 4; else hyperstone_ICount -= 6; } static void hyperstone_set(void) { int n = N_VALUE; if( DST_IS_PC ) { logerror("Denoted PC in hyperstone_set. PC = %08X\n", PC); } else if( DST_IS_SR ) { //TODO: add fetch opcode when there's the pipeline //TODO: no 1! hyperstone_ICount -= 1; } else { switch( n ) { // SETADR case 0: { UINT32 val; val = (SP & 0xfffffe00) | (GET_FP << 2); //plus carry into bit 9 val += (( (SP & 0x100) && (SIGN_BIT(SR) == 0) ) ? 1 : 0); SET_DREG(val); break; } // Reserved case 1: case 16: case 17: case 19: logerror("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC); break; // SETxx case 2: SET_DREG(1); break; case 3: SET_DREG(0); break; case 4: if( GET_N || GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 5: if( !GET_N && !GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 6: if( GET_N ) { SET_DREG(1); } else { SET_DREG(0); } break; case 7: if( !GET_N ) { SET_DREG(1); } else { SET_DREG(0); } break; case 8: if( GET_C || GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 9: if( !GET_C && !GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 10: if( GET_C ) { SET_DREG(1); } else { SET_DREG(0); } break; case 11: if( !GET_C ) { SET_DREG(1); } else { SET_DREG(0); } break; case 12: if( GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 13: if( !GET_Z ) { SET_DREG(1); } else { SET_DREG(0); } break; case 14: if( GET_V ) { SET_DREG(1); } else { SET_DREG(0); } break; case 15: if( !GET_V ) { SET_DREG(1); } else { SET_DREG(0); } break; case 18: SET_DREG(-1); break; case 20: if( GET_N || GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 21: if( !GET_N && !GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 22: if( GET_N ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 23: if( !GET_N ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 24: if( GET_C || GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 25: if( !GET_C && !GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 26: if( GET_C ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 27: if( !GET_C ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 28: if( GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 29: if( !GET_Z ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 30: if( GET_V ) { SET_DREG(-1); } else { SET_DREG(0); } break; case 31: if( !GET_V ) { SET_DREG(-1); } else { SET_DREG(0); } break; } hyperstone_ICount -= 1; } } static void hyperstone_mul(void) { UINT32 single_word; // PC or SR aren't denoted, else result is undefined if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) { logerror("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC); } else { single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken SET_DREG(single_word); SET_Z( single_word == 0 ? 1 : 0 ); SET_N( SIGN_BIT(single_word) ); } if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) hyperstone_ICount -= 3; else hyperstone_ICount -= 5; } static void hyperstone_fadd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_faddd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fsub(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fsubd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fmul(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fmuld(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fdiv(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fdivd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcmp(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcmpd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcmpu(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcmpud(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcvt(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_fcvtd(void) { execute_software(); hyperstone_ICount -= 6; } static void hyperstone_extend(void) { //TODO: add locks, overflow error and other things UINT32 vals, vald; vals = SREG; vald = DREG; switch( EXTRA_U ) // extended opcode { // signed or unsigned multiplication, single word product case EMUL: case 0x100: // used in "N" type cpu { UINT32 result; result = vals * vald; SET_G_REG(15, result); break; } // unsigned multiplication, double word product case EMULU: { UINT64 result; result = (UINT64)vals * (UINT64)vald; vals = result >> 32; vald = result & 0xffffffff; SET_G_REG(14, vals); SET_G_REG(15, vald); break; } // signed multiplication, double word product case EMULS: { INT64 result; result = (INT64)(INT32)(vals) * (INT64)(INT32)(vald); vals = result >> 32; vald = result & 0xffffffff; SET_G_REG(14, vals); SET_G_REG(15, vald); break; } // signed multiply/add, single word product sum case EMAC: { INT32 result; result = (INT32)GET_G_REG(15) + ((INT32)(vals) * (INT32)(vald)); SET_G_REG(15, result); break; } // signed multiply/add, double word product sum case EMACD: { INT64 result; result = (INT64)COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) + (INT64)((INT64)(INT32)(vals) * (INT64)(INT32)(vald)); vals = result >> 32; vald = result & 0xffffffff; SET_G_REG(14, vals); SET_G_REG(15, vald); break; } // signed multiply/substract, single word product difference case EMSUB: { INT32 result; result = (INT32)GET_G_REG(15) - ((INT32)(vals) * (INT32)(vald)); SET_G_REG(15, result); break; } // signed multiply/substract, double word product difference case EMSUBD: { INT64 result; result = (INT64)COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) - (INT64)((INT64)(INT32)(vals) * (INT64)(INT32)(vald)); vals = result >> 32; vald = result & 0xffffffff; SET_G_REG(14, vals); SET_G_REG(15, vald); break; } // signed half-word multiply/add, single word product sum case EHMAC: { INT32 result; result = (INT32)GET_G_REG(15) + ((INT32)((vald & 0xffff0000) >> 16) * (INT32)((vals & 0xffff0000) >> 16)) + ((INT32)(vald & 0xffff) * (INT32)(vals & 0xffff)); SET_G_REG(15, result); break; } // signed half-word multiply/add, double word product sum case EHMACD: { INT64 result; result = (INT64)COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) + (INT64)((INT64)(INT32)((vald & 0xffff0000) >> 16) * (INT64)(INT32)((vals & 0xffff0000) >> 16)) + ((INT64)(INT32)(vald & 0xffff) * (INT64)(INT32)(vals & 0xffff)); vals = result >> 32; vald = result & 0xffffffff; SET_G_REG(14, vals); SET_G_REG(15, vald); break; } // half-word complex multiply case EHCMULD: { UINT32 result; result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); SET_G_REG(14, result); result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); SET_G_REG(15, result); break; } // half-word complex multiply/add case EHCMACD: { UINT32 result; result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); SET_G_REG(14, result); result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); SET_G_REG(15, result); break; } // half-word (complex) add/substract // Ls is not used and should denote the same register as Ld case EHCSUMD: { UINT32 result; result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000; result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff; SET_G_REG(14, result); result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000; result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff; SET_G_REG(15, result); break; } // half-word (complex) add/substract with fixed point adjustment // Ls is not used and should denote the same register as Ld case EHCFFTD: { UINT32 result; result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff; SET_G_REG(14, result); result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff; SET_G_REG(15, result); break; } // half-word (complex) add/substract with fixed point adjustment and shift // Ls is not used and should denote the same register as Ld case EHCFFTSD: { UINT32 result; result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff); SET_G_REG(14, result); result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff); SET_G_REG(15, result); break; } default: logerror("Executed Illegal extended opcode (%X). PC = %08X\n", EXTRA_U, PC); break; } hyperstone_ICount -= 1; //TODO: with the latency it can change } static void hyperstone_do(void) { fatalerror("Executed hyperstone_do instruction. PC = %08X", PPC); } static void hyperstone_ldwr(void) { SET_SREG(READ_W(DREG)); hyperstone_ICount -= 1; } static void hyperstone_lddr(void) { SET_SREG(READ_W(DREG)); SET_SREGF(READ_W(DREG + 4)); hyperstone_ICount -= 2; } static void hyperstone_ldwp(void) { SET_SREG(READ_W(DREG)); // post increment the destination register if it's different from the source one // (needed by Hidden Catch) if(!(current_regs.src == current_regs.dst && S_BIT == LOCAL)) SET_DREG(DREG + 4); hyperstone_ICount -= 1; } static void hyperstone_lddp(void) { SET_SREG(READ_W(DREG)); SET_SREGF(READ_W(DREG + 4)); // post increment the destination register if it's different from the source one // and from the "next source" one if(!(current_regs.src == current_regs.dst && S_BIT == LOCAL) && !SAME_SRCF_DST ) { SET_DREG(DREG + 8); } else { popmessage("LDD.P denoted same regs @ %08X",PPC); } hyperstone_ICount -= 2; } static void hyperstone_stwr(void) { if( SRC_IS_SR ) SREG = 0; WRITE_W(DREG, SREG); hyperstone_ICount -= 1; } static void hyperstone_stdr(void) { if( SRC_IS_SR ) SREG = SREGF = 0; WRITE_W(DREG, SREG); WRITE_W(DREG + 4, SREGF); hyperstone_ICount -= 2; } static void hyperstone_stwp(void) { if( SRC_IS_SR ) SREG = 0; WRITE_W(DREG, SREG); SET_DREG(DREG + 4); hyperstone_ICount -= 1; } static void hyperstone_stdp(void) { if( SRC_IS_SR ) SREG = SREGF = 0; WRITE_W(DREG, SREG); SET_DREG(DREG + 8); if( SAME_SRCF_DST ) WRITE_W(DREG + 4, SREGF + 8); // because DREG == SREGF and DREG has been incremented else WRITE_W(DREG + 4, SREGF); hyperstone_ICount -= 2; } static void hyperstone_dbv(void) { if( GET_V ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbnv(void) { if( !GET_V ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbe(void) //or DBZ { if( GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbne(void) //or DBNZ { if( !GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbc(void) //or DBST { if( GET_C ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbnc(void) //or DBHE { if( !GET_C ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbse(void) { if( GET_C || GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbht(void) { if( !GET_C && !GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbn(void) //or DBLT { if( GET_N ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbnn(void) //or DBGE { if( !GET_N ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dble(void) { if( GET_N || GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbgt(void) { if( !GET_N && !GET_Z ) execute_dbr(); hyperstone_ICount -= 1; } static void hyperstone_dbr(void) { execute_dbr(); } static void hyperstone_frame(void) { INT8 difference; // really it's 7 bits UINT8 realfp = GET_FP - SRC_CODE; SET_FP(realfp); SET_FL(DST_CODE); SET_M(0); difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); /* convert to 8 bits */ if(difference > 63) difference = (INT8)(difference|0x80); else if( difference < -64 ) difference = difference & 0x7f; if( difference < 0 ) // else it's finished { UINT8 tmp_flag; tmp_flag = ( SP >= UB ? 1 : 0 ); do { WRITE_W(SP, GET_ABS_L_REG((SP & 0xfc) >> 2)); SP += 4; difference++; } while(difference != 0); if( tmp_flag ) { UINT32 addr = get_trap_addr(FRAME_ERROR); execute_exception(addr); } } //TODO: no 1! hyperstone_ICount -= 1; } static void hyperstone_call(void) { if( SRC_IS_SR ) SREG = 0; if( !DST_CODE ) current_regs.dst = 16; EXTRA_S = (EXTRA_S & ~1) + SREG; SET_ILC(hyperstone.instruction_length & 3); SET_DREG((PC & 0xfffffffe) | GET_S); SET_DREGF(SR); SET_FP(GET_FP + current_regs.dst); SET_FL(6); //default value for call SET_M(0); PPC = PC; PC = EXTRA_S; // const value change_pc(PC); hyperstone.intblock = 2; //TODO: add interrupt locks, errors, .... //TODO: no 1! hyperstone_ICount -= 1; } static void hyperstone_bv(void) { if( GET_V ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bnv(void) { if( !GET_V ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_be(void) //or BZ { if( GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bne(void) //or BNZ { if( !GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bc(void) //or BST { if( GET_C ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bnc(void) //or BHE { if( !GET_C ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bse(void) { if( GET_C || GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bht(void) { if( !GET_C && !GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bn(void) //or BLT { if( GET_N ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bnn(void) //or BGE { if( !GET_N ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_ble(void) { if( GET_N || GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_bgt(void) { if( !GET_N && !GET_Z ) execute_br(); else hyperstone_ICount -= 1; } static void hyperstone_br(void) { execute_br(); } static void hyperstone_trap(void) { UINT8 code, trapno; UINT32 addr; trapno = (OP & 0xfc) >> 2; addr = get_trap_addr(trapno); code = ((OP & 0x300) >> 6) | (OP & 0x03); switch( code ) { case TRAPLE: if( GET_N || GET_Z ) execute_trap(addr); break; case TRAPGT: if( !GET_N && !GET_Z ) execute_trap(addr); break; case TRAPLT: if( GET_N ) execute_trap(addr); break; case TRAPGE: if( !GET_N ) execute_trap(addr); break; case TRAPSE: if( GET_C || GET_Z ) execute_trap(addr); break; case TRAPHT: if( !GET_C && !GET_Z ) execute_trap(addr); break; case TRAPST: if( GET_C ) execute_trap(addr); break; case TRAPHE: if( !GET_C ) execute_trap(addr); break; case TRAPE: if( GET_Z ) execute_trap(addr); break; case TRAPNE: if( !GET_Z ) execute_trap(addr); break; case TRAPV: if( GET_V ) execute_trap(addr); break; case TRAP: execute_trap(addr); break; } hyperstone_ICount -= 1; } /************************************************************************** * Generic set_info **************************************************************************/ static void hyperstone_set_info(UINT32 state, cpuinfo *info) { switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + E132XS_PC: PC = info->i; change_pc(PC); break; case CPUINFO_INT_REGISTER + E132XS_SR: SR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_FER: FER = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G3: hyperstone.global_regs[3] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G4: hyperstone.global_regs[4] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G5: hyperstone.global_regs[5] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G6: hyperstone.global_regs[6] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G7: hyperstone.global_regs[7] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G8: hyperstone.global_regs[8] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G9: hyperstone.global_regs[9] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G10: hyperstone.global_regs[10] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G11: hyperstone.global_regs[11] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G12: hyperstone.global_regs[12] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G13: hyperstone.global_regs[13] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G14: hyperstone.global_regs[14] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G15: hyperstone.global_regs[15] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G16: hyperstone.global_regs[16] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G17: hyperstone.global_regs[17] = info->i; break; case CPUINFO_INT_SP: case CPUINFO_INT_REGISTER + E132XS_SP: SP = info->i; break; case CPUINFO_INT_REGISTER + E132XS_UB: UB = info->i; break; case CPUINFO_INT_REGISTER + E132XS_BCR: BCR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_TPR: TPR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_TCR: TCR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_TR: TR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_WCR: WCR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_ISR: ISR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_FCR: FCR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_MCR: MCR = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G28: hyperstone.global_regs[28] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G29: hyperstone.global_regs[29] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G30: hyperstone.global_regs[30] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_G31: hyperstone.global_regs[31] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL0: hyperstone.local_regs[(0 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL1: hyperstone.local_regs[(1 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL2: hyperstone.local_regs[(2 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL3: hyperstone.local_regs[(3 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL4: hyperstone.local_regs[(4 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL5: hyperstone.local_regs[(5 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL6: hyperstone.local_regs[(6 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL7: hyperstone.local_regs[(7 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL8: hyperstone.local_regs[(8 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL9: hyperstone.local_regs[(9 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL10: hyperstone.local_regs[(10 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL11: hyperstone.local_regs[(11 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL12: hyperstone.local_regs[(12 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL13: hyperstone.local_regs[(13 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL14: hyperstone.local_regs[(14 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_CL15: hyperstone.local_regs[(15 + GET_FP) % 64] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L0: hyperstone.local_regs[0] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L1: hyperstone.local_regs[1] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L2: hyperstone.local_regs[2] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L3: hyperstone.local_regs[3] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L4: hyperstone.local_regs[4] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L5: hyperstone.local_regs[5] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L6: hyperstone.local_regs[6] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L7: hyperstone.local_regs[7] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L8: hyperstone.local_regs[8] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L9: hyperstone.local_regs[9] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L10: hyperstone.local_regs[10] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L11: hyperstone.local_regs[11] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L12: hyperstone.local_regs[12] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L13: hyperstone.local_regs[13] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L14: hyperstone.local_regs[14] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L15: hyperstone.local_regs[15] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L16: hyperstone.local_regs[16] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L17: hyperstone.local_regs[17] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L18: hyperstone.local_regs[18] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L19: hyperstone.local_regs[19] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L20: hyperstone.local_regs[20] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L21: hyperstone.local_regs[21] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L22: hyperstone.local_regs[22] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L23: hyperstone.local_regs[23] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L24: hyperstone.local_regs[24] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L25: hyperstone.local_regs[25] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L26: hyperstone.local_regs[26] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L27: hyperstone.local_regs[27] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L28: hyperstone.local_regs[28] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L29: hyperstone.local_regs[29] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L30: hyperstone.local_regs[30] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L31: hyperstone.local_regs[31] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L32: hyperstone.local_regs[32] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L33: hyperstone.local_regs[33] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L34: hyperstone.local_regs[34] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L35: hyperstone.local_regs[35] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L36: hyperstone.local_regs[36] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L37: hyperstone.local_regs[37] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L38: hyperstone.local_regs[38] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L39: hyperstone.local_regs[39] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L40: hyperstone.local_regs[40] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L41: hyperstone.local_regs[41] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L42: hyperstone.local_regs[42] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L43: hyperstone.local_regs[43] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L44: hyperstone.local_regs[44] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L45: hyperstone.local_regs[45] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L46: hyperstone.local_regs[46] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L47: hyperstone.local_regs[47] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L48: hyperstone.local_regs[48] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L49: hyperstone.local_regs[49] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L50: hyperstone.local_regs[50] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L51: hyperstone.local_regs[51] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L52: hyperstone.local_regs[52] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L53: hyperstone.local_regs[53] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L54: hyperstone.local_regs[54] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L55: hyperstone.local_regs[55] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L56: hyperstone.local_regs[56] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L57: hyperstone.local_regs[57] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L58: hyperstone.local_regs[58] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L59: hyperstone.local_regs[59] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L60: hyperstone.local_regs[60] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L61: hyperstone.local_regs[61] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L62: hyperstone.local_regs[62] = info->i; break; case CPUINFO_INT_REGISTER + E132XS_L63: hyperstone.local_regs[63] = info->i; break; case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break; case CPUINFO_INT_INPUT_STATE + 1: set_irq_line(1, info->i); break; case CPUINFO_INT_INPUT_STATE + 2: set_irq_line(2, info->i); break; case CPUINFO_INT_INPUT_STATE + 3: set_irq_line(3, info->i); break; case CPUINFO_INT_INPUT_STATE + 4: set_irq_line(4, info->i); break; case CPUINFO_INT_INPUT_STATE + 5: set_irq_line(5, info->i); break; case CPUINFO_INT_INPUT_STATE + 6: set_irq_line(6, info->i); break; case CPUINFO_INT_INPUT_STATE + 7: set_irq_line(7, info->i); break; } } /************************************************************************** * Generic get_info **************************************************************************/ void hyperstone_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(hyperstone_regs); break; case CPUINFO_INT_INPUT_LINES: info->i = 8; 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 = 2; break; case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 6; break; case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; case CPUINFO_INT_MAX_CYCLES: info->i = 36; break; case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; 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_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 15; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; case CPUINFO_INT_INPUT_STATE + 0: /* not implemented */ break; case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break; case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + E132XS_PC: info->i = PC; break; case CPUINFO_INT_REGISTER + E132XS_SR: info->i = SR; break; case CPUINFO_INT_REGISTER + E132XS_FER: info->i = FER; break; case CPUINFO_INT_REGISTER + E132XS_G3: info->i = hyperstone.global_regs[3]; break; case CPUINFO_INT_REGISTER + E132XS_G4: info->i = hyperstone.global_regs[4]; break; case CPUINFO_INT_REGISTER + E132XS_G5: info->i = hyperstone.global_regs[5]; break; case CPUINFO_INT_REGISTER + E132XS_G6: info->i = hyperstone.global_regs[6]; break; case CPUINFO_INT_REGISTER + E132XS_G7: info->i = hyperstone.global_regs[7]; break; case CPUINFO_INT_REGISTER + E132XS_G8: info->i = hyperstone.global_regs[8]; break; case CPUINFO_INT_REGISTER + E132XS_G9: info->i = hyperstone.global_regs[9]; break; case CPUINFO_INT_REGISTER + E132XS_G10: info->i = hyperstone.global_regs[10]; break; case CPUINFO_INT_REGISTER + E132XS_G11: info->i = hyperstone.global_regs[11]; break; case CPUINFO_INT_REGISTER + E132XS_G12: info->i = hyperstone.global_regs[12]; break; case CPUINFO_INT_REGISTER + E132XS_G13: info->i = hyperstone.global_regs[13]; break; case CPUINFO_INT_REGISTER + E132XS_G14: info->i = hyperstone.global_regs[14]; break; case CPUINFO_INT_REGISTER + E132XS_G15: info->i = hyperstone.global_regs[15]; break; case CPUINFO_INT_REGISTER + E132XS_G16: info->i = hyperstone.global_regs[16]; break; case CPUINFO_INT_REGISTER + E132XS_G17: info->i = hyperstone.global_regs[17]; break; case CPUINFO_INT_SP: case CPUINFO_INT_REGISTER + E132XS_SP: info->i = SP; break; case CPUINFO_INT_REGISTER + E132XS_UB: info->i = UB; break; case CPUINFO_INT_REGISTER + E132XS_BCR: info->i = BCR; break; case CPUINFO_INT_REGISTER + E132XS_TPR: info->i = TPR; break; case CPUINFO_INT_REGISTER + E132XS_TCR: info->i = TCR; break; case CPUINFO_INT_REGISTER + E132XS_TR: info->i = TR; break; case CPUINFO_INT_REGISTER + E132XS_WCR: info->i = WCR; break; case CPUINFO_INT_REGISTER + E132XS_ISR: info->i = ISR; break; case CPUINFO_INT_REGISTER + E132XS_FCR: info->i = FCR; break; case CPUINFO_INT_REGISTER + E132XS_MCR: info->i = MCR; break; case CPUINFO_INT_REGISTER + E132XS_G28: info->i = hyperstone.global_regs[28]; break; case CPUINFO_INT_REGISTER + E132XS_G29: info->i = hyperstone.global_regs[29]; break; case CPUINFO_INT_REGISTER + E132XS_G30: info->i = hyperstone.global_regs[30]; break; case CPUINFO_INT_REGISTER + E132XS_G31: info->i = hyperstone.global_regs[31]; break; case CPUINFO_INT_REGISTER + E132XS_CL0: info->i = hyperstone.local_regs[(0 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL1: info->i = hyperstone.local_regs[(1 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL2: info->i = hyperstone.local_regs[(2 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL3: info->i = hyperstone.local_regs[(3 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL4: info->i = hyperstone.local_regs[(4 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL5: info->i = hyperstone.local_regs[(5 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL6: info->i = hyperstone.local_regs[(6 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL7: info->i = hyperstone.local_regs[(7 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL8: info->i = hyperstone.local_regs[(8 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL9: info->i = hyperstone.local_regs[(9 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL10: info->i = hyperstone.local_regs[(10 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL11: info->i = hyperstone.local_regs[(11 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL12: info->i = hyperstone.local_regs[(12 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL13: info->i = hyperstone.local_regs[(13 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL14: info->i = hyperstone.local_regs[(14 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_CL15: info->i = hyperstone.local_regs[(15 + GET_FP) % 64]; break; case CPUINFO_INT_REGISTER + E132XS_L0: info->i = hyperstone.local_regs[0]; break; case CPUINFO_INT_REGISTER + E132XS_L1: info->i = hyperstone.local_regs[1]; break; case CPUINFO_INT_REGISTER + E132XS_L2: info->i = hyperstone.local_regs[2]; break; case CPUINFO_INT_REGISTER + E132XS_L3: info->i = hyperstone.local_regs[3]; break; case CPUINFO_INT_REGISTER + E132XS_L4: info->i = hyperstone.local_regs[4]; break; case CPUINFO_INT_REGISTER + E132XS_L5: info->i = hyperstone.local_regs[5]; break; case CPUINFO_INT_REGISTER + E132XS_L6: info->i = hyperstone.local_regs[6]; break; case CPUINFO_INT_REGISTER + E132XS_L7: info->i = hyperstone.local_regs[7]; break; case CPUINFO_INT_REGISTER + E132XS_L8: info->i = hyperstone.local_regs[8]; break; case CPUINFO_INT_REGISTER + E132XS_L9: info->i = hyperstone.local_regs[9]; break; case CPUINFO_INT_REGISTER + E132XS_L10: info->i = hyperstone.local_regs[10]; break; case CPUINFO_INT_REGISTER + E132XS_L11: info->i = hyperstone.local_regs[11]; break; case CPUINFO_INT_REGISTER + E132XS_L12: info->i = hyperstone.local_regs[12]; break; case CPUINFO_INT_REGISTER + E132XS_L13: info->i = hyperstone.local_regs[13]; break; case CPUINFO_INT_REGISTER + E132XS_L14: info->i = hyperstone.local_regs[14]; break; case CPUINFO_INT_REGISTER + E132XS_L15: info->i = hyperstone.local_regs[15]; break; case CPUINFO_INT_REGISTER + E132XS_L16: info->i = hyperstone.local_regs[16]; break; case CPUINFO_INT_REGISTER + E132XS_L17: info->i = hyperstone.local_regs[17]; break; case CPUINFO_INT_REGISTER + E132XS_L18: info->i = hyperstone.local_regs[18]; break; case CPUINFO_INT_REGISTER + E132XS_L19: info->i = hyperstone.local_regs[19]; break; case CPUINFO_INT_REGISTER + E132XS_L20: info->i = hyperstone.local_regs[20]; break; case CPUINFO_INT_REGISTER + E132XS_L21: info->i = hyperstone.local_regs[21]; break; case CPUINFO_INT_REGISTER + E132XS_L22: info->i = hyperstone.local_regs[22]; break; case CPUINFO_INT_REGISTER + E132XS_L23: info->i = hyperstone.local_regs[23]; break; case CPUINFO_INT_REGISTER + E132XS_L24: info->i = hyperstone.local_regs[24]; break; case CPUINFO_INT_REGISTER + E132XS_L25: info->i = hyperstone.local_regs[25]; break; case CPUINFO_INT_REGISTER + E132XS_L26: info->i = hyperstone.local_regs[26]; break; case CPUINFO_INT_REGISTER + E132XS_L27: info->i = hyperstone.local_regs[27]; break; case CPUINFO_INT_REGISTER + E132XS_L28: info->i = hyperstone.local_regs[28]; break; case CPUINFO_INT_REGISTER + E132XS_L29: info->i = hyperstone.local_regs[29]; break; case CPUINFO_INT_REGISTER + E132XS_L30: info->i = hyperstone.local_regs[30]; break; case CPUINFO_INT_REGISTER + E132XS_L31: info->i = hyperstone.local_regs[31]; break; case CPUINFO_INT_REGISTER + E132XS_L32: info->i = hyperstone.local_regs[32]; break; case CPUINFO_INT_REGISTER + E132XS_L33: info->i = hyperstone.local_regs[33]; break; case CPUINFO_INT_REGISTER + E132XS_L34: info->i = hyperstone.local_regs[34]; break; case CPUINFO_INT_REGISTER + E132XS_L35: info->i = hyperstone.local_regs[35]; break; case CPUINFO_INT_REGISTER + E132XS_L36: info->i = hyperstone.local_regs[36]; break; case CPUINFO_INT_REGISTER + E132XS_L37: info->i = hyperstone.local_regs[37]; break; case CPUINFO_INT_REGISTER + E132XS_L38: info->i = hyperstone.local_regs[38]; break; case CPUINFO_INT_REGISTER + E132XS_L39: info->i = hyperstone.local_regs[39]; break; case CPUINFO_INT_REGISTER + E132XS_L40: info->i = hyperstone.local_regs[40]; break; case CPUINFO_INT_REGISTER + E132XS_L41: info->i = hyperstone.local_regs[41]; break; case CPUINFO_INT_REGISTER + E132XS_L42: info->i = hyperstone.local_regs[42]; break; case CPUINFO_INT_REGISTER + E132XS_L43: info->i = hyperstone.local_regs[43]; break; case CPUINFO_INT_REGISTER + E132XS_L44: info->i = hyperstone.local_regs[44]; break; case CPUINFO_INT_REGISTER + E132XS_L45: info->i = hyperstone.local_regs[45]; break; case CPUINFO_INT_REGISTER + E132XS_L46: info->i = hyperstone.local_regs[46]; break; case CPUINFO_INT_REGISTER + E132XS_L47: info->i = hyperstone.local_regs[47]; break; case CPUINFO_INT_REGISTER + E132XS_L48: info->i = hyperstone.local_regs[48]; break; case CPUINFO_INT_REGISTER + E132XS_L49: info->i = hyperstone.local_regs[49]; break; case CPUINFO_INT_REGISTER + E132XS_L50: info->i = hyperstone.local_regs[50]; break; case CPUINFO_INT_REGISTER + E132XS_L51: info->i = hyperstone.local_regs[51]; break; case CPUINFO_INT_REGISTER + E132XS_L52: info->i = hyperstone.local_regs[52]; break; case CPUINFO_INT_REGISTER + E132XS_L53: info->i = hyperstone.local_regs[53]; break; case CPUINFO_INT_REGISTER + E132XS_L54: info->i = hyperstone.local_regs[54]; break; case CPUINFO_INT_REGISTER + E132XS_L55: info->i = hyperstone.local_regs[55]; break; case CPUINFO_INT_REGISTER + E132XS_L56: info->i = hyperstone.local_regs[56]; break; case CPUINFO_INT_REGISTER + E132XS_L57: info->i = hyperstone.local_regs[57]; break; case CPUINFO_INT_REGISTER + E132XS_L58: info->i = hyperstone.local_regs[58]; break; case CPUINFO_INT_REGISTER + E132XS_L59: info->i = hyperstone.local_regs[59]; break; case CPUINFO_INT_REGISTER + E132XS_L60: info->i = hyperstone.local_regs[60]; break; case CPUINFO_INT_REGISTER + E132XS_L61: info->i = hyperstone.local_regs[61]; break; case CPUINFO_INT_REGISTER + E132XS_L62: info->i = hyperstone.local_regs[62]; break; case CPUINFO_INT_REGISTER + E132XS_L63: info->i = hyperstone.local_regs[63]; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_SET_INFO: info->setinfo = hyperstone_set_info; break; case CPUINFO_PTR_GET_CONTEXT: info->getcontext = hyperstone_get_context; break; case CPUINFO_PTR_SET_CONTEXT: info->setcontext = hyperstone_set_context; break; case CPUINFO_PTR_INIT: info->init = hyperstone_init; break; case CPUINFO_PTR_RESET: info->reset = hyperstone_reset; break; case CPUINFO_PTR_EXIT: info->exit = hyperstone_exit; break; case CPUINFO_PTR_EXECUTE: info->execute = hyperstone_execute; break; case CPUINFO_PTR_BURN: info->burn = NULL; break; #ifdef MAME_DEBUG case CPUINFO_PTR_DISASSEMBLE: info->disassemble = hyperstone_dasm; break; #endif /* MAME_DEBUG */ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &hyperstone_ICount; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map = 0; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map = 0; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Hyperstone CPU"); break; case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "0.9"); break; case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Pierpaolo Prazzoli and Ryan Holtz"); break; case CPUINFO_STR_FLAGS: sprintf(info->s, "%c%c%c%c%c%c%c%c%c%c%c%c FTE:%X FRM:%X ILC:%d FL:%d FP:%d", GET_S ? 'S':'.', GET_P ? 'P':'.', GET_T ? 'T':'.', GET_L ? 'L':'.', GET_I ? 'I':'.', hyperstone.global_regs[1] & 0x00040 ? '?':'.', GET_H ? 'H':'.', GET_M ? 'M':'.', GET_V ? 'V':'.', GET_N ? 'N':'.', GET_Z ? 'Z':'.', GET_C ? 'C':'.', GET_FTE, GET_FRM, GET_ILC, GET_FL, GET_FP); break; case CPUINFO_STR_REGISTER + E132XS_PC: sprintf(info->s, "PC :%08X", hyperstone.global_regs[0]); break; case CPUINFO_STR_REGISTER + E132XS_SR: sprintf(info->s, "SR :%08X", hyperstone.global_regs[1]); break; case CPUINFO_STR_REGISTER + E132XS_FER: sprintf(info->s, "FER :%08X", hyperstone.global_regs[2]); break; case CPUINFO_STR_REGISTER + E132XS_G3: sprintf(info->s, "G3 :%08X", hyperstone.global_regs[3]); break; case CPUINFO_STR_REGISTER + E132XS_G4: sprintf(info->s, "G4 :%08X", hyperstone.global_regs[4]); break; case CPUINFO_STR_REGISTER + E132XS_G5: sprintf(info->s, "G5 :%08X", hyperstone.global_regs[5]); break; case CPUINFO_STR_REGISTER + E132XS_G6: sprintf(info->s, "G6 :%08X", hyperstone.global_regs[6]); break; case CPUINFO_STR_REGISTER + E132XS_G7: sprintf(info->s, "G7 :%08X", hyperstone.global_regs[7]); break; case CPUINFO_STR_REGISTER + E132XS_G8: sprintf(info->s, "G8 :%08X", hyperstone.global_regs[8]); break; case CPUINFO_STR_REGISTER + E132XS_G9: sprintf(info->s, "G9 :%08X", hyperstone.global_regs[9]); break; case CPUINFO_STR_REGISTER + E132XS_G10: sprintf(info->s, "G10 :%08X", hyperstone.global_regs[10]); break; case CPUINFO_STR_REGISTER + E132XS_G11: sprintf(info->s, "G11 :%08X", hyperstone.global_regs[11]); break; case CPUINFO_STR_REGISTER + E132XS_G12: sprintf(info->s, "G12 :%08X", hyperstone.global_regs[12]); break; case CPUINFO_STR_REGISTER + E132XS_G13: sprintf(info->s, "G13 :%08X", hyperstone.global_regs[13]); break; case CPUINFO_STR_REGISTER + E132XS_G14: sprintf(info->s, "G14 :%08X", hyperstone.global_regs[14]); break; case CPUINFO_STR_REGISTER + E132XS_G15: sprintf(info->s, "G15 :%08X", hyperstone.global_regs[15]); break; case CPUINFO_STR_REGISTER + E132XS_G16: sprintf(info->s, "G16 :%08X", hyperstone.global_regs[16]); break; case CPUINFO_STR_REGISTER + E132XS_G17: sprintf(info->s, "G17 :%08X", hyperstone.global_regs[17]); break; case CPUINFO_STR_REGISTER + E132XS_SP: sprintf(info->s, "SP :%08X", hyperstone.global_regs[18]); break; case CPUINFO_STR_REGISTER + E132XS_UB: sprintf(info->s, "UB :%08X", hyperstone.global_regs[19]); break; case CPUINFO_STR_REGISTER + E132XS_BCR: sprintf(info->s, "BCR :%08X", hyperstone.global_regs[20]); break; case CPUINFO_STR_REGISTER + E132XS_TPR: sprintf(info->s, "TPR :%08X", hyperstone.global_regs[21]); break; case CPUINFO_STR_REGISTER + E132XS_TCR: sprintf(info->s, "TCR :%08X", hyperstone.global_regs[22]); break; case CPUINFO_STR_REGISTER + E132XS_TR: sprintf(info->s, "TR :%08X", hyperstone.global_regs[23]); break; case CPUINFO_STR_REGISTER + E132XS_WCR: sprintf(info->s, "WCR :%08X", hyperstone.global_regs[24]); break; case CPUINFO_STR_REGISTER + E132XS_ISR: sprintf(info->s, "ISR :%08X", hyperstone.global_regs[25]); break; case CPUINFO_STR_REGISTER + E132XS_FCR: sprintf(info->s, "FCR :%08X", hyperstone.global_regs[26]); break; case CPUINFO_STR_REGISTER + E132XS_MCR: sprintf(info->s, "MCR :%08X", hyperstone.global_regs[27]); break; case CPUINFO_STR_REGISTER + E132XS_G28: sprintf(info->s, "G28 :%08X", hyperstone.global_regs[28]); break; case CPUINFO_STR_REGISTER + E132XS_G29: sprintf(info->s, "G29 :%08X", hyperstone.global_regs[29]); break; case CPUINFO_STR_REGISTER + E132XS_G30: sprintf(info->s, "G30 :%08X", hyperstone.global_regs[30]); break; case CPUINFO_STR_REGISTER + E132XS_G31: sprintf(info->s, "G31 :%08X", hyperstone.global_regs[31]); break; case CPUINFO_STR_REGISTER + E132XS_CL0: sprintf(info->s, "CL0 :%08X", hyperstone.local_regs[(0 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL1: sprintf(info->s, "CL1 :%08X", hyperstone.local_regs[(1 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL2: sprintf(info->s, "CL2 :%08X", hyperstone.local_regs[(2 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL3: sprintf(info->s, "CL3 :%08X", hyperstone.local_regs[(3 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL4: sprintf(info->s, "CL4 :%08X", hyperstone.local_regs[(4 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL5: sprintf(info->s, "CL5 :%08X", hyperstone.local_regs[(5 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL6: sprintf(info->s, "CL6 :%08X", hyperstone.local_regs[(6 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL7: sprintf(info->s, "CL7 :%08X", hyperstone.local_regs[(7 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL8: sprintf(info->s, "CL8 :%08X", hyperstone.local_regs[(8 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL9: sprintf(info->s, "CL9 :%08X", hyperstone.local_regs[(9 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL10: sprintf(info->s, "CL10:%08X", hyperstone.local_regs[(10 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL11: sprintf(info->s, "CL11:%08X", hyperstone.local_regs[(11 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL12: sprintf(info->s, "CL12:%08X", hyperstone.local_regs[(12 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL13: sprintf(info->s, "CL13:%08X", hyperstone.local_regs[(13 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL14: sprintf(info->s, "CL14:%08X", hyperstone.local_regs[(14 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_CL15: sprintf(info->s, "CL15:%08X", hyperstone.local_regs[(15 + GET_FP) % 64]); break; case CPUINFO_STR_REGISTER + E132XS_L0: sprintf(info->s, "L0 :%08X", hyperstone.local_regs[0]); break; case CPUINFO_STR_REGISTER + E132XS_L1: sprintf(info->s, "L1 :%08X", hyperstone.local_regs[1]); break; case CPUINFO_STR_REGISTER + E132XS_L2: sprintf(info->s, "L2 :%08X", hyperstone.local_regs[2]); break; case CPUINFO_STR_REGISTER + E132XS_L3: sprintf(info->s, "L3 :%08X", hyperstone.local_regs[3]); break; case CPUINFO_STR_REGISTER + E132XS_L4: sprintf(info->s, "L4 :%08X", hyperstone.local_regs[4]); break; case CPUINFO_STR_REGISTER + E132XS_L5: sprintf(info->s, "L5 :%08X", hyperstone.local_regs[5]); break; case CPUINFO_STR_REGISTER + E132XS_L6: sprintf(info->s, "L6 :%08X", hyperstone.local_regs[6]); break; case CPUINFO_STR_REGISTER + E132XS_L7: sprintf(info->s, "L7 :%08X", hyperstone.local_regs[7]); break; case CPUINFO_STR_REGISTER + E132XS_L8: sprintf(info->s, "L8 :%08X", hyperstone.local_regs[8]); break; case CPUINFO_STR_REGISTER + E132XS_L9: sprintf(info->s, "L9 :%08X", hyperstone.local_regs[9]); break; case CPUINFO_STR_REGISTER + E132XS_L10: sprintf(info->s, "L10 :%08X", hyperstone.local_regs[10]); break; case CPUINFO_STR_REGISTER + E132XS_L11: sprintf(info->s, "L11 :%08X", hyperstone.local_regs[11]); break; case CPUINFO_STR_REGISTER + E132XS_L12: sprintf(info->s, "L12 :%08X", hyperstone.local_regs[12]); break; case CPUINFO_STR_REGISTER + E132XS_L13: sprintf(info->s, "L13 :%08X", hyperstone.local_regs[13]); break; case CPUINFO_STR_REGISTER + E132XS_L14: sprintf(info->s, "L14 :%08X", hyperstone.local_regs[14]); break; case CPUINFO_STR_REGISTER + E132XS_L15: sprintf(info->s, "L15 :%08X", hyperstone.local_regs[15]); break; case CPUINFO_STR_REGISTER + E132XS_L16: sprintf(info->s, "L16 :%08X", hyperstone.local_regs[16]); break; case CPUINFO_STR_REGISTER + E132XS_L17: sprintf(info->s, "L17 :%08X", hyperstone.local_regs[17]); break; case CPUINFO_STR_REGISTER + E132XS_L18: sprintf(info->s, "L18 :%08X", hyperstone.local_regs[18]); break; case CPUINFO_STR_REGISTER + E132XS_L19: sprintf(info->s, "L19 :%08X", hyperstone.local_regs[19]); break; case CPUINFO_STR_REGISTER + E132XS_L20: sprintf(info->s, "L20 :%08X", hyperstone.local_regs[20]); break; case CPUINFO_STR_REGISTER + E132XS_L21: sprintf(info->s, "L21 :%08X", hyperstone.local_regs[21]); break; case CPUINFO_STR_REGISTER + E132XS_L22: sprintf(info->s, "L22 :%08X", hyperstone.local_regs[22]); break; case CPUINFO_STR_REGISTER + E132XS_L23: sprintf(info->s, "L23 :%08X", hyperstone.local_regs[23]); break; case CPUINFO_STR_REGISTER + E132XS_L24: sprintf(info->s, "L24 :%08X", hyperstone.local_regs[24]); break; case CPUINFO_STR_REGISTER + E132XS_L25: sprintf(info->s, "L25 :%08X", hyperstone.local_regs[25]); break; case CPUINFO_STR_REGISTER + E132XS_L26: sprintf(info->s, "L26 :%08X", hyperstone.local_regs[26]); break; case CPUINFO_STR_REGISTER + E132XS_L27: sprintf(info->s, "L27 :%08X", hyperstone.local_regs[27]); break; case CPUINFO_STR_REGISTER + E132XS_L28: sprintf(info->s, "L28 :%08X", hyperstone.local_regs[28]); break; case CPUINFO_STR_REGISTER + E132XS_L29: sprintf(info->s, "L29 :%08X", hyperstone.local_regs[29]); break; case CPUINFO_STR_REGISTER + E132XS_L30: sprintf(info->s, "L30 :%08X", hyperstone.local_regs[30]); break; case CPUINFO_STR_REGISTER + E132XS_L31: sprintf(info->s, "L31 :%08X", hyperstone.local_regs[31]); break; case CPUINFO_STR_REGISTER + E132XS_L32: sprintf(info->s, "L32 :%08X", hyperstone.local_regs[32]); break; case CPUINFO_STR_REGISTER + E132XS_L33: sprintf(info->s, "L33 :%08X", hyperstone.local_regs[33]); break; case CPUINFO_STR_REGISTER + E132XS_L34: sprintf(info->s, "L34 :%08X", hyperstone.local_regs[34]); break; case CPUINFO_STR_REGISTER + E132XS_L35: sprintf(info->s, "L35 :%08X", hyperstone.local_regs[35]); break; case CPUINFO_STR_REGISTER + E132XS_L36: sprintf(info->s, "L36 :%08X", hyperstone.local_regs[36]); break; case CPUINFO_STR_REGISTER + E132XS_L37: sprintf(info->s, "L37 :%08X", hyperstone.local_regs[37]); break; case CPUINFO_STR_REGISTER + E132XS_L38: sprintf(info->s, "L38 :%08X", hyperstone.local_regs[38]); break; case CPUINFO_STR_REGISTER + E132XS_L39: sprintf(info->s, "L39 :%08X", hyperstone.local_regs[39]); break; case CPUINFO_STR_REGISTER + E132XS_L40: sprintf(info->s, "L40 :%08X", hyperstone.local_regs[40]); break; case CPUINFO_STR_REGISTER + E132XS_L41: sprintf(info->s, "L41 :%08X", hyperstone.local_regs[41]); break; case CPUINFO_STR_REGISTER + E132XS_L42: sprintf(info->s, "L42 :%08X", hyperstone.local_regs[42]); break; case CPUINFO_STR_REGISTER + E132XS_L43: sprintf(info->s, "L43 :%08X", hyperstone.local_regs[43]); break; case CPUINFO_STR_REGISTER + E132XS_L44: sprintf(info->s, "L44 :%08X", hyperstone.local_regs[44]); break; case CPUINFO_STR_REGISTER + E132XS_L45: sprintf(info->s, "L45 :%08X", hyperstone.local_regs[45]); break; case CPUINFO_STR_REGISTER + E132XS_L46: sprintf(info->s, "L46 :%08X", hyperstone.local_regs[46]); break; case CPUINFO_STR_REGISTER + E132XS_L47: sprintf(info->s, "L47 :%08X", hyperstone.local_regs[47]); break; case CPUINFO_STR_REGISTER + E132XS_L48: sprintf(info->s, "L48 :%08X", hyperstone.local_regs[48]); break; case CPUINFO_STR_REGISTER + E132XS_L49: sprintf(info->s, "L49 :%08X", hyperstone.local_regs[49]); break; case CPUINFO_STR_REGISTER + E132XS_L50: sprintf(info->s, "L50 :%08X", hyperstone.local_regs[50]); break; case CPUINFO_STR_REGISTER + E132XS_L51: sprintf(info->s, "L51 :%08X", hyperstone.local_regs[51]); break; case CPUINFO_STR_REGISTER + E132XS_L52: sprintf(info->s, "L52 :%08X", hyperstone.local_regs[52]); break; case CPUINFO_STR_REGISTER + E132XS_L53: sprintf(info->s, "L53 :%08X", hyperstone.local_regs[53]); break; case CPUINFO_STR_REGISTER + E132XS_L54: sprintf(info->s, "L54 :%08X", hyperstone.local_regs[54]); break; case CPUINFO_STR_REGISTER + E132XS_L55: sprintf(info->s, "L55 :%08X", hyperstone.local_regs[55]); break; case CPUINFO_STR_REGISTER + E132XS_L56: sprintf(info->s, "L56 :%08X", hyperstone.local_regs[56]); break; case CPUINFO_STR_REGISTER + E132XS_L57: sprintf(info->s, "L57 :%08X", hyperstone.local_regs[57]); break; case CPUINFO_STR_REGISTER + E132XS_L58: sprintf(info->s, "L58 :%08X", hyperstone.local_regs[58]); break; case CPUINFO_STR_REGISTER + E132XS_L59: sprintf(info->s, "L59 :%08X", hyperstone.local_regs[59]); break; case CPUINFO_STR_REGISTER + E132XS_L60: sprintf(info->s, "L60 :%08X", hyperstone.local_regs[60]); break; case CPUINFO_STR_REGISTER + E132XS_L61: sprintf(info->s, "L61 :%08X", hyperstone.local_regs[61]); break; case CPUINFO_STR_REGISTER + E132XS_L62: sprintf(info->s, "L62 :%08X", hyperstone.local_regs[62]); break; case CPUINFO_STR_REGISTER + E132XS_L63: sprintf(info->s, "L63 :%08X", hyperstone.local_regs[63]); break; } } #if (HAS_E116T) void e116t_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_4k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-16T"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E116XT) void e116xt_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_8k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-16XT"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E116XS) void e116xs_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_16k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-16XS"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E116XSR) void e116xsr_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_16k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-16XSR"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132N) void e132n_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_4k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32N"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132T) void e132t_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_4k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32T"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132XN) void e132xn_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_8k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32XN"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132XT) void e132xt_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_8k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32XT"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132XS) void e132xs_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_16k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32XS"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_E132XSR) void e132xsr_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_16k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "E1-32XSR"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_GMS30C2116) void gms30c2116_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_4k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "GMS30C2116"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_GMS30C2132) void gms30c2132_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_4k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "GMS30C2132"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_GMS30C2216) void gms30c2216_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e116_8k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e116_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "GMS30C2216"); break; default: hyperstone_get_info(state, info); } } #endif #if (HAS_GMS30C2232) void gms30c2232_get_info(UINT32 state, cpuinfo *info) { switch (state) { case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break; case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 32; break; case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_e132_8k_iram_map; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case CPUINFO_PTR_INIT: info->init = e132_init; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case CPUINFO_STR_NAME: strcpy(info->s, "GMS30C2232"); break; default: hyperstone_get_info(state, info); } } #endif