/*
 * Electron emulation
 */

#ifndef ELECTRON_H
#define ELECTRON_H

#include <stdio.h>

#include "CompEmul.h"
#include "MemEmul.h"

class ElectronEmul: public CompEmul
{
protected:

public:
	ElectronEmul (void);
	virtual ~ElectronEmul (void);
	virtual void ExecThread (void);
};

class ElectronULA;

class ElectronMem: public MemEmul
{
protected:
	ElectronULA *ULA;
	int kb_paged;
	
	friend class ElectronULA;
	
	ElectronEmul *parent;
	byte KbdRead (int addr);

public:
	ElectronMem (ElectronEmul *p);
	virtual ~ElectronMem (void);
	
	inline byte Read (int addr);
};

class ElectronULA: public MMIO_Dev
{
protected:
	ElectronMem *mem;
	int dir_sw;
	int irq_status, irq_mask;
	enum electron_irqs
	{
		IRQ_MASTER = 1,
		IRQ_POWERON = 2,
		IRQ_DISPLAY = 4,
		IRQ_RTC = 8,
		IRQ_TX = 0x10,
		IRQ_RX = 0x20,
		IRQ_HIGHTONE = 0x40,
	};
	int ticks_to_50hz;
	
	virtual void SetInt (int num);
	virtual void ClearInt (int num);

public:
	ElectronULA (ElectronMem *m);
	virtual ~ElectronULA (void);
	virtual byte MMIO_Read (int addr);
	virtual void MMIO_Write (int addr, byte value);
	virtual void Break (void);
	virtual void Reset (void);
	virtual void DoTicks (int ticks);
	void KeyEvent (int row, int col);
};

byte ElectronMem::Read (int addr)
{
	if (kb_paged && addr >= 0x8000 & addr < 0xc000)
	{
		//printf ("keyboard %x\n", addr - 0x8000);
		return KbdRead (addr);
	}
	else if (addr < 0xfc00 || addr >= 0xff00)
		return coremem[addr];
	else
		return Read_MMIO (addr);
}

#endif /* ELECTRON_H */

/* End of file. */
