/branches/yoyo/sdcc/link/z80/lklist.c

# · C · 1268 lines · 737 code · 60 blank · 471 comment · 266 complexity · b25c7d98094ba14505d92ed24b68ae4f MD5 · raw file

  1. /* lklist.c */
  2. /*
  3. * (C) Copyright 1989-1995
  4. * All Rights Reserved
  5. *
  6. * Alan R. Baldwin
  7. * 721 Berkeley St.
  8. * Kent, Ohio 44240
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <alloc.h>
  13. #include "aslink.h"
  14. /*)Module lklist.c
  15. *
  16. * The module lklist.c contains the functions which
  17. * output the linker .map file and produce a relocated
  18. * listing .rst file.
  19. *
  20. * lklist.c contains the following functions:
  21. * int dgt()
  22. * VOID lstarea()
  23. * VOID lkulist()
  24. * VOID lkalist()
  25. * VOID lkglist()
  26. * VOID newpag()
  27. * VOID slew()
  28. *
  29. * lklist.c contains no local variables.
  30. */
  31. /*)Function VOID slew(fp)
  32. *
  33. * FILE * fp output file handle
  34. *
  35. * The function slew() increments the page line counter.
  36. * If the number of lines exceeds the maximum number of
  37. * lines per page then a page skip and a page header are
  38. * output.
  39. *
  40. * local variables:
  41. * int i loop counter
  42. *
  43. * global variables:
  44. * int lop current line number on page
  45. * int xflag Map file radix type flag
  46. *
  47. * functions called:
  48. * int fprintf() c_library
  49. * VOID newpag() lklist.c
  50. *
  51. * side effects:
  52. * The page line and the page count may be updated.
  53. */
  54. VOID
  55. slew(fp)
  56. FILE *fp;
  57. {
  58. register i;
  59. if (lop++ >= NLPP) {
  60. newpag(fp);
  61. if (xflag == 0) {
  62. fprintf(fp, "Hexidecimal\n\n");
  63. } else
  64. if (xflag == 1) {
  65. fprintf(fp, "Octal\n\n");
  66. } else
  67. if (xflag == 2) {
  68. fprintf(fp, "Decimal\n\n");
  69. }
  70. fprintf(fp, "Area Addr Size");
  71. fprintf(fp, " Decimal Bytes (Attributes)\n");
  72. for(i=0;i<4;++i)
  73. fprintf(fp, " Value--Global");
  74. fprintf(fp, "\n\n");
  75. lop += 6;
  76. }
  77. }
  78. /*)Function VOID newpag()
  79. *
  80. * The function newpag() outputs a page skip, writes the
  81. * first page header line, sets the line count to 1, and
  82. * increments the page counter.
  83. *
  84. * local variables:
  85. * none
  86. *
  87. * global variables:
  88. * int lop current line number on page
  89. * int page current page number
  90. *
  91. * functions called:
  92. * int fprintf() c_library
  93. *
  94. * side effects:
  95. * The page and line counters are updated.
  96. */
  97. VOID
  98. newpag(fp)
  99. FILE *fp;
  100. {
  101. fprintf(fp, "\fASxxxx Linker %s, page %u.\n", VERSION, ++page);
  102. lop = 1;
  103. }
  104. #if NCPS-8
  105. /* NCPS != 8 */
  106. /*)Function VOID lstarea(xp)
  107. *
  108. * area * xp pointer to an area structure
  109. *
  110. * The function lstarea() creates the linker map output for
  111. * the area specified by pointer xp. The generated output
  112. * area header includes the area name, starting address,
  113. * size of area, number of words (in decimal), and the
  114. * area attributes. The symbols defined in this area are
  115. * sorted by ascending address and output one per line
  116. * in the selected radix.
  117. *
  118. * local variables:
  119. * areax * oxp pointer to an area extension structure
  120. * int c character value
  121. * int i loop counter
  122. * int j bubble sort update status
  123. * char * ptr pointer to an id string
  124. * int nmsym number of symbols in area
  125. * addr_t a0 temporary
  126. * addr_t ai temporary
  127. * addr_t aj temporary
  128. * sym * sp pointer to a symbol structure
  129. * sym ** p pointer to an array of
  130. * pointers to symbol structures
  131. *
  132. * global variables:
  133. * FILE *mfp Map output file handle
  134. * sym *symhash[NHASH] array of pointers to NHASH
  135. * linked symbol lists
  136. * int xflag Map file radix type flag
  137. *
  138. * functions called:
  139. * int fprintf() c_library
  140. * VOID free() c_library
  141. * char * malloc() c_library
  142. * char putc() c_library
  143. * VOID slew() lklist.c
  144. *
  145. * side effects:
  146. * Map output generated.
  147. */
  148. #ifndef MLH_MAP
  149. VOID
  150. lstarea(xp)
  151. struct area *xp;
  152. {
  153. register struct area *op;
  154. register struct areax *oxp;
  155. register c, i, j;
  156. register char *ptr;
  157. int nmsym;
  158. addr_t a0, ai, aj;
  159. struct sym *sp;
  160. struct sym **p;
  161. putc('\n', mfp);
  162. if (xflag == 0) {
  163. fprintf(mfp, "Hexidecimal\n\n");
  164. } else
  165. if (xflag == 1) {
  166. fprintf(mfp, "Octal\n\n");
  167. } else
  168. if (xflag == 2) {
  169. fprintf(mfp, "Decimal\n\n");
  170. }
  171. fprintf(mfp, "Area ");
  172. fprintf(mfp, "Addr Size Decimal Bytes (Attributes)\n");
  173. fprintf(mfp, "-------------------------------- ");
  174. fprintf(mfp, "---- ---- ------- ----- ------------\n");
  175. /*
  176. * Output Area Header
  177. */
  178. ptr = &xp->a_id[0];
  179. while (ptr < &xp->a_id[NCPS]) {
  180. if ((c = *ptr++) != 0) {
  181. putc(c, mfp);
  182. } else {
  183. putc(' ', mfp);
  184. }
  185. }
  186. ai = xp->a_addr;
  187. aj = xp->a_size;
  188. if (xflag == 0) {
  189. fprintf(mfp, " %04X %04X", ai, aj);
  190. } else
  191. if (xflag == 1) {
  192. fprintf(mfp, " %06o %06o", ai, aj);
  193. } else
  194. if (xflag == 2) {
  195. fprintf(mfp, " %05u %05u", ai, aj);
  196. }
  197. fprintf(mfp, " = %6u. bytes ", aj);
  198. if (xp->a_flag & A_ABS) {
  199. fprintf(mfp, "(ABS");
  200. } else {
  201. fprintf(mfp, "(REL");
  202. }
  203. if (xp->a_flag & A_OVR) {
  204. fprintf(mfp, ",OVR");
  205. } else {
  206. fprintf(mfp, ",CON");
  207. }
  208. if (xp->a_flag & A_PAG) {
  209. fprintf(mfp, ",PAG");
  210. }
  211. fprintf(mfp, ")");
  212. if (xp->a_flag & A_PAG) {
  213. ai = (ai & 0xFF);
  214. aj = (aj > 256);
  215. if (ai || aj) { fprintf(mfp, " "); }
  216. if (ai) { fprintf(mfp, " Boundary"); }
  217. if (ai & aj) { fprintf(mfp, " /"); }
  218. if (aj) { fprintf(mfp, " Length"); }
  219. if (ai || aj) { fprintf(mfp, " Error"); }
  220. }
  221. /*
  222. * Find number of symbols in area
  223. */
  224. nmsym = 0;
  225. oxp = xp->a_axp;
  226. while (oxp) {
  227. for (i=0; i<NHASH; i++) {
  228. sp = symhash[i];
  229. while (sp != NULL) {
  230. if (oxp == sp->s_axp)
  231. ++nmsym;
  232. sp = sp->s_sp;
  233. }
  234. }
  235. oxp = oxp->a_axp;
  236. }
  237. if (nmsym == 0) {
  238. putc('\n', mfp);
  239. return;
  240. }
  241. /*
  242. * Allocate space for an array of pointers to symbols
  243. * and load array.
  244. */
  245. if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
  246. == NULL) {
  247. fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
  248. return;
  249. }
  250. nmsym = 0;
  251. oxp = xp->a_axp;
  252. while (oxp) {
  253. for (i=0; i<NHASH; i++) {
  254. sp = symhash[i];
  255. while (sp != NULL) {
  256. if (oxp == sp->s_axp) {
  257. p[nmsym++] = sp;
  258. }
  259. sp = sp->s_sp;
  260. }
  261. }
  262. oxp = oxp->a_axp;
  263. }
  264. /*
  265. * Bubble Sort of Addresses in Symbol Table Array
  266. */
  267. j = 1;
  268. while (j) {
  269. j = 0;
  270. sp = p[0];
  271. a0 = sp->s_addr + sp->s_axp->a_addr;
  272. for (i=1; i<nmsym; ++i) {
  273. sp = p[i];
  274. ai = sp->s_addr + sp->s_axp->a_addr;
  275. if (a0 > ai) {
  276. j = 1;
  277. p[i] = p[i-1];
  278. p[i-1] = sp;
  279. }
  280. a0 = ai;
  281. }
  282. }
  283. /*
  284. * Symbol Table Output
  285. */
  286. i = 0;
  287. fprintf(mfp, "\n\n");
  288. fprintf(mfp, " Value Global\n");
  289. fprintf(mfp, " ----- --------------------------------");
  290. while (i < nmsym) {
  291. fprintf(mfp, "\n");
  292. fprintf(mfp, " ");
  293. sp = p[i];
  294. aj = sp->s_addr + sp->s_axp->a_addr;
  295. if (xflag == 0) {
  296. fprintf(mfp, " %04X ", aj);
  297. } else
  298. if (xflag == 1) {
  299. fprintf(mfp, "%06o ", aj);
  300. } else
  301. if (xflag == 2) {
  302. fprintf(mfp, " %05u ", aj);
  303. }
  304. ptr = &sp->s_id[0];
  305. while (ptr < &sp->s_id[NCPS]) {
  306. if ((c = *ptr++) != 0) {
  307. putc(c, mfp);
  308. } else {
  309. putc(' ', mfp);
  310. }
  311. }
  312. i++;
  313. }
  314. putc('\n', mfp);
  315. free(p);
  316. }
  317. #else
  318. VOID lstarea(struct area *xp)
  319. {
  320. register struct area *op;
  321. register struct areax *oxp;
  322. register c, i, j;
  323. register char *ptr;
  324. int nmsym;
  325. addr_t a0, ai, aj;
  326. struct sym *sp;
  327. struct sym **p;
  328. /*
  329. * Find number of symbols in area
  330. */
  331. nmsym = 0;
  332. oxp = xp->a_axp;
  333. while (oxp) {
  334. for (i=0; i<NHASH; i++) {
  335. sp = symhash[i];
  336. while (sp != NULL) {
  337. if (oxp == sp->s_axp)
  338. ++nmsym;
  339. sp = sp->s_sp;
  340. }
  341. }
  342. oxp = oxp->a_axp;
  343. }
  344. /*
  345. * Symbol Table Output
  346. */
  347. if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
  348. fprintf(mfp, "AREA %s\n", xp->a_id );
  349. switch (xflag) {
  350. case 1:
  351. fprintf(mfp, "\tRADIX OCTAL\n" );
  352. break;
  353. case 2:
  354. fprintf(mfp, "\tRADIX DEC\n" );
  355. break;
  356. default:
  357. fprintf(mfp, "\tRADIX HEX\n" );
  358. break;
  359. }
  360. fprintf( mfp, "\tBASE %04X\n"
  361. "\tSIZE %04X\n"
  362. "\tATTRIB "
  363. , xp->a_addr, xp->a_size );
  364. if (xp->a_flag & A_ABS) {
  365. fprintf(mfp, "ABS");
  366. } else {
  367. fprintf(mfp, "REL");
  368. }
  369. if (xp->a_flag & A_OVR) {
  370. fprintf(mfp, " OVR");
  371. } else {
  372. fprintf(mfp, " CON");
  373. }
  374. if (xp->a_flag & A_PAG) {
  375. fprintf(mfp, " PAG");
  376. }
  377. if (xp->a_flag & A_PAG) {
  378. ai = (ai & 0xFF);
  379. aj = (aj > 256);
  380. if (ai || aj) { fprintf(mfp, " "); }
  381. if (ai) { fprintf(mfp, " Boundary"); }
  382. if (ai & aj) { fprintf(mfp, " /"); }
  383. if (aj) { fprintf(mfp, " Length"); }
  384. if (ai || aj) { fprintf(mfp, " Error"); }
  385. }
  386. fprintf( mfp,"\n");
  387. if (nmsym>0) {
  388. /*
  389. * Allocate space for an array of pointers to symbols
  390. * and load array.
  391. */
  392. if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
  393. == NULL) {
  394. fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
  395. return;
  396. }
  397. nmsym = 0;
  398. oxp = xp->a_axp;
  399. while (oxp) {
  400. for (i=0; i<NHASH; i++) {
  401. sp = symhash[i];
  402. while (sp != NULL) {
  403. if (oxp == sp->s_axp) {
  404. p[nmsym++] = sp;
  405. }
  406. sp = sp->s_sp;
  407. }
  408. }
  409. oxp = oxp->a_axp;
  410. }
  411. /*
  412. * Bubble Sort of Addresses in Symbol Table Array
  413. */
  414. j = 1;
  415. while (j) {
  416. j = 0;
  417. sp = p[0];
  418. a0 = sp->s_addr + sp->s_axp->a_addr;
  419. for (i=1; i<nmsym; ++i) {
  420. sp = p[i];
  421. ai = sp->s_addr + sp->s_axp->a_addr;
  422. if (a0 > ai) {
  423. j = 1;
  424. p[i] = p[i-1];
  425. p[i-1] = sp;
  426. }
  427. a0 = ai;
  428. }
  429. }
  430. fprintf( mfp, "\tGLOBALS\n");
  431. i = 0;
  432. while (i < nmsym) {
  433. fprintf(mfp, "\t\t%s\t%04X\n", p[i]->s_id, p[i]->s_addr + p[i]->s_axp->a_addr );
  434. i++;
  435. }
  436. free(p);
  437. }
  438. }
  439. }
  440. #endif /* MLH_MAP */
  441. #else
  442. /* NCPS == 8 */
  443. /*)Function VOID lstarea(xp)
  444. *
  445. * area * xp pointer to an area structure
  446. *
  447. * The function lstarea() creates the linker map output for
  448. * the area specified by pointer xp. The generated output
  449. * area header includes the area name, starting address,
  450. * size of area, number of words (in decimal), and the
  451. * area attributes. The symbols defined in this area are
  452. * sorted by ascending address and output four per line
  453. * in the selected radix.
  454. *
  455. * local variables:
  456. * areax * oxp pointer to an area extension structure
  457. * int c character value
  458. * int i loop counter
  459. * int j bubble sort update status
  460. * char * ptr pointer to an id string
  461. * int nmsym number of symbols in area
  462. * addr_t a0 temporary
  463. * addr_t ai temporary
  464. * addr_t aj temporary
  465. * sym * sp pointer to a symbol structure
  466. * sym ** p pointer to an array of
  467. * pointers to symbol structures
  468. *
  469. * global variables:
  470. * FILE *mfp Map output file handle
  471. * sym *symhash[NHASH] array of pointers to NHASH
  472. * linked symbol lists
  473. * int xflag Map file radix type flag
  474. *
  475. * functions called:
  476. * int fprintf() c_library
  477. * VOID free() c_library
  478. * char * malloc() c_library
  479. * char putc() c_library
  480. * VOID slew() lklist.c
  481. *
  482. * side effects:
  483. * Map output generated.
  484. */
  485. VOID
  486. lstarea(xp)
  487. struct area *xp;
  488. {
  489. register struct areax *oxp;
  490. register c, i, j;
  491. register char *ptr;
  492. int nmsym;
  493. addr_t a0, ai, aj;
  494. struct sym *sp;
  495. struct sym **p;
  496. putc('\n', mfp);
  497. slew(mfp);
  498. /*
  499. * Output Area Header
  500. */
  501. ptr = &xp->a_id[0];
  502. while (ptr < &xp->a_id[NCPS]) {
  503. if ((c = *ptr++) != 0) {
  504. putc(c, mfp);
  505. } else {
  506. putc(' ', mfp);
  507. }
  508. }
  509. ai = xp->a_addr;
  510. aj = xp->a_size;
  511. if (xflag == 0) {
  512. fprintf(mfp, " %04X %04X", ai, aj);
  513. } else
  514. if (xflag == 1) {
  515. fprintf(mfp, " %06o %06o", ai, aj);
  516. } else
  517. if (xflag == 2) {
  518. fprintf(mfp, " %05u %05u", ai, aj);
  519. }
  520. fprintf(mfp, " = %6u. bytes ", aj);
  521. if (xp->a_flag & A_ABS) {
  522. fprintf(mfp, "(ABS");
  523. } else {
  524. fprintf(mfp, "(REL");
  525. }
  526. if (xp->a_flag & A_OVR) {
  527. fprintf(mfp, ",OVR");
  528. } else {
  529. fprintf(mfp, ",CON");
  530. }
  531. if (xp->a_flag & A_PAG) {
  532. fprintf(mfp, ",PAG");
  533. }
  534. fprintf(mfp, ")");
  535. if (xp->a_flag & A_PAG) {
  536. ai = (ai & 0xFF);
  537. aj = (aj > 256);
  538. if (ai || aj) { fprintf(mfp, " "); }
  539. if (ai) { fprintf(mfp, " Boundary"); }
  540. if (ai & aj) { fprintf(mfp, " /"); }
  541. if (aj) { fprintf(mfp, " Length"); }
  542. if (ai || aj) { fprintf(mfp, " Error"); }
  543. }
  544. /*
  545. * Find number of symbols in area
  546. */
  547. nmsym = 0;
  548. oxp = xp->a_axp;
  549. while (oxp) {
  550. for (i=0; i<NHASH; i++) {
  551. sp = symhash[i];
  552. while (sp != NULL) {
  553. if (oxp == sp->s_axp)
  554. ++nmsym;
  555. sp = sp->s_sp;
  556. }
  557. }
  558. oxp = oxp->a_axp;
  559. }
  560. if (nmsym == 0) {
  561. putc('\n', mfp);
  562. slew(mfp);
  563. return;
  564. }
  565. /*
  566. * Allocate space for an array of pointers to symbols
  567. * and load array.
  568. */
  569. if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
  570. == NULL) {
  571. fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
  572. slew(mfp);
  573. return;
  574. }
  575. nmsym = 0;
  576. oxp = xp->a_axp;
  577. while (oxp) {
  578. for (i=0; i<NHASH; i++) {
  579. sp = symhash[i];
  580. while (sp != NULL) {
  581. if (oxp == sp->s_axp) {
  582. p[nmsym++] = sp;
  583. }
  584. sp = sp->s_sp;
  585. }
  586. }
  587. oxp = oxp->a_axp;
  588. }
  589. /*
  590. * Bubble Sort of Addresses in Symbol Table Array
  591. */
  592. j = 1;
  593. while (j) {
  594. j = 0;
  595. sp = p[0];
  596. a0 = sp->s_addr + sp->s_axp->a_addr;
  597. for (i=1; i<nmsym; ++i) {
  598. sp = p[i];
  599. ai = sp->s_addr + sp->s_axp->a_addr;
  600. if (a0 > ai) {
  601. j = 1;
  602. p[i] = p[i-1];
  603. p[i-1] = sp;
  604. }
  605. a0 = ai;
  606. }
  607. }
  608. /*
  609. * Symbol Table Output
  610. */
  611. i = 0;
  612. while (i < nmsym) {
  613. if (i % 4 == 0) {
  614. fprintf(mfp, "\n");
  615. slew(mfp);
  616. fprintf(mfp, " ");
  617. }
  618. sp = p[i];
  619. aj = sp->s_addr + sp->s_axp->a_addr;
  620. if (xflag == 0) {
  621. fprintf(mfp, " %04X ", aj);
  622. } else
  623. if (xflag == 1) {
  624. fprintf(mfp, "%06o ", aj);
  625. } else
  626. if (xflag == 2) {
  627. fprintf(mfp, " %05u ", aj);
  628. }
  629. ptr = &sp->s_id[0];
  630. while (ptr < &sp->s_id[NCPS]) {
  631. if ((c = *ptr++) != 0) {
  632. putc(c, mfp);
  633. } else {
  634. putc(' ', mfp);
  635. }
  636. }
  637. if (++i < nmsym)
  638. if (i % 4 != 0)
  639. fprintf(mfp, " | ");
  640. }
  641. putc('\n', mfp);
  642. free(p);
  643. slew(mfp);
  644. }
  645. #endif
  646. #ifdef SDK
  647. VOID lstareatosym(struct area *xp)
  648. {
  649. /* Output the current area symbols to a NO$GMB .sym file */
  650. register struct areax *oxp;
  651. register i, j;
  652. int nmsym;
  653. addr_t a0, ai;
  654. struct sym *sp;
  655. struct sym **p;
  656. /*
  657. * Find number of symbols in area
  658. */
  659. nmsym = 0;
  660. oxp = xp->a_axp;
  661. while (oxp) {
  662. for (i=0; i<NHASH; i++) {
  663. sp = symhash[i];
  664. while (sp != NULL) {
  665. if (oxp == sp->s_axp)
  666. ++nmsym;
  667. sp = sp->s_sp;
  668. }
  669. }
  670. oxp = oxp->a_axp;
  671. }
  672. /*
  673. * Symbol Table Output
  674. */
  675. if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
  676. /* Dont worry about any area information */
  677. fprintf(mfp, "; Area: %s\n", xp->a_id );
  678. if (nmsym>0) {
  679. /*
  680. * Allocate space for an array of pointers to symbols
  681. * and load array.
  682. */
  683. if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
  684. == NULL) {
  685. fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
  686. return;
  687. }
  688. nmsym = 0;
  689. oxp = xp->a_axp;
  690. while (oxp) {
  691. for (i=0; i<NHASH; i++) {
  692. sp = symhash[i];
  693. while (sp != NULL) {
  694. if (oxp == sp->s_axp) {
  695. p[nmsym++] = sp;
  696. }
  697. sp = sp->s_sp;
  698. }
  699. }
  700. oxp = oxp->a_axp;
  701. }
  702. /*
  703. * Bubble Sort of Addresses in Symbol Table Array
  704. */
  705. j = 1;
  706. while (j) {
  707. j = 0;
  708. sp = p[0];
  709. a0 = sp->s_addr + sp->s_axp->a_addr;
  710. for (i=1; i<nmsym; ++i) {
  711. sp = p[i];
  712. ai = sp->s_addr + sp->s_axp->a_addr;
  713. if (a0 > ai) {
  714. j = 1;
  715. p[i] = p[i-1];
  716. p[i-1] = sp;
  717. }
  718. a0 = ai;
  719. }
  720. }
  721. i = 0;
  722. while (i < nmsym) {
  723. if ((strncmp("l__", p[i]->s_id, 3)!=0)&&(strchr(p[i]->s_id,' ')==NULL)) {
  724. a0=p[i]->s_addr + p[i]->s_axp->a_addr;
  725. if (a0>0x7FFFU) {
  726. /* Not inside the ROM, so treat as being in bank zero */
  727. fprintf(mfp, "00:%04X %s\n", a0, p[i]->s_id);
  728. }
  729. else {
  730. fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, p[i]->s_id );
  731. }
  732. }
  733. i++;
  734. }
  735. free(p);
  736. }
  737. }
  738. }
  739. #endif
  740. /*)Function VOID lkulist(i)
  741. *
  742. * int i i # 0 process LST to RST file
  743. * i = 0 copy remainder of LST file
  744. * to RST file and close files
  745. *
  746. * The function lkulist() creates a relocated listing (.rst)
  747. * output file from the ASxxxx assembler listing (.lst)
  748. * files. The .lst file's program address and code bytes
  749. * are changed to reflect the changes made by ASlink as
  750. * the .rel files are combined into a single relocated
  751. * output file.
  752. *
  753. * local variables:
  754. * addr_t pc current program counter address
  755. *
  756. * global variables:
  757. * int hilo byte order
  758. * int gline get a line from the LST file
  759. * to translate for the RST file
  760. * char rb[] read listing file text line
  761. * FILE *rfp The file handle to the current
  762. * output RST file
  763. * int rtcnt count of data words
  764. * int rtflg[] output the data flag
  765. * addr_t rtval[] relocated data
  766. * FILE *tfp The file handle to the current
  767. * LST file being scanned
  768. *
  769. * functions called:
  770. * int fclose() c_library
  771. * int fgets() c_library
  772. * int fprintf() c_library
  773. * VOID lkalist() lklist.c
  774. * VOID lkglist() lklist.c
  775. *
  776. * side effects:
  777. * A .rst file is created for each available .lst
  778. * file associated with a .rel file.
  779. */
  780. VOID
  781. lkulist(i)
  782. int i;
  783. {
  784. addr_t pc;
  785. /*
  786. * Exit if listing file is not open
  787. */
  788. if (tfp == NULL)
  789. return;
  790. /*
  791. * Normal processing of LST to RST
  792. */
  793. if (i) {
  794. /*
  795. * Evaluate current code address
  796. */
  797. if (hilo == 0) {
  798. pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
  799. } else {
  800. pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
  801. }
  802. /*
  803. * Line with only address
  804. */
  805. if (rtcnt == 2) {
  806. lkalist(pc);
  807. /*
  808. * Line with address and code
  809. */
  810. } else {
  811. for (i=2; i < rtcnt; i++) {
  812. if (rtflg[i]) {
  813. lkglist(pc++, rtval[i] & 0xFF);
  814. }
  815. }
  816. }
  817. /*
  818. * Copy remainder of LST to RST
  819. */
  820. } else {
  821. if (gline == 0)
  822. fprintf(rfp, rb);
  823. while (fgets(rb, sizeof(rb), tfp) != 0) {
  824. fprintf(rfp, rb);
  825. }
  826. fclose(tfp);
  827. tfp = NULL;
  828. fclose(rfp);
  829. rfp = NULL;
  830. }
  831. }
  832. /*)Function VOID lkalist(pc)
  833. *
  834. * int pc current program counter value
  835. *
  836. * The function lkalist() performs the following functions:
  837. *
  838. * (1) if the value of gline = 0 then the current listing
  839. * file line is copied to the relocated listing file output.
  840. *
  841. * (2) the listing file is read line by line and copied to
  842. * the relocated listing file until a valid source
  843. * line number and a program counter value of the correct
  844. * radix is found. The new relocated pc value is substituted
  845. * and the line is written to the RST file.
  846. *
  847. * local variables:
  848. * int i loop counter
  849. * char str[] temporary string
  850. *
  851. * global variables:
  852. * int gcntr data byte counter
  853. * int gline get a line from the LST file
  854. * to translate for the RST file
  855. * char rb[] read listing file text line
  856. * char *rp pointer to listing file text line
  857. * FILE *rfp The file handle to the current
  858. * output RST file
  859. * FILE *tfp The file handle to the current
  860. * LST file being scanned
  861. *
  862. * functions called:
  863. * int dgt() lklist.c
  864. * int fclose() c_library
  865. * int fgets() c_library
  866. * int fprintf() c_library
  867. * int sprintf() c_library
  868. * char * strncpy() c_library
  869. *
  870. * side effects:
  871. * Lines of the LST file are copied to the RST file,
  872. * the last line copied has the code address
  873. * updated to reflect the program relocation.
  874. */
  875. VOID
  876. lkalist(pc)
  877. addr_t pc;
  878. {
  879. char str[8];
  880. int i;
  881. /*
  882. * Exit if listing file is not open
  883. */
  884. loop: if (tfp == NULL)
  885. return;
  886. /*
  887. * Copy current LST to RST
  888. */
  889. if (gline == 0) {
  890. fprintf(rfp, rb);
  891. gline = 1;
  892. }
  893. /*
  894. * Clear text line buffer
  895. */
  896. for (i=0,rp=rb; i<sizeof(rb); i++) {
  897. *rp++ = 0;
  898. }
  899. /*
  900. * Get next LST text line
  901. */
  902. if (fgets(rb, sizeof(rb), tfp) == NULL) {
  903. fclose(tfp);
  904. tfp = NULL;
  905. fclose(rfp);
  906. rfp = NULL;
  907. return;
  908. }
  909. /*
  910. * Must have an ASxxxx Listing line number
  911. */
  912. if (!dgt(RAD10, &rb[30], 1)) {
  913. fprintf(rfp, rb);
  914. goto loop;
  915. }
  916. /*
  917. * Must have an address in the expected radix
  918. */
  919. if (radix == 16) {
  920. if (!dgt(RAD16, &rb[3], 4)) {
  921. fprintf(rfp, rb);
  922. goto loop;
  923. }
  924. sprintf(str, "%04X", pc);
  925. strncpy(&rb[3], str, 4);
  926. } else
  927. if (radix == 10) {
  928. if (!dgt(RAD10, &rb[3], 5)) {
  929. fprintf(rfp, rb);
  930. goto loop;
  931. }
  932. sprintf(str, "%05d", pc);
  933. strncpy(&rb[3], str, 5);
  934. } else
  935. if (radix == 8) {
  936. if (!dgt(RAD8, &rb[3], 6)) {
  937. fprintf(rfp, rb);
  938. goto loop;
  939. }
  940. sprintf(str, "%06o", pc);
  941. strncpy(&rb[3], str, 6);
  942. }
  943. /*
  944. * Copy updated LST text line to RST
  945. */
  946. fprintf(rfp, rb);
  947. gcntr = 0;
  948. }
  949. /*)Function VOID lkglist(pc,v)
  950. *
  951. * int pc current program counter value
  952. * int v value of byte at this address
  953. *
  954. * The function lkglist() performs the following functions:
  955. *
  956. * (1) if the value of gline = 1 then the listing file
  957. * is read line by line and copied to the
  958. * relocated listing file until a valid source
  959. * line number and a program counter value of the correct
  960. * radix is found.
  961. *
  962. * (2) The new relocated values and code address are
  963. * substituted and the line may be written to the RST file.
  964. *
  965. * local variables:
  966. * int i loop counter
  967. * char str[] temporary string
  968. *
  969. * global variables:
  970. * int gcntr data byte counter
  971. * set to -1 for a continuation line
  972. * int gline get a line from the LST file
  973. * to translate for the RST file
  974. * char rb[] read listing file text line
  975. * char *rp pointer to listing file text line
  976. * FILE *rfp The file handle to the current
  977. * output RST file
  978. * FILE *tfp The file handle to the current
  979. * LST file being scanned
  980. *
  981. * functions called:
  982. * int dgt() lklist.c
  983. * int fclose() c_library
  984. * int fgets() c_library
  985. * int fprintf() c_library
  986. * int sprintf() c_library
  987. * char * strncpy() c_library
  988. *
  989. * side effects:
  990. * Lines of the LST file are copied to the RST file
  991. * with updated data values and code addresses.
  992. */
  993. VOID
  994. lkglist(pc,v)
  995. addr_t pc;
  996. int v;
  997. {
  998. char str[8];
  999. int i;
  1000. /*
  1001. * Exit if listing file is not open
  1002. */
  1003. loop: if (tfp == NULL)
  1004. return;
  1005. /*
  1006. * Get next LST text line
  1007. */
  1008. if (gline) {
  1009. /*
  1010. * Clear text line buffer
  1011. */
  1012. for (i=0,rp=rb; i<sizeof(rb); i++) {
  1013. *rp++ = 0;
  1014. }
  1015. /*
  1016. * Get next LST text line
  1017. */
  1018. if (fgets(rb, sizeof(rb), tfp) == NULL) {
  1019. fclose(tfp);
  1020. tfp = NULL;
  1021. fclose(rfp);
  1022. rfp = NULL;
  1023. return;
  1024. }
  1025. /*
  1026. * Check for a listing line number if required
  1027. */
  1028. if (gcntr != -1) {
  1029. if (!dgt(RAD10, &rb[30], 1)) {
  1030. fprintf(rfp, rb);
  1031. goto loop;
  1032. }
  1033. gcntr = 0;
  1034. }
  1035. gline = 0;
  1036. }
  1037. /*
  1038. * Hex Listing
  1039. */
  1040. if (radix == 16) {
  1041. /*
  1042. * Data Byte Pointer
  1043. */
  1044. if (gcntr == -1) {
  1045. rp = &rb[8];
  1046. } else {
  1047. rp = &rb[8 + (3 * gcntr)];
  1048. }
  1049. /*
  1050. * Number must be of proper radix
  1051. */
  1052. if (!dgt(RAD16, rp, 2)) {
  1053. fprintf(rfp, rb);
  1054. gline = 1;
  1055. goto loop;
  1056. }
  1057. /*
  1058. * Output new data value, overwrite relocation codes
  1059. */
  1060. sprintf(str, " %02X", v);
  1061. strncpy(rp-1, str, 3);
  1062. if (gcntr == -1) {
  1063. gcntr = 0;
  1064. }
  1065. /*
  1066. * Output relocated code address
  1067. */
  1068. if (gcntr == 0) {
  1069. if (dgt(RAD16, &rb[3], 4)) {
  1070. sprintf(str, "%04X", pc);
  1071. strncpy(&rb[3], str, 4);
  1072. }
  1073. }
  1074. /*
  1075. * Output text line when updates finished
  1076. */
  1077. if (++gcntr == 6) {
  1078. fprintf(rfp, rb);
  1079. gline = 1;
  1080. gcntr = -1;
  1081. }
  1082. } else
  1083. /*
  1084. * Decimal Listing
  1085. */
  1086. if (radix == 10) {
  1087. /*
  1088. * Data Byte Pointer
  1089. */
  1090. if (gcntr == -1) {
  1091. rp = &rb[9];
  1092. } else {
  1093. rp = &rb[9 + (3 * gcntr)];
  1094. }
  1095. /*
  1096. * Number must be of proper radix
  1097. */
  1098. if (!dgt(RAD10, rp, 3)) {
  1099. fprintf(rfp, rb);
  1100. gline = 1;
  1101. goto loop;
  1102. }
  1103. /*
  1104. * Output new data value, overwrite relocation codes
  1105. */
  1106. sprintf(str, " %03d", v);
  1107. strncpy(rp-1, str, 4);
  1108. if (gcntr == -1) {
  1109. gcntr = 0;
  1110. }
  1111. /*
  1112. * Output relocated code address
  1113. */
  1114. if (gcntr == 0) {
  1115. if (dgt(RAD10, &rb[3], 5)) {
  1116. sprintf(str, "%05d", pc);
  1117. strncpy(&rb[3], str, 5);
  1118. }
  1119. }
  1120. /*
  1121. * Output text line when updates finished
  1122. */
  1123. if (++gcntr == 4) {
  1124. fprintf(rfp, rb);
  1125. gline = 1;
  1126. gcntr = -1;
  1127. }
  1128. } else
  1129. /*
  1130. * Octal Listing
  1131. */
  1132. if (radix == 8) {
  1133. /*
  1134. * Data Byte Pointer
  1135. */
  1136. if (gcntr == -1) {
  1137. rp = &rb[10];
  1138. } else {
  1139. rp = &rb[10 + (3 * gcntr)];
  1140. }
  1141. /*
  1142. * Number must be of proper radix
  1143. */
  1144. if (!dgt(RAD8, rp, 3)) {
  1145. fprintf(rfp, rb);
  1146. gline = 1;
  1147. goto loop;
  1148. }
  1149. /*
  1150. * Output new data value, overwrite relocation codes
  1151. */
  1152. sprintf(str, " %03o", v);
  1153. strncpy(rp-1, str, 4);
  1154. if (gcntr == -1) {
  1155. gcntr = 0;
  1156. }
  1157. /*
  1158. * Output relocated code address
  1159. */
  1160. if (gcntr == 0) {
  1161. if (dgt(RAD8, &rb[3], 6)) {
  1162. sprintf(str, "%06o", pc);
  1163. strncpy(&rb[3], str, 6);
  1164. }
  1165. }
  1166. /*
  1167. * Output text line when updates finished
  1168. */
  1169. if (++gcntr == 4) {
  1170. fprintf(rfp, rb);
  1171. gline = 1;
  1172. gcntr = -1;
  1173. }
  1174. }
  1175. }
  1176. /*)Function int dgt(rdx,str,n)
  1177. *
  1178. * int rdx radix bit code
  1179. * char *str pointer to the test string
  1180. * int n number of characters to check
  1181. *
  1182. * The function dgt() verifies that the string under test
  1183. * is of the specified radix.
  1184. *
  1185. * local variables:
  1186. * int i loop counter
  1187. *
  1188. * global variables:
  1189. * ctype[] array of character types
  1190. *
  1191. * functions called:
  1192. * none
  1193. *
  1194. * side effects:
  1195. * none
  1196. */
  1197. int
  1198. dgt(rdx, str, n)
  1199. int rdx, n;
  1200. char *str;
  1201. {
  1202. int i;
  1203. for (i=0; i<n; i++) {
  1204. if ((ctype[*str++] & rdx) == 0)
  1205. return(0);
  1206. }
  1207. return(1);
  1208. }