////////////////////////////////////////////////////////////////////////////////
// CPU65xx.h -- this file is part of the Emulator Developers Kit
// available at http://ourworld.compuserve.com/homepages/pc64/develop.htm
//
// The CPU65xx class is the basic implementation of the 6502 and the
// 6510. The classes CPU6502 and CPU6510C64 contain only the differences.

class CPU65xx : public CPU16x4k {
protected:

  byte* pbPCPtr;     // fetch next byte (needs adjustement every 4k)
  int iAddr8;        // $000000xx
  int iAddr16;       // $0000xxxx
  byte bAccu;        // accumulator
  byte bZVal;        // ZFlag = bZVal == 0 ? 1 : 0
  byte bData;        // for modify instructions
  byte bFixAdr;      // for indexing and branch commands
  byte bFlags;       // %001BDI00
  byte bVFlag;       // %0000000V
  byte bIRQ;         // %00000x00, bit 2 = 0: IRQ line is active
  byte abIRQFill[1];
  int iNCFlag;       // %xxxxxxxCNxxxxxxx
  int iXReg;         // $000000xx
  int iYReg;         // $000000xx
  byte* pbPCBase;    // PC = PCPtr - PCBase
  int iRWAddress;    // 0x0000 to 0xFFFF
  int iSP;           // $000001xx
  int iInterrupts;   // index into priority table
  pfn pfnAction;     // main implementation of the current command
  pfn pfnInterrupt;  // normally Command, or IRQ1/NMI1
  int iPostponeIRQ;  // postpone interrupts which have occurred only
  int iPostponeNMI;  // one clock before the next command

  // line functions
  void OnResetHigh();
  void OnResetLow();
  void OnIRQHigh();
  void OnIRQLow();
  void OnNMILow();
  void OnRDYHigh();
  void OnRDYLow();

  // initialisation
  virtual void DoInit();

public:

  // constructor
  global CPU65xx() {
    iAddr8 = 0;
    iAddr16 = 0;
    pbPCBase = NULL;
    pbPCPtr = NULL;
    iSP = 0x100;
    iXReg = 0;
    iYReg = 0;
    bAccu = 0;
    bFlags = 0x30;
    iNCFlag = 0;
    bZVal = 0;
    bVFlag = 0;
    bData = 0;
    bFixAdr = 0;
    bIRQ = 4;
    iRWAddress = 0;
    iInterrupts = 0;
    pfnInterrupt = NULL;
    pfnAction = NULL;
    iPostponeIRQ = -1;
    iPostponeNMI = -1;
  }

  // interrupt lines
  Line Reset;
  Line IRQ;
  Line NMI;

  // halt CPU when drawn low
  Line RDY;

  // get read/write address for trap arrays
  // for example the C64 color RAM at $D800 to $DBFF
  inline int GetRWAddress() {
    return iRWAddress;
  }

  // adjust PC pointer after memory mapping has changed
  global void AdjustPCPtr();
};
