summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2008-10-12 00:05:13 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2008-10-12 00:05:13 +0000
commit864820d8ade26280adbdb01da26fbdca2b677f99 (patch)
tree2b0af5176214d13fab83983bfee4ab81ecd0d536 /src
parente135e4e8d661693f7238497b211c9c5a28a666be (diff)
Fix Mantis #02211
PsikyoSH: hook up VBL IRQ ack SH2: fix DRC's handling of internally generated IRQs SH2: fix compiling in interpreter mode
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/sh2/sh2.c24
-rw-r--r--src/emu/cpu/sh2/sh2comn.c2
-rw-r--r--src/emu/cpu/sh2/sh2drc.c22
-rw-r--r--src/mame/drivers/psikyosh.c17
4 files changed, 52 insertions, 13 deletions
diff --git a/src/emu/cpu/sh2/sh2.c b/src/emu/cpu/sh2/sh2.c
index ba5e285225e..99d20fdbe44 100644
--- a/src/emu/cpu/sh2/sh2.c
+++ b/src/emu/cpu/sh2/sh2.c
@@ -2176,6 +2176,16 @@ static void sh2_reset(void)
sh2->internal_irq_level = -1;
}
+/*-------------------------------------------------
+ sh1_reset - reset the processor
+-------------------------------------------------*/
+
+static void sh1_reset(void)
+{
+ sh2_reset();
+ sh2->cpu_type = CPU_TYPE_SH1;
+}
+
/* Execute cycles - returns number of cycles actually run */
static int sh2_execute(int cycles)
{
@@ -2462,4 +2472,18 @@ void sh2_get_info(UINT32 state, cpuinfo *info)
}
}
+void sh1_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_RESET: info->reset = sh1_reset; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "SH-1"); break;
+
+ default: sh2_get_info(state, info); break;
+ }
+}
+
#endif
diff --git a/src/emu/cpu/sh2/sh2comn.c b/src/emu/cpu/sh2/sh2comn.c
index 917cd876090..7998f4ad3b8 100644
--- a/src/emu/cpu/sh2/sh2comn.c
+++ b/src/emu/cpu/sh2/sh2comn.c
@@ -651,7 +651,7 @@ void sh2_exception(const char *message, int irqline)
else
sh2->sr = (sh2->sr & ~I) | (irqline << 4);
-// printf("sh2_exception [%s] irqline %x evec %x save SR %x new SR %x\n", message, irqline, sh2->evec, sh2->irqsr, sh2->sr);
+// printf("sh2_exception [%s] irqline %x evec %x save SR %x new SR %x\n", message, irqline, sh2->evec, sh2->irqsr, sh2->sr);
#else
sh2->r[15] -= 4;
WL( sh2->r[15], sh2->sr ); /* push SR onto stack */
diff --git a/src/emu/cpu/sh2/sh2drc.c b/src/emu/cpu/sh2/sh2drc.c
index ece49719d3c..1f30af17435 100644
--- a/src/emu/cpu/sh2/sh2drc.c
+++ b/src/emu/cpu/sh2/sh2drc.c
@@ -1034,6 +1034,7 @@ static void static_generate_entry_point(drcuml_state *drcuml)
load_fast_iregs(block);
/* check for interrupts */
+ UML_MOV(block, MEM(&sh2->irqline), IMM(0xffffffff)); // mov irqline, #-1
UML_CMP(block, MEM(&sh2->pending_nmi), IMM(0)); // cmp pending_nmi, #0
UML_JMPc(block, IF_Z, skip+2); // jz skip+2
@@ -1044,16 +1045,18 @@ static void static_generate_entry_point(drcuml_state *drcuml)
UML_MOV(block, MEM(&sh2->evec), IMM(0xffffffff)); // mov evec, -1
UML_MOV(block, IREG(0), IMM(0xffffffff)); // mov r0, -1 (r0 = irq)
UML_AND(block, IREG(1), IREG(0), IMM(0xffff)); // and r1, 0xffff
+
UML_LZCNT(block, IREG(1), MEM(&sh2->pending_irq)); // lzcnt r1, r1
UML_CMP(block, IREG(1), IMM(32)); // cmp r1, #32
- UML_JMPc(block, IF_Z, skip+1); // jz skip+1
+ UML_JMPc(block, IF_Z, skip+4); // jz skip+4
UML_SUB(block, MEM(&sh2->irqline), IMM(31), IREG(1)); // sub irqline, #31, r1
+ UML_LABEL(block, skip+4); // skip+4:
UML_CMP(block, MEM(&sh2->internal_irq_level), IMM(0xffffffff)); // cmp internal_irq_level, #-1
UML_JMPc(block, IF_Z, skip+3); // jz skip+3
UML_CMP(block, MEM(&sh2->internal_irq_level), MEM(&sh2->irqline)); // cmp internal_irq_level, irqline
- UML_JMPc(block, IF_BE, skip+3); // ja skip+3
+ UML_JMPc(block, IF_LE, skip+3); // jle skip+3
UML_MOV(block, MEM(&sh2->irqline), MEM(&sh2->internal_irq_level)); // mov r0, internal_irq_level
@@ -1409,14 +1412,15 @@ static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op)
static void generate_update_cycles(drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception)
{
/* check full interrupts if pending */
- if (compiler->checkints)
+ if (compiler->checkints)
{
drcuml_codelabel skip = compiler->labelnum++;
compiler->checkints = FALSE;
- compiler->labelnum += 3;
+ compiler->labelnum += 4;
/* check for interrupts */
+ UML_MOV(block, MEM(&sh2->irqline), IMM(0xffffffff)); // mov irqline, #-1
UML_CMP(block, MEM(&sh2->pending_nmi), IMM(0)); // cmp pending_nmi, #0
UML_JMPc(block, IF_Z, skip+2); // jz skip+2
@@ -1426,17 +1430,19 @@ static void generate_update_cycles(drcuml_block *block, compiler_state *compiler
UML_LABEL(block, skip+2); // skip+2:
UML_MOV(block, MEM(&sh2->evec), IMM(0xffffffff)); // mov evec, -1
UML_MOV(block, IREG(0), IMM(0xffffffff)); // mov r0, -1 (r0 = irq)
- UML_AND(block, IREG(1), IREG(0), IMM(0xffff)); // and r1, 0xffff
- UML_LZCNT(block, IREG(1), MEM(&sh2->pending_irq)); // lzcnt r1, r1
+ UML_AND(block, IREG(1), IREG(0), IMM(0xffff)); // and r1, r0, 0xffff
+
+ UML_LZCNT(block, IREG(1), MEM(&sh2->pending_irq)); // lzcnt r1, pending_irq
UML_CMP(block, IREG(1), IMM(32)); // cmp r1, #32
- UML_JMPc(block, IF_Z, skip+1); // jz skip+1
+ UML_JMPc(block, IF_Z, skip+4); // jz skip+4
UML_SUB(block, MEM(&sh2->irqline), IMM(31), IREG(1)); // sub irqline, #31, r1
+ UML_LABEL(block, skip+4); // skip+4:
UML_CMP(block, MEM(&sh2->internal_irq_level), IMM(0xffffffff)); // cmp internal_irq_level, #-1
UML_JMPc(block, IF_Z, skip+3); // jz skip+3
UML_CMP(block, MEM(&sh2->internal_irq_level), MEM(&sh2->irqline)); // cmp internal_irq_level, irqline
- UML_JMPc(block, IF_BE, skip+3); // ja skip+3
+ UML_JMPc(block, IF_LE, skip+3); // jle skip+3
UML_MOV(block, MEM(&sh2->irqline), MEM(&sh2->internal_irq_level)); // mov r0, internal_irq_level
diff --git a/src/mame/drivers/psikyosh.c b/src/mame/drivers/psikyosh.c
index 7b8a6852b87..8e3cc3de4aa 100644
--- a/src/mame/drivers/psikyosh.c
+++ b/src/mame/drivers/psikyosh.c
@@ -48,7 +48,6 @@ To Do:
- see notes in video file -
- Sol Divide's music is completely broken since the SH2 DRC
Daraku is missing some screen blend effects
@@ -414,7 +413,17 @@ static READ32_HANDLER( psh_eeprom_r )
static INTERRUPT_GEN(psikyosh_interrupt)
{
- cpunum_set_input_line(machine, 0, 4, HOLD_LINE);
+ cpunum_set_input_line(machine, 0, 4, ASSERT_LINE);
+}
+
+// VBL handler writes 0x00 on entry, 0xc0 on exit
+// bit 0 controls game speed on readback, mechanism is a little weird
+static WRITE32_HANDLER( psikyosh_irqctrl_w )
+{
+ if (!(data & 0x00c00000))
+ {
+ cpunum_set_input_line(machine, 0, 4, CLEAR_LINE);
+ }
}
static WRITE32_HANDLER( paletteram32_RRRRRRRRGGGGGGGGBBBBBBBBxxxxxxxx_dword_w )
@@ -532,7 +541,7 @@ static ADDRESS_MAP_START( ps3v1_writemem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x03004000, 0x0300ffff) AM_WRITE(SMH_RAM) AM_BASE(&psikyosh_bgram) // backgrounds
AM_RANGE(0x03040000, 0x03044fff) AM_WRITE(paletteram32_RRRRRRRRGGGGGGGGBBBBBBBBxxxxxxxx_dword_w) AM_BASE(&paletteram32) // palette..
AM_RANGE(0x03050000, 0x030501ff) AM_WRITE(SMH_RAM) AM_BASE(&psikyosh_zoomram) // a gradient sometimes ...
- AM_RANGE(0x0305ffdc, 0x0305ffdf) AM_WRITE(SMH_RAM) // also reads from this address
+ AM_RANGE(0x0305ffdc, 0x0305ffdf) AM_WRITE(psikyosh_irqctrl_w)
AM_RANGE(0x0305ffe0, 0x0305ffff) AM_WRITE(psikyosh_vidregs_w) AM_BASE(&psikyosh_vidregs) // video registers
AM_RANGE(0x05000000, 0x05000003) AM_WRITE(psh_ymf_fm_w) // first 2 OPL4 register banks
AM_RANGE(0x05000004, 0x05000007) AM_WRITE(psh_ymf_pcm_w) // third OPL4 register bank
@@ -569,7 +578,7 @@ static ADDRESS_MAP_START( ps5_writemem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x04004000, 0x0400ffff) AM_WRITE(SMH_RAM) AM_BASE(&psikyosh_bgram) // backgrounds
AM_RANGE(0x04040000, 0x04044fff) AM_WRITE(paletteram32_RRRRRRRRGGGGGGGGBBBBBBBBxxxxxxxx_dword_w) AM_BASE(&paletteram32)
AM_RANGE(0x04050000, 0x040501ff) AM_WRITE(SMH_RAM) AM_BASE(&psikyosh_zoomram)
- AM_RANGE(0x0405ffdc, 0x0405ffdf) AM_WRITE(SMH_RAM) // also reads from this address
+ AM_RANGE(0x0405ffdc, 0x0405ffdf) AM_WRITE(psikyosh_irqctrl_w)
AM_RANGE(0x0405ffe0, 0x0405ffff) AM_WRITE(psikyosh_vidregs_w) AM_BASE(&psikyosh_vidregs) // video registers
AM_RANGE(0x05000000, 0x0507ffff) AM_WRITE(SMH_ROM) // data ROM
AM_RANGE(0x06000000, 0x060fffff) AM_WRITE(SMH_RAM) AM_BASE(&psh_ram)