XAPDisAsm.java 36 KB

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