diff --git a/ARMInterpreter_LoadStore.cpp b/ARMInterpreter_LoadStore.cpp index 583f175d..4a78186c 100644 --- a/ARMInterpreter_LoadStore.cpp +++ b/ARMInterpreter_LoadStore.cpp @@ -477,6 +477,39 @@ s32 T_LDRB_REG(ARM* cpu) } +s32 T_STRH_REG(ARM* cpu) +{ + u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; + cpu->Write16(addr, cpu->R[cpu->CurInstr & 0x7]); + + return C_N(2) + cpu->MemWaitstate(2, addr); +} + +s32 T_LDRSB_REG(ARM* cpu) +{ + u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; + cpu->R[cpu->CurInstr & 0x7] = (s32)(s8)cpu->Read8(addr); + + return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr); +} + +s32 T_LDRH_REG(ARM* cpu) +{ + u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; + cpu->R[cpu->CurInstr & 0x7] = cpu->Read16(addr); + + return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, addr); +} + +s32 T_LDRSH_REG(ARM* cpu) +{ + u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7]; + cpu->R[cpu->CurInstr & 0x7] = (s32)(s16)cpu->Read16(addr); + + return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(2, addr); +} + + s32 T_STR_IMM(ARM* cpu) { u32 offset = (cpu->CurInstr >> 4) & 0x7C; @@ -620,6 +653,48 @@ s32 T_POP(ARM* cpu) return cycles; } +s32 T_STMIA(ARM* cpu) +{ + u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; + + int cycles = C_N(2); + + for (int i = 0; i < 8; i++) + { + if (cpu->CurInstr & (1<Write32(base, cpu->R[i]); + cycles += C_S(1) + cpu->MemWaitstate(3, base); + base += 4; + } + } + + cpu->R[(cpu->CurInstr >> 8) & 0x7] = base; + + return cycles - C_S(1); +} + +s32 T_LDMIA(ARM* cpu) +{ + u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; + + int cycles = C_N(1) + C_I(1); + + for (int i = 0; i < 8; i++) + { + if (cpu->CurInstr & (1<R[i] = cpu->Read32(base); + cycles += C_S(1) + cpu->MemWaitstate(3, base); + base += 4; + } + } + + cpu->R[(cpu->CurInstr >> 8) & 0x7] = base; + + return cycles; +} + } diff --git a/ARMInterpreter_LoadStore.h b/ARMInterpreter_LoadStore.h index 61b1a39f..4759d1f5 100644 --- a/ARMInterpreter_LoadStore.h +++ b/ARMInterpreter_LoadStore.h @@ -48,6 +48,11 @@ s32 T_STRB_REG(ARM* cpu); s32 T_LDR_REG(ARM* cpu); s32 T_LDRB_REG(ARM* cpu); +s32 T_STRH_REG(ARM* cpu); +s32 T_LDRSB_REG(ARM* cpu); +s32 T_LDRH_REG(ARM* cpu); +s32 T_LDRSH_REG(ARM* cpu); + s32 T_STR_IMM(ARM* cpu); s32 T_LDR_IMM(ARM* cpu); s32 T_STRB_IMM(ARM* cpu); @@ -61,6 +66,8 @@ s32 T_LDR_SPREL(ARM* cpu); s32 T_PUSH(ARM* cpu); s32 T_POP(ARM* cpu); +s32 T_STMIA(ARM* cpu); +s32 T_LDMIA(ARM* cpu); } diff --git a/ARM_InstrTable.h b/ARM_InstrTable.h index 78dd18c2..03f7c3a7 100644 --- a/ARM_InstrTable.h +++ b/ARM_InstrTable.h @@ -1695,26 +1695,26 @@ INSTRFUNC_PROTO(THUMBInstrTable[1024]) = // 0101 0000 00 T_STR_REG, T_STR_REG, T_STR_REG, T_STR_REG, T_STR_REG, T_STR_REG, T_STR_REG, T_STR_REG, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_STRH_REG, T_STRH_REG, T_STRH_REG, T_STRH_REG, + T_STRH_REG, T_STRH_REG, T_STRH_REG, T_STRH_REG, // 0101 0100 00 T_STRB_REG, T_STRB_REG, T_STRB_REG, T_STRB_REG, T_STRB_REG, T_STRB_REG, T_STRB_REG, T_STRB_REG, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_LDRSB_REG, T_LDRSB_REG, T_LDRSB_REG, T_LDRSB_REG, + T_LDRSB_REG, T_LDRSB_REG, T_LDRSB_REG, T_LDRSB_REG, // 0101 1000 00 T_LDR_REG, T_LDR_REG, T_LDR_REG, T_LDR_REG, T_LDR_REG, T_LDR_REG, T_LDR_REG, T_LDR_REG, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_LDRH_REG, T_LDRH_REG, T_LDRH_REG, T_LDRH_REG, + T_LDRH_REG, T_LDRH_REG, T_LDRH_REG, T_LDRH_REG, // 0101 1100 00 T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, T_LDRB_REG, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_LDRSH_REG, T_LDRSH_REG, T_LDRSH_REG, T_LDRSH_REG, + T_LDRSH_REG, T_LDRSH_REG, T_LDRSH_REG, T_LDRSH_REG, // 0110 0000 00 T_STR_IMM, T_STR_IMM, T_STR_IMM, T_STR_IMM, @@ -1865,28 +1865,28 @@ INSTRFUNC_PROTO(THUMBInstrTable[1024]) = // 1100 0000 00 - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, // 1100 0100 00 - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, + T_STMIA, T_STMIA, T_STMIA, T_STMIA, // 1100 1000 00 - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, // 1100 1100 00 - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, - T_UNK, T_UNK, T_UNK, T_UNK, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, + T_LDMIA, T_LDMIA, T_LDMIA, T_LDMIA, // 1101 0000 00 T_BCOND, T_BCOND, T_BCOND, T_BCOND, diff --git a/NDS.cpp b/NDS.cpp index 23a781a7..1b33f3ed 100644 --- a/NDS.cpp +++ b/NDS.cpp @@ -18,6 +18,13 @@ u8 ARM7BIOS[0x4000]; u8 MainRAM[0x400000]; +u8 SharedWRAM[0x8000]; +u8 WRAMCnt; +u8* SWRAM_ARM9; +u8* SWRAM_ARM7; +u32 SWRAM_ARM9Mask; +u32 SWRAM_ARM7Mask; + u8 ARM7WRAM[0x10000]; u8 ARM9ITCM[0x8000]; @@ -68,10 +75,14 @@ void Reset() } memset(MainRAM, 0, 0x400000); + memset(SharedWRAM, 0, 0x8000); memset(ARM7WRAM, 0, 0x10000); memset(ARM9ITCM, 0, 0x8000); memset(ARM9DTCM, 0, 0x4000); + WRAMCnt = 0; + MapSharedWRAM(); + ARM9ITCMSize = 0; ARM9DTCMBase = 0xFFFFFFFF; ARM9DTCMSize = 0; @@ -112,6 +123,41 @@ void Halt() } +void MapSharedWRAM() +{ + switch (WRAMCnt & 0x3) + { + case 0: + SWRAM_ARM9 = &SharedWRAM[0]; + SWRAM_ARM9Mask = 0x7FFF; + SWRAM_ARM7 = NULL; + SWRAM_ARM7Mask = 0; + break; + + case 1: + SWRAM_ARM9 = &SharedWRAM[0x4000]; + SWRAM_ARM9Mask = 0x3FFF; + SWRAM_ARM7 = &SharedWRAM[0]; + SWRAM_ARM7Mask = 0x3FFF; + break; + + case 2: + SWRAM_ARM9 = &SharedWRAM[0]; + SWRAM_ARM9Mask = 0x3FFF; + SWRAM_ARM7 = &SharedWRAM[0x4000]; + SWRAM_ARM7Mask = 0x3FFF; + break; + + case 3: + SWRAM_ARM9 = NULL; + SWRAM_ARM9Mask = 0; + SWRAM_ARM7 = &SharedWRAM[0]; + SWRAM_ARM7Mask = 0x7FFF; + break; + } +} + + u8 ARM9Read8(u32 addr) { @@ -132,6 +178,17 @@ u8 ARM9Read8(u32 addr) { case 0x02000000: return *(u8*)&MainRAM[addr & 0x3FFFFF]; + + case 0x03000000: + if (SWRAM_ARM9) return *(u8*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask]; + else return 0; + + case 0x04000000: + switch (addr) + { + case 0x04000247: + return WRAMCnt; + } } printf("unknown arm9 read8 %08X\n", addr); @@ -158,6 +215,10 @@ u16 ARM9Read16(u32 addr) case 0x02000000: return *(u16*)&MainRAM[addr & 0x3FFFFF]; + case 0x03000000: + if (SWRAM_ARM9) return *(u16*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask]; + else return 0; + case 0x04000000: switch (addr) { @@ -188,6 +249,10 @@ u32 ARM9Read32(u32 addr) { case 0x02000000: return *(u32*)&MainRAM[addr & 0x3FFFFF]; + + case 0x03000000: + if (SWRAM_ARM9) return *(u32*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask]; + else return 0; } printf("unknown arm9 read32 %08X | %08X\n", addr, ARM9->R[15]); @@ -212,6 +277,19 @@ void ARM9Write8(u32 addr, u8 val) case 0x02000000: *(u8*)&MainRAM[addr & 0x3FFFFF] = val; return; + + case 0x03000000: + if (SWRAM_ARM9) *(u8*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; + return; + + case 0x04000000: + switch (addr) + { + case 0x04000247: + WRAMCnt = val; + MapSharedWRAM(); + return; + } } printf("unknown arm9 write8 %08X %02X\n", addr, val); @@ -236,6 +314,10 @@ void ARM9Write16(u32 addr, u16 val) *(u16*)&MainRAM[addr & 0x3FFFFF] = val; return; + case 0x03000000: + if (SWRAM_ARM9) *(u16*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; + return; + case 0x04000000: switch (addr) { @@ -273,6 +355,10 @@ void ARM9Write32(u32 addr, u32 val) case 0x02000000: *(u32*)&MainRAM[addr & 0x3FFFFF] = val; return; + + case 0x03000000: + if (SWRAM_ARM9) *(u32*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; + return; } printf("unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9->R[15]); @@ -292,8 +378,19 @@ u8 ARM7Read8(u32 addr) case 0x02000000: return *(u8*)&MainRAM[addr & 0x3FFFFF]; + case 0x03000000: + if (SWRAM_ARM7) return *(u8*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask]; + else return *(u8*)&ARM7WRAM[addr & 0xFFFF]; + case 0x03800000: return *(u8*)&ARM7WRAM[addr & 0xFFFF]; + + case 0x04000000: + switch (addr) + { + case 0x04000241: + return WRAMCnt; + } } printf("unknown arm7 read8 %08X\n", addr); @@ -312,6 +409,10 @@ u16 ARM7Read16(u32 addr) case 0x02000000: return *(u16*)&MainRAM[addr & 0x3FFFFF]; + case 0x03000000: + if (SWRAM_ARM7) return *(u16*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask]; + else return *(u16*)&ARM7WRAM[addr & 0xFFFF]; + case 0x03800000: return *(u16*)&ARM7WRAM[addr & 0xFFFF]; @@ -338,8 +439,19 @@ u32 ARM7Read32(u32 addr) case 0x02000000: return *(u32*)&MainRAM[addr & 0x3FFFFF]; + case 0x03000000: + if (SWRAM_ARM7) return *(u32*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask]; + else return *(u32*)&ARM7WRAM[addr & 0xFFFF]; + case 0x03800000: return *(u32*)&ARM7WRAM[addr & 0xFFFF]; + + case 0x04000000: + switch (addr) + { + case 0x040001A4: + return 0x00800000; // hax + } } if ((addr&0xFF000000) == 0xEA000000) Halt(); printf("unknown arm7 read32 %08X | %08X\n", addr, ARM7->R[15]); @@ -354,12 +466,17 @@ void ARM7Write8(u32 addr, u8 val) *(u8*)&MainRAM[addr & 0x3FFFFF] = val; return; + case 0x03000000: + if (SWRAM_ARM7) *(u8*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; + else *(u8*)&ARM7WRAM[addr & 0xFFFF] = val; + return; + case 0x03800000: *(u8*)&ARM7WRAM[addr & 0xFFFF] = val; return; } - printf("unknown arm7 write8 %08X %02X\n", addr, val); + printf("unknown arm7 write8 %08X %02X | %08X\n", addr, val, ARM7->R[15]); } void ARM7Write16(u32 addr, u16 val) @@ -370,6 +487,11 @@ void ARM7Write16(u32 addr, u16 val) *(u16*)&MainRAM[addr & 0x3FFFFF] = val; return; + case 0x03000000: + if (SWRAM_ARM7) *(u16*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; + else *(u16*)&ARM7WRAM[addr & 0xFFFF] = val; + return; + case 0x03800000: *(u16*)&ARM7WRAM[addr & 0xFFFF] = val; return; @@ -390,7 +512,7 @@ void ARM7Write16(u32 addr, u16 val) } } - printf("unknown arm7 write16 %08X %04X\n", addr, val); + printf("unknown arm7 write16 %08X %04X | %08X\n", addr, val, ARM7->R[15]); } void ARM7Write32(u32 addr, u32 val) @@ -401,12 +523,17 @@ void ARM7Write32(u32 addr, u32 val) *(u32*)&MainRAM[addr & 0x3FFFFF] = val; return; + case 0x03000000: + if (SWRAM_ARM7) *(u32*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; + else *(u32*)&ARM7WRAM[addr & 0xFFFF] = val; + return; + case 0x03800000: *(u32*)&ARM7WRAM[addr & 0xFFFF] = val; return; } - printf("unknown arm7 write32 %08X %08X\n", addr, val); + printf("unknown arm7 write32 %08X %08X | %08X\n", addr, val, ARM7->R[15]); } } diff --git a/NDS.h b/NDS.h index 06490425..b0a3311b 100644 --- a/NDS.h +++ b/NDS.h @@ -17,6 +17,8 @@ void RunFrame(); void Halt(); +void MapSharedWRAM(); + u8 ARM9Read8(u32 addr); u16 ARM9Read16(u32 addr); u32 ARM9Read32(u32 addr); diff --git a/melonDS.depend b/melonDS.depend index e36f7dd6..100795b8 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -3,12 +3,12 @@ "NDS.h" -1480776639 c:\documents\sources\melonds\nds.h +1480786007 c:\documents\sources\melonds\nds.h "types.h" 1463409689 c:\documents\sources\melonds\types.h -1480783776 source:c:\documents\sources\melonds\nds.cpp +1480784993 source:c:\documents\sources\melonds\nds.cpp "NDS.h" @@ -25,7 +25,7 @@ "types.h" "NDS.h" -1480784235 c:\documents\sources\melonds\arm_instrtable.h +1480785229 c:\documents\sources\melonds\arm_instrtable.h 1480725698 c:\documents\sources\melonds\arminterpreter.h "types.h" @@ -49,12 +49,12 @@ 1480784137 c:\documents\sources\melonds\arminterpreter_alu.h -1480783339 source:c:\documents\sources\melonds\arminterpreter_alu.cpp +1480784110 source:c:\documents\sources\melonds\arminterpreter_alu.cpp "ARM.h" -1480780717 c:\documents\sources\melonds\arminterpreter_loadstore.h +1480785175 c:\documents\sources\melonds\arminterpreter_loadstore.h -1480783030 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp +1480785158 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp "ARM.h"