home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / as32 / as31.y < prev    next >
Text File  |  1991-01-27  |  22KB  |  1,143 lines

  1. /* ----------------------------------------------------------------------
  2.  * FILE: as31.y
  3.  * PACKAGE: as31 - 8031/8051 Assembler.
  4.  *
  5.  * DESCRIPTION:
  6.  *    This file contains the yacc parser for the assembler.
  7.  *    Related to this are the following:
  8.  *        error(), warning(), yyerror()
  9.  *        genbyte(), genword(), genstr(), makeop()
  10.  *
  11.  *
  12.  * REVISION HISTORY:
  13.  *    Jan. 19, 1990 - Created. (Ken Stauffer)
  14.  *
  15.  * AUTHOR:
  16.  *    All code in this file written by Ken Stauffer (University of Calgary).
  17.  *    January 1990.
  18.  *
  19.  */
  20.  
  21. %{
  22.  
  23. #include <setjmp.h>
  24. #include <stdio.h>
  25. #define NOPE
  26. #include "as31.h"
  27. #undef NOPE
  28.  
  29. #define YYSTYPE union ystack
  30.  
  31. extern int lineno;
  32. extern int dashl;
  33. extern char *asmfile;
  34. extern jmp_buf main_env;
  35. extern FILE *listing;
  36.  
  37. int pass,fatal;
  38. unsigned long lc;
  39.  
  40. static unsigned char bytebuf[1024];        /* used by dumplist() */
  41. static int bytecount;
  42.  
  43. /* ------------------------ G R A M M E R ----------------------------- */
  44.  
  45. %}
  46.  
  47. %token STRING
  48. %token D_ORG
  49. %token D_BYTE
  50. %token D_WORD
  51. %token D_SKIP
  52. %token D_EQU
  53. %token D_FLAG
  54. %token D_END
  55. %token ACALL
  56. %token ADD
  57. %token ADDC
  58. %token AJMP
  59. %token ANL
  60. %token CJNE
  61. %token CLR
  62. %token CPL
  63. %token DA
  64. %token DEC
  65. %token DIV
  66. %token DJNZ
  67. %token INC
  68. %token JB
  69. %token JBC
  70. %token JC
  71. %token JMP
  72. %token JNB
  73. %token JNC
  74. %token JNZ
  75. %token JZ
  76. %token LCALL
  77. %token LJMP
  78. %token MOV
  79. %token MOVC
  80. %token MOVX
  81. %token NOP
  82. %token MUL
  83. %token ORL
  84. %token POP
  85. %token PUSH
  86. %token RET
  87. %token RETI
  88. %token RL
  89. %token RLC
  90. %token RR
  91. %token RRC
  92. %token SETB
  93. %token SJMP
  94. %token SUBB
  95. %token SWAP
  96. %token XCH
  97. %token XCHD
  98. %token XRL
  99. %token AB
  100. %token A
  101. %token C
  102. %token PC
  103. %token DPTR
  104. %token BITPOS
  105. %token R0
  106. %token R1
  107. %token R2
  108. %token R3
  109. %token R4
  110. %token R5
  111. %token R6
  112. %token R7
  113. %token VALUE
  114. %token SYMBOL
  115.  
  116. %left '+' '-'
  117. %left '*' '/' '%'
  118. %left '|' '&'
  119.  
  120. %start program
  121.  
  122. %%
  123. program        :    linelist
  124. {
  125. }
  126.         ;
  127.  
  128. linelist    : linelist line
  129.         | line
  130.         ;
  131.  
  132. line        : undefsym ':' linerest
  133. {
  134.     if( pass1 ) {
  135.         $1.sym->type = LABEL;
  136.         $1.sym->value = lc;
  137.     }
  138.     inclc($3.value);
  139.     bytecount = 0;
  140. }
  141.         | linerest        { inclc($1.value); bytecount = 0; }
  142.         ;
  143.  
  144. linerest    : directive '\n'    {
  145.                         $$.value = $1.value;
  146.                         if( dashl && pass2 )
  147.                             dumplist($2.str,1);
  148.                     }
  149.         | instr '\n'        {
  150.                         $$.value = $1.value;
  151.                         if( dashl && pass2 )
  152.                             dumplist($2.str,1);
  153.  
  154.                     }
  155.         | '\n'            {
  156.                         $$.value = 0;
  157.                         if( dashl && pass2 )
  158.                             dumplist($1.str,0);
  159.                     }
  160.         ;
  161.  
  162.  
  163.  
  164.  
  165.  
  166. /* --------------------
  167.  * DIRECTIVES:
  168.  *
  169.  */
  170.  
  171. directive    : '.' D_ORG defexpr
  172. {
  173.     lc = $3.val.v;
  174.     if( pass2 ) emitaddr(lc);
  175.     bytecount = 0;
  176.     $$.value = 0;
  177. }
  178.         | '.' D_BYTE blist    { $$.value = $3.value; }
  179.         | '.' D_WORD wlist    { $$.value = $3.value; }
  180.         | '.' D_SKIP defexpr    { $$.value = $3.val.v;
  181.                       if( pass2 )
  182.                         emitaddr(lc+$$.value); }
  183.         | '.' D_EQU undefsym ',' expr
  184. {
  185.     if( $5.val.d == 0 )
  186.         error("Expression is undefined in pass 1");
  187.     $3.sym->type = LABEL;
  188.     $3.sym->value = $5.val.v;
  189.     $$.value = 0;
  190. }
  191.     
  192.         | '.' D_FLAG SYMBOL ',' flag
  193. {
  194.     $3.sym->type = LABEL;
  195.     $3.sym->value = $5.value;
  196.     $$.value = 0;
  197. }
  198.         | '.' D_END            { $$.value = 0; }
  199.         ;
  200.  
  201. defexpr        : expr
  202. {
  203.         if( $1.val.d == 0 )
  204.             error("Expression is undefined in pass 1");
  205.         if( !(isbit16($1.val.v)) )
  206.             error("Value greater than 16-bits");
  207.         $$.value = $1.val.v;
  208. }
  209.         ;
  210.  
  211. flag        : flagv BITPOS
  212. {
  213.     if( !isbit8($1.value) )
  214.         warning("Bit address exceeds 8-bits");
  215.     if( isbmram($1.value) )
  216.         $$.value = ($1.value-0x20)*8+ $2.value;
  217.     else if( isbmsfr($1.value) )
  218.         $$.value = $1.value + $2.value;
  219.     else
  220.         warning("Invalid bit addressable RAM location");
  221. }
  222.         ;
  223.  
  224. flagv        : SYMBOL
  225. {
  226.     if( $1.sym->type == UNDEF )
  227.         error("Symbol %s must be defined in pass 1",$1.sym->name);
  228.     $$.value = $1.sym->value;
  229. }
  230.         | VALUE            { $$.value = $1.value; }
  231.         ;
  232.  
  233.  
  234. undefsym    : SYMBOL
  235. {
  236.     if( $1.sym->type != UNDEF && pass1)
  237.         error("Attempt to redefine symbol: %s",$1.sym->name);
  238.     $$.sym = $1.sym;
  239. }
  240.         ;
  241.  
  242. blist        : blist ',' data8
  243. {
  244.     if( pass2 ) genbyte($3.value);
  245.     $$.value = $1.value + 1;
  246. }
  247.         | blist ',' STRING
  248. {
  249.     if( pass1 )
  250.         $$.value = $1.value + $3.value;
  251.     else {
  252.         $$.value = $1.value + strlen($3.str);
  253.         genstr($3.str);
  254.         
  255.         free($3.str);
  256.     }
  257. }
  258.         | data8
  259. {
  260.     if( pass2 ) genbyte($1.value);
  261.     $$.value = 1;
  262. }
  263.         | STRING
  264. {
  265.     if( pass1 )
  266.         $$.value = $1.value;
  267.     else {
  268.         $$.value = strlen($1.str);
  269.         genstr($1.str);
  270.         free($1.str);
  271.     }
  272. }
  273.         ;
  274.  
  275. wlist        : wlist ',' data16
  276. {
  277.     if( pass2 ) genword($3.value);
  278.     $$.value = $1.value + 2;
  279. }
  280.         | data16
  281. {
  282.     if( pass2 ) genword($1.value);
  283.     $$.value = 2;
  284. }
  285.         ;
  286.  
  287.  
  288.  
  289. /* --------------------
  290.  * EXPRESSIONS:
  291.  *
  292.  */
  293.  
  294. expr        : '*'            { $$.val.v = lc;
  295.                       $$.val.d = 1; }
  296.  
  297.         | '(' expr ')'        { $$.val.v = $2.val.v;
  298.                       $$.val.d = $2.val.d; }
  299.  
  300.         | '-' expr %prec '*'    { $$.val.v = -$2.val.v;
  301.                       $$.val.d = $2.val.d;  }
  302.  
  303.         | expr '|' expr        { $$.val.v = $1.val.v | $3.val.v;
  304.                       $$.val.d = $1.val.d && $3.val.d; }
  305.  
  306.         | expr '&' expr        { $$.val.v = $1.val.v & $3.val.v;
  307.                       $$.val.d = $1.val.d && $3.val.d; }
  308.  
  309.         | expr '*' expr        { $$.val.v = $1.val.v * $3.val.v;
  310.                       $$.val.d = $1.val.d && $3.val.d; }
  311.  
  312.         | expr '/' expr        { $$.val.v = $1.val.v / $3.val.v;
  313.                       $$.val.d = $1.val.d && $3.val.d; }
  314.  
  315.         | expr '%' expr        { $$.val.v = $1.val.v % $3.val.v;
  316.                       $$.val.d = $1.val.d && $3.val.d; }
  317.  
  318.         | expr '-' expr        { $$.val.v = $1.val.v - $3.val.v;
  319.                       $$.val.d = $1.val.d && $3.val.d; }
  320.  
  321.         | expr '+' expr        { $$.val.v = $1.val.v + $3.val.v;
  322.                       $$.val.d = $1.val.d && $3.val.d; }
  323.         | SYMBOL
  324. {
  325.     if( pass1 ) {
  326.         $$.val.v = $1.sym->value;
  327.         $$.val.d = ($1.sym->type != UNDEF);
  328.     }
  329.     else {
  330.         if( $1.sym->type == UNDEF )
  331.             error("Undefined symbol %s",$1.sym->name);
  332.         $$.val.v = $1.sym->value;
  333.         $$.val.d = 1;
  334.     }
  335. }
  336.         | VALUE        { $$.val.v = $1.val.v; $$.val.d=1; }
  337.         ;
  338.  
  339.  
  340.  
  341.  
  342.  
  343. /* --------------------
  344.  * INSTRUCTIONS:
  345.  *
  346.  */
  347.  
  348. instr        : NOP
  349.                 { $$.value = makeop($1.op,NULL,0); }
  350.         | ACALL addr11
  351.                 { $$.value = makeop($1.op,&$2.mode,0); }
  352.         | AJMP addr11
  353.                 { $$.value = makeop($1.op,&$2.mode,0); }
  354.         | ADD two_op1
  355.                 { $$.value = makeop($1.op,&$2.mode,0); }
  356.         | ADDC two_op1
  357.                 { $$.value = makeop($1.op,&$2.mode,0); }
  358.         | SUBB two_op1
  359.                 { $$.value = makeop($1.op,&$2.mode,0); }
  360.         | XRL two_op1
  361.                 { $$.value = makeop($1.op,&$2.mode,0); }
  362.         | XRL two_op2
  363.                 { $$.value = makeop($1.op,&$2.mode,4); }
  364.         | ANL two_op1
  365.                 { $$.value = makeop($1.op,&$2.mode,0); }
  366.         | ANL two_op2
  367.                 { $$.value = makeop($1.op,&$2.mode,4); }
  368.         | ANL two_op3
  369.                 { $$.value = makeop($1.op,&$2.mode,6); }
  370.         | ORL two_op1
  371.                 { $$.value = makeop($1.op,&$2.mode,0); }
  372.         | ORL two_op2
  373.                 { $$.value = makeop($1.op,&$2.mode,4); }
  374.         | ORL two_op3
  375.                 { $$.value = makeop($1.op,&$2.mode,6); }
  376.         | XCH two_op1
  377.                 { if( get_md($2.mode) == 3 )
  378.                     error("Immediate mode is illegal");
  379.                   $$.value = makeop($1.op,&$2.mode,0);
  380.                 }
  381.         | INC single_op1
  382.                 { $$.value = makeop($1.op,&$2.mode,0); }
  383.         | INC DPTR
  384.                 { $$.value = makeop($1.op,NULL,4); }
  385.         | DEC single_op1
  386.                 { $$.value = makeop($1.op,&$2.mode,0); }
  387.         | DA A
  388.                 { $$.value = makeop($1.op,NULL,0); }
  389.         | DIV AB
  390.                 { $$.value = makeop($1.op,NULL,0); }
  391.         | JMP '@' A '+' DPTR
  392.                 { $$.value = makeop($1.op,NULL,0); }
  393.         | JMP '@' DPTR '+' A
  394.                 { $$.value = makeop($1.op,NULL,0); }
  395.         | MUL AB
  396.                 { $$.value = makeop($1.op,NULL,0); }
  397.         | RET
  398.                 { $$.value = makeop($1.op,NULL,0); }
  399.         | RETI
  400.                 { $$.value = makeop($1.op,NULL,0); }
  401.         | RL A
  402.                 { $$.value = makeop($1.op,NULL,0); }
  403.         | RLC A
  404.                 { $$.value = makeop($1.op,NULL,0); }
  405.         | RR A
  406.                 { $$.value = makeop($1.op,NULL,0); }
  407.         | RRC A
  408.                 { $$.value = makeop($1.op,NULL,0); }
  409.         | SWAP A
  410.                 { $$.value = makeop($1.op,NULL,0); }
  411.         | XCHD two_op1
  412.                 { if( get_md($2.mode) != 2 )
  413.                     error("Invalid addressing mode");
  414.                   $$.value = makeop($1.op,&$2.mode,-2); }
  415.         | CLR single_op2
  416.                 { $$.value = makeop($1.op,&$2.mode,0); }
  417.         | CPL single_op2
  418.                 { $$.value = makeop($1.op,&$2.mode,0); }
  419.         | SETB single_op2
  420.                 { if( get_md($2.mode) == 0 )
  421.                     error("Invalid addressing mode");
  422.                   $$.value = makeop($1.op,&$2.mode,-1); }
  423.         | PUSH data8
  424.                 {
  425.                    struct mode tmp;
  426.                     set_md(tmp,0);
  427.                     set_ov(tmp,0);
  428.                     set_sz(tmp,1);
  429.                     set_b1(tmp,$2.value);
  430.                     $$.value = makeop($1.op,&tmp,0);
  431.                 }
  432.         | POP data8
  433.                 {
  434.                    struct mode tmp;
  435.                     set_md(tmp,0);
  436.                     set_ov(tmp,0);
  437.                     set_sz(tmp,1);
  438.                     set_b1(tmp,$2.value);
  439.                     $$.value = makeop($1.op,&tmp,0);
  440.                 }
  441.         | LJMP addr16
  442.                 { $$.value = makeop($1.op,&$2.mode,0); }
  443.         | LCALL addr16
  444.                 { $$.value = makeop($1.op,&$2.mode,0); }
  445.         | JC relative
  446.                 { $$.value = makeop($1.op,&$2.mode,0); }
  447.         | JNC relative
  448.                 { $$.value = makeop($1.op,&$2.mode,0); }
  449.         | JNZ relative
  450.                 { $$.value = makeop($1.op,&$2.mode,0); }
  451.         | JZ relative
  452.                 { $$.value = makeop($1.op,&$2.mode,0); }
  453.         | SJMP relative
  454.                 { $$.value = makeop($1.op,&$2.mode,0); }
  455.         | CJNE three_op1
  456.                 { $$.value = makeop($1.op,&$2.mode,0); }
  457.         | JB two_op4
  458.                 { $$.value = makeop($1.op,&$2.mode,0); }
  459.         | JNB two_op4
  460.                 { $$.value = makeop($1.op,&$2.mode,0); }
  461.         | JBC two_op4
  462.                 { $$.value = makeop($1.op,&$2.mode,0); }
  463.         | DJNZ two_op5
  464.                 { $$.value = makeop($1.op,&$2.mode,0); }
  465.         | MOV two_op1
  466.                 { $$.value = makeop($1.op,&$2.mode,0); }
  467.         | MOV two_op2
  468.                 { $$.value = makeop($1.op,&$2.mode,4); }
  469.         | MOV two_op6
  470.                 { $$.value = makeop($1.op,&$2.mode,6); }
  471.  
  472.  
  473.         | MOVC A ',' '@' A '+' DPTR
  474.                 { $$.value = makeop($1.op,NULL,0); }
  475.         | MOVC A ',' '@' DPTR '+' A
  476.                 { $$.value = makeop($1.op,NULL,0); }
  477.         | MOVC A ',' '@' A '+' PC
  478.                 { $$.value = makeop($1.op,NULL,1); }
  479.         | MOVC A ',' '@' PC '+' A
  480.                 { $$.value = makeop($1.op,NULL,1); }
  481.  
  482.         | MOVX A ',' '@' regi
  483.                 { $$.value = makeop($1.op,NULL,$5.value); }
  484.         | MOVX A ',' '@' DPTR
  485.                 { $$.value = makeop($1.op,NULL,2); }
  486.         | MOVX '@' regi ',' A
  487.                 { $$.value = makeop($1.op,NULL,$3.value+3); }
  488.         | MOVX '@' DPTR ',' A
  489.                 { $$.value = makeop($1.op,NULL,5); }
  490.         ;
  491.  
  492.  
  493.  
  494.  
  495. /* --------------------
  496.  * ADDRESSING MODES:
  497.  *
  498.  */
  499.  
  500. two_op1        : A ',' reg
  501.                 {
  502.                     set_md($$.mode,0);
  503.                     set_ov($$.mode, $3.value);
  504.                     set_sz($$.mode, 0);
  505.                 }
  506.         | A ',' data8
  507.                 {
  508.                     set_md($$.mode,1);
  509.                     set_ov($$.mode,0);
  510.                     set_sz($$.mode,1);
  511.                     set_b1($$.mode,$3.value);
  512.                 }
  513.         | A ',' '@' regi
  514.                 {
  515.                     set_md($$.mode,2);
  516.                     set_ov($$.mode,$4.value);
  517.                     set_sz($$.mode,0);
  518.                 }
  519.         | A ',' '#' data8
  520.                 {
  521.                     set_md($$.mode,3);
  522.                     set_ov($$.mode,0);
  523.                     set_sz($$.mode,1);
  524.                     set_b1($$.mode,$4.value);
  525.                 }
  526.         ;
  527.  
  528. two_op2        : data8 ',' A
  529.                 {
  530.                     set_md($$.mode,0);
  531.                     set_ov($$.mode,0);
  532.                     set_sz($$.mode,1);
  533.                     set_b1($$.mode,$1.value);
  534.                 }
  535.         | data8 ',' '#' data8
  536.                 {
  537.                     set_md($$.mode,1);
  538.                     set_ov($$.mode,0);
  539.                     set_sz($$.mode,2);
  540.                     set_b1($$.mode,$1.value);
  541.                     set_b2($$.mode,$4.value);
  542.                 }
  543.         ;
  544.  
  545. two_op3        : C ',' bit
  546.                 {
  547.                     set_md($$.mode,0);
  548.                     set_ov($$.mode,0);
  549.                     set_sz($$.mode,1);
  550.                     set_b1($$.mode,$3.value);
  551.                 }
  552.         | C ',' '/' bit
  553.                 {
  554.                     set_md($$.mode,1);
  555.                     set_ov($$.mode,0);
  556.                     set_sz($$.mode,1);
  557.                     set_b1($$.mode,$4.value);
  558.                 }
  559.         | C ',' '!' bit
  560.                 {
  561.                     set_md($$.mode,1);
  562.                     set_ov($$.mode,0);
  563.                     set_sz($$.mode,1);
  564.                     set_b1($$.mode,$4.value);
  565.                 }
  566.         ;
  567.  
  568. two_op4        : bit ',' rel
  569.                 {
  570.                     set_md($$.mode,0);
  571.                     set_ov($$.mode,0);
  572.                     set_sz($$.mode,2);
  573.                     set_b1($$.mode,$1.value);
  574.                     set_b2($$.mode,$3.value);
  575.                 }
  576.         ;
  577.  
  578. two_op5        : reg ',' rel2
  579.                 {
  580.                     set_md($$.mode,0);
  581.                     set_ov($$.mode,$1.value);
  582.                     set_sz($$.mode,1);
  583.                     set_b1($$.mode,$3.value);
  584.                 }
  585.         | data8 ',' rel
  586.                 {
  587.                     set_md($$.mode,1);
  588.                     set_ov($$.mode,0);
  589.                     set_sz($$.mode,2);
  590.                     set_b1($$.mode,$1.value);
  591.                     set_b2($$.mode,$3.value);
  592.                 }
  593.         ;
  594.  
  595. two_op6        : reg ',' A
  596.                 {
  597.                     set_md($$.mode,0);
  598.                     set_ov($$.mode,$1.value);
  599.                     set_sz($$.mode,0);
  600.                 }
  601.         | reg ',' data8
  602.                 {
  603.                     set_md($$.mode,1);
  604.                     set_ov($$.mode,$1.value);
  605.                     set_sz($$.mode,1);
  606.                     set_b1($$.mode,$3.value);
  607.                 }
  608.         | reg ',' '#' data8
  609.                 {
  610.                     set_md($$.mode,2);
  611.                     set_ov($$.mode,$1.value);
  612.                     set_sz($$.mode,1);
  613.                     set_b1($$.mode,$4.value);
  614.                 }
  615.         | data8 ',' reg
  616.                 {
  617.                     set_md($$.mode,3);
  618.                     set_ov($$.mode,$3.value);
  619.                     set_sz($$.mode,1);
  620.                     set_b1($$.mode,$1.value);
  621.                 }
  622.         | data8 ',' data8
  623.                 {
  624.                     set_md($$.mode,4);
  625.                     set_ov($$.mode,0);
  626.                     set_sz($$.mode,2);
  627.                     set_b1($$.mode,$3.value);
  628.                     set_b2($$.mode,$1.value);
  629.                 }
  630.         | data8 ',' '@' regi
  631.                 {
  632.                     set_md($$.mode,5);
  633.                     set_ov($$.mode,$4.value);
  634.                     set_sz($$.mode,1);
  635.                     set_b1($$.mode,$1.value);
  636.                 }
  637.         | '@' regi ',' A
  638.                 {
  639.                     set_md($$.mode,6);
  640.                     set_ov($$.mode,$2.value);
  641.                     set_sz($$.mode,0);
  642.                 }
  643.         | '@' regi ',' data8
  644.                 {
  645.                     set_md($$.mode,7);
  646.                     set_ov($$.mode,$2.value);
  647.                     set_sz($$.mode,1);
  648.                     set_b1($$.mode,$4.value);
  649.                 }
  650.         | '@' regi ',' '#' data8
  651.                 {
  652.                     set_md($$.mode,8);
  653.                     set_ov($$.mode,$2.value);
  654.                     set_sz($$.mode,1);
  655.                     set_b1($$.mode,$5.value);
  656.                 }
  657.         | DPTR ',' '#' data16
  658.             {
  659.                 set_md($$.mode,9);
  660.                 set_ov($$.mode,0);
  661.                 set_sz($$.mode,2);
  662.                 set_b1($$.mode, ($4.value & 0xff00) >> 8 );
  663.                 set_b2($$.mode, ($4.value & 0x00ff) );
  664.             }
  665.         | C ',' bit
  666.                 {
  667.                     set_md($$.mode,10);
  668.                     set_ov($$.mode,0);
  669.                     set_sz($$.mode,1);
  670.                     set_b1($$.mode,$3.value);
  671.                 }
  672.     /*
  673.      * Following two productions cannot be represented by:
  674.      *
  675.      *    bit ',' C
  676.      *
  677.      * Because yacc gives tons of reduce/reduce errors if
  678.       * that is attempted.
  679.      *
  680.      */
  681.         | data8 ',' C
  682.                 {
  683.                     set_md($$.mode,11);
  684.                     set_ov($$.mode,0);
  685.                     set_sz($$.mode,1);
  686.                     set_b1($$.mode,$1.value);
  687.                 }
  688.         | data8 BITPOS ',' C
  689. {
  690.     if( pass2 ) {
  691.         if( !isbit8($1.value) )
  692.             warning("Bit address exceeds 8-bits");
  693.         if( isbmram($1.value) )
  694.             set_b1($$.mode, ($1.value-0x20)*8+ $2.value );
  695.         else if( isbmsfr($1.value) )
  696.             set_b1($$.mode, $1.value + $2.value );
  697.         else
  698.             warning("Invalid bit addressable RAM location");
  699.     }
  700.     set_md($$.mode,11);
  701.     set_ov($$.mode,0);
  702.     set_sz($$.mode,1);
  703. }
  704.         ;
  705.  
  706.  
  707. single_op1    : A
  708.                 {
  709.                     set_md($$.mode,0);
  710.                     set_ov($$.mode,0);
  711.                     set_sz($$.mode,0);
  712.                 }
  713.  
  714.         | reg
  715.                 {
  716.                     set_md($$.mode,1);
  717.                     set_ov($$.mode,$1.value);
  718.                     set_sz($$.mode,0);
  719.                 }
  720.         | data8
  721.                 {
  722.                     set_md($$.mode,2);
  723.                     set_ov($$.mode,0);
  724.                     set_sz($$.mode,1);
  725.                     set_b1($$.mode,$1.value);
  726.                 }
  727.         | '@' regi
  728.                 {
  729.                     set_md($$.mode,3);
  730.                     set_ov($$.mode,$2.value);
  731.                     set_sz($$.mode,0);
  732.                 }
  733.         ;
  734.  
  735. single_op2    : A
  736.                 {
  737.                     set_md($$.mode,0);
  738.                     set_ov($$.mode,0);
  739.                     set_sz($$.mode,0);
  740.                 }
  741.         | C
  742.                 {
  743.                     set_md($$.mode,1);
  744.                     set_ov($$.mode,0);
  745.                     set_sz($$.mode,0);
  746.                 }
  747.         | bit
  748.                 {
  749.                     set_md($$.mode,2);
  750.                     set_ov($$.mode,0);
  751.                     set_sz($$.mode,1);
  752.                     set_b1($$.mode,$1.value);
  753.                 }
  754.         ;
  755.  
  756. three_op1    : A ',' data8 ',' rel
  757.                 {
  758.                     set_md($$.mode,0);
  759.                     set_ov($$.mode,0);
  760.                     set_sz($$.mode,2);
  761.                     set_b1($$.mode,$3.value);
  762.                     set_b2($$.mode,$5.value);
  763.                 }
  764.         | A ',' '#' data8 ',' rel
  765.                 {
  766.                     set_md($$.mode,1);
  767.                     set_ov($$.mode,0);
  768.                     set_sz($$.mode,2);
  769.                     set_b1($$.mode,$4.value);
  770.                     set_b2($$.mode,$6.value);
  771.                 }
  772.         | reg ',' '#' data8 ',' rel
  773.                 {
  774.                     set_md($$.mode,2);
  775.                     set_ov($$.mode,$1.value);
  776.                     set_sz($$.mode,2);
  777.                     set_b1($$.mode,$4.value);
  778.                     set_b2($$.mode,$6.value);
  779.                 }
  780.         | '@' regi ',' '#' data8 ',' rel
  781.                 {
  782.                     set_md($$.mode,3);
  783.                     set_ov($$.mode,$2.value);
  784.                     set_sz($$.mode,2);
  785.                     set_b1($$.mode,$5.value);
  786.                     set_b2($$.mode,$7.value);
  787.                 }
  788.         ;
  789.  
  790. rel        : expr
  791. {
  792.         long offset;
  793.         if( pass2 ) {
  794.             offset = $1.val.v - (lc+3);
  795.             if( offset > 127 || offset < -128 )
  796.                warning("Relative offset exceeds -128 / +127");
  797.             $$.value = offset;
  798.         }
  799. }
  800.         ;
  801.  
  802. /*
  803.  * This production differs from the above, by 1 number!
  804.  *
  805.  */
  806.  
  807. rel2        : expr
  808. {
  809.         long offset;
  810.         if( pass2 ) {
  811.             offset = $1.val.v - (lc+2); /* different! */
  812.             if( offset > 127 || offset < -128 )
  813.                warning("Relative offset exceeds -128 / +127");
  814.             $$.value = offset;
  815.         }
  816. }
  817.         ;
  818.  
  819.  
  820. bit        : bitv BITPOS
  821. {
  822.     if( pass2 ) {
  823.         if( !isbit8($1.value) )
  824.             warning("Bit address exceeds 8-bits");
  825.         if( isbmram($1.value) )
  826.             $$.value = ($1.value-0x20)*8+$2.value;
  827.         else if( isbmsfr($1.value) )
  828.             $$.value = $1.value + $2.value;
  829.         else
  830.             warning("Invalid bit addressable RAM location");
  831.     }
  832. }
  833.         | bitv
  834. {
  835.     if( pass2 ) {
  836.         if( !isbit8($1.value) )
  837.             warning("Bit address exceeds 8-bits");
  838.         $$.value = $1.value;
  839.     }
  840. }
  841.         ;
  842.  
  843. bitv        : SYMBOL
  844. {
  845.     if( $1.sym->type == UNDEF && pass2 )
  846.         error("Symbol %s undefined",$1.sym->name);
  847.     $$.value = $1.sym->value;
  848. }
  849.         | VALUE        { $$.value = $1.value; }
  850.         ;
  851.  
  852. reg        : R0        { $$.value = 0; }
  853.         | R1        { $$.value = 1; }
  854.         | R2        { $$.value = 2; }
  855.         | R3        { $$.value = 3; }
  856.         | R4        { $$.value = 4; }
  857.         | R5        { $$.value = 5; }
  858.         | R6        { $$.value = 6; }
  859.         | R7        { $$.value = 7; }
  860.         ;
  861.  
  862. regi        : R0        { $$.value = 0; }
  863.         | R1        { $$.value = 1; }
  864.         | R2
  865.                 { $$.value = 0;
  866.                   warning("Illegal indirect register: @r2"); }
  867.         | R3
  868.                 { $$.value = 0;
  869.                   warning("Illegal indirect register: @r3"); }
  870.         | R4
  871.                 { $$.value = 0;
  872.                   warning("Illegal indirect register: @r4"); }
  873.         | R5
  874.                 { $$.value = 0;
  875.                   warning("Illegal indirect register: @r5"); }
  876.         | R6
  877.                 { $$.value = 0;
  878.                   warning("Illegal indirect register: @r6"); }
  879.         | R7
  880.                 { $$.value = 0;
  881.                   warning("Illegal indirect register: @r7"); }
  882.         ;
  883.  
  884. data8        : expr
  885. {
  886.     if( pass2 ) {
  887.         if( !isbit8($1.val.v) )
  888.             warning("Expression greater than 8-bits");
  889.     }
  890.     $$.value = $1.val.v;
  891. }
  892.         ;
  893.  
  894. data16        : expr
  895. {
  896.     if( pass2 ) {
  897.         if( !isbit16($1.val.v) )
  898.             warning("Expression greater than 16-bits");
  899.     }
  900.     $$.value = $1.val.v;
  901. }
  902.         ;
  903.  
  904. addr11        : expr
  905. {
  906.         if( pass2 ) {
  907.             if( !isbit16($1.val.v)  )
  908.                 warning("Address greater than 16-bits");
  909.             if( ($1.val.v & size11) != ((lc+2) & size11) )
  910.                 warning("Address outside current 2K page");
  911.         }
  912.         set_md($$.mode,0);
  913.         set_ov($$.mode, ($1.val.v&0x0700)>>3 );
  914.         set_sz($$.mode,1);
  915.         set_b1($$.mode,$1.val.v&0x00ff);
  916. }
  917.         ;
  918.  
  919. addr16        : expr
  920. {
  921.         if( pass2 ) {
  922.             if( !isbit16($1.val.v)  )
  923.                 warning("Address greater than 16-bits");
  924.         }
  925.         set_md($$.mode,0);
  926.         set_ov($$.mode, 0 );
  927.         set_sz($$.mode,2);
  928.         set_b1($$.mode, ($1.val.v & 0xff00 ) >> 8 );
  929.         set_b2($$.mode, ($1.val.v & 0x00ff ) );
  930. }
  931.         ;
  932.  
  933. relative    : expr
  934. {
  935.         long offset;
  936.         if( pass2 ) {
  937.             offset = $1.val.v - (lc+2);
  938.             if( offset>127 || offset<-128 )
  939.                warning("Relative offset exceeds -128 / +127");
  940.         }
  941.         set_md($$.mode,0);
  942.         set_ov($$.mode,0);
  943.         set_sz($$.mode,1);
  944.         set_b1($$.mode,offset);
  945.  
  946. }
  947.         ;
  948.  
  949. %%
  950.  
  951. /* ---------------------------------------------------------------------- */
  952.  
  953. yyerror(s)
  954. char *s;
  955. {
  956.     error(s);
  957. }
  958.  
  959.  
  960. /* ----------------------------------------------------------------------
  961.  * error:
  962.  *    Uses semi-variable arguments. This causes immediate assembler
  963.  *    termination.
  964.  */
  965.  
  966. error(cs,a1,a2,a3,a4,a5,a6)
  967. char *cs,*a1,*a2,*a3,*a4,*a5,*a6;
  968. {
  969.     fprintf(stderr,"File: %s, line: %d, ",asmfile,lineno);
  970.     fprintf(stderr,cs,a1,a2,a3,a4,a5,a6);
  971.     fprintf(stderr,".\n");
  972.     longjmp(main_env,1);
  973. }
  974.  
  975. /* ----------------------------------------------------------------------
  976.  * warning:
  977.  *    Produce error message. This will abort assembly at
  978.  *    the end of the current pass.
  979.  *
  980.  */
  981.  
  982. warning(cs,a1,a2,a3,a4,a5,a6)
  983. char *cs,*a1,*a2,*a3,*a4,*a5,*a6;
  984. {
  985.     fatal++;
  986.     fprintf(stderr,"File: %s, line: %d, ",asmfile,lineno);
  987.     fprintf(stderr,cs,a1,a2,a3,a4,a5,a6);
  988.     fprintf(stderr,".\n");
  989. }
  990.  
  991.  
  992. /* ----------------------------------------------------------------------
  993.  * makeop:
  994.  *    This function makes an opcode based on the instruction symbol table
  995.  *    entry, and an addressing mode structure.
  996.  *    This function is called from both passes, but
  997.  *    only generates code in pass 2.
  998.  *
  999.  *    Resultant opcode bytes are passed to genbyte().
  1000.  *
  1001.  *    Returns the nuumber of bytes that the instruction
  1002.  *    occupies.
  1003.  *
  1004.  */
  1005.  
  1006. makeop(op,m,add)
  1007. struct opcode *op;
  1008. struct mode *m;
  1009. {
  1010.     register unsigned int newop;
  1011.  
  1012.     if( m == NULL ) {
  1013.         if(pass2) genbyte(op->bytes[0+add]);
  1014.         return(1);
  1015.     }
  1016.  
  1017.     if( pass2 ) {
  1018.         newop = op->bytes[ get_md(*m)+add ] | get_ov(*m);
  1019.         genbyte(newop);
  1020.         if( get_sz(*m) > 0 ) genbyte( get_b1(*m) );
  1021.         if( get_sz(*m) > 1 ) genbyte( get_b2(*m) );
  1022.     }
  1023.     return( get_sz(*m)+1 );
  1024. }
  1025.  
  1026.  
  1027. /* ----------------------------------------------------------------------
  1028.  * inclc:
  1029.  *    Increments the Location Counter by 'i' amount.
  1030.  *    Check to see if 'i' overflows 64K.
  1031.  *    Checks to see if assembler is overlapping previous sections
  1032.  *    of code. (using a large bit field).
  1033.  *
  1034.  */
  1035.  
  1036. #define indx(a) ( (a)/(sizeof(long)*8) )
  1037. #define bit(a)    ( 1 << ((a)%(sizeof(long)*8)) )
  1038.  
  1039. #define getloc(a) (regions[indx(a)] & bit(a))
  1040. #define setloc(a) (regions[indx(a)] |= bit(a))
  1041.  
  1042. inclc(i)
  1043. {
  1044.     static unsigned long regions[ 0x10000/(sizeof(long)*8) ];
  1045.  
  1046.     while(i-- > 0) {
  1047.         if( pass2 && getloc(lc) )
  1048.             error("Location counter overlaps");
  1049.         if( pass2 ) setloc(lc);
  1050.         lc += 1;
  1051.     }
  1052.         
  1053.     if( lc > 0xffff )
  1054.         error("Location counter has exceeded 16-bits");
  1055. }
  1056.  
  1057. /* ----------------------------------------------------------------------
  1058.  * padline:
  1059.  *    This routine returns a new string, which is equivilant to
  1060.  *    'line' except that all tabs have been expanded to spaces, and
  1061.  *    the total length has been truncated to 60 chars.
  1062.  */
  1063.  
  1064. char *padline(line)
  1065. char *line;
  1066. {
  1067.     static char newline[61];
  1068.     char *p1;
  1069.     int pos=0,nxtpos;
  1070.  
  1071.     for(p1=line; pos<sizeof(newline)-1 && *p1; p1++ ) {
  1072.         if( *p1 == '\t' ) {
  1073.             nxtpos = pos+8-pos%8;
  1074.             while(pos<sizeof(newline)-1 && pos <= nxtpos)
  1075.                 newline[pos++] = ' ';
  1076.         } else if( *p1 != '\n' )
  1077.             newline[pos++]= *p1;
  1078.     }
  1079.     newline[pos] = '\0';
  1080.     return(newline);
  1081. }
  1082.  
  1083.  
  1084. /* ----------------------------------------------------------------------
  1085.  * dumplist:
  1086.  *    Outputs the current location counter, bytebuf[] array, and
  1087.  *    the string 'txt' to the listing file.
  1088.  *    This routine is called for every source line encountered in the
  1089.  *    source file. (Only in pass 2, and if listing is turned on).
  1090.  *
  1091.  */
  1092.  
  1093. dumplist(txt,show)
  1094. char *txt;
  1095. {
  1096.     int i,j;
  1097.  
  1098.     fprintf(listing,show?"%04X: ":"      ",lc);
  1099.  
  1100.     j=0;
  1101.     for(i=0; i<bytecount; i++ ) {
  1102.         fprintf(listing,"%02X ",bytebuf[i]);
  1103.         if( ++j >= 4 ) {
  1104.             j = 0;
  1105.             fprintf(listing,"\n      ");
  1106.         }
  1107.     }
  1108.     while(++j <= 4)
  1109.         fprintf(listing,"   ");
  1110.  
  1111.     fprintf(listing," %s\n",padline(txt));
  1112. }
  1113.  
  1114. /* ----------------------------------------------------------------------
  1115.  * gen* routines:
  1116.  *    Place information into the bytebuf[] array, and also
  1117.  *    call emitbyte with the byte.
  1118.  *
  1119.  */
  1120.  
  1121. genbyte(b)
  1122. int b;
  1123. {
  1124.     if( bytecount < sizeof(bytebuf) )
  1125.         bytebuf[bytecount++] = b;
  1126.     emitbyte(b);
  1127. }
  1128.  
  1129. genstr(s)
  1130. char *s;
  1131. {
  1132.     while( *s )
  1133.         genbyte(*s++);
  1134. }
  1135.  
  1136. genword(w)
  1137. unsigned long w;
  1138. {
  1139.     genbyte( (w & 0xff00) >> 8 );
  1140.     genbyte( (w & 0x00ff) );
  1141. }
  1142.  
  1143.