home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 148_01 / a99get.c < prev    next >
Text File  |  1987-09-28  |  9KB  |  366 lines

  1. /*
  2.     TMS9900/99105  Cross-Assembler  v. 1.0
  3.  
  4.     January, 1985
  5.  
  6.     Original 6800 version Copyright (c) 1980 William C. Colley, III.
  7.     Modified for the TMS9900/99105  Series by Alexander Cameron.
  8.  
  9. File:    a99get.c
  10.  
  11. Routines to get source text from the disk and return it in
  12. manageable chunks such as operators, labels, opcodes, etc.
  13. */
  14.  
  15. /*  Get Globals:  */
  16.  
  17. #include "a99.gbl"
  18.  
  19. /*
  20. Function to get an opcode from the present source line and return
  21. its value and attributes.  The function returns -1 if no opcode was
  22. on the line, 0 if the opcode was not in the opcode table, and 1
  23. otherwise.  If the opcode was on the line, but not in the table, the
  24. error is marked up.
  25. */
  26.  
  27. getopcod(value,attrib)
  28. char *attrib;
  29. unsigned *value;
  30. {
  31.     char dxop[2*SYMLEN],temp[SYMLEN+1], getopc();
  32.     switch (getchr(value,SKIP))
  33.     {
  34.         case ALPHA:    backchr;
  35.                 getname(temp);
  36.                 if (bsearch(temp,value,attrib,0,numopcs(),getopc)) return 1;
  37.                 else
  38.                 {    
  39.                     strcpy(dxop,temp);
  40.                     strcat(dxop,PADDING);
  41.                     if(slookup(dxop))
  42.                     {
  43.                         markerr('O');
  44.                         return 0;
  45.                     }
  46.                     *value = sympoint -> symvalu; /* DXOP's value */
  47.                     *attrib = 0x01;    /* uses format 1 */
  48.                     return 1;
  49.                 }
  50.  
  51.         default:    markerr('S');
  52.                 return -1;
  53.  
  54.         case END_LIN:    return 0;
  55.  
  56.  
  57.     }
  58. }
  59.  
  60. /*
  61. Function to look up an item in a fixed table by binary search.  The function
  62. returns 1 if the item was found, 0 if not.  name points to the name to be
  63. looked up (null terminated).  value and attrib catch two bytes of parameters
  64. attached to the item if the item is found.  high and low are for the benefit of
  65. the recursion.  For the first call use the number of items in the table for
  66. high and 0 for low.  table is a pointer to a function to get an item from the
  67. appropriate table.  Note that in the comparison, lower case is converted to
  68. upper case.
  69. */
  70.  
  71. bsearch(name,value,attrib,low,high,table)
  72. char *name, *attrib, (*table)();
  73. int low, high;
  74. unsigned *value;
  75. {
  76.     char temp[5], *pntr1, *pntr2;
  77.     int t, check;
  78.     if (low > high) return 0;
  79.     check = low + (high - low >> 1);
  80.     (*table)(check,temp,value,attrib);
  81.     pntr1 = temp;
  82.     pntr2 = name;
  83.     while ((t = toupper(*pntr2++) - *pntr1) == 0 && *pntr1++ != '\0');
  84.     if (t == 0) return 1;
  85.     if (t > 0) return bsearch(name,value,attrib,check+1,high,table);
  86.     return bsearch(name,value,attrib,low,check-1,table);
  87. }
  88.  
  89. /*
  90. Function to push back an item so that getitem will retrieve it
  91. a second time.  Only one level of pushback is supported.
  92. */
  93.  
  94. backitem(value,attrib)
  95. unsigned value, attrib;
  96. {
  97.     oldvalu = value;
  98.     oldattr = attrib;
  99.     backflg = TRUE;
  100. }
  101.  
  102. /*
  103. Function to get an item from the present source line.  Items may be
  104. looked-up symbols, numeric constants, string constants, operators, etc.
  105. The function returns the attribute of the item gotten.  value is a
  106. pointer to where the value of the item will be stored, and quoteflg
  107. determines whether getitem will look for one- and two-character string
  108. constants or not.
  109. */
  110.  
  111. getitem(value,quoteflg)
  112. unsigned *value;
  113. char quoteflg;
  114. {
  115.     char c, c1, attrib, *tmpptr, temp[2*SYMLEN];
  116.     unsigned base, u;
  117.     if (backflg)
  118.     {
  119.         backflg = FALSE;
  120.         *value = oldvalu;
  121.         return oldattr;
  122.     }
  123.     switch ((attrib = getchr(&c,SKIP)))
  124.     {
  125.         case END_LIN:
  126.         case COMMA:    return attrib;
  127.  
  128.         case NUMERIC:    backchr;
  129.                 getnum(value,&base);
  130.                 return VALUE;
  131.  
  132.         case BAS_DES:    switch (c)
  133.                 {
  134.                     case '#':    base = 16;
  135.                             break;
  136.  
  137.                     case '%':    base = 2;
  138.                 }
  139.                 *value = 0;
  140.                 while ((attrib = getchr(&c,NOSKIP)) == NUMERIC || attrib == ALPHA)
  141.                 {
  142.                     *value = *value * base + _aton(toupper(c),base);
  143.                 }
  144.                 backchr;
  145.                 return VALUE;
  146.  
  147.         case OPERATR:    switch (c)
  148.                 {
  149.                     case '>':
  150.                     case '=':
  151.                     case '<':    getchr(&c1,NOSKIP);
  152.                             if (c == '>' && c1 == '=') c = GRTEQ;
  153.                             else if (c == '>' && c1 == '<') c = NOTEQ;
  154.                             else if (c == '=' && c1 == '>') c = GRTEQ;
  155.                             else if (c == '=' && c1 == '<') c = LESEQ;
  156.                             else if (c == '<' && c1 == '>') c = GRTEQ;
  157.                             else if (c == '<' && c1 == '=') c = LESEQ;
  158.                             else backchr;
  159.  
  160.                     default:    *value = c;
  161.                             return attrib;
  162.                 }
  163.  
  164.         case QUOTE:    if (quoteflg)
  165.                 {
  166.                     *value = c;
  167.                     return attrib;
  168.                 }
  169.                 tmpptr = temp;
  170.                 attrib = 0;
  171.                 while ((getchr(&c1,NOSKIP),c1) != '\n' &&  c1 != c)
  172.                     if (++attrib <= 2) *tmpptr++ = c1;
  173.                 if (c1 == '\n' || attrib > 2)
  174.                 {
  175.                     if (c1 == '\n') backchr;
  176.                     evalerr = TRUE;
  177.                     markerr('"');
  178.                     return VALUE;
  179.                 }
  180.                 tmpptr = temp;
  181.                 for (*value = 0; attrib != 0; attrib--) *value = (*value << 8) + *tmpptr++;
  182.                 return VALUE;
  183.  
  184.         case ALPHA:    backchr;
  185.                 getname(temp);
  186.                 if ((*value = chkoprat(temp) & 0xff) != NO_OPR) return OPERATR;
  187.                 strcat(temp,PADDING);
  188.                 if (slookup(temp) == 0)
  189.                 {
  190.                     *value = sympoint -> symvalu;
  191.                     if (sympoint -> symname[0] > 0x7f) directok = FALSE;
  192.                 }
  193.                 else
  194.                 {
  195.                     evalerr = TRUE;
  196.                     markerr('U');
  197.                 }
  198.                 return VALUE;
  199.     }
  200. }
  201.  
  202. /*
  203. Function to get a symbol name, opcode, or label from the present source
  204. line.  The name is returned (null terminated) in buffer.  Names are
  205. terminated by any non-alphanumeric character.
  206. */
  207.  
  208. getname(buffer)
  209. char *buffer;
  210. {
  211.     char c, d, count;
  212.     count = 0;
  213.     while ((c = getchr(&d,NOSKIP)) == ALPHA || c == NUMERIC)
  214.         if (++count <= SYMLEN) *buffer++ = d;
  215.     backchr;
  216.     *buffer = '\0';
  217. }
  218.  
  219. /*
  220. Function to check a string against the list of operators that get spelled out.
  221. This list consists of GE, GT, LE, LT, EQ, NE, AND, OR, XOR, NOT, MOD, SHL,
  222. SHR, HIGH, LOW.  The function returns the token for the operator if the
  223. string is an operator, the token NO_OPR otherwise.
  224. */
  225.  
  226. chkoprat(string)
  227. char *string;
  228. {
  229.     char t, getopr();
  230.     unsigned s;
  231.     return (bsearch(string,&s,&t,0,numoprs(),getopr)) ? t : NO_OPR;
  232. }
  233.  
  234. /*
  235. Function to get an Intel format number from the present input line.
  236. value points to the number to be returned, and base points to an
  237. unsigned where the base of the number will be saved during internal
  238. computations.  The function returns a fixed value of 1 and flags errors
  239. as it goes along.
  240. */
  241.  
  242. getnum(number,base)
  243. unsigned *number, *base;
  244. {
  245.     char c1, c2;
  246.     unsigned b;
  247.     if ((c1 = getchr(&c2,NOSKIP)) != ALPHA && c1 != NUMERIC)
  248.     {
  249.         backchr;
  250.         return 0xffff;
  251.     }
  252.     if ((b = getnum(number,base)) == 0xffff)
  253.     {
  254.         *number = 0;
  255.         switch (toupper(c2))
  256.         {
  257.             case 'H':    *base = 16;    return 1;
  258.             case 'D':    *base = 10;    return 1;
  259.             case 'O':
  260.             case 'Q':    *base = 8;    return 1;
  261.             case 'B':    *base = 2;    return 1;
  262.             default:    *base = 10;    b = 1;
  263.         }
  264.     }
  265.     *number += b * _aton(toupper(c2),*base);
  266.     return b * *base;
  267. }
  268.  
  269. /*
  270. Internal function in getnum to convert a character to a digit.  The base
  271. is passed so that this routine can check for digits larger than the base.
  272. */
  273.  
  274. _aton(letter,base)
  275. char letter;
  276. unsigned base;
  277. {
  278.     unsigned n;
  279.     if (letter >= '0' && letter <= '9') n = letter - '0';
  280.     else if (letter >= 'A' && letter <= 'F') n = letter - ('A' - 10);
  281.     else
  282.     {
  283.         markerr('E');
  284.         evalerr = TRUE;
  285.         return 0;
  286.     }
  287.     if (n < base) return n;
  288.     markerr('D');
  289.     evalerr = TRUE;
  290.     return 0;
  291. }
  292.  
  293. /*
  294. Function to get a character from the present source line.  The function
  295. returns the attribute of the character fetched.  value is a pointer to
  296. the location where the character itself will be saved, and skipflg
  297. determines whether or not white space is skipped.
  298. */
  299.  
  300. getchr(value,skipflg)
  301. char *value, skipflg;
  302. {
  303.     char c;
  304.     while (TRUE) if ((c = getattr(*value = *linptr++)) != TRASH &&
  305.             (c != BLANK || skipflg != SKIP)) return c;
  306. }
  307.  
  308. /*
  309. Function to get a new line of source text from the disk.  Returns 0
  310. if EOF encountered, 1 otherwise.
  311. */
  312.  
  313. getlin()
  314. {
  315.     char count, c;
  316.     linptr = linbuf;
  317.     count = 0;
  318.     backflg = FALSE;
  319.     while (movchr(&c))
  320.     {
  321.         if (c == '\n')
  322.         {
  323.             *linptr = '\0';
  324.             *--linptr = c;
  325.             linptr = linbuf;
  326.             return 1;
  327.         }
  328.         if (count < LINLEN) *linptr++ = c;
  329.         count++;
  330.     }
  331.     return 0;
  332. }
  333.  
  334. /*
  335. Function to move a character from the source disk buffer to the
  336. location dest.  Returns 0 if no character available, 1 otherwise.
  337. */
  338.  
  339. movchr(dest)
  340. char *dest;
  341. {
  342.     int t;
  343.     if (sorbuf.pointr >= sorbuf.space + (NSECT * 128))
  344.     {
  345.         sorbuf.pointr =sorbuf.space;
  346.         if ((t = read(sorbuf.fd,sorbuf.space,NSECT)) == -1)
  347.         {
  348.             printf("\nDisk read error. ++ %s\n",errmsg(errno()));
  349.             wipeout("\n");
  350.         }
  351.         if (t != NSECT) sorbuf.space[t * 128] = CPMEOF;
  352.     }
  353.     return((*dest = *sorbuf.pointr++ & 0x7f) == CPMEOF) ? 0 : 1;
  354. }
  355.  
  356. /*
  357. Function to rewind the source file.
  358. */
  359.  
  360. rewind()
  361. {
  362.     seek(sorbuf.fd,0,0);
  363.     sorbuf.pointr = sorbuf.space + (NSECT * 128);
  364. }
  365.  
  366.