- Treballant en la CPU
This commit is contained in:
9
mem.h
Normal file
9
mem.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace mem
|
||||||
|
{
|
||||||
|
void reset();
|
||||||
|
uint8_t readMem(uint16_t address);
|
||||||
|
void writeMem(uint16_t address, uint8_t value);
|
||||||
|
}
|
||||||
572
sm83.cpp
572
sm83.cpp
@@ -1,4 +1,5 @@
|
|||||||
#include "sm83.h"
|
#include "sm83.h"
|
||||||
|
#include "mem.h"
|
||||||
//#include "z80debug.h"
|
//#include "z80debug.h"
|
||||||
//#include "z80mem.h"
|
//#include "z80mem.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -66,7 +67,7 @@ namespace sm83
|
|||||||
#define rSP (*_rSP)
|
#define rSP (*_rSP)
|
||||||
#define rPC (*_rPC)
|
#define rPC (*_rPC)
|
||||||
|
|
||||||
#define im2 (*_rIME)
|
#define ime (*_rIME)
|
||||||
|
|
||||||
#define EX(a,b) {auto temp=a;a=b;b=temp;}
|
#define EX(a,b) {auto temp=a;a=b;b=temp;}
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ namespace sm83
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
reading_m1 = false;
|
reading_m1 = false;
|
||||||
return z80mem::get()->readMem(addr);
|
return mem::readMem(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t READ_MEM_8()
|
uint8_t READ_MEM_8()
|
||||||
@@ -124,7 +125,7 @@ namespace sm83
|
|||||||
const uint8_t WRITE_MEM_8(const uint16_t addr, const uint8_t value)
|
const uint8_t WRITE_MEM_8(const uint16_t addr, const uint8_t value)
|
||||||
{
|
{
|
||||||
t+=4;
|
t+=4;
|
||||||
z80mem::get()->writeMem(addr, value);
|
mem::writeMem(addr, value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (z80debug::isbreak(addr, 4)) z80debug::stop();
|
if (z80debug::isbreak(addr, 4)) z80debug::stop();
|
||||||
@@ -194,40 +195,12 @@ namespace sm83
|
|||||||
*a = (uint16_t)res;
|
*a = (uint16_t)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADC16(uint16_t* a, uint16_t b)
|
|
||||||
{
|
|
||||||
t++;
|
|
||||||
const uint32_t res = *a + b + (rF & fC);
|
|
||||||
rF=0;
|
|
||||||
SET_FLAGS(((*a ^ res ^ b) >> 8) & fH);
|
|
||||||
SET_FLAGS((res >> 16) & fC);
|
|
||||||
SET_FLAGS((res >> 8) & (fS | fY | fX));
|
|
||||||
SET_FLAGS((res & 0xffff) ? 0 : fZ);
|
|
||||||
SET_FLAGS(((b ^ *a ^ 0x8000) & (b ^ res) & 0x8000) >> 13);
|
|
||||||
*a = (uint16_t)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SBC16(uint16_t* a, uint16_t b)
|
|
||||||
{
|
|
||||||
t++;
|
|
||||||
const uint32_t res = *a - b - (rF & fC);
|
|
||||||
rF = 0;
|
|
||||||
SET_FLAGS(((*a ^ res ^ b) >> 8) & fH);
|
|
||||||
SET_FLAGS(fN);
|
|
||||||
SET_FLAGS((res >> 16) & fC);
|
|
||||||
SET_FLAGS((res >> 8) & (fS | fY | fX));
|
|
||||||
SET_FLAGS((res & 0xffff) ? 0 : fZ);
|
|
||||||
SET_FLAGS(((b ^ *a) & (*a ^ res) & 0x8000) >> 13);
|
|
||||||
*a = (uint16_t)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void INC8(uint8_t *reg)
|
void INC8(uint8_t *reg)
|
||||||
{
|
{
|
||||||
uint8_t value = *reg + 1;
|
uint8_t value = *reg + 1;
|
||||||
|
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(value);
|
if (value==0) SET_FLAGS(fZ);
|
||||||
if (value == 0x80) SET_FLAGS(fV);
|
|
||||||
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
||||||
|
|
||||||
*reg = value;
|
*reg = value;
|
||||||
@@ -238,9 +211,8 @@ namespace sm83
|
|||||||
uint8_t value = *reg - 1;
|
uint8_t value = *reg - 1;
|
||||||
|
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(value);
|
|
||||||
SET_FLAGS(fN);
|
SET_FLAGS(fN);
|
||||||
if (value == 0x7f) SET_FLAGS(fV);
|
if (value==0) SET_FLAGS(fZ);
|
||||||
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
||||||
|
|
||||||
*reg = value;
|
*reg = value;
|
||||||
@@ -248,13 +220,11 @@ namespace sm83
|
|||||||
|
|
||||||
void INCMEM8(const uint16_t addr)
|
void INCMEM8(const uint16_t addr)
|
||||||
{
|
{
|
||||||
t++;
|
|
||||||
uint8_t value = READ_MEM_8(addr);
|
uint8_t value = READ_MEM_8(addr);
|
||||||
value++;
|
value++;
|
||||||
|
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(value);
|
if (value==0) SET_FLAGS(fZ);
|
||||||
if (value == 0x80) SET_FLAGS(fV);
|
|
||||||
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
||||||
|
|
||||||
WRITE_MEM_8(addr, value);
|
WRITE_MEM_8(addr, value);
|
||||||
@@ -262,14 +232,12 @@ namespace sm83
|
|||||||
|
|
||||||
void DECMEM8(const uint16_t addr)
|
void DECMEM8(const uint16_t addr)
|
||||||
{
|
{
|
||||||
t+=1;
|
|
||||||
uint8_t value = READ_MEM_8(addr);
|
uint8_t value = READ_MEM_8(addr);
|
||||||
value--;
|
value--;
|
||||||
|
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
FLAGS_SZXY(value);
|
|
||||||
SET_FLAGS(fN);
|
SET_FLAGS(fN);
|
||||||
if (value == 0x7f) SET_FLAGS(fV);
|
if (value==0) SET_FLAGS(fZ);
|
||||||
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
||||||
|
|
||||||
WRITE_MEM_8(addr, value);
|
WRITE_MEM_8(addr, value);
|
||||||
@@ -292,10 +260,9 @@ namespace sm83
|
|||||||
else {
|
else {
|
||||||
uint16_t res = rA + b + 1;
|
uint16_t res = rA + b + 1;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if ( (res & 0x0f) <= (rA & 0x0f) ) SET_FLAGS(fH);
|
if ( (res & 0x0f) <= (rA & 0x0f) ) SET_FLAGS(fH);
|
||||||
if ( res > 255 ) SET_FLAGS(fC);
|
if ( res > 255 ) SET_FLAGS(fC);
|
||||||
if ( (b^rA^0x80) & (b^res) & 0x80 ) SET_FLAGS(fV);
|
|
||||||
rA = (uint8_t)res;
|
rA = (uint8_t)res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,11 +271,10 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = rA - b;
|
const uint8_t res = rA - b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
SET_FLAGS(fN);
|
SET_FLAGS(fN);
|
||||||
if ( (res & 0x0f) > (rA & 0x0f) ) SET_FLAGS(fH);
|
if ( (res & 0x0f) > (rA & 0x0f) ) SET_FLAGS(fH);
|
||||||
if ( res > rA ) SET_FLAGS(fC);
|
if ( res > rA ) SET_FLAGS(fC);
|
||||||
if ( (b^rA) & (rA^res) & 0x80 ) SET_FLAGS(fV);
|
|
||||||
if (update) rA = (uint8_t)res;
|
if (update) rA = (uint8_t)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,45 +285,33 @@ namespace sm83
|
|||||||
else {
|
else {
|
||||||
const uint8_t res = rA - b - 1;
|
const uint8_t res = rA - b - 1;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
SET_FLAGS(fN);
|
SET_FLAGS(fN);
|
||||||
if ( (res & 0x0f) >= (rA & 0x0f) ) SET_FLAGS(fH);
|
if ( (res & 0x0f) >= (rA & 0x0f) ) SET_FLAGS(fH);
|
||||||
if ( res >= rA ) SET_FLAGS(fC);
|
if ( res >= rA ) SET_FLAGS(fC);
|
||||||
if ( (b^rA) & (rA^res) & 0x80 ) SET_FLAGS(fV);
|
|
||||||
rA = (uint8_t)res;
|
rA = (uint8_t)res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NEG()
|
|
||||||
{
|
|
||||||
uint8_t val = rA;
|
|
||||||
rA = 0;
|
|
||||||
SUB8(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AND(uint8_t b)
|
void AND(uint8_t b)
|
||||||
{
|
{
|
||||||
rA = rA & b;
|
rA = rA & b;
|
||||||
rF=0;
|
rF=fH;
|
||||||
FLAGS_SZXY(rA);
|
if (rA==0) SET_FLAGS(fZ);
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
SET_FLAGS(fH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XOR(uint8_t b)
|
void XOR(uint8_t b)
|
||||||
{
|
{
|
||||||
rA = rA ^ b;
|
rA = rA ^ b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(rA);
|
if (rA==0) SET_FLAGS(fZ);
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OR(uint8_t b)
|
void OR(uint8_t b)
|
||||||
{
|
{
|
||||||
rA = rA | b;
|
rA = rA | b;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(rA);
|
if (rA==0) SET_FLAGS(fZ);
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP(uint8_t b)
|
void CP(uint8_t b)
|
||||||
@@ -365,30 +319,11 @@ namespace sm83
|
|||||||
SUB8(b, false);
|
SUB8(b, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LD_A_I()
|
|
||||||
{
|
|
||||||
t++;
|
|
||||||
rA = rI;
|
|
||||||
KEEP_FLAGS(fC);
|
|
||||||
FLAGS_SZXY(rA);
|
|
||||||
if (iff2) SET_FLAGS(fP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LD_A_R()
|
|
||||||
{
|
|
||||||
t++;
|
|
||||||
rA = rR;
|
|
||||||
KEEP_FLAGS(fC);
|
|
||||||
FLAGS_SZXY(rA);
|
|
||||||
if (iff2) SET_FLAGS(fP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RLCA()
|
void RLCA()
|
||||||
{
|
{
|
||||||
const bool should_carry = rA & 0x80;
|
const bool should_carry = rA & 0x80;
|
||||||
rA = (rA>>7) | (rA<<1);
|
rA = (rA>>7) | (rA<<1);
|
||||||
KEEP_FLAGS(fS | fZ | fP);
|
rF = 0;
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
if (should_carry) SET_FLAGS(fC);
|
if (should_carry) SET_FLAGS(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,8 +331,7 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const bool should_carry = rA & 0x01;
|
const bool should_carry = rA & 0x01;
|
||||||
rA = (rA<<7) | (rA>>1);
|
rA = (rA<<7) | (rA>>1);
|
||||||
KEEP_FLAGS(fS | fZ | fP);
|
rF = 0;
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
if (should_carry) SET_FLAGS(fC);
|
if (should_carry) SET_FLAGS(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,8 +339,7 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const bool should_carry = rA & 0x80;
|
const bool should_carry = rA & 0x80;
|
||||||
rA = (rA<<1) | (rF&fC);
|
rA = (rA<<1) | (rF&fC);
|
||||||
KEEP_FLAGS(fS | fZ | fP);
|
rF = 0;
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
if (should_carry) SET_FLAGS(fC);
|
if (should_carry) SET_FLAGS(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,37 +347,11 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const bool should_carry = rA & 0x01;
|
const bool should_carry = rA & 0x01;
|
||||||
rA = ((rF&fC)<<7) | (rA>>1);
|
rA = ((rF&fC)<<7) | (rA>>1);
|
||||||
KEEP_FLAGS(fS | fZ | fP);
|
rF = 0;
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
if (should_carry) SET_FLAGS(fC);
|
if (should_carry) SET_FLAGS(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RRD()
|
/*
|
||||||
{
|
|
||||||
uint8_t a = rA;
|
|
||||||
uint8_t hl = READ_MEM_8(rHL);
|
|
||||||
rA = (rA & 0xF0) | (hl & 0x0F);
|
|
||||||
hl = (hl >> 4) | (a << 4);
|
|
||||||
WRITE_MEM_8(rHL, hl);
|
|
||||||
KEEP_FLAGS(fC);
|
|
||||||
FLAGS_SZXY(rA);
|
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
t+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RLD()
|
|
||||||
{
|
|
||||||
uint8_t a = rA;
|
|
||||||
uint8_t hl = READ_MEM_8(rHL);
|
|
||||||
rA = (rA & 0xF0) | (hl >> 4);
|
|
||||||
hl = (hl << 4) | (a & 0x0F);
|
|
||||||
WRITE_MEM_8(rHL, hl);
|
|
||||||
KEEP_FLAGS(fC);
|
|
||||||
FLAGS_SZXY(rA);
|
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
t+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void new_DAA()
|
void new_DAA()
|
||||||
{
|
{
|
||||||
uint8_t cf = rA > 0x99;
|
uint8_t cf = rA > 0x99;
|
||||||
@@ -459,18 +366,10 @@ namespace sm83
|
|||||||
SET_FLAGS((rA ^ diff) & fH);
|
SET_FLAGS((rA ^ diff) & fH);
|
||||||
SET_PARITY_FLAG(diff);
|
SET_PARITY_FLAG(diff);
|
||||||
SET_FLAGS(cf);
|
SET_FLAGS(cf);
|
||||||
/* FLAGS = (zuint8)(
|
|
||||||
(F & (NF | CF)) | // NF unchanged; CF dominant
|
|
||||||
(t & SYXF) | // SF = sign; YF = Y; XF = X
|
|
||||||
ZF_ZERO(t) | // ZF = zero
|
|
||||||
((A ^ t) & HF) | // HF = Ai.4 != Ao.4
|
|
||||||
PF_PARITY(t) | // PF = parity
|
|
||||||
cf); // CF |= 1 (if BCD carry)
|
|
||||||
*/
|
|
||||||
rA = diff;
|
rA = diff;
|
||||||
t+=4;
|
t+=4;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void DAA()
|
void DAA()
|
||||||
{
|
{
|
||||||
bool carry_set = false;
|
bool carry_set = false;
|
||||||
@@ -479,112 +378,87 @@ namespace sm83
|
|||||||
rA += 0x06;
|
rA += 0x06;
|
||||||
if ( (rA >> 4)>9 || (rF & fC) ) { rA += 0x60; carry_set = true; }
|
if ( (rA >> 4)>9 || (rF & fC) ) { rA += 0x60; carry_set = true; }
|
||||||
KEEP_FLAGS(fN);
|
KEEP_FLAGS(fN);
|
||||||
FLAGS_SZXY(rA);
|
if (rA==0) SET_FLAGS(fZ);
|
||||||
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
||||||
if (carry_set) SET_FLAGS(fC);
|
if (carry_set) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(rA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPL()
|
void CPL()
|
||||||
{
|
{
|
||||||
rA = ~rA;
|
rA = ~rA;
|
||||||
KEEP_FLAGS(fS | fZ | fP | fC);
|
KEEP_FLAGS(fZ | fC);
|
||||||
SET_FLAGS(fH | fN);
|
SET_FLAGS(fH | fN);
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCF()
|
void SCF()
|
||||||
{
|
{
|
||||||
KEEP_FLAGS( fS | fZ | fP );
|
KEEP_FLAGS( fZ );
|
||||||
SET_FLAGS(fC);
|
SET_FLAGS(fC);
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCF()
|
void CCF()
|
||||||
{
|
{
|
||||||
const bool carry = (rF & fC);
|
const bool carry = (rF & fC);
|
||||||
KEEP_FLAGS( fS | fZ | fP );
|
KEEP_FLAGS( fZ );
|
||||||
SET_FLAGS(carry ? fH : fC);
|
SET_FLAGS(carry ? fH : fC);
|
||||||
SET_FLAGS(rA & (fX | fY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DJNZ()
|
void JR(uint8_t cond = cUnconditional)
|
||||||
{
|
{
|
||||||
const int8_t d = (int8_t)READ_MEM_8();
|
const int8_t d = (int8_t)READ_MEM_8();
|
||||||
rB--;
|
if ( cond == cUnconditional ||
|
||||||
if (rB!=0)
|
|
||||||
{
|
|
||||||
rPC = rPC + d;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JR(uint8_t cond = cNO)
|
|
||||||
{
|
|
||||||
const int8_t d = (int8_t)READ_MEM_8();
|
|
||||||
if ( cond == cNO ||
|
|
||||||
( (cond == cNZ) && !(rF & fZ) ) ||
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
||||||
( (cond == cZ) && (rF & fZ) ) ||
|
( (cond == cZ) && (rF & fZ) ) ||
|
||||||
( (cond == cNC) && !(rF & fC) ) ||
|
( (cond == cNC) && !(rF & fC) ) ||
|
||||||
( (cond == cC) && (rF & fC) ) )
|
( (cond == cC) && (rF & fC) ) )
|
||||||
{
|
{
|
||||||
rPC = rPC + d;
|
rPC = rPC + d;
|
||||||
t+=5;
|
t+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JP(uint8_t cond, uint16_t addr)
|
void JP(uint8_t cond, uint16_t addr, const bool fast = false)
|
||||||
{
|
{
|
||||||
if ( cond == cNO ||
|
if ( cond == cUnconditional ||
|
||||||
( (cond == cNZ) && !(rF & fZ) ) ||
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
||||||
( (cond == cZ) && (rF & fZ) ) ||
|
( (cond == cZ) && (rF & fZ) ) ||
|
||||||
( (cond == cNC) && !(rF & fC) ) ||
|
( (cond == cNC) && !(rF & fC) ) ||
|
||||||
( (cond == cC) && (rF & fC) ) ||
|
( (cond == cC) && (rF & fC) ) )
|
||||||
( (cond == cPO) && !(rF & fV) ) ||
|
|
||||||
( (cond == cPE) && (rF & fV) ) ||
|
|
||||||
( (cond == cM) && (rF & fS) ) ||
|
|
||||||
( (cond == cP) && !(rF & fS) ) )
|
|
||||||
rPC = addr;
|
rPC = addr;
|
||||||
|
if (!fast) t+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALL(uint8_t cond, uint16_t addr)
|
void CALL(uint8_t cond, uint16_t addr)
|
||||||
{
|
{
|
||||||
if ( cond == cNO ||
|
if ( cond == cUnconditional ||
|
||||||
( (cond == cNZ) && !(rF & fZ) ) ||
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
||||||
( (cond == cZ) && (rF & fZ) ) ||
|
( (cond == cZ) && (rF & fZ) ) ||
|
||||||
( (cond == cNC) && !(rF & fC) ) ||
|
( (cond == cNC) && !(rF & fC) ) ||
|
||||||
( (cond == cC) && (rF & fC) ) ||
|
( (cond == cC) && (rF & fC) ) )
|
||||||
( (cond == cPO) && !(rF & fV) ) ||
|
|
||||||
( (cond == cPE) && (rF & fV) ) ||
|
|
||||||
( (cond == cM) && (rF & fS) ) ||
|
|
||||||
( (cond == cP) && !(rF & fS) ) )
|
|
||||||
{
|
{
|
||||||
PUSH(rPC);
|
PUSH(rPC);
|
||||||
rPC = addr;
|
rPC = addr;
|
||||||
|
|
||||||
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
/*if (options[Z80_OPTION_BREAK_ON_RET]) {
|
||||||
calls_stacked++;
|
calls_stacked++;
|
||||||
printf("CALL: calls stacked: %i", calls_stacked);
|
printf("CALL: calls stacked: %i", calls_stacked);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RET(uint8_t cond)
|
void RET(uint8_t cond)
|
||||||
{
|
{
|
||||||
if ( cond == cNO ||
|
t+=4;
|
||||||
|
if ( cond == cUnconditional ||
|
||||||
( (cond == cNZ) && !(rF & fZ) ) ||
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
||||||
( (cond == cZ) && (rF & fZ) ) ||
|
( (cond == cZ) && (rF & fZ) ) ||
|
||||||
( (cond == cNC) && !(rF & fC) ) ||
|
( (cond == cNC) && !(rF & fC) ) ||
|
||||||
( (cond == cC) && (rF & fC) ) ||
|
( (cond == cC) && (rF & fC) ) )
|
||||||
( (cond == cPO) && !(rF & fV) ) ||
|
|
||||||
( (cond == cPE) && (rF & fV) ) ||
|
|
||||||
( (cond == cM) && (rF & fS) ) ||
|
|
||||||
( (cond == cP) && !(rF & fS) ) )
|
|
||||||
{
|
{
|
||||||
POP(_rPC);
|
POP(_rPC);
|
||||||
if (cond != cNO) t++;
|
if (cond != cUnconditional) t += 4;
|
||||||
|
|
||||||
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
/*if (options[Z80_OPTION_BREAK_ON_RET]) {
|
||||||
if (calls_stacked>0) {
|
if (calls_stacked>0) {
|
||||||
calls_stacked--;
|
calls_stacked--;
|
||||||
printf("RET: calls still stacked: %i\n", calls_stacked);
|
printf("RET: calls still stacked: %i\n", calls_stacked);
|
||||||
@@ -595,63 +469,70 @@ namespace sm83
|
|||||||
z80debug::history::store();
|
z80debug::history::store();
|
||||||
z80debug::stop();
|
z80debug::stop();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
} else {
|
|
||||||
t++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RETN()
|
void processInterrupts()
|
||||||
{
|
{
|
||||||
POP(_rPC);
|
const uint8_t IF = mem::readMem(0xff0f);
|
||||||
iff1 = iff2;
|
if ( (IF & 0x1f) == 0) return;
|
||||||
|
DI();
|
||||||
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
PUSH(rPC);
|
||||||
options[Z80_OPTION_BREAK_ON_RET] = false;
|
t+=20;
|
||||||
|
if (IF & INTERRUPT_VBLANK) {
|
||||||
|
rPC = 0x40;
|
||||||
|
mem::writeMem(0xff0f, IF & ~INTERRUPT_VBLANK);
|
||||||
|
} else if (IF & INTERRUPT_LCD) {
|
||||||
|
rPC = 0x40;
|
||||||
|
mem::writeMem(0xff0f, IF & ~INTERRUPT_LCD);
|
||||||
|
} else if (IF & INTERRUPT_TIMER) {
|
||||||
|
rPC = 0x40;
|
||||||
|
mem::writeMem(0xff0f, IF & ~INTERRUPT_TIMER);
|
||||||
|
} else if (IF & INTERRUPT_SERIAL) {
|
||||||
|
rPC = 0x40;
|
||||||
|
mem::writeMem(0xff0f, IF & ~INTERRUPT_SERIAL);
|
||||||
|
} else if (IF & INTERRUPT_JOYPAD) {
|
||||||
|
rPC = 0x40;
|
||||||
|
mem::writeMem(0xff0f, IF & ~INTERRUPT_JOYPAD);
|
||||||
|
}
|
||||||
|
/*if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
||||||
|
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
||||||
z80debug::setcursor(rPC);
|
z80debug::setcursor(rPC);
|
||||||
z80debug::history::store();
|
z80debug::history::store();
|
||||||
z80debug::stop();
|
z80debug::stop();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RETI()
|
void RETI()
|
||||||
{
|
{
|
||||||
RETN();
|
RET(cUnconditional);
|
||||||
|
*_rIME = 1;
|
||||||
|
processInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RST(uint8_t vec)
|
void RST(uint8_t vec)
|
||||||
{
|
{
|
||||||
|
t-=4; // PUSH i RST duren el mateix en la gameboy, per tant llevem els 4 t que duiem de llegir el opcode
|
||||||
PUSH(rPC);
|
PUSH(rPC);
|
||||||
rPC = vec;
|
rPC = vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IM(uint8_t mode)
|
|
||||||
{
|
|
||||||
im = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EX_MEM(uint16_t *reg, uint16_t addr)
|
|
||||||
{
|
|
||||||
auto temp = *reg;
|
|
||||||
*reg = READ_MEM_16(addr);
|
|
||||||
WRITE_MEM_16(addr, temp);
|
|
||||||
t+=3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DI()
|
void DI()
|
||||||
{
|
{
|
||||||
iff1 = iff2 = 0;
|
pending_ei = 0; // If interrupts are disabled right after enabling them, they keep disabled
|
||||||
|
*_rIME = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EI()
|
void EI()
|
||||||
{
|
{
|
||||||
pending_ei=1;
|
pending_ei = 1; // Enabling interrupts is delayed by one instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
void actualEI()
|
void actualEI()
|
||||||
{
|
{
|
||||||
iff1 = iff2 = 1;
|
*_rIME = 1;
|
||||||
|
processInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HALT()
|
void HALT()
|
||||||
@@ -664,38 +545,21 @@ namespace sm83
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void interrupt()
|
void interrupt(uint8_t type)
|
||||||
{
|
{
|
||||||
if (!iff1) return;
|
|
||||||
DI();
|
|
||||||
exit_from_halt = true;
|
exit_from_halt = true;
|
||||||
PUSH(rPC);
|
const uint8_t IE = mem::readMem(0xffff);
|
||||||
uint16_t address;
|
const uint8_t IF = mem::readMem(0xff0f);
|
||||||
if (im==1) {
|
mem::writeMem(0xff0f, IF || (IE & type));
|
||||||
rPC = 0x38;
|
processInterrupts();
|
||||||
} else if (im==2) {
|
|
||||||
address = (rI<<8) | 0xFE;
|
|
||||||
rPC = READ_MEM_16(address);
|
|
||||||
} else if (im==0) {
|
|
||||||
printf("Interrupt mode 0!\n");
|
|
||||||
z80debug::stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
|
||||||
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
|
||||||
z80debug::setcursor(rPC);
|
|
||||||
z80debug::history::store();
|
|
||||||
z80debug::stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const uint8_t RLC(const uint8_t v)
|
static inline const uint8_t RLC(const uint8_t v)
|
||||||
{
|
{
|
||||||
const uint8_t res = (v>>7) | (v<<1);
|
const uint8_t res = (v>>7) | (v<<1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (res&1) SET_FLAGS(fC);
|
if (res&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,9 +567,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v<<7) | (v>>1);
|
const uint8_t res = (v<<7) | (v>>1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (res&0x80) SET_FLAGS(fC);
|
if (res&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,9 +576,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v<<1) | (rF&fC);
|
const uint8_t res = (v<<1) | (rF&fC);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,9 +585,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = ((rF&fC)<<7) | (v>>1);
|
const uint8_t res = ((rF&fC)<<7) | (v>>1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,9 +594,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v<<1);
|
const uint8_t res = (v<<1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,9 +603,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v&0x80) | (v>>1);
|
const uint8_t res = (v&0x80) | (v>>1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,9 +612,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v<<1) | 1;
|
const uint8_t res = (v<<1) | 1;
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&0x80) SET_FLAGS(fC);
|
if (v&0x80) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,9 +621,8 @@ namespace sm83
|
|||||||
{
|
{
|
||||||
const uint8_t res = (v>>1);
|
const uint8_t res = (v>>1);
|
||||||
rF=0;
|
rF=0;
|
||||||
FLAGS_SZXY(res);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (v&1) SET_FLAGS(fC);
|
if (v&1) SET_FLAGS(fC);
|
||||||
SET_PARITY_FLAG(res);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,10 +631,7 @@ namespace sm83
|
|||||||
const uint8_t res = v & 1<<pos;
|
const uint8_t res = v & 1<<pos;
|
||||||
KEEP_FLAGS(fC);
|
KEEP_FLAGS(fC);
|
||||||
SET_FLAGS(fH);
|
SET_FLAGS(fH);
|
||||||
if (!res) SET_FLAGS(fZ | fP);
|
if (res==0) SET_FLAGS(fZ);
|
||||||
if (res&0x80) SET_FLAGS(fS);
|
|
||||||
if (res&0x20) SET_FLAGS(fY);
|
|
||||||
if (res&0x08) SET_FLAGS(fX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const uint8_t SET(uint8_t pos, const uint8_t v)
|
static inline const uint8_t SET(uint8_t pos, const uint8_t v)
|
||||||
@@ -790,245 +644,42 @@ namespace sm83
|
|||||||
return v & ~(1<<pos);
|
return v & ~(1<<pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LDI()
|
void LDI_A_HL()
|
||||||
{
|
{
|
||||||
WRITE_MEM_8(rDE, READ_MEM_8(rHL));
|
rA = READ_MEM_8(rHL);
|
||||||
rDE++;
|
|
||||||
rHL++;
|
rHL++;
|
||||||
rBC--;
|
|
||||||
t+=2;
|
|
||||||
KEEP_FLAGS(fS | fZ | fC);
|
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LDIR()
|
void LDI_HL_A()
|
||||||
{
|
{
|
||||||
LDI();
|
WRITE_MEM_8(rHL, rA);
|
||||||
if (rBC!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LDD()
|
|
||||||
{
|
|
||||||
WRITE_MEM_8(rDE, READ_MEM_8(rHL));
|
|
||||||
rDE--;
|
|
||||||
rHL--;
|
|
||||||
rBC--;
|
|
||||||
t+=2;
|
|
||||||
KEEP_FLAGS(fS | fZ | fC);
|
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LDDR()
|
|
||||||
{
|
|
||||||
LDD();
|
|
||||||
if (rBC!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t CPI()
|
|
||||||
{
|
|
||||||
bool keep_fC = (rF & fC);
|
|
||||||
const uint8_t hlmem = READ_MEM_8(rHL);
|
|
||||||
CP(hlmem);
|
|
||||||
rHL++;
|
rHL++;
|
||||||
rBC--;
|
|
||||||
t+=2;
|
|
||||||
KEEP_FLAGS(fS | fZ | fH | fN);
|
|
||||||
if (keep_fC) SET_FLAGS(fC);
|
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
|
||||||
//if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
|
||||||
return hlmem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPIR()
|
void LDD_A_HL()
|
||||||
{
|
{
|
||||||
const uint8_t hlmem = CPI();
|
rA = READ_MEM_8(rHL);
|
||||||
if (rBC!=0 && hlmem!=rA)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPD()
|
|
||||||
{
|
|
||||||
bool keep_fC = (rF & fC);
|
|
||||||
CP(READ_MEM_8(rHL));
|
|
||||||
rHL--;
|
rHL--;
|
||||||
rBC--;
|
|
||||||
t+=2;
|
|
||||||
KEEP_FLAGS(fS | fZ | fH | fN);
|
|
||||||
if (keep_fC) SET_FLAGS(fC);
|
|
||||||
if (rBC!=0) SET_FLAGS(fP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPDR()
|
|
||||||
{
|
|
||||||
CPD();
|
|
||||||
if (rBC!=0 && READ_MEM_8(rHL)!=rA)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t IN(int port = 0x10000)
|
void LDD_HL_A()
|
||||||
{
|
{
|
||||||
bool set_flags=true;
|
WRITE_MEM_8(rHL, rA);
|
||||||
t+=4;
|
|
||||||
|
|
||||||
if (port == 0x10000) {
|
|
||||||
port = rBC;
|
|
||||||
} else {
|
|
||||||
set_flags=false;
|
|
||||||
port = (rA<<8) | port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_ports[port&0xff]) {
|
|
||||||
const uint8_t val = (uint8_t)in_ports[port&0xff](port);
|
|
||||||
if (set_flags) {
|
|
||||||
KEEP_FLAGS(fC);
|
|
||||||
SET_PARITY_FLAG(val);
|
|
||||||
FLAGS_SZXY(val);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
} else
|
|
||||||
return 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OUT(uint8_t val, int port = 0x10000)
|
|
||||||
{
|
|
||||||
t+=4;
|
|
||||||
if (port == 0x10000) {
|
|
||||||
port = rBC;
|
|
||||||
if (rC==0xfe) port = 0xfe;
|
|
||||||
}
|
|
||||||
if (out_ports[port&0xff]) out_ports[port&0xff](port, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void INI()
|
|
||||||
{
|
|
||||||
DEC8(_rB);
|
|
||||||
const uint8_t flags_after_dec = rF;
|
|
||||||
const uint8_t val = IN();
|
|
||||||
WRITE_MEM_8(rHL, val);
|
|
||||||
rHL++;
|
|
||||||
SET_FLAGS(flags_after_dec);
|
|
||||||
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
||||||
if (val&0x80) SET_FLAGS(fN);
|
|
||||||
uint16_t k = val + ((rC+1)&255);
|
|
||||||
if (k>255) SET_FLAGS(fH | fC);
|
|
||||||
SET_PARITY_FLAG((k&7)^rB);
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void INIR()
|
|
||||||
{
|
|
||||||
INI();
|
|
||||||
if (rB!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IND()
|
|
||||||
{
|
|
||||||
DEC8(_rB);
|
|
||||||
const uint8_t flags_after_dec = rF;
|
|
||||||
const uint8_t val = IN();
|
|
||||||
WRITE_MEM_8(rHL, val);
|
|
||||||
rHL--;
|
rHL--;
|
||||||
SET_FLAGS(flags_after_dec);
|
|
||||||
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
||||||
if (val&0x80) SET_FLAGS(fN);
|
|
||||||
uint16_t k = val + ((rC-1)&255);
|
|
||||||
if (k>255) SET_FLAGS(fH | fC);
|
|
||||||
SET_PARITY_FLAG((k&7)^rB);
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void INDR()
|
|
||||||
{
|
|
||||||
IND();
|
|
||||||
if (rB!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OUTI()
|
|
||||||
{
|
|
||||||
const uint8_t val = READ_MEM_8(rHL);
|
|
||||||
OUT(val);
|
|
||||||
rHL++;
|
|
||||||
DEC8(_rB);
|
|
||||||
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
||||||
if (val&0x80) SET_FLAGS(fN);
|
|
||||||
uint16_t k = rL+val;
|
|
||||||
if (k>255) SET_FLAGS(fH | fC);
|
|
||||||
SET_PARITY_FLAG((k&7)^rB);
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OUTIR()
|
|
||||||
{
|
|
||||||
OUTI();
|
|
||||||
if (rB!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OUTD() {
|
|
||||||
const uint8_t val = READ_MEM_8(rHL);
|
|
||||||
OUT(val);
|
|
||||||
rHL--;
|
|
||||||
DEC8(_rB);
|
|
||||||
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
||||||
if (val&0x80) SET_FLAGS(fN);
|
|
||||||
uint16_t k = rL+val;
|
|
||||||
if (k>255) SET_FLAGS(fH | fC);
|
|
||||||
SET_PARITY_FLAG((k&7)^rB);
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OUTDR() {
|
|
||||||
OUTD();
|
|
||||||
if (rB!=0)
|
|
||||||
{
|
|
||||||
rPC-=2;
|
|
||||||
t+=5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void INVALID(uint8_t opcode)
|
void INVALID(uint8_t opcode)
|
||||||
{
|
{
|
||||||
printf("INVALID OPCODE AT: %04x\n", current_opcode_address);
|
printf("INVALID OPCODE AT: %04x\n", current_opcode_address);
|
||||||
if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop();
|
//if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
for (int i=0; i<256; ++i)
|
mem::reset();
|
||||||
{
|
|
||||||
in_ports[i] = nullptr;
|
|
||||||
out_ports[i] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
z80mem::get()->reset();
|
rPC = ime = 0;
|
||||||
|
rAF = rBC = rDE = rHL = rSP = 0xffff;
|
||||||
rPC = iff1 = iff2 = im = 0;
|
|
||||||
rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff;
|
|
||||||
t = 0;
|
t = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,17 +694,6 @@ namespace sm83
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BIT_INSTRUCTIONS();
|
void BIT_INSTRUCTIONS();
|
||||||
void IX_INSTRUCTIONS();
|
|
||||||
void IX_BIT_INSTRUCTIONS();
|
|
||||||
void MISC_INSTRUCTIONS();
|
|
||||||
void IY_INSTRUCTIONS();
|
|
||||||
void IY_BIT_INSTRUCTIONS();
|
|
||||||
|
|
||||||
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int))
|
|
||||||
{
|
|
||||||
if (in_ptr) in_ports[num] = in_ptr;
|
|
||||||
if (out_ptr) out_ports[num] = out_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool opcode_ignored = false;
|
bool opcode_ignored = false;
|
||||||
uint32_t step()
|
uint32_t step()
|
||||||
@@ -1064,14 +704,14 @@ namespace sm83
|
|||||||
t = 0;
|
t = 0;
|
||||||
const uint8_t opcode = READ_M1();
|
const uint8_t opcode = READ_M1();
|
||||||
|
|
||||||
uint8_t tag = z80mem::get()->getTag(current_opcode_address);
|
/*uint8_t tag = z80mem::get()->getTag(current_opcode_address);
|
||||||
if ( !(tag & MEMTAG_IGNORE) )
|
if ( !(tag & MEMTAG_IGNORE) )
|
||||||
tag = tag | MEMTAG_INST;
|
tag = tag | MEMTAG_INST;
|
||||||
z80mem::get()->setTag(current_opcode_address, tag | (!(tag&MEMTAG_TOUCHED) ? MEMTAG_TREPEAT : MEMTAG_TINST) );
|
z80mem::get()->setTag(current_opcode_address, tag | (!(tag&MEMTAG_TOUCHED) ? MEMTAG_TREPEAT : MEMTAG_TINST) );*/
|
||||||
|
|
||||||
uint16_t tmp;
|
uint16_t tmp;
|
||||||
|
|
||||||
if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0);
|
//if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0);
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
@@ -1322,7 +962,7 @@ namespace sm83
|
|||||||
case 0xE6: AND(READ_MEM_8()); break;
|
case 0xE6: AND(READ_MEM_8()); break;
|
||||||
case 0xE7: RST(0x20); break;
|
case 0xE7: RST(0x20); break;
|
||||||
case 0xE8: RET(cPE); break;
|
case 0xE8: RET(cPE); break;
|
||||||
case 0xE9: JP(cNO, rHL); break;
|
case 0xE9: JP(cNO, rHL, true); break;
|
||||||
case 0xEA: JP(cPE, READ_MEM_16()); break;
|
case 0xEA: JP(cPE, READ_MEM_16()); break;
|
||||||
case 0xEB: EX(rDE, rHL); break;
|
case 0xEB: EX(rDE, rHL); break;
|
||||||
case 0xEC: CALL(cPE, READ_MEM_16()); break;
|
case 0xEC: CALL(cPE, READ_MEM_16()); break;
|
||||||
|
|||||||
8
sm83.h
8
sm83.h
@@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
namespace sm83
|
namespace sm83
|
||||||
{
|
{
|
||||||
|
#define INTERRUPT_VBLANK 0x01
|
||||||
|
#define INTERRUPT_LCD 0x02
|
||||||
|
#define INTERRUPT_TIMER 0x04
|
||||||
|
#define INTERRUPT_SERIAL 0x08
|
||||||
|
#define INTERRUPT_JOYPAD 0x10
|
||||||
|
|
||||||
#define SM83_OPTION_STOP_ON_INVALID 0
|
#define SM83_OPTION_STOP_ON_INVALID 0
|
||||||
#define SM83_OPTION_BREAK_ON_INTERRUPT 1
|
#define SM83_OPTION_BREAK_ON_INTERRUPT 1
|
||||||
#define SM83_OPTION_BREAK_ON_RET 2
|
#define SM83_OPTION_BREAK_ON_RET 2
|
||||||
@@ -14,7 +20,7 @@ namespace sm83
|
|||||||
void setClock(uint32_t freq);
|
void setClock(uint32_t freq);
|
||||||
uint32_t getClock();
|
uint32_t getClock();
|
||||||
|
|
||||||
void interrupt();
|
void interrupt(uint8_t type);
|
||||||
|
|
||||||
uint32_t step();
|
uint32_t step();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user