dishand.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. static char *sccsid =
  2. "@(#) dishand.c, Ver. 2.1 created 00:00:00 87/09/01";
  3. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4. * *
  5. * Copyright (C) 1987 G. M. Harding, all rights reserved *
  6. * *
  7. * Permission to copy and redistribute is hereby granted, *
  8. * provided full source code, with all copyright notices, *
  9. * accompanies any redistribution. *
  10. * *
  11. * This file contains the source code for most of the spe- *
  12. * cialized handler routines of the disassembler program. *
  13. * (The file disfp.c contains handler routines specific to *
  14. * the 8087 numeric co-processor.) Each handler routine *
  15. * interprets the opcode byte (and subsequent data bytes, *
  16. * if any) of a particular family of opcodes, and is re- *
  17. * sponsible for generating appropriate output. All of the *
  18. * code in this file is highly MACHINE-SPECIFIC, and would *
  19. * have to be rewritten for a different CPU. The handler *
  20. * routines are accessed only via pointers in the optab[] *
  21. * array, however, so machine dependencies are confined to *
  22. * this file, its sister file "disfp.c", and the data file *
  23. * "distabs.c". *
  24. * *
  25. * All of the code in this file is based on the assumption *
  26. * of sixteen-bit integers. *
  27. * *
  28. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  29. #include "dis.h" /* Disassembler declarations */
  30. int segflg; /* Segment-override flag */
  31. unsigned char objbuf[OBJMAX]; /* Buffer for object code */
  32. int objptr; /* Index into objbuf[] */
  33. unsigned long PC; /* Current program counter */
  34. /* * * * * * MISCELLANEOUS SUPPORTING ROUTINES * * * * * */
  35. void
  36. objini(j) /* Object code init routine */
  37. register int j;
  38. {
  39. if ((segflg == 1) || (segflg == 2))
  40. segflg *= 3;
  41. else
  42. segflg = 0;
  43. objptr = 0;
  44. objbuf[objptr++] = (unsigned char)(j);
  45. }
  46. void
  47. objout() /* Object-code output routine */
  48. {
  49. register int k;
  50. if ( ! objflg )
  51. return;
  52. else
  53. {
  54. printf("\t|");
  55. if (symptr >= 0)
  56. printf(" %05.5lx:",(PC + 1L - (long)(objptr)));
  57. for (k = 0; k < objptr; ++k)
  58. printf(" %02.2x",objbuf[k]);
  59. putchar('\n');
  60. }
  61. }
  62. void
  63. badseq(j,k) /* Invalid-sequence routine */
  64. register int j, k;
  65. {
  66. printf("\t.byte\t$%02.2x\t\t| invalid code sequence\n",j);
  67. printf("\t.byte\t$%02.2x\n",k);
  68. }
  69. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  70. * *
  71. * This routine is the first of several opcode-specific *
  72. * handlers, each of which is dedicated to a particular *
  73. * opcode family. A pointer to a handler routine is con- *
  74. * tained in the second field of each optab[] entry. The *
  75. * dfhand() routine is the default handler, invoked when *
  76. * no other handler is appropriate (generally, when an in- *
  77. * valid opcode is encountered). *
  78. * *
  79. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  80. void
  81. dfhand(j)
  82. register int j; /* Pointer to optab[] entry */
  83. {/* * * * * * * * * * START OF dfhand() * * * * * * * * * */
  84. segflg = 0;
  85. printf("\t.byte\t$%02.2x",j);
  86. if (optab[j].min || optab[j].max)
  87. putchar('\n');
  88. else
  89. printf("\t\t| unimplemented opcode\n");
  90. }/* * * * * * * * * * * END OF dfhand() * * * * * * * * * * */
  91. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  92. * *
  93. * This is the single-byte handler, invoked whenever a *
  94. * one-byte opcode is encountered. *
  95. * *
  96. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  97. void
  98. sbhand(j)
  99. register int j; /* Pointer to optab[] entry */
  100. {/* * * * * * * * * * START OF sbhand() * * * * * * * * * */
  101. objini(j);
  102. if (j == 0x2e) /* seg cs */
  103. segflg = 1;
  104. if ((j == 0x26) /* seg es */
  105. || (j == 0x36) /* seg ss */
  106. || (j == 0x3e)) /* seg ds */
  107. segflg = 2;
  108. printf("%s\n",optab[j].text);
  109. objout();
  110. }/* * * * * * * * * * * END OF sbhand() * * * * * * * * * * */
  111. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  112. * *
  113. * This is the handler for most of the processor's regular *
  114. * arithmetic operations. *
  115. * *
  116. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  117. void
  118. aohand(j)
  119. register int j; /* Pointer to optab[] entry */
  120. {/* * * * * * * * * * START OF aohand() * * * * * * * * * */
  121. register int k;
  122. int m, n;
  123. char b[80];
  124. objini(j);
  125. switch (j & 7)
  126. {
  127. case 0 :
  128. case 1 :
  129. case 2 :
  130. case 3 :
  131. printf("%s\t",optab[j].text);
  132. FETCH(k);
  133. printf("%s\n",mtrans(j,k,TR_STD));
  134. break;
  135. case 4 :
  136. FETCH(k);
  137. if( k < 16 )
  138. printf("%s\tal,*%d\n",optab[j].text,k);
  139. else
  140. printf("%s\tal,*$%02.2x\n",optab[j].text,k);
  141. break;
  142. case 5 :
  143. FETCH(m);
  144. FETCH(n);
  145. k = (n << 8) | m;
  146. if (lookext((long)(k),(PC - 1),b))
  147. printf("%s\tax,#%s\n",optab[j].text,b);
  148. else
  149. {
  150. if( k < 100 || k > 65436 )
  151. printf("%s\tax,#%d\n",optab[j].text, (short)k);
  152. else
  153. printf("%s\tax,#$%04x\n",optab[j].text,k);
  154. }
  155. break;
  156. default :
  157. dfhand(j);
  158. break;
  159. }
  160. objout();
  161. }/* * * * * * * * * * * END OF aohand() * * * * * * * * * * */
  162. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  163. * *
  164. * This is the handler for opcodes which perform short *
  165. * (eight-bit) relative jumps. *
  166. * *
  167. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  168. void
  169. sjhand(j)
  170. register int j; /* Pointer to optab[] entry */
  171. {/* * * * * * * * * * START OF sjhand() * * * * * * * * * */
  172. register int k;
  173. int m;
  174. unsigned short dest;
  175. objini(j);
  176. FETCH(m);
  177. if (m & 0x80)
  178. k = 0xff00;
  179. else
  180. k = 0;
  181. k |= m;
  182. dest = (PC + k + 1);
  183. printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text,
  184. lookup((long) dest,N_TEXT,LOOK_REL,-1L),
  185. (long) dest);
  186. objout();
  187. }/* * * * * * * * * * * END OF sjhand() * * * * * * * * * * */
  188. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  189. * *
  190. * This is the handler for a loosely-knit family of op- *
  191. * codes which perform arithmetic and logical operations, *
  192. * and which take immediate data. The routine's logic is *
  193. * rather complex, so, in an effort to avoid additional *
  194. * complexity, the search for external references in the *
  195. * relocation table has been dispensed with. Eager hackers *
  196. * can try their hand at coding such a search. *
  197. * *
  198. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  199. void
  200. imhand(j)
  201. register int j; /* Pointer to optab[] entry */
  202. {/* * * * * * * * * * START OF imhand() * * * * * * * * * */
  203. unsigned long pc;
  204. register int k;
  205. int offset, oflag, immed, iflag, mod, opi, w, rm;
  206. int m, n;
  207. static char a[100], b[30];
  208. objini(j);
  209. FETCH(k);
  210. pc = PC + 1;
  211. offset = 0;
  212. mod = (k & 0xc0) >> 6;
  213. opi = (k & 0x38) >> 3;
  214. w = j & 1;
  215. rm = k & 7;
  216. if ((j & 2)
  217. && ((opi == 1)
  218. || (opi == 4)
  219. || (opi == 6)))
  220. {
  221. badseq(j,k);
  222. return;
  223. }
  224. strcpy(a,OPFAM[opi]);
  225. if ( ! w )
  226. strcat(a,"b");
  227. if ((oflag = mod) > 2)
  228. oflag = 0;
  229. if ((mod == 0) && (rm == 6))
  230. {
  231. FETCH(m);
  232. FETCH(n);
  233. offset = (n << 8) | m;
  234. }
  235. else if (oflag)
  236. if (oflag == 2)
  237. {
  238. FETCH(m);
  239. FETCH(n);
  240. offset = (n << 8) | m;
  241. }
  242. else
  243. {
  244. FETCH(m);
  245. if (m & 0x80)
  246. n = -0xFF;
  247. else
  248. n = 0;
  249. offset = n | m;
  250. }
  251. switch (j & 3)
  252. {
  253. case 0 :
  254. case 2 :
  255. FETCH(immed);
  256. iflag = 0;
  257. break;
  258. case 1 :
  259. FETCH(m);
  260. FETCH(n);
  261. immed = (n << 8) | m;
  262. iflag = 1;
  263. break;
  264. case 3 :
  265. FETCH(immed);
  266. if (immed & 0x80)
  267. immed &= 0xff00;
  268. iflag = 0;
  269. break;
  270. }
  271. strcat(a,"\t");
  272. switch (mod)
  273. {
  274. case 0 :
  275. if (rm == 6)
  276. strcat(a,
  277. lookup((long)(offset),N_DATA,LOOK_ABS,pc));
  278. else
  279. {
  280. sprintf(b,"(%s)",REGS0[rm]);
  281. strcat(a,b);
  282. }
  283. break;
  284. case 1 :
  285. case 2 :
  286. if (mod == 1)
  287. {
  288. strcat(a,"*");
  289. sprintf(b,"%d(", (short)offset);
  290. }
  291. else
  292. {
  293. strcat(a,"#");
  294. if( offset < 100 || offset > 65436 )
  295. sprintf(b,"%d(", (short)offset);
  296. else
  297. sprintf(b,"$%04x(",offset);
  298. }
  299. strcat(a,b);
  300. strcat(a,REGS1[rm]);
  301. strcat(a,")");
  302. break;
  303. case 3 :
  304. strcat(a,REGS[(w << 3) | rm]);
  305. break;
  306. }
  307. strcat(a,",");
  308. if (iflag)
  309. {
  310. strcat(a,"#");
  311. if( immed < 100 || immed > 65436 )
  312. sprintf(b,"%d", (short)immed);
  313. else
  314. sprintf(b,"$%04x",immed);
  315. }
  316. else
  317. {
  318. strcat(a,"*");
  319. sprintf(b,"%d",immed);
  320. }
  321. strcat(a,b);
  322. printf("%s\n",a);
  323. objout();
  324. }/* * * * * * * * * * * END OF imhand() * * * * * * * * * * */
  325. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  326. * *
  327. * This is the handler for various "mov"-type opcodes *
  328. * which use the mod, reg, and r/m fields of the second *
  329. * code byte in a standard, straightforward way. *
  330. * *
  331. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  332. void
  333. mvhand(j)
  334. int j; /* Pointer to optab[] entry */
  335. {/* * * * * * * * * * START OF mvhand() * * * * * * * * * */
  336. register int k, m = j;
  337. objini(j);
  338. FETCH(k);
  339. if ((m == 0x84) || (m == 0x85) /* Kind of kludgey */
  340. || (m == 0xc4) || (m == 0xc5)
  341. || (m == 0x8d))
  342. if (m & 0x40)
  343. m |= 0x03;
  344. else
  345. m |= 0x02;
  346. printf("%s\t%s\n",optab[j].text,mtrans(m,k,TR_STD));
  347. objout();
  348. }/* * * * * * * * * * * END OF mvhand() * * * * * * * * * * */
  349. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  350. * *
  351. * This is the handler for segment-register "mov" opcodes. *
  352. * *
  353. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  354. void
  355. mshand(j)
  356. register int j; /* Pointer to optab[] entry */
  357. {/* * * * * * * * * * START OF mshand() * * * * * * * * * */
  358. register int k;
  359. objini(j);
  360. FETCH(k);
  361. if (k & 0x20)
  362. {
  363. badseq(j,k);
  364. return;
  365. }
  366. printf("%s\t%s\n",optab[j].text,mtrans(j,k,TR_SEG));
  367. objout();
  368. }/* * * * * * * * * * * END OF mshand() * * * * * * * * * * */
  369. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  370. * *
  371. * This is the handler for pops, other than single-byte *
  372. * pops. (The 8088 allows popping into any register, or *
  373. * directly into memory, accessed either immediately or *
  374. * through a register and an index.) *
  375. * *
  376. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  377. void
  378. pohand(j)
  379. register int j; /* Pointer to optab[] entry */
  380. {/* * * * * * * * * * START OF pohand() * * * * * * * * * */
  381. char *a;
  382. register int k;
  383. objini(j);
  384. FETCH(k);
  385. if (k & 0x38)
  386. {
  387. badseq(j,k);
  388. return;
  389. }
  390. printf("%s\t",optab[j].text);
  391. a = mtrans((j & 0xfd),k,TR_STD);
  392. mtrunc(a);
  393. printf("%s\n",a);
  394. objout();
  395. }/* * * * * * * * * * * END OF pohand() * * * * * * * * * * */
  396. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  397. * *
  398. * This is the handler routine for intersegment calls and *
  399. * jumps. Its output is never symbolic, because the host *
  400. * linker does not allow symbolic intersegment address *
  401. * references except by means of symbolic constants, and *
  402. * any such constants in the symbol table, even if they *
  403. * are of the appropriate value, may be misleading. In *
  404. * compiled code, intersegment references should not be *
  405. * encountered, and even in assembled code, they should *
  406. * occur infrequently. If and when they do occur, however, *
  407. * they will be disassembled in absolute form. *
  408. * *
  409. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  410. void
  411. cihand(j)
  412. int j; /* Pointer to optab[] entry */
  413. {/* * * * * * * * * * START OF cihand() * * * * * * * * * */
  414. register int m, n;
  415. objini(j);
  416. printf("%s\t",optab[j].text);
  417. FETCH(m);
  418. FETCH(n);
  419. printf("#$%04.4x,",((n << 8) | m));
  420. FETCH(m);
  421. FETCH(n);
  422. printf("#$%04.4x\n",((n << 8) | m));
  423. objout();
  424. }/* * * * * * * * * * * END OF cihand() * * * * * * * * * * */
  425. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  426. * *
  427. * This is the handler for "mov" opcodes with immediate *
  428. * data. *
  429. * *
  430. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  431. void
  432. mihand(j)
  433. register int j; /* Pointer to optab[] entry */
  434. {/* * * * * * * * * * START OF mihand() * * * * * * * * * */
  435. register int k;
  436. int m, n;
  437. char b[80];
  438. objini(j);
  439. printf("%s",optab[j].text);
  440. if (j & 8)
  441. {
  442. FETCH(m);
  443. FETCH(n);
  444. k = ((n << 8) | m);
  445. if (lookext((long)(k),(PC - 1),b))
  446. printf("#%s\n",b);
  447. else
  448. {
  449. if( k < 100 || k > 65436 )
  450. printf("#%d\n",(short)k);
  451. else
  452. printf("#$%04x\n",k);
  453. }
  454. }
  455. else
  456. {
  457. FETCH(m);
  458. printf("*%d\n",m);
  459. }
  460. objout();
  461. }/* * * * * * * * * * * END OF mihand() * * * * * * * * * * */
  462. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  463. * *
  464. * This is the handler for a family of quick-move opcodes. *
  465. * *
  466. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  467. void
  468. mqhand(j)
  469. int j; /* Pointer to optab[] entry */
  470. {/* * * * * * * * * * START OF mqhand() * * * * * * * * * */
  471. unsigned long pc;
  472. register int m, n;
  473. objini(j);
  474. pc = PC + 1;
  475. FETCH(m);
  476. FETCH(n);
  477. m = (n << 8) | m;
  478. printf("%s\t",optab[j].text);
  479. if (j & 2)
  480. printf("%s,%s\n",
  481. lookup((long)(m),N_DATA,LOOK_ABS,pc),
  482. REGS[(j & 1) << 3]);
  483. else
  484. printf("%s,%s\n",
  485. REGS[(j & 1) << 3],
  486. lookup((long)(m),N_DATA,LOOK_ABS,pc));
  487. objout();
  488. }/* * * * * * * * * * * END OF mqhand() * * * * * * * * * * */
  489. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  490. * *
  491. * This is the handler for a family of quick-test opcodes. *
  492. * *
  493. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  494. void
  495. tqhand(j)
  496. int j; /* Pointer to optab[] entry */
  497. {/* * * * * * * * * * START OF tqhand() * * * * * * * * * */
  498. register int m, n;
  499. int k;
  500. char b[80];
  501. objini(j);
  502. printf("%s\t%s,",optab[j].text,REGS[(j & 1) << 3]);
  503. FETCH(m);
  504. if (j & 1)
  505. {
  506. FETCH(n);
  507. k = ((n << 8) | m);
  508. if (lookext((long)(k),(PC - 1),b))
  509. printf("#%s\n",b);
  510. else
  511. {
  512. if( k < 100 || k > 65436 )
  513. printf("#%d\n",(short)k);
  514. else
  515. printf("#$%04x\n",k);
  516. }
  517. }
  518. else
  519. {
  520. if (m & 80)
  521. m |= -0xFF;
  522. printf("*%d\n",m);
  523. }
  524. objout();
  525. }/* * * * * * * * * * * END OF tqhand() * * * * * * * * * * */
  526. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  527. * *
  528. * This is the handler for multiple-byte "return" opcodes. *
  529. * The 8088 allows returns to take an optional 16-bit ar- *
  530. * gument, which reflects the amount to be added to SP *
  531. * after the pop of the return address. The idea is to *
  532. * facilitate the use of local parameters on the stack. *
  533. * After some rumination, it was decided to disassemble *
  534. * any such arguments as absolute quantities, rather than *
  535. * rummaging through the symbol table for possible corre- *
  536. * sponding constants. *
  537. * *
  538. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  539. void
  540. rehand(j)
  541. int j; /* Pointer to optab[] entry */
  542. {/* * * * * * * * * * START OF rehand() * * * * * * * * * */
  543. register int m, n;
  544. objini(j);
  545. FETCH(m);
  546. FETCH(n);
  547. m = (n << 8) | m;
  548. printf("%s\t#0x%04.4x\n",optab[j].text,m);
  549. objout();
  550. }/* * * * * * * * * * * END OF rehand() * * * * * * * * * * */
  551. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  552. * *
  553. * This is the handler for "mov" opcodes involving memory *
  554. * and immediate data. *
  555. * *
  556. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  557. void
  558. mmhand(j)
  559. register int j; /* Pointer to optab[] entry */
  560. {/* * * * * * * * * * START OF mmhand() * * * * * * * * * */
  561. char *a;
  562. register int k;
  563. char b[80];
  564. objini(j);
  565. FETCH(k);
  566. if (k & 0x38)
  567. {
  568. badseq(j,k);
  569. return;
  570. }
  571. printf("%s",optab[j].text);
  572. if ( ! (j & 1) )
  573. putchar('b');
  574. a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
  575. mtrunc(a);
  576. printf("\t%s,",a);
  577. if (j & 1)
  578. {
  579. FETCH(j);
  580. FETCH(k);
  581. k = (k << 8) | j;
  582. if (lookext((long)(k),(PC - 1),b))
  583. printf("#%s\n",b);
  584. else
  585. {
  586. if( k < 100 || k > 65436 )
  587. printf("#%d\n",(short)k);
  588. else
  589. printf("#$%04x\n",k);
  590. }
  591. }
  592. else
  593. {
  594. FETCH(k);
  595. printf("*%d\n",k);
  596. }
  597. objout();
  598. }/* * * * * * * * * * * END OF mmhand() * * * * * * * * * * */
  599. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  600. * *
  601. * This is the handler for the 8088 family of shift and *
  602. * rotate instructions. *
  603. * *
  604. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  605. void
  606. srhand(j)
  607. register int j; /* Pointer to optab[] entry */
  608. {/* * * * * * * * * * START OF srhand() * * * * * * * * * */
  609. char *a;
  610. register int k;
  611. objini(j);
  612. FETCH(k);
  613. if ((k & 0x38) == 0x30)
  614. {
  615. badseq(j,k);
  616. return;
  617. }
  618. printf("%s",OPFAM[((k & 0x38) >> 3) + 16]);
  619. if ( ! (j & 1) )
  620. putchar('b');
  621. a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
  622. mtrunc(a);
  623. printf("\t%s",a);
  624. if (j & 2)
  625. printf(",cl\n");
  626. else
  627. printf(",*1\n");
  628. objout();
  629. }/* * * * * * * * * * * END OF srhand() * * * * * * * * * * */
  630. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  631. * *
  632. * This is the handler for the ASCII-adjust opcodes. *
  633. * *
  634. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  635. void
  636. aahand(j)
  637. register int j; /* Pointer to optab[] entry */
  638. {/* * * * * * * * * * START OF aahand() * * * * * * * * * */
  639. register int k;
  640. objini(j);
  641. FETCH(k);
  642. if (k != 0x0a)
  643. {
  644. badseq(j,k);
  645. return;
  646. }
  647. printf("%s\n",optab[j].text);
  648. objout();
  649. }/* * * * * * * * * * * END OF aahand() * * * * * * * * * * */
  650. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  651. * *
  652. * This is the handler for port I/O opcodes which specify *
  653. * the port address as an immediate operand. *
  654. * *
  655. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  656. void
  657. iohand(j)
  658. register int j; /* Pointer to optab[] entry */
  659. {/* * * * * * * * * * START OF iohand() * * * * * * * * * */
  660. register int k;
  661. objini(j);
  662. FETCH(k);
  663. printf("%s\t$%02.2x\n",optab[j].text,k);
  664. objout();
  665. }/* * * * * * * * * * * END OF iohand() * * * * * * * * * * */
  666. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  667. * *
  668. * This is the handler for opcodes which perform long *
  669. * (sixteen-bit) relative jumps and calls. *
  670. * *
  671. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  672. void
  673. ljhand(j)
  674. register int j; /* Pointer to optab[] entry */
  675. {/* * * * * * * * * * START OF ljhand() * * * * * * * * * */
  676. register int k;
  677. int m, n;
  678. unsigned short dest;
  679. objini(j);
  680. FETCH(m);
  681. FETCH(n);
  682. k = (n << 8) | m;
  683. dest = PC + k + 1;
  684. printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text,
  685. lookup((long)dest,N_TEXT,LOOK_LNG,(PC - 1L)),
  686. (long)dest);
  687. objout();
  688. }/* * * * * * * * * * * END OF ljhand() * * * * * * * * * * */
  689. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  690. * *
  691. * This is the handler for a pair of oddball opcodes (0xf6 *
  692. * and 0xf7) which perform miscellaneous arithmetic opera- *
  693. * tions not dealt with elsewhere. *
  694. * *
  695. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  696. void
  697. mahand(j)
  698. register int j; /* Pointer to optab[] entry */
  699. {/* * * * * * * * * * START OF mahand() * * * * * * * * * */
  700. char *a;
  701. register int k;
  702. char b[80];
  703. objini(j);
  704. FETCH(k);
  705. a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
  706. mtrunc(a);
  707. switch (((k = objbuf[1]) & 0x38) >> 3)
  708. {
  709. case 0 :
  710. printf("\ttest");
  711. break;
  712. case 1 :
  713. badseq(j,k);
  714. return;
  715. case 2 :
  716. printf("\tnot");
  717. break;
  718. case 3 :
  719. printf("\tneg");
  720. break;
  721. case 4 :
  722. printf("\tmul");
  723. break;
  724. case 5 :
  725. printf("\timul");
  726. break;
  727. case 6 :
  728. printf("\tdiv");
  729. break;
  730. case 7 :
  731. printf("\tidiv");
  732. break;
  733. }
  734. if ( ! (j & 1) )
  735. putchar('b');
  736. printf("\t%s",a);
  737. if (k & 0x38)
  738. putchar('\n');
  739. else
  740. if (j & 1)
  741. {
  742. FETCH(j);
  743. FETCH(k);
  744. k = (k << 8) | j;
  745. if (lookext((long)(k),(PC - 1),b))
  746. printf(",#%s\n",b);
  747. else
  748. printf(",#$%04x\n",k);
  749. }
  750. else
  751. {
  752. FETCH(k);
  753. printf(",*%d\n",k);
  754. }
  755. objout();
  756. }/* * * * * * * * * * * END OF mahand() * * * * * * * * * * */
  757. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  758. * *
  759. * This is the handler for miscellaneous jump, call, push, *
  760. * and increment/decrement opcodes (0xfe and 0xff) which *
  761. * are not dealt with elsewhere. *
  762. * *
  763. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  764. void
  765. mjhand(j)
  766. register int j; /* Pointer to optab[] entry */
  767. {/* * * * * * * * * * START OF mjhand() * * * * * * * * * */
  768. char *a;
  769. register int k;
  770. objini(j);
  771. FETCH(k);
  772. a = mtrans((j & 0xfd),(k & 0xc7),TR_STD);
  773. mtrunc(a);
  774. switch (((k = objbuf[1]) & 0x38) >> 3)
  775. {
  776. case 0 :
  777. printf("\tinc");
  778. if ( ! (j & 1) )
  779. putchar('b');
  780. putchar('\t');
  781. break;
  782. case 1 :
  783. printf("\tdec");
  784. if ( ! (j & 1) )
  785. putchar('b');
  786. putchar('\t');
  787. break;
  788. case 2 :
  789. if (j & 1)
  790. printf("\tcall\t@");
  791. else
  792. goto BAD;
  793. break;
  794. case 3 :
  795. if (j & 1)
  796. printf("\tcalli\t@");
  797. else
  798. goto BAD;
  799. break;
  800. case 4 :
  801. if (j & 1)
  802. printf("\tjmp\t@");
  803. else
  804. goto BAD;
  805. break;
  806. case 5 :
  807. if (j & 1)
  808. printf("\tjmpi\t@");
  809. else
  810. goto BAD;
  811. break;
  812. case 6 :
  813. if (j & 1)
  814. printf("\tpush\t");
  815. else
  816. goto BAD;
  817. break;
  818. case 7 :
  819. BAD :
  820. badseq(j,k);
  821. return;
  822. }
  823. printf("%s\n",a);
  824. objout();
  825. }/* * * * * * * * * * * END OF mjhand() * * * * * * * * * * */