(MESS) Added preliminary S+core CPU emulation. [Sandro Ronco]

(MESS) New NOT WORKING system
-----------------------
- Mattel HyperScan [Sandro Ronco]
This commit is contained in:
Sandro Ronco 2013-09-07 21:33:27 +00:00
parent 26b4b109ff
commit dbb4595fcc
9 changed files with 2602 additions and 0 deletions

5
.gitattributes vendored
View File

@ -794,6 +794,10 @@ src/emu/cpu/sc61860/sctable.c svneol=native#text/plain
src/emu/cpu/scmp/scmp.c svneol=native#text/plain
src/emu/cpu/scmp/scmp.h svneol=native#text/plain
src/emu/cpu/scmp/scmpdasm.c svneol=native#text/plain
src/emu/cpu/score/score.c svneol=native#text/plain
src/emu/cpu/score/score.h svneol=native#text/plain
src/emu/cpu/score/scoredsm.c svneol=native#text/plain
src/emu/cpu/score/scorem.h svneol=native#text/plain
src/emu/cpu/scudsp/scudspdasm.c svneol=native#text/plain
src/emu/cpu/se3208/se3208.c svneol=native#text/plain
src/emu/cpu/se3208/se3208.h svneol=native#text/plain
@ -6317,6 +6321,7 @@ src/mess/drivers/hpz80unk.c svneol=native#text/plain
src/mess/drivers/ht68k.c svneol=native#text/plain
src/mess/drivers/huebler.c svneol=native#text/plain
src/mess/drivers/hx20.c svneol=native#text/plain
src/mess/drivers/hyperscan.c svneol=native#text/plain
src/mess/drivers/ibm6580.c svneol=native#text/plain
src/mess/drivers/ibmpc.c svneol=native#text/plain
src/mess/drivers/ie15.c svneol=native#text/plain

View File

