diff --git a/ARM.cpp b/ARM.cpp index a7fa71c0..4b63c049 100644 --- a/ARM.cpp +++ b/ARM.cpp @@ -248,6 +248,8 @@ s32 ARM::Execute(s32 cycles) while (cyclesrun < cycles) { + //if(Num==1)printf("%08X %08X\n", R[15] - (CPSR&0x20 ? 4:8), NextInstr); + if (CPSR & 0x20) // THUMB { // prefetch @@ -315,6 +317,18 @@ s32 ARM::Execute(s32 cycles) //printf("[%08X|%08X] IRQ RET VAL = %08X | %d\n", R[15], CPSR, Read32(0x0380FF7C), cyclesrun); } + /*if (R[15] == 0x03802D54+2) + printf("%08X -> %08X\n", addr, R[15]); + + // 37FE284(ARM) -> 37FE256 -> 37FECA0 !!! + if (R[15] == 0x037FE256+4) + printf("ROYAL %08X %s -> %08X %s | %08X\n", + addr, (cpsr&0x20)?"THUMB":"ARM", R[15], (CPSR&0x20)?"THUMB":"ARM", + R[0]); + if (R[15] == 0x37FE27C) + printf("NOTROYAL %08X %08X %08X/%08X\n", R[0], Read32(0x0380593C + 0x3C), R_SVC[2], Read32(0x0380593C-4));*/ + // R0 = 0380593C + addr = R[15] - (CPSR&0x20 ? 4:8); cpsr = CPSR; } diff --git a/ARMInterpreter.cpp b/ARMInterpreter.cpp index e156e255..f486d880 100644 --- a/ARMInterpreter.cpp +++ b/ARMInterpreter.cpp @@ -106,11 +106,14 @@ s32 A_MSR_REG(ARM* cpu) u32 oldpsr = *psr; u32 mask = 0; - if (cpu->CurInstr & (1<<16)) mask |= 0x000000DF; + if (cpu->CurInstr & (1<<16)) mask |= 0x000000FF; if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00; if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; if (cpu->CurInstr & (1<<19)) mask |= 0xFF000000; + if (!(cpu->CurInstr & (1<<22))) + mask &= 0xFFFFFFDF; + if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00; u32 val = cpu->R[cpu->CurInstr & 0xF]; @@ -190,6 +193,20 @@ s32 A_MRC(ARM* cpu) +s32 A_SVC(ARM* cpu) +{ + u32 oldcpsr = cpu->CPSR; + cpu->CPSR &= ~0xFF; + cpu->CPSR |= 0xD3; + cpu->UpdateMode(oldcpsr, cpu->CPSR); + + cpu->R_SVC[2] = oldcpsr; + cpu->R[14] = cpu->R[15] - 4; + cpu->JumpTo(cpu->ExceptionBase + 0x08); + + return C_S(2) + C_N(1); +} + s32 T_SVC(ARM* cpu) { u32 oldcpsr = cpu->CPSR; @@ -201,9 +218,6 @@ s32 T_SVC(ARM* cpu) cpu->R[14] = cpu->R[15] - 2; cpu->JumpTo(cpu->ExceptionBase + 0x08); - //printf("ARM%d SWI %02X %08X,%08X,%08X LR=%08X/%08X\n", cpu->Num?7:9, (cpu->CurInstr & 0xFF), cpu->R[0], cpu->R[1], cpu->R[2], cpu->R[14], cpu->R_SVC[1]); -//printf("%08X\n", cpu->Read32(0x27FF814)); - return C_S(2) + C_N(1); } diff --git a/ARM_InstrTable.h b/ARM_InstrTable.h index 03bbe299..1cc3fd2f 100644 --- a/ARM_InstrTable.h +++ b/ARM_InstrTable.h @@ -1489,100 +1489,100 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) = // 1111 0000 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0001 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0010 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0011 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0100 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0101 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0110 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 0111 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1000 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1001 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1010 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1011 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1100 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1101 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1110 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, // 1111 1111 0000 - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK, - A_UNK, A_UNK, A_UNK, A_UNK + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC, + A_SVC, A_SVC, A_SVC, A_SVC }; INSTRFUNC_PROTO(THUMBInstrTable[1024]) = diff --git a/CP15.cpp b/CP15.cpp index 72c1924b..363d4ee0 100644 --- a/CP15.cpp +++ b/CP15.cpp @@ -95,6 +95,21 @@ void Write(u32 id, u32 val) return; + case 0x761: + //printf("inval data cache %08X\n", val); + return; + case 0x762: + printf("inval data cache SI\n"); + return; + + case 0x7A1: + printf("flush data cache %08X\n", val); + return; + case 0x7A2: + printf("flush data cache SI\n"); + return; + + case 0x910: DTCMSetting = val; UpdateDTCMSetting(); @@ -104,6 +119,8 @@ void Write(u32 id, u32 val) UpdateITCMSetting(); return; } + + //printf("unknown CP15 write op %03X %08X\n", id, val); } u32 Read(u32 id) @@ -136,6 +153,7 @@ u32 Read(u32 id) return ITCMSetting; } + printf("unknown CP15 read op %03X\n", id); return 0; } diff --git a/GPU2D.cpp b/GPU2D.cpp index bd85ed7f..4c6962dc 100644 --- a/GPU2D.cpp +++ b/GPU2D.cpp @@ -98,6 +98,9 @@ void Reset() } +// VRAM mapping shit. +// TODO eventually: work out priority orders in case of overlaps. there _are_ games that map overlapping banks. + void MapVRAM_AB(u32 bank, u8 cnt) { u8 oldcnt = VRAMCNT[bank]; diff --git a/NDS.cpp b/NDS.cpp index ef845730..5c0ff954 100644 --- a/NDS.cpp +++ b/NDS.cpp @@ -25,6 +25,12 @@ #include "SPI.h" #include "Wifi.h" +// derp +namespace SPI_Firmware +{ + extern u8* Firmware; +} + namespace NDS { @@ -94,11 +100,13 @@ void Init() Reset(); } +// temp void LoadROM() { FILE* f; - f = fopen("armwrestler.nds", "rb"); + //f = fopen("rom/armwrestler.nds", "rb"); + f = fopen("rom/zorp.nds", "rb"); u32 bootparams[8]; fseek(f, 0x20, SEEK_SET); @@ -211,6 +219,7 @@ void Reset() // test //LoadROM(); + //LoadFirmware(); Running = true; // hax } @@ -898,6 +907,7 @@ void ARM9Write8(u32 addr, u8 val) void ARM9Write16(u32 addr, u16 val) { + if (addr == ARM9->R[15]) printf("!!!!!!!!!!!!9999 %08X %04X\n", addr, val); if (addr < ARM9ITCMSize) { *(u16*)&ARM9ITCM[addr & 0x7FFF] = val; @@ -1009,6 +1019,7 @@ void ARM9Write16(u32 addr, u16 val) void ARM9Write32(u32 addr, u32 val) { + if (addr == ARM9->R[15]) printf("!!!!!!!!!!!!9999 %08X %08X\n", addr, val); if (addr < ARM9ITCMSize) { *(u32*)&ARM9ITCM[addr & 0x7FFF] = val; @@ -1061,24 +1072,7 @@ void ARM9Write32(u32 addr, u32 val) return; case 0x04000208: IME[0] = val & 0x1; return; - case 0x04000210: IE[0] = val; printf("%08X %08X %08X\n", ARM7->R[15], WRAMCnt, ARM7->CPSR); - /*{ - FILE* f; - f = fopen("ARM7FIRM.bin", "wb"); - for (u32 i = 0; i < 0x18000; i+=4) - { - u32 tmp = ARM7Read32(0x37F8000+i); - fwrite(&tmp, 4, 1, f); - } - fclose(f); - f = fopen("ARM9FIRM.bin", "wb"); - for (u32 i = 0; i < 0x400000; i+=4) - { - u32 tmp = ARM9Read32(0x2000000+i); - fwrite(&tmp, 4, 1, f); - } - fclose(f); - }*/return; + case 0x04000210: IE[0] = val; return; case 0x04000214: IF[0] &= ~val; return; case 0x04000240: @@ -1263,8 +1257,12 @@ u32 ARM7Read32(u32 addr) { if (addr < 0x00004000) { - if (ARM7->R[15] > 0x4000) {printf("BAD BIOS READ32 %08X FROM %08X | %08X\n", addr, ARM7->R[15], ARM7Read32(0x0380776C+12));return 0xFFFFFFFF;} - if (addr < 0x1204 && ARM7->R[15] >= 0x1204) printf("BAD BIOS READ32 %08X FROM %08X\n", addr, ARM7->R[15]); + if (ARM7->R[15] > 0x4000) { + printf("BAD BIOS READ32 %08X FROM %08X | %08X %08X\n", addr, ARM7->R[15], ARM7Read32(0x03807758+12), ARM7Read32(0x03807758+4)); + Halt(); + return 0xFFFFFFFF; + } + //if (addr < 0x1204 && ARM7->R[15] >= 0x1204) printf("BAD BIOS READ32 %08X FROM %08X\n", addr, ARM7->R[15]); return *(u32*)&ARM7BIOS[addr]; } @@ -1405,6 +1403,7 @@ void ARM7Write8(u32 addr, u8 val) void ARM7Write16(u32 addr, u16 val) { + if (addr == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %04X\n", addr, val); if (addr==0x3807764) printf("DERP! %04X %08X\n", val, ARM7->R[15]); switch (addr & 0xFF800000) { @@ -1429,7 +1428,7 @@ void ARM7Write16(u32 addr, u16 val) case 0x04000100: Timers[4].Reload = val; return; case 0x04000102: TimerStart(4, val); return; case 0x04000104: Timers[5].Reload = val; - Timers[5].Reload = 0xFFE0; + //Timers[5].Reload = 0xFFE0; // hax. // firmware bootloader sets it to 0xFFFE, which doesn't give it enough time to do its IRQ handling shit before getting another IRQ //printf("TIMER RELOAD=%04X FROM %08X, %08X %08X\n", val, ARM7->R[15], ARM7->R[4], ARM7->CPSR); @@ -1437,7 +1436,8 @@ void ARM7Write16(u32 addr, u16 val) case 0x04000106: TimerStart(5, val); /*printf("TIMER CNT=%04X FROM %08X | %08X%08X - %08X%08X | %04X %04X %04X\n", val, ARM7->R[15], ARM7Read32(ARM7->R[4]+0x10), ARM7Read32(ARM7->R[4]+0xC), ARM7->R[1], ARM7->R[0], - Timers[4].Control, Timers[4].Counter, Timers[4].Reload);*/return; + Timers[4].Control, Timers[4].Counter, Timers[4].Reload);*/ + /*printf("enable timer1 %08X\n", ARM7->R[15]);*/return; case 0x04000108: Timers[6].Reload = val; return; case 0x0400010A: TimerStart(6, val); return; case 0x0400010C: Timers[7].Reload = val; return; @@ -1500,8 +1500,11 @@ void ARM7Write16(u32 addr, u16 val) void ARM7Write32(u32 addr, u32 val) { + if (addr == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %08X\n", addr, val); if (addr==0x27FF890) printf("HAHA! %08X\n", val); if (addr==0x3807764) printf("DERP! %08X %08X\n", val, ARM7->R[15]); + if (addr==0x380776C) printf("ZORP!!!!!!! %08X %08X %08X\n", val, ARM7->R[15], ARM7Read32(ARM7->R[13]+20)); + if (addr==0x3807770) printf("ZAARP!!!!!!! %08X %08X\n", val, ARM7->R[15]); switch (addr & 0xFF800000) { case 0x02000000: diff --git a/SPI.cpp b/SPI.cpp index c9847b72..3a7001aa 100644 --- a/SPI.cpp +++ b/SPI.cpp @@ -35,6 +35,39 @@ u8 Data; u8 StatusReg; u32 Addr; + +u16 CRC16(u8* data, u32 len, u32 start) +{ + u16 blarg[8] = {0xC0C1, 0xC181, 0xC301, 0xC601, 0xCC01, 0xD801, 0xF001, 0xA001}; + + for (u32 i = 0; i < len; i++) + { + start ^= data[i]; + + for (int j = 0; j < 8; j++) + { + if (start & 0x1) + { + start >>= 1; + start ^= (blarg[j] << (7-j)); + } + else + start >>= 1; + } + } + + return start & 0xFFFF; +} + +bool VerifyCRC16(u32 start, u32 offset, u32 len, u32 crcoffset) +{ + u16 crc_stored = *(u16*)&Firmware[crcoffset]; + u16 crc_calced = CRC16(&Firmware[offset], len, start); + //printf("%04X vs %04X\n", crc_stored, crc_calced); + return (crc_stored == crc_calced); +} + + void Init() { Firmware = NULL; @@ -54,6 +87,14 @@ void Reset() fclose(f); + // verify shit + printf("FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware[0x2C], 0x2A)?"GOOD":"BAD"); + printf("FW: AP1 CRC16 = %s\n", VerifyCRC16(0x0000, 0x3FA00, 0xFE, 0x3FAFE)?"GOOD":"BAD"); + printf("FW: AP2 CRC16 = %s\n", VerifyCRC16(0x0000, 0x3FB00, 0xFE, 0x3FBFE)?"GOOD":"BAD"); + printf("FW: AP3 CRC16 = %s\n", VerifyCRC16(0x0000, 0x3FC00, 0xFE, 0x3FCFE)?"GOOD":"BAD"); + printf("FW: USER0 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x3FE00, 0x70, 0x3FE72)?"GOOD":"BAD"); + printf("FW: USER1 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x3FF00, 0x70, 0x3FF72)?"GOOD":"BAD"); + Hold = 0; CurCmd = 0; Data = 0; diff --git a/melonDS.cbp b/melonDS.cbp index 4859fc6b..76e79d6e 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -14,6 +14,9 @@ + + +