2017-06-11 08:45:34 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "Processor.h"
|
|
|
|
|
|
|
|
namespace EightBit {
|
|
|
|
class IntelProcessor : public Processor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
register16_t& MEMPTR() { return m_memptr; }
|
|
|
|
|
|
|
|
virtual void initialise();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
IntelProcessor(Memory& memory);
|
|
|
|
|
|
|
|
std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
|
|
|
|
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
|
|
|
|
|
|
|
|
int buildHalfCarryIndex(uint8_t before, uint8_t value, int calculation) {
|
|
|
|
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool calculateHalfCarryAdd(uint8_t before, uint8_t value, int calculation) {
|
|
|
|
auto index = buildHalfCarryIndex(before, value, calculation);
|
2017-06-13 22:43:21 +00:00
|
|
|
return m_halfCarryTableAdd[index & Mask3];
|
2017-06-11 08:45:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool calculateHalfCarrySub(uint8_t before, uint8_t value, int calculation) {
|
|
|
|
auto index = buildHalfCarryIndex(before, value, calculation);
|
2017-06-13 22:43:21 +00:00
|
|
|
return m_halfCarryTableSub[index & Mask3];
|
2017-06-11 08:45:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void push(uint8_t value);
|
|
|
|
void pushWord(register16_t value);
|
|
|
|
|
|
|
|
uint8_t pop();
|
|
|
|
void popWord(register16_t& output);
|
|
|
|
|
|
|
|
void fetchWord() {
|
|
|
|
Processor::fetchWord(MEMPTR());
|
|
|
|
}
|
|
|
|
|
2017-06-11 20:08:40 +00:00
|
|
|
//
|
|
|
|
|
2017-06-15 21:21:26 +00:00
|
|
|
uint8_t& memptrReference() {
|
2017-06-12 13:33:00 +00:00
|
|
|
m_memory.ADDRESS() = MEMPTR();
|
|
|
|
MEMPTR().word++;
|
|
|
|
return m_memory.reference();
|
|
|
|
}
|
|
|
|
|
|
|
|
void getWordViaMemptr(register16_t& value) {
|
2017-06-15 21:21:26 +00:00
|
|
|
value.low = memptrReference();
|
2017-06-12 13:33:00 +00:00
|
|
|
m_memory.ADDRESS().word++;
|
|
|
|
value.high = m_memory.reference();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setWordViaMemptr(register16_t value) {
|
2017-06-15 21:21:26 +00:00
|
|
|
memptrReference() = value.low;
|
2017-06-12 13:33:00 +00:00
|
|
|
m_memory.ADDRESS().word++;
|
|
|
|
m_memory.reference() = value.high;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
2017-06-11 20:08:40 +00:00
|
|
|
void jump() {
|
2017-06-11 08:45:34 +00:00
|
|
|
pc = MEMPTR();
|
|
|
|
}
|
|
|
|
|
2017-06-11 20:08:40 +00:00
|
|
|
void call() {
|
|
|
|
pushWord(pc);
|
|
|
|
jump();
|
|
|
|
}
|
|
|
|
|
|
|
|
void restart(uint8_t address) {
|
|
|
|
MEMPTR().low = address;
|
|
|
|
MEMPTR().high = 0;
|
|
|
|
call();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool callConditional(int condition) {
|
|
|
|
fetchWord();
|
|
|
|
if (condition)
|
|
|
|
call();
|
|
|
|
return condition != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool jumpConditional(int conditional) {
|
|
|
|
fetchWord();
|
|
|
|
if (conditional)
|
|
|
|
jump();
|
|
|
|
return conditional != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ret() {
|
|
|
|
popWord(MEMPTR());
|
|
|
|
jump();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool returnConditional(int condition) {
|
|
|
|
if (condition)
|
|
|
|
ret();
|
|
|
|
return condition != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void jr(int8_t offset) {
|
|
|
|
MEMPTR().word = pc.word + offset;
|
|
|
|
jump();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool jrConditional(int conditional) {
|
|
|
|
auto offset = fetchByte();
|
|
|
|
if (conditional)
|
|
|
|
jr(offset);
|
|
|
|
return conditional != 0;
|
|
|
|
}
|
|
|
|
|
2017-06-11 08:45:34 +00:00
|
|
|
private:
|
|
|
|
register16_t m_memptr;
|
|
|
|
};
|
|
|
|
}
|