#ifndef MACHINE_H
#define MACHINE_H
#include "device.h"

class Machine {
private:
    int A;
    int B;
    int L;
    int T;
    int S;
    int X;
    int PC;
    int SW;
    double F;
    static const int MEMORY_SIZE = 1000000;
    static const int MAX_ADDRESS = MEMORY_SIZE - 1;
    unsigned char memory[MEMORY_SIZE];
    Device* devices[256];

public:
    Machine();

    int getA() { return A; }
    int getB() { return B; }
    int getL() { return L; }
    int getT() { return T; }
    int getS() { return S; }
    int getX() { return X; }
    int getPC() { return PC; }
    int getSW() { return SW; }
    double getF() { return F; }

    void setA(int val) { A = val; }
    void setB(int val) { B = val; }
    void setL(int val) { L = val; }
    void setT(int val) { T = val; }
    void setS(int val) { S = val; }
    void setX(int val) { X = val; }
    void setPC(int val) { PC = val; }
    void setSW(int val) { SW = val; }
    void setF(double val) { F = val; }

    void resetRegisters();

    void resetMemory();

    int getMemSize() { return MEMORY_SIZE; }

    int getReg(int reg);
    void setReg(int reg, int val);

    unsigned char readByte(unsigned int address);
    void writeByte(unsigned int address, unsigned char val);

    unsigned int getWord(unsigned int address);
    void setWord(unsigned int address, unsigned int val);

    Device * getDevice(int num);
    void setDevice(int num, Device * device);

    void notImplemented(int opcode);

    void invalidOpcode(int opcode);

    void invalidAddressing();

    int fetch();

    void execute();

    bool execF1(int opcode);

    bool execF2(int opcode, int operand);

    bool execSICF3F4(int opcode, int ni, int operand);
};

#endif