@ -2247,3 +2247,22 @@ endif
$(CPUOBJ)/scudsp/scudspdasm.o: CPUOBJS += $(CPUOBJ)/scudsp/scudspdasm.c
#-------------------------------------------------
# Sunplus Technology S+core
#@src/emu/cpu/score/score.h,CPUS += SCORE
#-------------------------------------------------
ifneq ($(filter SCORE,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/score
CPUOBJS += $(CPUOBJ)/score/score.o
DASMOBJS += $(CPUOBJ)/score/scoredsm.o
endif
$(CPUOBJ)/score/score.o: $(CPUSRC)/score/score.c \
$(CPUSRC)/score/score.h \
$(CPUSRC)/score/scorem.h
$(CPUOBJ)/score/scoredsm.o: $(CPUSRC)/score/scoredsm.c \
$(CPUSRC)/score/scorem.h

1346
src/emu/cpu/score/score.c Normal file

File diff suppressed because it is too large Load Diff

148
src/emu/cpu/score/score.h Normal file
View File

@ -0,0 +1,148 @@
/**********************************************************************
Sunplus Technology S+core
**********************************************************************/
#pragma once
#ifndef __SCORE_H__
#define __SCORE_H__
//**************************************************************************
// DEFINITION
//**************************************************************************
enum
{
SCORE_PC = 1,
SCORE_CEH,
SCORE_CEL,
SCORE_GPR,
SCORE_CR = SCORE_GPR + 0x20,
SCORE_SR = SCORE_CR + 0x20,
};
// ======================> score7_cpu_device
class score7_cpu_device : public cpu_device
{
public:
// construction/destruction
score7_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 1; }
virtual UINT32 execute_input_lines() const { return 64; }
virtual void execute_run();
virtual void execute_set_input(int inputnum, int state);
// device_state_interface overrides
void state_string_export(const device_state_entry &entry, astring &string);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
// device_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const { return 2; }
virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
private:
// helpers
bool check_condition_branch(UINT8 bc);
bool check_condition(UINT8 bc);
INT32 sign_extend(UINT32 data, UINT8 len);
UINT32 fetch();
UINT8 read_byte(offs_t offset);
UINT16 read_word(offs_t offset);
UINT32 read_dword(offs_t offset);
void write_byte(offs_t offset, UINT8 data);
void write_word(offs_t offset, UINT16 data);
void write_dword(offs_t offset, UINT32 data);
void check_irq();
void gen_exception(int cause, UINT32 param = 0);
offs_t disasm(char *buffer, offs_t pc, UINT32 opcode);
char *disasm32(char *buffer, offs_t pc, UINT32 opcode);
char *disasm16(char *buffer, offs_t pc, UINT16 opcode);
void unemulated_op(const char * op);
// 32-bit opcodes
void op_specialform();
void op_iform1();
void op_jump();
void op_rixform1();
void op_branch();
void op_iform2();
void op_crform();
void op_rixform2();
void op_addri();
void op_andri();
void op_orri();
void op_lw();
void op_lh();
void op_lhu();
void op_lb();
void op_sw();
void op_sh();
void op_lbu();
void op_sb();
void op_cache();
void op_cenew();
void op_undef();
// 16-bit opcodes
void op_rform1();
void op_rform2();
void op_jform();
void op_branch16();
void op_ldiu();
void op_iform1a();
void op_iform1b();
private:
address_space_config m_program_config;
address_space * m_program;
direct_read_data * m_direct;
// internal state
int m_icount;
UINT32 m_pc;
UINT32 m_ppc;
UINT32 m_op;
UINT32 m_gpr[0x20];
UINT32 m_cr[0x20];
UINT32 m_sr[3];
UINT32 m_ce[2];
bool m_pending_interrupt[64];
// opcodes tables
typedef void (score7_cpu_device::*op_handler)();
static const op_handler s_opcode32_table[4*8];
static const op_handler s_opcode16_table[8];
// mnemonics
static const char *const m_cond[16];
static const char *const m_tcs[4];
static const char *const m_rix1_op[8];
static const char *const m_rix2_op[8];
static const char *const m_r2_op[16];
static const char *const m_i1_op[8];
static const char *const m_i2_op[8];
static const char *const m_ls_op[8];
static const char *const m_i1a_op[8];
static const char *const m_i1b_op[8];
static const char *const m_cr_op[2];
};
extern const device_type SCORE7;
#endif /* __SCORE_H__ */

View File

@ -0,0 +1,292 @@
/******************************************************************************
Sunplus Technology S+core disassembler
******************************************************************************/
#include "emu.h"
#include "score.h"
#include "scorem.h"
const char *const score7_cpu_device::m_cond[16] = { "cs", "cc", "gtu", "leu", "eq", "ne", "gt", "le", "ge", "lt", "mi", "pl", "vs", "vc", "cnz", "" };
const char *const score7_cpu_device::m_tcs[4] = { "teq", "tmi", "", ""};
const char *const score7_cpu_device::m_rix1_op[8] = { "lw" ,"lh" ,"lhu" ,"lb" ,"sw" ,"sh" ,"lbu" ,"sb" };
const char *const score7_cpu_device::m_rix2_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" };
const char *const score7_cpu_device::m_r2_op[16] = { "add", "sub", "neg", "cmp", "and", "or", "not", "xor", "lw", "lh", "pop", "lbu", "sw", "sh", "push", "sb" };
const char *const score7_cpu_device::m_i1_op[8] = { "addi", "", "cmpi", "", "andi", "ori", "ldi", "" };
const char *const score7_cpu_device::m_i2_op[8] = { "addis", "", "cmpis", "", "andis", "oris", "ldis", "" };
const char *const score7_cpu_device::m_ls_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" };
const char *const score7_cpu_device::m_i1a_op[8] = { "addei", "slli", "sdbbp", "srli", "bitclr", "bitset", "bittst", "" };
const char *const score7_cpu_device::m_i1b_op[8] = { "lwp", "lhp", "", "lbup", "swp", "shp", "", "sbp" };
const char *const score7_cpu_device::m_cr_op[2] = { "mtcr", "mfcr" };
char *score7_cpu_device::disasm32(char *buffer, offs_t pc, UINT32 opcode)
{
switch((opcode >> 25) & 0x1f)
{
case 0x00: // Special-form
{
UINT8 ra = GET_S_RA(opcode);
UINT8 rb = GET_S_RB(opcode);
UINT8 rd = GET_S_RD(opcode);
const char *cu = GET_S_CU(opcode) ? ".c": "";
const char *lk = GET_S_LK(opcode) ? "l": "";
switch(GET_S_FUNC6(opcode))
{
case 0x00: buffer += sprintf(buffer, "nop"); break;
case 0x01: buffer += sprintf(buffer, "syscall 0x%04x", (rd<<10) | (ra << 5) | rb); break;
case 0x02: buffer += sprintf(buffer, "trap%s 0x%02x", m_cond[rb & 0x0f], ra); break;
case 0x03: buffer += sprintf(buffer, "sdbbp 0x%02x", ra); break;
case 0x04: buffer += sprintf(buffer, "br%s%s r%d", m_cond[rb & 0x0f], lk, ra); break;
case 0x05: buffer += sprintf(buffer, "pflush"); break;
case 0x08: buffer += sprintf(buffer, "add%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x09: buffer += sprintf(buffer, "addc%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x0a: buffer += sprintf(buffer, "sub%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x0b: buffer += sprintf(buffer, "subc%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x0c: buffer += sprintf(buffer, "cmp%s%s r%d, r%d", m_tcs[rd & 3], cu, ra, rb); break;
case 0x0d: buffer += sprintf(buffer, "cmpz%s%s r%d, r%d", m_tcs[rd & 3], cu, ra, rb); break;
case 0x0f: buffer += sprintf(buffer, "neg%s r%d, r%d", cu, rd, rb); break;
case 0x10: buffer += sprintf(buffer, "and%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x11: buffer += sprintf(buffer, "or%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x12: buffer += sprintf(buffer, "not%s r%d, r%d", cu, rd, ra); break;
case 0x13: buffer += sprintf(buffer, "xor%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x14: buffer += sprintf(buffer, "bitclr%s r%d, %d", cu, ra, rb); break;
case 0x15: buffer += sprintf(buffer, "bitset%s r%d, %d", cu, ra, rb); break;
case 0x16: buffer += sprintf(buffer, "bittst%s r%d, %d", cu, ra, rb); break;
case 0x17: buffer += sprintf(buffer, "bittgl%s r%d, %d", cu, ra, rb); break;
case 0x18: buffer += sprintf(buffer, "sll%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1a: buffer += sprintf(buffer, "srl%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1b: buffer += sprintf(buffer, "sra%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1c: buffer += sprintf(buffer, "ror%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1d: buffer += sprintf(buffer, "rorc%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1e: buffer += sprintf(buffer, "rol%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x1f: buffer += sprintf(buffer, "rolc%s r%d, r%d, r%d", cu, rd, ra, rb); break;
case 0x20: buffer += sprintf(buffer, "mul r%d, r%d", ra, rb); break;
case 0x21: buffer += sprintf(buffer, "mulu r%d, r%d", ra, rb); break;
case 0x22: buffer += sprintf(buffer, "div r%d, r%d", ra, rb); break;
case 0x23: buffer += sprintf(buffer, "divu r%d, r%d", ra, rb); break;
case 0x24:
buffer += sprintf(buffer, "mfce%s%s r%d", rb & 2 ? "h" : "", rb & 1 ? "l" : "", rd);
if ((rb & 3) == 3) buffer += sprintf(buffer, ", r%d", ra);
break;
case 0x25:
buffer += sprintf(buffer, "mtce%s%s r%d", rb & 2 ? "h" : "", rb & 1 ? "l" : "", rd);
if ((rb & 3) == 3) buffer += sprintf(buffer, ", r%d", ra);
break;
case 0x28: buffer += sprintf(buffer, "mfsr sr%d, r%d", rb, ra); break;
case 0x29: buffer += sprintf(buffer, "mtsr r%d, sr%d", ra, rb); break;
case 0x2a: buffer += sprintf(buffer, "t%s r%d", m_cond[rb & 0x0f], rb); break;
case 0x2b: buffer += sprintf(buffer, "mv%s r%d, r%d", m_cond[rb & 0x0f], rd, ra); break;
case 0x2c: buffer += sprintf(buffer, "extsb%s r%d, r%d", cu, rd, ra); break;
case 0x2d: buffer += sprintf(buffer, "extsh%s r%d, r%d", cu, rd, ra); break;
case 0x2e: buffer += sprintf(buffer, "extzb%s r%d, r%d", cu, rd, ra); break;
case 0x2f: buffer += sprintf(buffer, "extzh%s r%d, r%d", cu, rd, ra); break;
case 0x30: buffer += sprintf(buffer, "lcb [r%d]+", ra); break;
case 0x31: buffer += sprintf(buffer, "lcw r%d, [r%d]+", rd, ra); break;
case 0x33: buffer += sprintf(buffer, "lce r%d, [r%d]+", rd, ra); break;
case 0x34: buffer += sprintf(buffer, "scb r%d, [r%d]+", rd, ra); break;
case 0x35: buffer += sprintf(buffer, "scw r%d, [r%d]+", rd, ra); break;
case 0x37: buffer += sprintf(buffer, "sce [r%d]+", ra); break;
case 0x38: buffer += sprintf(buffer, "slli r%d, r%d, %d", rd, ra, rb); break;
case 0x3a: buffer += sprintf(buffer, "srli r%d, r%d, %d", rd, ra, rb); break;
case 0x3b: buffer += sprintf(buffer, "srai r%d, r%d, %d", rd, ra, rb); break;
case 0x3c: buffer += sprintf(buffer, "rori%s r%d, r%d, %d", cu, rd, ra, rb); break;
case 0x3d: buffer += sprintf(buffer, "roric%s r%d, r%d, %d", cu, rd, ra, rb); break;
case 0x3e: buffer += sprintf(buffer, "roli%s r%d, r%d, %d", cu, rd, ra, rb); break;
case 0x3f: buffer += sprintf(buffer, "rolic%s r%d, r%d, %d", cu, rd, ra, rb); break;
default: buffer += sprintf(buffer, "<undefined special-form 0x%02x>", GET_S_FUNC6(opcode));
}
break;
}
case 0x01: // I-form-1
switch(GET_I_FUNC3(opcode))
{
case 0x00:
buffer += sprintf(buffer, "%s%s r%d, %d", m_i1_op[GET_I_FUNC3(opcode)], GET_I_CU(opcode) ? ".c": "", GET_I_RD(opcode), sign_extend(GET_I_IMM16(opcode), 16));
break;
case 0x02: case 0x04: case 0x05: case 0x06:
buffer += sprintf(buffer, "%s%s r%d, 0x%04x", m_i1_op[GET_I_FUNC3(opcode)], GET_I_CU(opcode) ? ".c": "", GET_I_RD(opcode), GET_I_IMM16(opcode));
break;
default:
buffer += sprintf(buffer, "<undefined i-form-1 0x%02x>", GET_I_FUNC3(opcode));
}
break;
case 0x02:
buffer += sprintf(buffer, "j%s 0x%08x", GET_J_LK(opcode) ? "l": "", (pc & 0xfc000000) | (GET_J_DISP24(opcode) << 1));
break;
case 0x03: // RIX-form-1
buffer += sprintf(buffer, "%s r%d, [R%d, %d]+", m_rix1_op[GET_RIX_FUNC3(opcode)], GET_RIX_RD(opcode), GET_RIX_RA(opcode), sign_extend(GET_RIX_IMM12(opcode), 12));
break;
case 0x04:
buffer += sprintf(buffer, "b%s%s 0x%08x", m_cond[GET_BC_BC(opcode) & 0x0f], GET_BC_LK(opcode) ? "l": "", pc + (sign_extend(GET_BC_DISP19(opcode), 19) << 1));
break;
case 0x05: // I-form-2
switch(GET_I_FUNC3(opcode))
{
case 0x00: case 0x02:
case 0x04: case 0x05: case 0x06:
buffer += sprintf(buffer, "%s%s r%d, 0x%04x", m_i2_op[GET_I_FUNC3(opcode)], GET_I_CU(opcode) ? ".c": "", GET_I_RD(opcode), GET_I_IMM16(opcode));
break;
default:
buffer += sprintf(buffer, "<undefined i-form-2 0x%02x>", GET_I_FUNC3(opcode));
}
break;
case 0x06: // CR-form
switch(GET_CR_OP(opcode))
{
case 0x00: case 0x01:
buffer += sprintf(buffer, "%s r%d, cr%d", m_cr_op[GET_CR_OP(opcode)], GET_CR_RD(opcode), GET_CR_CR(opcode));
break;
case 0x84:
buffer += sprintf(buffer, "rte");
break;
default:
if ((GET_CR_OP(opcode) & 0xc0) == 0)
buffer += sprintf(buffer, "<coprocessor instruction 0x%02x>", GET_CR_OP(opcode) & 0x07);
else
buffer += sprintf(buffer, "<undefined cr-form 0x%02x>", GET_S_FUNC6(opcode));
}
break;
case 0x07: // RIX-form-2
buffer += sprintf(buffer, "%s r%d, [R%d]+, %d", m_rix2_op[GET_RIX_FUNC3(opcode)], GET_RIX_RD(opcode), GET_RIX_RA(opcode), sign_extend(GET_RIX_IMM12(opcode), 12));
break;
case 0x08:
buffer += sprintf(buffer, "addri%s r%d, r%d, %d", GET_RI_CU(opcode) ? ".c": "", GET_RI_RD(opcode), GET_RI_RA(opcode), sign_extend(GET_RI_IMM14(opcode), 14));
break;
case 0x0c:
buffer += sprintf(buffer, "andri%s r%d, r%d, 0x%04x", GET_RI_CU(opcode) ? ".c": "", GET_RI_RD(opcode), GET_RI_RA(opcode), GET_RI_IMM14(opcode));
break;
case 0x0d:
buffer += sprintf(buffer, "orri%s r%d, r%d, 0x%04x", GET_RI_CU(opcode) ? ".c": "", GET_RI_RD(opcode), GET_RI_RA(opcode), GET_RI_IMM14(opcode));
break;
case 0x10: case 0x11: case 0x12: case 0x13:
case 0x14: case 0x15: case 0x16: case 0x17:
buffer += sprintf(buffer, "%s r%d, [r%d, %d]", m_ls_op[(opcode >> 25) & 0x07], GET_LS_RD(opcode), GET_LS_RA(opcode), sign_extend(GET_LS_IMM15(opcode), 15));
break;
case 0x18:
buffer += sprintf(buffer, "cache 0x%02x, [r%d, %d]", GET_LS_RD(opcode), GET_LS_RA(opcode), sign_extend(GET_LS_IMM15(opcode), 15));
break;
case 0x1c:
sprintf(buffer,"<CENew op: 0x%x>", opcode);
break;
default:
buffer += sprintf(buffer, "<undefined 32-bit opcode 0x%08x>", opcode);
}
return buffer;
}
char *score7_cpu_device::disasm16(char *buffer, offs_t pc, UINT16 opcode)
{
switch((opcode >> 12) & 0x07)
{
case 0x00: // R-form-1
{
UINT8 rd = GET_R_RD(opcode);
UINT8 ra = GET_R_RA(opcode);
switch(GET_R_FUNC4(opcode))
{
case 0x00: buffer += sprintf(buffer, "nop!"); break;
case 0x01: buffer += sprintf(buffer, "mlfh! r%d, r%d", rd, 0x10 + ra); break;
case 0x02: buffer += sprintf(buffer, "mhfl! r%d, r%d", 0x10 + rd, ra); break;
case 0x03: buffer += sprintf(buffer, "mv! r%d, r%d", rd, ra); break;
case 0x04: buffer += sprintf(buffer, "br%s! r%d", m_cond[rd & 0x0f], ra); break;
case 0x05: buffer += sprintf(buffer, "t%s!", m_cond[rd & 0x0f]); break;
case 0x08: buffer += sprintf(buffer, "sll! r%d, r%d", rd, ra); break;
case 0x09: buffer += sprintf(buffer, "addc! r%d, r%d", rd, ra); break;
case 0x0a: buffer += sprintf(buffer, "srl! r%d, r%d", rd, ra); break;
case 0x0b: buffer += sprintf(buffer, "sra! r%d, r%d", rd, ra); break;
case 0x0c: buffer += sprintf(buffer, "br%sl! r%d", m_cond[rd & 0x0f], ra); break;
default: buffer += sprintf(buffer, "<undefined r-form-1 0x%02x>", GET_R_FUNC4(opcode));
}
break;
}
case 0x02: // R-form-2
switch(GET_R_FUNC4(opcode))
{
case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7:
buffer += sprintf(buffer, "%s! r%d, r%d", m_r2_op[GET_R_FUNC4(opcode)], GET_R_RD(opcode), GET_R_RA(opcode));
break;
case 0x0a: case 0x0e:
buffer += sprintf(buffer, "%s! r%d, [r%d]", m_r2_op[GET_R_FUNC4(opcode)], GET_P_RDG(opcode), GET_P_RAG(opcode));
break;
default:
buffer += sprintf(buffer, "%s! r%d, [r%d]", m_r2_op[GET_R_FUNC4(opcode)], GET_R_RD(opcode), GET_R_RA(opcode));
}
break;
case 0x03:
buffer += sprintf(buffer, "j%s! 0x%08x", GET_J_LK(opcode) ? "l": "", (pc & 0xfffff000) | (GET_J_DISP11(opcode) << 1));
break;
case 0x04:
buffer += sprintf(buffer, "b%s! 0x%08x", m_cond[GET_BX_EC(opcode) & 0x0f], pc + sign_extend(GET_BX_DISP8(opcode) << 1, 9));
break;
case 0x05:
buffer += sprintf(buffer, "ldiu! r%d, 0x%02x", GET_I2_RD(opcode), GET_I2_IMM8(opcode));
break;
case 0x06: // I-form-1a
if (GET_I16_FUNC3(opcode) != 7)
buffer += sprintf(buffer, "%s! r%d, %d", m_i1a_op[GET_I16_FUNC3(opcode)], GET_I16_RD(opcode), GET_I16_IMM5(opcode));
else
buffer += sprintf(buffer, "<undefined i-form-1a 0x%02x>", GET_I16_FUNC3(opcode));
break;
case 0x07: // I-form-1b
switch(GET_I16_FUNC3(opcode))
{
case 0: case 4:
buffer += sprintf(buffer, "%s! r%d, %d", m_i1b_op[GET_I16_FUNC3(opcode)], GET_I16_RD(opcode), GET_I16_IMM5(opcode)<<2);
break;
case 1: case 5:
buffer += sprintf(buffer, "%s! r%d, %d", m_i1b_op[GET_I16_FUNC3(opcode)], GET_I16_RD(opcode), GET_I16_IMM5(opcode)<<1);
break;
case 3: case 7:
buffer += sprintf(buffer, "%s! r%d, %d", m_i1b_op[GET_I16_FUNC3(opcode)], GET_I16_RD(opcode), GET_I16_IMM5(opcode));
break;
default:
buffer += sprintf(buffer, "<undefined i-form-1b 0x%02x>", GET_I16_FUNC3(opcode));
}
break;
}
return buffer;
}
offs_t score7_cpu_device::disasm(char *buffer, offs_t pc, UINT32 opcode)
{
UINT8 p = (pc & 0x02) ? 0 : (((opcode>>30) & 2) | ((opcode>>15) & 1));
switch(p)
{
case 0: // 16-bit + 16-bit instruction
buffer = disasm16(buffer, pc, opcode & 0x7fff);
break;
case 1: // undefined
buffer += sprintf(buffer,"<undefined parity-check 0x%08x>", opcode);
break;
case 2: // parallel conditional execution
buffer = disasm16(buffer, pc, opcode & 0x7fff);
buffer += sprintf(buffer, " ||");
break;
case 3: // 32-bit instruction
buffer = disasm32(buffer, pc, (opcode & 0x7fff) | ((opcode >> 1) & 0x3fff8000));
break;
}
return (p & 0x01) ? 4 : 2;
}
//-------------------------------------------------
// disasm_disassemble - call the disassembly
// helper function
//-------------------------------------------------
offs_t score7_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
UINT32 opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
return disasm(buffer, pc, opcode);
}

144
src/emu/cpu/score/scorem.h Normal file
View File

@ -0,0 +1,144 @@
// Special-form
#define GET_S_FUNC6(op) ((op >> 1) & 0x3f)
#define GET_S_RB(op) ((op >> 10) & 0x1f)
#define GET_S_RA(op) ((op >> 15) & 0x1f)
#define GET_S_RD(op) ((op >> 20) & 0x1f)
#define GET_S_CU(op) (op & 0x01)
#define GET_S_LK(op) (op & 0x01)
// I-form
#define GET_I_FUNC3(op) ((op >> 17) & 0x07)
#define GET_I_IMM16(op) ((op >> 1) & 0xffff)
#define GET_I_RD(op) ((op >> 20) & 0x1f)
#define GET_I_CU(op) (op & 0x01)
// RI-form
#define GET_RI_IMM14(op) ((op >> 1) & 0x3fff)
#define GET_RI_RA(op) ((op >> 15) & 0x1f)
#define GET_RI_RD(op) ((op >> 20) & 0x1f)
#define GET_RI_CU(op) (op & 0x01)
// J-form
#define GET_J_DISP24(op) ((op >> 1) & 0x00ffffff)
#define GET_J_DISP11(op) ((op >> 1) & 0x000007ff)
#define GET_J_LK(op) (op & 0x01)
// BC-form
#define GET_BC_DISP19(op) (((op >> 6) & 0x07fe00) | ((op >> 1) & 0x0001ff))
#define GET_BC_BC(op) ((op >> 10) & 0x1f)
#define GET_BC_LK(op) (op & 0x01)
// RIX-form
#define GET_RIX_FUNC3(op) (op & 0x07)
#define GET_RIX_IMM12(op) ((op >> 3) & 0x0fff)
#define GET_RIX_RA(op) ((op >> 15) & 0x1f)
#define GET_RIX_RD(op) ((op >> 20) & 0x1f)
// R-form
#define GET_R_FUNC4(op) (op & 0x0f)
#define GET_R_RA(op) ((op >> 4) & 0x0f)
#define GET_R_RD(op) ((op >> 8) & 0x0f)
// BX-form
#define GET_BX_DISP8(op) (op & 0xff)
#define GET_BX_EC(op) ((op >> 8) & 0x0f)
// LS-form
#define GET_LS_RD(op) ((op >> 20) & 0x1f)
#define GET_LS_RA(op) ((op >> 15) & 0x1f)
#define GET_LS_IMM15(op) (op & 0x7fff)
// I2-form
#define GET_I2_RD(op) ((op >> 8) & 0x0f)
#define GET_I2_IMM8(op) (op & 0xff)
// I-form
#define GET_I16_FUNC3(op) (op & 0x07)
#define GET_I16_RD(op) ((op >> 8) & 0x0f)
#define GET_I16_IMM5(op) ((op >> 3) & 0x1f)
// CR-form
#define GET_CR_OP(op) (op & 0xff)
#define GET_CR_IMM10(op) ((op >> 5) & 0x3ff)
#define GET_CR_CR(op) ((op >> 15) & 0x1f)
#define GET_CR_RD(op) ((op >> 20) & 0x1f)
// PUSH/POP-form
#define GET_P_RAG(op) ((op >> 4) & 0x07)
#define GET_P_RDG(op) (((op >> 8) & 0x0f) | ((op >> 3) & 0x10))
// flags
#define FLAG_V 0x01
#define FLAG_C 0x02
#define FLAG_Z 0x04
#define FLAG_N 0x08
#define FLAG_T 0x10
#define GET_V ((REG_CR & FLAG_V)>>0)
#define GET_C ((REG_CR & FLAG_C)>>1)
#define GET_Z ((REG_CR & FLAG_Z)>>2)
#define GET_N ((REG_CR & FLAG_N)>>3)
#define GET_T ((REG_CR & FLAG_T)>>4)
#define SET_V(f) if (f) REG_CR |= FLAG_V; else REG_CR &= ~FLAG_V;
#define SET_C(f) if (f) REG_CR |= FLAG_C; else REG_CR &= ~FLAG_C;
#define SET_Z(f) if (f) REG_CR |= FLAG_Z; else REG_CR &= ~FLAG_Z;
#define SET_N(f) if (f) REG_CR |= FLAG_N; else REG_CR &= ~FLAG_N;
#define SET_T(f) if (f) REG_CR |= FLAG_T; else REG_CR &= ~FLAG_T;
#define CHECK_Z(r) SET_Z((r)==0)
#define CHECK_N(r) SET_N((INT32)(r) < 0)
#define CHECK_C_ADD(a,b) SET_C((a) > (0xffffffffu - (b)))
#define CHECK_C_SUB(a,b) SET_C((a) >= (b))
#define CHECK_V_ADD(a,b,d) SET_V((INT32)(((a) ^ (d)) & ((b) ^ (d))) < 0)
#define CHECK_V_SUB(a,b,d) SET_V((INT32)(((a) ^ (b)) & ((a) ^ (d))) < 0)
// registers
#define REG_BP m_gpr[2]
#define REG_LNK m_gpr[3]
#define REG_PSR m_cr[0]
#define REG_CR m_cr[1]
#define REG_ECR m_cr[2]
#define REG_EXCPVEC m_cr[3]
#define REG_CCR m_cr[4]
#define REG_EPC m_cr[5]
#define REG_EMA m_cr[6]
#define REG_TLBLOCK m_cr[7]
#define REG_TLBPT m_cr[8]
#define REG_PEADDR m_cr[9]
#define REG_TLBRPT m_cr[10]
#define REG_PEVN m_cr[11]
#define REG_PECTX m_cr[12]
#define REG_LIMPFN m_cr[15]
#define REG_LDMPFN m_cr[16]
#define REG_PREV m_cr[18]
#define REG_DREG m_cr[29]
#define REG_DEPC m_cr[30]
#define REG_DSAVE m_cr[31]
#define REG_CNT m_sr[0]
#define REG_LCR m_sr[1]
#define REG_SCR m_sr[2]
#define REG_CEH m_ce[0]
#define REG_CEL m_ce[1]
// exceptions causes
#define EXCEPTION_RESET 0
#define EXCEPTION_NMI 1
#define EXCEPTION_ADEL_INSTRUCTION 2
#define EXCEPTION_BUSEL_INSTRUCTION 5
#define EXCEPTION_P_EL 6
#define EXCEPTION_SYSCALL 7
#define EXCEPTION_CCU 8
#define EXCEPTION_RI 9
#define EXCEPTION_TRAP 10
#define EXCEPTION_ADEL_DATA 11
#define EXCEPTION_ADES_DATA 12
#define EXCEPTION_CEE 16
#define EXCEPTION_CPE 17
#define EXCEPTION_BUSEL_DATA 18
#define EXCEPTION_SWI 19
#define EXCEPTION_INTERRUPT 20

View File

@ -0,0 +1,645 @@
/***************************************************************************
Mattel HyperScan
08/17/2013 Skeleton driver by Sandro Ronco
SPG290 Interrupt:
Vector Source
63 SPU FIQ
62 SPU Beatirq
61 SPU Envirq
60 CD servo
59 ADC gain overflow / ADC recorder / FIFO overflow
58 General purpose ADC
57 Timer base
56 Timer
55 TV vblanking start
54 LCD vblanking start
53 PPU vblanking start
52 TV
51 Sensor frame end
50 Sensor coordinate hit
49 Sensor motion frame end
48 Sensor capture done + sensor debug IRQ
47 TV coordinate hit
46 PPU coordinate hit
45 USB host+device
44 SIO
43 SPI
42 Uart (IrDA)
41 NAND
40 SD
39 I2C master
38 I2S slave
37 APBDMA CH1
36 APBDMA CH2
35 LDM_DMA
34 BLN_DMA
33 APBDMA CH3
32 APBDMA CH4
31 Alarm + HMS
30 MP4
29 C3 (ECC module)
28 GPIO
27 Bufctl (for debug) + TV/PPU vblanking end (for debug)
26 RESERVED1
25 RESERVED2
24 RESERVED3
****************************************************************************/
#include "emu.h"
#include "cpu/score/score.h"
#define LOG_SPG290_REGISTER_ACCESS (1)
class hyperscan_state : public driver_device
{
public:
hyperscan_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{ }
required_device<score7_cpu_device> m_maincpu;
virtual void machine_start();
virtual void machine_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
UINT32 spg290_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ32_MEMBER(spg290_regs_r);
DECLARE_WRITE32_MEMBER(spg290_regs_w);
void spg290_timers_update();
void spg290_vblank_irq(screen_device &screen, bool state);
inline UINT32 spg290_read_mem(UINT32 offset);
inline void spg290_write_mem(UINT32 offset, UINT32 data);
void spg290_argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 posy, UINT16 posx, UINT16 argb);
void spg290_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 posy, UINT16 posx, UINT16 rgb, UINT32 transrgb);
void spg290_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, UINT32 *palettes, UINT32 buf_start);
void spg290_blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, int posy, int posx, UINT32 nptr, UINT32 buf_start, UINT32 transrgb);
void spg290_blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, int posy, int posx, UINT32 nptr, UINT32 buf_start, UINT32 transrgb);
private:
static const device_timer_id TIMER_SPG290 = 0;
static const device_timer_id TIMER_I2C = 1;
struct spg290_miu
{
UINT32 status;
};
struct spg290_ppu
{
UINT32 control;
UINT32 irq_control;
UINT32 irq_status;
UINT32 sprite_max;
UINT32 sprite_buf_start;
UINT32 frame_buff[3];
UINT32 palettes[0x200];
UINT32 tx_hoffset[0x200];
UINT32 tx_hcomp[0x200];
UINT32 transrgb;
struct ppu_spite
{
UINT32 control;
UINT32 attribute;
} sprites[0x200];
struct ppu_tx
{
UINT32 control;
UINT32 attribute;
UINT32 posx;
UINT32 posy;
UINT32 nptr;
UINT32 buf_start[3];
} txs[3];
};
struct spg290_timer
{
UINT32 control;
UINT32 control2;
UINT16 preload;
UINT16 counter;
};
struct spg290_i2c
{
UINT32 config;
UINT32 irq_control;
UINT32 clock;
UINT8 count;
UINT32 id;
UINT32 port_addr;
UINT32 wdata;
UINT32 rdata;
};
spg290_miu m_miu;
spg290_ppu m_ppu;
spg290_timer m_timers[6];
spg290_i2c m_i2c;
emu_timer * m_update_timer;
emu_timer * m_i2c_timer;
};
#if LOG_SPG290_REGISTER_ACCESS
static void log_spg290_regs(UINT8 module, UINT16 reg, UINT32 mem_mask, bool write, UINT32 data=0)
{
static const char *const modules_name[] =
{
"CSI", "PPU", "JPG", "TV", "LCD", "SPU", "CD", "MIU", "APBDMA", "BUFCTL","IRQCTL", "GPUBUF", "LDMDMA",
"BLNDMA", "TPGBUF", "AHBDEC", "GPIO", "SPI", "SIO", "I2C", "I2S", "UART", "TIMERS/RTC", "WDOG", "SD",
"FLASH", "ADC", "USB device", "USB host", "Reserved", "Reserved", "Reserved", "SFTCFG", "CKG", "MP4",
"MIU2", "ECC"
};
if (module < 0x25)
logerror("SPG: %-10s", modules_name[module]);
else
logerror("SPG: mod 0x%02x ", module);
if (!write)
logerror(" R 0x%04x", reg);
else
logerror(" W 0x%04x = 0x%08x", reg, data);
if (mem_mask != 0xffffffffu)
logerror(" (0x%08x)\n", mem_mask);
else
logerror("\n");
}
#endif
READ32_MEMBER(hyperscan_state::spg290_regs_r)
{
UINT32 addr = offset << 2;
UINT32 data = 0;
if (addr == 0x010000) // PPU Control
{
data = m_ppu.control;
}
else if (addr == 0x010084) // PPU IRQ Status
{
data = m_ppu.irq_status;
}
if (addr == 0x07006c) // MIU Status
{
data = m_miu.status;
}
else if ((addr & 0xff0fff) == 0x160000) // Timer X Status
{
int idx = (offset>>10) & 0x0f;
data = m_timers[idx].control;
}
else if(addr == 0x130024) // I2C interrupt
{
data = m_i2c.irq_control;
}
else if(addr == 0x130034) // I2C write data
{
data = m_i2c.wdata;
}
else if(addr == 0x130038) // I2C data data
{
data = m_i2c.rdata;
}
#if LOG_SPG290_REGISTER_ACCESS
//else
{
if (!space.debugger_access())
log_spg290_regs((offset >> 14) & 0xff, (offset<<2) & 0xffff, mem_mask, false);
}
#endif
return data;
}
WRITE32_MEMBER(hyperscan_state::spg290_regs_w)
{
UINT32 addr = offset << 2;
if (addr == 0x010000) // PPU Control
{
COMBINE_DATA(&m_ppu.control);
}
else if (addr == 0x010008) // PPU Max Sprites
{
COMBINE_DATA(&m_ppu.sprite_max);
}
else if (addr == 0x010010) // PPU Max Sprites
{
COMBINE_DATA(&m_ppu.transrgb);
}
else if (addr == 0x0100d0) // Sprites buffer start
{
COMBINE_DATA(&m_ppu.sprite_buf_start);
}
else if (addr == 0x010020 || addr == 0x01003c || addr == 0x010058) // Text Layers x pos
{
int idx = (((offset>>3) & 3) | ((offset>>4) & 1)) - 1;
COMBINE_DATA(&m_ppu.txs[idx].posx);
}
else if (addr == 0x010024 || addr == 0x010040 || addr == 0x01005c) // Text Layers y pos
{
int idx = (((offset>>3) & 3) | ((offset>>4) & 1)) - 1;
COMBINE_DATA(&m_ppu.txs[idx].posy);
}
else if (addr == 0x010028 || addr == 0x010044 || addr == 0x010060) // Text Layers attribute
{
int idx = ((offset>>3) & 3) - 1;
COMBINE_DATA(&m_ppu.txs[idx].attribute);
}
else if (addr == 0x01002c || addr == 0x010048 || addr == 0x010064) // Text Layers control
{
int idx = ((offset>>3) & 3) - 1;
COMBINE_DATA(&m_ppu.txs[idx].control);
}
else if (addr == 0x010030 || addr == 0x01004c || addr == 0x010068) // Text Layers number ptr
{
int idx = ((offset>>3) & 3) - 1;
COMBINE_DATA(&m_ppu.txs[idx].nptr);
}
else if (addr == 0x010080) // PPU IRQ Control
{
COMBINE_DATA(&m_ppu.irq_control);
}
else if (addr == 0x010084) // PPU IRQ ack
{
if (ACCESSING_BITS_0_7)
m_ppu.irq_status &= ~data;
}
else if (addr >= 0x0100a0 && addr <= 0x0100a8) // Tx1 buffer start
{
COMBINE_DATA(&m_ppu.txs[0].buf_start[offset & 3]);
}
else if (addr >= 0x0100ac && addr <= 0x0100b4) // Tx2 buffer start
{
COMBINE_DATA(&m_ppu.txs[1].buf_start[(offset+1) & 3]);
}
else if (addr >= 0x0100b8 && addr <= 0x0100c0) // Tx3 buffer starts
{
COMBINE_DATA(&m_ppu.txs[2].buf_start[(offset+2) & 3]);
}
else if ((addr & 0xfff000) == 0x011000) // Palettes
{
COMBINE_DATA(&m_ppu.palettes[offset & 0x01ff]);
}
else if ((addr & 0xfff000) == 0x012000) // Tx horizontal offset
{
COMBINE_DATA(&m_ppu.tx_hoffset[offset & 0x01ff]);
}
else if ((addr & 0xfff000) == 0x013000) // Tx horizontal compression
{
COMBINE_DATA(&m_ppu.tx_hcomp[offset & 0x01ff]);
}
else if ((addr & 0xfff000) == 0x014000) // Sprite Control Registers
{
int idx = (offset>>1) & 0x1ff;
if (offset & 1)
COMBINE_DATA(&m_ppu.sprites[idx].attribute);
else
COMBINE_DATA(&m_ppu.sprites[idx].control);
}
else if (addr == 0x07005c) // MIU Status
{
COMBINE_DATA(&m_miu.status);
}
else if ((addr & 0xff0fff) == 0x160000) // Timer X Control 1
{
int idx = (offset>>10) & 0x07;
COMBINE_DATA(&m_timers[idx].control);
if (ACCESSING_BITS_24_31)
m_timers[idx].control &= ~(data & 0x04000000); // Timers IRQ ack
}
else if ((addr & 0xff0fff) == 0x160004) // Timer X Control 2
{
int idx = (offset>>10) & 0x07;
COMBINE_DATA(&m_timers[idx].control2);
}
else if ((addr & 0xff0fff) == 0x160008) // Timer X Preload
{
int idx = (offset>>10) & 0x07;
COMBINE_DATA(&m_timers[idx].preload);
}
else if (addr == 0x2100e4) // Timer Source Clock Selection
{
UINT32 timers_clk = XTAL_27MHz / ((data & 0xff) + 1);
m_update_timer->adjust(attotime::from_hz(timers_clk), 0, attotime::from_hz(timers_clk));
}
else if(addr == 0x130020) // I2C configuration
{
COMBINE_DATA(&m_i2c.config);
}
else if(addr == 0x130024) // I2C interrupt
{
COMBINE_DATA(&m_i2c.irq_control);
if (ACCESSING_BITS_0_7)
m_i2c.irq_control &= ~(data & 0x00000001); // I2C IRQ ack
}
else if(addr == 0x130028) // I2C clock setting
{
COMBINE_DATA(&m_i2c.clock);
UINT32 i2c_clk = XTAL_27MHz / ((m_i2c.clock & 0x3ff) + 1);
m_i2c_timer->adjust(attotime::from_hz(i2c_clk), 0, attotime::from_hz(i2c_clk));
}
else if(addr == 0x13002c) // I2C ID
{
COMBINE_DATA(&m_i2c.id);
}
else if(addr == 0x130030) // I2C port address
{
COMBINE_DATA(&m_i2c.port_addr);
}
else if(addr == 0x130034) // I2C write data
{
COMBINE_DATA(&m_i2c.wdata);
}
else if(addr == 0x130038) // I2C data data
{
COMBINE_DATA(&m_i2c.rdata);
}
else if(addr == 0x150000) // UART data
{
if (ACCESSING_BITS_0_7)
printf("%c", data & 0xff);
}
#if LOG_SPG290_REGISTER_ACCESS
//else
{
if (!space.debugger_access())
log_spg290_regs((offset >> 14) & 0xff, (offset<<2) & 0xffff, mem_mask, true, data);
}
#endif
}
inline UINT32 hyperscan_state::spg290_read_mem(UINT32 offset)
{
return m_maincpu->space(0).read_dword(offset);
}
inline void hyperscan_state::spg290_write_mem(UINT32 offset, UINT32 data)
{
return m_maincpu->space(0).write_dword(offset, data);
}
void hyperscan_state::spg290_argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 posy, UINT16 posx, UINT16 argb)
{
if (!(argb & 0x8000) && cliprect.contains(posx, posy))
{
rgb_t color = MAKE_RGB(pal5bit(argb >> 10), pal5bit(argb >> 5), pal5bit(argb >> 0));
bitmap.pix32(posy, posx) = color;
}
}
void hyperscan_state::spg290_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 posy, UINT16 posx, UINT16 rgb, UINT32 transrgb)
{
if ((!(transrgb & 0x10000) || (transrgb & 0xffff) != rgb) && cliprect.contains(posx, posy))
{
rgb_t color = MAKE_RGB(pal5bit(rgb >> 11), pal6bit(rgb >> 5), pal5bit(rgb >> 0));
bitmap.pix32(posy, posx) = color;
}
}
void hyperscan_state::spg290_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, UINT32 *palettes, UINT32 buf_start)
{
UINT32 sprite_base = buf_start + ((control & 0xffff) << 8);
UINT16 sprite_x = (control >> 16) & 0x3ff;
UINT16 sprite_y = (attribute >> 16) & 0x3ff;
UINT8 sprite_hsize = 8 << ((attribute >> 4) & 0x03);
UINT8 sprite_vsize = 8 << ((attribute >> 6) & 0x03);
UINT8 bit_pixel = ((attribute & 3) + 1) << 1;
UINT8 pixel_word = 32 / bit_pixel;
UINT8 word_line = sprite_hsize / pixel_word;
UINT8 sprite_flip = (attribute >> 2) & 0x03;
for (int y=0; y < sprite_vsize; y++)
for (int x=0; x < word_line; x++)
{
UINT32 data = spg290_read_mem(sprite_base + (y * pixel_word + x) * 4);
for (int b=0; b < pixel_word; b++)
{
UINT16 pen = ((data >> (b * bit_pixel)) & ((1 << bit_pixel) - 1));
UINT16 posx;
if (sprite_flip & 0x01)
posx = sprite_x + (sprite_hsize - (x * word_line + b));
else
posx = sprite_x + x * (word_line) + b;
UINT16 posy;
if (sprite_flip & 0x02)
posy = sprite_y + (sprite_vsize - y);
else
posy = sprite_y + y;
spg290_argb1555(bitmap, cliprect, posy, posx, palettes[pen]);
}
}
}
void hyperscan_state::spg290_blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, int posy, int posx, UINT32 nptr, UINT32 buf_start, UINT32 transrgb)
{
for (int y=0; y<512; y++)
{
int line = (control & 0x04) ? 0 : y;
UINT32 tx_start = spg290_read_mem(nptr + (posy + line) * 4);
for (int x=0; x < 1024>>1; x++)
{
UINT32 data = spg290_read_mem(buf_start + (tx_start + posx) * 2 + x * 4);
for (int b=0; b < 2; b++)
{
UINT16 posx = x * 2 + b;
UINT16 posy = y;
UINT16 pix = (data >> (b*16)) & 0xffff;
if (control & 0x0080)
spg290_argb1555(bitmap, cliprect, posy, posx, pix);
if (control & 0x1000)
spg290_rgb565(bitmap, cliprect, posy, posx, pix, transrgb);
}
}
}
}
void hyperscan_state::spg290_blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 control, UINT32 attribute, int posy, int posx, UINT32 nptr, UINT32 buf_start, UINT32 transrgb)
{
// TODO
}
UINT32 hyperscan_state::spg290_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
if (m_ppu.control & 0x1000)
{
for (int depth=0; depth<4; depth++)
{
// draw the bitmap/text layers
for (int l=0; l<3; l++)
if ((m_ppu.txs[l].control & 0x08) && ((m_ppu.txs[l].attribute >> 13) & 3) == depth)
{
if (m_ppu.txs[l].control & 0x01)
spg290_blit_bitmap(bitmap, cliprect, m_ppu.txs[l].control, m_ppu.txs[l].attribute, m_ppu.txs[l].posy & 0x1ff, m_ppu.txs[l].posx & 0x1ff, m_ppu.txs[l].nptr, m_ppu.txs[l].buf_start[0], m_ppu.transrgb);
else
spg290_blit_character(bitmap, cliprect, m_ppu.txs[l].control, m_ppu.txs[l].attribute, m_ppu.txs[l].posy & 0x1ff, m_ppu.txs[l].posx & 0x1ff, m_ppu.txs[l].nptr, m_ppu.txs[l].buf_start[0], m_ppu.transrgb);
}
// draw the sprites
for (int i=0; i<=(m_ppu.sprite_max & 0x1ff); i++)
{
if (((m_ppu.sprites[i].attribute >> 13) & 3) == depth)
spg290_blit_sprite(bitmap, cliprect, m_ppu.sprites[i].control, m_ppu.sprites[i].attribute, m_ppu.palettes, m_ppu.sprite_buf_start);
}
}
}
else
{
bitmap.fill(RGB_BLACK, cliprect);
}
return 0;
}
void hyperscan_state::spg290_timers_update()
{
for(int i=0; i<6; i++)
if (m_timers[i].control & 0x80000000)
{
if (((m_timers[i].control2 >> 30) & 0x03) == 0x00)
{
if (m_timers[i].counter == 0xffff)
{
m_timers[i].counter = m_timers[i].preload;
if (m_timers[i].control & 0x08000000)
{
m_timers[i].control |= 0x04000000;
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 56);
}
}
else
m_timers[i].counter++;
}
else
{
// TODO: capture, comparison and PWM mode
}
}
}
void hyperscan_state::spg290_vblank_irq(screen_device &screen, bool state)
{
if (state && m_ppu.irq_control & 0x01) // VBlanking Start IRQ
{
m_ppu.irq_status |= 0x01;
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 53);
}
else if (!state && m_ppu.irq_control & 0x02) // VBlanking End IRQ
{
m_ppu.irq_status |= 0x02;
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 53);
}
}
void hyperscan_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_SPG290:
spg290_timers_update();
break;
case TIMER_I2C:
if ((m_i2c.config & 0x40) && (m_i2c.config & 0x01))
{
// TODO: replace with real I2C emulation
m_i2c.rdata = 0;
m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 39);
}
break;
}
}
static ADDRESS_MAP_START(spg290_mem, AS_PROGRAM, 32, hyperscan_state)
ADDRESS_MAP_GLOBAL_MASK(0x1fffffff)
AM_RANGE(0x00000000, 0x00ffffff) AM_RAM AM_MIRROR(0x07000000)
AM_RANGE(0x08000000, 0x09ffffff) AM_READWRITE(spg290_regs_r, spg290_regs_w)
AM_RANGE(0x0a000000, 0x0a003fff) AM_RAM // internal SRAM
AM_RANGE(0x0b000000, 0x0b007fff) AM_ROM AM_REGION("spg290", 0) // internal ROM
AM_RANGE(0x1e000000, 0x1e0fffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x0e000000)
AM_RANGE(0x1f000000, 0x1f0fffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x0e000000)
ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( hyperscan )
INPUT_PORTS_END
void hyperscan_state::machine_start()
{
m_update_timer = timer_alloc(TIMER_SPG290);
m_i2c_timer = timer_alloc(TIMER_I2C);
}
void hyperscan_state::machine_reset()
{
memset(&m_ppu, 0, sizeof(spg290_ppu));
memset(&m_miu, 0, sizeof(spg290_miu));
memset(&m_i2c, 0, sizeof(m_i2c));
m_i2c_timer->adjust(attotime::never, 0, attotime::never);
// disable JTAG
m_maincpu->set_state_int(SCORE_CR + 29, 0x20000000);
}
static MACHINE_CONFIG_START( hyperscan, hyperscan_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", SCORE7, XTAL_27MHz * 4) // 108MHz S+core 7
MCFG_CPU_PROGRAM_MAP(spg290_mem)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_UPDATE_DRIVER(hyperscan_state, spg290_screen_update)
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
MCFG_SCREEN_VBLANK_DRIVER(hyperscan_state, spg290_vblank_irq)
MACHINE_CONFIG_END
/* ROM definition */
ROM_START( hs )
ROM_REGION( 0x100000, "bios", ROMREGION_32BIT | ROMREGION_LE )
ROM_LOAD32_DWORD("hyperscan.bin", 0x000000, 0x100000, CRC(ce346a14) SHA1(560cb747e7193e6781d4b8b0bd4d7b45d3d28690))
ROM_REGION( 0x008000, "spg290", ROMREGION_32BIT | ROMREGION_LE )
ROM_LOAD32_DWORD("spg290.bin", 0x000000, 0x008000, NO_DUMP) // 256Kbit SPG290 internal ROM
ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
COMP( 2006, hs, 0, 0, hyperscan , hyperscan , driver_device, 0, "Mattel", "HyperScan", GAME_NOT_WORKING | GAME_NO_SOUND)

View File

@ -1421,6 +1421,7 @@ intvecs // 1983 - Mattel Intellivision ECS
aquarius // 1983 Aquarius
// aquariu2 // 1984 Aquarius II
juicebox
hs
// Exidy, Inc.
sorcerer // Sorcerer

View File

@ -125,6 +125,7 @@ CPUS += PPS4
CPUS += UPD7725
CPUS += HD61700
CPUS += LC8670
CPUS += SCORE
CPUS += ES5510
CPUS += SCUDSP
CPUS += IE15
@ -1581,6 +1582,7 @@ $(MESSOBJ)/mattel.a: \
$(MESS_VIDEO)/aquarius.o \
$(MESS_DRIVERS)/juicebox.o \
$(MESS_MACHINE)/s3c44b0.o \
$(MESS_DRIVERS)/hyperscan.o \
$(MESSOBJ)/matsushi.a: \
$(MESS_DRIVERS)/jr100.o \