Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***********************************************************************
  2.  *
  3.  *  avra - Assembler for the Atmel AVR microcontroller series
  4.  *
  5.  *  Copyright (C) 1998-2004 Jon Anders Haugum, Tobias Weber
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; see the file COPYING.  If not, write to
  19.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  *  Boston, MA 02111-1307, USA.
  21.  *
  22.  *
  23.  *  Authors of avra can be reached at:
  24.  *     email: jonah@omegav.ntnu.no, tobiw@suprafluid.com
  25.  *     www: http://sourceforge.net/projects/avra
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32.  
  33. #include "misc.h"
  34. #include "avra.h"
  35. #include "device.h"
  36.  
  37. #define MAX_MNEMONIC_LEN        8       // Maximum mnemonic length
  38.  
  39. enum {
  40.         MNEMONIC_NOP = 0,  //          0000 0000 0000 0000
  41.         MNEMONIC_SEC,      //          1001 0100 0000 1000
  42.         MNEMONIC_CLC,      //          1001 0100 1000 1000
  43.         MNEMONIC_SEN,      //          1001 0100 0010 1000
  44.         MNEMONIC_CLN,      //          1001 0100 1010 1000
  45.         MNEMONIC_SEZ,      //          1001 0100 0001 1000
  46.         MNEMONIC_CLZ,      //          1001 0100 1001 1000
  47.         MNEMONIC_SEI,      //          1001 0100 0111 1000
  48.         MNEMONIC_CLI,      //          1001 0100 1111 1000
  49.         MNEMONIC_SES,      //          1001 0100 0100 1000
  50.         MNEMONIC_CLS,      //          1001 0100 1100 1000
  51.         MNEMONIC_SEV,      //          1001 0100 0011 1000
  52.         MNEMONIC_CLV,      //          1001 0100 1011 1000
  53.         MNEMONIC_SET,      //          1001 0100 0110 1000
  54.         MNEMONIC_CLT,      //          1001 0100 1110 1000
  55.         MNEMONIC_SEH,      //          1001 0100 0101 1000
  56.         MNEMONIC_CLH,      //          1001 0100 1101 1000
  57.         MNEMONIC_SLEEP,    //          1001 0101 1000 1000
  58.         MNEMONIC_WDR,      //          1001 0101 1010 1000
  59.         MNEMONIC_IJMP,     //          1001 0100 0000 1001
  60.         MNEMONIC_EIJMP,    //          1001 0100 0001 1001
  61.         MNEMONIC_ICALL,    //          1001 0101 0000 1001
  62.         MNEMONIC_EICALL,   //          1001 0101 0001 1001
  63.         MNEMONIC_RET,      //          1001 0101 0000 1000
  64.         MNEMONIC_RETI,     //          1001 0101 0001 1000
  65.         MNEMONIC_SPM,      //          1001 0101 1110 1000
  66.         MNEMONIC_ESPM,     //          1001 0101 1111 1000
  67.         MNEMONIC_BREAK,    //          1001 0101 1001 1000
  68.         MNEMONIC_LPM,      //          1001 0101 1100 1000
  69.         MNEMONIC_ELPM,     //          1001 0101 1101 1000
  70.         MNEMONIC_BSET,     // s        1001 0100 0sss 1000
  71.         MNEMONIC_BCLR,     // s        1001 0100 1sss 1000
  72.         MNEMONIC_SER,      // Rd       1110 1111 dddd 1111
  73.         MNEMONIC_COM,      // Rd       1001 010d dddd 0000
  74.         MNEMONIC_NEG,      // Rd       1001 010d dddd 0001
  75.         MNEMONIC_INC,      // Rd       1001 010d dddd 0011
  76.         MNEMONIC_DEC,      // Rd       1001 010d dddd 1010
  77.         MNEMONIC_LSR,      // Rd       1001 010d dddd 0110
  78.         MNEMONIC_ROR,      // Rd       1001 010d dddd 0111
  79.         MNEMONIC_ASR,      // Rd       1001 010d dddd 0101
  80.         MNEMONIC_SWAP,     // Rd       1001 010d dddd 0010
  81.         MNEMONIC_PUSH,     // Rr       1001 001r rrrr 1111
  82.         MNEMONIC_POP,      // Rd       1001 000d dddd 1111
  83.         MNEMONIC_TST,      // Rd       0010 00dd dddd dddd
  84.         MNEMONIC_CLR,      // Rd       0010 01dd dddd dddd
  85.         MNEMONIC_LSL,      // Rd       0000 11dd dddd dddd
  86.         MNEMONIC_ROL,      // Rd       0001 11dd dddd dddd
  87.         MNEMONIC_BREQ,     // k        1111 00kk kkkk k001
  88.         MNEMONIC_BRNE,     // k        1111 01kk kkkk k001
  89.         MNEMONIC_BRCS,     // k        1111 00kk kkkk k000
  90.         MNEMONIC_BRCC,     // k        1111 01kk kkkk k000
  91.         MNEMONIC_BRSH,     // k        1111 01kk kkkk k000
  92.         MNEMONIC_BRLO,     // k        1111 00kk kkkk k000
  93.         MNEMONIC_BRMI,     // k        1111 00kk kkkk k010
  94.         MNEMONIC_BRPL,     // k        1111 01kk kkkk k010
  95.         MNEMONIC_BRGE,     // k        1111 01kk kkkk k100
  96.         MNEMONIC_BRLT,     // k        1111 00kk kkkk k100
  97.         MNEMONIC_BRHS,     // k        1111 00kk kkkk k101
  98.         MNEMONIC_BRHC,     // k        1111 01kk kkkk k101
  99.         MNEMONIC_BRTS,     // k        1111 00kk kkkk k110
  100.         MNEMONIC_BRTC,     // k        1111 01kk kkkk k110
  101.         MNEMONIC_BRVS,     // k        1111 00kk kkkk k011
  102.         MNEMONIC_BRVC,     // k        1111 01kk kkkk k011
  103.         MNEMONIC_BRIE,     // k        1111 00kk kkkk k111
  104.         MNEMONIC_BRID,     // k        1111 01kk kkkk k111
  105.         MNEMONIC_RJMP,     // k        1100 kkkk kkkk kkkk
  106.         MNEMONIC_RCALL,    // k        1101 kkkk kkkk kkkk
  107.         MNEMONIC_JMP,      // k        1001 010k kkkk 110k + 16k
  108.         MNEMONIC_CALL,     // k        1001 010k kkkk 111k + 16k
  109.         MNEMONIC_BRBS,     // s, k     1111 00kk kkkk ksss
  110.         MNEMONIC_BRBC,     // s, k     1111 01kk kkkk ksss
  111.         MNEMONIC_ADD,      // Rd, Rr   0000 11rd dddd rrrr
  112.         MNEMONIC_ADC,      // Rd, Rr   0001 11rd dddd rrrr
  113.         MNEMONIC_SUB,      // Rd, Rr   0001 10rd dddd rrrr
  114.         MNEMONIC_SBC,      // Rd, Rr   0000 10rd dddd rrrr
  115.         MNEMONIC_AND,      // Rd, Rr   0010 00rd dddd rrrr
  116.         MNEMONIC_OR,       // Rd, Rr   0010 10rd dddd rrrr
  117.         MNEMONIC_EOR,      // Rd, Rr   0010 01rd dddd rrrr
  118.         MNEMONIC_CP,       // Rd, Rr   0001 01rd dddd rrrr
  119.         MNEMONIC_CPC,      // Rd, Rr   0000 01rd dddd rrrr
  120.         MNEMONIC_CPSE,     // Rd, Rr   0001 00rd dddd rrrr
  121.         MNEMONIC_MOV,      // Rd, Rr   0010 11rd dddd rrrr
  122.         MNEMONIC_MUL,      // Rd, Rr   1001 11rd dddd rrrr
  123.         MNEMONIC_MOVW,     // Rd, Rr   0000 0001 dddd rrrr
  124.         MNEMONIC_MULS,     // Rd, Rr   0000 0010 dddd rrrr
  125.         MNEMONIC_MULSU,    // Rd, Rr   0000 0011 0ddd 0rrr
  126.         MNEMONIC_FMUL,     // Rd, Rr   0000 0011 0ddd 1rrr
  127.         MNEMONIC_FMULS,    // Rd, Rr   0000 0011 1ddd 0rrr
  128.         MNEMONIC_FMULSU,   // Rd, Rr   0000 0011 1ddd 1rrr
  129.         MNEMONIC_ADIW,     // Rd, K    1001 0110 KKdd KKKK
  130.         MNEMONIC_SBIW,     // Rd, K    1001 0111 KKdd KKKK
  131.         MNEMONIC_SUBI,     // Rd, K    0101 KKKK dddd KKKK
  132.         MNEMONIC_SBCI,     // Rd, K    0100 KKKK dddd KKKK
  133.         MNEMONIC_ANDI,     // Rd, K    0111 KKKK dddd KKKK
  134.         MNEMONIC_ORI,      // Rd, K    0110 KKKK dddd KKKK
  135.         MNEMONIC_SBR,      // Rd, K    0110 KKKK dddd KKKK
  136.         MNEMONIC_CPI,      // Rd, K    0011 KKKK dddd KKKK
  137.         MNEMONIC_LDI,      // Rd, K    1110 KKKK dddd KKKK
  138.         MNEMONIC_CBR,      // Rd, K    0111 KKKK dddd KKKK ~K
  139.         MNEMONIC_SBRC,     // Rr, b    1111 110r rrrr 0bbb
  140.         MNEMONIC_SBRS,     // Rr, b    1111 111r rrrr 0bbb
  141.         MNEMONIC_BST,      // Rr, b    1111 101d dddd 0bbb
  142.         MNEMONIC_BLD,      // Rd, b    1111 100d dddd 0bbb
  143.         MNEMONIC_IN,       // Rd, P    1011 0PPd dddd PPPP
  144.         MNEMONIC_OUT,      // P, Rr    1011 1PPr rrrr PPPP
  145.         MNEMONIC_SBIC,     // P, b     1001 1001 PPPP Pbbb
  146.         MNEMONIC_SBIS,     // P, b     1001 1011 PPPP Pbbb
  147.         MNEMONIC_SBI,      // P, b     1001 1010 PPPP Pbbb
  148.         MNEMONIC_CBI,      // P, b     1001 1000 PPPP Pbbb
  149.         MNEMONIC_LDS,      // Rd, k    1001 000d dddd 0000 + 16k
  150.         MNEMONIC_STS,      // k, Rr    1001 001d dddd 0000 + 16k
  151.         MNEMONIC_LD,       // Rd, __   dummy
  152.         MNEMONIC_ST,       // __, Rr   dummy
  153.         MNEMONIC_LDD,      // Rd, _+q  dummy
  154.         MNEMONIC_STD,      // _+q, Rr  dummy
  155.         MNEMONIC_COUNT,
  156.         MNEMONIC_LPM_Z,    // Rd, Z    1001 000d dddd 0100
  157.         MNEMONIC_LPM_ZP,   // Rd, Z+   1001 000d dddd 0101
  158.         MNEMONIC_ELPM_Z,   // Rd, Z    1001 000d dddd 0110
  159.         MNEMONIC_ELPM_ZP,  // Rd, Z+   1001 000d dddd 0111
  160.         MNEMONIC_LD_X,     // Rd, X    1001 000d dddd 1100
  161.         MNEMONIC_LD_XP,    // Rd, X+   1001 000d dddd 1101
  162.         MNEMONIC_LD_MX,    // Rd, -X   1001 000d dddd 1110
  163.         MNEMONIC_LD_Y,     // Rd, Y    1000 000d dddd 1000
  164.         MNEMONIC_LD_YP,    // Rd, Y+   1001 000d dddd 1001
  165.         MNEMONIC_LD_MY,    // Rd, -Y   1001 000d dddd 1010
  166.         MNEMONIC_LD_Z,     // Rd, Z    1000 000d dddd 0000
  167.         MNEMONIC_LD_ZP,    // Rd, Z+   1001 000d dddd 0001
  168.         MNEMONIC_LD_MZ,    // Rd, -Z   1001 000d dddd 0010
  169.         MNEMONIC_ST_X,     // X, Rr    1001 001d dddd 1100
  170.         MNEMONIC_ST_XP,    // X+, Rr   1001 001d dddd 1101
  171.         MNEMONIC_ST_MX,    // -X, Rr   1001 001d dddd 1110
  172.         MNEMONIC_ST_Y,     // Y, Rr    1000 001d dddd 1000
  173.         MNEMONIC_ST_YP,    // Y+, Rr   1001 001d dddd 1001
  174.         MNEMONIC_ST_MY,    // -Y, Rr   1001 001d dddd 1010
  175.         MNEMONIC_ST_Z,     // Z, Rr    1000 001d dddd 0000
  176.         MNEMONIC_ST_ZP,    // Z+, Rr   1001 001d dddd 0001
  177.         MNEMONIC_ST_MZ,    // -Z, Rr   1001 001d dddd 0010
  178.         MNEMONIC_LDD_Y,    // Rd, Y+q  10q0 qq0d dddd 1qqq
  179.         MNEMONIC_LDD_Z,    // Rd, Z+q  10q0 qq0d dddd 0qqq
  180.         MNEMONIC_STD_Y,    // Y+q, Rr  10q0 qq1r rrrr 1qqq
  181.         MNEMONIC_STD_Z,    // Z+q, Rr  10q0 qq1r rrrr 0qqq
  182.         MNEMONIC_END
  183. };
  184.  
  185. struct instruction {
  186.         char *mnemonic;
  187.         int opcode;
  188.         int flag;       /* Device flags meaning the instruction is not
  189.                            supported */
  190. };
  191.  
  192. struct instruction instruction_list[] = {
  193.         {"nop",   0x0000,          0},
  194.         {"sec",   0x9408,          0},
  195.         {"clc",   0x9488,          0},
  196.         {"sen",   0x9428,          0},
  197.         {"cln",   0x94a8,          0},
  198.         {"sez",   0x9418,          0},
  199.         {"clz",   0x9498,          0},
  200.         {"sei",   0x9478,          0},
  201.         {"cli",   0x94f8,          0},
  202.         {"ses",   0x9448,          0},
  203.         {"cls",   0x94c8,          0},
  204.         {"sev",   0x9438,          0},
  205.         {"clv",   0x94b8,          0},
  206.         {"set",   0x9468,          0},
  207.         {"clt",   0x94e8,          0},
  208.         {"seh",   0x9458,          0},
  209.         {"clh",   0x94d8,          0},
  210.         {"sleep", 0x9588,          0},
  211.         {"wdr",   0x95a8,          0},
  212.         {"ijmp",  0x9409,  DF_TINY1X},
  213.         {"eijmp", 0x9419, DF_NO_EIJMP},
  214.         {"icall", 0x9509,  DF_TINY1X},
  215.         {"eicall",0x9519, DF_NO_EICALL},
  216.         {"ret",   0x9508,          0},
  217.         {"reti",  0x9518,          0},
  218.         {"spm",   0x95e8, DF_NO_SPM},
  219.         {"espm",  0x95f8, DF_NO_ESPM},
  220.         {"break", 0x9598, DF_NO_BREAK},
  221.         {"lpm",   0x95c8, DF_NO_LPM},
  222.         {"elpm",  0x95d8, DF_NO_ELPM},
  223.         {"bset",  0x9408,          0},
  224.         {"bclr",  0x9488,          0},
  225.         {"ser",   0xef0f,          0},
  226.         {"com",   0x9400,          0},
  227.         {"neg",   0x9401,          0},
  228.         {"inc",   0x9403,          0},
  229.         {"dec",   0x940a,          0},
  230.         {"lsr",   0x9406,          0},
  231.         {"ror",   0x9407,          0},
  232.         {"asr",   0x9405,          0},
  233.         {"swap",  0x9402,          0},
  234.         {"push",  0x920f,  DF_TINY1X},
  235.         {"pop",   0x900f,  DF_TINY1X},
  236.         {"tst",   0x2000,          0},
  237.         {"clr",   0x2400,          0},
  238.         {"lsl",   0x0c00,          0},
  239.         {"rol",   0x1c00,          0},
  240.         {"breq",  0xf001,          0},
  241.         {"brne",  0xf401,          0},
  242.         {"brcs",  0xf000,          0},
  243.         {"brcc",  0xf400,          0},
  244.         {"brsh",  0xf400,          0},
  245.         {"brlo",  0xf000,          0},
  246.         {"brmi",  0xf002,          0},
  247.         {"brpl",  0xf402,          0},
  248.         {"brge",  0xf404,          0},
  249.         {"brlt",  0xf004,          0},
  250.         {"brhs",  0xf005,          0},
  251.         {"brhc",  0xf405,          0},
  252.         {"brts",  0xf006,          0},
  253.         {"brtc",  0xf406,          0},
  254.         {"brvs",  0xf003,          0},
  255.         {"brvc",  0xf403,          0},
  256.         {"brie",  0xf007,          0},
  257.         {"brid",  0xf407,          0},
  258.         {"rjmp",  0xc000,          0},
  259.         {"rcall", 0xd000,          0},
  260.         {"jmp",   0x940c,  DF_NO_JMP},
  261.         {"call",  0x940e,  DF_NO_JMP},
  262.         {"brbs",  0xf000,          0},
  263.         {"brbc",  0xf400,          0},
  264.         {"add",   0x0c00,          0},
  265.         {"adc",   0x1c00,          0},
  266.         {"sub",   0x1800,          0},
  267.         {"sbc",   0x0800,          0},
  268.         {"and",   0x2000,          0},
  269.         {"or",    0x2800,          0},
  270.         {"eor",   0x2400,          0},
  271.         {"cp",    0x1400,          0},
  272.         {"cpc",   0x0400,          0},
  273.         {"cpse",  0x1000,          0},
  274.         {"mov",   0x2c00,          0},
  275.         {"mul",   0x9c00, DF_NO_MUL},
  276.         {"movw",  0x0100, DF_NO_MOVW},
  277.         {"muls",  0x0200, DF_NO_MUL},
  278.         {"mulsu", 0x0300, DF_NO_MUL},
  279.         {"fmul",  0x0308, DF_NO_MUL},
  280.         {"fmuls", 0x0380, DF_NO_MUL},
  281.         {"fmulsu",0x0388, DF_NO_MUL},
  282.         {"adiw",  0x9600,  DF_TINY1X},
  283.         {"sbiw",  0x9700,  DF_TINY1X},
  284.         {"subi",  0x5000,          0},
  285.         {"sbci",  0x4000,          0},
  286.         {"andi",  0x7000,          0},
  287.         {"ori",   0x6000,          0},
  288.         {"sbr",   0x6000,          0},
  289.         {"cpi",   0x3000,          0},
  290.         {"ldi",   0xe000,          0},
  291.         {"cbr",   0x7000,          0},
  292.         {"sbrc",  0xfc00,          0},
  293.         {"sbrs",  0xfe00,          0},
  294.         {"bst",   0xfa00,          0},
  295.         {"bld",   0xf800,          0},
  296.         {"in",    0xb000,          0},
  297.         {"out",   0xb800,          0},
  298.         {"sbic",  0x9900,          0},
  299.         {"sbis",  0x9b00,          0},
  300.         {"sbi",   0x9a00,          0},
  301.         {"cbi",   0x9800,          0},
  302.         {"lds",   0x9000,  DF_TINY1X},
  303.         {"sts",   0x9200,  DF_TINY1X},
  304.         {"ld",    0,          0},
  305.         {"st",    0,          0},
  306.         {"ldd",   0,  DF_TINY1X},
  307.         {"std",   0,  DF_TINY1X},
  308.         {"count", 0,          0},
  309.         {"lpm",   0x9004, DF_NO_LPM|DF_NO_LPM_X},
  310.         {"lpm",   0x9005, DF_NO_LPM|DF_NO_LPM_X},
  311.         {"elpm",  0x9006, DF_NO_ELPM|DF_NO_ELPM_X},
  312.         {"elpm",  0x9007, DF_NO_ELPM|DF_NO_ELPM_X},
  313.         {"ld",    0x900c, DF_NO_XREG},
  314.         {"ld",    0x900d, DF_NO_XREG},
  315.         {"ld",    0x900e, DF_NO_XREG},
  316.         {"ld",    0x8008, DF_NO_YREG},
  317.         {"ld",    0x9009, DF_NO_YREG},
  318.         {"ld",    0x900a, DF_NO_YREG},
  319.         {"ld",    0x8000,          0},
  320.         {"ld",    0x9001, DF_TINY1X},
  321.         {"ld",    0x9002, DF_TINY1X},
  322.         {"st",    0x920c, DF_NO_XREG},
  323.         {"st",    0x920d, DF_NO_XREG},
  324.         {"st",    0x920e, DF_NO_XREG},
  325.         {"st",    0x8208, DF_NO_YREG},
  326.         {"st",    0x9209, DF_NO_YREG},
  327.         {"st",    0x920a, DF_NO_YREG},
  328.         {"st",    0x8200,          0},
  329.         {"st",    0x9201, DF_TINY1X},
  330.         {"st",    0x9202, DF_TINY1X},
  331.         {"ldd",   0x8008, DF_TINY1X},
  332.         {"ldd",   0x8000, DF_TINY1X},
  333.         {"std",   0x8208, DF_TINY1X},
  334.         {"std",   0x8200, DF_TINY1X},
  335.         {"end", 0, 0}
  336.         };
  337.  
  338.  
  339. /* We try to parse the command name. Is it a assembler mnemonic or anything else ?
  340.  * If so, it may be a macro.
  341. */
  342.  
  343. int parse_mnemonic(struct prog_info *pi)
  344. {
  345.   int mnemonic;
  346.   int i;
  347.   int opcode = 0;
  348.   int opcode2 = 0;
  349.   int instruction_long = False;
  350.   char *operand1;
  351.   char *operand2;
  352.   struct macro *macro;
  353.   char temp[MAX_MNEMONIC_LEN + 1];
  354.  
  355.   operand1 = get_next_token(pi->fi->scratch, TERM_SPACE);  // we get the first word on line
  356.   mnemonic = get_mnemonic_type(my_strlwr(pi->fi->scratch));
  357.   if(mnemonic == -1) {                          // if -1 this must be a macro name
  358.         macro = get_macro(pi, pi->fi->scratch); // and so, we try to get the corresponding macro struct.
  359.         if(macro) {
  360.                 return(expand_macro(pi, macro, operand1)); // we expand the macro
  361.         } else {                                // if we cant find a name, this is a unknown word.
  362.                 print_msg(pi, MSGTYPE_ERROR, "Unknown mnemonic/macro: %s", pi->fi->scratch);
  363.                 return(True);
  364.         }
  365.   }
  366.   if(pi->pass == PASS_2) {
  367.         if(mnemonic <= MNEMONIC_BREAK) {
  368.                 if(operand1) {
  369.                         print_msg(pi, MSGTYPE_WARNING, "Garbage after instruction %s: %s", instruction_list[mnemonic].mnemonic, operand1);
  370.                 }
  371.                 opcode = 0;                     // No operand
  372.         } else if(mnemonic <= MNEMONIC_ELPM) {
  373.                 if(operand1) {
  374.                         operand2 = get_next_token(operand1, TERM_COMMA);
  375.                         if(!operand2) {
  376.                                 print_msg(pi, MSGTYPE_ERROR, "%s needs a second operand", instruction_list[mnemonic].mnemonic);
  377.                                 return(True);
  378.                         }
  379.                         get_next_token(operand2, TERM_END);
  380.                         i = get_register(pi, operand1);
  381.                         opcode = i << 4;
  382.                         i = get_indirect(pi, operand2);
  383.                         if(i == 6) { // Means Z
  384.                                 if(mnemonic == MNEMONIC_LPM)
  385.                                         mnemonic = MNEMONIC_LPM_Z;
  386.                                 else if(mnemonic == MNEMONIC_ELPM)
  387.                                         mnemonic = MNEMONIC_ELPM_Z;
  388.                         } else if(i == 7) { // Means Z+
  389.                                 if(mnemonic == MNEMONIC_LPM)
  390.                                         mnemonic = MNEMONIC_LPM_ZP;
  391.                                 else if(mnemonic == MNEMONIC_ELPM)
  392.                                         mnemonic = MNEMONIC_ELPM_ZP;
  393.                         } else {
  394.                                 print_msg(pi, MSGTYPE_ERROR, "Unsupported operand: %s", operand2);
  395.                                 return(True);
  396.                         }
  397.                 } else
  398.                         opcode = 0;
  399.         } else {
  400.                 if(!operand1) {
  401.                         print_msg(pi, MSGTYPE_ERROR, "%s needs an operand", instruction_list[mnemonic].mnemonic);
  402.                         return(True);
  403.                 }
  404.                 operand2 = get_next_token(operand1, TERM_COMMA);
  405.                 if(mnemonic >= MNEMONIC_BRBS) {
  406.                         if(!operand2) {
  407.                                 print_msg(pi, MSGTYPE_ERROR, "%s needs a second operand", instruction_list[mnemonic].mnemonic);
  408.                                 return(True);
  409.                         }
  410.                         get_next_token(operand2, TERM_END);
  411.                 }
  412.                 if(mnemonic <= MNEMONIC_BCLR) {
  413.                         if(!get_bitnum(pi, operand1, &i))
  414.                                 return(False);
  415.                         opcode = i << 4;
  416.                 } else if(mnemonic <= MNEMONIC_ROL) {
  417.                         i = get_register(pi, operand1);
  418.                         if((mnemonic == MNEMONIC_SER) && (i < 16)) {
  419.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic);
  420.                                 i &= 0x0f;
  421.                         }
  422.                         opcode = i << 4;
  423.                         if(mnemonic >= MNEMONIC_TST)
  424.                                 opcode |= ((i & 0x10) << 5) | (i & 0x0f);
  425.                 } else if(mnemonic <= MNEMONIC_RCALL) {
  426.                         if(!get_expr(pi, operand1, &i))
  427.                                 return(False);
  428.                         i -= pi->cseg_addr + 1;
  429.                         if(mnemonic <= MNEMONIC_BRID) {
  430.                                 if((i < -64) || (i > 63))
  431.                                         print_msg(pi, MSGTYPE_ERROR, "Branch out of range (-64 <= k <= 63)");
  432.                                 opcode = (i & 0x7f) << 3;
  433.                         } else {
  434.                                 if(((i < -2048) || (i > 2047)) && (pi->device->flash_size != 4096))
  435.                                         print_msg(pi, MSGTYPE_ERROR, "Relative address out of range (-2048 <= k <= 2047)");
  436.                                 opcode = i & 0x0fff;
  437.                         }
  438.                 } else if(mnemonic <= MNEMONIC_CALL) {
  439.                         if(!get_expr(pi, operand1, &i))
  440.                                 return(False);
  441.                         if((i < 0) || (i > 4194303))
  442.                                 print_msg(pi, MSGTYPE_ERROR, "Address out of range (0 <= k <= 4194303)");
  443.                         opcode = ((i & 0x3e0000) >> 13) | ((i & 0x010000) >> 16);
  444.                         opcode2 = i & 0xffff;
  445.                         instruction_long = True;
  446.                 } else if(mnemonic <= MNEMONIC_BRBC) {
  447.                         if(!get_bitnum(pi, operand1, &i))
  448.                                 return(False);
  449.                         opcode = i;
  450.                         if(!get_expr(pi, operand2, &i))
  451.                                 return(False);
  452.                         i -= pi->cseg_addr + 1;
  453.                         if((i < -64) || (i > 63))
  454.                                 print_msg(pi, MSGTYPE_ERROR, "Branch out of range (-64 <= k <= 63)");
  455.                         opcode |= (i & 0x7f) << 3;
  456.                 } else if(mnemonic <= MNEMONIC_MUL) {
  457.                         i = get_register(pi, operand1);
  458.                         opcode = i << 4;
  459.                         i = get_register(pi, operand2);
  460.                         opcode |= ((i & 0x10) << 5) | (i & 0x0f);
  461.                 } else if(mnemonic <= MNEMONIC_MOVW) {
  462.                         i = get_register(pi, operand1);
  463.                         if((i % 2) == 1)
  464.                                 print_msg(pi, MSGTYPE_ERROR, "%s must use a even numbered register for Rd", instruction_list[mnemonic].mnemonic);
  465.                         opcode = (i / 2) << 4;
  466.                         i = get_register(pi, operand2);
  467.                         if((i % 2) == 1)
  468.                                 print_msg(pi, MSGTYPE_ERROR, "%s must use a even numbered register for Rr", instruction_list[mnemonic].mnemonic);
  469.                         opcode |= i / 2;
  470.                 } else if(mnemonic <= MNEMONIC_MULS) {
  471.                         i = get_register(pi, operand1);
  472.                         if(i < 16)
  473.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic);
  474.                         opcode = (i & 0x0f) << 4;
  475.                         i = get_register(pi, operand2);
  476.                         if(i < 16)
  477.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic);
  478.                         opcode |= (i & 0x0f);
  479.                 } else if(mnemonic <= MNEMONIC_FMULSU) {
  480.                         i = get_register(pi, operand1);
  481.                         if((i < 16) || (i >= 24))
  482.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use registers (r16 - r23)", instruction_list[mnemonic].mnemonic);
  483.                         opcode = (i & 0x07) << 4;
  484.                         i = get_register(pi, operand2);
  485.                         if((i < 16) || (i >= 24))
  486.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use registers (r16 - r23)", instruction_list[mnemonic].mnemonic);
  487.                         opcode |= (i & 0x07);
  488.                 } else if(mnemonic <= MNEMONIC_SBIW) {
  489.                         i = get_register(pi, operand1);
  490.                         if(!((i == 24) || (i == 26) || (i == 28) || (i == 30)))
  491.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use registers R24, R26, R28 or R30", instruction_list[mnemonic].mnemonic);
  492.                         opcode = ((i - 24) / 2) << 4;
  493.                         if(!get_expr(pi, operand2, &i))
  494.                         return(False);
  495.                         if((i < 0) || (i > 63))
  496.                                 print_msg(pi, MSGTYPE_ERROR, "Constant out of range (0 <= k <= 63)");
  497.                         opcode |= ((i & 0x30) << 2) | (i & 0x0f);
  498.                 } else if(mnemonic <= MNEMONIC_CBR) {
  499.                         i = get_register(pi, operand1);
  500.                         if(i < 16)
  501.                                 print_msg(pi, MSGTYPE_ERROR, "%s can only use a high register (r16 - r31)", instruction_list[mnemonic].mnemonic);
  502.                         opcode = (i & 0x0f) << 4;
  503.                         if(!get_expr(pi, operand2, &i))
  504.                                 return(False);
  505.                         if((i < -128) || (i > 255))
  506.                                 print_msg(pi, MSGTYPE_WARNING, "Constant out of range (-128 <= k <= 255). Will be masked");
  507.                         if(mnemonic == MNEMONIC_CBR)
  508.                                 i = ~i;
  509.                         opcode |= ((i & 0xf0) << 4) | (i & 0x0f);
  510.                 } else if(mnemonic <= MNEMONIC_BLD) {
  511.                         i = get_register(pi, operand1);
  512.                         opcode = i << 4;
  513.                         if(!get_bitnum(pi, operand2, &i))
  514.                                 return(False);
  515.                         opcode |= i;
  516.                 } else if(mnemonic == MNEMONIC_IN) {
  517.                         i = get_register(pi, operand1);
  518.                         opcode = i << 4;
  519.                         if(!get_expr(pi, operand2, &i))
  520.                                 return(False);
  521.                         if((i < 0) || (i > 63))
  522.                                 print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 63)");
  523.                         opcode |= ((i & 0x30) << 5) | (i & 0x0f);
  524.                 } else if(mnemonic == MNEMONIC_OUT) {
  525.                         if(!get_expr(pi, operand1, &i))
  526.                                 return(False);
  527.                         if((i < 0) || (i > 63))
  528.                                 print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 63)");
  529.                         opcode = ((i & 0x30) << 5) | (i & 0x0f);
  530.                         i = get_register(pi, operand2);
  531.                         opcode |= i << 4;
  532.                 } else if(mnemonic <= MNEMONIC_CBI) {
  533.                         if(!get_expr(pi, operand1, &i))
  534.                                 return(False);
  535.                         if((i < 0) || (i > 31))
  536.                                 print_msg(pi, MSGTYPE_ERROR, "I/O out of range (0 <= P <= 31)");
  537.                         opcode = i << 3;
  538.                         if(!get_bitnum(pi, operand2, &i))
  539.                                 return(False);
  540.                         opcode |= i;
  541.                 } else if(mnemonic == MNEMONIC_LDS) {
  542.                         i = get_register(pi, operand1);
  543.                         opcode = i << 4;
  544.                         if(!get_expr(pi, operand2, &i))
  545.                                 return(False);
  546.                         if((i < 0) || (i > 65535))
  547.                                 print_msg(pi, MSGTYPE_ERROR, "SRAM out of range (0 <= k <= 65535)");
  548.                         opcode2 = i;
  549.                         instruction_long = True;
  550.                 } else if(mnemonic == MNEMONIC_STS) {
  551.                         if(!get_expr(pi, operand1, &i))
  552.                                 return(False);
  553.                         if((i < 0) || (i > 65535))
  554.                                 print_msg(pi, MSGTYPE_ERROR, "SRAM out of range (0 <= k <= 65535)");
  555.                         opcode2 = i;
  556.                         i = get_register(pi, operand2);
  557.                         opcode = i << 4;
  558.                         instruction_long = True;
  559.                 } else if(mnemonic == MNEMONIC_LD) {
  560.                         i = get_register(pi, operand1);
  561.                         opcode = i << 4;
  562.                         mnemonic = MNEMONIC_LD_X + get_indirect(pi, operand2);
  563.                 } else if(mnemonic == MNEMONIC_ST) {
  564.                         mnemonic = MNEMONIC_ST_X + get_indirect(pi, operand1);
  565.                         i = get_register(pi, operand2);
  566.                         opcode = i << 4;
  567.                 } else if(mnemonic == MNEMONIC_LDD) {
  568.                         i = get_register(pi, operand1);
  569.                         opcode = i << 4;
  570.                         if(tolower(operand2[0]) == 'z')
  571.                                 mnemonic = MNEMONIC_LDD_Z;
  572.                         else if(tolower(operand2[0]) == 'y')
  573.                                         mnemonic = MNEMONIC_LDD_Y;
  574.                                 else
  575.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in second operand (%s)", operand2);
  576.                         i = 1;
  577.                         while((operand2[i] != '\0') && (operand2[i] != '+')) i++;
  578.                         if(operand2[i] == '\0') {
  579.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage in second operand (%s)", operand2);
  580.                                 return(False);
  581.                         }
  582.                         if(!get_expr(pi, &operand2[i + 1], &i))
  583.                                 return(False);
  584.                         if((i < 0) || (i > 63))
  585.                                 print_msg(pi, MSGTYPE_ERROR, "Displacement out of range (0 <= q <= 63)");
  586.                         opcode |= ((i & 0x20) << 8) | ((i & 0x18) << 7) | (i & 0x07);
  587.                 } else if(mnemonic == MNEMONIC_STD) {
  588.                         if(tolower(operand1[0]) == 'z')
  589.                                 mnemonic = MNEMONIC_STD_Z;
  590.                         else if(tolower(operand1[0]) == 'y')
  591.                                         mnemonic = MNEMONIC_STD_Y;
  592.                                 else
  593.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in first operand (%s)", operand1);
  594.                         i = 1;
  595.                         while((operand1[i] != '\0') && (operand1[i] != '+')) i++;
  596.                         if(operand1[i] == '\0') {
  597.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage in first operand (%s)", operand1);
  598.                                 return(False);
  599.                         }
  600.                         if(!get_expr(pi, &operand1[i + 1], &i))
  601.                                 return(False);
  602.                         if((i < 0) || (i > 63))
  603.                                 print_msg(pi, MSGTYPE_ERROR, "Displacement out of range (0 <= q <= 63)");
  604.                         opcode = ((i & 0x20) << 8) | ((i & 0x18) << 7) | (i & 0x07);
  605.                         i = get_register(pi, operand2);
  606.                         opcode |= i << 4;
  607.                 } else
  608.                         print_msg(pi, MSGTYPE_ERROR, "Shit! Missing opcode check [%d]...", mnemonic);
  609.         }
  610.         if (pi->device->flag & instruction_list[mnemonic].flag) {
  611.                 strncpy(temp, instruction_list[mnemonic].mnemonic, MAX_MNEMONIC_LEN);
  612.                 print_msg(pi, MSGTYPE_ERROR, "%s instruction is not supported on %s",
  613.                           my_strupr(temp), pi->device->name);
  614.         }
  615.         opcode |= instruction_list[mnemonic].opcode;
  616.         if(pi->list_on && pi->list_line) {
  617.                 if(instruction_long)
  618.                         fprintf(pi->list_file, "C:%06x %04x %04x %s\n", pi->cseg_addr, opcode, opcode2, pi->list_line);
  619.                 else
  620.                         fprintf(pi->list_file, "C:%06x %04x      %s\n", pi->cseg_addr, opcode, pi->list_line);
  621.                 pi->list_line = NULL;
  622.         }
  623.         if(pi->hfi) {
  624.                 write_prog_word(pi, pi->cseg_addr, opcode);
  625.                 if(instruction_long)
  626.                         write_prog_word(pi, pi->cseg_addr + 1, opcode2);
  627.         }
  628.         if(instruction_long)
  629.                 pi->cseg_addr += 2;
  630.         else
  631.                 pi->cseg_addr++;
  632.   } else { // Pass 1
  633.         if((mnemonic == MNEMONIC_JMP) || (mnemonic == MNEMONIC_CALL)
  634.                 || (mnemonic == MNEMONIC_LDS) || (mnemonic == MNEMONIC_STS)) {
  635.                 pi->cseg_addr += 2;
  636.                 pi->cseg_count += 2;
  637.         } else {
  638.                 pi->cseg_addr++;
  639.                 pi->cseg_count++;
  640.         }
  641.   }
  642.   return(True);
  643. }
  644.  
  645.  
  646. int get_mnemonic_type(char *mnemonic)
  647. {
  648.         int i;
  649.  
  650.         for(i = 0; i < MNEMONIC_COUNT; i++) {
  651.                 if(!strcmp(mnemonic, instruction_list[i].mnemonic)) {
  652.                         return(i);
  653.                 }
  654.         }
  655.         return(-1);
  656. }
  657.  
  658.  
  659. int get_register(struct prog_info *pi, char *data)
  660. {
  661.         char *second_reg;
  662.         int reg = 0;
  663.         struct def *def;
  664.  
  665.         // Check for any occurence of r1:r0 pairs, and if so skip to second register
  666.         second_reg = strchr(data, ':');
  667.         if(second_reg != NULL)
  668.                 data = second_reg + 1;
  669.  
  670.         for(def = pi->first_def; def; def = def->next)
  671.                 if(!nocase_strcmp(def->name, data))
  672.                         {
  673.                         reg = def->reg;
  674.                         return(reg);
  675.                         }
  676.         if((tolower(data[0]) == 'r') && isdigit(data[1])) {
  677.                 reg = atoi(&data[1]);
  678.                 if(reg > 31)
  679.                         print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", reg);
  680.         }
  681.         else
  682.                 print_msg(pi, MSGTYPE_ERROR, "No register associated with %s", data);
  683.         return(reg);
  684. }
  685.  
  686.  
  687. int get_bitnum(struct prog_info *pi, char *data, int *ret)
  688. {
  689.         if(!get_expr(pi, data, ret))
  690.                 return(False);
  691.         if((*ret < 0) || (*ret > 7)) {
  692.                 print_msg(pi, MSGTYPE_ERROR, "Operand out of range (0 <= s <= 7)");
  693.                 return(False);
  694.         }
  695.         return(True);
  696. }
  697.  
  698.  
  699. int get_indirect(struct prog_info *pi, char *operand)
  700. {
  701.         int i = 1;
  702.  
  703.         switch(tolower(operand[0])) {
  704.                 case '-':
  705.                         while(IS_HOR_SPACE(operand[i])) i++;
  706.                         if(operand[i + 1] != '\0')
  707.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  708.                         switch(tolower(operand[i])) {
  709.                                 case 'x':
  710.                                         if (pi->device->flag & DF_NO_XREG)
  711.                                            print_msg(pi, MSGTYPE_ERROR, "X register is not supported on %s", pi->device->name);
  712.                                         return(2);
  713.                                 case 'y':
  714.                                         if (pi->device->flag & DF_NO_YREG)
  715.                                            print_msg(pi, MSGTYPE_ERROR, "Y register is not supported on %s", pi->device->name);
  716.                                         return(5);
  717.                                 case 'z':
  718.                                         return(8);
  719.                                 default:
  720.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  721.                                         return(0);
  722.                         }
  723.                 case 'x':
  724.                         if (pi->device->flag & DF_NO_XREG)
  725.                            print_msg(pi, MSGTYPE_ERROR, "X register is not supported on %s", pi->device->name);
  726.                         while(IS_HOR_SPACE(operand[i])) i++;
  727.                         if(operand[i] == '+') {
  728.                                 if(operand[i + 1] != '\0')
  729.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  730.                                 return(1);
  731.                         }
  732.                         else if(operand[i] == '\0')
  733.                                 return(0);
  734.                         else
  735.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand);
  736.                         return(0);
  737.                 case 'y':
  738.                         if (pi->device->flag & DF_NO_YREG)
  739.                            print_msg(pi, MSGTYPE_ERROR, "Y register is not supported on %s", pi->device->name);
  740.                         while(IS_HOR_SPACE(operand[i])) i++;
  741.                         if(operand[i] == '+') {
  742.                                 if(operand[i + 1] != '\0')
  743.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  744.                                 return(4);
  745.                         }
  746.                         else if(operand[i] == '\0')
  747.                                 return(3);
  748.                         else
  749.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand);
  750.                         return(0);
  751.                 case 'z':
  752.                         while(IS_HOR_SPACE(operand[i])) i++;
  753.                         if(operand[i] == '+') {
  754.                                 if(operand[i + 1] != '\0')
  755.                                         print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  756.                                 return(7);
  757.                         }
  758.                         else if(operand[i] == '\0')
  759.                                 return(6);
  760.                         else
  761.                                 print_msg(pi, MSGTYPE_ERROR, "Garbage after operand (%s)", operand);
  762.                         return(0);
  763.                 default:
  764.                         print_msg(pi, MSGTYPE_ERROR, "Garbage in operand (%s)", operand);
  765.         }
  766.         return(0);
  767. }
  768.  
  769. /* Return 1 if instruction name is supported by the current device,
  770.    0 if unsupported, -1 if it is invalid */
  771. int is_supported(struct prog_info *pi, char *name) {
  772.    char temp[MAX_MNEMONIC_LEN+1];
  773.    int mnemonic;
  774.  
  775.    strncpy(temp,name,MAX_MNEMONIC_LEN);
  776.    mnemonic = get_mnemonic_type(my_strlwr(temp));
  777.    if (mnemonic == -1) return -1;
  778.    if (pi->device->flag & instruction_list[mnemonic].flag) return 0;
  779.    return 1;
  780. }
  781.  
  782. int count_supported_instructions(int flags)
  783. {
  784.   int i = 0, count = 0;
  785.   while(i < MNEMONIC_END) {
  786.     if((i < MNEMONIC_LD) || (i > MNEMONIC_COUNT))
  787.       if(!(flags & instruction_list[i].flag))
  788.         count++;
  789.     i++;
  790.   }
  791.   return(count);
  792. }
  793.  
  794. /* end of mnemonic.c */
  795.  
  796.