mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
vsmile: Fixed erroneous cartridge ROM mirroring. Gets V.Smile games to boot. Needs cleanup. [Ryan Holtz]
This commit is contained in:
parent
5e85036f34
commit
af515310d7
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,14 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Segher Boessenkool,Ryan Holtz
|
||||
/*****************************************************************************
|
||||
|
||||
SunPlus micro'nSP core
|
||||
SunPlus micro'nSP emulator
|
||||
|
||||
based primarily on Unununium, by segher
|
||||
Copyright 2008-2017 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
Licensed under the terms of the GNU GPL, version 2
|
||||
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
Ported to MAME framework by Ryan Holtz
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
@ -13,7 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define UNSP_LOG_OPCODES (0)
|
||||
#define UNSP_LOG_OPCODES (1)
|
||||
|
||||
enum
|
||||
{
|
||||
@ -56,6 +60,13 @@ enum
|
||||
UNSP_NUM_LINES
|
||||
};
|
||||
|
||||
struct unsp_timer
|
||||
{
|
||||
uint32_t time;
|
||||
uint32_t interval;
|
||||
int index;
|
||||
struct unsp_timer *next;
|
||||
};
|
||||
|
||||
class unsp_device : public cpu_device
|
||||
{
|
||||
@ -63,6 +74,10 @@ public:
|
||||
// construction/destruction
|
||||
unsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_timer_interval(int timer, uint32_t interval);
|
||||
|
||||
uint16_t get_video_line();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
@ -87,8 +102,15 @@ protected:
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
private:
|
||||
void add_lpc(const int32_t offset);
|
||||
|
||||
inline void execute_one(const uint16_t op);
|
||||
|
||||
address_space_config m_program_config;
|
||||
|
||||
void timer_add(struct unsp_timer *timer);
|
||||
void timer_run(uint32_t ticks);
|
||||
|
||||
uint16_t m_r[16];
|
||||
bool m_enable_irq;
|
||||
bool m_enable_fiq;
|
||||
@ -98,6 +120,7 @@ private:
|
||||
uint16_t m_sirq;
|
||||
uint8_t m_sb;
|
||||
uint8_t m_saved_sb[3];
|
||||
struct unsp_timer *timers;
|
||||
|
||||
address_space *m_program;
|
||||
int m_icount;
|
||||
@ -117,6 +140,7 @@ private:
|
||||
inline void trigger_fiq();
|
||||
inline void trigger_irq(int line);
|
||||
inline void check_irqs();
|
||||
inline int get_irq();
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,257 +1,435 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Segher Boessenkool
|
||||
/*****************************************************************************
|
||||
|
||||
SunPlus micro'nSP disassembler
|
||||
|
||||
Copyright 2008-2017 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
Licensed under the terms of the GNU GPL, version 2
|
||||
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "unspdasm.h"
|
||||
|
||||
char const *const unsp_disassembler::reg[] =
|
||||
char const *const unsp_disassembler::regs[] =
|
||||
{
|
||||
"sp", "r1", "r2", "r3", "r4", "bp", "sr", "pc"
|
||||
};
|
||||
|
||||
char const *const unsp_disassembler::jmp[] =
|
||||
char const *const unsp_disassembler::jumps[] =
|
||||
{
|
||||
"jb", "jae", "jge", "jl", "jne", "je", "jpl", "jmi",
|
||||
"jbe", "ja", "jle", "jg", "jvc", "jvs", "jmp", "<inv>"
|
||||
};
|
||||
|
||||
char const *const unsp_disassembler::alu[] =
|
||||
{
|
||||
"add", "adc", "sub", "sbc",
|
||||
"cmp", "<inv>", "neg", "<inv>",
|
||||
"xor", "load", "or", "and",
|
||||
"test", "store", "<inv>", "<inv>"
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define OP0 (op >> 12)
|
||||
#define OPA ((op >> 9) & 7)
|
||||
#define OP1 ((op >> 6) & 7)
|
||||
#define OPN ((op >> 3) & 7)
|
||||
#define OPB (op & 7)
|
||||
#define OPIMM (op & 0x3f)
|
||||
#define OP2X ((OP0 < 14 && OP1 == 4 && (OPN >= 1 && OPN <= 3)) || (OP0 == 15 && (OP1 == 1 || OP1 == 2)))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define UNSP_DASM_OK ((OP2X ? 2 : 1) | SUPPORTED)
|
||||
#define UNSP_DASM_OK (len | SUPPORTED)
|
||||
|
||||
u32 unsp_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
offs_t unsp_disassembler::disassemble(std::ostream &stream, offs_t pc, uint16_t op, uint16_t imm16)
|
||||
void unsp_disassembler::print_alu_op_start(std::ostream &stream, uint8_t op0, uint8_t opA)
|
||||
{
|
||||
if(OP0 < 0xf && OPA == 0x7 && OP1 < 2)
|
||||
static const char* const alu_op_start[] =
|
||||
{
|
||||
util::stream_format(stream, "%s %04x", jmp[OP0], OP1 ? (pc - OPIMM + 1) : (pc + OPIMM + 1));
|
||||
"%s += ", "%s += ", "%s -= ", "%s -= ",
|
||||
"cmp %s, ", "<BAD>", "%s =- ", "<BAD>",
|
||||
"%s ^= ", "%s = ", "%s |= ", "%s &= ",
|
||||
"test %s, "
|
||||
};
|
||||
|
||||
util::stream_format(stream, alu_op_start[op0], regs[opA]);
|
||||
}
|
||||
|
||||
void unsp_disassembler::print_alu_op3(std::ostream &stream, uint8_t op0, uint8_t opB)
|
||||
{
|
||||
static const char* const alu_op3[] =
|
||||
{
|
||||
"%s + ", "%s + ", "%s - ", "%s - ",
|
||||
"cmp %s, ", "<BAD>", "-", "<BAD>",
|
||||
"%s ^ ", "", "%s | ", "%s & ",
|
||||
"test %s, "
|
||||
};
|
||||
|
||||
util::stream_format(stream, alu_op3[op0], regs[opB]);
|
||||
}
|
||||
|
||||
void unsp_disassembler::print_alu_op_end(std::ostream &stream, uint8_t op0)
|
||||
{
|
||||
if (op0 == 1 || op0 == 3)
|
||||
util::stream_format(stream, ", carry");
|
||||
}
|
||||
|
||||
void unsp_disassembler::print_indirect_op(std::ostream &stream, uint8_t opN, uint8_t opB)
|
||||
{
|
||||
static const char* const forms[] = { "[%s]", "[%s--]", "[%s++]", "[++%s]" };
|
||||
|
||||
if (opN & 4)
|
||||
util::stream_format(stream, "ds:");
|
||||
util::stream_format(stream, forms[opN & 3], regs[opB]);
|
||||
}
|
||||
|
||||
offs_t unsp_disassembler::disassemble(std::ostream &stream, offs_t pc, uint16_t op, uint16_t ximm)
|
||||
{
|
||||
// the top four bits are the alu op or the branch condition, or E or F
|
||||
uint8_t op0 = (op >> 12);
|
||||
|
||||
// the next three are usually the destination register
|
||||
uint8_t opA = (op >> 9) & 7;
|
||||
|
||||
// and the next three the addressing mode
|
||||
uint8_t op1 = (op >> 6) & 7;
|
||||
|
||||
// the next three can be anything
|
||||
uint8_t opN = (op >> 3) & 7;
|
||||
|
||||
// and the last three usually the second register (source register)
|
||||
uint8_t opB = op & 7;
|
||||
|
||||
// the last six sometimes are a single immediate number
|
||||
uint8_t opimm = op & 63;
|
||||
|
||||
uint32_t len = 1;
|
||||
if ((op0 < 14 && op1 == 4 && (opN == 1 || opN == 2 || opN == 3)) || (op0 == 15 && (op1 == 1 || op1 == 2)))
|
||||
{
|
||||
len = 2;
|
||||
}
|
||||
|
||||
// all-zero and all-one are invalid insns:
|
||||
if (op == 0 || op == 0xffff)
|
||||
{
|
||||
util::stream_format(stream, "--");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
switch((OP1 << 4) | OP0)
|
||||
// first, check for the conditional branch insns
|
||||
if (op0 < 15 && opA == 7 && op1 == 0)
|
||||
{
|
||||
// ALU, Indexed
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x06: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d:
|
||||
util::stream_format(stream, "%s %s, [bp+%02x]", alu[OP0], reg[OPA], OPIMM);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Immediate
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x16: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c:
|
||||
util::stream_format(stream, "%s %s, %02x", alu[OP0], reg[OPA], OPIMM);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Pop / Interrupt return
|
||||
case 0x29:
|
||||
if(op == 0x9a90)
|
||||
{
|
||||
util::stream_format(stream, "retf");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
else if(op == 0x9a98)
|
||||
{
|
||||
util::stream_format(stream, "reti");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
else if((OPA + 1) < 8 && ((OPA + OPN) < 8))
|
||||
{
|
||||
util::stream_format(stream, "pop %s, %s [%s]", reg[OPA+1], reg[OPA+OPN], reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
// Push
|
||||
case 0x2d:
|
||||
if((OPA + 1) >= OPN && OPA < (OPN + 7))
|
||||
{
|
||||
util::stream_format(stream, "push %s, %s [%s]", reg[(OPA+1)-OPN], reg[OPA], reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
// ALU, Indirect
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x36: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d:
|
||||
switch(OPN & 3)
|
||||
{
|
||||
case 0:
|
||||
util::stream_format(stream, "%s %s, [%s%s]", alu[OP0], reg[OPA], (OPN & 4) ? "ds:" : "", reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
case 1:
|
||||
util::stream_format(stream, "%s %s, [%s%s--]", alu[OP0], reg[OPA], (OPN & 4) ? "ds:" : "", reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
case 2:
|
||||
util::stream_format(stream, "%s %s, [%s%s++]", alu[OP0], reg[OPA], (OPN & 4) ? "ds:" : "", reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
case 3:
|
||||
util::stream_format(stream, "%s %s, [%s++%s]", alu[OP0], reg[OPA], (OPN & 4) ? "ds:" : "", reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, 16-bit ops
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x46: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c:
|
||||
switch(OPN)
|
||||
{
|
||||
// ALU, Register
|
||||
case 0:
|
||||
util::stream_format(stream, "%s %s, %s", alu[OP0], reg[OPA], reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, 16-bit Immediate
|
||||
case 1:
|
||||
if(!((OP0 == 4 || OP0 == 6 || OP0 == 9 || OP0 == 12) && OPA != OPB))
|
||||
{
|
||||
if(OP0 != 4 && OP0 != 12)
|
||||
{
|
||||
util::stream_format(stream, "%s %s, %s, %04x", alu[OP0], reg[OPA], reg[OPB], imm16);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%s %s, %04x", alu[OP0], reg[OPB], imm16);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// ALU, Direct 16
|
||||
case 2:
|
||||
util::stream_format(stream, "%s %s, [%04x]", alu[OP0], reg[OPA], imm16);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Direct 16
|
||||
case 3:
|
||||
util::stream_format(stream, "%s [%04x], %s, %s", alu[OP0], imm16, reg[OPA], reg[OPB]);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Shifted
|
||||
default:
|
||||
util::stream_format(stream, "%s %s, %s asr %d", alu[OP0], reg[OPA], reg[OPB], (OPN & 3) + 1);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
case 0x4d:
|
||||
if((OPN == 3) && (OPA == OPB))
|
||||
util::stream_format(stream, "store [%04x], %s", imm16, reg[OPB]);
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Shifted
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x56: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c:
|
||||
util::stream_format(stream, "%s %s, %s %s %d", alu[OP0], reg[OPA], reg[OPB], (OPN & 4) ? ">>" : "<<", (OPN & 3) + 1);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Rotated
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x66: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c:
|
||||
util::stream_format(stream, "%s %s, %s %s %d", alu[OP0], reg[OPA], reg[OPB], (OPN & 4) ? "ror" : "rol", (OPN & 3) + 1);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// ALU, Direct 8
|
||||
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x76: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c:
|
||||
util::stream_format(stream, "%s %s, [%02x]", alu[OP0], reg[OPA], OPIMM);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Call
|
||||
case 0x1f:
|
||||
if(OPA == 0)
|
||||
util::stream_format(stream, "call %06x", (OPIMM << 16) | imm16);
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Far Jump
|
||||
case 0x2f: case 0x3f: case 0x6f: case 0x7f:
|
||||
if (OPA == 7 && OP1 == 2)
|
||||
util::stream_format(stream, "goto %06x", (OPIMM << 16) | imm16);
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Multiply, Unsigned * Signed
|
||||
case 0x0f:
|
||||
if(OPN == 1 && OPA != 7)
|
||||
util::stream_format(stream, "mulus %s, %s", reg[OPA], reg[OPB]);
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Multiply, Signed * Signed
|
||||
case 0x4f:
|
||||
if(OPN == 1 && OPA != 7)
|
||||
util::stream_format(stream, "mulss %s, %s", reg[OPA], reg[OPB]);
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// Interrupt flags
|
||||
case 0x5f:
|
||||
if(OPA == 0)
|
||||
{
|
||||
switch(OPIMM)
|
||||
{
|
||||
case 0:
|
||||
util::stream_format(stream, "int off");
|
||||
break;
|
||||
case 1:
|
||||
util::stream_format(stream, "int irq");
|
||||
break;
|
||||
case 2:
|
||||
util::stream_format(stream, "int fiq");
|
||||
break;
|
||||
case 3:
|
||||
util::stream_format(stream, "int irq,fiq");
|
||||
break;
|
||||
case 8:
|
||||
util::stream_format(stream, "irq off");
|
||||
break;
|
||||
case 9:
|
||||
util::stream_format(stream, "irq on");
|
||||
break;
|
||||
case 12:
|
||||
util::stream_format(stream, "fiq off");
|
||||
break;
|
||||
case 14:
|
||||
util::stream_format(stream, "fiq on");
|
||||
break;
|
||||
case 37:
|
||||
util::stream_format(stream, "nop");
|
||||
break;
|
||||
default:
|
||||
util::stream_format(stream, "<inv>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
util::stream_format(stream, "%s %04x", jumps[op0], pc+1+opimm);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
if (op0 < 15 && opA == 7 && op1 == 1)
|
||||
{
|
||||
util::stream_format(stream, "%s %04x", jumps[op0], pc+1-opimm);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
switch ((op1 << 4) | op0)
|
||||
{
|
||||
case 0x05: case 0x15: case 0x25: case 0x35:
|
||||
case 0x45: case 0x55: case 0x65: case 0x75:
|
||||
case 0x85: case 0x95: case 0xa5: case 0xb5:
|
||||
case 0xc5: case 0xd5:
|
||||
case 0x07: case 0x17: case 0x27: case 0x37:
|
||||
case 0x47: case 0x57: case 0x67: case 0x77:
|
||||
case 0x87: case 0x97: case 0xa7: case 0xb7:
|
||||
case 0xc7: case 0xd7:
|
||||
case 0x1d: case 0x5d: case 0x6d:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23:
|
||||
case 0x24: case 0x26: case 0x28: case 0x2a:
|
||||
case 0x2b: case 0x2c:
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// alu, base+displacement
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x04: case 0x06: case 0x08: case 0x09:
|
||||
case 0x0a: case 0x0b: case 0x0c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
util::stream_format(stream, "[bp+%02x]", opimm);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
case 0x0d:
|
||||
util::stream_format(stream, "[bp+%02x] = %s", opimm, regs[opA]);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// alu, 6-bit immediate
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x14: case 0x16: case 0x18: case 0x19:
|
||||
case 0x1a: case 0x1b: case 0x1c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
util::stream_format(stream, "%02x", opimm);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// pop insns
|
||||
case 0x29:
|
||||
if (op == 0x9a90)
|
||||
util::stream_format(stream, "retf");
|
||||
else if (op == 0x9a98)
|
||||
util::stream_format(stream, "reti");
|
||||
else if (opA+1 < 8 && opA+opN < 8)
|
||||
util::stream_format(stream, "pop %s, %s from [%s]",
|
||||
regs[opA+1], regs[opA+opN], regs[opB]);
|
||||
else
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// push insns
|
||||
case 0x2d:
|
||||
if (opA+1 >= opN && opA < opN+7)
|
||||
util::stream_format(stream, "push %s, %s to [%s]",
|
||||
regs[opA+1-opN], regs[opA], regs[opB]);
|
||||
else
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// alu, indirect memory
|
||||
case 0x30: case 0x31: case 0x32: case 0x33:
|
||||
case 0x34: case 0x36: case 0x38: case 0x39:
|
||||
case 0x3a: case 0x3b: case 0x3c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
print_indirect_op(stream, opN, opB);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
case 0x3d:
|
||||
print_indirect_op(stream, opN, opB);
|
||||
util::stream_format(stream, " = %s", regs[opA]);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||
case 0x44: case 0x46: case 0x48: case 0x49:
|
||||
case 0x4a: case 0x4b: case 0x4c:
|
||||
switch (opN)
|
||||
{
|
||||
// alu, register
|
||||
case 0:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
util::stream_format(stream, "%s", regs[opB]);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// alu, 16-bit immediate
|
||||
case 1:
|
||||
if ((op0 == 4 || op0 == 12 || op0 == 6 || op0 == 9) && opA != opB)
|
||||
{
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
if (op0 != 4 && op0 != 12)
|
||||
util::stream_format(stream, "%s = ", regs[opA]);
|
||||
print_alu_op3(stream, op0, opB);
|
||||
util::stream_format(stream, "%04x", ximm);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// alu, direct memory
|
||||
case 2:
|
||||
if ((op0 == 4 || op0 == 12 || op0 == 6 || op0 == 9) && opA != opB)
|
||||
{
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
if (op0 != 4 && op0 != 12)
|
||||
util::stream_format(stream, "%s = ", regs[opA]);
|
||||
print_alu_op3(stream, op0, opB);
|
||||
util::stream_format(stream, "[%04x]", ximm);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// alu, direct memory
|
||||
case 3:
|
||||
if (op0 == 4 || op0 == 12)
|
||||
{
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
if ((op0 == 6 || op0 == 9) && opA != opB)
|
||||
{
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "[%04x] = ", ximm);
|
||||
print_alu_op3(stream, op0, opB);
|
||||
util::stream_format(stream, "%s", regs[opA]);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
// alu, with shift
|
||||
default:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
util::stream_format(stream, "%s asr %x", regs[opB], (opN & 3) + 1);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
case 0x4d:
|
||||
switch (opN)
|
||||
{
|
||||
// alu, direct memory
|
||||
case 3:
|
||||
if (opA != opB)
|
||||
{
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "[%04x] = %s", ximm, regs[opB]);
|
||||
return UNSP_DASM_OK;
|
||||
default:
|
||||
util::stream_format(stream, "<BAD>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
|
||||
// alu, with shift
|
||||
case 0x50: case 0x51: case 0x52: case 0x53:
|
||||
case 0x54: case 0x56: case 0x58: case 0x59:
|
||||
case 0x5a: case 0x5b: case 0x5c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
if ((opN & 4) == 0)
|
||||
util::stream_format(stream, "%s lsl %x", regs[opB], (opN & 3) + 1);
|
||||
else
|
||||
util::stream_format(stream, "%s lsr %x", regs[opB], (opN & 3) + 1);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// alu, with shift
|
||||
case 0x60: case 0x61: case 0x62: case 0x63:
|
||||
case 0x64: case 0x66: case 0x68: case 0x69:
|
||||
case 0x6a: case 0x6b: case 0x6c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
if ((opN & 4) == 0)
|
||||
util::stream_format(stream, "%s rol %x", regs[opB], (opN & 3) + 1);
|
||||
else
|
||||
util::stream_format(stream, "%s ror %x", regs[opB], (opN & 3) + 1);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
// alu, direct memory
|
||||
case 0x70: case 0x71: case 0x72: case 0x73:
|
||||
case 0x74: case 0x76: case 0x78: case 0x79:
|
||||
case 0x7a: case 0x7b: case 0x7c:
|
||||
print_alu_op_start(stream, op0, opA);
|
||||
util::stream_format(stream, "[%02x]", opimm);
|
||||
print_alu_op_end(stream, op0);
|
||||
return UNSP_DASM_OK;
|
||||
case 0x7d:
|
||||
util::stream_format(stream, "[%02x] = %s", opimm, regs[opA]);
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
case 0x1f:
|
||||
if (opA == 0)
|
||||
{
|
||||
util::stream_format(stream, "call %04x", (opimm << 16) | ximm);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
case 0x2f: case 0x3f: case 0x6f: case 0x7f:
|
||||
if (opA == 7 && op1 == 2)
|
||||
{
|
||||
util::stream_format(stream, "goto %04x", (opimm << 16) | ximm);
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
if (opA == 7 && op1 == 3)
|
||||
{
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
|
||||
case 0x0f:
|
||||
switch (opN)
|
||||
{
|
||||
case 1:
|
||||
if (opA == 7)
|
||||
{
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "mr = %s*%s, us", regs[opA], regs[opB]);
|
||||
return UNSP_DASM_OK;
|
||||
default:
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
case 0x4f:
|
||||
switch (opN)
|
||||
{
|
||||
case 1:
|
||||
if (opA == 7)
|
||||
{
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "mr = %s*%s", regs[opA], regs[opB]);
|
||||
return UNSP_DASM_OK;
|
||||
default:
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
case 0x5f:
|
||||
if (opA != 0)
|
||||
{
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
switch (opimm)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "int off");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x01:
|
||||
util::stream_format(stream, "int irq");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x02:
|
||||
util::stream_format(stream, "int fiq");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x03:
|
||||
util::stream_format(stream, "int fiq,irq");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x04:
|
||||
util::stream_format(stream, "fir_mov on");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x05:
|
||||
util::stream_format(stream, "fir_mov off");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x08:
|
||||
util::stream_format(stream, "irq off");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x09:
|
||||
util::stream_format(stream, "irq on");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x0c:
|
||||
util::stream_format(stream, "fiq off");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x0e:
|
||||
util::stream_format(stream, "fiq on");
|
||||
return UNSP_DASM_OK;
|
||||
case 0x25:
|
||||
util::stream_format(stream, "nop");
|
||||
return UNSP_DASM_OK;
|
||||
default:
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
case 0x0e: case 0x1e: case 0x2e: case 0x3e:
|
||||
case 0x4e: case 0x5e: case 0x6e: case 0x7e:
|
||||
util::stream_format(stream, "<DUNNO>");
|
||||
return UNSP_DASM_OK;
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "<UNHANDLED>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
util::stream_format(stream, "<inv>");
|
||||
return UNSP_DASM_OK;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// license:GPL-2.0
|
||||
// copyright-holders:Segher Boessenkool
|
||||
/*****************************************************************************
|
||||
|
||||
SunPlus micro'nSP disassembler
|
||||
|
||||
Copyright 2008-2017 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
Licensed under the terms of the GNU GPL, version 2
|
||||
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_UNSP_UNSPDASM_H
|
||||
@ -22,9 +26,13 @@ public:
|
||||
offs_t disassemble(std::ostream &stream, offs_t pc, uint16_t op, uint16_t imm16);
|
||||
|
||||
private:
|
||||
static char const *const reg[];
|
||||
static char const *const jmp[];
|
||||
static char const *const alu[];
|
||||
void print_alu_op_start(std::ostream &stream, uint8_t op0, uint8_t opA);
|
||||
void print_alu_op3(std::ostream &stream, uint8_t op0, uint8_t opB);
|
||||
void print_alu_op_end(std::ostream &stream, uint8_t op0);
|
||||
void print_indirect_op(std::ostream &stream, uint8_t opN, uint8_t opB);
|
||||
|
||||
static char const *const regs[];
|
||||
static char const *const jumps[];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -167,7 +167,8 @@ void spg2xx_device::device_reset()
|
||||
memset(m_video_regs, 0, 0x100 * sizeof(uint16_t));
|
||||
memset(m_io_regs, 0, 0x200 * sizeof(uint16_t));
|
||||
|
||||
m_io_regs[0x23] = 0x0028;
|
||||
//m_io_regs[0x23] = 0x0028;
|
||||
m_uart_rx_available = false;
|
||||
|
||||
m_video_regs[0x36] = 0xffff;
|
||||
m_video_regs[0x37] = 0xffff;
|
||||
@ -830,7 +831,7 @@ WRITE_LINE_MEMBER(spg2xx_device::vblank)
|
||||
#endif
|
||||
|
||||
const uint16_t old = VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS;
|
||||
VIDEO_IRQ_STATUS |= 1;
|
||||
//VIDEO_IRQ_STATUS |= 1;
|
||||
LOGMASKED(LOG_IRQS, "Setting video IRQ status to %04x\n", VIDEO_IRQ_STATUS);
|
||||
const uint16_t changed = old ^ (VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS);
|
||||
if (changed)
|
||||
@ -849,18 +850,16 @@ void spg2xx_device::check_video_irq()
|
||||
|
||||
void spg2xx_device::uart_rx(uint8_t data)
|
||||
{
|
||||
if (m_uart_rx_index < 8)
|
||||
if (!m_uart_rx_available)
|
||||
{
|
||||
m_uart_rx_fifo[m_uart_rx_index] = data;
|
||||
m_uart_rx_index++;
|
||||
m_io_regs[0x31] |= 1;
|
||||
if (m_uart_rx_index > (m_io_regs[0x37] & 7))
|
||||
if (BIT(m_io_regs[0x30], 6))
|
||||
{
|
||||
const uint16_t old = IO_IRQ_STATUS;
|
||||
IO_IRQ_STATUS |= 0x0100;
|
||||
const uint16_t changed = old ^ IO_IRQ_STATUS;
|
||||
if (changed & IO_IRQ_ENABLE)
|
||||
m_io_regs[0x36] = data;
|
||||
if (BIT(m_io_regs[0x30], 0))
|
||||
{
|
||||
IO_IRQ_STATUS |= 0x0100;
|
||||
check_irqs(0x0100);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -947,32 +946,26 @@ READ16_MEMBER(spg2xx_device::io_r)
|
||||
break;
|
||||
|
||||
case 0x31: // UART Status
|
||||
val = 0x0002 | (m_uart_rx_index ? 1 : 0) | (m_uart_rx_index == 8 ? 0x80 : 0);
|
||||
val |= 0x81;//(m_uart_rx_available ? 0x81 : 0);
|
||||
LOGMASKED(LOG_UART, "io_r: UART Status = %04x\n", val);
|
||||
break;
|
||||
|
||||
case 0x36: // UART RX Data
|
||||
if (m_uart_rx_index)
|
||||
if (m_uart_rx_available)
|
||||
{
|
||||
val = m_uart_rx_fifo[0];
|
||||
m_uart_rx_fifo[0] = 0;
|
||||
m_uart_rx_index--;
|
||||
for (uint8_t i = 0; i < m_uart_rx_index; i++)
|
||||
{
|
||||
m_uart_rx_fifo[i] = m_uart_rx_fifo[i + 1];
|
||||
}
|
||||
m_uart_rx_available = false;
|
||||
m_io_regs[0x36] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_io_regs[0x37] |= 0x2000;
|
||||
val = 0;
|
||||
}
|
||||
LOGMASKED(LOG_UART, "io_r: UART Rx Data = %04x\n", val);
|
||||
break;
|
||||
|
||||
case 0x37: // UART Rx FIFO Control
|
||||
val &= ~0x0070;
|
||||
val |= (m_uart_rx_index > 7 ? 7 : m_uart_rx_index) << 4;
|
||||
val |= (m_uart_rx_available ? 7 : 0) << 4;
|
||||
LOGMASKED(LOG_UART, "io_r: UART Rx FIFO Control = %04x\n", val);
|
||||
break;
|
||||
|
||||
@ -1147,12 +1140,14 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
if (changed & 0x0013)
|
||||
{
|
||||
const uint32_t freq = s_tmb1_freq[hifreq][data & 3];
|
||||
m_tmb1->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
|
||||
m_cpu->set_timer_interval(0, 27000000 / freq);
|
||||
//m_tmb1->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
|
||||
}
|
||||
if (changed & 0x001c)
|
||||
{
|
||||
const uint32_t freq = s_tmb2_freq[hifreq][(data >> 2) & 3];
|
||||
m_tmb2->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
|
||||
m_cpu->set_timer_interval(1, 27000000 / freq);
|
||||
//m_tmb2->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1238,16 +1233,16 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
case 0x25: // ADC Control
|
||||
{
|
||||
LOGMASKED(LOG_IO_WRITES, "io_w: ADC Control = %04x\n", data);
|
||||
const uint16_t changed = m_io_regs[offset] ^ data;
|
||||
//const uint16_t changed = m_io_regs[offset] ^ data;
|
||||
m_io_regs[offset] = data;
|
||||
if (BIT(changed, 12) && BIT(data, 12) && !BIT(m_io_regs[offset], 1))
|
||||
//if (BIT(changed, 12) && BIT(data, 12) && !BIT(m_io_regs[offset], 1))
|
||||
{
|
||||
m_io_regs[0x27] = 0x80ff;
|
||||
const uint16_t old = IO_IRQ_STATUS;
|
||||
IO_IRQ_STATUS |= 0x2000;
|
||||
const uint16_t changed = IO_IRQ_STATUS ^ old;
|
||||
if (changed)
|
||||
check_irqs(changed);
|
||||
//m_io_regs[0x27] = 0x80ff;
|
||||
//const uint16_t old = IO_IRQ_STATUS;
|
||||
//IO_IRQ_STATUS |= 0x2000;
|
||||
//const uint16_t changed = IO_IRQ_STATUS ^ old;
|
||||
//if (changed)
|
||||
//check_irqs(changed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1306,23 +1301,23 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
static const char* const s_9th_bit[4] = { "0", "1", "Odd", "Even" };
|
||||
LOGMASKED(LOG_UART, "io_w: UART Control = %04x (TxEn:%d, RxEn:%d, Bits:%d, MultiProc:%d, 9thBit:%s, TxIntEn:%d, RxIntEn:%d\n", data
|
||||
, BIT(data, 7), BIT(data, 6), BIT(data, 5) ? 9 : 8, BIT(data, 4), s_9th_bit[(data >> 2) & 3], BIT(data, 1), BIT(data, 0));
|
||||
const uint16_t changed = m_io_regs[offset] ^ data;
|
||||
//const uint16_t changed = m_io_regs[offset] ^ data;
|
||||
m_io_regs[offset] = data;
|
||||
if (!BIT(data, 6))
|
||||
{
|
||||
m_uart_rx_index = 0;
|
||||
memset(m_uart_rx_fifo, 0, 8);
|
||||
}
|
||||
if (BIT(changed, 7) && BIT(data, 7))
|
||||
{
|
||||
m_io_regs[0x31] |= 0x0002;
|
||||
m_uart_rx_available = false;
|
||||
m_io_regs[0x36] = 0;
|
||||
}
|
||||
//if (BIT(changed, 7) && BIT(data, 7))
|
||||
//{
|
||||
// m_io_regs[0x31] |= 0x0002;
|
||||
//}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x31: // UART Status
|
||||
LOGMASKED(LOG_UART, "io_w: UART Status = %04x\n", data);
|
||||
//m_io_regs[offset] &= ~data;
|
||||
m_io_regs[offset] &= ~data;
|
||||
break;
|
||||
|
||||
case 0x33: // UART Baud Rate
|
||||
@ -1333,6 +1328,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
case 0x35: // UART TX Data
|
||||
LOGMASKED(LOG_UART, "io_w: UART Tx Data = %02x\n", data & 0x00ff);
|
||||
m_io_regs[offset] = data;
|
||||
m_io_regs[0x31] |= 2;
|
||||
m_uart_tx((uint8_t)data);
|
||||
break;
|
||||
|
||||
@ -1345,8 +1341,8 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
, BIT(data, 15), BIT(data, 14), BIT(data, 13), (data >> 4) & 7, data & 7);
|
||||
if (data & 0x8000)
|
||||
{
|
||||
m_uart_rx_index = 0;
|
||||
memset(m_uart_rx_fifo, 0, 8);
|
||||
m_uart_rx_available = false;
|
||||
m_io_regs[0x36] = 0;
|
||||
}
|
||||
m_io_regs[offset] &= ~data & 0x6000;
|
||||
m_io_regs[offset] &= ~0x0007;
|
||||
@ -1394,6 +1390,18 @@ WRITE16_MEMBER(spg2xx_device::io_w)
|
||||
m_io_regs[offset] = data;
|
||||
break;
|
||||
|
||||
case 0x60: // SPECIAL INTERRUPT HAX - REMOVE BEFORE CHECKIN
|
||||
m_io_regs[0x22] |= data;
|
||||
break;
|
||||
|
||||
case 0x61: // SPECIAL INTERRUPT HAX - REMOVE BEFORE CHECKIN
|
||||
m_video_regs[0x63] |= data;
|
||||
break;
|
||||
|
||||
case 0x62: // SPECIAL INTERRUPT HAX - REMOVE BEFORE CHECKIN
|
||||
m_io_regs[0x22] |= data;
|
||||
break;
|
||||
|
||||
case 0x100: // DMA Source (lo)
|
||||
LOGMASKED(LOG_DMA, "io_w: DMA Source (lo) = %04x\n", data);
|
||||
m_io_regs[offset] = data;
|
||||
@ -1427,17 +1435,17 @@ void spg2xx_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
{
|
||||
case TIMER_TMB1:
|
||||
{
|
||||
LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
|
||||
IO_IRQ_STATUS |= 1;
|
||||
check_irqs(0x0001);
|
||||
//LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
|
||||
//IO_IRQ_STATUS |= 1;
|
||||
//check_irqs(0x0001);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIMER_TMB2:
|
||||
{
|
||||
LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
|
||||
IO_IRQ_STATUS |= 2;
|
||||
check_irqs(0x0002);
|
||||
//LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
|
||||
//IO_IRQ_STATUS |= 2;
|
||||
//check_irqs(0x0002);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1468,6 +1476,9 @@ void spg2xx_device::check_irqs(const uint16_t changed)
|
||||
// m_cpu->set_input_line(UNSP_IRQ1_LINE, ASSERT_LINE);
|
||||
// }
|
||||
|
||||
if (true)
|
||||
return;
|
||||
|
||||
if (changed & 0x0c00) // Timer A, Timer B IRQ
|
||||
{
|
||||
m_cpu->set_input_line(UNSP_IRQ2_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
|
||||
|
@ -225,16 +225,16 @@ protected:
|
||||
AUDIO_ADPCM36_MASK = 0x8000,
|
||||
|
||||
AUDIO_PHASE_HIGH = 0x200,
|
||||
AUDIO_PHASE_HIGH_MASK = 0x0007,
|
||||
AUDIO_PHASE_HIGH_MASK = 0xffff,
|
||||
|
||||
AUDIO_PHASE_ACCUM_HIGH = 0x201,
|
||||
AUDIO_PHASE_ACCUM_HIGH_MASK = 0x0007,
|
||||
AUDIO_PHASE_ACCUM_HIGH_MASK = 0xffff,
|
||||
|
||||
AUDIO_TARGET_PHASE_HIGH = 0x202,
|
||||
AUDIO_TARGET_PHASE_HIGH_MASK= 0x0007,
|
||||
AUDIO_TARGET_PHASE_HIGH_MASK= 0xffff,
|
||||
|
||||
AUDIO_RAMP_DOWN_CLOCK = 0x203,
|
||||
AUDIO_RAMP_DOWN_CLOCK_MASK = 0x0007,
|
||||
AUDIO_RAMP_DOWN_CLOCK_MASK = 0xffff,
|
||||
|
||||
AUDIO_PHASE = 0x204,
|
||||
AUDIO_PHASE_ACCUM = 0x205,
|
||||
@ -439,8 +439,7 @@ protected:
|
||||
uint16_t m_audio_curr_beat_base_count;
|
||||
|
||||
uint16_t m_io_regs[0x200];
|
||||
uint8_t m_uart_rx_fifo[8];
|
||||
uint8_t m_uart_rx_index;
|
||||
bool m_uart_rx_available;
|
||||
|
||||
uint16_t m_video_regs[0x100];
|
||||
size_t m_sprite_limit;
|
||||
@ -468,7 +467,7 @@ protected:
|
||||
sound_stream *m_stream;
|
||||
oki_adpcm_state m_adpcm[16];
|
||||
|
||||
required_device<cpu_device> m_cpu;
|
||||
required_device<unsp_device> m_cpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_shared_ptr<uint16_t> m_scrollram;
|
||||
required_shared_ptr<uint16_t> m_paletteram;
|
||||
|
@ -186,7 +186,7 @@ public:
|
||||
: spg2xx_game_state(mconfig, type, tag)
|
||||
, m_cart(*this, "cartslot")
|
||||
, m_bankdev(*this, "bank")
|
||||
, m_cart_banks(*this, "cartbank%u", 0U)
|
||||
, m_system_region(*this, "maincpu")
|
||||
{ }
|
||||
|
||||
void vsmile(machine_config &config);
|
||||
@ -218,9 +218,9 @@ private:
|
||||
DECLARE_READ16_MEMBER(bank2_r);
|
||||
DECLARE_READ16_MEMBER(bank3_r);
|
||||
optional_device<generic_slot_device> m_cart;
|
||||
memory_region *m_cart_rom;
|
||||
required_device<address_map_bank_device> m_bankdev;
|
||||
optional_memory_bank_array<4> m_cart_banks;
|
||||
memory_region *m_cart_region;
|
||||
required_memory_region m_system_region;
|
||||
|
||||
emu_timer *m_pad_timer;
|
||||
uint8_t m_pad_counter;
|
||||
@ -248,7 +248,7 @@ private:
|
||||
virtual void machine_reset() override;
|
||||
|
||||
optional_device<generic_slot_device> m_cart;
|
||||
memory_region *m_cart_rom;
|
||||
memory_region *m_cart_region;
|
||||
};
|
||||
|
||||
#define VERBOSE_LEVEL (4)
|
||||
@ -340,7 +340,7 @@ void vsmile_state::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
if (m_pad_counter >= 100)
|
||||
{
|
||||
m_pad_counter = 0;
|
||||
m_spg->uart_rx(0x55);
|
||||
//m_spg->uart_rx(0x55);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,59 +362,55 @@ void vsmile_state::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
|
||||
READ16_MEMBER(vsmile_state::bank0_r)
|
||||
{
|
||||
const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset];
|
||||
//printf("bank0_r: %06x: %04x\n", offset, data);
|
||||
return data;
|
||||
return ((uint16_t*)m_cart_region->base())[offset];
|
||||
}
|
||||
|
||||
READ16_MEMBER(vsmile_state::bank1_r)
|
||||
{
|
||||
const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset + 0x100000];
|
||||
//printf("bank1_r: %06x: %04x\n", offset + 0x100000, data);
|
||||
return data;
|
||||
return ((uint16_t*)m_cart_region->base())[offset + 0x100000];
|
||||
}
|
||||
|
||||
READ16_MEMBER(vsmile_state::bank2_r)
|
||||
{
|
||||
const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset + 0x200000];
|
||||
//printf("bank2_r: %06x: %04x\n", offset + 0x200000, data);
|
||||
return data;
|
||||
return ((uint16_t*)m_cart_region->base())[offset + 0x200000];
|
||||
}
|
||||
|
||||
READ16_MEMBER(vsmile_state::bank3_r)
|
||||
{
|
||||
const uint16_t data = ((uint16_t*)memregion("maincpu")->base())[offset];
|
||||
//printf("bank3_r: %06x: %04x\n", offset + 0x300000, data);
|
||||
return data;
|
||||
return ((uint16_t*)m_system_region->base())[offset];
|
||||
}
|
||||
|
||||
READ16_MEMBER(vsmile_state::portb_r)
|
||||
{
|
||||
//const uint8_t inputs = m_io_p2->read();
|
||||
//const uint16_t input_bits = BIT(inputs, 0) ? VSMILE_PORTB_ON_SW : 0;
|
||||
const uint16_t data = VSMILE_PORTB_ON_SW | (m_cart && m_cart->exists() ? VSMILE_PORTB_CART : 0);
|
||||
//const uint16_t data = VSMILE_PORTB_ON_SW | VSMILE_PORTB_OFF_SW | (m_cart && m_cart->exists() ? VSMILE_PORTB_CART : 0);
|
||||
//logerror("V.Smile Port B read %04x, mask %04x\n", data, mem_mask);
|
||||
//printf("V.Smile Port B read %04x, mask %04x\n", data, mem_mask);
|
||||
return data;
|
||||
return m_portb_data;// | data;
|
||||
}
|
||||
|
||||
READ16_MEMBER(vsmile_state::portc_r)
|
||||
{
|
||||
const uint16_t data = VSMILE_PORTC_LOGO | 0x0004;
|
||||
uint16_t data = 0x0004;
|
||||
if (m_portc_data & 0x0100)
|
||||
data |= 0x0400;
|
||||
if (m_portc_data & 0x0200)
|
||||
data |= 0x1000;
|
||||
//logerror("V.Smile Port C read %04x, mask %04x\n", data, mem_mask);
|
||||
return data;
|
||||
return (m_portc_data & ~0x000f) | data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(vsmile_state::portb_w)
|
||||
{
|
||||
m_portb_data = data & mem_mask;
|
||||
m_portb_data = data;//(m_portb_data &~ mem_mask) | (data & mem_mask);
|
||||
//logerror("V.Smile Port B write %04x, mask %04x\n", m_portb_data, mem_mask);
|
||||
//printf("V.Smile Port B write %04x, mask %04x\n", m_portb_data, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(vsmile_state::portc_w)
|
||||
{
|
||||
m_portc_data = data & mem_mask;
|
||||
m_portc_data = data;//(m_portc_data &~ mem_mask) | (data & mem_mask);
|
||||
//logerror("V.Smile Port C write %04x, mask %04x\n", m_portc_data, mem_mask);
|
||||
//printf("V.Smile Port C write %04x, mask %04x\n", m_portc_data, mem_mask);
|
||||
//printf("%02x ", data >> 8);
|
||||
@ -422,26 +418,22 @@ WRITE16_MEMBER(vsmile_state::portc_w)
|
||||
|
||||
WRITE8_MEMBER(vsmile_state::uart_tx)
|
||||
{
|
||||
//logerror("UART Tx: %02x\n", data);
|
||||
logerror("UART Tx: %02x\n", data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(vsmile_state::chip_sel_w)
|
||||
{
|
||||
//logerror("Chip select mode: %d\n", data);
|
||||
const uint16_t cart_offset = m_cart && m_cart->exists() ? 4 : 0;
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
//logerror("Setting bank %d\n", cart_offset);
|
||||
m_bankdev->set_bank(cart_offset);
|
||||
break;
|
||||
case 1:
|
||||
//logerror("Setting bank %d\n", 1 + cart_offset);
|
||||
m_bankdev->set_bank(1 + cart_offset);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
//logerror("Setting bank %d\n", 2 + cart_offset);
|
||||
m_bankdev->set_bank(2 + cart_offset);
|
||||
break;
|
||||
}
|
||||
@ -499,15 +491,10 @@ void vsmile_state::banked_map(address_map &map)
|
||||
map(0x0a00000, 0x0afffff).rom().region("maincpu", 0);
|
||||
map(0x0b00000, 0x0bfffff).rom().region("maincpu", 0);
|
||||
|
||||
map(0x1000000, 0x10fffff).bankr("cartbank0");
|
||||
map(0x1100000, 0x11fffff).bankr("cartbank0");
|
||||
map(0x1200000, 0x12fffff).bankr("cartbank0");
|
||||
map(0x1300000, 0x13fffff).bankr("cartbank0");
|
||||
map(0x1000000, 0x13fffff).r(FUNC(vsmile_state::bank0_r));
|
||||
|
||||
map(0x1400000, 0x14fffff).bankr("cartbank0");
|
||||
map(0x1500000, 0x15fffff).bankr("cartbank0");
|
||||
map(0x1600000, 0x16fffff).bankr("cartbank1");
|
||||
map(0x1700000, 0x17fffff).bankr("cartbank1");
|
||||
map(0x1400000, 0x15fffff).r(FUNC(vsmile_state::bank0_r));
|
||||
map(0x1600000, 0x17fffff).r(FUNC(vsmile_state::bank1_r));
|
||||
|
||||
map(0x1800000, 0x18fffff).r(FUNC(vsmile_state::bank0_r));
|
||||
map(0x1900000, 0x19fffff).r(FUNC(vsmile_state::bank1_r));
|
||||
@ -759,8 +746,8 @@ void spg2xx_cart_state::machine_start()
|
||||
if (m_cart && m_cart->exists())
|
||||
{
|
||||
std::string region_tag;
|
||||
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
m_bank->configure_entries(0, ceilf((float)m_cart_rom->bytes() / 0x800000), m_cart_rom->base(), 0x800000);
|
||||
m_cart_region = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
m_bank->configure_entries(0, ceilf((float)m_cart_region->bytes() / 0x800000), m_cart_region->base(), 0x800000);
|
||||
m_bank->set_entry(0);
|
||||
}
|
||||
}
|
||||
@ -771,22 +758,7 @@ void vsmile_state::machine_start()
|
||||
if (m_cart && m_cart->exists())
|
||||
{
|
||||
std::string region_tag;
|
||||
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
const uint32_t banks = (m_cart_rom->bytes() + 0x1fffff) / 0x200000;
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
m_cart_banks[i]->configure_entries(0, banks, m_cart_rom->base(), 0x200000);
|
||||
m_cart_banks[i]->set_entry(i % banks);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
m_cart_rom = memregion("maincpu");
|
||||
m_cart_banks[i]->configure_entries(0, (m_cart_rom->bytes() + 0x1fffff) / 0x200000, m_cart_rom->base(), 0x200000);
|
||||
m_cart_banks[i]->set_entry(0);
|
||||
}
|
||||
m_cart_region = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
|
||||
}
|
||||
|
||||
m_bankdev->set_bank(m_cart && m_cart->exists() ? 4 : 0);
|
||||
|
Loading…
Reference in New Issue
Block a user