diff --git a/CMakeLists.txt b/CMakeLists.txt
index 59f6a27804..d98728371f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -935,6 +935,10 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/MIPS/MIPSTables.h
Core/MIPS/MIPSVFPUUtils.cpp
Core/MIPS/MIPSVFPUUtils.h
+ Core/MIPS/MIPSAsmTables.cpp
+ Core/MIPS/MIPSAsmTables.h
+ Core/MIPS/MIPSAsm.cpp
+ Core/MIPS/MIPSAsm.h
Core/MemMap.cpp
Core/MemMap.h
Core/MemMapFunctions.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index e95ca005d2..cdc76a6070 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -311,6 +311,8 @@
+
+
@@ -463,6 +465,8 @@
+
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index a71b4375b3..49008c0860 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -442,6 +442,12 @@
Core
+
+ MIPS
+
+
+ MIPS
+
@@ -819,6 +825,12 @@
Core
+
+ MIPS
+
+
+ MIPS
+
diff --git a/Core/MIPS/MIPSAsm.cpp b/Core/MIPS/MIPSAsm.cpp
new file mode 100644
index 0000000000..1f79a79791
--- /dev/null
+++ b/Core/MIPS/MIPSAsm.cpp
@@ -0,0 +1,408 @@
+#include "stdafx.h"
+#include "MIPSAsm.h"
+
+namespace MIPSAsm
+{
+
+void SplitLine(const char* Line, char* Name, char* Arguments)
+{
+ while (*Line == ' ' || *Line == '\t') Line++;
+ while (*Line != ' ')
+ {
+ if (*Line == 0)
+ {
+ *Name = 0;
+ *Arguments = 0;
+ return;
+ }
+ *Name++ = *Line++;
+ }
+ *Name = 0;
+
+ while (*Line == ' ' || *Line == '\t') Line++;
+
+ while (*Line != 0)
+ {
+ *Arguments++ = *Line++;
+ }
+ *Arguments = 0;
+}
+
+bool MipsAssembleOpcode(char* line, DebugInterface* cpu, u32 address, u32& dest)
+{
+ char name[64],args[256];
+ SplitLine(line,name,args);
+
+ CMipsInstruction Opcode(cpu);
+ if (cpu == NULL || Opcode.Load(name,args,(int)address) == false)
+ {
+ return false;
+ }
+ if (Opcode.Validate() == false)
+ {
+ return false;
+ }
+
+ Opcode.Encode();
+ dest = Opcode.getEncoding();
+
+ return true;
+}
+
+int MipsGetRegister(char* source, int& RetLen)
+{
+ for (int z = 0; MipsRegister[z].name != NULL; z++)
+ {
+ int len = MipsRegister[z].len;
+ if (strncmp(MipsRegister[z].name,source,len) == 0) // fine so far
+ {
+ if (source[len] == ',' || source[len] == '\n' || source[len] == 0
+ || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these HAS TO come after a register
+ {
+ RetLen = len;
+ return MipsRegister[z].num;
+ }
+ }
+ }
+ return -1;
+}
+
+int MipsGetFloatRegister(char* source, int& RetLen)
+{
+ for (int z = 0; MipsFloatRegister[z].name != NULL; z++)
+ {
+ int len = MipsFloatRegister[z].len;
+ if (strncmp(MipsFloatRegister[z].name,source,len) == 0) // fine so far
+ {
+ if (source[len] == ',' || source[len] == '\n' || source[len] == 0
+ || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these HAS TO come after a register
+ {
+ RetLen = len;
+ return MipsFloatRegister[z].num;
+ }
+ }
+ }
+ return -1;
+}
+
+bool MipsCheckImmediate(char* Source, char* Dest, int& RetLen)
+{
+ int BufferPos = 0;
+ int l;
+
+ if (MipsGetRegister(Source,l) != -1) // there's a register -> no immediate
+ {
+ return false;
+ }
+
+ int SourceLen = 0;
+
+ while (true)
+ {
+ if (*Source == '\'' && *(Source+2) == '\'')
+ {
+ Dest[BufferPos++] = *Source++;
+ Dest[BufferPos++] = *Source++;
+ Dest[BufferPos++] = *Source++;
+ SourceLen+=3;
+ continue;
+ }
+
+ if (*Source == 0 || *Source == '\n' || *Source == ',')
+ {
+ Dest[BufferPos] = 0;
+ break;
+ }
+ if ( *Source == ' ' || *Source == '\t')
+ {
+ Source++;
+ SourceLen++;
+ continue;
+ }
+
+
+ if (*Source == '(') // could also be part of the opcode, ie (r4)
+ {
+ if (MipsGetRegister(Source+1,l) != -1) // stop if it is
+ {
+ Dest[BufferPos] = 0;
+ break;
+ }
+ }
+ Dest[BufferPos++] = *Source++;
+ SourceLen++;
+ }
+
+ if (BufferPos == 0) return false;
+
+ RetLen = SourceLen;
+ return true;
+}
+
+
+
+bool CMipsInstruction::Load(char* Name, char* Params, int RamPos)
+{
+ bool paramfail = false;
+ NoCheckError = false;
+ this->RamPos = RamPos;
+
+ for (int z = 0; MipsOpcodes[z].name != NULL; z++)
+ {
+ if (strcmp(Name,MipsOpcodes[z].name) == 0)
+ {
+ if (LoadEncoding(MipsOpcodes[z],Params) == true)
+ {
+ Loaded = true;
+ return true;
+ }
+ paramfail = true;
+ }
+ }
+
+ if (NoCheckError == false)
+ {
+ if (paramfail == true)
+ {
+ // PrintError(ERROR_ERROR,"Parameter failure \"%s\"",Params);
+ } else {
+ // PrintError(ERROR_ERROR,"Invalid opcode \"%s\"",Name);
+ }
+ }
+ return false;
+}
+
+bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, char* Line)
+{
+ char ImmediateBuffer[512];
+
+ int RetLen;
+ bool Immediate = false;
+
+ char* SourceEncoding = SourceOpcode.encoding;
+ char* OriginalLine = Line;
+
+ while (*Line == ' ' || *Line == '\t') Line++;
+
+ if (!(*SourceEncoding == 0 && *Line == 0))
+ {
+ while (*SourceEncoding != NULL)
+ {
+ while (*Line == ' ' || *Line == '\t') Line++;
+ if (*Line == 0) return false;
+
+ switch (*SourceEncoding)
+ {
+ case 'T': // float reg
+ if ((Vars.rt = MipsGetFloatRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 'D': // float reg
+ if ((Vars.rd = MipsGetFloatRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 'S': // float reg
+ if ((Vars.rs = MipsGetFloatRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 't':
+ if ((Vars.rt = MipsGetRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 'd':
+ if ((Vars.rd = MipsGetRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 's':
+ if ((Vars.rs = MipsGetRegister(Line,RetLen)) == -1) return false;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 'i': // 16 bit immediate
+ case 'I': // 32 bit immediate
+ case 'a': // 5 bit immediate
+ case 'b': // 20 bit immediate
+ if (MipsCheckImmediate(Line,ImmediateBuffer,RetLen) == false) return false;
+ Immediate = true;
+ Line += RetLen;
+ SourceEncoding++;
+ break;
+ case 'r': // forced register
+ if (MipsGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false;
+ Line += RetLen;
+ SourceEncoding += 2;
+ break;
+ default: // everything else
+ if (*SourceEncoding++ != *Line++) return false;
+ break;
+ }
+ }
+ }
+
+ while (*Line == ' ' || *Line == '\t') Line++;
+ if (*Line != 0) return false; // there's something else at the end, bad
+
+ // the opcode is fine - now set all remaining flags
+ Opcode = SourceOpcode;
+
+ if (Immediate == true)
+ {
+ u32 imm;
+ PostfixExpression postfix;
+ if (cpu->initExpression(ImmediateBuffer,postfix) == false) return false;
+ if (cpu->parseExpression(postfix,imm) == false) return false;
+
+ Vars.Immediate = (int) imm;
+ if (Opcode.flags & O_I5)
+ {
+ Vars.ImmediateType = MIPS_IMMEDIATE5;
+ } else if (Opcode.flags & O_I16)
+ {
+ Vars.ImmediateType = MIPS_IMMEDIATE16;
+ } else if (Opcode.flags & O_I20)
+ {
+ Vars.ImmediateType = MIPS_IMMEDIATE20;
+ } else if (Opcode.flags & O_I26)
+ {
+ Vars.ImmediateType = MIPS_IMMEDIATE26;
+ }
+ } else {
+ Vars.ImmediateType = MIPS_NOIMMEDIATE;
+ }
+
+ return true;
+}
+
+bool CMipsInstruction::Validate()
+{
+ if (RamPos % 4)
+ {
+ return false;
+ }
+
+ // check immediates
+ if (Vars.ImmediateType != MIPS_NOIMMEDIATE)
+ {
+ Vars.OriginalImmediate = Vars.Immediate;
+
+ if (Opcode.flags & O_IPCA) // absolute value >> 2)
+ {
+ Vars.Immediate = (Vars.Immediate >> 2) & 0x3FFFFFF;
+ } else if (Opcode.flags & O_IPCR) // relative 16 bit value
+ {
+ int num = (Vars.Immediate-RamPos-4);
+
+ if (num > 0x20000 || num < (-0x20000))
+ {
+ //QueueError(ERROR_ERROR,"Branch target %08X out of range",Vars.Immediate);
+ return false;
+ }
+ Vars.Immediate = num >> 2;
+ }
+
+ switch (Vars.ImmediateType)
+ {
+ case MIPS_IMMEDIATE5:
+ if (Vars.Immediate > 0x1F)
+ {
+ // QueueError(ERROR_ERROR,"Immediate value %02X out of range",Vars.OriginalImmediate);
+ return false;
+ }
+ break;
+ Vars.Immediate &= 0x1F;
+ break;
+ case MIPS_IMMEDIATE16:
+ if (abs(Vars.Immediate) > 0xFFFF)
+ {
+ // QueueError(ERROR_ERROR,"Immediate value %04X out of range",Vars.OriginalImmediate);
+ return false;
+ }
+ Vars.Immediate &= 0xFFFF;
+ break;
+ case MIPS_IMMEDIATE20:
+ if (abs(Vars.Immediate) > 0xFFFFF)
+ {
+ // QueueError(ERROR_ERROR,"Immediate value %08X out of range",Vars.OriginalImmediate);
+ return false;
+ }
+ Vars.Immediate &= 0xFFFFF;
+ break;
+ case MIPS_IMMEDIATE26:
+ if (abs(Vars.Immediate) > 0x3FFFFFF)
+ {
+ // QueueError(ERROR_ERROR,"Immediate value %08X out of range",Vars.OriginalImmediate);
+ return false;
+ }
+ Vars.Immediate &= 0x3FFFFFF;
+ break;
+ }
+ }
+
+ return true;
+}
+
+void CMipsInstruction::Encode()
+{
+ encoding = (u32) Opcode.destencoding;
+
+ if (Opcode.flags & O_RS) encoding |= (Vars.rs << 21); // source reg
+ if (Opcode.flags & O_RT) encoding |= (Vars.rt << 16); // target reg
+ if (Opcode.flags & O_RD) encoding |= (Vars.rd << 11); // dest reg
+ if (Opcode.flags & O_RSD) // s = d & s
+ {
+ encoding |= (Vars.rs << 21);
+ encoding |= (Vars.rs << 11);
+ }
+ if (Opcode.flags & O_RST) // s = t & s
+ {
+ encoding |= (Vars.rs << 21);
+ encoding |= (Vars.rs << 16);
+ }
+ if (Opcode.flags & O_RDT) // d = t & d
+ {
+ encoding |= (Vars.rd << 16);
+ encoding |= (Vars.rd << 11);
+ }
+
+ if (Opcode.flags & MO_FRT) encoding |= (Vars.rt << 16); // float target
+ if (Opcode.flags & MO_FRS) encoding |= (Vars.rs << 11); // float source
+ if (Opcode.flags & MO_FRD) encoding |= (Vars.rd << 6); // float target
+ if (Opcode.flags & MO_FRSD) // s = d & s
+ {
+ encoding |= (Vars.rs << 6);
+ encoding |= (Vars.rs << 11);
+ }
+ if (Opcode.flags & MO_FRST) // s = t & s
+ {
+ encoding |= (Vars.rs << 11);
+ encoding |= (Vars.rs << 16);
+ }
+ if (Opcode.flags & MO_FRDT) // d = t & d
+ {
+ encoding |= (Vars.rd << 6);
+ encoding |= (Vars.rd << 16);
+ }
+
+ switch (Vars.ImmediateType)
+ {
+ case MIPS_IMMEDIATE5:
+ encoding |= ((Vars.Immediate & 0x1F) << 6);
+ break;
+ case MIPS_IMMEDIATE16:
+ encoding |= (Vars.Immediate & 0xFFFF);
+ break;
+ case MIPS_IMMEDIATE20:
+ encoding |= (Vars.Immediate & 0xFFFFF) << 6;
+ break;
+ case MIPS_IMMEDIATE26:
+ encoding |= Vars.Immediate & 0x3FFFFFF;
+ break;
+ }
+}
+
+}
\ No newline at end of file
diff --git a/Core/MIPS/MIPSAsm.h b/Core/MIPS/MIPSAsm.h
new file mode 100644
index 0000000000..9c851c06b4
--- /dev/null
+++ b/Core/MIPS/MIPSAsm.h
@@ -0,0 +1,42 @@
+#pragma once
+#include "../../Globals.h"
+#include "../Debugger/DebugInterface.h"
+#include "MIPSAsmTables.h"
+
+namespace MIPSAsm
+{
+
+bool MipsAssembleOpcode(char* line, DebugInterface* cpu, u32 address, u32& dest);
+
+typedef enum eMipsImmediateType { MIPS_NOIMMEDIATE, MIPS_IMMEDIATE5,
+ MIPS_IMMEDIATE16, MIPS_IMMEDIATE20, MIPS_IMMEDIATE26 };
+
+typedef struct {
+ int rs; // source reg
+ int rt; // target reg
+ int rd; // dest reg
+ eMipsImmediateType ImmediateType;
+ int Immediate;
+ int OriginalImmediate;
+} tMipsOpcodeVariables;
+
+class CMipsInstruction
+{
+public:
+ CMipsInstruction(DebugInterface* cpu):cpu(cpu),Loaded(false) { };
+ bool Load(char* Name, char* Params, int RamPos);
+ bool Validate();
+ void Encode();
+ u32 getEncoding() { return encoding; };
+private:
+ bool LoadEncoding(const tMipsOpcode& SourceOpcode, char* Line);
+ tMipsOpcode Opcode;
+ bool NoCheckError;
+ bool Loaded;
+ tMipsOpcodeVariables Vars;
+ int RamPos;
+ DebugInterface* cpu;
+ u32 encoding;
+};
+
+}
\ No newline at end of file
diff --git a/Core/MIPS/MIPSAsmTables.cpp b/Core/MIPS/MIPSAsmTables.cpp
new file mode 100644
index 0000000000..b1ecfbf4d4
--- /dev/null
+++ b/Core/MIPS/MIPSAsmTables.cpp
@@ -0,0 +1,418 @@
+#include "stdafx.h"
+#include "MIPSAsmTables.h"
+
+namespace MIPSAsm
+{
+
+const tMipsRegister MipsRegister[] = {
+ { "r0", 0, 2 }, { "zero", 0, 4}, { "$0", 0, 2 },
+ { "at", 1, 2 }, { "r1", 1, 2 }, { "$1", 1, 2 },
+ { "v0", 2, 2 }, { "r2", 2, 2 }, { "$v0", 2, 3 },
+ { "v1", 3, 2 }, { "r3", 3, 2 }, { "$v1", 3, 3 },
+ { "a0", 4, 2 }, { "r4", 4, 2 }, { "$a0", 4, 3 },
+ { "a1", 5, 2 }, { "r5", 5, 2 }, { "$a1", 5, 3 },
+ { "a2", 6, 2 }, { "r6", 6, 2 }, { "$a2", 6, 3 },
+ { "a3", 7, 2 }, { "r7", 7, 2 }, { "$a3", 7, 3 },
+ { "t0", 8, 2 }, { "r8", 8, 2 }, { "$t0", 8, 3 },
+ { "t1", 9, 2 }, { "r9", 9, 2 }, { "$t1", 9, 3 },
+ { "t2", 10, 2 }, { "r10", 10, 3 }, { "$t2", 10, 3 },
+ { "t3", 11, 2 }, { "r11", 11, 3 }, { "$t3", 11, 3 },
+ { "t4", 12, 2 }, { "r12", 12, 3 }, { "$t4", 12, 3 },
+ { "t5", 13, 2 }, { "r13", 13, 3 }, { "$t5", 13, 3 },
+ { "t6", 14, 2 }, { "r14", 14, 3 }, { "$t6", 14, 3 },
+ { "t7", 15, 2 }, { "r15", 15, 3 }, { "$t7", 15, 3 },
+ { "s0", 16, 2 }, { "r16", 16, 3 }, { "$s0", 16, 3 },
+ { "s1", 17, 2 }, { "r17", 17, 3 }, { "$s1", 17, 3 },
+ { "s2", 18, 2 }, { "r18", 18, 3 }, { "$s2", 18, 3 },
+ { "s3", 19, 2 }, { "r19", 19, 3 }, { "$s3", 19, 3 },
+ { "s4", 20, 2 }, { "r20", 20, 3 }, { "$s4", 20, 3 },
+ { "s5", 21, 2 }, { "r21", 21, 3 }, { "$s5", 21, 3 },
+ { "s6", 22, 2 }, { "r22", 22, 3 }, { "$s6", 22, 3 },
+ { "s7", 23, 2 }, { "r23", 23, 3 }, { "$s7", 23, 3 },
+ { "t8", 24, 2 }, { "r24", 24, 3 }, { "$t8", 24, 3 },
+ { "t9", 25, 2 }, { "r25", 25, 3 }, { "$t9", 25, 3 },
+ { "k0", 26, 2 }, { "r26", 26, 3 }, { "$k0", 26, 3 },
+ { "k1", 27, 2 }, { "r27", 27, 3 }, { "$k1", 27, 3 },
+ { "gp", 28, 2 }, { "r28", 28, 3 }, { "$gp", 28, 3 },
+ { "sp", 29, 2 }, { "r29", 29, 3 }, { "$sp", 29, 3 },
+ { "fp", 30, 2 }, { "r30", 30, 3 }, { "$fp", 30, 3 },
+ { "ra", 31, 2 }, { "r31", 31, 3 }, { "$ra", 31, 3 },
+ { NULL, -1, 0}
+};
+
+
+const tMipsRegister MipsFloatRegister[] = {
+ { "f0", 0, 2}, { "$f0", 0, 3 },
+ { "f1", 1, 2}, { "$f1", 1, 3 },
+ { "f2", 2, 2}, { "$f2", 2, 3 },
+ { "f3", 3, 2}, { "$f3", 3, 3 },
+ { "f4", 4, 2}, { "$f4", 4, 3 },
+ { "f5", 5, 2}, { "$f5", 5, 3 },
+ { "f6", 6, 2}, { "$f6", 6, 3 },
+ { "f7", 7, 2}, { "$f7", 7, 3 },
+ { "f8", 8, 2}, { "$f8", 8, 3 },
+ { "f9", 9, 2}, { "$f9", 9, 3 },
+ { "f10", 10, 3}, { "$f10", 10, 4 },
+ { "f11", 11, 3}, { "$f11", 11, 4 },
+ { "f12", 12, 3}, { "$f12", 12, 4 },
+ { "f13", 13, 3}, { "$f13", 13, 4 },
+ { "f14", 14, 3}, { "$f14", 14, 4 },
+ { "f15", 15, 3}, { "$f15", 15, 4 },
+ { "f16", 16, 3}, { "$f16", 16, 4 },
+ { "f17", 17, 3}, { "$f17", 17, 4 },
+ { "f18", 18, 3}, { "$f18", 18, 4 },
+ { "f19", 19, 3}, { "$f19", 19, 4 },
+ { "f20", 20, 3}, { "$f20", 20, 4 },
+ { "f21", 21, 3}, { "$f21", 21, 4 },
+ { "f22", 22, 3}, { "$f22", 22, 4 },
+ { "f23", 23, 3}, { "$f23", 23, 4 },
+ { "f24", 24, 3}, { "$f24", 24, 4 },
+ { "f25", 25, 3}, { "$f25", 25, 4 },
+ { "f26", 26, 3}, { "$f26", 26, 4 },
+ { "f27", 27, 3}, { "$f27", 27, 4 },
+ { "f28", 28, 3}, { "$f28", 28, 4 },
+ { "f29", 29, 3}, { "$f29", 29, 4 },
+ { "f30", 30, 3}, { "$f30", 30, 4 },
+ { "f31", 31, 3}, { "$f31", 31, 4 }
+};
+
+/* Placeholders for encoding
+
+ s source register
+ d destination register
+ t target register
+ S float source reg
+ D float dest reg
+ T float traget reg
+ i 16 bit immediate value
+ I 32 bit immediate value
+ u Shifted 16 bit immediate (upper)
+ n negative 16 bit immediate (for subi/u aliases)
+ b 26 bit immediate
+ a 5 bit immediate
+*/
+
+const tMipsOpcode MipsOpcodes[] = {
+// 31---------26------------------------------------------5--------0
+// |= SPECIAL| | function|
+// ------6----------------------------------------------------6-----
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 000 | SLL | --- | SRL*1 | SRA | SLLV | --- | SRLV*2| SRAV |
+// 001 | JR | JALR | MOVZ | MOVN |SYSCALL| BREAK | --- | SYNC |
+// 010 | MFHI | MTHI | MFLO | MTLO | DSLLV | --- | *3 | *4 |
+// 011 | MULT | MULTU | DIV | DIVU | MADD | MADDU | ---- | ----- |
+// 100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR |
+// 101 | mfsa | mtsa | SLT | SLTU | *5 | *6 | *7 | *8 |
+// 110 | TGE | TGEU | TLT | TLTU | TEQ | --- | TNE | --- |
+// 111 | dsll | --- | dsrl | dsra |dsll32 | --- |dsrl32 |dsra32 |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+// *1: rotr when rs = 1 (PSP only) *2: rotrv when rs = 1 (PSP only)
+// *3: dsrlv on PS2, clz on PSP *4: dsrav on PS2, clo on PSP
+// *5: dadd on PS2, max on PSP *6: daddu on PS2, min on PSP
+// *7: dsub on PS2, msub on PSP *8: dsubu on PS2, msubu on PSP
+ { "sll", "d,t,a", 0x00000000, O_RD|O_RT|O_I5 },
+ { "sll", "d,a", 0x00000000, O_RDT|O_I5 },
+ { "nop", "", 0x00000000, 0 },
+ { "srl", "d,t,a", 0x00000002, O_RD|O_RT|O_I5 },
+ { "srl", "d,a", 0x00000002, O_RDT|O_I5 },
+ { "rotr", "d,t,a", 0x00200002, O_RD|O_RT|O_I5 },
+ { "rotr", "d,a", 0x00200002, O_RDT|O_I5 },
+ { "sra", "d,t,a", 0x00000003, O_RD|O_RT|O_I5 },
+ { "sra", "d,a", 0x00000003, O_RDT|O_I5 },
+ { "sllv", "d,t,s", 0x00000004, O_RD|O_RT|O_RS },
+ { "sllv", "d,s", 0x00000004, O_RDT|O_RS },
+ { "srlv", "d,t,s", 0x00000006, O_RD|O_RT|O_RS },
+ { "srlv", "d,s", 0x00000006, O_RDT|O_RS },
+ { "rotrv", "d,t,s", 0x00200006, O_RD|O_RT|O_RS },
+ { "rotrv", "d,s", 0x00200006, O_RDT|O_RS },
+ { "srav", "d,t,s", 0x00000007, O_RD|O_RT|O_RS },
+ { "srav", "d,s", 0x00000007, O_RDT|O_RS },
+ { "jr", "s", 0x00000008, O_RS|MO_DELAY|MO_NODELAY },
+ { "jalr", "s,d", 0x00000009, O_RD|O_RS|MO_DELAY|MO_NODELAY },
+ { "jalr", "s", 0x0000F809, O_RS|MO_DELAY|MO_NODELAY },
+ { "movz", "d,s,t", 0x0000000A, O_RD|O_RT|O_RS },
+ { "movn", "d,s,t", 0x0000000B, O_RD|O_RT|O_RS },
+ { "syscall","b", 0x0000000c, O_I20|MO_DELAY|MO_NODELAY },
+ { "break", "b", 0x0000000d, O_I20|MO_DELAY|MO_NODELAY },
+ { "sync", "", 0x0000000f, 0 },
+ { "mfhi", "d", 0x00000010, O_RD },
+ { "mthi", "s", 0x00000011, O_RS },
+ { "mflo", "d", 0x00000012, O_RD },
+ { "mtlo", "s", 0x00000013, O_RS },
+ { "clz", "d,s", 0x00000016, O_RD|O_RS },
+ { "clo", "d,s", 0x00000017, O_RD|O_RS },
+ { "mult", "s,t", 0x00000018, O_RS|O_RT },
+ { "mult", "r\x0,s,t", 0x00000018, O_RS|O_RT },
+ { "multu", "s,t", 0x00000019, O_RS|O_RT },
+ { "multu", "r\x0,s,t", 0x00000019, O_RS|O_RT },
+ { "div", "s,t", 0x0000001a, O_RS|O_RT },
+ { "div", "r\x0,s,t", 0x0000001a, O_RS|O_RT },
+ { "divu", "s,t", 0x0000001b, O_RS|O_RT },
+ { "divu", "r\x0,s,t", 0x0000001b, O_RS|O_RT },
+ { "madd", "s,t", 0x0000001c, O_RS|O_RT },
+ { "maddu", "s,t", 0x0000001d, O_RS|O_RT },
+ { "add", "d,s,t", 0x00000020, O_RD|O_RS|O_RT },
+ { "add", "s,t", 0x00000020, O_RSD|O_RT },
+ { "addu", "d,s,t", 0x00000021, O_RD|O_RS|O_RT },
+ { "addu", "s,t", 0x00000021, O_RSD|O_RT },
+ { "move", "d,s", 0x00000021, O_RD|O_RS },
+ { "sub", "d,s,t", 0x00000022, O_RD|O_RS|O_RT },
+ { "sub", "s,t", 0x00000022, O_RSD|O_RT },
+ { "neg", "d,t", 0x00000022, O_RD|O_RT },
+ { "subu", "d,s,t", 0x00000023, O_RD|O_RS|O_RT },
+ { "subu", "s,t", 0x00000023, O_RSD|O_RT },
+ { "negu", "d,t", 0x00000023, O_RD|O_RT },
+ { "and", "d,s,t", 0x00000024, O_RD|O_RS|O_RT },
+ { "and", "s,t", 0x00000024, O_RSD|O_RT },
+ { "or", "d,s,t", 0x00000025, O_RS|O_RT|O_RD },
+ { "or", "s,t", 0x00000025, O_RSD|O_RT },
+ { "xor", "d,s,t", 0x00000026, O_RS|O_RD|O_RT },
+ { "xor", "s,t", 0x00000026, O_RSD|O_RT },
+ { "nor", "d,s,t", 0x00000027, O_RS|O_RT|O_RD },
+ { "nor", "s,t", 0x00000027, O_RSD|O_RT },
+ { "slt", "d,s,t", 0x0000002a, O_RD|O_RT|O_RS },
+ { "slt", "s,t", 0x0000002a, O_RSD|O_RT},
+ { "sltu", "d,s,t", 0x0000002b, O_RD|O_RT|O_RS },
+ { "sltu", "s,t", 0x0000002b, O_RSD|O_RT },
+ { "max", "d,s,t", 0x0000002C, O_RD|O_RT|O_RS },
+ { "min", "d,s,t", 0x0000002D, O_RD|O_RT|O_RS },
+ { "msub", "s,t", 0x0000002E, O_RS|O_RT },
+ { "msubu", "s,t", 0x0000002F, O_RS|O_RT },
+
+// REGIMM: encoded by the rt field when opcode field = REGIMM.
+// 31---------26----------20-------16------------------------------0
+// |= REGIMM| | rt | |
+// ------6---------------------5------------------------------------
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 00 | BLTZ | BGEZ | BLTZL | BGEZL | --- | --- | --- | --- |
+// 01 | tgei | tgeiu | tlti | tltiu | teqi | --- | tnei | --- |
+// 10 | BLTZAL| BGEZAL|BLTZALL|BGEZALL| --- | --- | --- | --- |
+// 11 | mtsab | mtsah | --- | --- | --- | --- | --- | --- |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+ { "bltz", "s,I", 0x04000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bgez", "s,I", 0x04010000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bltzl", "s,I", 0x04020000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bgezl", "s,I", 0x04030000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bltzal", "s,I", 0x04100000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bgezal", "s,I", 0x04110000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bltzall","s,I", 0x04120000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bgezall","s,I", 0x04130000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+
+ // OPCODE 02 - J
+ { "j", "I", 0x08000000, O_I26|O_IPCA|MO_DELAY|MO_NODELAY },
+ { "b", "I", 0x08000000, O_I26|O_IPCA|MO_DELAY|MO_NODELAY },
+ // OPCODE 03 - JAL
+ { "jal", "I", 0x0c000000, O_I26|O_IPCA|MO_DELAY|MO_NODELAY },
+ // OPCODE 04 - BEQ
+ { "beq", "s,t,I", 0x10000000, O_RS|O_RT|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "beqz", "s,I", 0x10000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 05 - BNE
+ { "bne", "s,t,I", 0x14000000, O_RS|O_RT|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bnez", "s,I", 0x14000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 06 - BLEZ
+ { "blez", "s,I", 0x18000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 07 - BGTZ
+ { "bgtz", "s,I", 0x1c000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 08 - ADDI
+ { "addi", "t,s,i", 0x20000000, O_RT|O_RS|O_I16 },
+ { "addi", "s,i", 0x20000000, O_RST|O_I16 },
+ // OPCODE 09 - ADDIU
+ { "addiu", "t,s,i", 0x24000000, O_RT|O_RS|O_I16 },
+ { "addiu", "s,i", 0x24000000, O_RST|O_I16 },
+ { "li", "t,i", 0x24000000, O_RT|O_I16 },
+ // OPCODE 0A - SLTI
+ { "slti", "t,s,i", 0x28000000, O_RT|O_RS|O_I16 },
+ { "slti", "s,i", 0x28000000, O_RST|O_I16 },
+ // OPCODE 0B - SLTIU
+ { "sltiu", "t,s,i", 0x2c000000, O_RT|O_RS|O_I16 },
+ { "sltiu", "s,i", 0x2c000000, O_RST|O_I16 },
+ // OPCODE 0C - ANDI
+ { "andi", "t,s,i", 0x30000000, O_RT|O_RS|O_I16 },
+ { "andi", "s,i", 0x30000000, O_RST|O_I16 },
+ // OPCODE 0D - ORI
+ { "ori", "t,s,i", 0x34000000, O_RS|O_RT|O_I16 },
+ { "ori", "s,i", 0x34000000, O_RST|O_I16 },
+ // OPCODE 0E - XORI
+ { "xori", "t,s,i", 0x38000000, O_RT|O_RS|O_I16 },
+ { "xori", "s,i", 0x38000000, O_RST|O_I16 },
+ // OPCODE 0F - LUI
+ { "lui", "t,i", 0x3c000000, O_RT|O_I16 },
+ // OPCODE 10 - COP0
+ // OPCODE 11 - COP1
+ // OPCODE 12 - COP2
+ // OPCODE 13 - COP3
+ // OPCODE 14 - BEQL MIPS 2
+ { "beql", "s,t,I", 0x50000000, O_RS|O_RT|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "beqzl", "s,I", 0x50000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 15 - BNEZL MIPS 2
+ { "bnel", "s,t,I", 0x54000000, O_RS|O_RT|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bnezl", "s,I", 0x54000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 16 - BLEZL MIPS 2
+ { "blezl", "s,I", 0x58000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 17 - BGTZL MIPS 2
+ { "bgtzl", "s,I", 0x5c000000, O_RS|O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ // OPCODE 18 - UNDEF
+ // OPCODE 19 - UNDEF
+ // OPCODE 1A - UNDEF
+ // OPCODE 1B - UNDEF
+ // OPCODE 1C - UNDEF
+ // OPCODE 1D - UNDEF
+ // OPCODE 1E - UNDEF
+ // OPCODE 1F - UNDEF
+ // OPCODE 20 - LB
+ { "lb", "t,i(s)", 0x80000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lb", "t,(s)", 0x80000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 21 - LH
+ { "lh", "t,i(s)", 0x84000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lh", "t,(s)", 0x84000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 22 - LWL
+ { "lwl", "t,i(s)", 0x88000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lwl", "t,(s)", 0x88000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 23 - LW
+ { "lw", "t,i(s)", 0x8c000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lw", "t,(s)", 0x8c000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 24 - LBU
+ { "lbu", "t,i(s)", 0x90000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lbu", "t,(s)", 0x90000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 25 - LHU
+ { "lhu", "t,i(s)", 0x94000000, O_RT|O_I16|O_RS|MO_DELAYRT },
+ { "lhu", "t,(s)", 0x94000000, O_RT|O_RS|MO_DELAYRT },
+ // OPCODE 26 - LWR
+ { "lwr", "t,i(s)", 0x98000000, O_RT|O_I16|O_RS|MO_DELAYRT|MO_IGNORERTD },
+ { "lwr", "t,(s)", 0x98000000, O_RT|O_RS|MO_DELAYRT|MO_IGNORERTD },
+ // OPCODE 27 - UNDEF
+ // OPCODE 28 - SB
+ { "sb", "t,i(s)", 0xa0000000, O_RT|O_I16|O_RS },
+ { "sb", "t,(s)", 0xa0000000, O_RT|O_RS },
+ // OPCODE 29 - SH
+ { "sh", "t,i(s)", 0xa4000000, O_RT|O_I16|O_RS },
+ { "sh", "t,(s)", 0xa4000000, O_RT|O_RS },
+ // OPCODE 2A - SWL
+ { "swl", "t,i(s)", 0xa8000000, O_RT|O_I16|O_RS },
+ { "swl", "t,(s)", 0xa8000000, O_RT|O_RS },
+ // OPCODE 2B - SW
+ { "sw", "t,i(s)", 0xac000000, O_RT|O_I16|O_RS },
+ { "sw", "t,(s)", 0xac000000, O_RT|O_RS },
+ // OPCODE 2C - UNDEF
+ // OPCODE 2D - UNDEF
+ // OPCODE 2E - SWR
+ { "swr", "t,i(s)", 0xb8000000, O_RT|O_I16|O_RS },
+ { "swr", "t,(s)", 0xb8000000, O_RT|O_RS },
+ // OPCODE 2F - UNDEF
+ // OPCODE 30 - UNDEF
+ // OPCODE 31 - LWC1
+ // OPCODE 32 - LWC2
+ // OPCODE 33 - LWC3
+ // OPCODE 34 - UNDEF
+ // OPCODE 35 - UNDEF
+ // OPCODE 36 - UNDEF
+ // OPCODE 37 - UNDEF
+ // OPCODE 38 - UNDEF
+ // OPCODE 39 - SWC1
+ // OPCODE 3A - SWC2
+ // OPCODE 3B - SWC3
+ // OPCODE 3C - UNDEF
+ // OPCODE 3D - UNDEF
+ // OPCODE 3E - UNDEF
+ // OPCODE 3F - UNDEF
+
+
+// 31-------26------21---------------------------------------------0
+// |= COP1| rs | |
+// -----6-------5---------------------------------------------------
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 00 | MFC1 | --- | CFC1 | --- | MTC1 | --- | CTC1 | --- |
+// 01 | BC* | --- | --- | --- | --- | --- | --- | --- |
+// 10 | S* | --- | --- | --- | W* | --- | --- | --- |
+// 11 | --- | --- | --- | --- | --- | --- | --- | --- |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+ { "mfc1", "t,S", 0x44000000, O_RT|MO_FRS },
+ { "cfc1", "t,S", 0x44400000, O_RT|MO_FRS },
+ { "mtc1", "t,S", 0x44800000, O_RT|MO_FRS },
+ { "ctc1", "t,S", 0x44C00000, O_RT|MO_FRS },
+
+// 31---------21-------16------------------------------------------0
+// |= COP1BC| rt | |
+// ------11---------5-----------------------------------------------
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 00 | BC1F | BC1T | BC1FL | BC1TL | --- | --- | --- | --- |
+// 01 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 10 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 11 | --- | --- | --- | --- | --- | --- | --- | --- |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+ { "bc1f", "I", 0x45000000, O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bc1t", "I", 0x45010000, O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bc1fl", "I", 0x45020000, O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+ { "bc1tl", "I", 0x45030000, O_I16|O_IPCR|MO_DELAY|MO_NODELAY },
+
+// 31---------21------------------------------------------5--------0
+// |= COP1S | | function|
+// -----11----------------------------------------------------6-----
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 000 | add | sub | mul | div | sqrt | abs | mov | neg |
+// 001 | --- | --- | --- | --- |round.w|trunc.w|ceil.w |floor.w|
+// 010 | --- | --- | --- | --- | --- | --- | rsqrt | --- |
+// 011 | adda | suba | mula | --- | madd | msub | madda | msuba |
+// 100 | --- | --- | --- | --- | cvt.w | --- | --- | --- |
+// 101 | max | min | --- | --- | --- | --- | --- | --- |
+// 110 | c.f | c.un | c.eq | c.ueq |c.(o)lt| c.ult |c.(o)le| c.ule |
+// 110 | c.sf | c.ngle| c.seq | c.ngl | c.lt | c.nge | c.le | c.ngt |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+ { "add.s", "D,S,T", 0x46000000, MO_FRT|MO_FRD|MO_FRS },
+ { "add.s", "S,T", 0x46000000, MO_FRT|MO_FRSD },
+ { "sub.s", "D,S,T", 0x46000001, MO_FRT|MO_FRD|MO_FRS },
+ { "sub.s", "S,T", 0x46000001, MO_FRT|MO_FRSD },
+ { "mul.s", "D,S,T", 0x46000002, MO_FRT|MO_FRD|MO_FRS },
+ { "mul.s", "S,T", 0x46000002, MO_FRT|MO_FRSD },
+ { "div.s", "D,S,T", 0x46000003, MO_FRT|MO_FRD|MO_FRS },
+ { "div.s", "S,T", 0x46000003, MO_FRT|MO_FRSD },
+ { "sqrt.s", "D,S", 0x46000004, MO_FRD|MO_FRS },
+ { "abs.s", "D,S", 0x46000005, MO_FRD|MO_FRS },
+ { "mov.s", "D,S", 0x46000006, MO_FRD|MO_FRS },
+ { "neg.s", "D,S", 0x46000007, MO_FRD|MO_FRS },
+ { "round.w.s", "D,S", 0x4600000C, MO_FRD|MO_FRS },
+ { "trunc.w.s", "D,S", 0x4600000D, MO_FRD|MO_FRS },
+ { "ceil.w.s", "D,S", 0x4600000E, MO_FRD|MO_FRS },
+ { "floor.w.s", "D,S", 0x4600000F, MO_FRD|MO_FRS },
+ { "cvt.w.s", "D,S", 0x46000024, MO_FRD|MO_FRS },
+ { "c.f.s", "S,T", 0x46000030, MO_FRT|MO_FRS },
+ { "c.un.s", "S,T", 0x46000031, MO_FRT|MO_FRS },
+ { "c.eq.s", "S,T", 0x46000032, MO_FRT|MO_FRS },
+ { "c.ueq.s", "S,T", 0x46000033, MO_FRT|MO_FRS },
+ { "c.olt.s", "S,T", 0x46000034, MO_FRT|MO_FRS },
+ { "c.ult.s", "S,T", 0x46000035, MO_FRT|MO_FRS },
+ { "c.ole.s", "S,T", 0x46000036, MO_FRT|MO_FRS },
+ { "c.ule.s", "S,T", 0x46000037, MO_FRT|MO_FRS },
+ { "c.sf.s", "S,T", 0x46000038, MO_FRT|MO_FRS },
+ { "c.ngle.s", "S,T", 0x46000039, MO_FRT|MO_FRS },
+ { "c.seq.s", "S,T", 0x4600003A, MO_FRT|MO_FRS },
+ { "c.ngl.s", "S,T", 0x4600003B, MO_FRT|MO_FRS },
+ { "c.lt.s", "S,T", 0x4600003C, MO_FRT|MO_FRS },
+ { "c.nge.s", "S,T", 0x4600003D, MO_FRT|MO_FRS },
+ { "c.le.s", "S,T", 0x4600003E, MO_FRT|MO_FRS },
+ { "c.ngt.s", "S,T", 0x4600003F, MO_FRT|MO_FRS },
+
+// COP1W: encoded by function field
+// 31---------21------------------------------------------5--------0
+// |= COP1W | | function|
+// -----11----------------------------------------------------6-----
+// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
+// 000 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 001 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 010 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 011 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 100 |cvt.s.w| --- | --- | --- | --- | --- | --- | --- |
+// 101 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 110 | --- | --- | --- | --- | --- | --- | --- | --- |
+// 110 | --- | --- | --- | --- | --- | --- | --- | --- |
+// hi |-------|-------|-------|-------|-------|-------|-------|-------|
+ { "cvt.s.w", "D,S", 0x46800020, MO_FRD|MO_FRS },
+
+
+
+
+ // END
+ { NULL, NULL, 0, 0 }
+};
+
+}
\ No newline at end of file
diff --git a/Core/MIPS/MIPSAsmTables.h b/Core/MIPS/MIPSAsmTables.h
new file mode 100644
index 0000000000..2e8c068c31
--- /dev/null
+++ b/Core/MIPS/MIPSAsmTables.h
@@ -0,0 +1,47 @@
+#pragma once
+
+namespace MIPSAsm
+{
+
+typedef struct {
+ char* name;
+ char* encoding;
+ int destencoding;
+ int flags;
+} tMipsOpcode;
+
+typedef struct {
+ char* name;
+ short num;
+ short len;
+} tMipsRegister;
+
+#define O_RS 0x00000001 // source reg
+#define O_RT 0x00000002 // target reg
+#define O_RD 0x00000004 // dest reg
+#define O_I16 0x00000008 // 16 bit immediate
+#define O_I20 0x00000010 // 16 bit immediate
+#define O_IPCA 0x00000020 // pc >> 2
+#define O_IPCR 0x00000080 // PC, -> difference >> 2
+#define O_I26 0x00000200 // 26 bit immediate
+#define O_I5 0x00000400 // 5 bit immediate
+#define O_RSD 0x00000800 // rs = rd
+#define O_RST 0x00001000 // rs = rt
+#define O_RDT 0x00002000 // rd = rt
+#define MO_DELAY 0x00004000 // delay slot follows
+#define MO_NODELAY 0x00008000 // can't be in a delay slot
+#define MO_DELAYRT 0x00010000 // rt won't be available for one instruction
+#define MO_IGNORERTD 0x00020000 // don't care for rt delay
+
+#define MO_FRS 0x00040000 // float rs
+#define MO_FRD 0x00080000 // float rd
+#define MO_FRT 0x00100000 // float rt
+#define MO_FRSD 0x00200000 // float rs + rd
+#define MO_FRST 0x00400000 // float rs + rt
+#define MO_FRDT 0x00800000 // float rt + rd
+
+extern const tMipsRegister MipsRegister[];
+extern const tMipsRegister MipsFloatRegister[];
+extern const tMipsOpcode MipsOpcodes[];
+
+}
\ No newline at end of file
diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp
index bb6e938868..4a87d5bf06 100644
--- a/Windows/Debugger/CtrlDisAsmView.cpp
+++ b/Windows/Debugger/CtrlDisAsmView.cpp
@@ -7,6 +7,7 @@
#include "../WndMainWindow.h"
#include "../InputBox.h"
+#include "Core/MIPS/MIPSAsm.h"
#include "Core/Config.h"
#include "CtrlDisAsmView.h"
#include "Debugger_MemoryDlg.h"
@@ -284,6 +285,25 @@ void CtrlDisAsmView::parseDisasm(const char* disasm, char* opcode, char* argumen
*arguments = 0;
}
+void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText)
+{
+ char op[256];
+ u32 encoded;
+
+ bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,"Assemble opcode",(char*)defaultText.c_str(),op);
+ if (result == false) return;
+
+ result = MIPSAsm::MipsAssembleOpcode(op,debugger,address,encoded);
+ if (result == true)
+ {
+ Memory::Write_U32(encoded,address);
+ MIPSComp::jit->ClearCacheAt(address);
+ redraw();
+ } else {
+ MessageBox(wnd,"Couldn''t assemble.","Error",MB_OK);
+ }
+}
+
void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
{
if (!debugger->isAlive()) return;
@@ -498,6 +518,10 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam)
case 'x':
disassembleToFile();
break;
+ case 'a':
+ controlHeld = false;
+ assembleOpcode(curAddress,"");
+ break;
case 'g':
{
u32 addr;
@@ -691,6 +715,9 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
toggleBreakpoint();
redraw();
break;
+ case ID_DISASM_ASSEMBLE:
+ assembleOpcode(curAddress,"");
+ break;
case ID_DISASM_COPYINSTRUCTIONDISASM:
{
int space = 256 * (selectRangeEnd - selectRangeStart) / instructionSize;
diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h
index 59b2b5f8be..01403d6055 100644
--- a/Windows/Debugger/CtrlDisAsmView.h
+++ b/Windows/Debugger/CtrlDisAsmView.h
@@ -71,6 +71,7 @@ class CtrlDisAsmView
bool searching;
bool dontRedraw;
+ void assembleOpcode(u32 address, std::string defaultText);
void disassembleToFile();
void search(bool continueSearch);
void followBranch();
diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc
index 4eebf6a5f1..652c424c6f 100644
Binary files a/Windows/ppsspp.rc and b/Windows/ppsspp.rc differ
diff --git a/Windows/resource.h b/Windows/resource.h
index d76aa346ff..c9eb274b5e 100644
Binary files a/Windows/resource.h and b/Windows/resource.h differ