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.HashMap; import java.util.List; interface OpCodeMangler { String mangleOpCode(short modifier, short[] opcode, int startAddress); } public class XAPDisAsm { private static HashMap labels = new HashMap<>(); private static OpCodeMangler brxl = (modifier,opcode,address)->{ return OpcodeAddressRangeToString(address,1)+": brxl"; }; private static OpCodeMangler invalid = (modifier,opcode,address)->{ String badOpCode =""; boolean modified=false; if(modifier!=0x00) { modified=true; badOpCode += (Utils.bytesToHex(Shorts.toByteArray(modifier))); }; for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; byte opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; byte opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; short opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; short opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { return invalid.mangleOpCode(modifier,opcode,address); }; return OpcodeAddressRangeToString(address,opcode.length)+": nop"; }; manglers[0x1]=invalid; manglers[0x2]=invalid; manglers[0x3]=invalid; manglers[0x4]=invalid; manglers[0x5]=invalid; manglers[0x6]=invalid; manglers[0x7]=invalid; manglers[0x8]=invalid; manglers[0x9]=(modifier,opcode,address)->{ return addressToString(address)+": Modifier, this should not be visible at all in the disassembly!!!!!, should not happen"; }; manglers[0xa]=st; manglers[0xb]=enterlleavel; manglers[0xc]=invalid; manglers[0xd]=invalid; manglers[0xe]=ld; manglers[0xf]=enterlleavel; manglers[0x10]=ld; manglers[0x11]=ld; manglers[0x12]=ld; manglers[0x13]=ld; manglers[0x14]=ld; manglers[0x15]=ld; manglers[0x16]=ld; manglers[0x17]=ld; manglers[0x18]=ld; manglers[0x19]=ld; manglers[0x1a]=ld; manglers[0x1b]=ld; manglers[0x1c]=ld; manglers[0x1d]=ld; manglers[0x1e]=ld; manglers[0x1f]=ld; manglers[0x20]=bxx; //BGT manglers[0x21]=st; manglers[0x22]=st; manglers[0x23]=st; manglers[0x24]=bxx;//bge manglers[0x25]=st; manglers[0x26]=st; manglers[0x27]=st; manglers[0x28]=bxx; //ble manglers[0x29]=st; manglers[0x2a]=st; manglers[0x2b]=st; manglers[0x2c]=bxx; //BCZ manglers[0x2d]=st; manglers[0x2e]=st; manglers[0x2f]=st; manglers[0x30]=add; manglers[0x31]=add; manglers[0x32]=add; manglers[0x33]=add; manglers[0x34]=add; manglers[0x35]=add; manglers[0x36]=add; manglers[0x37]=add; manglers[0x38]=add; manglers[0x39]=add; manglers[0x3a]=add; manglers[0x3b]=add; manglers[0x3c]=add; manglers[0x3d]=add; manglers[0x3e]=add; manglers[0x3f]=add; manglers[0x40]=addc; manglers[0x41]=addc; manglers[0x42]=addc; manglers[0x43]=addc; manglers[0x44]=addc; manglers[0x45]=addc; manglers[0x46]=addc; manglers[0x47]=addc; manglers[0x48]=addc; manglers[0x49]=addc; manglers[0x4a]=addc; manglers[0x4b]=addc; manglers[0x4c]=addc; manglers[0x4d]=addc; manglers[0x4e]=addc; manglers[0x4f]=addc; manglers[0x50]=sub; manglers[0x51]=sub; manglers[0x52]=sub; manglers[0x53]=sub; manglers[0x54]=sub; manglers[0x55]=sub; manglers[0x56]=sub; manglers[0x57]=sub; manglers[0x58]=sub; manglers[0x59]=sub; manglers[0x5a]=sub; manglers[0x5b]=sub; manglers[0x5c]=sub; manglers[0x5d]=sub; manglers[0x5e]=sub; manglers[0x5f]=sub; manglers[0x60]=subc; manglers[0x61]=subc; manglers[0x62]=subc; manglers[0x63]=subc; manglers[0x64]=subc; manglers[0x65]=subc; manglers[0x66]=subc; manglers[0x67]=subc; manglers[0x68]=subc; manglers[0x69]=subc; manglers[0x6a]=subc; manglers[0x6b]=subc; manglers[0x6c]=subc; manglers[0x6d]=subc; manglers[0x6e]=subc; manglers[0x6f]=subc; manglers[0x70]=nadd; manglers[0x71]=nadd; manglers[0x72]=nadd; manglers[0x73]=nadd; manglers[0x74]=nadd; manglers[0x75]=nadd; manglers[0x76]=nadd; manglers[0x77]=nadd; manglers[0x78]=nadd; manglers[0x79]=nadd; manglers[0x7a]=nadd; manglers[0x7b]=nadd; manglers[0x7c]=nadd; manglers[0x7d]=nadd; manglers[0x7e]=nadd; manglers[0x7f]=nadd; manglers[0x80]=cmp; manglers[0x81]=cmp; manglers[0x82]=cmp; manglers[0x83]=cmp; manglers[0x84]=cmp; manglers[0x85]=cmp; manglers[0x86]=cmp; manglers[0x87]=cmp; manglers[0x88]=cmp; manglers[0x89]=cmp; manglers[0x8a]=cmp; manglers[0x8b]=cmp; manglers[0x8c]=cmp; manglers[0x8d]=cmp; manglers[0x8e]=cmp; manglers[0x8f]=cmp; 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]=tst; manglers[0x99]=tst; manglers[0x9a]=tst; manglers[0x9b]=tst; manglers[0x9c]=bsr; manglers[0x9d]=bsr; manglers[0x9e]=bsr; manglers[0x9f]=bsr; //0xax 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; manglers[0xb0]=or; manglers[0xb1]=or; manglers[0xb2]=or; manglers[0xb3]=or; manglers[0xb4]=or; manglers[0xb5]=or; manglers[0xb6]=or; manglers[0xb7]=or; manglers[0xb8]=or; manglers[0xb9]=or; manglers[0xba]=or; manglers[0xbb]=or; manglers[0xbc]=or; manglers[0xbd]=or; manglers[0xbe]=or; manglers[0xbf]=or; manglers[0xc0]=and; manglers[0xc1]=and; manglers[0xc2]=and; manglers[0xc3]=and; manglers[0xc4]=and; manglers[0xc5]=and; manglers[0xc6]=and; manglers[0xc7]=and; manglers[0xc8]=and; manglers[0xc9]=and; manglers[0xca]=and; manglers[0xcb]=and; manglers[0xcc]=and; manglers[0xcd]=and; manglers[0xce]=and; manglers[0xcf]=and; manglers[0xd0]=xor; manglers[0xd1]=xor; manglers[0xd2]=xor; manglers[0xd3]=xor; manglers[0xd4]=xor; manglers[0xd5]=xor; manglers[0xd6]=xor; manglers[0xd7]=xor; manglers[0xd8]=xor; manglers[0xd9]=xor; manglers[0xda]=xor; manglers[0xdb]=xor; manglers[0xdc]=xor; manglers[0xdd]=xor; manglers[0xde]=xor; manglers[0xdf]=xor; manglers[0xe0]=bra; manglers[0xe1]=bra; manglers[0xe2]=bra; manglers[0xe3]=bra; manglers[0xe4]=blt; manglers[0xe5]=blt; manglers[0xe6]=blt; manglers[0xe7]=blt; manglers[0xe8]=bxx; // bpl manglers[0xe9]=invalid; manglers[0xea]=invalid; manglers[0xeb]=invalid; manglers[0xec]=bxx; //bmi manglers[0xed]=invalid; manglers[0xee]=invalid; manglers[0xef]=invalid; manglers[0xf0]=bne; manglers[0xf1]=bne; manglers[0xf2]=bne; manglers[0xf3]=bne; manglers[0xf4]=beq; manglers[0xf5]=beq; manglers[0xf6]=beq; manglers[0xf7]=beq; manglers[0xf8]=bcc; manglers[0xf9]=bcc; manglers[0xfa]=bcc; manglers[0xfb]=bcc; manglers[0xfc]=bcs; manglers[0xfd]=bcs; manglers[0xfe]=bcs; manglers[0xff]=bcs; } static OpCodeMangler GetModifiedMangler(String opcodeLabel, String OpcodeLabelModified, short opcodeBase) { return (modifier,opcode,address)->{ boolean modified = modifier==0x09; byte[] opcodeValues = new byte[opcode.length]; short opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; short opcodeReal = 0x00; // only checking lower byte though for(int i=0;i{ if(modifier!=0x00) { //return invalid.mangleOpCode(modifier,opcode,address); }; byte[] opcodeValues = new byte[opcode.length]; short opcodeReal = 0x00; // only checking lower byte though for(int i=0;i1) { return startaddr+ "---"+ addressToString(address+(opcodelen-1)); } else return startaddr; } private static String ParamManglerImmediate(int number) { return "#"+number; } private static String ParamManglerConstAddr(int number) { String addr = addressToString(number); if(labels.containsKey(addr)) { addr = addr+"("+labels.get(addr)+")"; } return addr; } private static String ParamManglerAddress(int number) { return "@"+number; } private static String ParamManglerIndirectX(int number) { return "@("+number+",X)"; } private static String ParamManglerIndirectY(int number) { return "@("+number+",Y)"; } public static void Disassemble(String in, String out) { try { RandomAccessFile f = new RandomAccessFile(in,"r"); PrintStream disassembled = new PrintStream(new FileOutputStream(out)); String mapfilepath = in+".sbwmap"; if(new File(mapfilepath).exists()) { RandomAccessFile mapfile = new RandomAccessFile(mapfilepath,"r"); String line = mapfile.readLine(); while(line !=null) { if(line.equals("")) { line = mapfile.readLine(); continue; } String[] entry = line.split(":"); labels.put(entry[0].toLowerCase(),entry[1]); line = mapfile.readLine(); } } long assemblyLength = f.length()/2; int baseAddressLastOpcode=0; List opcodeHoldingBay = new ArrayList<>(5); for(int i=0;i