/*
 * Model B emulation
 */

#include "ModelB.h"
#include "utils.h"

#include "ACIA.h"

#include "Display.h"

#include <unistd.h>

#include "dlc/dlc_register.h"

#define CPU_6502
#define HACK_WRCH
//#define HACK_RDCH
#include "CPU6502Emul.cc"
template CPU6502Emul<ModelBMem>;

#define _cpu ((CPU6502Emul<ModelBMem> *)(cpu))
#define _mem ((ModelBMem *)(mem))

ModelBEmul::ModelBEmul (void)
{
#ifndef MODELA
	printf ("Model B emulation: ModelB.cc $Revision: 1.8 $\n\n");
#else
	printf ("Model A emulation: ModelB.cc $Revision: 1.8 $\n\n");
#endif
	
	mem = new ModelBMem (this);
	dprintf ("Memory emulator created OK.\n");
	cpu = new CPU6502Emul<ModelBMem> (_mem);
	dprintf ("CPU emulator created OK.\n");
}

ModelBEmul::~ModelBEmul (void)
{
	delete cpu;
	delete mem;
}

void ModelBEmul::ExecThread (void)
{
	while (1)
	{
		if (trace)
			_cpu->Trace ();
		_cpu->ExecInstruction ();
		if (_cpu->check_cycles (200, 0))
		{
			// Do 1MHz bus ticks
			DoTicks (100);
			doevents ();
			//_mem->sysVIA->DoKbdCheck ();
		}
		if (_cpu->check_cycles (40000, 1))
		{
			// Display updates etc. should be done
		}
		if (_cpu->check_cycles (100000, 2))
			return;
	}
}

void ModelBMem::RenderDisplay (void)
{
	//Render_Display (&coremem[displaymem_begin], display);
}

ModelBMem::ModelBMem (ModelBEmul *p)
{
	parent = p;
	
	// Load the ROMs
	ReadFile ("os12.rom", &coremem[0xc000], 0x4000);
	ReadFile ("basic2.rom", swbanks[0xf], 0x4000);
	dprintf ("Standard ROMs loaded OK.\n");
	
	cur_swbank = -1;
	cur_sw_mod = 0;
	Switch_SWbank (0xf);
	
	coremem[0x20e] = coremem[0x20f] = coremem[0x210] = coremem[0x211] = 0xff;
	
	// Add the standard devices
	sysVIA = new ModelBSysVIA; AddDev (sysVIA, 0xfe40, 0xffe0);
#ifndef MODELA
	usrVIA = new ModelBUsrVIA; AddDev (usrVIA, 0xfe60, 0xffe0);
#endif
	acia = new ACIA; AddDev (acia, 0xfe08, 0xfff8);
	parent->Add_Ticker (sysVIA);
#ifndef MODELA
	parent->Add_Ticker (usrVIA);
#endif
	parent->Add_Ticker (acia);
	
	displaymem_begin = 0x7c00;
}

ModelBMem::~ModelBMem (void)
{
	delete acia;
#ifndef MODELA
	delete usrVIA;
#endif
	delete sysVIA;
}

#define SYSVIA ModelBSysVIA
#include "StdSysVIA.cc"

/* User VIA implementation */
#ifndef MODELA
#define USRVIA ModelBUsrVIA
#include "StdUsrVIA.cc"
#endif /* MODELA */

// Kludge, preprocessor macro in dlc_register.h doesn't expand properly
#ifndef MODELA
DLC_Register (ModelBEmul);
#else
DLC_Register (ModelAEmul);
#endif

/* End of file. */
