mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
161 lines
3.5 KiB
C++
161 lines
3.5 KiB
C++
#include "mem.h"
|
|
#include "arm7.h"
|
|
|
|
u8 *arm_aica_ram;
|
|
//Set to true when aica interrupt is pending
|
|
bool aica_interr=false;
|
|
u32 aica_reg_L=0;
|
|
//Set to true when the out of the intc is 1
|
|
bool e68k_out = false;
|
|
u32 e68k_reg_L;
|
|
u32 e68k_reg_M=0; //constant ?
|
|
|
|
void update_e68k()
|
|
{
|
|
if (!e68k_out && aica_interr)
|
|
{
|
|
//Set the pending signal
|
|
//Is L register holded here too ?
|
|
e68k_out=1;
|
|
e68k_reg_L=aica_reg_L;
|
|
}
|
|
}
|
|
|
|
void FASTCALL ArmInterruptChange(u32 bits,u32 L)
|
|
{
|
|
aica_interr=bits!=0;
|
|
if (aica_interr)
|
|
aica_reg_L=L;
|
|
update_e68k();
|
|
}
|
|
|
|
void e68k_AcceptInterrupt()
|
|
{
|
|
e68k_out=false;
|
|
update_e68k();
|
|
}
|
|
|
|
//Reg reads from arm side ..
|
|
template <u32 sz,class T>
|
|
inline T fastcall arm_ReadReg(u32 addr)
|
|
{
|
|
addr&=0x7FFF;
|
|
if (addr==REG_L)
|
|
return e68k_reg_L;
|
|
else if(addr==REG_M)
|
|
return e68k_reg_M; //shoudn't really happen
|
|
else
|
|
return arm_params.ReadMem_aica_reg(addr,sz);
|
|
}
|
|
template <u32 sz,class T>
|
|
inline void fastcall arm_WriteReg(u32 addr,T data)
|
|
{
|
|
addr&=0x7FFF;
|
|
if (addr==REG_L)
|
|
return; //shoudn't really happen (read only)
|
|
else if(addr==REG_M)
|
|
{
|
|
//accept interrupts
|
|
if (data&1)
|
|
e68k_AcceptInterrupt();
|
|
}
|
|
else
|
|
return arm_params.WriteMem_aica_reg(addr,data,sz);
|
|
}
|
|
//Map using _vmem .. yay
|
|
void arm_init_mem()
|
|
{
|
|
arm_aica_ram=arm_params.aica_ram;
|
|
}
|
|
//kill mem map & free used mem ;)
|
|
void arm_term_mem()
|
|
{
|
|
|
|
}
|
|
|
|
//00000000~007FFFFF @DRAM_AREA*
|
|
//00800000~008027FF @CHANNEL_DATA
|
|
//00802800~00802FFF @COMMON_DATA
|
|
//00803000~00807FFF @DSP_DATA
|
|
|
|
template<int sz,typename T>
|
|
T fastcall ReadMemArm(u32 addr)
|
|
{
|
|
// printf("ReadMemArm %08x\n",addr);
|
|
addr&=0x00FFFFFF;
|
|
if (addr<0x800000)
|
|
{
|
|
if (addr&(sz-1)){
|
|
//printf("ARM unal rd %d %08x\n",sz,addr);
|
|
switch (sz)
|
|
{
|
|
case 4:
|
|
u8 t[4];
|
|
int i;
|
|
for(i=0;i<4;++i)
|
|
t[i]=arm_aica_ram[((addr+i)^3)&ARAM_MASK];
|
|
|
|
return t[3]<<24 | t[2]<<16 | t[1]<<8 |t[0];
|
|
break;
|
|
default:
|
|
dbgbreak;
|
|
}
|
|
}
|
|
if (sz==1)
|
|
addr^=3;
|
|
else if (sz==2)
|
|
addr^=2;
|
|
|
|
return *(T*)&arm_aica_ram[addr&ARAM_MASK];
|
|
}
|
|
else
|
|
{
|
|
return arm_ReadReg<sz,T>(addr);
|
|
}
|
|
}
|
|
|
|
template<int sz,typename T>
|
|
void fastcall WriteMemArm(u32 addr,T data)
|
|
{
|
|
// printf("WriteMemArm %08x %08x\n",addr,data);
|
|
addr&=0x00FFFFFF;
|
|
if (addr<0x800000)
|
|
{
|
|
if (addr&(sz-1)){
|
|
//printf("ARM unal wr %d %08x\n",sz,addr);
|
|
switch (sz)
|
|
{
|
|
case 4:
|
|
u8 t[4];
|
|
t[3]=data>>24; t[2]=data>>16; t[1]=data>>8; t[0]=data;
|
|
|
|
int i;
|
|
for(i=0;i<4;++i)
|
|
arm_aica_ram[((addr+i)^3)&ARAM_MASK]=t[i];
|
|
break;
|
|
default:
|
|
dbgbreak;
|
|
}
|
|
return;
|
|
}
|
|
if (sz==1)
|
|
addr^=3;
|
|
else if (sz==2)
|
|
addr^=2;
|
|
|
|
*(T*)&arm_aica_ram[addr&ARAM_MASK]=data;
|
|
}
|
|
else
|
|
{
|
|
arm_WriteReg<sz,T>(addr,data);
|
|
}
|
|
}
|
|
|
|
template u8 ReadMemArm<1,u8>(u32 adr);
|
|
template u16 ReadMemArm<2,u16>(u32 adr);
|
|
template u32 ReadMemArm<4,u32>(u32 adr);
|
|
|
|
template void WriteMemArm<1>(u32 adr,u8 data);
|
|
template void WriteMemArm<2>(u32 adr,u16 data);
|
|
template void WriteMemArm<4>(u32 adr,u32 data);
|
|
|