|
@@ -3,13 +3,17 @@ package de.nplusc.izc.senabitwiggler;
|
|
|
import com.google.common.primitives.Ints;
|
|
|
import com.google.common.primitives.Shorts;
|
|
|
|
|
|
+import java.io.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
interface OpCodeMangler
|
|
|
{
|
|
|
String mangleOpCode(short modifier, short[] opcode, int startAddress);
|
|
|
}
|
|
|
|
|
|
public class XAPDisAsm {
|
|
|
- public static OpCodeMangler[] manglers = new OpCodeMangler[255];
|
|
|
+ public static OpCodeMangler[] manglers = new OpCodeMangler[256];
|
|
|
static {
|
|
|
OpCodeMangler invalid = (modifier,opcode,address)->{
|
|
|
String badOpCode ="";
|
|
@@ -36,12 +40,15 @@ public class XAPDisAsm {
|
|
|
for(int i=0;i<opcode.length;i++)
|
|
|
{
|
|
|
byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
|
|
|
+ System.out.println(opcodeWord[0]);
|
|
|
opcodeValues[i]=opcodeWord[0];
|
|
|
opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
|
|
|
}
|
|
|
+ String rawValue = EntryPoint.bytesToHex(opcodeValues);
|
|
|
+ System.out.println(rawValue);
|
|
|
|
|
|
- int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
- int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
+ int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawValue);
|
|
|
+ int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(rawValue);
|
|
|
String register = "";
|
|
|
|
|
|
String value = "";
|
|
@@ -140,8 +147,9 @@ public class XAPDisAsm {
|
|
|
opcodeValues[i]=opcodeWord[0];
|
|
|
opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
|
|
|
}
|
|
|
-
|
|
|
- int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
+ String rawVal = EntryPoint.bytesToHex(opcodeValues);
|
|
|
+ System.out.println(rawVal);
|
|
|
+ int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawVal);
|
|
|
int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
String register = "";
|
|
|
|
|
@@ -226,6 +234,70 @@ public class XAPDisAsm {
|
|
|
OpCodeMangler bsr = GetBraMangler("bsr",(short)0x9c,false);
|
|
|
|
|
|
|
|
|
+ OpCodeMangler xmult = GetModifiedMangler("smult","umult",(short)0x90);
|
|
|
+ OpCodeMangler xdiv = GetModifiedMangler("sdiv","udiv",(short)0x94);
|
|
|
+ OpCodeMangler xsr = GetModifiedMangler("asr","lsr",(short)0xA4);
|
|
|
+ OpCodeMangler xsl = GetModifiedMangler("asl","lsl",(short)0xA0);
|
|
|
+
|
|
|
+
|
|
|
+ OpCodeMangler enterlleavel = (modifier,opcode,address)->{
|
|
|
+ byte[] opcodeValues = new byte[opcode.length];
|
|
|
+ short opcodeReal = 0x00; // only checking lower byte though
|
|
|
+ for(int i=0;i<opcode.length;i++)
|
|
|
+ {
|
|
|
+ byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
|
|
|
+ opcodeValues[i]=opcodeWord[0];
|
|
|
+ opcodeReal=(short)((opcode[i]-0x00)&0xFF); //stompy stomp, only keeps the last
|
|
|
+ }
|
|
|
+
|
|
|
+ int valueStack = XAPDisAsmGeneratedCode.unsignedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
+ String label = "";
|
|
|
+
|
|
|
+ String value = "";
|
|
|
+ switch(opcodeReal)
|
|
|
+ {
|
|
|
+ case 0x0b:
|
|
|
+ label="enterl";
|
|
|
+ break;
|
|
|
+ case 0x0f:
|
|
|
+ label="leavel";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return addressToString(address)+":"+label+":"+ParamManglerImmediate(valueStack);
|
|
|
+ };
|
|
|
+
|
|
|
+ OpCodeMangler bxx = (modifier,opcode,address)->{
|
|
|
+ byte[] opcodeValues = new byte[opcode.length];
|
|
|
+ short opcodeReal = 0x00; // only checking lower byte though
|
|
|
+ for(int i=0;i<opcode.length;i++)
|
|
|
+ {
|
|
|
+ byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
|
|
|
+ opcodeValues[i]=opcodeWord[0];
|
|
|
+ opcodeReal=(short)((opcode[i]-0x00)&0xFF); //stompy stomp, only keeps the last
|
|
|
+ }
|
|
|
+
|
|
|
+ int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
+ int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(EntryPoint.bytesToHex(opcodeValues));
|
|
|
+ String label = "";
|
|
|
+
|
|
|
+ String value = "";
|
|
|
+ switch(opcodeReal)
|
|
|
+ {
|
|
|
+ case 0x20:
|
|
|
+ label="bgt";
|
|
|
+ value = ParamManglerAddress(valueSigned);
|
|
|
+ break;
|
|
|
+ case 0x2c:
|
|
|
+ label="bcz";
|
|
|
+ value = ParamManglerAddress(valueSigned);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ String potentialTargetAddress=addressToString(address+opcode.length-1+valueSigned);
|
|
|
+ return addressToString(address)+":"+label+":"+value+"; Target="+potentialTargetAddress+" OR "+addressToString(valueUnsigned);
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -246,11 +318,11 @@ public class XAPDisAsm {
|
|
|
return addressToString(address)+": Modifier, this should not be visible at all in the disassembly!!!!!, should not happen";
|
|
|
};
|
|
|
manglers[0xa]=st;
|
|
|
- manglers[0xb]=invalid;
|
|
|
+ manglers[0xb]=enterlleavel;
|
|
|
manglers[0xc]=invalid;
|
|
|
manglers[0xd]=invalid;
|
|
|
- manglers[0xe]=ld; //VERIFY
|
|
|
- manglers[0xf]=invalid;
|
|
|
+ manglers[0xe]=ld;
|
|
|
+ manglers[0xf]=enterlleavel;
|
|
|
|
|
|
|
|
|
manglers[0x10]=ld;
|
|
@@ -270,7 +342,7 @@ public class XAPDisAsm {
|
|
|
manglers[0x1e]=ld;
|
|
|
manglers[0x1f]=ld;
|
|
|
|
|
|
- manglers[0x20]=invalid; //BGT
|
|
|
+ manglers[0x20]=bxx; //BGT
|
|
|
manglers[0x21]=st;
|
|
|
manglers[0x22]=st;
|
|
|
manglers[0x23]=st;
|
|
@@ -282,7 +354,7 @@ public class XAPDisAsm {
|
|
|
manglers[0x29]=st;
|
|
|
manglers[0x2a]=st;
|
|
|
manglers[0x2b]=st;
|
|
|
- manglers[0x2c]=invalid; //BCZ
|
|
|
+ manglers[0x2c]=bxx; //BCZ
|
|
|
manglers[0x2d]=st;
|
|
|
manglers[0x2e]=st;
|
|
|
manglers[0x2f]=st;
|
|
@@ -392,14 +464,14 @@ public class XAPDisAsm {
|
|
|
manglers[0x8e]=cmp;
|
|
|
manglers[0x8f]=cmp;
|
|
|
|
|
|
- manglers[0x90]=invalid; //XXX
|
|
|
- manglers[0x91]=invalid;
|
|
|
- manglers[0x92]=invalid;
|
|
|
- manglers[0x93]=invalid;
|
|
|
- manglers[0x94]=invalid;
|
|
|
- manglers[0x95]=invalid;
|
|
|
- manglers[0x96]=invalid;
|
|
|
- manglers[0x97]=invalid;
|
|
|
+ manglers[0x90]=xmult;
|
|
|
+ manglers[0x91]=xmult;
|
|
|
+ manglers[0x92]=xmult;
|
|
|
+ manglers[0x93]=xmult;
|
|
|
+ manglers[0x94]=xdiv;
|
|
|
+ manglers[0x95]=xdiv;
|
|
|
+ manglers[0x96]=xdiv;
|
|
|
+ manglers[0x97]=xdiv;
|
|
|
manglers[0x98]=invalid;
|
|
|
manglers[0x99]=tst;
|
|
|
manglers[0x9a]=tst;
|
|
@@ -412,7 +484,22 @@ public class XAPDisAsm {
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+ manglers[0xa0]=xsl;
|
|
|
+ manglers[0xa1]=xsl;
|
|
|
+ manglers[0xa2]=xsl;
|
|
|
+ manglers[0xa3]=xsl;
|
|
|
+ manglers[0xa4]=xsr;
|
|
|
+ manglers[0xa5]=xsr;
|
|
|
+ manglers[0xa6]=xsr;
|
|
|
+ manglers[0xa7]=xsr;
|
|
|
+ manglers[0xa8]=invalid;
|
|
|
+ manglers[0xa9]=invalid;
|
|
|
+ manglers[0xaa]=invalid;
|
|
|
+ manglers[0xab]=invalid;
|
|
|
+ manglers[0xac]=invalid;
|
|
|
+ manglers[0xad]=invalid;
|
|
|
+ manglers[0xae]=invalid;
|
|
|
+ manglers[0xaf]=invalid;
|
|
|
|
|
|
|
|
|
|
|
@@ -504,7 +591,7 @@ public class XAPDisAsm {
|
|
|
manglers[0xff]=bcs;
|
|
|
}
|
|
|
|
|
|
- static OpCodeMangler GetModifiedMangler(String opcodeLabel, String OpcodeLabelModified, short opcodeBase, boolean bra_specialcase)
|
|
|
+ static OpCodeMangler GetModifiedMangler(String opcodeLabel, String OpcodeLabelModified, short opcodeBase)
|
|
|
{
|
|
|
return (modifier,opcode,address)->{
|
|
|
boolean modified = modifier==0x09;
|
|
@@ -525,28 +612,21 @@ public class XAPDisAsm {
|
|
|
String value = "";
|
|
|
switch(opcodeReal)
|
|
|
{
|
|
|
+ case 0x00:
|
|
|
+ value = ParamManglerImmediate(valueUnsigned);
|
|
|
+ break;
|
|
|
case 0x01:
|
|
|
- register="AH";
|
|
|
- value = ParamManglerAddress(valueSigned);
|
|
|
+ value = ParamManglerAddress(valueUnsigned);
|
|
|
break;
|
|
|
case 0x02:
|
|
|
- register="AH";
|
|
|
value = ParamManglerIndirectX(valueSigned);
|
|
|
break;
|
|
|
case 0x03:
|
|
|
- register="AH";
|
|
|
value = ParamManglerIndirectY(valueSigned);
|
|
|
break;
|
|
|
}
|
|
|
- String potentialTargetAddress=addressToString(address+opcode.length-1+valueSigned);
|
|
|
-
|
|
|
- if(bra_specialcase&&opcodeReal==0x02&&address==0)
|
|
|
- {
|
|
|
- return addressToString(address)+":rts";
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
- return addressToString(address)+":"+opcodeLabel+":"+value+"; Target="+potentialTargetAddress;
|
|
|
+ return addressToString(address)+":"+(modified?OpcodeLabelModified:opcodeLabel)+":"+value;
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -600,7 +680,7 @@ public class XAPDisAsm {
|
|
|
}
|
|
|
|
|
|
|
|
|
- return addressToString(address)+":"+opcodeLabel+":"+value+"; Target="+potentialTargetAddress;
|
|
|
+ return addressToString(address)+":"+opcodeLabel+":"+value+"; Target="+potentialTargetAddress+" OR "+addressToString(valueUnsigned);
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -733,7 +813,73 @@ public class XAPDisAsm {
|
|
|
|
|
|
|
|
|
|
|
|
+ public static void Disassemble(String in, String out)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ RandomAccessFile f = new RandomAccessFile(in,"r");
|
|
|
+ PrintStream disassembled = new PrintStream(new FileOutputStream(out));
|
|
|
+
|
|
|
+ long assemblyLength = f.length()/2;
|
|
|
+
|
|
|
+ int baseAddressLastOpcode=0;
|
|
|
+ List<Short> opcodeHoldingBay = new ArrayList<>(5);
|
|
|
+
|
|
|
+ for(int i=0;i<assemblyLength;i++)
|
|
|
+ {
|
|
|
+ Short word = f.readShort();
|
|
|
+ System.out.println("READ:"+ (word&0xff));
|
|
|
+ opcodeHoldingBay.add(word);
|
|
|
+ if((word&0xFF)!=0)
|
|
|
+ {
|
|
|
+ if((word&0xFF)!=0x09)//skip modifier
|
|
|
+ {
|
|
|
+ short[] opcode;
|
|
|
+ short modifier=0x00;
|
|
|
+ if(opcodeHoldingBay.get(0)==0x09) //modifier
|
|
|
+ {
|
|
|
+ modifier = 0x09;
|
|
|
+ opcode = new short[opcodeHoldingBay.size()-1];
|
|
|
+ for(int j=1;j<opcodeHoldingBay.size();j++)
|
|
|
+ {
|
|
|
+ opcode[j-1]=opcodeHoldingBay.get(j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ opcode = new short[opcodeHoldingBay.size()];
|
|
|
+ for(int j=0;j<opcodeHoldingBay.size();j++)
|
|
|
+ {
|
|
|
+ opcode[j]=opcodeHoldingBay.get(j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println("Mangling Opcode with length"+opcode.length);
|
|
|
+ disassembled.println(manglers[word&0xff].mangleOpCode(modifier,opcode,baseAddressLastOpcode));
|
|
|
+ baseAddressLastOpcode+=opcodeHoldingBay.size();
|
|
|
+ opcodeHoldingBay.clear();
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(word==0x00)//nop
|
|
|
+ {
|
|
|
+ disassembled.println(manglers[0].mangleOpCode((short)0x00, new short[]{(short)0x00}, baseAddressLastOpcode));
|
|
|
+ opcodeHoldingBay.clear();
|
|
|
+ baseAddressLastOpcode++;
|
|
|
+ }
|
|
|
+ System.out.println("VALUE");
|
|
|
+ //opcodeHoldingBay.add(word);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|