PsikyoSH: hook up VBL IRQ ack
SH2: fix DRC's handling of internally generated IRQs
SH2: fix compiling in interpreter mode
This commit is contained in:
R. Belmont 2008-10-12 00:05:13 +00:00
parent e135e4e8d6
commit 864820d8ad
4 changed files with 52 additions and 13 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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)