sh4: proper write masks for memory-mapped registers

This commit is contained in:
Flyinghead 2022-12-06 17:58:30 +01:00
parent e48b72a859
commit 8001af9743
14 changed files with 535 additions and 486 deletions

View File

@ -8,8 +8,7 @@
BSC_PDTRA_type BSC_PDTRA;
void write_BSC_PCTRA(u32 addr, u32 data)
static void write_BSC_PCTRA(u32 addr, u32 data)
{
BSC_PCTRA.full = data;
if (settings.platform.isNaomi())
@ -17,8 +16,9 @@ void write_BSC_PCTRA(u32 addr, u32 data)
//else
//printf("C:BSC_PCTRA = %08X\n",data);
}
//u32 port_out_data;
void write_BSC_PDTRA(u32 addr, u32 data)
static void write_BSC_PDTRA(u32 addr, u32 data)
{
BSC_PDTRA.full = (u16)data;
//printf("D:BSC_PDTRA = %04x\n", (u16)data);
@ -27,7 +27,7 @@ void write_BSC_PDTRA(u32 addr, u32 data)
NaomiBoardIDWrite((u16)data);
}
u32 read_BSC_PDTRA(u32 addr)
static u32 read_BSC_PDTRA(u32 addr)
{
if (settings.platform.isNaomi())
{
@ -63,55 +63,53 @@ u32 read_BSC_PDTRA(u32 addr)
void bsc_init()
{
//BSC BCR1 0xFF800000 0x1F800000 32 0x00000000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_BCR1_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_BCR1_addr, 0x033efffd>();
//BSC BCR2 0xFF800004 0x1F800004 16 0x3FFC Held Held Held Bclk
sh4_rio_reg(BSC,BSC_BCR2_addr,RIO_DATA,16);
sh4_rio_reg_wmask<BSC, BSC_BCR2_addr, 0x3ffd>();
//BSC WCR1 0xFF800008 0x1F800008 32 0x77777777 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_WCR1_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_WCR1_addr, 0x77777777>();
//BSC WCR2 0xFF80000C 0x1F80000C 32 0xFFFEEFFF Held Held Held Bclk
sh4_rio_reg(BSC,BSC_WCR2_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_WCR2_addr, 0xfffeefff>();
//BSC WCR3 0xFF800010 0x1F800010 32 0x07777777 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_WCR3_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_WCR3_addr, 0x07777777>();
//BSC MCR 0xFF800014 0x1F800014 32 0x00000000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_MCR_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_MCR_addr, 0xf8bbffff>();
//BSC PCR 0xFF800018 0x1F800018 16 0x0000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_PCR_addr,RIO_DATA,16);
sh4_rio_reg16<BSC, BSC_PCR_addr>();
//BSC RTCSR 0xFF80001C 0x1F80001C 16 0x0000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_RTCSR_addr,RIO_DATA,16);
sh4_rio_reg_wmask<BSC, BSC_RTCSR_addr, 0x00ff>();
//BSC RTCNT 0xFF800020 0x1F800020 16 0x0000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_RTCNT_addr,RIO_DATA,16);
sh4_rio_reg_wmask<BSC, BSC_RTCNT_addr, 0x00ff>();
//BSC RTCOR 0xFF800024 0x1F800024 16 0x0000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_RTCOR_addr,RIO_DATA,16);
sh4_rio_reg_wmask<BSC, BSC_RTCOR_addr, 0x00ff>();
//BSC RFCR 0xFF800028 0x1F800028 16 0x0000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_RFCR_addr,RIO_DATA,16);
// forced to 0x17 to help naomi/aw boot
sh4_rio_reg(BSC, BSC_RFCR_addr, RIO_RO);
//BSC PCTRA 0xFF80002C 0x1F80002C 32 0x00000000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_PCTRA_addr,RIO_WF,16,0,write_BSC_PCTRA);
sh4_rio_reg(BSC, BSC_PCTRA_addr, RIO_WF, nullptr, write_BSC_PCTRA);
//BSC PDTRA 0xFF800030 0x1F800030 16 Undefined Held Held Held Bclk
sh4_rio_reg(BSC,BSC_PDTRA_addr,RIO_FUNC,16,&read_BSC_PDTRA,&write_BSC_PDTRA);
sh4_rio_reg(BSC, BSC_PDTRA_addr, RIO_FUNC, read_BSC_PDTRA, write_BSC_PDTRA);
//BSC PCTRB 0xFF800040 0x1F800040 32 0x00000000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_PCTRB_addr,RIO_DATA,32);
sh4_rio_reg_wmask<BSC, BSC_PCTRB_addr, 0x000000ff>();
//BSC PDTRB 0xFF800044 0x1F800044 16 Undefined Held Held Held Bclk
sh4_rio_reg(BSC,BSC_PDTRB_addr,RIO_DATA,16);
sh4_rio_reg_wmask<BSC, BSC_PDTRB_addr, 0x000f>();
//BSC GPIOIC 0xFF800048 0x1F800048 16 0x00000000 Held Held Held Bclk
sh4_rio_reg(BSC,BSC_GPIOIC_addr,RIO_DATA,16);
//note: naomi//aw might depend on rfcr
sh4_rio_reg(BSC, BSC_RFCR_addr, RIO_RO, 16);
sh4_rio_reg16<BSC, BSC_GPIOIC_addr>();
}
void bsc_reset(bool hard)
@ -137,24 +135,24 @@ void bsc_reset(bool hard)
BSC SDMR2 H'FF90 xxxx H'1F90 xxxx 8 Write-only Bclk
BSC SDMR3 H'FF94 xxxx H'1F94 xxxx 8 Bclk
*/
BSC_BCR1.full=0x0;
BSC_BCR1.full = 0;
BSC_BCR2.full = 0x3FFC;
BSC_WCR1.full = 0x77777777;
BSC_WCR2.full = 0xFFFEEFFF;
BSC_WCR3.full = 0x07777777;
BSC_MCR.full=0x0;
BSC_PCR.full=0x0;
BSC_RTCSR.full=0x0;
BSC_RTCNT.full=0x0;
BSC_RTCOR.full=0x0;
BSC_PCTRA.full=0x0;
BSC_MCR.full = 0;
BSC_PCR.full = 0;
BSC_RTCSR.full = 0;
BSC_RTCNT.full = 0;
BSC_RTCOR.full = 0;
BSC_PCTRA.full = 0;
if (hard)
BSC_PDTRA.full = 0;
BSC_PCTRB.full=0x0;
BSC_PCTRB.full = 0;
if (hard)
BSC_PDTRB.full = 0;
BSC_GPIOIC.full=0x0;
BSC_GPIOIC.full = 0;
BSC_RFCR.full = 17;
}

View File

@ -18,9 +18,9 @@ template<u32 idx>
void CCN_QACR_write(u32 addr, u32 value)
{
if (idx == 0)
CCN_QACR0.reg_data = value;
CCN_QACR0.reg_data = value & 0x1c;
else
CCN_QACR1.reg_data = value;
CCN_QACR1.reg_data = value & 0x1c;
u32 area = ((CCN_QACR_type&)value).Area;
@ -45,20 +45,22 @@ void CCN_QACR_write(u32 addr, u32 value)
}
}
void CCN_PTEH_write(u32 addr, u32 value)
static void CCN_PTEH_write(u32 addr, u32 value)
{
CCN_PTEH_type temp;
temp.reg_data = value;
temp.reg_data = value & 0xfffffcff;
#ifdef FAST_MMU
if (temp.ASID != CCN_PTEH.ASID)
mmuAddressLUTFlush(false);
#endif
CCN_PTEH = temp;
}
void CCN_MMUCR_write(u32 addr, u32 value)
static void CCN_MMUCR_write(u32 addr, u32 value)
{
CCN_MMUCR_type temp;
temp.reg_data=value;
temp.reg_data = value & 0xfcfcff05;
bool mmu_changed_state = temp.AT != CCN_MMUCR.AT;
@ -78,10 +80,11 @@ void CCN_MMUCR_write(u32 addr, u32 value)
mmu_set_state();
}
}
void CCN_CCR_write(u32 addr, u32 value)
static void CCN_CCR_write(u32 addr, u32 value)
{
CCN_CCR_type temp;
temp.reg_data=value;
temp.reg_data = value & 0x89AF;
if (temp.ICI) {
DEBUG_LOG(SH4, "Sh4: i-cache invalidation %08X", curr_pc);
@ -114,52 +117,52 @@ static u32 CCN_PRR_read(u32 addr)
void ccn_init()
{
//CCN PTEH 0xFF000000 0x1F000000 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_PTEH_addr,RIO_WF,32,0,&CCN_PTEH_write);
sh4_rio_reg(CCN, CCN_PTEH_addr, RIO_WF, nullptr, CCN_PTEH_write);
//CCN PTEL 0xFF000004 0x1F000004 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_PTEL_addr,RIO_DATA,32);
sh4_rio_reg_wmask<CCN, CCN_PTEL_addr, 0x1ffffdff>();
//CCN TTB 0xFF000008 0x1F000008 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_TTB_addr,RIO_DATA,32);
sh4_rio_reg(CCN, CCN_TTB_addr, RIO_DATA);
//CCN TEA 0xFF00000C 0x1F00000C 32 Undefined Held Held Held Iclk
sh4_rio_reg(CCN,CCN_TEA_addr,RIO_DATA,32);
sh4_rio_reg(CCN, CCN_TEA_addr, RIO_DATA);
//CCN MMUCR 0xFF000010 0x1F000010 32 0x00000000 0x00000000 Held Held Iclk
sh4_rio_reg(CCN,CCN_MMUCR_addr,RIO_WF,32,0,&CCN_MMUCR_write);
sh4_rio_reg(CCN, CCN_MMUCR_addr, RIO_WF, nullptr, CCN_MMUCR_write);
//CCN BASRA 0xFF000014 0x1F000014 8 Undefined Held Held Held Iclk
sh4_rio_reg(CCN,CCN_BASRA_addr,RIO_DATA,8);
sh4_rio_reg8<CCN, CCN_BASRA_addr>();
//CCN BASRB 0xFF000018 0x1F000018 8 Undefined Held Held Held Iclk
sh4_rio_reg(CCN,CCN_BASRB_addr,RIO_DATA,8);
sh4_rio_reg8<CCN, CCN_BASRB_addr>();
//CCN CCR 0xFF00001C 0x1F00001C 32 0x00000000 0x00000000 Held Held Iclk
sh4_rio_reg(CCN,CCN_CCR_addr,RIO_WF,32,0,&CCN_CCR_write);
sh4_rio_reg(CCN, CCN_CCR_addr, RIO_WF, nullptr, CCN_CCR_write);
//CCN TRA 0xFF000020 0x1F000020 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_TRA_addr,RIO_DATA,32);
sh4_rio_reg_wmask<CCN, CCN_TRA_addr, 0x000003fc>();
//CCN EXPEVT 0xFF000024 0x1F000024 32 0x00000000 0x00000020 Held Held Iclk
sh4_rio_reg(CCN,CCN_EXPEVT_addr,RIO_DATA,32);
sh4_rio_reg_wmask<CCN, CCN_EXPEVT_addr, 0x00000fff>();
//CCN INTEVT 0xFF000028 0x1F000028 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_INTEVT_addr,RIO_DATA,32);
sh4_rio_reg_wmask<CCN, CCN_INTEVT_addr, 0x00000fff>();
// CPU VERSION 0xFF000030 0x1F000030 (undocumented)
sh4_rio_reg(CCN,CPU_VERSION_addr, RIO_RO_FUNC, 32, &CPU_VERSION_read, 0);
sh4_rio_reg(CCN, CPU_VERSION_addr, RIO_RO_FUNC, CPU_VERSION_read, nullptr);
//CCN PTEA 0xFF000034 0x1F000034 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_PTEA_addr,RIO_DATA,32);
sh4_rio_reg_wmask<CCN, CCN_PTEA_addr, 0x0000000f>();
//CCN QACR0 0xFF000038 0x1F000038 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_QACR0_addr,RIO_WF,32,0,&CCN_QACR_write<0>);
sh4_rio_reg(CCN, CCN_QACR0_addr, RIO_WF, nullptr, CCN_QACR_write<0>);
//CCN QACR1 0xFF00003C 0x1F00003C 32 Undefined Undefined Held Held Iclk
sh4_rio_reg(CCN,CCN_QACR1_addr,RIO_WF,32,0,&CCN_QACR_write<1>);
sh4_rio_reg(CCN, CCN_QACR1_addr, RIO_WF, nullptr, CCN_QACR_write<1>);
// CCN PRR 0xFF000044 0x1F000044 (undocumented)
sh4_rio_reg(CCN,CCN_PRR_addr, RIO_RO_FUNC, 32, &CCN_PRR_read, 0);
sh4_rio_reg(CCN,CCN_PRR_addr, RIO_RO_FUNC, &CCN_PRR_read, 0);
}

View File

@ -1,33 +1,27 @@
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
/*
u16 CPG_FRQCR;
u8 CPG_STBCR;
u16 CPG_WTCNT;
u16 CPG_WTCSR;
u8 CPG_STBCR2;
*/
//Init term res
void cpg_init()
{
//CPG FRQCR H'FFC0 0000 H'1FC0 0000 16 *2 Held Held Held Pclk
sh4_rio_reg(CPG,CPG_FRQCR_addr,RIO_DATA,16);
sh4_rio_reg_wmask<CPG, CPG_FRQCR_addr, 0x0fff>();
//CPG STBCR H'FFC0 0004 H'1FC0 0004 8 H'00 Held Held Held Pclk
sh4_rio_reg(CPG,CPG_STBCR_addr,RIO_DATA,8);
sh4_rio_reg(CPG, CPG_STBCR_addr, RIO_DATA);
//CPG WTCNT H'FFC0 0008 H'1FC0 0008 8/16*3 H'00 Held Held Held Pclk
sh4_rio_reg(CPG,CPG_WTCNT_addr,RIO_DATA,16);
// Need special pattern 0x5A in upper 8 bits on write. Not currently checked
sh4_rio_reg8<CPG, CPG_WTCNT_addr>();
//CPG WTCSR H'FFC0 000C H'1FC0 000C 8/16*3 H'00 Held Held Held Pclk
sh4_rio_reg(CPG,CPG_WTCSR_addr,RIO_DATA,16);
// Need special pattern 0x5A in upper 8 bits on write. Not currently checked
sh4_rio_reg8<CPG, CPG_WTCSR_addr>();
//CPG STBCR2 H'FFC0 0010 H'1FC0 0010 8 H'00 Held Held Held Pclk
sh4_rio_reg(CPG,CPG_STBCR2_addr,RIO_DATA,8);
sh4_rio_reg_wmask<CPG, CPG_STBCR2_addr, 0x80>();
}
void cpg_reset()
{
/*

View File

@ -101,7 +101,7 @@ void DMAC_Ch2St()
static const InterruptID dmac_itr[] = { sh4_DMAC_DMTE0, sh4_DMAC_DMTE1, sh4_DMAC_DMTE2, sh4_DMAC_DMTE3 };
template<u32 ch>
void WriteCHCR(u32 addr, u32 data)
static void WriteCHCR(u32 addr, u32 data)
{
if (ch == 0 || ch == 1)
DMAC_CHCR(ch).full = data & 0xff0ffff7;
@ -140,65 +140,61 @@ void WriteCHCR(u32 addr, u32 data)
}
}
void WriteDMAOR(u32 addr, u32 data)
{
DMAC_DMAOR.full = data;
}
//Init term res
void dmac_init()
{
//DMAC SAR0 0xFFA00000 0x1FA00000 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_SAR0_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_SAR0_addr, RIO_DATA);
//DMAC DAR0 0xFFA00004 0x1FA00004 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DAR0_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_DAR0_addr, RIO_DATA);
//DMAC DMATCR0 0xFFA00008 0x1FA00008 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DMATCR0_addr,RIO_DATA,32);
sh4_rio_reg_wmask<DMAC, DMAC_DMATCR0_addr, 0x00ffffff>();
//DMAC CHCR0 0xFFA0000C 0x1FA0000C 32 0x00000000 0x00000000 Held Held Bclk
sh4_rio_reg(DMAC,DMAC_CHCR0_addr,RIO_WF,32,0,&WriteCHCR<0>);
sh4_rio_reg(DMAC, DMAC_CHCR0_addr, RIO_WF, nullptr, WriteCHCR<0>);
//DMAC SAR1 0xFFA00010 0x1FA00010 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_SAR1_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_SAR1_addr, RIO_DATA);
//DMAC DAR1 0xFFA00014 0x1FA00014 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DAR1_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_DAR1_addr, RIO_DATA);
//DMAC DMATCR1 0xFFA00018 0x1FA00018 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DMATCR1_addr,RIO_DATA,32);
sh4_rio_reg_wmask<DMAC, DMAC_DMATCR1_addr, 0x00ffffff>();
//DMAC CHCR1 0xFFA0001C 0x1FA0001C 32 0x00000000 0x00000000 Held Held Bclk
sh4_rio_reg(DMAC,DMAC_CHCR1_addr,RIO_WF,32,0,&WriteCHCR<1>);
sh4_rio_reg(DMAC, DMAC_CHCR1_addr, RIO_WF, nullptr, WriteCHCR<1>);
//DMAC SAR2 0xFFA00020 0x1FA00020 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_SAR2_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_SAR2_addr, RIO_DATA);
//DMAC DAR2 0xFFA00024 0x1FA00024 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DAR2_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_DAR2_addr, RIO_DATA);
//DMAC DMATCR2 0xFFA00028 0x1FA00028 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DMATCR2_addr,RIO_DATA,32);
sh4_rio_reg_wmask<DMAC, DMAC_DMATCR2_addr, 0x00ffffff>();
//DMAC CHCR2 0xFFA0002C 0x1FA0002C 32 0x00000000 0x00000000 Held Held Bclk
sh4_rio_reg(DMAC,DMAC_CHCR2_addr,RIO_WF,32,0,&WriteCHCR<2>);
sh4_rio_reg(DMAC, DMAC_CHCR2_addr, RIO_WF, nullptr, WriteCHCR<2>);
//DMAC SAR3 0xFFA00030 0x1FA00030 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_SAR3_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_SAR3_addr, RIO_DATA);
//DMAC DAR3 0xFFA00034 0x1FA00034 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DAR3_addr,RIO_DATA,32);
sh4_rio_reg(DMAC, DMAC_DAR3_addr, RIO_DATA);
//DMAC DMATCR3 0xFFA00038 0x1FA00038 32 Undefined Undefined Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DMATCR3_addr,RIO_DATA,32);
sh4_rio_reg_wmask<DMAC, DMAC_DMATCR3_addr, 0x00ffffff>();
//DMAC CHCR3 0xFFA0003C 0x1FA0003C 32 0x00000000 0x00000000 Held Held Bclk
sh4_rio_reg(DMAC,DMAC_CHCR3_addr,RIO_WF,32,0,&WriteCHCR<3>);
sh4_rio_reg(DMAC, DMAC_CHCR3_addr, RIO_WF, nullptr, WriteCHCR<3>);
//DMAC DMAOR 0xFFA00040 0x1FA00040 32 0x00000000 0x00000000 Held Held Bclk
sh4_rio_reg(DMAC,DMAC_DMAOR_addr,RIO_WF,32,0,&WriteDMAOR);
sh4_rio_reg_wmask<DMAC, DMAC_DMAOR_addr, 0x00008307>();
}
void dmac_reset()
{
/*
@ -226,6 +222,7 @@ void dmac_reset()
DMAC_CHCR(3).full = 0x0;
DMAC_DMAOR.full = 0x0;
}
void dmac_term()
{
}

View File

@ -11,7 +11,6 @@
#include "../sh4_interrupts.h"
#include "../sh4_mmr.h"
//Register writes need interrupt re-testing !
static void write_INTC_IPRA(u32 addr, u32 data)
@ -22,6 +21,7 @@ static void write_INTC_IPRA(u32 addr, u32 data)
SIIDRebuild(); //we need to rebuild the table
}
}
static void write_INTC_IPRB(u32 addr, u32 data)
{
if (INTC_IPRB.reg_data != (u16)data)
@ -30,6 +30,7 @@ static void write_INTC_IPRB(u32 addr, u32 data)
SIIDRebuild(); //we need to rebuild the table
}
}
static void write_INTC_IPRC(u32 addr, u32 data)
{
if (INTC_IPRC.reg_data != (u16)data)
@ -38,6 +39,7 @@ static void write_INTC_IPRC(u32 addr, u32 data)
SIIDRebuild(); //we need to rebuild the table
}
}
static u32 read_INTC_IPRD(u32 addr)
{
return 0;
@ -47,29 +49,29 @@ static u32 read_INTC_IPRD(u32 addr)
void intc_init()
{
//INTC ICR 0xFFD00000 0x1FD00000 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(INTC,INTC_ICR_addr,RIO_DATA,16);
sh4_rio_reg_wmask<INTC, INTC_ICR_addr, 0x4380>();
//INTC IPRA 0xFFD00004 0x1FD00004 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(INTC,INTC_IPRA_addr,RIO_WF,16,0,&write_INTC_IPRA);
sh4_rio_reg(INTC, INTC_IPRA_addr, RIO_WF, nullptr, write_INTC_IPRA);
//INTC IPRB 0xFFD00008 0x1FD00008 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(INTC,INTC_IPRB_addr,RIO_WF,16,0,&write_INTC_IPRB);
sh4_rio_reg(INTC, INTC_IPRB_addr, RIO_WF, nullptr, write_INTC_IPRB);
//INTC IPRC 0xFFD0000C 0x1FD0000C 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(INTC,INTC_IPRC_addr,RIO_WF,16,0,&write_INTC_IPRC);
sh4_rio_reg(INTC, INTC_IPRC_addr, RIO_WF, nullptr, write_INTC_IPRC);
//INTC IPRD 0xFFD00010 0x1FD00010 16 0xDA74 0xDA74 Held Held Pclk (SH7750S, SH7750R only)
sh4_rio_reg(INTC,INTC_IPRD_addr,RIO_RO_FUNC,16,&read_INTC_IPRD);
sh4_rio_reg(INTC, INTC_IPRD_addr, RIO_RO_FUNC, read_INTC_IPRD);
interrupts_init();
}
void intc_reset()
{
INTC_ICR.reg_data = 0x0;
INTC_IPRA.reg_data = 0x0;
INTC_IPRB.reg_data = 0x0;
INTC_IPRC.reg_data = 0x0;
INTC_ICR.reg_data = 0;
INTC_IPRA.reg_data = 0;
INTC_IPRB.reg_data = 0;
INTC_IPRC.reg_data = 0;
interrupts_reset();
}

View File

@ -529,9 +529,11 @@ void MMU_init()
}
}
mmu_set_state();
#ifdef FAST_MMU
// pre-fill kernel memory
for (u32 vpn = ARRAY_SIZE(mmuAddressLUT) / 2; vpn < ARRAY_SIZE(mmuAddressLUT); vpn++)
mmuAddressLUT[vpn] = vpn << 12;
#endif
}
@ -559,7 +561,6 @@ void mmu_flush_table()
for (u32 i = 0; i < 64; i++)
UTLB[i].Data.V = 0;
mmuAddressLUTFlush(true);
}
#endif

View File

@ -152,8 +152,10 @@ static inline u32 mmuDynarecLookup(u32 vaddr, u32 write, u32 pc)
// not reached
return 0;
}
#ifdef FAST_MMU
if (vaddr >> 31 == 0)
mmuAddressLUT[vaddr >> 12] = paddr & ~0xfff;
#endif
return paddr;
}

View File

@ -10,52 +10,52 @@ void rtc_init()
// NAOMI reads from at least RTC_R64CNT
//RTC R64CNT 0xFFC80000 0x1FC80000 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_R64CNT_addr,RIO_DATA,8);
sh4_rio_reg(RTC, RTC_R64CNT_addr, RIO_RO);
//RTC RSECCNT H'FFC8 0004 H'1FC8 0004 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RSECCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RSECCNT_addr, 0x7f>();
//RTC RMINCNT H'FFC8 0008 H'1FC8 0008 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RMINCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RMINCNT_addr, 0x7f>();
//RTC RHRCNT H'FFC8 000C H'1FC8 000C 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RHRCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RHRCNT_addr, 0x3f>();
//RTC RWKCNT H'FFC8 0010 H'1FC8 0010 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RWKCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RWKCNT_addr, 0x07>();
//RTC RDAYCNT H'FFC8 0014 H'1FC8 0014 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RDAYCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RDAYCNT_addr, 0x3f>();
//RTC RMONCNT H'FFC8 0018 H'1FC8 0018 8 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RMONCNT_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RMONCNT_addr, 0x1f>();
//RTC RYRCNT H'FFC8 001C H'1FC8 001C 16 Held Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RYRCNT_addr,RIO_DATA,16);
sh4_rio_reg16<RTC, RTC_RYRCNT_addr>();
//RTC RSECAR H'FFC8 0020 H'1FC8 0020 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RSECAR_addr,RIO_DATA,8);
sh4_rio_reg8<RTC, RTC_RSECAR_addr>();
//RTC RMINAR H'FFC8 0024 H'1FC8 0024 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RMINAR_addr,RIO_DATA,8);
sh4_rio_reg8<RTC, RTC_RMINAR_addr>();
//RTC RHRAR H'FFC8 0028 H'1FC8 0028 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RHRAR_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RHRAR_addr, 0xbf>();
//RTC RWKAR H'FFC8 002C H'1FC8 002C 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RWKAR_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RWKAR_addr, 0x87>();
//RTC RDAYAR H'FFC8 0030 H'1FC8 0030 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RDAYAR_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RDAYAR_addr, 0xbf>();
//RTC RMONAR H'FFC8 0034 H'1FC8 0034 8 Held *2 Held Held Held Pclk
sh4_rio_reg(RTC,RTC_RMONAR_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RMONAR_addr, 0x9f>();
//RTC RCR1 H'FFC8 0038 H'1FC8 0038 8 H'00*2 H'00*2 Held Held Pclk
sh4_rio_reg(RTC,RTC_RCR1_addr,RIO_DATA,8);
sh4_rio_reg_wmask<RTC, RTC_RCR1_addr, 0x99>();
//RTC RCR2 H'FFC8 003C H'1FC8 003C 8 H'09*2 H'00*2 Held Held Pclk
sh4_rio_reg(RTC,RTC_RCR2_addr,RIO_DATA,8);
sh4_rio_reg8<RTC, RTC_RCR2_addr>();
}
void rtc_reset()
@ -78,8 +78,8 @@ void rtc_reset()
RTC RCR1 H'FFC8 0038 H'1FC8 0038 8 H'00*2 H'00*2 Held Held Pclk
RTC RCR2 H'FFC8 003C H'1FC8 003C 8 H'09*2 H'00*2 Held Held Pclk
*/
RTC_RCR1=0x00;
RTC_RCR2=0x09;
RTC_RCR1 = 0;
RTC_RCR2 = 9;
}
void rtc_term()

View File

@ -98,7 +98,7 @@ static void WriteSerialStatus(u32 addr,u32 data)
if (!SCIF_SCFSR2.BRK)
data &= ~0x10;
SCIF_SCFSR2.full = data & ~3;
SCIF_SCFSR2.full = data & 0x00f0;
SCIF_SCFSR2.TDFE = 1;
SCIF_SCFSR2.TEND = 1;
@ -134,7 +134,7 @@ static u32 SCSCR2_read(u32 addr)
static void SCSCR2_write(u32 addr, u32 data)
{
SCIF_SCSCR2.full = data;
SCIF_SCSCR2.full = data & 0x00fa;
Serial_UpdateInterrupts();
}
@ -204,46 +204,46 @@ void serial_init()
// Serial Communication Interface with FIFO
//SCIF SCSMR2 0xFFE80000 0x1FE80000 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCSMR2_addr,RIO_DATA,16);
sh4_rio_reg_wmask<SCIF, SCIF_SCSMR2_addr, 0x007b>();
//SCIF SCBRR2 0xFFE80004 0x1FE80004 8 0xFF 0xFF Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCBRR2_addr,RIO_DATA,8);
sh4_rio_reg8<SCIF, SCIF_SCBRR2_addr>();
//SCIF SCSCR2 0xFFE80008 0x1FE80008 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF, SCIF_SCSCR2_addr, RIO_FUNC, 16, &SCSCR2_read, &SCSCR2_write);
sh4_rio_reg(SCIF, SCIF_SCSCR2_addr, RIO_FUNC, SCSCR2_read, SCSCR2_write);
//Write only
//SCIF SCFTDR2 0xFFE8000C 0x1FE8000C 8 Undefined Undefined Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCFTDR2_addr,RIO_WF,8,0,&SerialWrite);
sh4_rio_reg(SCIF, SCIF_SCFTDR2_addr, RIO_WF, nullptr, SerialWrite);
//SCIF SCFSR2 0xFFE80010 0x1FE80010 16 0x0060 0x0060 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCFSR2_addr,RIO_FUNC,16,&ReadSerialStatus,&WriteSerialStatus);
sh4_rio_reg(SCIF, SCIF_SCFSR2_addr, RIO_FUNC, ReadSerialStatus, WriteSerialStatus);
//READ only
//SCIF SCFRDR2 0xFFE80014 0x1FE80014 8 Undefined Undefined Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCFRDR2_addr,RIO_RO_FUNC,8,&ReadSerialData);
sh4_rio_reg(SCIF, SCIF_SCFRDR2_addr, RIO_RO_FUNC, ReadSerialData);
//SCIF SCFCR2 0xFFE80018 0x1FE80018 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCFCR2_addr,RIO_DATA,16);
sh4_rio_reg_wmask<SCIF, SCIF_SCFCR2_addr, 0x00ff>();
//Read only
//SCIF SCFDR2 0xFFE8001C 0x1FE8001C 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCFDR2_addr,RIO_RO_FUNC,16,&Read_SCFDR2);
sh4_rio_reg(SCIF, SCIF_SCFDR2_addr, RIO_RO_FUNC, Read_SCFDR2);
//SCIF SCSPTR2 0xFFE80020 0x1FE80020 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCSPTR2_addr,RIO_DATA,16);
sh4_rio_reg_wmask<SCIF, SCIF_SCSPTR2_addr, 0x00f3>();
//SCIF SCLSR2 0xFFE80024 0x1FE80024 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(SCIF,SCIF_SCLSR2_addr,RIO_DATA,16);
sh4_rio_reg_wmask<SCIF, SCIF_SCLSR2_addr, 1>();
// Serial Communication Interface
sh4_rio_reg(SCI, SCI_SCSMR1_addr, RIO_DATA, 8);
sh4_rio_reg(SCI, SCI_SCBRR1_addr, RIO_DATA, 8);
sh4_rio_reg(SCI, SCI_SCSCR1_addr, RIO_DATA, 8);
sh4_rio_reg(SCI, SCI_SCTDR1_addr, RIO_DATA, 8);
sh4_rio_reg(SCI, SCI_SCSSR1_addr, RIO_DATA, 8);
sh4_rio_reg(SCI, SCI_SCRDR1_addr, RIO_RO, 8);
sh4_rio_reg(SCI, SCI_SCSPTR1_addr, RIO_DATA, 8);
sh4_rio_reg8<SCI, SCI_SCSMR1_addr>();
sh4_rio_reg8<SCI, SCI_SCBRR1_addr>();
sh4_rio_reg8<SCI, SCI_SCSCR1_addr>();
sh4_rio_reg8<SCI, SCI_SCTDR1_addr>();
sh4_rio_reg_wmask<SCI, SCI_SCSSR1_addr, 0xf9>();
sh4_rio_reg(SCI, SCI_SCRDR1_addr, RIO_RO);
sh4_rio_reg_wmask<SCI, SCI_SCSPTR1_addr, 0x8f>();
}
void serial_reset(bool hard)

View File

@ -117,13 +117,13 @@ static void write_TMU_TCNTch(u32 ch, u32 data)
}
template<u32 ch>
u32 read_TMU_TCNT(u32 addr)
static u32 read_TMU_TCNT(u32 addr)
{
return read_TMU_TCNTch(ch);
}
template<u32 ch>
void write_TMU_TCNT(u32 addr, u32 data)
static void write_TMU_TCNT(u32 addr, u32 data)
{
write_TMU_TCNTch(ch,data);
}
@ -188,9 +188,12 @@ static void UpdateTMUCounts(u32 reg)
//Write to status registers
template<int ch>
void TMU_TCR_write(u32 addr, u32 data)
static void TMU_TCR_write(u32 addr, u32 data)
{
TMU_TCR(ch)=(u16)data;
if (ch == 2)
TMU_TCR(ch) = data & 0x03ff;
else
TMU_TCR(ch) = data & 0x013f;
UpdateTMUCounts(ch);
}
@ -208,8 +211,7 @@ static void TMU_TCPR2_write(u32 addr, u32 data)
static void write_TMU_TSTR(u32 addr, u32 data)
{
TMU_TSTR=data;
//?
TMU_TSTR = data & 7;
for (int i = 0; i < 3; i++)
turn_on_off_ch(i, data & (1 << i));
@ -253,45 +255,43 @@ static int sched_tmu_cb(int ch, int sch_cycl, int jitter)
void tmu_init()
{
//TMU TOCR 0xFFD80000 0x1FD80000 8 0x00 0x00 Held Held Pclk
sh4_rio_reg(TMU,TMU_TOCR_addr,RIO_DATA,8);
sh4_rio_reg_wmask<TMU, TMU_TOCR_addr, 1>();
//TMU TSTR 0xFFD80004 0x1FD80004 8 0x00 0x00 Held 0x00 Pclk
sh4_rio_reg(TMU,TMU_TSTR_addr,RIO_WF,8,0,&write_TMU_TSTR);
sh4_rio_reg(TMU, TMU_TSTR_addr, RIO_WF, nullptr, write_TMU_TSTR);
//TMU TCOR0 0xFFD80008 0x1FD80008 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCOR0_addr,RIO_DATA,32);
sh4_rio_reg(TMU, TMU_TCOR0_addr, RIO_DATA);
//TMU TCNT0 0xFFD8000C 0x1FD8000C 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCNT0_addr,RIO_FUNC,32,&read_TMU_TCNT<0>,&write_TMU_TCNT<0>);
sh4_rio_reg(TMU, TMU_TCNT0_addr, RIO_FUNC, read_TMU_TCNT<0>, write_TMU_TCNT<0>);
//TMU TCR0 0xFFD80010 0x1FD80010 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(TMU,TMU_TCR0_addr,RIO_WF,16,0,&TMU_TCR_write<0>);
sh4_rio_reg(TMU, TMU_TCR0_addr, RIO_WF, nullptr, TMU_TCR_write<0>);
//TMU TCOR1 0xFFD80014 0x1FD80014 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCOR1_addr,RIO_DATA,32);
sh4_rio_reg(TMU, TMU_TCOR1_addr, RIO_DATA);
//TMU TCNT1 0xFFD80018 0x1FD80018 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCNT1_addr,RIO_FUNC,32,&read_TMU_TCNT<1>,&write_TMU_TCNT<1>);
sh4_rio_reg(TMU, TMU_TCNT1_addr, RIO_FUNC, read_TMU_TCNT<1>, write_TMU_TCNT<1>);
//TMU TCR1 0xFFD8001C 0x1FD8001C 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(TMU,TMU_TCR1_addr,RIO_WF,16,0,&TMU_TCR_write<1>);
sh4_rio_reg(TMU, TMU_TCR1_addr, RIO_WF, nullptr, TMU_TCR_write<1>);
//TMU TCOR2 0xFFD80020 0x1FD80020 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCOR2_addr,RIO_DATA,32);
sh4_rio_reg(TMU, TMU_TCOR2_addr, RIO_DATA);
//TMU TCNT2 0xFFD80024 0x1FD80024 32 0xFFFFFFFF 0xFFFFFFFF Held Held Pclk
sh4_rio_reg(TMU,TMU_TCNT2_addr,RIO_FUNC,32,&read_TMU_TCNT<2>,&write_TMU_TCNT<2>);
sh4_rio_reg(TMU, TMU_TCNT2_addr, RIO_FUNC, read_TMU_TCNT<2>, write_TMU_TCNT<2>);
//TMU TCR2 0xFFD80028 0x1FD80028 16 0x0000 0x0000 Held Held Pclk
sh4_rio_reg(TMU,TMU_TCR2_addr,RIO_WF,16,0,&TMU_TCR_write<2>);
sh4_rio_reg(TMU, TMU_TCR2_addr, RIO_WF, nullptr, TMU_TCR_write<2>);
//TMU TCPR2 0xFFD8002C 0x1FD8002C 32 Held Held Held Held Pclk
sh4_rio_reg(TMU,TMU_TCPR2_addr,RIO_FUNC,32,&TMU_TCPR2_read,&TMU_TCPR2_write);
sh4_rio_reg(TMU, TMU_TCPR2_addr, RIO_FUNC, &TMU_TCPR2_read, &TMU_TCPR2_write);
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 3; i++)
tmu_sched[i] = sh4_sched_register(i, &sched_tmu_cb);
sh4_sched_request(tmu_sched[i], -1);
}
}

