/*
* main.cpp
*
* main
*
* Copyright 2010 Tobias Wirtl, HBM <tobias.wirtl@hbm.com>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/


#include "instructionlist.h"
#include "instruction.h"
#include "instructionparser.h"
#include <iostream>
#include "helpers.h"

//#define DEBUG

int main(int argc, char *argv[])
{
    unsigned int i;
    bool assemble = false;
    bool humanReadable = false;
    bool lineComments = false;
    string mode;
    string source;
    string target;
    string inlPath;
    string temp;
    InstructionList* il;
    InstructionParser *parser;

#ifndef DEBUG
    if (argc >= 4)
    {
        mode    = argv[1];
        source  = argv[2];
        target  = argv[3];
        inlPath = argv[4];
#else

        mode    =  "-dlo6144"; //"-aho0";     //"-d"
        source  = "../sdmaasm/hexblob.txt";//hexblob.txt";
        target  = "../sdmaasm/out.txt";
        inlPath = "../sdmaasm/sdma.inst";

#endif
        il = new InstructionList(inlPath);
        parser = new InstructionParser(il);

        cout    <<"\nPath to source file:     "<<source<<'\n'
                <<"Path to instructions file: "<<inlPath<<'\n'
                <<"Path to output file:       "<<target<<"\n\n";


        for (i = 0; i < mode.size(); i++)
        {
            switch(mode[i])
            {
            case ('a'):
                assemble = true;
                break;
            case ('d'):
                assemble = false;
                break;
            case ('o'):
                i++;
                while(mode[i] > 47 && mode[i] < 58)
                    temp += (mode[i++]);
                parser->setOffset(Helpers::strToInt(temp));
                break;
            case ('h'):
                humanReadable = true;
                break;
            case ('l'):
                lineComments = true;
                break;
            }
        }

        if (assemble)
        {
            parser->readProgramLines(source);
            if (humanReadable)
                parser->hexBlobOutputToFile(target);
            else
                parser->binaryOutputToFile(target);
        }
        else
        {
            parser->setLineComments(lineComments);
            parser->readTextBlob(source);
            parser->instructionOutputToFile(target);
            cout<<"\ndone!\n";
        }

        delete parser;
        delete il;

#ifndef DEBUG
    }
    else
        cout    <<"Assembler for the i.MX356 SDMA controller\n"
                <<"Copyright Tobias Wirtl <tobias.wirtl@hbm.com> HBM 2010\n\n"

                <<"This program is licensed under the GNU General Public\n"
                <<"License. You may obtain a copy of the GNU General Public License\n"
                <<"Version 2 or later at the following locations:\n"
                <<"http://www.opensource.org/licenses/gpl-license.html\n"
                <<"http://www.gnu.org/copyleft/gpl.html\n\n"

                <<"Usage: SDMA_ASM -[mode][options] [source] [target] [instruction file]\n"
                <<"possible modes \n"
                <<"\td disassemble\thex blob --> code file \n"
                <<"\ta assemble\t\tcode file --> hexfile\n\n"
                <<"options:\n"
                <<"\toXXX - set offset\n"
                <<"\tl    - print line numbers (only for mode d)\n"
                <<"\th    - human readable hex blob (only for mode a)\n"
                <<"sample usage:\n"
                <<"\tSDMA_ASM -aho42 input.asm output.hex sdma.inst <-- assemble input.asm with an offset of 42\n"
                <<"\tSDMA_ASM -dlo42 input.blob output.asm sdma.inst <-- disassemble input.blob with an offset of 42\n";
#endif
    return 0;
}

