XAPDisAsm.java 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. package de.nplusc.izc.senabitwiggler;
  2. import com.google.common.primitives.Ints;
  3. import com.google.common.primitives.Shorts;
  4. import java.io.*;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. interface OpCodeMangler
  9. {
  10. String mangleOpCode(short modifier, short[] opcode, int startAddress);
  11. }
  12. public class XAPDisAsm {
  13. private static HashMap<String,String> labels = new HashMap<>();
  14. private static OpCodeMangler brxl = (modifier,opcode,address)->{
  15. return OpcodeAddressRangeToString(address,1)+": brxl";
  16. };
  17. private static OpCodeMangler invalid = (modifier,opcode,address)->{
  18. String badOpCode ="";
  19. boolean modified=false;
  20. if(modifier!=0x00)
  21. {
  22. modified=true;
  23. badOpCode += (Utils.bytesToHex(Shorts.toByteArray(modifier)));
  24. };
  25. for(int i=0;i<opcode.length;i++)
  26. {
  27. badOpCode += (Utils.bytesToHex(Shorts.toByteArray(opcode[i])));
  28. }
  29. String invalidCode = OpcodeAddressRangeToString(address,opcode.length+(modified?1:0))+":Invalid OpCode: "+badOpCode;
  30. System.err.println(invalidCode);
  31. return invalidCode;
  32. };
  33. public static OpCodeMangler[] manglers = new OpCodeMangler[256];
  34. static {
  35. OpCodeMangler ld = (modifier,opcode,address)->{
  36. if(modifier!=0x00)
  37. {
  38. //return invalid.mangleOpCode(modifier,opcode,address);
  39. };
  40. byte[] opcodeValues = new byte[opcode.length];
  41. byte opcodeReal = 0x00; // only checking lower byte though
  42. for(int i=0;i<opcode.length;i++)
  43. {
  44. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  45. if(EntryPoint.verbose)System.out.println(opcodeWord[0]);
  46. opcodeValues[i]=opcodeWord[0];
  47. opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
  48. }
  49. String rawValue = Utils.bytesToHex(opcodeValues);
  50. if(EntryPoint.verbose)System.out.println(rawValue);
  51. int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawValue);
  52. int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(rawValue);
  53. String register = "";
  54. String value = "";
  55. switch(opcodeReal)
  56. {
  57. case 0x0e:
  58. register="xh";
  59. value = ParamManglerIndirectY(valueSigned);
  60. break;
  61. case 0x10:
  62. register="AH";
  63. value = ParamManglerImmediate(valueUnsigned);
  64. break;
  65. case 0x11:
  66. register="AH";
  67. value = ParamManglerAddress(valueUnsigned);
  68. break;
  69. case 0x12:
  70. register="AH";
  71. value = ParamManglerIndirectX(valueSigned);
  72. break;
  73. case 0x13:
  74. register="AH";
  75. value = ParamManglerIndirectY(valueSigned);
  76. break;
  77. case 0x14:
  78. register="AL";
  79. value = ParamManglerImmediate(valueUnsigned);
  80. break;
  81. case 0x15:
  82. register="AL";
  83. value = ParamManglerAddress(valueUnsigned);
  84. break;
  85. case 0x16:
  86. register="AL";
  87. value = ParamManglerIndirectX(valueSigned);
  88. break;
  89. case 0x17:
  90. register="AL";
  91. value = ParamManglerIndirectY(valueSigned);
  92. break;
  93. case 0x18:
  94. register="X";
  95. value = ParamManglerImmediate(valueUnsigned);
  96. break;
  97. case 0x19:
  98. register="X";
  99. value = ParamManglerAddress(valueUnsigned);
  100. break;
  101. case 0x1a:
  102. register="X";
  103. value = ParamManglerIndirectX(valueSigned);
  104. break;
  105. case 0x1b:
  106. register="X";
  107. value = ParamManglerIndirectY(valueSigned);
  108. break;
  109. case 0x1c:
  110. register="Y";
  111. value = ParamManglerImmediate(valueUnsigned);
  112. break;
  113. case 0x1d:
  114. register="Y";
  115. value = ParamManglerAddress(valueUnsigned);
  116. break;
  117. case 0x1e:
  118. register="Y";
  119. value = ParamManglerIndirectX(valueSigned);
  120. break;
  121. case 0x1f:
  122. register="Y";
  123. value = ParamManglerIndirectY(valueSigned);
  124. break;
  125. }
  126. return OpcodeAddressRangeToString(address,opcode.length)+":ld: "+register+" "+value;
  127. };
  128. OpCodeMangler st = (modifier,opcode,address)->{
  129. if(modifier!=0x00)
  130. {
  131. //return invalid.mangleOpCode(modifier,opcode,address);
  132. };
  133. byte[] opcodeValues = new byte[opcode.length];
  134. byte opcodeReal = 0x00; // only checking lower byte though
  135. for(int i=0;i<opcode.length;i++)
  136. {
  137. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  138. opcodeValues[i]=opcodeWord[0];
  139. opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
  140. }
  141. String rawVal = Utils.bytesToHex(opcodeValues);
  142. if(EntryPoint.verbose)System.out.println(rawVal);
  143. int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawVal);
  144. int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
  145. String register = "";
  146. String value = "";
  147. switch(opcodeReal)
  148. {
  149. case 0x0a:
  150. register="xh";
  151. value = ParamManglerIndirectY(valueSigned);
  152. break;
  153. case 0x21:
  154. register="AH";
  155. value = ParamManglerAddress(valueUnsigned);
  156. break;
  157. case 0x22:
  158. register="AH";
  159. value = ParamManglerIndirectX(valueSigned);
  160. break;
  161. case 0x23:
  162. register="AH";
  163. value = ParamManglerIndirectY(valueSigned);
  164. break;
  165. case 0x25:
  166. register="AL";
  167. value = ParamManglerAddress(valueUnsigned);
  168. break;
  169. case 0x26:
  170. register="AL";
  171. value = ParamManglerIndirectX(valueSigned);
  172. break;
  173. case 0x27:
  174. register="AL";
  175. value = ParamManglerIndirectY(valueSigned);
  176. break;
  177. case 0x29:
  178. register="X";
  179. value = ParamManglerAddress(valueUnsigned);
  180. break;
  181. case 0x2a:
  182. register="X";
  183. value = ParamManglerIndirectX(valueSigned);
  184. break;
  185. case 0x2b:
  186. register="X";
  187. value = ParamManglerIndirectY(valueSigned);
  188. break;
  189. case 0x2d:
  190. register="Y";
  191. value = ParamManglerAddress(valueUnsigned);
  192. break;
  193. case 0x2e:
  194. register="Y";
  195. value = ParamManglerIndirectX(valueSigned);
  196. break;
  197. case 0x2f:
  198. register="Y";
  199. value = ParamManglerIndirectY(valueSigned);
  200. break;
  201. }
  202. return OpcodeAddressRangeToString(address,opcode.length)+":st: "+register+" "+value;
  203. };
  204. OpCodeMangler add = GetBasicMangler("add",(short)0x30);
  205. OpCodeMangler nadd = GetBasicMangler("nadd",(short)0x70);
  206. OpCodeMangler addc = GetBasicMangler("addc",(short)0x40);
  207. OpCodeMangler sub = GetBasicMangler("sub",(short)0x50);
  208. OpCodeMangler subc = GetBasicMangler("sub",(short)0x60);
  209. OpCodeMangler or = GetBasicMangler("or",(short)0xb0);
  210. OpCodeMangler and = GetBasicMangler("and",(short)0xc0);
  211. OpCodeMangler xor = GetBasicMangler("xor",(short)0xd0);
  212. OpCodeMangler cmp = GetBasicMangler("cmp",(short)0x80);
  213. OpCodeMangler bra = GetBraMangler("bra",(short)0xe0,true);
  214. OpCodeMangler blt = GetBraMangler("blt",(short)0xe4,false);
  215. OpCodeMangler bne = GetBraMangler("bne",(short)0xf0,false);
  216. OpCodeMangler beq = GetBraMangler("beq",(short)0xf4,false);
  217. OpCodeMangler bcc = GetBraMangler("bcc",(short)0xf8,false);
  218. OpCodeMangler bcs = GetBraMangler("bcs",(short)0xfc,false);
  219. OpCodeMangler tst = GetBraMangler("tst",(short)0x98,false);
  220. OpCodeMangler bsr = GetBraMangler("bsr",(short)0x9c,false);
  221. OpCodeMangler xmult = GetModifiedMangler("smult","umult",(short)0x90);
  222. OpCodeMangler xdiv = GetModifiedMangler("sdiv","udiv",(short)0x94);
  223. OpCodeMangler xsr = GetModifiedMangler("asr","lsr",(short)0xA4);
  224. OpCodeMangler xsl = GetModifiedMangler("asl","lsl",(short)0xA0);
  225. OpCodeMangler enterlleavel = (modifier,opcode,address)->{
  226. if(modifier!=0x00)
  227. {
  228. //return invalid.mangleOpCode(modifier,opcode,address);
  229. };
  230. byte[] opcodeValues = new byte[opcode.length];
  231. short opcodeReal = 0x00; // only checking lower byte though
  232. for(int i=0;i<opcode.length;i++)
  233. {
  234. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  235. opcodeValues[i]=opcodeWord[0];
  236. opcodeReal=(short)((opcode[i]-0x00)&0xFF); //stompy stomp, only keeps the last
  237. }
  238. int valueStack = XAPDisAsmGeneratedCode.unsignedCounts.get(Utils.bytesToHex(opcodeValues));
  239. String label = "";
  240. String value = "";
  241. switch(opcodeReal)
  242. {
  243. case 0x0b:
  244. label="enterl";
  245. break;
  246. case 0x0f:
  247. label="leavel";
  248. break;
  249. }
  250. return OpcodeAddressRangeToString(address,opcode.length)+":"+label+":"+ParamManglerImmediate(valueStack);
  251. };
  252. OpCodeMangler bxx = (modifier,opcode,address)->{
  253. if(modifier!=0x00)
  254. {
  255. //return invalid.mangleOpCode(modifier,opcode,address);
  256. };
  257. byte[] opcodeValues = new byte[opcode.length];
  258. short opcodeReal = 0x00; // only checking lower byte though
  259. for(int i=0;i<opcode.length;i++)
  260. {
  261. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  262. opcodeValues[i]=opcodeWord[0];
  263. opcodeReal=(short)((opcode[i]-0x00)&0xFF); //stompy stomp, only keeps the last
  264. }
  265. int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(Utils.bytesToHex(opcodeValues));
  266. int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
  267. String label = "";
  268. String value = "";
  269. switch(opcodeReal)
  270. {
  271. case 0x20:
  272. label="bgt";
  273. value = ParamManglerAddress(valueSigned);
  274. break;
  275. case 0x24:
  276. label="bge";
  277. value = ParamManglerAddress(valueSigned);
  278. break;
  279. case 0x28:
  280. label="blt";
  281. value = ParamManglerAddress(valueSigned);
  282. break;
  283. case 0x2c:
  284. label="bcz";
  285. value = ParamManglerAddress(valueSigned);
  286. break;
  287. case 0xe8:
  288. label="bpl";
  289. value = ParamManglerAddress(valueSigned);
  290. break;
  291. case 0xec:
  292. label="bmi";
  293. value = ParamManglerAddress(valueSigned);
  294. break;
  295. }
  296. String potentialTargetAddress=addressToString(address+opcode.length-1+valueSigned);
  297. return OpcodeAddressRangeToString(address,opcode.length)+":"+label+":"+value+"; Target="+potentialTargetAddress+" OR "+addressToString(valueUnsigned);
  298. };
  299. manglers[0x0] = (modifier,opcode,address)->{
  300. if(modifier!=0x00)
  301. {
  302. return invalid.mangleOpCode(modifier,opcode,address);
  303. };
  304. return OpcodeAddressRangeToString(address,opcode.length)+": nop";
  305. };
  306. manglers[0x1]=invalid;
  307. manglers[0x2]=invalid;
  308. manglers[0x3]=invalid;
  309. manglers[0x4]=invalid;
  310. manglers[0x5]=invalid;
  311. manglers[0x6]=invalid;
  312. manglers[0x7]=invalid;
  313. manglers[0x8]=invalid;
  314. manglers[0x9]=(modifier,opcode,address)->{
  315. return addressToString(address)+": Modifier, this should not be visible at all in the disassembly!!!!!, should not happen";
  316. };
  317. manglers[0xa]=st;
  318. manglers[0xb]=enterlleavel;
  319. manglers[0xc]=invalid;
  320. manglers[0xd]=invalid;
  321. manglers[0xe]=ld;
  322. manglers[0xf]=enterlleavel;
  323. manglers[0x10]=ld;
  324. manglers[0x11]=ld;
  325. manglers[0x12]=ld;
  326. manglers[0x13]=ld;
  327. manglers[0x14]=ld;
  328. manglers[0x15]=ld;
  329. manglers[0x16]=ld;
  330. manglers[0x17]=ld;
  331. manglers[0x18]=ld;
  332. manglers[0x19]=ld;
  333. manglers[0x1a]=ld;
  334. manglers[0x1b]=ld;
  335. manglers[0x1c]=ld;
  336. manglers[0x1d]=ld;
  337. manglers[0x1e]=ld;
  338. manglers[0x1f]=ld;
  339. manglers[0x20]=bxx; //BGT
  340. manglers[0x21]=st;
  341. manglers[0x22]=st;
  342. manglers[0x23]=st;
  343. manglers[0x24]=bxx;//bge
  344. manglers[0x25]=st;
  345. manglers[0x26]=st;
  346. manglers[0x27]=st;
  347. manglers[0x28]=bxx; //ble
  348. manglers[0x29]=st;
  349. manglers[0x2a]=st;
  350. manglers[0x2b]=st;
  351. manglers[0x2c]=bxx; //BCZ
  352. manglers[0x2d]=st;
  353. manglers[0x2e]=st;
  354. manglers[0x2f]=st;
  355. manglers[0x30]=add;
  356. manglers[0x31]=add;
  357. manglers[0x32]=add;
  358. manglers[0x33]=add;
  359. manglers[0x34]=add;
  360. manglers[0x35]=add;
  361. manglers[0x36]=add;
  362. manglers[0x37]=add;
  363. manglers[0x38]=add;
  364. manglers[0x39]=add;
  365. manglers[0x3a]=add;
  366. manglers[0x3b]=add;
  367. manglers[0x3c]=add;
  368. manglers[0x3d]=add;
  369. manglers[0x3e]=add;
  370. manglers[0x3f]=add;
  371. manglers[0x40]=addc;
  372. manglers[0x41]=addc;
  373. manglers[0x42]=addc;
  374. manglers[0x43]=addc;
  375. manglers[0x44]=addc;
  376. manglers[0x45]=addc;
  377. manglers[0x46]=addc;
  378. manglers[0x47]=addc;
  379. manglers[0x48]=addc;
  380. manglers[0x49]=addc;
  381. manglers[0x4a]=addc;
  382. manglers[0x4b]=addc;
  383. manglers[0x4c]=addc;
  384. manglers[0x4d]=addc;
  385. manglers[0x4e]=addc;
  386. manglers[0x4f]=addc;
  387. manglers[0x50]=sub;
  388. manglers[0x51]=sub;
  389. manglers[0x52]=sub;
  390. manglers[0x53]=sub;
  391. manglers[0x54]=sub;
  392. manglers[0x55]=sub;
  393. manglers[0x56]=sub;
  394. manglers[0x57]=sub;
  395. manglers[0x58]=sub;
  396. manglers[0x59]=sub;
  397. manglers[0x5a]=sub;
  398. manglers[0x5b]=sub;
  399. manglers[0x5c]=sub;
  400. manglers[0x5d]=sub;
  401. manglers[0x5e]=sub;
  402. manglers[0x5f]=sub;
  403. manglers[0x60]=subc;
  404. manglers[0x61]=subc;
  405. manglers[0x62]=subc;
  406. manglers[0x63]=subc;
  407. manglers[0x64]=subc;
  408. manglers[0x65]=subc;
  409. manglers[0x66]=subc;
  410. manglers[0x67]=subc;
  411. manglers[0x68]=subc;
  412. manglers[0x69]=subc;
  413. manglers[0x6a]=subc;
  414. manglers[0x6b]=subc;
  415. manglers[0x6c]=subc;
  416. manglers[0x6d]=subc;
  417. manglers[0x6e]=subc;
  418. manglers[0x6f]=subc;
  419. manglers[0x70]=nadd;
  420. manglers[0x71]=nadd;
  421. manglers[0x72]=nadd;
  422. manglers[0x73]=nadd;
  423. manglers[0x74]=nadd;
  424. manglers[0x75]=nadd;
  425. manglers[0x76]=nadd;
  426. manglers[0x77]=nadd;
  427. manglers[0x78]=nadd;
  428. manglers[0x79]=nadd;
  429. manglers[0x7a]=nadd;
  430. manglers[0x7b]=nadd;
  431. manglers[0x7c]=nadd;
  432. manglers[0x7d]=nadd;
  433. manglers[0x7e]=nadd;
  434. manglers[0x7f]=nadd;
  435. manglers[0x80]=cmp;
  436. manglers[0x81]=cmp;
  437. manglers[0x82]=cmp;
  438. manglers[0x83]=cmp;
  439. manglers[0x84]=cmp;
  440. manglers[0x85]=cmp;
  441. manglers[0x86]=cmp;
  442. manglers[0x87]=cmp;
  443. manglers[0x88]=cmp;
  444. manglers[0x89]=cmp;
  445. manglers[0x8a]=cmp;
  446. manglers[0x8b]=cmp;
  447. manglers[0x8c]=cmp;
  448. manglers[0x8d]=cmp;
  449. manglers[0x8e]=cmp;
  450. manglers[0x8f]=cmp;
  451. manglers[0x90]=xmult;
  452. manglers[0x91]=xmult;
  453. manglers[0x92]=xmult;
  454. manglers[0x93]=xmult;
  455. manglers[0x94]=xdiv;
  456. manglers[0x95]=xdiv;
  457. manglers[0x96]=xdiv;
  458. manglers[0x97]=xdiv;
  459. manglers[0x98]=tst;
  460. manglers[0x99]=tst;
  461. manglers[0x9a]=tst;
  462. manglers[0x9b]=tst;
  463. manglers[0x9c]=bsr;
  464. manglers[0x9d]=bsr;
  465. manglers[0x9e]=bsr;
  466. manglers[0x9f]=bsr;
  467. //0xax
  468. manglers[0xa0]=xsl;
  469. manglers[0xa1]=xsl;
  470. manglers[0xa2]=xsl;
  471. manglers[0xa3]=xsl;
  472. manglers[0xa4]=xsr;
  473. manglers[0xa5]=xsr;
  474. manglers[0xa6]=xsr;
  475. manglers[0xa7]=xsr;
  476. manglers[0xa8]=invalid;
  477. manglers[0xa9]=invalid;
  478. manglers[0xaa]=invalid;
  479. manglers[0xab]=invalid;
  480. manglers[0xac]=invalid;
  481. manglers[0xad]=invalid;
  482. manglers[0xae]=invalid;
  483. manglers[0xaf]=invalid;
  484. manglers[0xb0]=or;
  485. manglers[0xb1]=or;
  486. manglers[0xb2]=or;
  487. manglers[0xb3]=or;
  488. manglers[0xb4]=or;
  489. manglers[0xb5]=or;
  490. manglers[0xb6]=or;
  491. manglers[0xb7]=or;
  492. manglers[0xb8]=or;
  493. manglers[0xb9]=or;
  494. manglers[0xba]=or;
  495. manglers[0xbb]=or;
  496. manglers[0xbc]=or;
  497. manglers[0xbd]=or;
  498. manglers[0xbe]=or;
  499. manglers[0xbf]=or;
  500. manglers[0xc0]=and;
  501. manglers[0xc1]=and;
  502. manglers[0xc2]=and;
  503. manglers[0xc3]=and;
  504. manglers[0xc4]=and;
  505. manglers[0xc5]=and;
  506. manglers[0xc6]=and;
  507. manglers[0xc7]=and;
  508. manglers[0xc8]=and;
  509. manglers[0xc9]=and;
  510. manglers[0xca]=and;
  511. manglers[0xcb]=and;
  512. manglers[0xcc]=and;
  513. manglers[0xcd]=and;
  514. manglers[0xce]=and;
  515. manglers[0xcf]=and;
  516. manglers[0xd0]=xor;
  517. manglers[0xd1]=xor;
  518. manglers[0xd2]=xor;
  519. manglers[0xd3]=xor;
  520. manglers[0xd4]=xor;
  521. manglers[0xd5]=xor;
  522. manglers[0xd6]=xor;
  523. manglers[0xd7]=xor;
  524. manglers[0xd8]=xor;
  525. manglers[0xd9]=xor;
  526. manglers[0xda]=xor;
  527. manglers[0xdb]=xor;
  528. manglers[0xdc]=xor;
  529. manglers[0xdd]=xor;
  530. manglers[0xde]=xor;
  531. manglers[0xdf]=xor;
  532. manglers[0xe0]=bra;
  533. manglers[0xe1]=bra;
  534. manglers[0xe2]=bra;
  535. manglers[0xe3]=bra;
  536. manglers[0xe4]=blt;
  537. manglers[0xe5]=blt;
  538. manglers[0xe6]=blt;
  539. manglers[0xe7]=blt;
  540. manglers[0xe8]=bxx; // bpl
  541. manglers[0xe9]=invalid;
  542. manglers[0xea]=invalid;
  543. manglers[0xeb]=invalid;
  544. manglers[0xec]=bxx; //bmi
  545. manglers[0xed]=invalid;
  546. manglers[0xee]=invalid;
  547. manglers[0xef]=invalid;
  548. manglers[0xf0]=bne;
  549. manglers[0xf1]=bne;
  550. manglers[0xf2]=bne;
  551. manglers[0xf3]=bne;
  552. manglers[0xf4]=beq;
  553. manglers[0xf5]=beq;
  554. manglers[0xf6]=beq;
  555. manglers[0xf7]=beq;
  556. manglers[0xf8]=bcc;
  557. manglers[0xf9]=bcc;
  558. manglers[0xfa]=bcc;
  559. manglers[0xfb]=bcc;
  560. manglers[0xfc]=bcs;
  561. manglers[0xfd]=bcs;
  562. manglers[0xfe]=bcs;
  563. manglers[0xff]=bcs;
  564. }
  565. static OpCodeMangler GetModifiedMangler(String opcodeLabel, String OpcodeLabelModified, short opcodeBase)
  566. {
  567. return (modifier,opcode,address)->{
  568. boolean modified = modifier==0x09;
  569. byte[] opcodeValues = new byte[opcode.length];
  570. short opcodeReal = 0x00; // only checking lower byte though
  571. for(int i=0;i<opcode.length;i++)
  572. {
  573. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  574. opcodeValues[i]=opcodeWord[0];
  575. opcodeReal=(short)((opcode[i]-opcodeBase)&0xFF); //stompy stomp, only keeps the last
  576. }
  577. int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(Utils.bytesToHex(opcodeValues));
  578. int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
  579. String register = "";
  580. String value = "";
  581. switch(opcodeReal)
  582. {
  583. case 0x00:
  584. value = ParamManglerImmediate(valueUnsigned);
  585. break;
  586. case 0x01:
  587. value = ParamManglerAddress(valueUnsigned);
  588. break;
  589. case 0x02:
  590. value = ParamManglerIndirectX(valueSigned);
  591. break;
  592. case 0x03:
  593. value = ParamManglerIndirectY(valueSigned);
  594. break;
  595. }
  596. return OpcodeAddressRangeToString(address,opcode.length+(modified?1:0))+":"+(modified?OpcodeLabelModified:opcodeLabel)+":"+value;
  597. };
  598. }
  599. static OpCodeMangler GetBraMangler(String opcodeLabel, short opcodeBase, boolean bra_specialcase)
  600. {
  601. return (modifier,opcode,address)->{
  602. if(modifier!=0x00)
  603. {
  604. //return invalid.mangleOpCode(modifier,opcode,address);
  605. };
  606. byte[] opcodeValues = new byte[opcode.length];
  607. short opcodeReal = 0x00; // only checking lower byte though
  608. for(int i=0;i<opcode.length;i++)
  609. {
  610. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  611. opcodeValues[i]=opcodeWord[0];
  612. opcodeReal=(short)((opcode[i]-opcodeBase)&0xFF); //stompy stomp, only keeps the last
  613. }
  614. int valueUnsigned=0;
  615. int valueSigned=0;
  616. if(opcodeReal !=0x0)
  617. {
  618. valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(Utils.bytesToHex(opcodeValues));
  619. valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
  620. }
  621. String register = "";
  622. String value = "";
  623. switch(opcodeReal)
  624. {
  625. case 0x00:
  626. register="AH";
  627. value = ParamManglerConstAddr(untwiddleOpcodeParamBra(opcodeValues,address+opcode.length-1));
  628. break;
  629. case 0x01:
  630. register="AH";
  631. value = ParamManglerAddress(valueSigned);
  632. break;
  633. case 0x02:
  634. register="AH";
  635. value = ParamManglerIndirectX(valueSigned);
  636. break;
  637. case 0x03:
  638. register="AH";
  639. value = ParamManglerIndirectY(valueSigned);
  640. break;
  641. }
  642. String potentialTargetAddress=addressToString(address+opcode.length-1+valueSigned);
  643. if(bra_specialcase&&opcodeReal==0x02&&address==0)
  644. {
  645. return addressToString(address)+":rts";
  646. }
  647. return OpcodeAddressRangeToString(address,opcode.length)+":"+opcodeLabel+":"+value+"; Target="+potentialTargetAddress+" OR "+addressToString(valueUnsigned);
  648. };
  649. }
  650. static OpCodeMangler GetBasicMangler(String opcodeLabel, short opcodeBase)
  651. {
  652. return (modifier,opcode,address)->{
  653. if(modifier!=0x00)
  654. {
  655. //return invalid.mangleOpCode(modifier,opcode,address);
  656. };
  657. byte[] opcodeValues = new byte[opcode.length];
  658. short opcodeReal = 0x00; // only checking lower byte though
  659. for(int i=0;i<opcode.length;i++)
  660. {
  661. byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
  662. opcodeValues[i]=opcodeWord[0];
  663. opcodeReal=(short)(opcodeWord[1]&(short)0x00FF); //stompy stomp, only keeps the last
  664. }
  665. short opcodeDispatch = (short)(opcodeReal-opcodeBase);
  666. int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(Utils.bytesToHex(opcodeValues));
  667. int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
  668. String register = "";
  669. String value = "";
  670. switch(opcodeDispatch)
  671. {
  672. case 0x0:
  673. register="AH";
  674. value = ParamManglerImmediate(valueUnsigned);
  675. break;
  676. case 0x1:
  677. register="AH";
  678. value = ParamManglerAddress(valueUnsigned);
  679. break;
  680. case 0x2:
  681. register="AH";
  682. value = ParamManglerIndirectX(valueSigned);
  683. break;
  684. case 0x3:
  685. register="AH";
  686. value = ParamManglerIndirectY(valueSigned);
  687. break;
  688. case 0x4:
  689. register="AL";
  690. value = ParamManglerImmediate(valueUnsigned);
  691. break;
  692. case 0x5:
  693. register="AL";
  694. value = ParamManglerAddress(valueUnsigned);
  695. break;
  696. case 0x6:
  697. register="AL";
  698. value = ParamManglerIndirectX(valueSigned);
  699. break;
  700. case 0x7:
  701. register="AL";
  702. value = ParamManglerIndirectY(valueSigned);
  703. break;
  704. case 0x8:
  705. register="X";
  706. value = ParamManglerImmediate(valueUnsigned);
  707. break;
  708. case 0x9:
  709. register="X";
  710. value = ParamManglerAddress(valueUnsigned);
  711. break;
  712. case 0xa:
  713. register="X";
  714. value = ParamManglerIndirectX(valueSigned);
  715. break;
  716. case 0xb:
  717. register="X";
  718. value = ParamManglerIndirectY(valueSigned);
  719. break;
  720. case 0xc:
  721. register="Y";
  722. value = ParamManglerImmediate(valueUnsigned);
  723. break;
  724. case 0xd:
  725. register="Y";
  726. value = ParamManglerAddress(valueUnsigned);
  727. break;
  728. case 0xe:
  729. register="Y";
  730. value = ParamManglerIndirectX(valueSigned);
  731. break;
  732. case 0xf:
  733. register="Y";
  734. value = ParamManglerIndirectY(valueSigned);
  735. break;
  736. }
  737. return OpcodeAddressRangeToString(address,opcode.length)+":"+opcodeLabel+": "+register+" "+value;
  738. };
  739. }
  740. private static int untwiddleOpcodeParamBra(byte[] opcode,int opcodelocation)
  741. {
  742. int out = opcode[0];
  743. if(EntryPoint.verbose)System.out.println(out);
  744. if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
  745. for(int i=1;i<opcode.length;i++)
  746. {
  747. out=out<<8;
  748. out+=opcode[i];
  749. if(EntryPoint.verbose)System.out.println(out);
  750. if(EntryPoint.verbose)System.out.println(opcode[i]);
  751. if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
  752. }
  753. out=out+opcodelocation;
  754. out = out &0x00FFFFFF;
  755. return out;
  756. }
  757. private static String addressToString(int address)
  758. {
  759. //return "0x"+(Utils.bytesToHex(Ints.toByteArray(address)));
  760. return String.format("0x%08X", address);
  761. }
  762. private static String OpcodeAddressRangeToString(int address,int opcodelen)
  763. {
  764. String startaddr = addressToString(address);
  765. if(labels.containsKey(startaddr))
  766. {
  767. startaddr = labels.get(startaddr)+":\n"+startaddr;
  768. }
  769. if(opcodelen>1)
  770. {
  771. return startaddr+
  772. "---"+
  773. addressToString(address+(opcodelen-1));
  774. }
  775. else return startaddr;
  776. }
  777. private static String ParamManglerImmediate(int number)
  778. {
  779. return "#"+number;
  780. }
  781. private static String ParamManglerConstAddr(int number)
  782. {
  783. String addr = addressToString(number);
  784. if(labels.containsKey(addr))
  785. {
  786. addr = addr+"("+labels.get(addr)+")";
  787. }
  788. return addr;
  789. }
  790. private static String ParamManglerAddress(int number)
  791. {
  792. return "@"+number;
  793. }
  794. private static String ParamManglerIndirectX(int number)
  795. {
  796. return "@("+number+",X)";
  797. }
  798. private static String ParamManglerIndirectY(int number)
  799. {
  800. return "@("+number+",Y)";
  801. }
  802. public static void Disassemble(String in, String out)
  803. {
  804. try {
  805. RandomAccessFile f = new RandomAccessFile(in,"r");
  806. PrintStream disassembled = new PrintStream(new FileOutputStream(out));
  807. String mapfilepath = in+".sbwmap";
  808. if(new File(mapfilepath).exists())
  809. {
  810. RandomAccessFile mapfile = new RandomAccessFile(mapfilepath,"r");
  811. String line = mapfile.readLine();
  812. while(line !=null)
  813. {
  814. if(line.equals(""))
  815. {
  816. line = mapfile.readLine();
  817. continue;
  818. }
  819. String[] entry = line.split(":");
  820. labels.put(entry[0].toLowerCase(),entry[1]);
  821. line = mapfile.readLine();
  822. }
  823. }
  824. long assemblyLength = f.length()/2;
  825. int baseAddressLastOpcode=0;
  826. List<Short> opcodeHoldingBay = new ArrayList<>(5);
  827. for(int i=0;i<assemblyLength;i++)
  828. {
  829. Short word = f.readShort();
  830. if(EntryPoint.verbose)System.out.println("READ:"+ (word&0xff));
  831. if(EntryPoint.verbose)System.out.println(addressToString(i));
  832. if(EntryPoint.verbose)System.out.println(addressToString(baseAddressLastOpcode));
  833. opcodeHoldingBay.add(word);
  834. if(word==(short)0xfe09) //specialcasing one specific opcode
  835. {
  836. opcodeHoldingBay.clear();
  837. disassembled.println(brxl.mangleOpCode((short)0x00,(short[])null,baseAddressLastOpcode));
  838. baseAddressLastOpcode++;
  839. }
  840. else if((word&0xFF)!=0)
  841. {
  842. if((word&0xFF)!=0x09)//skip modifier
  843. {
  844. short[] opcode;
  845. short modifier=0x00;
  846. if(opcodeHoldingBay.get(0)==0x09) //modifier
  847. {
  848. modifier = 0x09;
  849. opcode = new short[opcodeHoldingBay.size()-1];
  850. for(int j=1;j<opcodeHoldingBay.size();j++)
  851. {
  852. opcode[j-1]=opcodeHoldingBay.get(j);
  853. }
  854. }
  855. else
  856. {
  857. opcode = new short[opcodeHoldingBay.size()];
  858. for(int j=0;j<opcodeHoldingBay.size();j++)
  859. {
  860. opcode[j]=opcodeHoldingBay.get(j);
  861. }
  862. }
  863. if(EntryPoint.verbose)System.out.println("Mangling Opcode with length"+opcode.length);
  864. try{
  865. disassembled.println(manglers[word&0xff].mangleOpCode(modifier,opcode,baseAddressLastOpcode));
  866. }
  867. catch(Exception e)
  868. {
  869. System.err.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
  870. disassembled.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
  871. //System.exit(-1);
  872. }
  873. baseAddressLastOpcode+=opcodeHoldingBay.size();
  874. opcodeHoldingBay.clear();
  875. }
  876. }
  877. else
  878. {
  879. if(word==0x00)//nop
  880. {
  881. disassembled.println(manglers[0].mangleOpCode((short)0x00, new short[]{(short)0x00}, baseAddressLastOpcode));
  882. opcodeHoldingBay.clear();
  883. baseAddressLastOpcode++;
  884. }
  885. if(EntryPoint.verbose)System.out.println("VALUE");
  886. //opcodeHoldingBay.add(word);
  887. }
  888. }
  889. } catch (FileNotFoundException e) {
  890. e.printStackTrace();
  891. } catch (IOException e) {
  892. e.printStackTrace();
  893. }
  894. }
  895. }