////////////////////////////////////////////////////////////
// Z80 Emulator Class Library Sample 1
//
// Written by Manuke
////////////////////////////////////////////////////////////
// include
#include "StdHeader.h"
#include "Z80.h"
////////////////////////////////////////////////////////////
// OS dependence console input/output library
#ifdef _MSC_VER // Win32 platform & Visual C++
#include <conio.h>
void InitConsole() {
}
void CloseConsole() {
}
#elif defined(__BORLANDC__) // Win32 platform & Borland C++
#include <conio.h>
#define _kbhit kbhit
#define _getch getch
#define _putch putch
void InitConsole() {
}
void CloseConsole() {
}
#else // GNU/Linux platform & g++
#include <termios.h>
static struct termios g_tiosOrg, g_tiosNew;
static int g_chPeek = -1;
void InitConsole() {
tcgetattr(0, &g_tiosOrg);
g_tiosNew = g_tiosOrg;
g_tiosNew.c_lflag &= ~(ICANON | ECHO | ISIG);
g_tiosNew.c_cc[VMIN] = 1;
g_tiosNew.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &g_tiosNew);
}
void CloseConsole() {
tcsetattr(0, TCSANOW, &g_tiosOrg);
}
int _kbhit() {
char ch;
int nRead;
if (g_chPeek != -1) {
return 1;
}
g_tiosNew.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &g_tiosNew);
nRead = read(0, &ch, 1);
g_tiosNew.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &g_tiosNew);
if (nRead == 1) {
g_chPeek = ch;
return 1;
}
return 0;
}
int _getch() {
char ch;
if (g_chPeek != -1) {
ch = (char)g_chPeek;
g_chPeek = -1;
} else {
if (read(0, &ch, 1) != 1) {
// ignore
}
}
if (ch == "\n") {
ch = "\r";
}
return ch;
}
int _putch(int a) {
int nResult = putchar(a);
fflush(stdout);
return nResult;
}
#endif // Platform
////////////////////////////////////////////////////////////
// CZ80Sample1
#ifdef Z80CFG_NOUSE_TEMPLATE
////////////////////////////////////////////////////////////
// exsample of imprement in non-template mode
class CZ80Sample1 : public CZ80 {
// attribute
protected:
bool m_bExit;
uint8_t m_abtRom[1024];
public:
bool IsExit() {
return m_bExit;
}
// construct/destruct
public:
CZ80Sample1() {
}
virtual ~CZ80Sample1() {
}
// initialize
public:
virtual void Initialize() {
CZ80::Initialize();
m_bExit = false;
memset(m_abtRom, 0x00, sizeof(m_abtRom));
static const uint8_t abtProgram[] = {
0xDB, 0x00, // 00000H IN A, (000H)
0xA7, // 00002H AND A
0x28, 0xFB, // 00003H JR Z, 00000H
0xFE, 0x1B, // 00005H CP 01BH
0x28, 0x0C, // 00007H JR Z, 00015H
0xD3, 0x01, // 00009H OUT (001H), A
0xFE, 0x0D, // 0000BH CP 00DH
0x20, 0xF1, // 0000DH JR NZ, 00000H
0x3E, 0x0A, // 0000FH LD A, 00AH
0xD3, 0x01, // 00011H OUT (001H), A
0x18, 0xEB, // 00013H JR 00000H
0xD3, 0x02, // 00015H OUT (002H), A
0x76 // 00017H HALT
};
memcpy(m_abtRom, abtProgram, sizeof(abtProgram));
}
virtual void Reset() {
CZ80::Reset();
}
// memory operation
protected:
virtual uint8_t ReadMemory(int nAddress) {
uint8_t btResult = 0xFF;
if (nAddress < 1024) {
btResult = m_abtRom[nAddress];
}
return btResult;
}
virtual void WriteMemory(int /*nAddress*/, uint8_t /*btData*/) {
}
virtual uint8_t ReadMemoryM1(int nAddress) {
return ReadMemory(nAddress);
}
virtual uint8_t ReadIO(int nAddress) {
uint8_t btResult = 0xFF;
if (nAddress == 0x00) {
btResult = 0x00;
if (_kbhit()) {
btResult = (uint8_t)_getch();
}
}
return btResult;
}
virtual void WriteIO(int nAddress, uint8_t btData) {
if (nAddress == 0x01) {
_putch((char)btData);
} else if (nAddress == 0x02) {
m_bExit = true;
}
}
};
#else // Z80CFG_USE_TEMPLATE
////////////////////////////////////////////////////////////
// exsample of imprement in template mode
class CZ80Sample1 : public CZ80_1 {
// attribute
protected:
static bool m_bExit;
static uint8_t m_abtRom[1024];
public:
static bool IsExit() {
return m_bExit;
}
// construct/destruct
public:
CZ80Sample1() {
}
virtual ~CZ80Sample1() {
}
// initialize
public:
virtual void Initialize() {
CZ80_1::Initialize();
m_bExit = false;
memset(m_abtRom, 0x00, sizeof(m_abtRom));
static const uint8_t abtProgram[] = {
0xDB, 0x00, // 00000H IN A, (000H)
0xA7, // 00002H AND A
0x28, 0xFB, // 00003H JR Z, 00000H
0xFE, 0x1B, // 00005H CP 01BH
0x28, 0x0C, // 00007H JR Z, 00015H
0xD3, 0x01, // 00009H OUT (001H), A
0xFE, 0x0D, // 0000BH CP 00DH
0x20, 0xF1, // 0000DH JR NZ, 00000H
0x3E, 0x0A, // 0000FH LD A, 00AH
0xD3, 0x01, // 00011H OUT (001H), A
0x18, 0xEB, // 00013H JR 00000H
0xD3, 0x02, // 00015H OUT (002H), A
0x76 // 00017H HALT
};
memcpy(m_abtRom, abtProgram, sizeof(abtProgram));
}
virtual void Reset() {
CZ80_1::Reset();
// initialize of memory access procedure
int i;
for (i = 0; i < 64; i++) {
SetReadMemoryProc(i, ReadNONE);
SetReadMemoryM1Proc(i, ReadNONE);
SetWriteMemoryProc(i, WriteNONE);
}
SetReadMemoryProc(0, ReadMemoryRom);
SetReadMemoryM1Proc(0, ReadMemoryRom);
// initialize of I/O access procedure
for (i = 0; i < 256; i++) {
SetReadIOProc(i, ReadNONE);
SetWriteIOProc(i, WriteNONE);
}
SetReadIOProc(0x00, ReadIO_00);
SetWriteIOProc(0x01, WriteIO_01);
SetWriteIOProc(0x02, WriteIO_02);
}
// memory operation
protected:
static uint8_t ReadNONE(int /*nAddress*/) {
return 0xFF;
}
static void WriteNONE(int /*nAddress*/, uint8_t /*btData*/) {
}
static uint8_t ReadMemoryRom(int nAddress) {
return m_abtRom[nAddress];
}
static uint8_t ReadIO_00(int /*nAddress*/) {
uint8_t btResult = 0x00;
if (_kbhit()) {
btResult = (uint8_t)_getch();
}
return btResult;
}
static void WriteIO_01(int /*nAddress*/, uint8_t btData) {
_putch((char)btData);
}
static void WriteIO_02(int /*nAddress*/, uint8_t /*btData*/) {
m_bExit = true;
}
};
bool CZ80Sample1::m_bExit;
uint8_t CZ80Sample1::m_abtRom[1024];
#endif // Z80CFG_USE/NOUSE_TEMPLATE
////////////////////////////////////////////////////////////
// main
int main(void) {
InitConsole();
CZ80Sample1 z80;
z80.Initialize();
z80.Reset();
do {
z80.ExecuteOneOpCode();
} while (!z80.IsExit());
CloseConsole();
return 0;
}