home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / orig / op.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-10  |  8.4 KB  |  210 lines

  1. #include <stdio.h>
  2. #include "io.h"
  3. #include "ex.h"
  4. #include "st.h"
  5. #include "res.h"
  6. #include "op.h"
  7.  
  8. #define ELEMENTS(Arr) (sizeof(Arr)/sizeof(Arr[0]))
  9.  
  10. /* Translate controls:
  11.    X: . = x     # = #x      / = /x      n = Rn
  12.       A = A     B = AB      C = C       D = DPTR
  13.       i = @Ri   @ = @DPTR   > = @A+DPTR $ = @A+PC
  14.    Y: (x)  L = Long Code Address
  15.            P = Paged Code Address
  16.            R = Relative Code Address
  17.            D = Direct Register Address
  18.       (x/) B = Bit Address
  19.       (@)  w = Word
  20.            b = Byte
  21.       (i)  i = Register Pointer R0/R1
  22.       (n)  n = Register R0/R1/R2/R3/R4/R5/R6/R7
  23.            x = Reverse Order of Next 2 Operands.
  24.   */
  25.  
  26. Mode ModeTab[] = {
  27. /* acall */ { 0x11, ".",   "P" },
  28. /* add */   { 0x24, "A#",  "b" },  { 0x26, "Ai",  "i" }, { 0x25, "A.",  "D" },
  29.             { 0x28, "An",  "n" },
  30. /* addc */  { 0x34, "A#",  "b" },  { 0x36, "Ai",  "i" }, { 0x35, "A.",  "D" },
  31.             { 0x38, "An",  "n" },
  32. /* ajmp */  { 0x01, ".",   "P" },
  33. /* anl */   { 0x54, "A#",  "b" },  { 0x56, "Ai",  "i" }, { 0x55, "A.",  "D" },
  34.             { 0x58, "An",  "n" },  { 0xb0, "C/",  "B" }, { 0x82, "C.",  "B" },
  35.             { 0x53, ".#",  "Db" }, { 0x52, ".A",  "D" },
  36. /* cjne */  { 0xb6, "i#.", "ibR" },{ 0xb4, "A#.", "bR" },{ 0xb5, "A..", "DR" },
  37.             { 0xb8, "n#.", "nbR" },
  38. /* clr */   { 0xe4, "A",   "" },   { 0xc2, ".",   "B" }, { 0xc3, "C",   "" },
  39. /* cpl */   { 0xf4, "A",   "" },   { 0xb2, ".",   "B" }, { 0xb3, "C",   "" },
  40. /* da */    { 0xd4, "A",   "" },
  41. /* dec */   { 0x16, "i",   "i" },  { 0x14, "A",   ""},   { 0x15, ".",   "D" },
  42.             { 0x18, "n",   "n" },
  43. /* div */   { 0x84, "B",   "" },
  44. /* djnz */  { 0xd5, "..",  "DR" }, { 0xd8, "n.",  "nR" },
  45. /* inc */   { 0x06, "i",   "i" },  { 0x04, "A",   "" },  { 0x05, ".",   "D" },
  46.             { 0xa3, "D",   "" },   { 0x08, "n",   "n" },
  47. /* jb */    { 0x20, "..",  "BR" },
  48. /* jbc */   { 0x10, "..",  "BR" },
  49. /* jc */    { 0x40, ".",   "R" },
  50. /* jmp */   { 0x73, ">",   "" },
  51. /* jnb */   { 0x30, "..",  "BR" },
  52. /* jnc */   { 0x50, ".",   "R" },
  53. /* jnz */   { 0x70, ".",   "R" },
  54. /* jz */    { 0x60, ".",   "R" },
  55. /* lcall */ { 0x12, ".",   "L" },
  56. /* ljmp */  { 0x02, ".",   "L" },
  57. /* mov */   { 0x76, "i#",  "ib" }, { 0xf6, "iA",  "i" }, { 0xa6, "i.",  "iD" },
  58.             { 0x74, "A#",  "b" },  { 0xe6, "Ai",  "i" }, { 0xe5, "A.",  "D" },
  59.             { 0xe8, "An",  "n" },  { 0x92, ".C",  "B" }, { 0xa2, "C.",  "B" },
  60.             { 0x75, ".#",  "Db" }, { 0x86, ".i",  "iD" },{ 0xf5, ".A",  "D" },
  61.             { 0x85, "..",  "xDD" },{ 0x88, ".n",  "nD" },{ 0x90, "D#",  "w" },
  62.             { 0x78, "n#",  "nb" }, { 0xf8, "nA",  "n" }, { 0xa8, "n.",  "nD" },
  63. /* movc */  { 0x93, "A>",  "" },   { 0x83, "A$",  "" },
  64. /* movx */  { 0xf0, "@A",  "" },   { 0xf2, "iA",  "i" }, { 0xe0, "A@",  "" },
  65.             { 0xe2, "Ai",  "i" },
  66. /* mul */   { 0xa4, "B",   "" },
  67. /* nop */   { 0x00, "",    "" },
  68. /* orl */   { 0x44, "A#",  "b" },  { 0x46, "Ai",  "i" }, { 0x45, "A.",  "D" },
  69.             { 0x48, "An",  "n" },  { 0xa0, "C/",  "B" }, { 0x72, "C.",  "B" },
  70.             { 0x43, ".#",  "Db" }, { 0x42, ".A",  "D" },
  71. /* pop */   { 0xd0, ".",   "D" },
  72. /* push */  { 0xc0, ".",   "D" },
  73. /* ret */   { 0x22, "",    "" },
  74. /* reti */  { 0x32, "",    "" },
  75. /* rl */    { 0x23, "A",   "" },
  76. /* rlc */   { 0x33, "A",   "" },
  77. /* rr */    { 0x03, "A",   "" },
  78. /* rrc */   { 0x13, "A",   "" },
  79. /* setb */  { 0xd2, ".",   "B" },  { 0xd3, "C",   "" },
  80. /* sjmp */  { 0x80, ".",   "R" },
  81. /* subb */  { 0x94, "A#",  "b" },  { 0x96, "Ai",  "i" }, { 0x95, "A.",  "D" },
  82.             { 0x98, "An",  "n" },
  83. /* swap */  { 0xc4, "A",   "" },
  84. /* xch */   { 0xc6, "Ai",  "i" },  { 0xc5, "A.",  "D" }, { 0xc8, "An",  "n" },
  85. /* xchd */  { 0xd6, "Ai",  "i" },
  86. /* xrl */   { 0x64, "A#",  "b" },  { 0x66, "Ai",  "i" }, { 0x65, "A.",  "D" },
  87.             { 0x68, "An",  "n" },  { 0x63, ".#",  "Db" },{ 0x62, ".A",  "D" }
  88. };
  89.  
  90. Code CodeTab[] = {
  91.    { "acall", 1 }, { "add",   4 }, { "addc",  4 }, { "ajmp",  1 },
  92.    { "anl",   8 }, { "cjne",  4 }, { "clr",   3 }, { "cpl",   3 },
  93.    { "da",    1 }, { "dec",   4 }, { "div",   1 }, { "djnz",  2 },
  94.    { "inc",   5 }, { "jb",    1 }, { "jbc",   1 }, { "jc",    1 },
  95.    { "jmp",   1 }, { "jnb",   1 }, { "jnc",   1 }, { "jnz",   1 },
  96.    { "jz",    1 }, { "lcall", 1 }, { "ljmp",  1 }, { "mov",  18 },
  97.    { "movc",  2 }, { "movx",  4 }, { "mul",   1 }, { "nop",   1 },
  98.    { "orl",   8 }, { "pop",   1 }, { "push",  1 }, { "ret",   1 },
  99.    { "reti",  1 }, { "rl",    1 }, { "rlc",   1 }, { "rr",    1 },
  100.    { "rrc",   1 }, { "setb",  2 }, { "sjmp",  1 }, { "subb",  4 },
  101.    { "swap",  1 }, { "xch",   3 }, { "xchd",  1 }, { "xrl",   6 },
  102.    { 0, 0 }
  103. };
  104.  
  105. /* Argument buffer. */
  106. #define A_MAX 4
  107. char XBuf[A_MAX + 1]; Exp XExp[A_MAX];
  108.  
  109. void OpInit(void) {
  110.    Code *OC; Mode *M; int I, J;
  111.    for (OC = CodeTab, M = ModeTab; OC < CodeTab + ELEMENTS(CodeTab); OC++) {
  112.       OC->Start = M; M += OC->Modes;
  113.       if (M > ModeTab + ELEMENTS(ModeTab))
  114.          fprintf(stderr, "Bad opcode initialization.\n"), exit(1);
  115.    }
  116. }
  117.  
  118. void ParseArgs(byte Mnem) {
  119.    Lexical L = OldL; Code *CP; Mode *MP; int XReg;
  120.    char *XP, *S; Exp *EP, E; byte Op; word W;
  121.    XP = XBuf, EP = XExp;
  122.    do {
  123.       L = Scan();
  124.       if (L == SEMI) {
  125.          if (XP > XBuf) ERROR("Extra ','."); break;
  126.       }
  127.       switch (L) {
  128.          case POUND: *XP = '#', Scan(), *EP++ = Parse(2); break;
  129.          case DIV: *XP = '/', Scan(), *EP++ = Parse(2); break;
  130.          case AT:
  131.             L = Scan();
  132.             switch (L) {
  133.                case REGISTER: switch ((Register)Value) {
  134.                   case ACC:
  135.                      if (Scan() != PLUS)
  136.                         ERROR("Cannot use @A."), *XP = ' ';
  137.                      else if (Scan() != REGISTER)
  138.                         ERROR("Missing DPTR or PC after @A+"), *XP = ' ';
  139.                      else {
  140.                         switch (Value) {
  141.                            case ACC:ERROR("Cannot use @A+A"), *XP = ' '; break;
  142.                            case AB:ERROR("Cannot use @A+AB."); *XP = ' '; break;
  143.                            case CY:ERROR("Cannot use @A+C."); *XP = ' '; break;
  144.                            case DPTR: *XP = '>'; break;
  145.                            case PC: *XP = '$'; break;
  146.                            default:ERROR("Cannot use @A+Rn"); *XP = ' '; break;
  147.                         }
  148.                         Scan();
  149.                      }
  150.                   break;
  151.                   case AB: ERROR("Cannot use @AB."); *XP = ' '; break;
  152.                   case CY: ERROR("Cannot use @C."); *XP = ' '; break;
  153.                   case DPTR: *XP = '@'; Scan(); break;
  154.                   case PC: ERROR("Cannot use @PC."); *XP = ' '; break;
  155.                   default:
  156.                      Value -= (short)R0;
  157.                      if (Value != 0 && Value != 1) {
  158.                         ERROR("Register in @Rn out of range."); *XP = ' ';
  159.                      } else *XP = 'i', XReg = Value;
  160.                      Scan();
  161.                   break;
  162.                }
  163.                break;
  164.                default:
  165.                   ERROR("Register must appear after @."); *XP = ' ';
  166.                break;
  167.             }
  168.          break;
  169.          case REGISTER: switch ((Register)Value) {
  170.             case ACC: *XP = 'A'; break;
  171.             case AB: *XP = 'B'; break;
  172.             case CY: *XP = 'C'; break;
  173.             case DPTR: *XP = 'D'; break;
  174.             case PC:
  175.                ERROR("Cannot use PC as a register.");
  176.                *XP = '.', *EP++ = MakeExp(AddrX, SegP, (word)LOC);
  177.             break;
  178.             default: *XP = 'n', XReg = Value - (short)R0; break;
  179.          }
  180.             Scan();
  181.          break;
  182.          default: *XP = '.', *EP++ = Parse(2); break;
  183.       }
  184.       L = OldL;
  185.       if (XP++ >= XBuf + A_MAX) {
  186.          ERROR("Too many arguments specified."); return;
  187.          while (L != SEMI && L != 0) L = Scan();
  188.          break;
  189.       }
  190.    } while (L == COMMA);
  191.    if (!Active) return;
  192.    *XP = 0, *EP = 0;
  193.    CP = CodeTab + Mnem;
  194.    for (MP = CP->Start; MP < CP->Start + CP->Modes; MP++)
  195.       if (strcmp(XBuf, MP->X) == 0) break;
  196.    if (MP >= CP->Start + CP->Modes) {
  197.       ERROR("Invalid addressing mode: %s.", CP->Name); return;
  198.    }
  199.    Op = MP->OpCode;
  200.    S = MP->Y, EP = XExp;
  201.    switch (*S) {
  202.       case 'n': S++; Op |= XReg&7; break;/* Register R0/R1/R2/R3/R4/R5/R6/R7 */
  203.       case 'i': S++; Op |= XReg&1; break;/* Register Pointer @R0/@R1 */
  204.       case 'x': E = EP[0], EP[0] = EP[1], EP[1] = E; S++; break;
  205.       case 'P': Reloc(Op, 'P', *EP++); return; /* P Paged Address */
  206.    }
  207.    PByte(Op);
  208.    for (; *S != 0; S++) Reloc(0, *S, *EP++);
  209. }
  210.