home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume5 / z80ad / part03 < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  24.3 KB

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: bownesrm@beowulf.UUCP (Keptin Comrade Dr. Bob)
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i088: Z80 Assembler/Disassembler part 3 of 3
  5. Message-ID: <1126@beowulf.UUCP>
  6. Date: 19 Dec 88 01:11:22 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: bownesrm@beowulf.UUCP (Keptin Comrade Dr. Bob)
  9. Organization: Reality Central
  10. Lines: 1311
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. Posting-number: Volume 5, Issue 88
  14. Submitted-by: "Keptin Comrade Dr. Bob" <bownesrm@beowulf.UUCP>
  15. Archive-name: z80ad/part03
  16.  
  17. #!/bin/sh
  18. # this is part 3 of an archive
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file zmac/zmac.y continued
  21. #
  22. CurArch=3
  23. if test ! -r ._seq_
  24. then echo "Please unpack part 1 first!"
  25.      exit 1; fi
  26. ( read Scheck
  27.   if test "$Scheck" != $CurArch
  28.   then echo "Please unpack part $Scheck next!"
  29.        exit 1;
  30.   else exit 0; fi
  31. ) < ._seq_ || exit 1
  32. sed 's/^X//' << 'SHAR_EOF' >> zmac/zmac.y
  33. X    '8',    '9',    0,    0,    0,    0,    0,    0,
  34. X    0,    'A',    'B',    'C',    'D',    'E',    'F',    0,
  35. X    'H',    0,    0,    0,    0,    0,    0,    'O',
  36. X    0,    'Q',    0,    0,    0,    0,    0,    0,
  37. X    0,    0,    0,    0,    0,    0,    0,    0,
  38. X    0,    'a',    'b',    'c',    'd',    'e',    'f',    0,
  39. X    'h',    0,    0,    0,    0,    0,    0,    'o',
  40. X    0,    'q',    0,    0,    0,    0,    0,    0,
  41. X    0,    0,    0,    0,    0,    0,    0,    0,
  42. X    0};
  43. X
  44. X
  45. X
  46. X
  47. X/*
  48. X *  the following table is a list of assembler mnemonics;
  49. X *  for each mnemonic the associated machine-code bit pattern
  50. X *  and symbol type are given.
  51. X */
  52. Xstruct    item    keytab[] = {
  53. X    "a",    7,    ACC,    0,
  54. X    "adc",    1,    ARITHC,    0,
  55. X    "add",    0,    ADD,    0,
  56. X    "af",    060,    AF,    0,
  57. X    "and",    4,    LOGICAL,    0,
  58. X    "ascii",0,    DEFB,    0,
  59. X    "b",    0,    REGNAME,    0,
  60. X    "bc",    0,    RP,    0,
  61. X    "bit",    0145500,BIT,    0,
  62. X    "block",0,    DEFS,    0,
  63. X    "byte",    0,    DEFB,    0,
  64. X    "c",    1,    C,    0,
  65. X    "call", 0315,    CALL,    0,
  66. X    "ccf",    077,    NOOPERAND,    0,
  67. X    "cmp",    7,    LOGICAL,    0,        /* -cdk */
  68. X    "cp",    7,    LOGICAL,    0,
  69. X    "cpd",    0166651,NOOPERAND,    0,
  70. X    "cpdr",    0166671,NOOPERAND,    0,
  71. X    "cpi",    0166641,NOOPERAND,    0,
  72. X    "cpir",    0166661,NOOPERAND,    0,
  73. X    "cpl",    057,    NOOPERAND,    0,
  74. X    "d",    2,    REGNAME,    0,
  75. X    "daa",    0047,    NOOPERAND,    0,
  76. X    "de",    020,    RP,    0,
  77. X    "dec",    1,    INCDEC,    0,
  78. X    "defb",    0,    DEFB,    0,
  79. X    "defl",0,    DEFL,    0,
  80. X    "defs",    0,    DEFS,    0,
  81. X    "defw",    0,    DEFW,    0,
  82. X    "dephase",    0,    DEPHASE,    0,
  83. X    "di",    0363,    NOOPERAND,    0,
  84. X    "djnz",    020,    DJNZ,    0,
  85. X    "e",    3,    REGNAME,    0,
  86. X    "ei",    0373,    NOOPERAND,    0,
  87. X    "eject",1,    LIST,    0,
  88. X    "elist",3,    LIST,    0,
  89. X    "end",    0,    END,    0,
  90. X    "endif",0,    ENDIF,    0,
  91. X    "endm", 0,    ENDM,    0,
  92. X    "equ",    0,    EQU,    0,
  93. X    "ex",    0,    EX,    0,
  94. X    "exx",    0331,    NOOPERAND,    0,
  95. X    "f",    0,    F,    0,
  96. X    "flist",4,    LIST,    0,
  97. X    "glist",5,    LIST,    0,
  98. X    "h",    4,    REGNAME,    0,
  99. X    "halt",    0166,    NOOPERAND,    0,
  100. X    "hl",    040,    HL,    0,
  101. X    "i",    0,    MISCREG,    0,
  102. X    "if",    0,    IF,    0,
  103. X    "im",    0166506,IM,    0,
  104. X    "in",    0333,    IN,    0,
  105. X    "inc",    0,    INCDEC,    0,
  106. X    "include", 3,    ARGPSEUDO,    0,
  107. X    "ind",    0166652,NOOPERAND,    0,
  108. X    "indr",    0166672,NOOPERAND,    0,
  109. X    "ini",    0166642,NOOPERAND,    0,
  110. X    "inir",    0166662,NOOPERAND,    0,
  111. X    "ix",    0156440,INDEX,    0,
  112. X    "iy",    0176440,INDEX,    0,
  113. X    "jmp",    0303,    JP,    0,        /* -cdk */
  114. X    "jp",    0303,    JP,    0,
  115. X    "jr",    040,    JR,    0,
  116. X    "l",    5,    REGNAME,    0,
  117. X    "ld",    0,    LD,    0,
  118. X    "ldd",    0166650,NOOPERAND,    0,
  119. X    "lddr",    0166670,NOOPERAND,    0,
  120. X    "ldi",    0166640,NOOPERAND,    0,
  121. X    "ldir",    0166660,NOOPERAND,    0,
  122. X    "list",    0,    LIST,    0,
  123. X    "m",    070,    COND,    0,
  124. X    "macro",0,    MACRO,    0,
  125. X    "max",    1,    MINMAX,    0,
  126. X    "min",    0,    MINMAX,    0,
  127. X    "mlist",6,    LIST,    0,
  128. X    "mod",    0,    MOD,    0,
  129. X    "nc",    020,    SPCOND,    0,
  130. X    "neg",    0166504,NOOPERAND,    0,
  131. X    "nolist",-1,    LIST,    0,
  132. X    "nop",    0,    NOOPERAND,    0,
  133. X    "not",    0,    NOT,    0,
  134. X    "nv",    040,    COND,    0,
  135. X    "nz",    0,    SPCOND,    0,
  136. X    "or",    6,    LOGICAL,    0,
  137. X    "org",    0,    ORG,    0,
  138. X    "otdr",0166673,NOOPERAND,    0,
  139. X    "otir",0166663,NOOPERAND,    0,
  140. X    "out",    0323,    OUT,    0,
  141. X    "outd",    0166653,NOOPERAND,    0,
  142. X    "outi",    0166643,NOOPERAND,    0,
  143. X    "p",    060,    COND,    0,
  144. X    "pe",    050,    COND,    0,
  145. X    "phase",    0,    PHASE,    0,
  146. X    "po",    040,    COND,    0,
  147. X    "pop",    0301,    PUSHPOP,    0,
  148. X    "push", 0305,    PUSHPOP,    0,
  149. X    "r",    010,    MISCREG,    0,
  150. X    "res",    0145600,BIT,    0,
  151. X    "ret",    0311,    RET,    0,
  152. X    "reti",    0166515,NOOPERAND,    0,
  153. X    "retn",    0166505,NOOPERAND,    0,
  154. X    "rl",    2,    SHIFT,    0,
  155. X    "rla",    027,    NOOPERAND,    0,
  156. X    "rlc",    0,    SHIFT,    0,
  157. X    "rlca",    07,    NOOPERAND,    0,
  158. X    "rld",    0166557,NOOPERAND,    0,
  159. X    "rr",    3,    SHIFT,    0,
  160. X    "rra",    037,    NOOPERAND,    0,
  161. X    "rrc",    1,    SHIFT,    0,
  162. X    "rrca",    017,    NOOPERAND,    0,
  163. X    "rrd",    0166547,NOOPERAND,    0,
  164. X    "rst",    0307,    RST,    0,
  165. X    "rsym",    1,    ARGPSEUDO,    0,
  166. X    "sbc",    3,    ARITHC,    0,
  167. X    "scf",    067,    NOOPERAND,    0,
  168. X    "set",    0145700,BIT,    0,
  169. X    "shl",    0,    SHL,    0,
  170. X    "shr",    0,    SHR,    0,
  171. X    "sla",    4,    SHIFT,    0,
  172. X    "sp",    060,    SP,    0,
  173. X    "space",2,    LIST,    0,
  174. X    "sra",    5,    SHIFT,    0,
  175. X    "srl",    7,    SHIFT,    0,
  176. X    "sub",    2,    LOGICAL,    0,
  177. X    "title",0,    ARGPSEUDO,    0,
  178. X    "v",    050,    COND,    0,
  179. X    "word",    0,    DEFW,    0,
  180. X    "wsym",    2,    ARGPSEUDO,    0,
  181. X    "xor",    5,    LOGICAL,    0,
  182. X    "z",    010,    SPCOND,    0,
  183. X};
  184. X
  185. X/*
  186. X *  user-defined items are tabulated in the following table.
  187. X */
  188. X
  189. Xstruct item    itemtab[ITEMTABLESIZE];
  190. Xstruct item    *itemmax = &itemtab[ITEMTABLESIZE];
  191. X
  192. X
  193. X
  194. X
  195. X
  196. X/*
  197. X *  lexical analyser, called by yyparse.
  198. X */
  199. Xyylex()
  200. X{
  201. X    register char    c;
  202. X    register char *p;
  203. X    register int    radix;
  204. X    int  limit;
  205. X
  206. X    if (arg_flag)
  207. X        return(getarg());
  208. Xloop switch(charclass[c = nextchar()]) {
  209. X    case F_END:
  210. X        if (expptr) {
  211. X            popsi();
  212. X            continue;
  213. X        } else return(0);
  214. X
  215. X    case SPACE:
  216. X        break;
  217. X    case LETTER:
  218. X    case STARTER:
  219. X        p = tempbuf;
  220. X        do {
  221. X            if (p >= tempmax)
  222. X                error(symlong);
  223. X            *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  224. X            while    ((c = nextchar()) == '$')
  225. X                ;
  226. X        } while    (charclass[c]==LETTER || charclass[c]==DIGIT);
  227. X        if (p - tempbuf > MAXSYMBOLSIZE)
  228. X            p = tempbuf + MAXSYMBOLSIZE;
  229. X        *p++ = '\0';
  230. X        peekc = c;
  231. X        return(tokenofitem(UNDECLARED));
  232. X    case DIGIT:
  233. X        if (*ifptr) return(skipline(c));
  234. X        p = tempbuf;
  235. X        do    {
  236. X            if (p >= tempmax)
  237. X                error(symlong);
  238. X            *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  239. X            while    ((c = nextchar()) == '$');
  240. X            }
  241. X            while(numpart[c]);
  242. X        peekc = c;
  243. X        *p-- = '\0';
  244. X        switch(*p)    {
  245. X            case 'o':
  246. X            case 'q':
  247. X                radix = 8;
  248. X                limit = 020000;
  249. X                *p = '\0';
  250. X                break;
  251. X            case 'd':
  252. X                radix = 10;
  253. X                limit = 3276;
  254. X                *p = '\0';
  255. X                break;
  256. X            case 'h':
  257. X                radix = 16;
  258. X                limit = 010000;
  259. X                *p = '\0';
  260. X                break;
  261. X            case 'b':
  262. X                radix = 2;
  263. X                limit = 077777;
  264. X                *p = '\0';
  265. X                break;
  266. X            default:
  267. X                radix = 10;
  268. X                limit = 3276;
  269. X                p++;
  270. X                break;
  271. X            }
  272. X
  273. X        /*
  274. X         *  tempbuf now points to the number, null terminated
  275. X         *  with radix 'radix'.
  276. X         */
  277. X        yylval.ival = 0;
  278. X        p = tempbuf;
  279. X        do    {
  280. X            c = *p - (*p > '9' ? ('a' - 10) : '0');
  281. X            if (c >= radix)
  282. X                {
  283. X                err[iflag]++;
  284. X                yylval.ival = 0;
  285. X                break;
  286. X                }
  287. X            if (yylval.ival < limit ||
  288. X                (radix == 10 && yylval.ival == 3276 && c < 8) ||
  289. X                (radix == 2 && yylval.ival == limit))
  290. X                yylval.ival = yylval.ival * radix + c;
  291. X            else {
  292. X                err[vflag]++;
  293. X                yylval.ival = 0;
  294. X                break;
  295. X                }
  296. X            }
  297. X            while(*++p != '\0');
  298. X        return(NUMBER);
  299. X    default:
  300. X        if (*ifptr)
  301. X            return(skipline(c));
  302. X        switch(c) {
  303. X        case ';':
  304. X            return(skipline(c));
  305. X        case '\'':
  306. X            if (quoteflag) return('\'');
  307. X            p = tempbuf;
  308. X            p[1] = 0;
  309. X            do    switch(c = nextchar())    {
  310. X            case '\0':
  311. X            case '\n':
  312. X                err[bflag]++;
  313. X                goto retstring;
  314. X            case '\'':
  315. X                if ((c = nextchar()) != '\'') {
  316. X                retstring:
  317. X                    peekc = c;
  318. X                    *p = '\0';
  319. X                    if ((p-tempbuf) >2) {
  320. X                        yylval.cval = tempbuf;
  321. X                        return(STRING);
  322. X                    } else if (p-tempbuf == 2)    {
  323. X                        p = tempbuf;
  324. X                        yylval.ival = *p++ ;
  325. X                        yylval.ival |= *p<<8;
  326. X                        return(TWOCHAR);
  327. X                    } else    {
  328. X                        p = tempbuf;
  329. X                        yylval.ival = *p++;
  330. X                        return(ONECHAR);
  331. X                    }
  332. X                }
  333. X            default:
  334. X                *p++ = c;
  335. X            } while (p < tempmax);
  336. X            /*
  337. X             *  if we break out here, our string is longer than
  338. X             *  our input line
  339. X             */
  340. X            error("string buffer overflow");
  341. X        default:
  342. X            return(c);
  343. X        }
  344. X    }
  345. X}
  346. X
  347. X/*
  348. X *  return the token associated with the string pointed to by
  349. X *  tempbuf.  if no token is associated with the string, associate
  350. X *  deftoken with the string and return deftoken.
  351. X *  in either case, cause yylval to point to the relevant
  352. X *  symbol table entry.
  353. X */
  354. X
  355. Xtokenofitem(deftoken)
  356. Xint    deftoken;
  357. X{
  358. X    register  char *p;
  359. X    register struct item *    ip;
  360. X    register  i;
  361. X    int  r, l, u, hash;
  362. X
  363. X
  364. X#ifdef T_DEBUG
  365. X    fputs("'tokenofitem entry'    ", stderr) ;
  366. X    fputs(tempbuf, stderr) ;
  367. X#endif
  368. X    /*
  369. X     *  binary search
  370. X     */
  371. X    l = 0;
  372. X    u = (sizeof keytab/sizeof keytab[0])-1;
  373. X    while (l <= u) {
  374. X        i = (l+u)/2;
  375. X        ip = &keytab[i];
  376. X        if ((r = strcmp(tempbuf, ip->i_string)) == 0)
  377. X            goto found;
  378. X        if (r < 0)
  379. X            u = i-1;
  380. X        else
  381. X            l = i+1;
  382. X    }
  383. X
  384. X    /*
  385. X     *  hash into item table
  386. X     */
  387. X    hash = 0;
  388. X    p = tempbuf;
  389. X    while (*p) hash += *p++;
  390. X    hash %= ITEMTABLESIZE;
  391. X    ip = &itemtab[hash];
  392. X
  393. X    loop {
  394. X        if (ip->i_token == 0)
  395. X            break;
  396. X        if (strcmp(tempbuf, ip->i_string) == 0)
  397. X            goto found;
  398. X        if (++ip >= itemmax)
  399. X            ip = itemtab;
  400. X    }
  401. X
  402. X    if (!deftoken) {
  403. X        i = 0 ;
  404. X        goto token_done ;
  405. X    }
  406. X    if (++nitems > ITEMTABLESIZE-20)
  407. X        error("item table overflow");
  408. X    ip->i_string = malloc(strlen(tempbuf)+1);
  409. X    ip->i_token = deftoken;
  410. X    ip->i_uses = 0 ;
  411. X    strcpy(ip->i_string, tempbuf);
  412. X
  413. Xfound:
  414. X    if (*ifptr) {
  415. X        if (ip->i_token == ENDIF) {
  416. X            i = ENDIF ;
  417. X            goto token_done ;
  418. X        }
  419. X        if (ip->i_token == IF) {
  420. X            if (ifptr >= ifstmax)
  421. X                error("Too many ifs");
  422. X            else *++ifptr = 1;
  423. X        }
  424. X        i = skipline(' ');
  425. X        goto token_done ;
  426. X    }
  427. X    yylval.itemptr = ip;
  428. X    i = ip->i_token;
  429. Xtoken_done:
  430. X#ifdef T_DEBUG
  431. X    fputs("\t'tokenofitem exit'\n", stderr) ;
  432. X#endif
  433. X    return(i) ;
  434. X}
  435. X
  436. X
  437. X/*
  438. X *  interchange two entries in the item table -- used by qsort
  439. X */
  440. Xinterchange(i, j)
  441. X{
  442. X    register  struct item *fp, *tp;
  443. X    struct item temp;
  444. X
  445. X    fp = &itemtab[i];
  446. X    tp = &itemtab[j];
  447. X    temp.i_string = fp->i_string;
  448. X    temp.i_value = fp->i_value;
  449. X    temp.i_token = fp->i_token;
  450. X    temp.i_uses = fp->i_uses;
  451. X
  452. X    fp->i_string = tp->i_string;
  453. X    fp->i_value = tp->i_value;
  454. X    fp->i_token = tp->i_token;
  455. X    fp->i_uses = tp->i_uses;
  456. X
  457. X    tp->i_string = temp.i_string;
  458. X    tp->i_value = temp.i_value;
  459. X    tp->i_token = temp.i_token;
  460. X    tp->i_uses = temp.i_uses;
  461. X}
  462. X
  463. X
  464. X
  465. X/*
  466. X *  quick sort -- used by putsymtab to sort the symbol table
  467. X */
  468. Xqsort(m, n)
  469. X{
  470. X    register  i, j;
  471. X
  472. X    if (m < n) {
  473. X        i = m;
  474. X        j = n+1;
  475. X        loop {
  476. X            do i++; while(strcmp(itemtab[i].i_string,
  477. X                    itemtab[m].i_string) < 0);
  478. X            do j--; while(strcmp(itemtab[j].i_string,
  479. X                    itemtab[m].i_string) > 0);
  480. X            if (i < j) interchange(i, j); else break;
  481. X        }
  482. X        interchange(m, j);
  483. X        qsort(m, j-1);
  484. X        qsort(j+1, n);
  485. X    }
  486. X}
  487. X
  488. X
  489. X
  490. X/*
  491. X *  get the next character
  492. X */
  493. Xnextchar()
  494. X{
  495. X    register int c, ch;
  496. X    static  char  *earg;
  497. X    char *getlocal();
  498. X
  499. X    if (peekc != -1) {
  500. X        c = peekc;
  501. X        peekc = -1;
  502. X        return(c);
  503. X    }
  504. X
  505. Xstart:
  506. X    if (earg) {
  507. X        if (*earg)
  508. X            return(addtoline(*earg++));
  509. X        earg = 0;
  510. X    }
  511. X
  512. X    if (expptr) {
  513. X        if ((ch = getm()) == '\1') {    /*  expand argument  */
  514. X            ch = getm() - 'A';
  515. X            if (ch >= 0 && ch < PARMMAX && est[ch])
  516. X                earg = est[ch];
  517. X            goto start;
  518. X        }
  519. X        if (ch == '\2') {    /*  local symbol  */
  520. X            ch = getm() - 'A';
  521. X            if (ch >= 0 && ch < PARMMAX && est[ch]) {
  522. X                earg = est[ch];
  523. X                goto start;
  524. X            }
  525. X            earg = getlocal(ch, (int)est[TEMPNUM]);
  526. X            goto start;
  527. X        }
  528. X
  529. X        return(addtoline(ch));
  530. X    }
  531. X    ch = getc(now_file) ;
  532. X    /* if EOF, check for include file */
  533. X    if (ch == EOF) {
  534. X        while (ch == EOF && now_in) {
  535. X            fclose(fin[now_in]) ;
  536. X            free(src_name[now_in]) ;
  537. X            now_file = fin[--now_in] ;
  538. X            ch = getc(now_file) ;
  539. X        }
  540. X        if (linein[now_in] < 0) {
  541. X            lstoff = 1 ;
  542. X            linein[now_in] = -linein[now_in] ;
  543. X        } else {
  544. X            lstoff = 0 ;
  545. X        }
  546. X        if (pass2 && iflist()) {
  547. X            lineout() ;
  548. X            fprintf(fout, "**** %s ****\n", src_name[now_in]) ;
  549. X        }
  550. X    }
  551. X    if (ch == '\n')
  552. X        linein[now_in]++ ;
  553. X
  554. X    return(addtoline(ch)) ;
  555. X}
  556. X
  557. X
  558. X/*
  559. X *  skip to rest of the line -- comments and if skipped lines
  560. X */
  561. Xskipline(ac)
  562. X{
  563. X    register  c;
  564. X
  565. X    c = ac;
  566. X    while (c != '\n' && c != '\0')
  567. X        c = nextchar();
  568. X    return('\n');
  569. X}
  570. X
  571. X
  572. X
  573. Xmain(argc, argv)
  574. Xchar  **argv;
  575. X{
  576. X    register  struct item *ip;
  577. X    register  i;
  578. X    int  files;
  579. X#ifdef DBUG
  580. X    extern  yydebug;
  581. X#endif
  582. X
  583. X    fout = stdout ;
  584. X    fin[0] = stdin ;
  585. X    now_file = stdin ;
  586. X    files = 0;
  587. X
  588. X    for (i=1; i<argc; i++) {
  589. X        if (*argv[i] == '-') while (*++argv[i]) switch(*argv[i]) {
  590. X
  591. X        case 'b':    /*  no binary  */
  592. X            bopt = 0;
  593. X            continue;
  594. X
  595. X#ifdef DBUG
  596. X        case 'd':    /*  debug  */
  597. X            yydebug++;
  598. X            continue;
  599. X#endif
  600. X
  601. X        case 'e':    /*  error list only  */
  602. X            eopt = 0;
  603. X            edef = 0;
  604. X            continue;
  605. X
  606. X        case 'f':    /*  print if skipped lines  */
  607. X            fopt++;
  608. X            fdef++;
  609. X            continue;
  610. X
  611. X        case 'g':    /*  do not list extra code  */
  612. X            gopt = 0;
  613. X            gdef = 0;
  614. X            continue;
  615. X
  616. X        case 'i':    /* do not list include files */
  617. X            iopt = 1 ;
  618. X            continue ;
  619. X
  620. X        case 'l':    /*  no list  */
  621. X            lopt++;
  622. X            continue;
  623. X
  624. X        case 'L':    /*  force listing of everything */
  625. X            lston++;
  626. X            continue;
  627. X
  628. X        case 'm':    /*  print macro expansions  */
  629. X            mdef++;
  630. X            mopt++;
  631. X            continue;
  632. X
  633. X        case 'n':    /*  put line numbers off */
  634. X            nopt-- ;
  635. X            continue;
  636. X
  637. X        case 'o':    /*  list to standard output  */
  638. X            oopt++;
  639. X            continue;
  640. X
  641. X        case 'p':    /*  put out four \n's for eject */
  642. X            popt-- ;
  643. X            continue;
  644. X
  645. X        case 's':    /*  don't produce a symbol list  */
  646. X            sopt++;
  647. X            continue;
  648. X
  649. X        case 't':
  650. X            topt = 0;
  651. X            continue;
  652. X
  653. X        default:    /*  error  */
  654. X            error("Unknown option");
  655. X
  656. X        } else if (files++ == 0) {
  657. X            sourcef = argv[i];
  658. X            strcpy(src, sourcef);
  659. X            suffix(src,".z");
  660. X            if ((now_file = fopen(src, "r")) == NULL)
  661. X                error("Cannot open source file");
  662. X            now_in = 0 ;
  663. X            fin[now_in] = now_file ;
  664. X            src_name[now_in] = src ;
  665. X        } else if (files)
  666. X            error("Too many arguments");
  667. X    }
  668. X
  669. X
  670. X    if (files == 0)
  671. X        error("No source file");
  672. X    strcpy(bin, sourcef);
  673. X    suffix(bin,".hex");
  674. X    if (bopt)
  675. X#ifdef MSDOS
  676. X        if (( fbuf = fopen(bin, "wb")) == NULL)
  677. X#else
  678. X        if (( fbuf = fopen(bin, "w")) == NULL)
  679. X#endif
  680. X            error("Cannot create binary file");
  681. X    if (!lopt && !oopt) {
  682. X        strcpy(listf, sourcef);
  683. X        suffix(listf,".lst");
  684. X        if ((fout = fopen(listf, "w")) == NULL)
  685. X            error("Cannot create list file");
  686. X    } else
  687. X        fout = stdout ;
  688. X    strcpy(mtmp, sourcef);
  689. X    suffix(mtmp,".tmp");
  690. X#ifdef MSDOS
  691. X    mfile = mfopen(mtmp,"w+b") ;
  692. X#else
  693. X    mfile = mfopen(mtmp,"w+") ;
  694. X#endif
  695. X    if (mfile == NULL) {
  696. X        error("Cannot create temp file");
  697. X    }
  698. X    /*unlink(mtmp);*/
  699. X
  700. X    /*
  701. X     *  get the time
  702. X     */
  703. X    time(&now);
  704. X    timp = ctime(&now);
  705. X    timp[16] = 0;
  706. X    timp[24] = 0;
  707. X
  708. X    title = sourcef;
  709. X    /*
  710. X     * pass 1
  711. X     */
  712. X#ifdef DEBUG
  713. X    fputs("DEBUG-pass 1\n", stderr) ;
  714. X#endif
  715. X    setvars();
  716. X    yyparse();
  717. X    pass2++;
  718. X    ip = &itemtab[-1];
  719. X    while (++ip < itemmax) {
  720. X        /* reset use count */
  721. X        ip->i_uses = 0 ;
  722. X
  723. X        /* set macro names, equated and defined names */
  724. X        switch    (ip->i_token) {
  725. X        case MNAME:
  726. X            ip->i_token = OLDMNAME;
  727. X            break;
  728. X
  729. X        case EQUATED:
  730. X            ip->i_token = WASEQUATED;
  731. X            break;
  732. X
  733. X        case DEFLED:
  734. X            ip->i_token = UNDECLARED;
  735. X            break;
  736. X        }
  737. X    }
  738. X    setvars();
  739. X    fseek(now_file, (long)0, 0);
  740. X
  741. X#ifdef DEBUG
  742. X    fputs("DEBUG- pass 2\n", stderr) ;
  743. X#endif
  744. X    yyparse();
  745. X
  746. X
  747. X    if (bopt) {
  748. X        flushbin();
  749. X        putc(':', fbuf);
  750. X        if (xeq_flag) {
  751. X            puthex(0, fbuf);
  752. X            puthex(xeq >> 8, fbuf);
  753. X            puthex(xeq, fbuf);
  754. X            puthex(1, fbuf);
  755. X            puthex(255-(xeq >> 8)-xeq, fbuf);
  756. X        } else
  757. X            for    (i = 0; i < 10; i++)
  758. X                putc('0', fbuf);
  759. X        putc('\n', fbuf);
  760. X        fflush(fbuf);
  761. X    }
  762. X
  763. X    if (!lopt)
  764. X        fflush(fout);
  765. X    if (writesyms)
  766. X        outsymtab(writesyms);
  767. X    if (eopt)
  768. X        erreport();
  769. X    if (!lopt && !sopt)
  770. X        putsymtab();
  771. X    if (!lopt) {
  772. X        eject();
  773. X        fflush(fout);
  774. X    }
  775. X    exit(0);
  776. X}
  777. X
  778. X
  779. X/*
  780. X *  set some data values before each pass
  781. X */
  782. Xsetvars()
  783. X{
  784. X    register  i;
  785. X
  786. X    peekc = -1;
  787. X    linein[now_in] = linecnt = 0;
  788. X    exp_number = 0;
  789. X    emitptr = emitbuf;
  790. X    lineptr = linebuf;
  791. X    ifptr = ifstack;
  792. X    expifp = expif;
  793. X    *ifptr = 0;
  794. X    dollarsign = 0;
  795. X    olddollar = 0;
  796. X    phaseflag = 0;
  797. X    for (i=0; i<FLAGS; i++) err[i] = 0;
  798. X}
  799. X
  800. X
  801. X
  802. X/*
  803. X *  print out an error message and die
  804. X */
  805. Xerror(as)
  806. Xchar *as;
  807. X{
  808. X
  809. X    *linemax = 0;
  810. X    fprintf(fout, "%s\n", linebuf);
  811. X    fflush(fout);
  812. X    fprintf(stderr, "%s\n", as) ;
  813. X    exit(1);
  814. X}
  815. X
  816. X
  817. X
  818. X/*
  819. X *  output the symbol table
  820. X */
  821. Xputsymtab()
  822. X{
  823. X    register  struct item *tp, *fp;
  824. X    int  i, j, k, t, rows;
  825. X    char c, c1 ;
  826. X
  827. X    if (!nitems)
  828. X        return;
  829. X
  830. X    /* compact the table so unused and UNDECLARED entries are removed */
  831. X    tp = &itemtab[-1];
  832. X    for (fp = itemtab; fp<itemmax; fp++) {
  833. X        if (fp->i_token == UNDECLARED) {
  834. X            nitems--;
  835. X            continue;
  836. X        }
  837. X        if (fp->i_token == 0)
  838. X            continue;
  839. X        tp++;
  840. X        if (tp != fp) {
  841. X            tp->i_string = fp->i_string;
  842. X            tp->i_value = fp->i_value;
  843. X            tp->i_token = fp->i_token;
  844. X            tp->i_uses = fp->i_uses ;
  845. X        }
  846. X    }
  847. X
  848. X    tp++;
  849. X    tp->i_string = "{";
  850. X
  851. X    /*  sort the table */
  852. X    qsort(0, nitems-1);
  853. X
  854. X    title = "**  Symbol Table  **";
  855. X
  856. X    rows = (nitems+3) / 4;
  857. X    if (rows+5+line > 60)
  858. X        eject();
  859. X    lineout();
  860. X    fprintf(fout,"\n\n\nSymbol Table:\n\n") ;
  861. X    line += 4;
  862. X
  863. X    for (i=0; i<rows; i++) {
  864. X        for(j=0; j<4; j++) {
  865. X            k = rows*j+i;
  866. X            if (k < nitems) {
  867. X                tp = &itemtab[k];
  868. X                t = tp->i_token;
  869. X                c = ' ' ;
  870. X                if (t == EQUATED || t == DEFLED)
  871. X                    c = '=' ;
  872. X                if (tp->i_uses == 0)
  873. X                    c1 = '+' ;
  874. X                else
  875. X                    c1 = ' ' ;
  876. X                fprintf(fout, "%-15s%c%4x%c    ",
  877. X                    tp->i_string, c, tp->i_value & 0xffff, c1);
  878. X            }
  879. X        }
  880. X        lineout();
  881. X        putc('\n', fout);
  882. X    }
  883. X}
  884. X
  885. X
  886. X
  887. X
  888. X/*
  889. X *  put out error report
  890. X */
  891. Xerreport()
  892. X{
  893. X    register i, numerr;
  894. X
  895. X    if (line > 50) eject();
  896. X    lineout();
  897. X    numerr = 0;
  898. X    for (i=0; i<FLAGS; i++) numerr += keeperr[i];
  899. X    if (numerr) {
  900. X        fputs("\n\n\nError report:\n\n", fout);
  901. X        fprintf(fout, "%6d errors\n", numerr);
  902. X        line += 5;
  903. X    } else {
  904. X        fputs("\n\n\nStatistics:\n", fout);
  905. X        line += 3;
  906. X    }
  907. X
  908. X    for (i=0; i<FLAGS; i++)
  909. X        if (keeperr[i]) {
  910. X            lineout();
  911. X            fprintf(fout, "%6d %c -- %s error\n",
  912. X                keeperr[i], errlet[i], errname[i]);
  913. X        }
  914. X
  915. X    if (line > 55) eject();
  916. X    lineout();
  917. X    fprintf(fout, "\n%6d\tsymbols\n", nitems);
  918. X    fprintf(fout, "%6d\tbytes\n", nbytes);
  919. X    line += 2;
  920. X    if (mfptr) {
  921. X        if (line > 53) eject();
  922. X        lineout();
  923. X        fprintf(fout, "\n%6d\tmacro calls\n", exp_number);
  924. X        fprintf(fout, "%6d\tmacro bytes\n", mfptr);
  925. X        fprintf(fout, "%6d\tinvented symbols\n", invented/2);
  926. X        line += 3;
  927. X    }
  928. X}
  929. X
  930. X
  931. X/*
  932. X *  lexical analyser for macro definition
  933. X */
  934. Xmlex()
  935. X{
  936. X    register  char  *p;
  937. X    register  c;
  938. X    int  t;
  939. X
  940. X    /*
  941. X     *  move text onto macro file, changing formal parameters
  942. X     */
  943. X#ifdef    M_DEBUG
  944. X    fprintf(stderr,"enter 'mlex'\t") ;
  945. X#endif
  946. X    inmlex++;
  947. X
  948. X    c = nextchar();
  949. Xloop {
  950. X    switch(charclass[c]) {
  951. X
  952. X    case DIGIT:
  953. X        while (numpart[c]) {
  954. X            putm(c);
  955. X            c = nextchar();
  956. X        }
  957. X        continue;
  958. X
  959. X    case STARTER:
  960. X    case LETTER:
  961. X        t = 0;
  962. X        p = tempbuf+MAXSYMBOLSIZE+2;
  963. X        do {
  964. X            if (p >= tempmax)
  965. X                error(symlong);
  966. X            *p++ = c;
  967. X            if (t < MAXSYMBOLSIZE)
  968. X                tempbuf[t++] = (c >= 'A' && c <= 'Z')  ?
  969. X                    c+'a'-'A' : c;
  970. X            c = nextchar();
  971. X        } while (charclass[c]==LETTER || charclass[c]==DIGIT);
  972. X
  973. X        tempbuf[t] = 0;
  974. X        *p++ = '\0';
  975. X        p = tempbuf+MAXSYMBOLSIZE+2;
  976. X        t = tokenofitem(0);
  977. X        if (t != MPARM) while (*p) putm(*p++);
  978. X        else {
  979. X            if (*(yylval.itemptr->i_string) == '?') putm('\2');
  980. X            else putm('\1');
  981. X            putm(yylval.itemptr->i_value + 'A');
  982. X        }
  983. X        if (t == ENDM) goto done;
  984. X        continue;
  985. X
  986. X    case F_END:
  987. X        if (expptr) {
  988. X            popsi();
  989. X            c = nextchar();
  990. X            continue;
  991. X        }
  992. X
  993. X        goto done;
  994. X
  995. X    default:
  996. X        if (c == '\n') {
  997. X            linecnt++;
  998. X        }
  999. X        if (c != '\1') putm(c);
  1000. X        c = nextchar();
  1001. X    }
  1002. X}
  1003. X
  1004. X    /*
  1005. X     *  finish off the file entry
  1006. X     */
  1007. Xdone:
  1008. X    while(c != EOF && c != '\n' && c != '\0') c = nextchar();
  1009. X    linecnt++;
  1010. X    putm('\n');
  1011. X    putm('\n');
  1012. X    putm(0);
  1013. X
  1014. X    for (c=0; c<ITEMTABLESIZE; c++)
  1015. X        if (itemtab[c].i_token == MPARM) {
  1016. X            itemtab[c].i_token = UNDECLARED;
  1017. X        }
  1018. X    inmlex = 0;
  1019. X#ifdef    M_DEBUG
  1020. X    fprintf(stderr,"exit 'mlex'\n") ;
  1021. X#endif
  1022. X}
  1023. X
  1024. X
  1025. X
  1026. X/*
  1027. X *  lexical analyser for the arguments of a macro call
  1028. X */
  1029. Xgetarg()
  1030. X{
  1031. X    register int c;
  1032. X    register char *p;
  1033. X    static int comma;
  1034. X
  1035. X    *tempbuf = 0;
  1036. X    yylval.cval = tempbuf;
  1037. X    while(charclass[c = nextchar()] == SPACE);
  1038. X
  1039. X    switch(c) {
  1040. X
  1041. X    case '\0':
  1042. X        popsi();
  1043. X    case '\n':
  1044. X    case ';':
  1045. X        comma = 0;
  1046. X        return(skipline(c));
  1047. X
  1048. X    case ',':
  1049. X        if (comma) {
  1050. X            comma = 0;
  1051. X            return(',');
  1052. X        }
  1053. X        else {
  1054. X            comma++;
  1055. X            return(ARG);
  1056. X        }
  1057. X
  1058. X    case '\'':
  1059. X        p = tempbuf;
  1060. X        do switch (c = nextchar()) {
  1061. X            case '\0':
  1062. X            case '\n':
  1063. X                peekc = c;
  1064. X                *p = 0;
  1065. X                err[bflag]++;
  1066. X                return(ARG);
  1067. X            case '\'':
  1068. X                if ((c = nextchar()) != '\'') {
  1069. X                    peekc = c;
  1070. X                    *p = '\0';
  1071. X                    comma++;
  1072. X                    return(ARG);
  1073. X                }
  1074. X            default:
  1075. X                *p++ = c;
  1076. X        } while (p < tempmax);
  1077. X        error(symlong);
  1078. X
  1079. X    default:  /* unquoted string */
  1080. X        p = tempbuf;
  1081. X        peekc = c;
  1082. X        do switch(c = nextchar()) {
  1083. X            case '\0':
  1084. X            case '\n':
  1085. X            case '\t':
  1086. X            case ' ':
  1087. X            case ',':
  1088. X                peekc = c;
  1089. X                *p = '\0';
  1090. X                comma++;
  1091. X                return(ARG);
  1092. X            default:
  1093. X                *p++ = c;
  1094. X        } while (p < tempmax);
  1095. X    }
  1096. X}
  1097. X
  1098. X
  1099. X
  1100. X
  1101. X
  1102. X/*
  1103. X *  add a suffix to a string
  1104. X */
  1105. Xsuffix(str,suff)
  1106. Xchar *str,*suff;
  1107. X{
  1108. X    while(*str != '\0' && *str != '.')
  1109. X        *str++;
  1110. X    strcpy(str, suff);
  1111. X}
  1112. X
  1113. X
  1114. X
  1115. X
  1116. X/*
  1117. X *  put out a byte to the macro file, keeping the offset
  1118. X */
  1119. Xputm(c)
  1120. Xchar c ;
  1121. X{
  1122. X    mfptr++;
  1123. X    mfputc(c,mfile) ;
  1124. X}
  1125. X
  1126. X
  1127. X
  1128. X/*
  1129. X *  get a byte from the macro file
  1130. X */
  1131. Xgetm()
  1132. X{
  1133. X    int ch;
  1134. X
  1135. X    floc++;
  1136. X    ch = mfgetc(mfile) ;
  1137. X    if (ch == EOF) {
  1138. X        ch = 0;
  1139. X        fprintf(stderr,"bad macro read\n") ;
  1140. X    }
  1141. X    return(ch);
  1142. X}
  1143. X
  1144. X
  1145. X
  1146. X/*
  1147. X *  pop standard input
  1148. X */
  1149. Xpopsi()
  1150. X{
  1151. X    register  i;
  1152. X
  1153. X    for (i=0; i<PARMMAX; i++) {
  1154. X        if (est[i]) free(est[i]);
  1155. X    }
  1156. X    floc = est[FLOC];
  1157. X    free(est);
  1158. X    expptr--;
  1159. X    est = expptr ? (char **) expstack[expptr-1] : (char **) 0;
  1160. X    mfseek(mfile, (long)floc, 0);
  1161. X    if (lineptr > linebuf) lineptr--;
  1162. X}
  1163. X
  1164. X
  1165. X
  1166. X/*
  1167. X *  return a unique name for a local symbol
  1168. X *  c is the parameter number, n is the macro number.
  1169. X */
  1170. X
  1171. Xchar *
  1172. Xgetlocal(c, n)
  1173. Xint c,n;
  1174. X{
  1175. Xstatic char local_label[10];
  1176. X    invented++;
  1177. X    if (c >= 26)
  1178. X        c += 'a' - '0';
  1179. X    sprintf(local_label, "?%c%04d", c+'a', n) ;
  1180. X    return(local_label);
  1181. X}
  1182. X
  1183. X
  1184. X
  1185. X/*
  1186. X *  read in a symbol table
  1187. X */
  1188. Xinsymtab(name)
  1189. Xchar *name;
  1190. X{
  1191. X    register struct stab *t;
  1192. X    int  s, i, sfile;
  1193. X
  1194. X    t = (struct stab *) tempbuf;
  1195. X#ifdef MSDOS
  1196. X    if ((sfile = open(name, O_RDONLY | O_BINARY)) < 0)
  1197. X#else
  1198. X    if ((sfile = open(name, O_RDONLY)) < 0)
  1199. X#endif
  1200. X        return;
  1201. X    read(sfile, (char *)t, sizeof *t);
  1202. X    if (t->t_value != SYMMAJIC)
  1203. X        return;
  1204. X
  1205. X    s = t->t_token;
  1206. X    for (i=0; i<s; i++) {
  1207. X        read(sfile, (char *)t, sizeof *t);
  1208. X        if (tokenofitem(UNDECLARED) != UNDECLARED)
  1209. X            continue;
  1210. X        yylval.itemptr->i_token = t->t_token;
  1211. X        yylval.itemptr->i_value = t->t_value;
  1212. X        if (t->t_token == MACRO)
  1213. X            yylval.itemptr->i_value += mfptr;
  1214. X    }
  1215. X
  1216. X    while ((s = read(sfile, tempbuf, TEMPBUFSIZE)) > 0) {
  1217. X        mfptr += s;
  1218. X        mfwrite(tempbuf, 1, s, mfile) ;
  1219. X    }
  1220. X}
  1221. X
  1222. X
  1223. X
  1224. X/*
  1225. X *  write out symbol table
  1226. X */
  1227. Xoutsymtab(name)
  1228. Xchar *name;
  1229. X{
  1230. X    register struct stab *t;
  1231. X    register struct item *ip;
  1232. X    int  i, sfile;
  1233. X
  1234. X    t = (struct stab *) tempbuf;
  1235. X    if ((sfile = creat(name, 0644)) < 0)
  1236. X        return;
  1237. X    for (ip=itemtab; ip<itemmax; ip++) {
  1238. X        if (ip->i_token == UNDECLARED) {
  1239. X            ip->i_token = 0;
  1240. X            nitems--;
  1241. X        }
  1242. X    }
  1243. X
  1244. X    copyname(title, (char *)t);
  1245. X    t->t_value = SYMMAJIC;
  1246. X    t->t_token = nitems;
  1247. X    write(sfile, (char *)t, sizeof *t);
  1248. X
  1249. X    for (ip=itemtab; ip<itemmax; ip++) {
  1250. X        if (ip->i_token != 0) {
  1251. X            t->t_token = ip->i_token;
  1252. X            t->t_value = ip->i_value;
  1253. X            copyname(ip->i_string, (char *)t);
  1254. X            write(sfile, (char *)t, sizeof *t);
  1255. X        }
  1256. X    }
  1257. X
  1258. X    mfseek(mfile, (long)0, 0);
  1259. X    while((i = mfread(tempbuf, 1, TEMPBUFSIZE, mfile) ) > 0)
  1260. X        write(sfile, tempbuf, i);
  1261. X}
  1262. X
  1263. X
  1264. X
  1265. X/*
  1266. X *  copy a name into the symbol file
  1267. X */
  1268. Xcopyname(st1, st2)
  1269. Xchar *st1, *st2;
  1270. X{
  1271. X    register  char  *s1, *s2;
  1272. X    register  i;
  1273. X
  1274. X    i = (MAXSYMBOLSIZE+2) & ~01;
  1275. X    s1 = st1;
  1276. X    s2 = st2;
  1277. X
  1278. X    while(*s2++ = *s1++) i--;
  1279. X    while(--i > 0) *s2++ = '\0';
  1280. X}
  1281. X
  1282. X/* get the next source file */
  1283. Xnext_source(sp)
  1284. Xchar *sp ;
  1285. X{
  1286. X
  1287. X    if(now_in == NEST_IN -1)
  1288. X        error("Too many nested includes") ;
  1289. X    if ((now_file = fopen(sp, "r")) == NULL) {
  1290. X        char ebuf[100] ;
  1291. X        sprintf(ebuf,"Can't open include file: %s", sp) ;
  1292. X        error(ebuf) ;
  1293. X    }
  1294. X    if (pass2 && iflist()) {
  1295. X        lineout() ;
  1296. X        fprintf(fout, "**** %s ****\n",sp) ;
  1297. X    }
  1298. X
  1299. X    /* save the list control flag with the current line number */
  1300. X    if (lstoff)
  1301. X        linein[now_in] = - linein[now_in] ;
  1302. X
  1303. X    /* no list if include files are turned off */
  1304. X    lstoff |= iopt ;
  1305. X
  1306. X    /* save the new file descriptor. */
  1307. X    fin[++now_in] = now_file ;
  1308. X    /* start with line 0 */
  1309. X    linein[now_in] = 0 ;
  1310. X    /* save away the file name */
  1311. X    src_name[now_in] = malloc(strlen(sp)+1) ;
  1312. X    strcpy(src_name[now_in],sp) ;
  1313. X}
  1314. SHAR_EOF
  1315. chmod 0755 zmac/zmac.y
  1316. rm -f ._seq_
  1317. echo "You have unpacked the last part"
  1318. exit 0
  1319. -- 
  1320. "If I'd known it was harmless, I'd have killed it myself"  Phillip K. Dick
  1321. Bob Bownes, aka iii, aka captain comrade doktor bobwrench
  1322. 3 A Pinehurst Ave,    Albany, New York, 12203, (518)-482-8798 voice 
  1323.  bownesrm@beowulf.uucp {uunet!steinmetz,rutgers!brspyr1}!beowulf!bownesrm
  1324.