View File

@ -3,37 +3,37 @@
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
//Init term res
void ubc_init()
{
//UBC BARA 0xFF200000 0x1F200000 32 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BARA_addr,RIO_DATA,32);
sh4_rio_reg(UBC, UBC_BARA_addr, RIO_DATA);
//UBC BAMRA 0xFF200004 0x1F200004 8 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BAMRA_addr,RIO_DATA,8);
sh4_rio_reg_wmask<UBC, UBC_BAMRA_addr, 0x0f>();
//UBC BBRA 0xFF200008 0x1F200008 16 0x0000 Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BBRA_addr,RIO_DATA,16);
sh4_rio_reg_wmask<UBC, UBC_BBRA_addr, 0x007f>();
//UBC BARB 0xFF20000C 0x1F20000C 32 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BARB_addr,RIO_DATA,32);
sh4_rio_reg(UBC, UBC_BARB_addr, RIO_DATA);
//UBC BAMRB 0xFF200010 0x1F200010 8 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BAMRB_addr,RIO_DATA,8);
sh4_rio_reg_wmask<UBC, UBC_BAMRB_addr, 0x0f>();
//UBC BBRB 0xFF200014 0x1F200014 16 0x0000 Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BBRB_addr,RIO_DATA,16);
sh4_rio_reg_wmask<UBC, UBC_BBRB_addr, 0x007f>();
//UBC BDRB 0xFF200018 0x1F200018 32 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BDRB_addr,RIO_DATA,32);
sh4_rio_reg(UBC, UBC_BDRB_addr, RIO_DATA);
//UBC BDMRB 0xFF20001C 0x1F20001C 32 Undefined Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BDMRB_addr,RIO_DATA,32);
sh4_rio_reg(UBC, UBC_BDMRB_addr, RIO_DATA);
//UBC BRCR 0xFF200020 0x1F200020 16 0x0000 Held Held Held Iclk
sh4_rio_reg(UBC,UBC_BRCR_addr,RIO_DATA,16);
sh4_rio_reg_wmask<UBC, UBC_BRCR_addr, 0xc4c9>();
}
void ubc_reset()
{
/*

View File

@ -17,149 +17,239 @@ std::array<u8, OnChipRAM_SIZE> OnChipRAM;
//All registers are 4 byte aligned
std::array<RegisterStruct, 18> CCN;
std::array<RegisterStruct, 9> UBC;
std::array<RegisterStruct, 19> BSC;
std::array<RegisterStruct, 17> DMAC;
std::array<RegisterStruct, 5> CPG;
std::array<RegisterStruct, 16> RTC;
std::array<RegisterStruct, 5> INTC;
std::array<RegisterStruct, 12> TMU;
std::array<RegisterStruct, 8> SCI;
std::array<RegisterStruct, 10> SCIF;
RegisterStruct CCN[18];
RegisterStruct UBC[9];
RegisterStruct BSC[19];
RegisterStruct DMAC[17];
RegisterStruct CPG[5];
RegisterStruct RTC[16];
RegisterStruct INTC[5];
RegisterStruct TMU[12];
RegisterStruct SCI[8];
RegisterStruct SCIF[10];
static u32 sh4io_read_noacc(u32 addr)
{
INFO_LOG(SH4, "sh4io: Invalid read access @@ %08X", addr);
INFO_LOG(SH4, "sh4io: Invalid read access @ %08X", addr);
return 0;
}
static void sh4io_write_noacc(u32 addr, u32 data)
{
INFO_LOG(SH4, "sh4io: Invalid write access @@ %08X %08X", addr, data);
INFO_LOG(SH4, "sh4io: Invalid write access @ %08X %08X", addr, data);
}
static void sh4io_write_const(u32 addr, u32 data)
{
INFO_LOG(SH4, "sh4io: Const write ignored @@ %08X <- %08X", addr, data);
INFO_LOG(SH4, "sh4io: Const write ignored @ %08X <- %08X", addr, data);
}
template<class T>
void sh4_rio_reg(T& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf)
void sh4_rio_reg(RegisterStruct *arr, u32 addr, RegIO flags, RegReadAddrFP* rf, RegWriteAddrFP* wf)
{
u32 idx = (addr & 255) / 4;
verify(idx < arr.size());
arr[idx].flags = flags;
if (flags == RIO_NO_ACCESS)
{
arr[idx].readFunctionAddr=&sh4io_read_noacc;
arr[idx].writeFunctionAddr=&sh4io_write_noacc;
arr[idx].readFunctionAddr = sh4io_read_noacc;
arr[idx].writeFunctionAddr = sh4io_write_noacc;
}
else if (flags == RIO_CONST)
else if (flags == RIO_RO)
{
arr[idx].writeFunctionAddr=&sh4io_write_const;
arr[idx].writeFunctionAddr = sh4io_write_const;
arr[idx].data32 = 0;
}
else
{
arr[idx].data32=0;
if (flags & REG_RF)
arr[idx].readFunctionAddr = rf;
else
arr[idx].data32 = 0;
if (flags & REG_WF)
arr[idx].writeFunctionAddr=wf==0?&sh4io_write_noacc:wf;
arr[idx].writeFunctionAddr = wf == nullptr ? &sh4io_write_noacc : wf;
}
}
template void sh4_rio_reg(std::array<RegisterStruct, 5>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 8>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 9>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 10>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 12>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 16>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 17>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 18>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template void sh4_rio_reg(std::array<RegisterStruct, 19>& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf);
template<u32 sz, class T>
u32 sh4_rio_read(T& regs, u32 addr)
template<typename T>
T sh4_rio_read(RegisterStruct *regs, u32 addr)
{
u32 offset = addr & 255;
#ifdef TRACE
if (offset & 3/*(size-1)*/) //4 is min align size
if (offset & 3) //4 is min align size
{
INFO_LOG(SH4, "Unaligned System Bus register read");
WARN_LOG(SH4, "Unaligned System Bus register read @ %x", addr);
}
#endif
offset >>= 2;
#ifdef TRACE
if (regs[offset].flags & sz)
{
#endif
if (!(regs[offset].flags & REG_RF))
{
if (sz==4)
return regs[offset].data32;
else if (sz==2)
return regs[offset].data16;
return (T)regs[offset].data32;
else
return regs[offset].data8;
}
else
{
return regs[offset].readFunctionAddr(addr);
}
#ifdef TRACE
}
else
{
INFO_LOG(SH4, "ERROR [wrong size read on register]");
}
#endif
return 0;
return (T)regs[offset].readFunctionAddr(addr);
}
template<u32 sz, class T>
void sh4_rio_write(T& regs, u32 addr, u32 data)
template<typename T>
void sh4_rio_write(RegisterStruct *regs, u32 addr, T data)
{
u32 offset = addr & 255;
#ifdef TRACE
if (offset & 3/*(size-1)*/) //4 is min align size
if (offset & 3) //4 is min align size
{
INFO_LOG(SH4, "Unaligned System bus register write");
WARN_LOG(SH4, "Unaligned System bus register write @ %x", addr);
}
#endif
offset >>= 2;
#ifdef TRACE
if (regs[offset].flags & sz)
{
#endif
if (!(regs[offset].flags & REG_WF) )
{
if (sz==4)
regs[offset].data32=data;
else if (sz==2)
regs[offset].data16=(u16)data;
else
regs[offset].data8=(u8)data;
return;
}
else
{
//printf("RSW: %08X\n",addr);
regs[offset].writeFunctionAddr(addr,data);
return;
}
#ifdef TRACE
}
else
{
INFO_LOG(SH4, "ERROR: Wrong size write on register - offset=%x, data=%x, size=%d",offset,data,sz);
}
#endif
if (!(regs[offset].flags & REG_WF))
regs[offset].data32 = data;
else
regs[offset].writeFunctionAddr(addr, data);
}
#define SH4_REG_NAME(r) { r##_addr, #r },
const std::map<u32, const char *> sh4_reg_names = {
SH4_REG_NAME(CCN_PTEH)
SH4_REG_NAME(CCN_PTEL)
SH4_REG_NAME(CCN_TTB)
SH4_REG_NAME(CCN_TEA)
SH4_REG_NAME(CCN_CCR)
SH4_REG_NAME(CCN_TRA)
SH4_REG_NAME(CCN_EXPEVT)
SH4_REG_NAME(CCN_INTEVT)
SH4_REG_NAME(CPU_VERSION)
SH4_REG_NAME(CCN_PTEA)
SH4_REG_NAME(CCN_QACR0)
SH4_REG_NAME(CCN_QACR1)
SH4_REG_NAME(CCN_PRR)
SH4_REG_NAME(UBC_BARA)
SH4_REG_NAME(UBC_BAMRA)
SH4_REG_NAME(UBC_BBRA)
SH4_REG_NAME(UBC_BARB)
SH4_REG_NAME(UBC_BAMRB)
SH4_REG_NAME(UBC_BBRB)
SH4_REG_NAME(UBC_BDRB)
SH4_REG_NAME(UBC_BDMRB)
SH4_REG_NAME(UBC_BRCR)
SH4_REG_NAME(BSC_BCR1)
SH4_REG_NAME(BSC_BCR2)
SH4_REG_NAME(BSC_WCR1)
SH4_REG_NAME(BSC_WCR2)
SH4_REG_NAME(BSC_WCR3)
SH4_REG_NAME(BSC_MCR)
SH4_REG_NAME(BSC_PCR)
SH4_REG_NAME(BSC_RTCSR)
SH4_REG_NAME(BSC_RTCNT)
SH4_REG_NAME(BSC_RTCOR)
SH4_REG_NAME(BSC_RFCR)
SH4_REG_NAME(BSC_PCTRA)
SH4_REG_NAME(BSC_PDTRA)
SH4_REG_NAME(BSC_PCTRB)
SH4_REG_NAME(BSC_PDTRB)
SH4_REG_NAME(BSC_GPIOIC)
SH4_REG_NAME(BSC_SDMR2)
SH4_REG_NAME(BSC_SDMR3)
SH4_REG_NAME(DMAC_SAR0)
SH4_REG_NAME(DMAC_DAR0)
SH4_REG_NAME(DMAC_DMATCR0)
SH4_REG_NAME(DMAC_CHCR0)
SH4_REG_NAME(DMAC_SAR1)
SH4_REG_NAME(DMAC_DAR1)
SH4_REG_NAME(DMAC_DMATCR1)
SH4_REG_NAME(DMAC_CHCR1)
SH4_REG_NAME(DMAC_SAR2)
SH4_REG_NAME(DMAC_DAR2)
SH4_REG_NAME(DMAC_DMATCR2)
SH4_REG_NAME(DMAC_CHCR2)
SH4_REG_NAME(DMAC_SAR3)
SH4_REG_NAME(DMAC_DAR3)
SH4_REG_NAME(DMAC_DMATCR3)
SH4_REG_NAME(DMAC_CHCR3)
SH4_REG_NAME(DMAC_DMAOR)
SH4_REG_NAME(CPG_FRQCR)
SH4_REG_NAME(CPG_STBCR)
SH4_REG_NAME(CPG_WTCNT)
SH4_REG_NAME(CPG_WTCSR)
SH4_REG_NAME(CPG_STBCR2)
SH4_REG_NAME(RTC_R64CNT)
SH4_REG_NAME(RTC_RSECCNT)
SH4_REG_NAME(RTC_RMINCNT)
SH4_REG_NAME(RTC_RHRCNT)
SH4_REG_NAME(RTC_RWKCNT)
SH4_REG_NAME(RTC_RDAYCNT)
SH4_REG_NAME(RTC_RMONCNT)
SH4_REG_NAME(RTC_RYRCNT)
SH4_REG_NAME(RTC_RSECAR)
SH4_REG_NAME(RTC_RMINAR)
SH4_REG_NAME(RTC_RHRAR)
SH4_REG_NAME(RTC_RWKAR)
SH4_REG_NAME(RTC_RDAYAR)
SH4_REG_NAME(RTC_RMONAR)
SH4_REG_NAME(RTC_RCR1)
SH4_REG_NAME(RTC_RCR2)
SH4_REG_NAME(INTC_ICR)
SH4_REG_NAME(INTC_IPRA)
SH4_REG_NAME(INTC_IPRB)
SH4_REG_NAME(INTC_IPRC)
SH4_REG_NAME(INTC_IPRD)
SH4_REG_NAME(TMU_TOCR)
SH4_REG_NAME(TMU_TSTR)
SH4_REG_NAME(TMU_TCOR0)
SH4_REG_NAME(TMU_TCNT0)
SH4_REG_NAME(TMU_TCR0)
SH4_REG_NAME(TMU_TCOR1)
SH4_REG_NAME(TMU_TCNT1)
SH4_REG_NAME(TMU_TCR1)
SH4_REG_NAME(TMU_TCOR2)
SH4_REG_NAME(TMU_TCNT2)
SH4_REG_NAME(TMU_TCR2)
SH4_REG_NAME(TMU_TCPR2)
SH4_REG_NAME(SCI_SCSMR1)
SH4_REG_NAME(SCI_SCBRR1)
SH4_REG_NAME(SCI_SCSCR1)
SH4_REG_NAME(SCI_SCTDR1)
SH4_REG_NAME(SCI_SCSSR1)
SH4_REG_NAME(SCI_SCRDR1)
SH4_REG_NAME(SCI_SCSCMR1)
SH4_REG_NAME(SCI_SCSPTR1)
SH4_REG_NAME(SCIF_SCSMR2)
SH4_REG_NAME(SCIF_SCBRR2)
SH4_REG_NAME(SCIF_SCSCR2)
SH4_REG_NAME(SCIF_SCFTDR2)
SH4_REG_NAME(SCIF_SCFSR2)
SH4_REG_NAME(SCIF_SCFRDR2)
SH4_REG_NAME(SCIF_SCFCR2)
SH4_REG_NAME(SCIF_SCFDR2)
SH4_REG_NAME(SCIF_SCSPTR2)
SH4_REG_NAME(SCIF_SCLSR2)
SH4_REG_NAME(UDI_SDIR)
SH4_REG_NAME(UDI_SDDR)
};
#undef SH4_REG_NAME
static const char *regName(u32 paddr)
{
u32 addr = paddr & 0x1fffffff;
static char regName[32];
auto it = sh4_reg_names.find(addr);
if (it == sh4_reg_names.end()) {
sprintf(regName, "?%08x", paddr);
return regName;
}
else
return it->second;
}
//Region P4
@ -253,7 +343,6 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
constexpr size_t sz = sizeof(T);
switch ((addr >> 24) & 0xFF)
{
case 0xE0:
case 0xE1:
case 0xE2:
@ -279,24 +368,19 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
ITLB[entry].Address.reg_data = data & 0xFFFFFCFF;
ITLB[entry].Data.V = (data >> 8) & 1;
ITLB_Sync(entry);
return;
}
return;
case 0xF3:
{
u32 entry = (addr >> 8) & 3;
if (addr & 0x800000)
{
ITLB[entry].Assistance.reg_data = data & 0xf;
}
else
{
ITLB[entry].Data.reg_data=data;
}
ITLB_Sync(entry);
return;
}
return;
case 0xF4:
// DEBUG_LOG(SH4, "OC Address write %08x = %x", addr, data);
@ -311,7 +395,6 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
return;
case 0xF6:
{
if (addr & 0x80)
{
CCN_PTEH_type t;
@ -348,24 +431,17 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
UTLB_Sync(entry);
}
return;
}
break;
case 0xF7:
{
u32 entry = (addr >> 8) & 63;
if (addr & 0x800000)
{
UTLB[entry].Assistance.reg_data = data & 0xf;
}
else
{
UTLB[entry].Data.reg_data = data;
}
UTLB_Sync(entry);
return;
}
return;
case 0xFF:
INFO_LOG(SH4, "Unhandled p4 Write [area7] 0x%x = %x", addr, data);
@ -388,24 +464,18 @@ void DYNACALL WriteMem_P4(u32 addr,T data)
template <class T>
T DYNACALL ReadMem_p4mmr(u32 addr)
{
constexpr size_t sz = sizeof(T);
DEBUG_LOG(SH4, "read %s", regName(addr));
/*
if (likely(addr == 0xffd80024))
{
return TMU_TCNT(2);
}
else if (likely(addr==0xFFD8000C))
{
if (likely(addr == 0xFFD8000C))
return TMU_TCNT(0);
}
else */if (likely(addr==0xFF000028))
{
return CCN_INTEVT;
}
else if (likely(addr==0xFFA0002C))
{
return DMAC_CHCR(2).full;
}
*/
if (likely(addr == 0xFF000028))
return (T)CCN_INTEVT;
if (likely(addr == 0xFFA0002C))
return (T)DMAC_CHCR(2).full;
addr &= 0x1FFFFFFF;
u32 map_base = addr >> 16;
@ -414,7 +484,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(CCN_BASE_addr):
if (addr <= 0x1F000044)
{
return (T)sh4_rio_read<sz>(CCN, addr);
return sh4_rio_read<T>(CCN, addr);
}
else
{
@ -426,7 +496,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(UBC_BASE_addr):
if (addr <= 0x1F200020)
{
return (T)sh4_rio_read<sz>(UBC, addr);
return sh4_rio_read<T>(UBC, addr);
}
else
{
@ -438,7 +508,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(BSC_BASE_addr):
if (addr <= 0x1F800048)
{
return (T)sh4_rio_read<sz>(BSC, addr);
return sh4_rio_read<T>(BSC, addr);
}
else
{
@ -459,7 +529,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(DMAC_BASE_addr):
if (addr <= 0x1FA00040)
{
return (T)sh4_rio_read<sz>(DMAC, addr);
return sh4_rio_read<T>(DMAC, addr);
}
else
{
@ -471,7 +541,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(CPG_BASE_addr):
if (addr <= 0x1FC00010)
{
return (T)sh4_rio_read<sz>(CPG, addr);
return sh4_rio_read<T>(CPG, addr);
}
else
{
@ -483,7 +553,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(RTC_BASE_addr):
if (addr <= 0x1FC8003C)
{
return (T)sh4_rio_read<sz>(RTC, addr);
return sh4_rio_read<T>(RTC, addr);
}
else
{
@ -495,7 +565,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(INTC_BASE_addr):
if (addr <= 0x1FD00010)
{
return (T)sh4_rio_read<sz>(INTC, addr);
return sh4_rio_read<T>(INTC, addr);
}
else
{
@ -507,7 +577,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(TMU_BASE_addr):
if (addr <= 0x1FD8002C)
{
return (T)sh4_rio_read<sz>(TMU, addr);
return sh4_rio_read<T>(TMU, addr);
}
else
{
@ -519,7 +589,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(SCI_BASE_addr):
if (addr <= 0x1FE0001C)
{
return (T)sh4_rio_read<sz>(SCI, addr);
return sh4_rio_read<T>(SCI, addr);
}
else
{
@ -531,7 +601,7 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
case A7_REG_HASH(SCIF_BASE_addr):
if (addr <= 0x1FE80024)
{
return (T)sh4_rio_read<sz>(SCIF, addr);
return sh4_rio_read<T>(SCIF, addr);
}
else
{
@ -564,13 +634,14 @@ T DYNACALL ReadMem_p4mmr(u32 addr)
template <class T>
void DYNACALL WriteMem_p4mmr(u32 addr, T data)
{
constexpr size_t sz = sizeof(T);
DEBUG_LOG(SH4, "write %s = %x", regName(addr), (int)data);
if (likely(addr == 0xFF000038))
{
CCN_QACR_write<0>(addr, data);
return;
}
else if (likely(addr==0xFF00003C))
if (likely(addr == 0xFF00003C))
{
CCN_QACR_write<1>(addr, data);
return;
@ -583,35 +654,23 @@ void DYNACALL WriteMem_p4mmr(u32 addr,T data)
case A7_REG_HASH(CCN_BASE_addr):
if (addr <= 0x1F00003C)
{
sh4_rio_write<sz>(CCN, addr, data);
}
sh4_rio_write(CCN, addr, data);
else
{
OUT_OF_RANGE("CCN");
}
return;
case A7_REG_HASH(UBC_BASE_addr):
if (addr <= 0x1F200020)
{
sh4_rio_write<sz>(UBC, addr, data);
}
sh4_rio_write(UBC, addr, data);
else
{
OUT_OF_RANGE("UBC");
}
return;
case A7_REG_HASH(BSC_BASE_addr):
if (addr <= 0x1F800048)
{
sh4_rio_write<sz>(BSC, addr, data);
}
sh4_rio_write(BSC, addr, data);
else
{
OUT_OF_RANGE("BSC");
}
return;
case A7_REG_HASH(BSC_SDMR2_addr):
//dram settings 2 / write only
@ -623,79 +682,51 @@ void DYNACALL WriteMem_p4mmr(u32 addr,T data)
case A7_REG_HASH(DMAC_BASE_addr):
if (addr <= 0x1FA00040)
{
sh4_rio_write<sz>(DMAC, addr, data);
}
sh4_rio_write(DMAC, addr, data);
else
{
OUT_OF_RANGE("DMAC");
}
return;
case A7_REG_HASH(CPG_BASE_addr):
if (addr <= 0x1FC00010)
{
sh4_rio_write<sz>(CPG, addr, data);
}
sh4_rio_write(CPG, addr, data);
else
{
OUT_OF_RANGE("CPG");
}
return;
case A7_REG_HASH(RTC_BASE_addr):
if (addr <= 0x1FC8003C)
{
sh4_rio_write<sz>(RTC, addr, data);
}
sh4_rio_write(RTC, addr, data);
else
{
OUT_OF_RANGE("RTC");
}
return;
case A7_REG_HASH(INTC_BASE_addr):
if (addr<=0x1FD0000C)
{
sh4_rio_write<sz>(INTC, addr, data);
}
if (addr <= 0x1FD00010)
sh4_rio_write(INTC, addr, data);
else
{
OUT_OF_RANGE("INTC");
}
return;
case A7_REG_HASH(TMU_BASE_addr):
if (addr <= 0x1FD8002C)
{
sh4_rio_write<sz>(TMU, addr, data);
}
sh4_rio_write(TMU, addr, data);
else
{
OUT_OF_RANGE("TMU");
}
return;
case A7_REG_HASH(SCI_BASE_addr):
if (addr <= 0x1FE0001C)
{
sh4_rio_write<sz>(SCI, addr, data);
}
sh4_rio_write(SCI, addr, data);
else
{
OUT_OF_RANGE("SCI");
}
return;
case A7_REG_HASH(SCIF_BASE_addr):
if (addr <= 0x1FE80024)
{
sh4_rio_write<sz>(SCIF, addr, data);
}
sh4_rio_write(SCIF, addr, data);
else
{
OUT_OF_RANGE("SCIF");
}
return;
//who really cares about ht-udi ? it's not existent on dc iirc ..

View File

@ -1,5 +1,4 @@
#pragma once
#include <array>
#include "types.h"
#include "sh4_if.h"
#include "hw/hwreg.h"
@ -14,23 +13,22 @@ void map_p4();
#define sq_both (sh4rcb.sq_buffer)
extern std::array<RegisterStruct, 18> CCN;
extern std::array<RegisterStruct, 9> UBC;
extern std::array<RegisterStruct, 19> BSC;
extern std::array<RegisterStruct, 17> DMAC;
extern std::array<RegisterStruct, 5> CPG;
extern std::array<RegisterStruct, 16> RTC;
extern std::array<RegisterStruct, 5> INTC;
extern std::array<RegisterStruct, 12> TMU;
extern std::array<RegisterStruct, 8> SCI;
extern std::array<RegisterStruct, 10> SCIF;
extern RegisterStruct CCN[18];
extern RegisterStruct UBC[9];
extern RegisterStruct BSC[19];
extern RegisterStruct DMAC[17];
extern RegisterStruct CPG[5];
extern RegisterStruct RTC[16];
extern RegisterStruct INTC[5];
extern RegisterStruct TMU[12];
extern RegisterStruct SCI[8];
extern RegisterStruct SCIF[10];
void sh4_mmr_init();
void sh4_mmr_reset(bool hard);
void sh4_mmr_term();
template<typename T>
void sh4_rio_reg(T& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf=0, RegWriteAddrFP* wf=0);
void sh4_rio_reg(RegisterStruct *arr, u32 addr, RegIO flags, RegReadAddrFP *rf = nullptr, RegWriteAddrFP *wf = nullptr);
#define SH4IO_REGN(mod, addr, size) ((mod)[((addr) & 255) / 4].data##size)
#define SH4IO_REG(mod, name, size) SH4IO_REGN(mod, mod##_##name##_addr, size)
@ -39,6 +37,30 @@ void sh4_rio_reg(T& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf=0, Reg
#define SH4IO_REG_OFS(mod, name, o, s, size) SH4IO_REGN(mod, mod##_##name##0_addr + (o) * (s), size)
#define SH4IO_REG_T_OFS(mod, name, o, s, size) ((mod##_##name##_type&)SH4IO_REG_OFS(mod, name, o, s, size))
template <RegisterStruct *Module, u32 Addr, u32 Mask = 0xffffffff, u32 OrMask = 0>
void sh4_write_reg(u32 addr, u32 data)
{
SH4IO_REGN(Module, Addr, 32) = (data & Mask) | OrMask;
}
template<RegisterStruct *Module, u32 Addr, u32 Mask>
void sh4_rio_reg_wmask()
{
sh4_rio_reg(Module, Addr, RIO_WF, nullptr, sh4_write_reg<Module, Addr, Mask>);
};
template<RegisterStruct *Module, u32 Addr>
void sh4_rio_reg16()
{
sh4_rio_reg_wmask<Module, Addr, 0xffff>();
};
template<RegisterStruct *Module, u32 Addr>
void sh4_rio_reg8()
{
sh4_rio_reg_wmask<Module, Addr, 0xff>();
};
//CCN module registers base
#define CCN_BASE_addr 0x1F000000

View File

@ -164,7 +164,6 @@ void sh4_sched_tick(int cycles)
for (sched_list& sched : sch_list)
{
int remaining = sh4_sched_remaining(sched, fztime);
verify(remaining >= 0 || remaining == -1);
if (remaining >= 0 && remaining <= (int)cycles)
handle_cb(sched);
}