/* 
 * ASCD : copyright (c) Aley Keprt 1998-2012
 * SimCoupe : Copyright (c) Allan Skillman 1996
 *
 * File z80.h - defines the processor and its registers.
 *
    This file is part of Z80 CPU emulation library used in ASCD emulator.

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef __Z80_H
#define __Z80_H


#pragma once


#include "types.h"


#ifdef Z80CPU
  #define DLL __declspec(dllexport)
#else
  #define DLL __declspec(dllimport)
//  #pragma comment(lib,"z80cpu")
#endif


#ifdef __cplusplus
extern "C" {
#endif


//Constants used to bit-mask the F register
enum {
  F_CARRY = 0x01,
  F_NADD = 0x02,   //for BCD
  F_PARITY = 0x04,
  F_OVERFLOW = 0x04,
  F_HCARRY = 0x10, //for BCD
  F_ZERO = 0x40,
  F_NEG = 0x80,
};


#pragma pack(push,1)
typedef struct {
  BYTE a, f, b, c, d, e, h, l;
  BYTE a1, f1, b1, c1, d1, e1, h1, l1;
  WORD ix, iy, pc, sp;
  BYTE i, r;
  BYTE im, iff; //bit0=IFF1, bit1=IFF2, bit3=!DelayedEI
  WORD LineCycleCounter;
  WORD IntActiveCounter;
  WORD lineno; //PAL line number - it is not used by Z80 CPU emulation core (i.e. always zero)
  //---
  //mouse active counter must always be the last value in this structure
  WORD MouseActiveCounter;
} Z80_Regs;
#pragma pack(pop)


//emulation mode
typedef enum {
  EM_None = -1,
  EM_Sam,
  EM_48k,
  EM_128k,
  EM_ZX80,
  EM_ZX81,
} EM;


DLL void Z80Reset(EM emumode); //resetuje vsechny CPU registry a porty
//DLL void Z80DumpState(FILE *f); //Zapise stav emulace do souboru

DLL void Z80GetRegs(Z80_Regs *regs);
DLL void Z80SetRegs(const Z80_Regs *regs);
DLL BYTE Z80GetI(void); //vraci hodnotu registru I (je to rychlejsi nez GetRegs())

DLL void Z80DoNMI(void);

//Z80 CPU emulation of a single PAL scanline
//do_interrupts=true to let the emulator process maskable interrupts before the first instruction
DLL void Z80RunLine(bool do_interrupts);

//Z80 CPU emulation of a single PAL scanline - ZX81
DLL void Z80RunZX81();

DLL void Z80ResetIntActiveCounter(void); //resetuje citac doby aktivity preruseni

DLL int Z80GetLineCycleCounter(void); //vraci aktualni hodnotu LineCycleCounter

DLL void (*out_byte)(WORD port, BYTE value);
DLL BYTE (*in_byte)(WORD port);
DLL void (*EDFEtrap)(void);

DLL bool MouseStrobed;

DLL BYTE status_reg;

DLL BYTE* theRdMemory[4];
DLL BYTE* theWrMemory[4];


#define MEM_R(addr) (theRdMemory[(addr)>>14][(addr)&0x3fff])
#define MEM_W(addr) (theWrMemory[(addr)>>14][(addr)&0x3fff])

static inline BYTE read_byte(WORD addr) { return MEM_R(addr); }

static inline WORD read_word(WORD addr) { return MEM_R(addr)+(MEM_R((WORD)(addr+1))<<8); }

static inline void write_byte(WORD addr, BYTE val) { MEM_W(addr)=val; }

static inline void write_word(WORD addr, WORD val) { MEM_W(addr)=(BYTE)val; MEM_W(addr+1)=val>>8; }

#undef MEM_R
#undef MEM_W


#ifdef __cplusplus
}
#endif


#endif
