XAPDisAsm.java 36 KB

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