home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2183 < prev    next >
Internet Message Format  |  1990-12-28  |  50KB

  1. From: markz@ssc.UUCP (Mark Zenier)
  2. Newsgroups: alt.sources
  3. Subject: Frankenstein Cross Assemblers, Base source, Part 2 of 3
  4. Message-ID: <593@ssc.UUCP>
  5. Date: 4 Dec 90 07:48:06 GMT
  6.  
  7. ---- Cut Here and feed the following to sh ----
  8. #!/bin/sh
  9. # This is part 02 of Frankasm/Base
  10. # ============= fraosub.c ==============
  11. if test -f 'fraosub.c' -a X"$1" != X"-c"; then
  12.     echo 'x - skipping fraosub.c (File already exists)'
  13. else
  14. echo 'x - extracting fraosub.c (Text)'
  15. sed 's/^X//' << 'SHAR_EOF' > 'fraosub.c' &&
  16. X/*
  17. XHEADER:     ;
  18. XTITLE:         Frankenstein Cross Assemblers;
  19. XVERSION:     2.0;
  20. XDESCRIPTION: "    Reconfigurable Cross-assembler producing Intel (TM)
  21. X        Hex format object records.  ";
  22. XSYSTEM:     UNIX, MS-Dos ;
  23. XFILENAME:     fraosub.c;
  24. XWARNINGS:     "This software is in the public domain.  
  25. X        Any prior copyright claims are relinquished.  
  26. X
  27. X        This software is distributed with no warranty whatever.  
  28. X        The author takes no responsibility for the consequences 
  29. X        of its use."  ;
  30. XSEE-ALSO:     frasmain.c;
  31. XAUTHORS:     Mark Zenier;
  32. X*/
  33. X
  34. X/*
  35. X    description    output pass utility routines
  36. X    history        September 27, 1987
  37. X            March 15, 1988   release 1.1 WIDTH
  38. X            September 14, 1990  Dosify, 6 char unique names
  39. X*/
  40. X
  41. X
  42. X#include <stdio.h>
  43. X#include "frasmdat.h"
  44. X#include "fragcon.h"
  45. X
  46. X#define OUTRESULTLEN 256
  47. X#define NUMHEXPERL 16
  48. X#define SOURCEOFFSET 24
  49. X#define NUMHEXSOURCE 6
  50. X
  51. Xint linenumber = 0;
  52. Xchar lineLbuff[INBUFFSZ];
  53. Xint lineLflag = FALSE;
  54. X
  55. Xstatic unsigned char    outresult[OUTRESULTLEN];
  56. Xstatic int    nextresult;
  57. Xstatic long     genlocctr, resultloc;
  58. X
  59. Xstatic char    *oeptr;
  60. X
  61. X#define    MAXIMPWID    24
  62. X
  63. Xstatic long widthmask[MAXIMPWID+1] =
  64. X{
  65. X/* 0 */        1L,
  66. X/* 1 */        1L,
  67. X/* 2 */        (1L <<  2 ) -1,
  68. X/* 3 */        (1L <<  3 ) -1,
  69. X/* 4 */        (1L <<  4 ) -1,
  70. X/* 5 */        (1L <<  5 ) -1,
  71. X/* 6 */        (1L <<  6 ) -1,
  72. X/* 7 */        (1L <<  7 ) -1,
  73. X/* 8 */        (1L <<  8 ) -1,
  74. X/* 9 */        (1L <<  9 ) -1,
  75. X/* 10 */    (1L <<  10 ) -1,
  76. X/* 11 */    (1L <<  11 ) -1,
  77. X/* 12 */    (1L <<  12 ) -1,
  78. X/* 13 */    (1L <<  13 ) -1,
  79. X/* 14 */    (1L <<  14 ) -1,
  80. X/* 15 */    (1L <<  15 ) -1,
  81. X/* 16 */    (1L <<  16 ) -1,
  82. X/* 17 */    (1L <<  17 ) -1,
  83. X/* 18 */    (1L <<  18 ) -1,
  84. X/* 19 */    (1L <<  19 ) -1,
  85. X/* 20 */    (1L <<  20 ) -1,
  86. X/* 21 */    (1L <<  21 ) -1,
  87. X/* 22 */    (1L <<  22 ) -1,
  88. X/* 23 */    (1L <<  23 ) -1,
  89. X/* 24 */    (1L <<  24 ) -1
  90. X};
  91. X    
  92. X
  93. Xstatic long dgethex()
  94. X/*
  95. X    description    convert the character string pointed to by
  96. X            the output expression pointer to a long integer
  97. X    globals        oeptr, the output expression pointer
  98. X    return        the value
  99. X*/
  100. X{
  101. X    long rv = 0;
  102. X
  103. X    while( *oeptr != '\0')
  104. X    {
  105. X        switch(*oeptr)
  106. X        {
  107. X        case '0':
  108. X        case '1':
  109. X        case '2':
  110. X        case '3':
  111. X        case '4':
  112. X        case '5':
  113. X        case '6':
  114. X        case '7':
  115. X        case '8':
  116. X        case '9':
  117. X            rv = (rv << 4) + ((*oeptr) - '0');
  118. X            break;
  119. X
  120. X        case 'a':
  121. X        case 'b':
  122. X        case 'c':
  123. X        case 'd':
  124. X        case 'e':
  125. X        case 'f':
  126. X            rv = (rv << 4) + ((*oeptr) - 'a' + 10);
  127. X            break;
  128. X        
  129. X        case 'A':
  130. X        case 'B':
  131. X        case 'C':
  132. X        case 'D':
  133. X        case 'E':
  134. X        case 'F':
  135. X            rv = (rv << 4) + ((*oeptr) - 'A' + 10);
  136. X            break;
  137. X
  138. X        default:
  139. X            return rv;
  140. X        }
  141. X
  142. X        oeptr++;
  143. X    }
  144. X
  145. X    return rv;
  146. X}
  147. X    
  148. X
  149. Xoutphase()
  150. X/*
  151. X    description    process all the lines in the intermediate file
  152. X    globals        the input line
  153. X            the output expression pointer
  154. X            line number
  155. X            file name
  156. X            the binary output array and counts
  157. X*/
  158. X{
  159. X    int firstchar;
  160. X
  161. X    for(;;)
  162. X    {
  163. X        if((firstchar = fgetc(intermedf)) == EOF)
  164. X            break;
  165. X
  166. X        if(firstchar == 'L')
  167. X        {
  168. X            if(listflag)
  169. X                flushlisthex();
  170. X
  171. X            if( fgets(&lineLbuff[1], INBUFFSZ-1, intermedf) 
  172. X             == (char *)NULL)
  173. X            {
  174. X        frp2error( "error or premature end of intermediate file");
  175. X                break;
  176. X            }
  177. X
  178. X            lineLflag = TRUE;
  179. X        }
  180. X        else
  181. X        {
  182. X            finbuff[0] = firstchar;
  183. X            if(fgets( &finbuff[1], INBUFFSZ-1, intermedf) 
  184. X             == (char *)NULL)
  185. X            {
  186. X        frp2error("error or premature end of intermediate file");
  187. X                break;
  188. X            }
  189. X        }
  190. X    
  191. X        switch(firstchar)
  192. X        {
  193. X        case 'E': /* error */
  194. X            if(listflag)
  195. X            {
  196. X                flushsourceline();
  197. X                fputs(&finbuff[2], loutf);
  198. X            }
  199. X            else
  200. X            {
  201. X                fprintf(loutf, "%s - line %d - %s", 
  202. X                    currentfnm, linenumber, &finbuff[2]);
  203. X            }
  204. X            break;
  205. X
  206. X        case 'L': /* listing */
  207. X            linenumber++;
  208. X            break;
  209. X
  210. X        case 'C': /* comment / uncounted listing */
  211. X            if(listflag)
  212. X            {
  213. X                char *stuff = strchr(finbuff, '\n');
  214. X
  215. X                if(stuff != NULL)
  216. X                    *stuff = '\0';
  217. X
  218. X                fprintf(loutf,"%-*.*s", 
  219. X                 SOURCEOFFSET, SOURCEOFFSET, &finbuff[2]);
  220. X                if(lineLflag)
  221. X                {
  222. X                    fputs(&lineLbuff[2], loutf);
  223. X                    lineLflag = FALSE;
  224. X                }
  225. X                else
  226. X                {
  227. X                    fputc('\n', loutf);
  228. X                }
  229. X            }
  230. X            break;
  231. X
  232. X        case 'P': /* location set */
  233. X            oeptr = &finbuff[2];
  234. X            currseg = dgethex();
  235. X            oeptr++;
  236. X            genlocctr = locctr = dgethex();
  237. X            break;
  238. X        
  239. X        case 'D': /* data */
  240. X            oeptr = &finbuff[2];
  241. X            nextresult = 0;
  242. X            resultloc = genlocctr;
  243. X            outeval();
  244. X            if(hexflag)
  245. X                outhexblock();
  246. X            if(listflag)
  247. X                listhex();
  248. X            break;
  249. X        
  250. X        case 'F': /* file start */
  251. X            {
  252. X                char *tp;
  253. X                if( (tp = strchr(finbuff,'\n')) != (char *)NULL)
  254. X                    *tp = '\0';
  255. X                strncpy(currentfnm, &finbuff[2], 100);
  256. X                currentfnm[99] = '\0';
  257. X            }
  258. X            lnumstk[currfstk++] = linenumber;
  259. X            linenumber = 0;
  260. X            break;
  261. X        
  262. X        case 'X': /* file resume */
  263. X            {
  264. X                char *tp;
  265. X                if( (tp = strchr(finbuff,'\n')) != (char *)NULL)
  266. X                    *tp = '\0';
  267. X                strncpy(currentfnm, &finbuff[2], 100);
  268. X                currentfnm[99] = '\0';
  269. X            }
  270. X            linenumber = lnumstk[--currfstk];
  271. X            break;
  272. X
  273. X        default:
  274. X            frp2error("unknown intermediate file command");
  275. X            break;
  276. X        }
  277. X    }
  278. X
  279. X    if(hexflag)
  280. X        flushhex();
  281. X
  282. X    if(listflag)
  283. X        flushlisthex();
  284. X}
  285. X
  286. Xouteval()
  287. X/*
  288. X    description    convert the polish form character string in the 
  289. X            intermediate file 'D' line to binary values in the
  290. X            output result array.
  291. X    globals        the output expression pointer
  292. X            the output result array
  293. X*/
  294. X{
  295. X    register long etop = 0;
  296. X
  297. X    register struct evstkel *estkm1p = &estk[0];
  298. X
  299. X    while( *oeptr != '\0')
  300. X    {
  301. X        switch(*oeptr)
  302. X        {
  303. X        case '0':
  304. X        case '1':
  305. X        case '2':
  306. X        case '3':
  307. X        case '4':
  308. X        case '5':
  309. X        case '6':
  310. X        case '7':
  311. X        case '8':
  312. X        case '9':
  313. X            etop = (etop << 4) + ((*oeptr) - '0');
  314. X            break;
  315. X
  316. X        case 'a':
  317. X        case 'b':
  318. X        case 'c':
  319. X        case 'd':
  320. X        case 'e':
  321. X        case 'f':
  322. X            etop = (etop << 4) + ((*oeptr) - 'a' + 10);
  323. X            break;
  324. X        
  325. X        case 'A':
  326. X        case 'B':
  327. X        case 'C':
  328. X        case 'D':
  329. X        case 'E':
  330. X        case 'F':
  331. X            etop = (etop << 4) + ((*oeptr) - 'A' + 10);
  332. X            break;
  333. X
  334. X#include "fraeuni.h"
  335. X#include "fraebin.h"
  336. X        case IFC_SYMB:
  337. X            {
  338. X                struct symel *tsy;
  339. X
  340. X                tsy = symbindex[etop];
  341. X                if(tsy -> seg <= 0)
  342. X                {
  343. X                    frp2undef(tsy);
  344. X                    etop = 0;
  345. X                }
  346. X                else
  347. X                {
  348. X                    if(tsy -> seg == SSG_EQU ||
  349. X                       tsy -> seg == SSG_SET)
  350. X                    {
  351. X            frp2warn( "forward reference to SET/EQU symbol");
  352. X                    }
  353. X                    etop = tsy -> value;
  354. X                }
  355. X            }
  356. X            break;
  357. X
  358. X        case IFC_CURRLOC: 
  359. X            etop = genlocctr;
  360. X            break;
  361. X
  362. X        case IFC_PROGCTR:
  363. X            etop = locctr;
  364. X            break;
  365. X
  366. X        case IFC_DUP:
  367. X            if(estkm1p >= &estk[PESTKDEPTH-1])
  368. X            {
  369. X                frp2error("expression stack overflow");
  370. X            }
  371. X            else
  372. X            {
  373. X                (++estkm1p)->v = etop;
  374. X            }
  375. X            break;
  376. X
  377. X        case IFC_LOAD:
  378. X            if(estkm1p >= &estk[PESTKDEPTH-1])
  379. X            {
  380. X                frp2error("expression stack overflow");
  381. X            }
  382. X            else
  383. X            {
  384. X                (++estkm1p)->v = etop;
  385. X            }
  386. X            etop = 0;
  387. X            break;
  388. X
  389. X        case IFC_CLR:
  390. X            etop = 0;
  391. X            break;
  392. X
  393. X        case IFC_CLRALL:
  394. X            etop = 0;
  395. X            estkm1p = &estk[0];
  396. X            break;
  397. X
  398. X        case IFC_POP:
  399. X            etop = (estkm1p--)->v;
  400. X            break;
  401. X
  402. X        case IFC_TESTERR:
  403. X            if(etop)
  404. X            {
  405. X                frp2error(
  406. X            "expression fails validity test");
  407. X            }
  408. X            break;
  409. X
  410. X        case IFC_SWIDTH:
  411. X            if( etop > 0 && etop <= MAXIMPWID)
  412. X            {
  413. X                if( estkm1p->v < -(widthmask[etop-1]+1) ||
  414. X                    estkm1p->v > widthmask[etop-1] )
  415. X                {
  416. X                    frp2error(
  417. X                "expression exceeds available field width");
  418. X                }
  419. X                etop = ((estkm1p--)->v)  & widthmask[etop];
  420. X            }
  421. X            else
  422. X                frp2error("unimplemented width");
  423. X            break;
  424. X
  425. X        case IFC_WIDTH:
  426. X            if( etop > 0 && etop <= MAXIMPWID)
  427. X            {
  428. X                if( estkm1p->v < -(widthmask[etop-1]+1) ||
  429. X                    estkm1p->v > widthmask[etop] )
  430. X                {
  431. X                    frp2error(
  432. X                "expression exceeds available field width");
  433. X                }
  434. X                etop = ((estkm1p--)->v)  & widthmask[etop];
  435. X            }
  436. X            else
  437. X                frp2error("unimplemented width");
  438. X            break;
  439. X
  440. X        case IFC_IWIDTH:
  441. X            if( etop > 0 && etop <= MAXIMPWID)
  442. X            {
  443. X                if( estkm1p->v < 0 ||
  444. X                    estkm1p->v > widthmask[etop] )
  445. X                {
  446. X                    frp2error(
  447. X                "expression exceeds available field width");
  448. X                }
  449. X                etop = ((estkm1p--)->v)  & widthmask[etop];
  450. X            }
  451. X            else
  452. X                frp2error("unimplemented width");
  453. X            break;
  454. X
  455. X        case IFC_EMU8:
  456. X            if( etop >= -128 && etop <= 255)
  457. X            {
  458. X                outresult[nextresult++] = etop & 0xff;
  459. X            }
  460. X            else
  461. X            {
  462. X                outresult[nextresult++] = 0;
  463. X                frp2error(
  464. X            "expression exceeds available field width");
  465. X            }
  466. X            genlocctr ++;
  467. X            etop = 0;
  468. X            break;
  469. X
  470. X        case IFC_EMS7:
  471. X            if(etop >= -128 && etop <= 127)
  472. X            {
  473. X                outresult[nextresult++] = etop & 0xff;
  474. X            }
  475. X            else
  476. X            {
  477. X                outresult[nextresult++] = 0;
  478. X                frp2error(
  479. X            "expression exceeds available field width");
  480. X            }
  481. X            genlocctr ++;
  482. X            etop = 0;
  483. X            break;
  484. X
  485. X        case IFC_EM16:
  486. X            if(etop >= -32768L && etop <= 65535L)
  487. X            {
  488. X                outresult[nextresult++] = (etop >> 8) & 0xff;
  489. X                outresult[nextresult++] = etop & 0xff;
  490. X            }
  491. X            else
  492. X            {
  493. X                outresult[nextresult++] = 0;
  494. X                outresult[nextresult++] = 0;
  495. X                frp2error(
  496. X            "expression exceeds available field width");
  497. X            }
  498. X            genlocctr += 2;
  499. X            etop = 0;
  500. X            break;
  501. X
  502. X        case IFC_EMBR16:
  503. X            if(etop >= -32768L && etop <= 65535L)
  504. X            {
  505. X                outresult[nextresult++] = etop & 0xff;
  506. X                outresult[nextresult++] = (etop >> 8) & 0xff;
  507. X            }
  508. X            else
  509. X            {
  510. X                outresult[nextresult++] = 0;
  511. X                outresult[nextresult++] = 0;
  512. X                frp2error(
  513. X            "expression exceeds available field width");
  514. X            }
  515. X            genlocctr += 2;
  516. X            etop = 0;
  517. X            break;
  518. X
  519. X        default:
  520. X            break;
  521. X        }
  522. X        oeptr++;
  523. X    }
  524. X}
  525. X
  526. Xstatic long lhaddr, lhnextaddr;
  527. Xstatic int lhnew, lhnext = 0;
  528. Xstatic unsigned char listbuffhex[NUMHEXPERL];
  529. X
  530. Xflushlisthex()
  531. X/*
  532. X    description    output the residue of the hexidecimal values for
  533. X            the previous assembler statement.
  534. X    globals        the new hex list flag
  535. X*/
  536. X{
  537. X    listouthex();
  538. X    lhnew = TRUE;
  539. X}
  540. X
  541. Xlisthex()
  542. X/*
  543. X    description    buffer the output result to block the hexidecimal 
  544. X            listing on the output file to NUMHEXPERL bytes per
  545. X            listing line.
  546. X    globals        The output result array and count
  547. X            the hex line buffer and counts
  548. X*/
  549. X{
  550. X    register int cht;
  551. X    register long inhaddr = resultloc;
  552. X
  553. X    if(lhnew)
  554. X    {
  555. X        lhaddr = lhnextaddr = resultloc;
  556. X        lhnew = FALSE;
  557. X    }
  558. X
  559. X    for(cht = 0; cht < nextresult; cht++)
  560. X    {
  561. X        if(lhnextaddr != inhaddr 
  562. X         || lhnext >= (lineLflag ? NUMHEXSOURCE : NUMHEXPERL ) )
  563. X        {
  564. X            listouthex();
  565. X            lhaddr = lhnextaddr = inhaddr;
  566. X        }
  567. X        listbuffhex[lhnext++] = outresult[cht];
  568. X        lhnextaddr ++;
  569. X        inhaddr ++;
  570. X    }
  571. X}
  572. X
  573. Xlistouthex()
  574. X/*
  575. X    description    print a line of hexidecimal on the listing
  576. X    globals        the hex listing buffer
  577. X*/
  578. X{
  579. X    register int cn;
  580. X    register int tc;
  581. X
  582. X    if(lhnext > 0)
  583. X    {
  584. X        fputc(hexch((int)lhaddr>>12), loutf);
  585. X        fputc(hexch((int)lhaddr>>8), loutf);
  586. X        fputc(hexch((int)lhaddr>>4), loutf);
  587. X        fputc(hexch((int)lhaddr), loutf);
  588. X        fputc(' ', loutf);
  589. X
  590. X        for(cn = 0; cn < lhnext; cn++)
  591. X        {
  592. X            fputc(hexch((int)(tc = listbuffhex[cn])>>4), loutf);
  593. X            fputc(hexch(tc), loutf);
  594. X            fputc(' ', loutf);
  595. X        }
  596. X
  597. X        if( ! lineLflag)
  598. X            fputc('\n', loutf);
  599. X    }
  600. X
  601. X    if(lineLflag)
  602. X    {
  603. X        if(lineLbuff[2] != '\n')
  604. X        {
  605. X            switch(lhnext)
  606. X            {
  607. X            case 0:
  608. X                fputs("\t\t\t",loutf);
  609. X                break;
  610. X            case 1:
  611. X            case 2:
  612. X            case 3:
  613. X                fputs("\t\t",loutf);
  614. X                break;
  615. X            case 4:
  616. X            case 5:
  617. X            case 6:
  618. X                fputs("\t",loutf);
  619. X            default:
  620. X                break;
  621. X            }
  622. X
  623. X            fputs(&lineLbuff[2], loutf);
  624. X            lineLflag = FALSE;
  625. X        }
  626. X        else
  627. X        {
  628. X            fputc('\n', loutf);
  629. X        }
  630. X    }
  631. X        
  632. X    lhnext = 0;
  633. X}
  634. X
  635. X#define INTELLEN 32
  636. X
  637. Xstatic long nextoutaddr, blockaddr;
  638. Xstatic int hnextsub;
  639. Xstatic char hlinebuff[INTELLEN];
  640. X
  641. X
  642. Xouthexblock()
  643. X/*
  644. X    description    buffer the output result to group adjacent output
  645. X            data into longer lines.
  646. X    globals        the output result array
  647. X            the intel hex line buffer
  648. X*/
  649. X{
  650. X    long inbuffaddr = resultloc;
  651. X    static int first = TRUE;
  652. X
  653. X    int loopc;
  654. X
  655. X    if(first)
  656. X    {
  657. X        nextoutaddr = blockaddr = resultloc;
  658. X        hnextsub = 0;
  659. X        first = FALSE;
  660. X    }
  661. X
  662. X    for(loopc = 0; loopc < nextresult; loopc++)
  663. X    {
  664. X        if(nextoutaddr != inbuffaddr || hnextsub >= INTELLEN)
  665. X        {
  666. X            intelout(0, blockaddr, hnextsub, hlinebuff);
  667. X            blockaddr = nextoutaddr = inbuffaddr;
  668. X            hnextsub = 0;
  669. X        }
  670. X        hlinebuff[hnextsub++] = outresult[loopc];
  671. X        nextoutaddr++;
  672. X        inbuffaddr++;
  673. X    }
  674. X}
  675. X
  676. Xflushhex()
  677. X/*
  678. X    description    flush the intel hex line buffer at the end of
  679. X            the second pass
  680. X    globals        the intel hex line buffer
  681. X*/
  682. X{
  683. X    if(hnextsub > 0)
  684. X        intelout(0, blockaddr, hnextsub, hlinebuff);
  685. X    if(endsymbol != SYMNULL && endsymbol -> seg > 0)
  686. X        intelout(1, endsymbol -> value, 0, "");
  687. X    else
  688. X        intelout(1, 0L, 0, "");
  689. X        
  690. X}
  691. X
  692. X
  693. Xintelout(type, addr, count, data)
  694. X    int type;
  695. X    long addr;
  696. X    int count;
  697. X    char data[];
  698. X/*
  699. X    description    print a line of intel format hex data to the output
  700. X            file
  701. X    parameters    see manual for record description
  702. X*/
  703. X{
  704. X    register int temp, checksum;
  705. X
  706. X    fputc(':', hexoutf);
  707. X    fputc(hexch(count>>4),hexoutf);
  708. X    fputc(hexch(count),hexoutf);
  709. X    fputc(hexch((int)addr>>12),hexoutf);
  710. X    fputc(hexch((int)addr>>8),hexoutf);
  711. X    fputc(hexch((int)addr>>4),hexoutf);
  712. X    fputc(hexch((int)addr),hexoutf);
  713. X    fputc(hexch(type>>4),hexoutf);
  714. X    fputc(hexch(type),hexoutf);
  715. X
  716. X    checksum = ((addr >> 8) & 0xff) + (addr & 0xff) + (count & 0xff);
  717. X    checksum += type & 0xff;
  718. X
  719. X    for(temp = 0; temp < count; temp ++)
  720. X    {
  721. X        checksum += data[temp] & 0xff;
  722. X        fputc(hexch(data[temp] >> 4), hexoutf);
  723. X        fputc(hexch(data[temp]), hexoutf);
  724. X    }
  725. X
  726. X    checksum = (-checksum) & 0xff;
  727. X    fputc(hexch(checksum>>4), hexoutf);
  728. X    fputc(hexch(checksum), hexoutf);
  729. X    fputc('\n',hexoutf);
  730. X}
  731. X
  732. X
  733. Xfrp2undef(symp)
  734. X    struct symel * symp;
  735. X/*
  736. X    description    second pass - print undefined symbol error message on
  737. X            the output listing device.  If the the listing flag
  738. X            is false, the output device is the standard output, and
  739. X            the message format is different.
  740. X    parameters    a pointer to a symbol table element
  741. X    globals        the count of errors
  742. X*/
  743. X{
  744. X    if(listflag)
  745. X    {
  746. X        flushsourceline();
  747. X        fprintf(loutf," ERROR -  undefined symbol %s\n", symp ->symstr);
  748. X    }
  749. X    else
  750. X        fprintf(loutf, "%s - line %d - ERROR - undefined symbol  %s\n", 
  751. X            currentfnm, linenumber, symp -> symstr);
  752. X    errorcnt++;
  753. X}
  754. X
  755. Xfrp2warn(str)
  756. X    char * str;
  757. X/*
  758. X    description    second pass - print a warning message on the listing
  759. X            file, varying the format for console messages.
  760. X    parameters    the message
  761. X    globals        the count of warnings
  762. X*/
  763. X{
  764. X    if(listflag)
  765. X    {
  766. X        flushsourceline();
  767. X        fprintf(loutf, " WARNING - %s\n", str);
  768. X    }
  769. X    else
  770. X        fprintf(loutf, "%s - line %d - WARNING - %s\n", 
  771. X            currentfnm, linenumber, str);
  772. X    warncnt++;
  773. X}
  774. X
  775. X
  776. Xfrp2error(str)
  777. X    char * str;
  778. X/*
  779. X    description    second pass - print a message on the listing file
  780. X    parameters    message
  781. X    globals        count of errors
  782. X*/
  783. X{
  784. X    if(listflag)
  785. X    {
  786. X        flushsourceline();
  787. X        fprintf(loutf, " ERROR - %s\n", str);
  788. X    }
  789. X    else
  790. X        fprintf(loutf, "%s - line %d - ERROR - %s\n", 
  791. X            currentfnm, linenumber, str);
  792. X    errorcnt++;
  793. X}
  794. X
  795. Xflushsourceline()
  796. X/*
  797. X    description    flush listing line buffer before an error for
  798. X            that line is printed
  799. X*/
  800. X{
  801. X    if(listflag && lineLflag)
  802. X    {
  803. X        fputs("\t\t\t", loutf);
  804. X        fputs(&lineLbuff[2], loutf);
  805. X        lineLflag = FALSE;
  806. X    }
  807. X}
  808. SHAR_EOF
  809. true || echo 'restore of fraosub.c failed'
  810. fi
  811. # ============= frapsub.c ==============
  812. if test -f 'frapsub.c' -a X"$1" != X"-c"; then
  813.     echo 'x - skipping frapsub.c (File already exists)'
  814. else
  815. echo 'x - extracting frapsub.c (Text)'
  816. sed 's/^X//' << 'SHAR_EOF' > 'frapsub.c' &&
  817. X/*
  818. XHEADER:     ;
  819. XTITLE:         Frankenstein Cross Assemblers;
  820. XVERSION:     2.0;
  821. XDESCRIPTION: "    Reconfigurable Cross-assembler producing Intel (TM)
  822. X        Hex format object records.  ";
  823. XSYSTEM:     UNIX, MS-Dos ;
  824. XFILENAME:     frapsub.c ;
  825. XWARNINGS:     "This software is in the public domain.  
  826. X        Any prior copyright claims are relinquished.  
  827. X
  828. X        This software is distributed with no warranty whatever.  
  829. X        The author takes no responsibility for the consequences 
  830. X        of its use.  "  ;
  831. XSEE-ALSO:     frasmain.c;
  832. XAUTHORS:     Mark Zenier;
  833. X*/
  834. X
  835. X/*
  836. X    description    Parser phase utility routines
  837. X    History        September 1987
  838. X            September 14, 1990 Dosify, 6 char unique names
  839. X*/
  840. X
  841. X#include "fragcon.h"
  842. X#include <stdio.h>
  843. X#include "frasmdat.h"
  844. X
  845. X#define STRALLOCSZ 4096
  846. X
  847. X    local char *currstr;
  848. X
  849. Xchar * savestring(stx, len)
  850. X    char *stx;
  851. X    int len;
  852. X/*
  853. X    description    save a character string in permanent (interpass) memory
  854. X    parameters    the string and its length
  855. X    globals     the string pool
  856. X    return        a pointer to the saved string
  857. X*/
  858. X{
  859. X    char * rv;
  860. X    static int savestrleft = 0;
  861. X
  862. X    if( savestrleft < (len+1))
  863. X    {
  864. X        if((currstr = malloc(STRALLOCSZ)) == (char *)NULL)
  865. X        {
  866. X            frafatal("cannot allocate string storage");
  867. X        }
  868. X        savestrleft = STRALLOCSZ;
  869. X    }
  870. X
  871. X    savestrleft -= (len+1);
  872. X
  873. X    rv = currstr;
  874. X    for(; len > 0; len--)
  875. X        *currstr++ = *stx++;
  876. X    *currstr++ = '\0';
  877. X
  878. X    return rv;
  879. X}
  880. X
  881. X/* expression node operations */
  882. X
  883. X/* expression tree element */
  884. Xstruct etelem
  885. X{
  886. X    int    evs;
  887. X    int    op;
  888. X    int    left, right;
  889. X    long    val;
  890. X    struct symel *sym;
  891. X};
  892. X
  893. X#define NUMENODE INBUFFSZ
  894. Xstruct etelem enode[NUMENODE];
  895. X
  896. Xlocal int nextenode = 1;
  897. X
  898. X/* non general, one exprlist or stringlist per line */
  899. Xint nextexprs = 0;
  900. Xint nextstrs = 0;
  901. X
  902. Xclrexpr()
  903. X/*
  904. X    description    clear out the stuff used for each line
  905. X            the temporary string pool
  906. X            the expression tree storage pool
  907. X            the string and expression lists
  908. X*/
  909. X{
  910. X    nextenode = 1;
  911. X    nextexprs = nextstrs = 0;
  912. X}
  913. X
  914. Xexprnode(swact, left, op, right, value, symbol)
  915. X    int swact, left, op, right;
  916. X    long value;
  917. X    struct symel * symbol;
  918. X/*
  919. X    description    add an element to the expression tree pool
  920. X    parameters    swact, the action performed by the switch in
  921. X                the polish conversion routine, the category
  922. X                of the expression node.
  923. X            left, right  the subscripts of the decendent nodes
  924. X                    of the expression tree element
  925. X            op, the operation to preform
  926. X            value, a constant value (maybe)
  927. X            symbol, a pointer to a symbol element (maybe)
  928. X    globals        the next available table element
  929. X    return        the subscript of the expression node
  930. X*/
  931. X{
  932. X    if(nextenode >= NUMENODE)
  933. X    {
  934. X        frafatal("excessive number of subexpressions");
  935. X    }
  936. X
  937. X    enode [nextenode].evs = swact;
  938. X    enode [nextenode].left = left;
  939. X    enode [nextenode].op = op;
  940. X    enode [nextenode].right = right;
  941. X    enode [nextenode].val = value;
  942. X    enode [nextenode].sym = symbol;
  943. X
  944. X    return nextenode ++;
  945. X}
  946. X
  947. Xint nextsymnum = 1;
  948. X
  949. Xlocal struct symel *syallob;
  950. X#define SYELPB 512
  951. Xlocal int nxtsyel = SYELPB;
  952. X
  953. Xstruct symel *allocsym()
  954. X/*
  955. X    description    allocate a symbol table element, and allocate
  956. X            a block if the current one is empty.  A fatal
  957. X            error if no more space can be gotten
  958. X    globals        the pointer to the current symbol table block
  959. X            the count of elements used in the block
  960. X    return        a pointer to the symbol table element
  961. X*/
  962. X{
  963. X
  964. X    if(nxtsyel >= SYELPB)
  965. X    {
  966. X        if( (syallob = (struct symel *)calloc(
  967. X            SYELPB , sizeof(struct symel)))
  968. X         == (struct symel *)NULL)
  969. X        {
  970. X            frafatal("cannot allocate symbol space");
  971. X        }
  972. X
  973. X        nxtsyel = 0;
  974. X    }
  975. X
  976. X    return &syallob[nxtsyel++];
  977. X}
  978. X
  979. X
  980. X#define SYHASHOFF 13
  981. X#define SYHASHSZ 1023
  982. X
  983. Xint syhash(str)
  984. X    register char *str;
  985. X/*
  986. X    description    produce a hash index from a character string for
  987. X            the symbol table.
  988. X    parameters     a character string
  989. X    return        an integer related in some way to the character string
  990. X*/
  991. X{
  992. X    unsigned rv = 0;
  993. X    register int offset = 1;
  994. X    register int c;
  995. X
  996. X    while((c = *(str++)) > 0)
  997. X    {
  998. X        rv += (c - ' ') * offset;
  999. X        offset *= SYHASHOFF;
  1000. X    }
  1001. X
  1002. X    return rv % SYHASHSZ;
  1003. X}
  1004. X
  1005. Xlocal struct symel * (shashtab[SYHASHSZ]);
  1006. X
  1007. Xstatic struct symel *getsymslot(str)
  1008. X    char * str;
  1009. X/*
  1010. X    description    find an existing symbol in the symbol table, or
  1011. X            allocate an new element if the symbol doen't exist.
  1012. X            action: hash the string
  1013. X                if there are no symbols for the hash value
  1014. X                    create one for this string
  1015. X                otherwise
  1016. X                scan the linked list until the symbol is 
  1017. X                found or the end of the list is found
  1018. X                if the symbol was found
  1019. X                    exit
  1020. X                if the symbol was not found, allocate and
  1021. X                add at the end of the linked list
  1022. X                fill out the symbol
  1023. X    parameters    the character string 
  1024. X    globals        all the symbol table
  1025. X    return        a pointer to the symbol table element for this
  1026. X            character string
  1027. X*/
  1028. X{
  1029. X    struct symel *currel, *prevel;
  1030. X    int hv;
  1031. X
  1032. X    if( (currel = shashtab[hv = syhash(str)])
  1033. X        == (struct symel *)NULL)
  1034. X    {
  1035. X        shashtab[hv] = currel = allocsym();
  1036. X    }
  1037. X    else
  1038. X    {
  1039. X        do  {
  1040. X            if(strcmp(currel -> symstr, str) == 0)
  1041. X            {
  1042. X                return currel;
  1043. X            }
  1044. X            else
  1045. X            {
  1046. X                prevel = currel;
  1047. X                currel = currel -> nextsym;
  1048. X            }
  1049. X        } while( currel != (struct symel *)NULL);
  1050. X
  1051. X        prevel -> nextsym = currel = allocsym();
  1052. X    }
  1053. X
  1054. X    currel -> symstr = savestring(str, strlen(str));
  1055. X    currel -> nextsym = (struct symel *)NULL;
  1056. X    currel -> tok = 0;
  1057. X    currel -> value = 0;
  1058. X    currel -> seg = SSG_UNUSED;
  1059. X
  1060. X    return currel;
  1061. X}
  1062. X
  1063. Xstruct symel * symbentry(str,toktyp)
  1064. X    char * str;
  1065. X    int toktyp;
  1066. X/*
  1067. X    description    find or add a nonreserved symbol to the symbol table
  1068. X    parameters    the character string
  1069. X            the syntactic token type for this charcter string
  1070. X                (this is a parameter so the routine doesn't
  1071. X                have to be recompiled since the yacc grammer
  1072. X                provides the value)
  1073. X    globals        the symbol table in all its messy glory
  1074. X    return        a pointer to the symbol table element
  1075. X*/
  1076. X{
  1077. X    struct symel * rv;
  1078. X
  1079. X    rv = getsymslot(str);
  1080. X
  1081. X    if(rv -> seg == SSG_UNUSED)
  1082. X    {
  1083. X        rv -> tok = toktyp;
  1084. X        rv -> symnum = nextsymnum ++;
  1085. X        rv -> seg = SSG_UNDEF;
  1086. X    }
  1087. X
  1088. X    return rv;
  1089. X}
  1090. X
  1091. Xvoid reservedsym(str, tok, value)
  1092. X    char * str;
  1093. X    int tok;
  1094. X    int value;
  1095. X/*
  1096. X    description    add a reserved symbol to the symbol table.
  1097. X    parameters    the character string, must be a constant as
  1098. X            the symbol table does not copy it, only point to it.
  1099. X            The syntactic token value.
  1100. X            The associated value of the symbol.
  1101. X*/
  1102. X{
  1103. X    struct symel * tv;
  1104. X
  1105. X    tv = getsymslot(str);
  1106. X
  1107. X    if(tv -> seg != SSG_UNUSED)
  1108. X    {
  1109. X        frafatal("cannot redefine reserved symbol");
  1110. X    }
  1111. X
  1112. X    tv -> symnum = 0;
  1113. X    tv -> tok = tok;
  1114. X    tv -> seg = SSG_RESV;
  1115. X    tv -> value = value;
  1116. X
  1117. X}
  1118. X
  1119. Xbuildsymbolindex()
  1120. X/*
  1121. X    description    allocate and fill an array that points to each
  1122. X            nonreserved symbol table element, used to reference
  1123. X            the symbols in the intermediate file, in the output
  1124. X            pass.
  1125. X    globals        the symbol table
  1126. X*/
  1127. X{
  1128. X    int hi;
  1129. X    struct symel *curr;
  1130. X
  1131. X    if((symbindex = (struct symel **)calloc((unsigned)nextsymnum, 
  1132. X            sizeof (struct symel *))) == (struct symel **)NULL)
  1133. X    {
  1134. X        frafatal(" unable to allocate symbol index");
  1135. X    }
  1136. X
  1137. X    for(hi = 0; hi < SYHASHSZ; hi++)
  1138. X    {
  1139. X        if( (curr = shashtab[hi]) != SYMNULL)
  1140. X        {
  1141. X            do  {
  1142. X                if( curr -> symnum)
  1143. X                    symbindex[curr -> symnum] = curr;
  1144. X
  1145. X                curr = curr -> nextsym;
  1146. X            }  while(curr != SYMNULL);
  1147. X        }
  1148. X    }
  1149. X}
  1150. X
  1151. X/* opcode symbol table */
  1152. X
  1153. X#define OPHASHOFF 13
  1154. X#define OPHASHSZ 1023
  1155. X
  1156. Xlocal int ohashtab[OPHASHSZ];
  1157. X
  1158. Xsetophash()
  1159. X/*
  1160. X    description    set up the linked list hash table for the
  1161. X            opcode symbols 
  1162. X    globals        the opcode hash table
  1163. X            the opcode table
  1164. X*/
  1165. X{
  1166. X    int opn, pl, hv;
  1167. X
  1168. X        /* optab[0] is reserved for the "invalid" entry */
  1169. X        /*  opcode subscripts range from 0 to numopcode - 1 */
  1170. X    for(opn = 1; opn < gnumopcode; opn++)
  1171. X    {
  1172. X        hv = opcodehash(optab[opn].opstr);
  1173. X
  1174. X        if( (pl = ohashtab[hv]) == 0)
  1175. X        {
  1176. X            ohashtab[hv] = opn;
  1177. X        }
  1178. X        else
  1179. X        {
  1180. X            while( ophashlnk[pl] != 0)
  1181. X            {
  1182. X                pl = ophashlnk[pl];
  1183. X            }
  1184. X
  1185. X            ophashlnk[pl] = opn;
  1186. X            ophashlnk[opn] = 0;
  1187. X        }
  1188. X    }
  1189. X}
  1190. X
  1191. X
  1192. Xint findop(str)
  1193. X    char *str;
  1194. X/*
  1195. X    description    find an opcode table subscript
  1196. X    parameters    the character string
  1197. X    globals        the opcode hash linked list table
  1198. X            the opcode table
  1199. X    return        0 if not found
  1200. X            the subscript of the matching element if found
  1201. X*/
  1202. X{
  1203. X    int ts;
  1204. X
  1205. X    if( (ts = ohashtab[opcodehash(str)]) == 0)
  1206. X    {
  1207. X        return 0;
  1208. X    }
  1209. X
  1210. X    do  {
  1211. X        if(strcmp(str,optab[ts].opstr) == 0)
  1212. X        {
  1213. X            return ts;
  1214. X        }
  1215. X        else
  1216. X        {
  1217. X            ts = ophashlnk[ts];
  1218. X        }
  1219. X    } while (ts != 0);
  1220. X
  1221. X    return 0;
  1222. X}
  1223. X
  1224. X
  1225. Xint opcodehash(str)
  1226. X    char *str;
  1227. X/*
  1228. X    description    hash a character string
  1229. X    return        an integer related somehow to the character string
  1230. X*/
  1231. X{
  1232. X    unsigned rv = 0;
  1233. X    int offset = 1, c;
  1234. X
  1235. X    while((c = *(str++)) > 0)
  1236. X    {
  1237. X        rv += (c - ' ') * offset;
  1238. X        offset *= OPHASHOFF;
  1239. X    }
  1240. X
  1241. X    return rv % OPHASHSZ;
  1242. X}
  1243. X
  1244. X
  1245. Xchar * findgen(op, syntax, crit)
  1246. X    int    op, syntax, crit;
  1247. X/*
  1248. X    description    given the subscript of the opcode table element,
  1249. X            find the instruction generation string for the
  1250. X            opcode with the given syntax and fitting the
  1251. X            given criteria.  This implement a sparse matrix
  1252. X            for  the dimensions [opcode, syntax] and then
  1253. X            points to a list of generation elements that
  1254. X            are matched to the criteria (binary set) that
  1255. X            are provided by the action in the grammer for that
  1256. X            specific syntax.
  1257. X    parameters    Opcode table subscript
  1258. X                note 0 is the value which points to an
  1259. X                syntax list that will accept anything
  1260. X                and gives the invalid instruction error
  1261. X            Syntax, a selector, a set member
  1262. X            Criteria, a integer used a a group of bit sets
  1263. X    globals        the opcode table, the opcode syntax table, the
  1264. X            instruction generation table
  1265. X    return        a pointer to a character string, either a
  1266. X            error message, or the generation string for the
  1267. X            instruction
  1268. X*/
  1269. X{
  1270. X    int    sys = optab[op].subsyn, stc, gsub = 0, dctr;
  1271. X
  1272. X    for(stc = optab[op].numsyn; stc > 0; stc--)
  1273. X    {
  1274. X        if( (ostab[sys].syntaxgrp & syntax) != 0)
  1275. X        {
  1276. X            gsub = ostab[sys].gentabsub;
  1277. X            break;
  1278. X        }
  1279. X        else
  1280. X            sys++;
  1281. X    }
  1282. X
  1283. X    if(gsub == 0)
  1284. X        return ignosyn;
  1285. X
  1286. X    for(dctr = ostab[sys].elcnt; dctr > 0; dctr--)
  1287. X    {
  1288. X        if( (igtab[gsub].selmask & crit) == igtab[gsub].criteria)
  1289. X        {
  1290. X            return igtab[gsub].genstr;
  1291. X        }
  1292. X        else
  1293. X        {
  1294. X            gsub++;
  1295. X        }
  1296. X    }
  1297. X
  1298. X    return ignosel;
  1299. X}
  1300. X
  1301. X
  1302. Xgenlocrec(seg, loc)
  1303. X    int seg;
  1304. X    long loc;
  1305. X/*
  1306. X    description    output to the intermediate file, a 'P' record
  1307. X            giving the current location counter.  Segment
  1308. X            is not used at this time.
  1309. X*/
  1310. X{
  1311. X    fprintf(intermedf, "P:%x:%lx\n", seg, loc);
  1312. X}
  1313. X
  1314. X#define GSTR_PASS 0
  1315. X#define GSTR_PROCESS 1
  1316. X
  1317. Xlocal char *goutptr, goutbuff[INBUFFSZ] = "D:";
  1318. X
  1319. Xvoid goutch(ch)
  1320. X    char ch;
  1321. X/*
  1322. X    description    put a character in the intermediate file buffer
  1323. X            for 'D' data records
  1324. X    globals        the buffer, its current position pointer
  1325. X*/
  1326. X{
  1327. X    if(goutptr < &goutbuff[INBUFFSZ-1])
  1328. X    {
  1329. X        *goutptr ++ = ch;
  1330. X    }
  1331. X    else
  1332. X    {
  1333. X        goutbuff[INBUFFSZ-1] = '\0';
  1334. X        goutptr = &goutbuff[INBUFFSZ]; 
  1335. X        fraerror("overflow in instruction generation");
  1336. X    }
  1337. X}
  1338. X
  1339. X
  1340. Xgout2hex(inv)
  1341. X    int inv;
  1342. X/*
  1343. X    description    output to the 'D' buffer, a byte in ascii hexidecimal
  1344. X*/
  1345. X{
  1346. X    goutch(hexch( inv>>4 ));
  1347. X    goutch(hexch( inv ));
  1348. X}
  1349. X
  1350. X
  1351. Xgoutxnum(num)
  1352. X    unsigned long num;
  1353. X/*
  1354. X    description    output to the 'D' record buffer a long integer in
  1355. X            hexidecimal
  1356. X*/
  1357. X{
  1358. X    if(num > 15)
  1359. X        goutxnum(num>>4);
  1360. X    goutch(hexch((int) num ));
  1361. X}
  1362. X
  1363. X
  1364. Xint geninstr(str)
  1365. X    register char * str;
  1366. X/*
  1367. X    description    Process an instruction generation string, from
  1368. X            the parser, into a polish form expression line
  1369. X            in a 'D' record in the intermediate file, after
  1370. X            merging in the expression results.
  1371. X    parameters    the instruction generation string
  1372. X    globals        the evaluation results 
  1373. X                evalr[].value    a numeric value known at
  1374. X                        the time of the first pass
  1375. X                evalr[].exprstr  a polish form expression
  1376. X                        derived from the expression
  1377. X                        parse tree, to be evaluated in
  1378. X                        the output phase.
  1379. X    return        the length of the instruction (machine code bytes)
  1380. X*/
  1381. X{
  1382. X    int len = 0;
  1383. X    int state = GSTR_PASS;
  1384. X    int innum = 0;
  1385. X
  1386. X    register char *exp;
  1387. X
  1388. X    goutptr = &goutbuff[2];
  1389. X
  1390. X    while( *str != '\0')
  1391. X    {
  1392. X        if(state == GSTR_PASS)
  1393. X        {
  1394. X            switch(*str)
  1395. X            {
  1396. X            case IG_START:
  1397. X                state = GSTR_PROCESS;
  1398. X                innum = 0;
  1399. X                str++;
  1400. X                break;
  1401. X
  1402. X            case IFC_EMU8:
  1403. X            case IFC_EMS7:
  1404. X                len++;
  1405. X                goutch(*str++);
  1406. X                break;
  1407. X
  1408. X            case IFC_EM16:
  1409. X            case IFC_EMBR16:
  1410. X                len += 2;
  1411. X                goutch(*str++);
  1412. X                break;
  1413. X
  1414. X            default:
  1415. X                goutch(*str++);
  1416. X                break;
  1417. X            }
  1418. X        }
  1419. X        else
  1420. X        {
  1421. X            switch(*str)
  1422. X            {
  1423. X            case IG_END:
  1424. X                state = GSTR_PASS;
  1425. X                str++;
  1426. X                break;
  1427. X            
  1428. X            case '0':
  1429. X            case '1':
  1430. X            case '2':
  1431. X            case '3':
  1432. X            case '4':
  1433. X            case '5':
  1434. X            case '6':
  1435. X            case '7':
  1436. X            case '8':
  1437. X            case '9':
  1438. X                innum = (innum << 4) + (*str++) - '0';
  1439. X                break;
  1440. X            
  1441. X            case 'a':
  1442. X            case 'b':
  1443. X            case 'c':
  1444. X            case 'd':
  1445. X            case 'e':
  1446. X            case 'f':
  1447. X                innum = (innum << 4) + (*str++) - 'a' + 10;
  1448. X                break;
  1449. X            
  1450. X            case 'A':
  1451. X            case 'B':
  1452. X            case 'C':
  1453. X            case 'D':
  1454. X            case 'E':
  1455. X            case 'F':
  1456. X                innum = (innum << 4) + (*str++) - 'A' + 10;
  1457. X                break;
  1458. X            
  1459. X            case IG_CPCON:
  1460. X                goutxnum((unsigned long)evalr[innum].value);
  1461. X                innum = 0;
  1462. X                str++;
  1463. X                break;
  1464. X
  1465. X            case IG_CPEXPR:
  1466. X                exp = &evalr[innum].exprstr[0];
  1467. X                innum = 0;
  1468. X                while(*exp != '\0')
  1469. X                    goutch(*exp++);
  1470. X                str++;
  1471. X                break;
  1472. X            
  1473. X            case IG_ERROR:
  1474. X                fraerror(++str);
  1475. X                return 0;
  1476. X            
  1477. X            default:
  1478. X                fraerror(
  1479. X                "invalid char in instruction generation");
  1480. X                break;
  1481. X            }
  1482. X        }
  1483. X    }
  1484. X
  1485. X    if(goutptr > &goutbuff[2])
  1486. X    {
  1487. X        goutch('\n');
  1488. X        fwrite(goutbuff,sizeof (char), goutptr - &goutbuff[0], 
  1489. X            intermedf);
  1490. X    }
  1491. X
  1492. X    return len;
  1493. X}
  1494. X
  1495. Xint     chtnxalph = 1, *chtcpoint = (int *)NULL, *chtnpoint = (int *)NULL;
  1496. X
  1497. Xint chtcreate()
  1498. X/*
  1499. X    description    allocate and initialize a character translate
  1500. X            table
  1501. X    return        0 for error, subscript into chtatab to pointer
  1502. X            to the allocated block
  1503. X*/
  1504. X{
  1505. X    int *trantab, cnt;
  1506. X
  1507. X    if(chtnxalph >= NUM_CHTA)
  1508. X        return 0; /* too many */
  1509. X
  1510. X    if( (trantab =  (int *)calloc(512, sizeof (int))) == (int *) NULL)
  1511. X        return 0;
  1512. X
  1513. X    for(cnt = 0; cnt < 512; cnt++)
  1514. X        trantab[cnt] = -1;
  1515. X    
  1516. X    chtatab[chtnxalph] = chtnpoint = trantab;
  1517. X
  1518. X    return chtnxalph++;
  1519. X}
  1520. X
  1521. X
  1522. Xint chtcfind(chtab, sourcepnt, tabpnt, numret)
  1523. X/*
  1524. X    description    find a character in a translate table
  1525. X    parameters    pointer to translate table
  1526. X            pointer to pointer to input string
  1527. X            pointer to return value integer pointer
  1528. X            pointer to numeric return
  1529. X    return        status of search
  1530. X*/
  1531. X    int *chtab;
  1532. X    char **sourcepnt; 
  1533. X    int **tabpnt;
  1534. X    int *numret;
  1535. X{
  1536. X    int numval, *valaddr;
  1537. X    char *sptr, cv;
  1538. X
  1539. X    sptr = *sourcepnt;
  1540. X
  1541. X    switch( cv = *sptr)
  1542. X    {
  1543. X    case '\0':
  1544. X        return CF_END;
  1545. X
  1546. X    default:
  1547. X        if( chtab == (int *)NULL)
  1548. X        {
  1549. X            *numret = *sptr;
  1550. X            *sourcepnt = ++sptr;
  1551. X            return CF_NUMBER;
  1552. X        }
  1553. X        else
  1554. X        {
  1555. X            valaddr = &(chtab[cv & 0xff]);
  1556. X            *sourcepnt = ++sptr;
  1557. X            *tabpnt = valaddr;
  1558. X            return (*valaddr == -1) ?
  1559. X                CF_UNDEF : CF_CHAR;
  1560. X        }
  1561. X        
  1562. X    case '\\':
  1563. X        switch(cv =  *(++sptr) )
  1564. X        {
  1565. X        case '\0':
  1566. X            *sourcepnt = sptr;
  1567. X            return CF_INVALID;
  1568. X        
  1569. X        case '\'':
  1570. X        case '\"':
  1571. X        case '\\':
  1572. X            if( chtab == (int *)NULL)
  1573. X            {
  1574. X                *numret = *sptr;
  1575. X                *sourcepnt = ++sptr;
  1576. X                return CF_NUMBER;
  1577. X            }
  1578. X            else
  1579. X            {
  1580. X                valaddr = &(chtab[(cv & 0xff) + 256]);
  1581. X                *sourcepnt = ++sptr;
  1582. X                *tabpnt = valaddr;
  1583. X                return (*valaddr == -1) ?
  1584. X                    CF_UNDEF : CF_CHAR;
  1585. X            }
  1586. X
  1587. X
  1588. X        default:
  1589. X            if( chtab == (int *)NULL)
  1590. X            {
  1591. X                *sourcepnt = ++sptr;
  1592. X                return CF_INVALID;
  1593. X            }
  1594. X            else
  1595. X            {
  1596. X                valaddr = &(chtab[(cv & 0xff) + 256]);
  1597. X                *sourcepnt = ++sptr;
  1598. X                *tabpnt = valaddr;
  1599. X                return (*valaddr == -1) ?
  1600. X                    CF_UNDEF : CF_CHAR;
  1601. X            }
  1602. X
  1603. X        case '0': case '1': case '2': case '3':
  1604. X        case '4': case '5': case '6': case '7':
  1605. X            {
  1606. X                numval = cv - '0';
  1607. X                cv =  *(++sptr);
  1608. X                if(cv >= '0' && cv <= '7')
  1609. X                {
  1610. X                    numval = numval * 8 +
  1611. X                        cv - '0';
  1612. X
  1613. X                    cv = *(++sptr);
  1614. X                    if(cv >= '0' && cv <= '7')
  1615. X                    {
  1616. X                        numval = numval * 8 +
  1617. X                            cv - '0';
  1618. X                        ++sptr;
  1619. X                    }
  1620. X                }
  1621. X                *sourcepnt = sptr;
  1622. X                *numret = numval & 0xff;
  1623. X                return CF_NUMBER;
  1624. X            }
  1625. X
  1626. X        case 'x':
  1627. X            switch(cv = *(++sptr))
  1628. X            {
  1629. X            case '0': case '1': case '2': case '3':
  1630. X            case '4': case '5': case '6': case '7':
  1631. X            case '8': case '9':
  1632. X                numval = cv - '0';
  1633. X                break;
  1634. X            
  1635. X            case 'a': case 'b': case 'c':
  1636. X            case 'd': case 'e': case 'f':
  1637. X                numval = cv - 'a' + 10; 
  1638. X                break;
  1639. X            
  1640. X            case 'A': case 'B': case 'C':
  1641. X            case 'D': case 'E': case 'F':
  1642. X                numval = cv - 'A' + 10;
  1643. X                break;
  1644. X            
  1645. X            default:
  1646. X                *sourcepnt = sptr;
  1647. X                return CF_INVALID;
  1648. X            }
  1649. X
  1650. X            switch(cv = *(++sptr))
  1651. X            {
  1652. X            case '0': case '1': case '2': case '3':
  1653. X            case '4': case '5': case '6': case '7':
  1654. X            case '8': case '9':
  1655. X                numval = numval * 16 + cv - '0';
  1656. X                ++sptr;
  1657. X                break;
  1658. X            
  1659. X            case 'a': case 'b': case 'c': 
  1660. X            case 'd': case 'e': case 'f':
  1661. X                numval = numval * 16 + cv - 'a' + 10; 
  1662. X                ++sptr;
  1663. X                break;
  1664. X            
  1665. X            case 'A': case 'B': case 'C':
  1666. X            case 'D': case 'E': case 'F':
  1667. X                numval = numval * 16 + cv - 'A' + 10;
  1668. X                ++sptr;
  1669. X                break;
  1670. X            
  1671. X            default:
  1672. X                break;
  1673. X            }
  1674. X
  1675. X            *sourcepnt = sptr;
  1676. X            *numret = numval;
  1677. X            return CF_NUMBER;
  1678. X        }
  1679. X    }
  1680. X}
  1681. X
  1682. Xint chtran(sourceptr)
  1683. X    char **sourceptr;
  1684. X{
  1685. X    int numval;
  1686. X    int *retptr;
  1687. X    char *beforeptr = *sourceptr;
  1688. X
  1689. X    switch(chtcfind(chtcpoint, sourceptr, &retptr, &numval))
  1690. X    {
  1691. X    case CF_END:
  1692. X    default:
  1693. X        return 0;
  1694. X    
  1695. X    case CF_INVALID:
  1696. X        fracherror("invalid character constant", beforeptr, *sourceptr);
  1697. X        return 0;
  1698. X
  1699. X    case CF_UNDEF:
  1700. X        fracherror("undefined character value", beforeptr, *sourceptr);
  1701. X        return 0;
  1702. X
  1703. X    case CF_NUMBER:
  1704. X        return numval;
  1705. X
  1706. X    case CF_CHAR:
  1707. X        return *retptr;
  1708. X    }
  1709. X}
  1710. X
  1711. X
  1712. Xint genstring(str)
  1713. X    char *str;
  1714. X/*
  1715. X    description    Produce 'D' records for a ascii string constant
  1716. X            by chopping it up into lengths that will fit
  1717. X            in the intermediate file
  1718. X    parameters    a character string
  1719. X    return        the length of the string total (machine code bytes)
  1720. X*/
  1721. X{
  1722. X#define STCHPERLINE 20
  1723. X    int rvlen = 0, linecount;
  1724. X
  1725. X    while(*str != '\0')
  1726. X    {
  1727. X        goutptr = &goutbuff[2];
  1728. X
  1729. X        for( linecount = 0; 
  1730. X            linecount < STCHPERLINE && *str != '\0';
  1731. X            linecount++)
  1732. X        {
  1733. X            gout2hex(chtran(&str));
  1734. X            goutch(IFC_EMU8);
  1735. X            rvlen++;
  1736. X        }
  1737. X
  1738. X        if(goutptr > &goutbuff[2])
  1739. X        {
  1740. X            goutch('\n');
  1741. X            fwrite(goutbuff,sizeof (char), goutptr - &goutbuff[0], 
  1742. X                intermedf);
  1743. X        }
  1744. X    }
  1745. X
  1746. X    return rvlen;
  1747. X}
  1748. X    
  1749. Xstatic char *pepolptr;
  1750. Xstatic int pepolcnt;
  1751. Xstatic long etop;
  1752. Xstatic int    etopseg;
  1753. X#define STACKALLOWANCE 4 /* number of level used outside polish expr */
  1754. X
  1755. Xpevalexpr(sub, exn)
  1756. X    int sub, exn;
  1757. X/*
  1758. X    description    evaluate and save the results of an expression tree
  1759. X    parameters    the subscript to the evalr element to place the results
  1760. X            the subscript of the root node of a parser expression
  1761. X                tree
  1762. X    globals        the evaluation results array
  1763. X            the expression stack
  1764. X            the expression tree node array
  1765. X    return        in evalr[sub].seg == SSG_UNDEF if the polish expression
  1766. X            conversion overflowed, or any undefined symbols were
  1767. X            referenced.
  1768. X*/
  1769. X{
  1770. X    etop = 0;
  1771. X    etopseg = SSG_UNUSED;
  1772. X    estkm1p = &estk[0];
  1773. X
  1774. X    pepolptr = &evalr[sub].exprstr[0];
  1775. X    pepolcnt = PPEXPRLEN;
  1776. X
  1777. X    if(pepolcon(exn))
  1778. X    {
  1779. X        evalr[sub].seg = etopseg;
  1780. X        evalr[sub].value = etop;
  1781. X        polout('\0');
  1782. X    }
  1783. X    else
  1784. X    {
  1785. X        evalr[sub].exprstr[0] = '\0';
  1786. X        evalr[sub].seg = SSG_UNDEF;
  1787. X    }
  1788. X}
  1789. X
  1790. Xpolout(ch)
  1791. X    char ch;
  1792. X/*
  1793. X    description    output a character to a evar[?].exprstr array
  1794. X    globals        parser expression to polish pointer pepolptr
  1795. X*/
  1796. X{
  1797. X    if(pepolcnt > 1)
  1798. X    {
  1799. X        *pepolptr++ = ch;
  1800. X        pepolcnt --;
  1801. X    }
  1802. X    else
  1803. X    {
  1804. X        *pepolptr = '\0';
  1805. X        fraerror("overflow in polish expression conversion");
  1806. X    }
  1807. X}
  1808. X
  1809. Xpolnumout(inv)
  1810. X    unsigned long inv;
  1811. X/*
  1812. X    description    output a long constant to a polish expression
  1813. X*/
  1814. X{
  1815. X    if( inv > 15)
  1816. X        polnumout(inv >> 4);
  1817. X    polout(hexch((int) inv ));
  1818. X}
  1819. X
  1820. Xpepolcon(esub)
  1821. X    int esub;
  1822. X/*
  1823. X    description    convert an expression tree to polish notation
  1824. X            and do a preliminary evaluation of the numeric value
  1825. X            of the expression
  1826. X    parameters    the subscript of an expression node
  1827. X    globals        the expression stack
  1828. X            the polish expression string in an evalr element
  1829. X    return        False if the expression stack overflowed
  1830. X
  1831. X            The expression stack top contains the
  1832. X            value and segment for the result of the expression
  1833. X            which are propgated along as numeric operators are
  1834. X            evaluated.  Undefined references result in an
  1835. X            undefined result.
  1836. X*/
  1837. X{
  1838. X    switch(enode[esub].evs)
  1839. X    {
  1840. X    case  PCCASE_UN:
  1841. X        {
  1842. X            if( ! pepolcon(enode[esub].left))
  1843. X                return FALSE;
  1844. X
  1845. X            polout(enode[esub].op);
  1846. X
  1847. X            switch(enode[esub].op)
  1848. X            {
  1849. X#include "fraeuni.h"
  1850. X            }
  1851. X        }
  1852. X        break;
  1853. X
  1854. X    case  PCCASE_BIN:
  1855. X        {
  1856. X            if( ! pepolcon(enode[esub].left))
  1857. X                return FALSE;
  1858. X
  1859. X            polout(IFC_LOAD);
  1860. X
  1861. X            if(estkm1p >= &estk[PESTKDEPTH-1-STACKALLOWANCE])
  1862. X            {
  1863. X                fraerror("expression stack overflow");
  1864. X                return FALSE;
  1865. X            }
  1866. X
  1867. X            (++estkm1p)->v = etop;
  1868. X            estkm1p -> s = etopseg;
  1869. X            etopseg = SSG_UNUSED;    
  1870. X            etop = 0;
  1871. X
  1872. X            if( ! pepolcon(enode[esub].right))
  1873. X                return FALSE;
  1874. X
  1875. X            polout(enode[esub].op);
  1876. X
  1877. X            if(estkm1p -> s != SSG_ABS)
  1878. X                etopseg = estkm1p -> s;
  1879. X
  1880. X            switch(enode[esub].op)
  1881. X            {
  1882. X#include "fraebin.h"
  1883. X            }
  1884. X        }
  1885. X        break;
  1886. X
  1887. X    case  PCCASE_DEF:
  1888. X        if(enode[esub].sym -> seg > 0)
  1889. X        {
  1890. X            polnumout(1L);
  1891. X            etop = 1;
  1892. X            etopseg = SSG_ABS;
  1893. X        }
  1894. X        else
  1895. X        {
  1896. X            polnumout(0L);
  1897. X            etop = 0;
  1898. X            etopseg = SSG_ABS;
  1899. X        }
  1900. X        break;
  1901. X
  1902. X    case  PCCASE_SYMB:
  1903. X        etop = (enode[esub].sym) -> value;
  1904. X        etopseg = (enode[esub].sym) -> seg;
  1905. X        if(etopseg == SSG_EQU ||
  1906. X           etopseg == SSG_SET ) 
  1907. X        {
  1908. X            etopseg = SSG_ABS;
  1909. X            polnumout((unsigned long)(enode[esub].sym) -> value);
  1910. X        }
  1911. X        else
  1912. X        {
  1913. X            polnumout((unsigned long)(enode[esub].sym) -> symnum);
  1914. X            polout(IFC_SYMB);
  1915. X        }
  1916. X        break;
  1917. X            
  1918. X    case  PCCASE_PROGC:
  1919. X        polout(IFC_PROGCTR);
  1920. X        etop = locctr;
  1921. X        etopseg = SSG_ABS;
  1922. X        break;
  1923. X            
  1924. X    case  PCCASE_CONS:
  1925. X        polnumout((unsigned long)enode[esub].val);
  1926. X        etop = enode[esub].val;
  1927. X        etopseg = SSG_ABS;
  1928. X        break;
  1929. X
  1930. X    }
  1931. X    return TRUE;
  1932. X}
  1933. SHAR_EOF
  1934. true || echo 'restore of frapsub.c failed'
  1935. fi
  1936. # ============= frasmain.c ==============
  1937. if test -f 'frasmain.c' -a X"$1" != X"-c"; then
  1938.     echo 'x - skipping frasmain.c (File already exists)'
  1939. else
  1940. echo 'x - extracting frasmain.c (Text)'
  1941. sed 's/^X//' << 'SHAR_EOF' > 'frasmain.c' &&
  1942. X/*
  1943. XHEADER:     ;
  1944. XTITLE:         Frankenstein Cross Assemblers;
  1945. XVERSION:     2.0;
  1946. XDESCRIPTION: "    Reconfigurable Cross-assembler producing Intel (TM)
  1947. X        Hex format object records.  ";
  1948. XKEYWORDS:     cross-assemblers, 1805, 2650, 6301, 6502, 6805, 6809, 
  1949. X        6811, tms7000, 8048, 8051, 8096, z8, z80;
  1950. XSYSTEM:     UNIX, MS-Dos ;
  1951. XFILENAME:     frasmain.c;
  1952. XWARNINGS:     "This software is in the public domain.  
  1953. X        Any prior copyright claims are relinquished.  
  1954. X
  1955. X        This software is distributed with no warranty whatever.  
  1956. X        The author takes no responsibility for the consequences 
  1957. X        of its use.
  1958. X
  1959. X        Yacc (or Bison) required to compile."  ;
  1960. XSEE-ALSO:     base.doc, as*.doc (machine specific appendices) , 
  1961. X        as*.1 (man pages);
  1962. XAUTHORS:     Mark Zenier;
  1963. XCOMPILERS:     Microport Sys V/AT, ATT Yacc, Turbo C V1.5, Bison (CUG disk 285)
  1964. X        (previous versions Xenix, Unisoft 68000 Version 7, Sun 3);
  1965. X*/
  1966. X/*
  1967. X    description    Main file
  1968. X    usage        Unix, framework crossassembler
  1969. X    history        September 25, 1987
  1970. X            August 3, 1988    v 1.4
  1971. X            September 14, 1990  v 1.5  Dosified
  1972. X*/
  1973. X
  1974. X#define    Global
  1975. X
  1976. X#include <stdio.h>
  1977. X#include "frasmdat.h"
  1978. X
  1979. XFILE * intermedf = (FILE *) NULL;
  1980. Xchar *interfn = 
  1981. X#ifdef DOSTMP
  1982. X "frtXXXXXX";
  1983. X#else
  1984. X "/usr/tmp/frtXXXXXX";
  1985. X#endif
  1986. Xchar *hexfn, *loutfn;
  1987. Xint errorcnt = 0, warncnt = 0;
  1988. Xint listflag = FALSE, hexflag = FALSE, hexvalid = FALSE;
  1989. Xstatic int debugmode = FALSE;
  1990. Xstatic FILE *symbf;
  1991. Xstatic char *symbfn;
  1992. Xstatic int  symbflag = FALSE;
  1993. Xchar hexcva[17] = "0123456789abcdef";
  1994. X
  1995. X#ifdef NOGETOPT
  1996. X#include "getopt.h"
  1997. X#endif
  1998. Xmain(argc, argv)
  1999. X    int argc;
  2000. X    char *(argv[]);
  2001. X/*
  2002. X    description    top driver routine for framework cross assembler
  2003. X                set the cpu type if implemented in parser
  2004. X                process the command line parameters
  2005. X                setup the tables
  2006. X                call the first pass parser
  2007. X                print the symbol table
  2008. X                call the second pass
  2009. X                close down and delete the outputs if any errors
  2010. X    return        exit(2) for error, exit(0) for OK
  2011. X*/
  2012. X{
  2013. X    extern char *optarg;
  2014. X    extern int optind;
  2015. X    int grv;
  2016. X
  2017. X    grv = cpumatch(argv[0]);
  2018. X
  2019. X    while( (grv = getopt(argc, argv, "dh:o:l:s:p:")) != EOF)
  2020. X    {
  2021. X        switch(grv)
  2022. X        {
  2023. X        case 'o':
  2024. X        case 'h':
  2025. X            hexfn = optarg;
  2026. X            hexflag = hexvalid = TRUE;
  2027. X            break;
  2028. X        
  2029. X        case 'l':
  2030. X            loutfn = optarg;
  2031. X            listflag = TRUE;
  2032. X            break;
  2033. X
  2034. X        case 'd':
  2035. X            debugmode = TRUE;
  2036. X            break;
  2037. X
  2038. X        case 's':
  2039. X            symbflag = TRUE;
  2040. X            symbfn = optarg;
  2041. X            break;
  2042. X
  2043. X        case 'p':
  2044. X            if( ! cpumatch(optarg) )
  2045. X            {
  2046. X                fprintf(stderr, 
  2047. X        "%s: no match on CPU type %s, default used\n", 
  2048. X                    argv[0], optarg);
  2049. X            }
  2050. X            break;
  2051. X
  2052. X        case '?':
  2053. X            break;
  2054. X        }
  2055. X    }
  2056. X
  2057. X    if(optind < argc)
  2058. X    {
  2059. X        if(strcmp(argv[optind], "-") == 0)
  2060. X        {
  2061. X            yyin = stdin;
  2062. X        }
  2063. X        else
  2064. X        {
  2065. X            if( (yyin = fopen(argv[optind], "r")) == (FILE *)NULL)
  2066. X            {
  2067. X                fprintf(stderr, 
  2068. X                    "%s: cannot open input file %s\n",
  2069. X                    argv[0], argv[optind]);
  2070. X                exit(1);
  2071. X            }
  2072. X        }
  2073. X    }
  2074. X    else
  2075. X    {
  2076. X        fprintf(stderr, "%s: no input file\n", argv[0]);
  2077. X        exit(1);
  2078. X    }
  2079. X
  2080. X    if(listflag)
  2081. X    {
  2082. X        if(strcmp(argv[optind], loutfn) == 0) 
  2083. X        {
  2084. X            fprintf(stderr, "%s: list file overwrites input %s\n",
  2085. X                argv[0], loutfn);
  2086. X            listflag = FALSE;
  2087. X        }
  2088. X        else if( (loutf = fopen(loutfn, "w")) == (FILE *) NULL)
  2089. X        {
  2090. X            fprintf(stderr, "%s: cannot open list file %s\n",
  2091. X                argv[0], loutfn);
  2092. X            listflag = FALSE;
  2093. X        }
  2094. X    }
  2095. X
  2096. X    if( ! listflag)
  2097. X    {
  2098. X        loutf = stdout;
  2099. X    }
  2100. X
  2101. X    mktemp(interfn);
  2102. X    if( (intermedf = fopen(interfn, "w")) == (FILE *) NULL)
  2103. X    {
  2104. X        fprintf(stderr, "%s: cannot open temp file %s\n",
  2105. X            argv[0], interfn);
  2106. X        exit(1);
  2107. X    }
  2108. X
  2109. X    setophash();
  2110. X    setreserved();
  2111. X    elseifstk[0] = endifstk[0] = If_Err;
  2112. X    fprintf(intermedf, "F:%s\n", argv[optind]);
  2113. X    infilestk[0].fpt = yyin;
  2114. X    infilestk[0].fnm = argv[optind];
  2115. X    currfstk = 0;
  2116. X    currseg = 0;
  2117. X    
  2118. X    yyparse();
  2119. X    
  2120. X    if(ifstkpt != 0)
  2121. X        fraerror("active IF at end of file");
  2122. X
  2123. X    buildsymbolindex();
  2124. X    if(listflag)
  2125. X        printsymbols();
  2126. X
  2127. X    if(symbflag)
  2128. X    {
  2129. X        if(strcmp(argv[optind], symbfn) == 0) 
  2130. X        {
  2131. X            fprintf(stderr, "%s: symbol file overwrites input %s\n",
  2132. X                argv[0], symbfn);
  2133. X        }
  2134. X        else if( (symbf = fopen(symbfn, "w")) == (FILE *) NULL)
  2135. X        {
  2136. X            fprintf(stderr, "%s: cannot open symbol file %s\n",
  2137. X                argv[0], symbfn);
  2138. X        }
  2139. X        else
  2140. X        {
  2141. X            filesymbols();
  2142. X            fclose(symbf);
  2143. X        }
  2144. X    }
  2145. X
  2146. X    
  2147. X    fclose(intermedf);
  2148. X    if( (intermedf = fopen(interfn, "r")) == (FILE *) NULL)
  2149. X    {
  2150. X        fprintf(stderr, "%s: cannot open temp file %s\n",
  2151. X            argv[0], interfn);
  2152. X        exit(1);
  2153. X    }
  2154. X
  2155. X    if(errorcnt > 0)
  2156. X        hexflag = FALSE;
  2157. X
  2158. X    if(hexflag)
  2159. X    {
  2160. X        if(strcmp(argv[optind], hexfn) == 0) 
  2161. X        {
  2162. X            fprintf(stderr, "%s: hex output overwrites input %s\n",
  2163. X                argv[0], hexfn);
  2164. X            hexflag = FALSE;
  2165. X        }
  2166. X        else if( (hexoutf = fopen(hexfn, "w")) == (FILE *) NULL)
  2167. X        {
  2168. X            fprintf(stderr, "%s: cannot open hex output %s\n",
  2169. X                argv[0], hexfn);
  2170. X            hexflag = FALSE;
  2171. X        }
  2172. X    }
  2173. X
  2174. X    currfstk = 0;
  2175. X    outphase();
  2176. X
  2177. X    if(errorcnt > 0)
  2178. X        hexvalid = FALSE;
  2179. X
  2180. X    fprintf(loutf, " ERROR SUMMARY - ERRORS DETECTED %d\n", errorcnt);
  2181. X    fprintf(loutf, "               -  WARNINGS       %d\n", warncnt);
  2182. X
  2183. X    if(listflag)
  2184. X    {
  2185. X        fprintf(stderr, " ERROR SUMMARY - ERRORS DETECTED %d\n", 
  2186. X            errorcnt);
  2187. X        fprintf(stderr, "               -  WARNINGS       %d\n", 
  2188. X            warncnt);
  2189. X    }
  2190. X
  2191. X    if(listflag)
  2192. X        fclose(loutf);
  2193. X    
  2194. X    if(hexflag)
  2195. X    {
  2196. X        fclose(hexoutf);
  2197. X        if( ! hexvalid)
  2198. X            unlink(hexfn);
  2199. X    }
  2200. X    
  2201. X    fclose(intermedf);
  2202. X    if( ! debugmode)
  2203. X        unlink(interfn);
  2204. X    else
  2205. X        abort();
  2206. X    
  2207. X    exit(errorcnt > 0 ? 2 : 0);
  2208. X}
  2209. X        
  2210. X
  2211. Xfrafatal(str)
  2212. X    char * str;
  2213. X/*
  2214. X    description    Fatal error subroutine, shutdown and quit right now!
  2215. X    parameters    message
  2216. X    globals        if debug mode is true, save intermediate file
  2217. X    return        exit(2)
  2218. X*/
  2219. X{
  2220. X    fprintf(stderr, "Fatal error - %s\n",str);
  2221. X
  2222. X    if( intermedf != (FILE *) NULL)
  2223. X    {
  2224. X        fclose(intermedf);
  2225. X        if( ! debugmode)
  2226. X            unlink(interfn);
  2227. X    }
  2228. X        
  2229. X    exit(2);
  2230. X}
  2231. X
  2232. Xfrawarn(str)
  2233. X    char * str;
  2234. X/*
  2235. X    description    first pass - generate warning message by writing line
  2236. X            to intermediate file
  2237. X    parameters    message
  2238. X    globals        the count of warnings
  2239. X*/
  2240. X{
  2241. X    fprintf(intermedf, "E: WARNING - %s\n",str);
  2242. X    warncnt++;
  2243. X}
  2244. X
  2245. Xfraerror(str)
  2246. X    char * str;
  2247. X/*
  2248. X    description    first pass - generate error message by writing line to
  2249. X            intermediate file
  2250. X    parameters    message
  2251. X    globals        count of errors
  2252. X*/
  2253. X{
  2254. X    fprintf(intermedf, "E: ERROR - %s\n",str);
  2255. X    errorcnt++;
  2256. X}
  2257. X
  2258. Xfracherror(str, start, beyond)
  2259. X    char * str, *start, *beyond;
  2260. X/*
  2261. X    description    first pass - generate error message by writing line to
  2262. X            intermediate file
  2263. X    parameters    message
  2264. X            pointer to bad character definition
  2265. X            pointer after bad definition
  2266. X    globals        count of errors
  2267. X*/
  2268. X{
  2269. X    char bcbuff[8];
  2270. X    int cnt;
  2271. X
  2272. X    for(cnt=0; start < beyond && *start != '\0' && cnt < 7; cnt++)
  2273. X    {
  2274. X        bcbuff[cnt] = *start++;
  2275. X    }
  2276. X    bcbuff[cnt] = '\0';
  2277. X
  2278. X    fprintf(intermedf, "E: ERROR - %s \'%s\'\n",str, bcbuff);
  2279. X    errorcnt++;
  2280. X}
  2281. X
  2282. X
  2283. Xprtequvalue(fstr, lv)
  2284. X    char * fstr;
  2285. X    long lv;
  2286. X/*
  2287. X    description    first pass - generate comment lines in intermediate file
  2288. X            for the value in a set, equate, or org statement, etc...
  2289. X    parameters    format string and a long integer value
  2290. X*/
  2291. X{
  2292. X    fprintf(intermedf, fstr, lv);
  2293. X}
  2294. X
  2295. X#define SYMPERLINE 3
  2296. X
  2297. Xprintsymbols()
  2298. X/*
  2299. X    description    print the symbols on the listing file, 3 symbols
  2300. X            across.  Only the first 15 characters are printed
  2301. X            though all are significant.  Reserved symbols are
  2302. X            not assigned symbol numbers and thus are not printed.
  2303. X    globals        the symbol index array and the symbol table elements.
  2304. X*/
  2305. X{
  2306. X    int syn, npl = 0;
  2307. X    struct symel *syp;
  2308. X
  2309. X    for(syn = 1; syn <nextsymnum; syn++)
  2310. X    {
  2311. X        if(npl >= SYMPERLINE)
  2312. X        {
  2313. X            fputc('\n', loutf);
  2314. X            npl = 0;
  2315. X        }
  2316. X
  2317. X        syp = symbindex[syn];
  2318. X
  2319. X        if(syp -> seg != SSG_UNDEF)
  2320. X            fprintf(loutf, "%8.8lx %-15.15s  ",syp -> value,
  2321. X                syp -> symstr);
  2322. X        else
  2323. X            fprintf(loutf, "???????? %-15.15s  ", syp -> symstr);
  2324. X        npl++;
  2325. X    }
  2326. X
  2327. X    if(npl > 0)
  2328. X        fputc('\n', loutf);
  2329. X
  2330. X    fputc('\f', loutf);
  2331. X}
  2332. X
  2333. X
  2334. Xfilesymbols()
  2335. X/*
  2336. X    description    print the symbols to the symbol table file
  2337. X    globals        the symbol index array and the symbol table elements.
  2338. X*/
  2339. X{
  2340. X    int syn;
  2341. X    struct symel *syp;
  2342. X
  2343. X    for(syn = 1; syn <nextsymnum; syn++)
  2344. X    {
  2345. X        syp = symbindex[syn];
  2346. X
  2347. X        if(syp -> seg != SSG_UNDEF)
  2348. X            fprintf(symbf, "%8.8lx %s\n",syp -> value,
  2349. X                syp -> symstr);
  2350. X        else
  2351. X            fprintf(symbf, "???????? %s\n", syp -> symstr);
  2352. X    }
  2353. X}
  2354. SHAR_EOF
  2355. true || echo 'restore of frasmain.c failed'
  2356. fi
  2357. # ============= frasmdat.h ==============
  2358. if test -f 'frasmdat.h' -a X"$1" != X"-c"; then
  2359.     echo 'x - skipping frasmdat.h (File already exists)'
  2360. else
  2361. echo 'x - extracting frasmdat.h (Text)'
  2362. sed 's/^X//' << 'SHAR_EOF' > 'frasmdat.h' &&
  2363. X
  2364. X/*
  2365. XHEADER:     ;
  2366. XTITLE:         Frankenstein Cross Assemblers;
  2367. XVERSION:     2.0;
  2368. XDESCRIPTION: "    Reconfigurable Cross-assembler producing Intel (TM)
  2369. X        Hex format object records.  ";
  2370. XFILENAME:     frasmdat.h;
  2371. XSEE-ALSO:     ;
  2372. XAUTHORS:     Mark Zenier;
  2373. X*/
  2374. X
  2375. X/*
  2376. X    description    structures and data used in parser and output phases
  2377. X    history        September 15, 1987
  2378. X            August 3, 1988   Global
  2379. X            September 14, 1990   6 char portable var
  2380. X*/
  2381. X
  2382. X#include <ctype.h>
  2383. X#define PRINTCTRL(char) ((char)+'@')
  2384. X
  2385. X#ifndef Global
  2386. X#define    Global    extern
  2387. X#endif
  2388. X
  2389. X#ifdef USEINDEX
  2390. X#define strchr index
  2391. X#endif
  2392. X
  2393. X#ifdef NOSTRING
  2394. Xextern char * strncpy();
  2395. Xextern char * strchr();
  2396. Xextern int strcmp();
  2397. Xextern int strlen();
  2398. X#else
  2399. X#include <string.h>
  2400. X#endif
  2401. X
  2402. X#define local 
  2403. X
  2404. X#define TRUE 1
  2405. X#define FALSE 0
  2406. X
  2407. X#define hexch(cv) (hexcva[(cv)&0xf])
  2408. Xextern char hexcva[];
  2409. X
  2410. X/* symbol table element */
  2411. Xstruct symel
  2412. X{
  2413. X    char    *symstr;
  2414. X    int    tok;
  2415. X    int    seg;
  2416. X    long    value;
  2417. X    struct    symel *nextsym;
  2418. X    int    symnum;
  2419. X};
  2420. X
  2421. X#define SSG_UNUSED 0
  2422. X#define SSG_UNDEF -1
  2423. X#define SSG_ABS 8
  2424. X#define SSG_RESV -2
  2425. X#define SSG_EQU 2
  2426. X#define SSG_SET 3
  2427. X
  2428. X#define SYMNULL (struct symel *) NULL
  2429. Xstruct symel * symbentry();
  2430. X
  2431. X/* opcode symbol table element */
  2432. X
  2433. Xstruct opsym
  2434. X{
  2435. X    char    *opstr;
  2436. X    int    token;
  2437. X    int    numsyn;
  2438. X    int    subsyn;
  2439. X};
  2440. X
  2441. Xstruct opsynt
  2442. X{
  2443. X    int    syntaxgrp;
  2444. X    int    elcnt;
  2445. X    int    gentabsub;
  2446. X};
  2447. X
  2448. Xstruct igel 
  2449. X{
  2450. X    int    selmask;
  2451. X    int    criteria;
  2452. X    char    * genstr;
  2453. X};
  2454. X    
  2455. X#define PPEXPRLEN 256
  2456. X
  2457. Xstruct evalrel
  2458. X{
  2459. X    int    seg;
  2460. X    long    value;
  2461. X    char    exprstr[PPEXPRLEN];
  2462. X};
  2463. X
  2464. X#define INBUFFSZ 258
  2465. Xextern char finbuff[INBUFFSZ];
  2466. X
  2467. Xextern int nextsymnum;
  2468. XGlobal struct symel **symbindex;
  2469. X
  2470. X#define EXPRLSIZE (INBUFFSZ/2)
  2471. Xextern int nextexprs;
  2472. XGlobal int    exprlist[EXPRLSIZE];
  2473. X
  2474. X#define STRLSIZE (INBUFFSZ/2)
  2475. Xextern int nextstrs;
  2476. XGlobal char *    stringlist[STRLSIZE];
  2477. X
  2478. Xextern struct opsym optab[];
  2479. Xextern int gnumopcode;
  2480. Xextern struct opsynt ostab[];
  2481. Xextern struct igel igtab[];
  2482. Xextern int ophashlnk[];
  2483. X
  2484. X#define NUMPEXP 6
  2485. XGlobal struct evalrel evalr[NUMPEXP];
  2486. X
  2487. X#define PESTKDEPTH 32
  2488. Xstruct evstkel
  2489. X{
  2490. X    long v;
  2491. X    int s;
  2492. X};
  2493. X
  2494. XGlobal struct evstkel    estk[PESTKDEPTH], *estkm1p;
  2495. X
  2496. XGlobal int    currseg; 
  2497. XGlobal long     locctr; 
  2498. X
  2499. Xextern FILE *yyin;
  2500. Xextern FILE    *intermedf;
  2501. Xextern int    listflag;
  2502. Xextern int hexvalid, hexflag;
  2503. XGlobal FILE    *hexoutf, *loutf;
  2504. Xextern int errorcnt, warncnt;
  2505. X
  2506. Xextern int linenumber;
  2507. X
  2508. X#define IFSTKDEPTH 32
  2509. Xextern int    ifstkpt; 
  2510. XGlobal enum { If_Active, If_Skip, If_Err } 
  2511. X    elseifstk[IFSTKDEPTH], endifstk[IFSTKDEPTH];
  2512. X
  2513. X#define FILESTKDPTH 20
  2514. XGlobal int currfstk;
  2515. X#define nextfstk (currfstk+1)
  2516. XGlobal struct fstkel
  2517. X{
  2518. X    char *fnm;
  2519. X    FILE *fpt;
  2520. X} infilestk[FILESTKDPTH];
  2521. X
  2522. XGlobal int lnumstk[FILESTKDPTH];
  2523. XGlobal char currentfnm[100];
  2524. X
  2525. Xextern struct symel * endsymbol;
  2526. X
  2527. Xenum readacts
  2528. X{
  2529. X    Nra_normal, 
  2530. X    Nra_new, 
  2531. X    Nra_end 
  2532. X} ;
  2533. X
  2534. Xextern enum readacts nextreadact;
  2535. X
  2536. Xchar * savestring(), *findgen();
  2537. Xlong    strtol();
  2538. Xvoid    reservedsym();
  2539. Xchar    *calloc(), *malloc();
  2540. X
  2541. Xextern struct symel * endsymbol;
  2542. Xextern char ignosyn[] ;
  2543. Xextern char ignosel[] ;
  2544. X
  2545. X#define NUM_CHTA 6
  2546. Xextern int chtnxalph, *chtcpoint, *chtnpoint ;
  2547. XGlobal int *(chtatab[NUM_CHTA]);
  2548. Xint chtcreate(), chtcfind(), chtran();
  2549. X
  2550. X#define CF_END        -2
  2551. X#define CF_INVALID     -1
  2552. X#define CF_UNDEF     0
  2553. X#define CF_CHAR     1
  2554. X#define CF_NUMBER     2
  2555. X
  2556. SHAR_EOF
  2557. true || echo 'restore of frasmdat.h failed'
  2558. fi
  2559. true || echo 'restore of fryylex.c failed'
  2560. echo End of part 2, continue with part 3
  2561. exit 0
  2562.