#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "cputest.h"
#include "initregs.h"
#include "framework.h"
#ifndef FALSE
#define FALSE (0!=0)
#endif
#ifndef TRUE
#define TRUE (0==0)
#endif
int DEBUG = TRUE;
static inline void checkDP(void) {
// hook for specific roms eg starwars to assert that DP never points to I/O space!
}
#define callinst(proc, code) do { runinst(proc, code); proc(); } while (0)
#define calltest(proc) do { runtest(#proc); proc(); } while (0)
void ANDA1(void);
void ANDA2(void);
void ANDA3(void);
void NEG0(void);
void NEG1(void);
void NEG2(void);
void NEG80(void);
void BITimm(void);
void COMA(void);
void DAA1(void);
void DAA2(void);
void DAA3(void);
void DAA4(void);
void DAA5(void);
void DAA6(void);
void DAA7(void);
void DAA8(void);
void EXGdx(void);
void TFRyx(void);
void TFRax(void);
void TFRxb(void);
void MUL(void);
void MUL2(void);
void SEX1(void);
void SEX2(void);
void TSTmemory(void);
void BGT1(void);
void BGT2(void);
void BGT3(void);
void BGT4(void);
void BGT5(void);
void BHI1(void);
void BLE1(void);
void BLE2(void);
void BLE3(void);
void BLE4(void);
void BLE5(void);
void ASRMem(void);
void ASRB1(void);
void ASRB2(void);
void LSL1(void);
void LSL2(void);
void LSL3(void);
void LSR1(void);
void LSR2(void);
void LSR3(void);
void ROLB1(void);
void ROLB2(void);
void ROLB3(void);
void RORB1(void);
void RORB2(void);
void RORB3(void);
void ABX1(void);
void ABX2(void);
void ADCANoC1(void);
void ADCANoC2(void);
void ADCAWiC(void);
void ADCAWiHC(void);
void ADDB1(void);
void ADDB2(void);
void ADDB3(void);
void ADDB4(void);
void ADDANoC(void);
void ADDAWiC(void);
void ADDDNoC(void);
void ADDD1(void);
void ADDD2(void);
void ADDD3(void);
void INCA1(void);
void INCA2(void);
void INCA3(void);
void CMP1(void);
void CMP2(void);
void CMP3(void);
void CMP16(void);
void DECA0x32(void);
void DECA0x80(void);
void DECA0x00(void);
void SBCB(void);
void SBCA1(void);
void SBCA2(void);
void SBCA3(void);
void SBCA4(void);
void SUBA1(void);
void SUBA2(void);
void SUBB1(void);
void SUBB2(void);
void SUBBY(void);
void LEAXpcr(void);
void LEAXincby2(void);
void LEAXno(void);
void LEAXinc1(void);
void LEAXinc2(void);
void Doffset1(void);
void Doffset2(void);
/**
* Tests AND A with a value ($F) loaded from the direct page.
*/
static void ANDA(void)
{
static char testins[] = {0x94, 0xEF, RTS};
char dp;
fprintf(stderr, "=================================================== ANDA:\n");
fprintf(stderr, "--------------------------------------------------- ANDA1\n");
setA(0x8B);
setCC(0x02);
setDP();
dp = getDP();
writeDPloc(0xEF, 0x0F);
callinst(ANDA1, testins);
assertA(0x0B);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertDP(dp);
fprintf(stderr, "--------------------------------------------------- ANDA2\n");
/* Test where result is 0 */
setA(0x10);
calltest(ANDA2);
assertA(0x00);
assertCC(1, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- ANDA3\n");
/* Test where the result becomes negative. */
writeDPloc(0xEF, 0xF0);
setA(0xE0);
calltest(ANDA3);
assertA(0xE0);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
/**
* Tests negation of the A register.
*/
static void NEG(void) {
static char testins[] = {0x40, RTS};
fprintf(stderr, "=================================================== NEG:\n");
fprintf(stderr, "--------------------------------------------------- NEG0\n");
copydata(CODESTRT, testins, sizeof testins);
/* Negate 0 */
setRegs(0,0,0,0,0);
setCC(0);
calltest(NEG0);
assertRegs(0,0,0,0,0);
assertCC(0, CC_C);
assertCC(0, CC_V);
fprintf(stderr, "--------------------------------------------------- NEG1 A=1 CC=0 -> A=FF C=1 V=0\n");
/* Negate 1 */
setRegs(1,0,0,0,0);
setCC(0);
calltest(NEG1);
assertRegs(0xFF,0,0,0,0);
assertCC(1, CC_C);
assertCC(0, CC_V);
fprintf(stderr, "--------------------------------------------------- NEG2\n");
/* Negate 2 */
setRegs(2,0,0,0,0);
setCC(0);
calltest(NEG2);
assertRegs(0xFE,0,0,0,0);
assertCC(1, CC_C);
assertCC(0, CC_V);
fprintf(stderr, "--------------------------------------------------- NEG80\n");
/* Negate 0x80 */
setRegs(0x80,0,0,0,0);
setCC(0);
calltest(NEG80);
assertRegs(0x80,0,0,0,0);
assertCC(1, CC_C);
assertCC(1, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
static void BITimm_(void) {
static char testins[] = {0x85, 0xAA, RTS};
fprintf(stderr, "=================================================== BITimm: A=8B CC=0F -> A=8B C0 Z0 V0 N1\n");
setA(0x8B);
setCC(0x0F);
copydata(CODESTRT, testins, sizeof testins);
calltest(BITimm);
assertA(0x8B);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
}
/**
* Complement register A.
*/
static void COMA_(void) {
static char testins[] = {0x43, RTS};
fprintf(stderr, "=================================================== COMA:\n");
setCC(0);
setA(0x74);
callinst(COMA, testins);
assertA(0x8B);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
/**
* Decimal Addition Adjust.
* The Half-Carry flag is not affected by this instruction.
* The Negative flag is set equal to the new value of bit 7 in Accumulator A.
* The Zero flag is set if the new value of Accumulator A is zero; cleared otherwise.
* The affect this instruction has on the Overflow flag is undefined.
* The Carry flag is set if the BCD addition produced a carry; cleared otherwise.
*/
static void DAA(void) {
static char testins[] = {0x19, RTS};
fprintf(stderr, "=================================================== DAA:\n");
fprintf(stderr, "--------------------------------------------------- DAA1 CC=0 A=7F -> A=85 H0 C0 Z0 N1\n");
setCC(0);
setA(0x7F);
copydata(CODESTRT, testins, sizeof testins);
calltest(DAA1);
assertA(0x85);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(1, CC_N);
assertCC(0, CC_H);
fprintf(stderr, "--------------------------------------------------- DAA2 CC=0 A=0F -> A=15 H0 C0 Z0 N0\n");
setCC(0);
setA(0x0F);
calltest(DAA2);
assertA(0x15);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertCC(0, CC_H);
fprintf(stderr, "--------------------------------------------------- DAA3 CC=0 A=99 -> A=99 H0 C0 Z0 N1\n");
setCC(0);
setA(0x99);
calltest(DAA3);
assertA(0x99);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(1, CC_N);
assertCC(0, CC_H);
fprintf(stderr, "--------------------------------------------------- DAA4 CC=0,H=1 A=40 -> A=46 H1 C0 Z0 N0\n");
/* Perform DAA on LSN if half-carry is set */
setCC(0);
setCCflag(1, CC_H);
setA(0x40);
calltest(DAA4);
assertA(0x46);
assertCC(1, CC_H);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_C);
fprintf(stderr, "--------------------------------------------------- DAA5\n");
/* Perform DAA on MSN if carry is set */
setCC(0);
setCCflag(1, CC_C);
setA(0x40);
calltest(DAA5);
assertA(0xA0);
assertCC(0, CC_H);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_C);
fprintf(stderr, "--------------------------------------------------- DAA6\n");
/* Perform DAA of 9A */
setCC(0);
setCCflag(1, CC_N); /* BUG! 0, or 1, was missing */
setA(0x9A);
calltest(DAA6);
assertA(0x00);
assertCC(0, CC_H);
assertCC(0, CC_N);
assertCC(1, CC_Z);
assertCC(1, CC_C);
fprintf(stderr, "--------------------------------------------------- DAA7\n");
/* Perform DAA of A2 */
setCC(0);
setCCflag(1, CC_N); /* BUG! 0, or 1, was missing */
setA(0xA2);
calltest(DAA7);
assertA(0x02);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_C);
}
/**
* Set A to 0x91, add 0x91, then do DAA.
* Result should be C=1.
*/
static void DAA8_(void) {
static char testins[] = {0x8b, 0x91, 0x19, RTS};
fprintf(stderr, "=================================================== DAA8: CC=0 A=91 -> A=82 C1 Z0 N1\n");
setCC(0);
setA(0x91);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
//calltest(DAA8);
callinst(DAA8, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0x82);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_C);
//system("head -28 code/DAA8.c|grep -v '// FCB'");
}
/**
* Exchange D and X.
*/
static void EXGdx_(void) {
static char testins[] = {0x1E, 0x01, RTS};
fprintf(stderr, "=================================================== EXGdx:\n");
setCC(0);
setA(0x11);
setB(0x7F);
setX(0xFF16);
callinst(EXGdx, testins);
assertA(0xFF);
assertB(0x16);
assertX(0x117F);
}
/**
* Transfers.
*/
static void TFR(void) {
/* Transfer Y to X */
static char instructions[] = {0x1F, 0x21, RTS};
fprintf(stderr, "=================================================== TFR:\n");
fprintf(stderr, "--------------------------------------------------- TFRyx\n");
instructions[1] = 0x21;
setCC(0);
setY(0x1234);
setX(0xFF16);
callinst(TFRyx, instructions);
assertY(0x1234);
assertX(0x1234);
fprintf(stderr, "--------------------------------------------------- TFRax\n");
/* Transfer A to X */
instructions[1] = 0x81;
setA(0x56);
setB(0x78);
callinst(TFRax, instructions);
assertX(0xFF56);
fprintf(stderr, "--------------------------------------------------- TFRxb\n");
/* Transfer X to B */
instructions[1] = 0x19;
setX(0x6541);
setB(0x78);
callinst(TFRxb, instructions);
assertX(0x6541);
assertB(0x41);
}
/**
* Multiply 0x0C with 0x64. Result is 0x04B0.
* The Zero flag is set if the 16-bit result is zero; cleared otherwise.
* The Carry flag is set equal to the new value of bit 7 in Accumulator B.
*/
static void MUL_(void) {
static char testins[] = {0x3D, RTS};
fprintf(stderr, "=================================================== MUL_:\n");
fprintf(stderr, "--------------------------------------------------- MUL\n");
setCCflag(0, CC_C);
setCCflag(1, CC_Z);
setA(0x0C);
setB(0x64);
callinst(MUL, testins);
assertA(0x04);
assertB(0xB0);
assertCC(0, CC_Z);
assertCC(1, CC_C);
fprintf(stderr, "--------------------------------------------------- MUL2\n");
setA(0x00);
setB(0x64);
calltest(MUL2);
assertA(0x00);
assertB(0x00);
assertCC(1, CC_Z);
assertCC(0, CC_C);
}
static void SEX(void) {
static char testins[] = {0x1D, RTS};
fprintf(stderr, "=================================================== SEX:\n");
fprintf(stderr, "--------------------------------------------------- SEX1\n");
setA(0x02);
setB(0xE6);
callinst(SEX1, testins);
assertA(0xFF);
assertB(0xE6);
fprintf(stderr, "--------------------------------------------------- SEX2\n");
setA(0x02);
setB(0x76);
calltest(SEX2);
assertA(0x00);
assertB(0x76);
}
/**
* Test the instruction TST.
* TST: The Z and N bits are affected according to the value
* of the specified operand. The V bit is cleared.
*/
static void TSTmemory_(void) {
static char testins[] = {0x4D, RTS};
fprintf(stderr, "=================================================== TSTmemory:\n");
setCC(0);
setA(0xFF);
copydata(CODESTRT, testins, sizeof testins);
calltest(TSTmemory);
assertA(0xFF);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
}
/**
* Branch on greater than. Signed conditional.
* BGT = 0x2E
*/
static void BGT(void)
{
static char instructions[] = {0x2E, 0x03, LDA, 0x01, RTS, LDA, 0x02, RTS};
fprintf(stderr, "=================================================== BGT:\n");
fprintf(stderr, "--------------------------------------------------- BGT1 A=0 CC=0 Z=1 N=0 V=0 -> A=1\n");
setA(0);
setCC(0x00);
setCCflag(1, CC_Z);
setCCflag(0, CC_N);
setCCflag(0, CC_V);
callinst(BGT1, instructions);
assertA(1);
fprintf(stderr, "--------------------------------------------------- BGT2 A=0 CC=0 Z=0 N=0 V=0 -> A=2\n");
setCCflag(0, CC_Z);
setCCflag(0, CC_N);
setCCflag(0, CC_V);
calltest(BGT2);
assertA(2);
fprintf(stderr, "--------------------------------------------------- BGT3 A=0 CC=0 Z=0 N=1 V=0 -> A=1\n");
setCCflag(0, CC_Z);
setCCflag(1, CC_N);
setCCflag(0, CC_V);
calltest(BGT3);
assertA(1);
fprintf(stderr, "--------------------------------------------------- BGT4 A=0 CC=0 Z=0 N=1 V=1 -> A=2\n");
setCCflag(0, CC_Z);
setCCflag(1, CC_N);
setCCflag(1, CC_V);
calltest(BGT4);
assertA(2);
fprintf(stderr, "--------------------------------------------------- BGT5 A=0 CC=0 Z=1 N=1 V=0 -> A=1\n");
setCCflag(1, CC_Z);
setCCflag(1, CC_N);
setCCflag(0, CC_V);
calltest(BGT5);
assertA(1);
}
/**
* Branch on higher. Unsigned conditional.
* BHI = 0x22
*/
static void BHI(void)
{
static char instructions[] = {0x22, 0x03, LDA, 0x01, RTS, LDA, 0x02, RTS};
fprintf(stderr, "=================================================== BHI: A=0 CC=0 Z=1 C=0 -> A=1\n");
setA(0);
setCC(0x00);
setCCflag(1, CC_Z);
setCCflag(0, CC_C);
callinst(BHI1, instructions);
assertA(1);
}
static void BLE(void)
{
static char instructions[] = {0x2F, 0x03, LDA, 0x01, RTS, LDA, 0x02, RTS};
fprintf(stderr, "=================================================== BLE:\n");
fprintf(stderr, "--------------------------------------------------- BLE1 A=0 CC=0 Z=1 N=0 V=0 -> A=2\n");
setA(0);
setCC(0x00);
setCCflag(1, CC_Z);
setCCflag(0, CC_N);
setCCflag(0, CC_V);
callinst(BLE1, instructions);
assertA(2);
fprintf(stderr, "--------------------------------------------------- BLE2 A=0 CC=0 Z=0 N=0 V=0 -> A=1\n");
setCCflag(0, CC_Z);
setCCflag(0, CC_N);
setCCflag(0, CC_V);
calltest(BLE2);
assertA(1);
fprintf(stderr, "--------------------------------------------------- BLE3 A=0 CC=0 Z=0 N=1 V=0 -> A=2\n");
setCCflag(0, CC_Z);
setCCflag(1, CC_N);
setCCflag(0, CC_V);
calltest(BLE3);
assertA(2);
fprintf(stderr, "--------------------------------------------------- BLE4 A=0 CC=0 Z=0 N=1 V=1 -> A=1\n");
setCCflag(0, CC_Z);
setCCflag(1, CC_N);
setCCflag(1, CC_V);
calltest(BLE4);
assertA(1);
fprintf(stderr, "--------------------------------------------------- BLE5 A=0 CC=0 Z=1 N=1 V=0 -> A=2\n");
setCCflag(1, CC_Z);
setCCflag(1, CC_N);
setCCflag(0, CC_V);
calltest(BLE5);
assertA(2);
}
static void ASRMem_() {
static char instructions[] = { 0x07, 0x02, RTS };
int result;
fprintf(stderr, "=================================================== ASRMem: A=0 B=0 X=0 Y=0 U=0 CC=0 DP=??? >$02=F1 -> C=1 V=0 Z=0 N=1 >$02=F8\n");
setRegs(0,0,0,0,0);
setCC(0x00);
setDP(); // initregs->rg_dp = ((*dpLoc) >> 8);
writeDPloc(0x02, 0xF1);
callinst(ASRMem, instructions);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
result = readDPloc(0x02);
assertByte(0xf8, result, "DP[0x02]");
}
/**
* Shift a byte at 0x0402, because DP = 0x04.
*/
static void ASRB() {
static char instructions[] = { 0x57, RTS };
fprintf(stderr, "=================================================== ASRB1:\n");
setB(0xF2);
setCC(0x00);
callinst(ASRB1, instructions);
assertB(0xF9);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(1, CC_N);
fprintf(stderr, "--------------------------------------------------- ASRB2\n");
setB(0x01);
calltest(ASRB2);
assertB(0x00);
assertCC(1, CC_C);
assertCC(1, CC_Z);
assertCC(0, CC_N);
}
/**
* Test the LSL - Logical Shift Left instruction.
* H The affect on the Half-Carry flag is undefined for these instructions.
* N The Negative flag is set equal to the new value of bit 7; previously bit 6.
* Z The Zero flag is set if the new 8-bit value is zero; cleared otherwise.
* V The Overflow flag is set to the Exclusive-OR of the original values of bits 6 and 7.
* C The Carry flag receives the value shifted out of bit 7.
*
* Logical Shift Left of 0xff in register A
*/
static void LSLA() {
static char instructions[] = { 0x48, RTS };
fprintf(stderr, "=================================================== LSL1:\n");
setCC(0);
setA(0xFF);
callinst(LSL1, instructions);
assertA(0xFE);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
fprintf(stderr, "--------------------------------------------------- LSL2\n");
/* Logical Shift Left of 1. */
setCC(0);
setCCflag(1, CC_V);
setA(0x01);
callinst(LSL2, instructions);
assertA(0x02);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- LSL3\n");
/* Logical Shift Left of 0xB8. */
setCC(0);
setCCflag(0, CC_V);
setA(0xB8);
callinst(LSL3, instructions);
assertA(0x70);
assertCC(1, CC_C);
assertCC(1, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
}
/**
* Test the LSR - Logical Shift Right instruction.
* Logical Shift Right of 0x3E to 0x1F
*/
static void LSRA() {
static char instructions[] = { 0x44, RTS };
fprintf(stderr, "=================================================== LSR1:\n");
setCC(0x0F);
setA(0x3E);
callinst(LSR1, instructions);
assertA(0x1F);
assertCC(0, CC_C);
assertCC(1, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- LSR2\n");
/* Logical Shift Right of 1 */
setCCflag(0, CC_C);
setCCflag(1, CC_V);
setCCflag(1, CC_N);
setA(0x01);
callinst(LSR2, instructions);
assertA(0x00);
assertCC(1, CC_C);
assertCC(1, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- LSR3\n");
/* Logical Shift Right of 0xB8. */
setCCflag(0, CC_C);
setCCflag(0, CC_V);
setA(0xB8);
callinst(LSR3, instructions);
assertA(0x5C);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(0, CC_N);
}
/**
* Rotate 8-Bit Accumulator or Memory Byte Left through Carry.
* N The Negative flag is set equal to the new value of bit 7.
* Z The Zero flag is set if the new 8-bit value is zero; cleared otherwise.
* V The Overflow flag is set equal to the exclusive-OR of the original values of bits 6 and 7.
* C The Carry flag receives the value shifted out of bit 7.
* Rotate 0x89 to 0x13.
*/
static void ROLB() {
static char instructions[] = { 0x59, RTS };
fprintf(stderr, "=================================================== ROLB1:\n");
setB(0x89);
setCC(0);
setCCflag(1, CC_N);
setCCflag(1, CC_C);
callinst(ROLB1, instructions);
assertB(0x13);
assertCC(1, CC_V);
assertCC(1, CC_C);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- ROLB2\n");
/* Logical Shift Left of 1 with carry set */
setCCflag(1, CC_C);
setCCflag(1, CC_V);
setB(0x01);
callinst(ROLB2, instructions);
assertB(0x03);
assertCC(0, CC_V);
assertCC(0, CC_C);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- ROLB3\n");
/* Rotate Left of 0xD8 */
setCCflag(0, CC_C);
setCCflag(0, CC_V);
setB(0xD8);
callinst(ROLB3, instructions);
assertB(0xB0);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
/**
* Rotate 8-Bit Accumulator or Memory Byte Right through Carry
* N The Negative flag is set equal to the new value of bit 7 (original value of Carry).
* Z The Zero flag is set if the new 8-bit value is zero; cleared otherwise.
* V The Overflow flag is not affected by these instructions.
* C The Carry flag receives the value shifted out of bit 0.
*/
static void RORB() {
/* Rotate 0x89 with CC set to 0xC4 */
static char instructions[] = { 0x56, RTS };
fprintf(stderr, "=================================================== RORB1:\n");
setB(0x89);
setCC(0);
setCCflag(1, CC_C);
callinst(RORB1, instructions);
assertB(0xC4);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
fprintf(stderr, "--------------------------------------------------- RORB2\n");
/* Rotate 0x89 with CC clear to 0x44 */
setB(0x89);
setCC(0);
setCCflag(0, CC_C);
callinst(RORB2, instructions);
assertB(0x44);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- RORB3\n");
/* Rotate 0x08 with CC clear to 0x04 */
setB(0x08);
setCC(0);
setCCflag(0, CC_C);
callinst(RORB3, instructions);
assertB(0x04);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
}
/**
* Add Accumulator B into index register X.
* The ABX instruction was included in the 6809 instruction set for
* compatibility with the 6801 microprocessor.
* void setRegs(a, b, x, y, u)
*/
static void ABX(void)
{
static char instructions[] = {0x3a, RTS};
fprintf(stderr, "=================================================== ABX1:\n");
setRegs(0,0xCE,0x8006,0,0);
setCC(0x00);
callinst(ABX1, instructions);
assertRegs(0, 0xCE, 0x80D4, 0,0);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertCC(0, CC_H);
fprintf(stderr, "--------------------------------------------------- ABX2\n");
setRegs(0,0xD6,0x7FFE,0,0);
setCC(0x07);
callinst(ABX2, instructions);
assertRegs(0, 0xD6, 0x80D4, 0,0);
assertCC(1, CC_C);
assertCC(1, CC_V);
assertCC(1, CC_Z);
assertCC(0, CC_N);
assertCC(0, CC_H);
}
/**
* Add 2 to register A.
*/
static void ADCANoC(void) {
static char instructions[] = {0x89, 0x02, RTS};
fprintf(stderr, "=================================================== ADCANoC1:\n");
copydata(CODESTRT, instructions, sizeof instructions);
setA(5);
setCC(0);
callinst(ADCANoC1, instructions);
assertA(7);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertCC(0, CC_H);
fprintf(stderr, "--------------------------------------------------- ADCANoC2\n");
/* Test half-carry $E + $2 = $10 */
setA(0x0E);
setCC(0);
calltest(ADCANoC2);
assertA(0x10);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertCC(1, CC_H);
}
/**
* Add $22 and carry to register A ($14).
*/
static void ADCAWiC_(void) {
static char instructions[] = {0x89, 0x22, RTS};
fprintf(stderr, "=================================================== ADCAWiC:\n");
setA(0x14);
setCC(0);
setCCflag(1, CC_C);
setCCflag(1, CC_H);
callinst(ADCAWiC, instructions);
assertA(0x37);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
assertCC(0, CC_H);
}
/*
* Test that half-carry is set when adding with a carry.
*/
static void ADCAWiHC_(void) {
static char instructions[] = {
0x89, /* ADCA */
0x2B, /* value */
RTS
};
fprintf(stderr, "=================================================== ADCAWiHC:\n");
setCCflag(1, CC_C);
setA(0x14);
callinst(ADCAWiHC, instructions);
assertA(0x40);
assertCC(0, CC_C);
assertCC(1, CC_H);
}
/**
* positive + positive with overflow.
* B=0x40 + 0x41 becomes 0x81 or -127
*/
static void ADDB1_(void) {
static char instructions[] = {0xCB, 0x41, RTS};
fprintf(stderr, "=================================================== ADDB1:\n");
setCC(0);
setB(0x40);
copydata(CODESTRT, instructions, sizeof instructions);
calltest(ADDB1);
assertB(0x81);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(0, CC_C);
assertCC(0, CC_H);
}
/**
* negative + negative
* B=0xFF + 0xFF becomes 0xFE or -2
*/
static void ADDB2_(void) {
static char instructions[] = {0xCB, 0xFF, RTS};
fprintf(stderr, "=================================================== ADDB2:\n");
setCC(0);
setB(0xFF);
copydata(CODESTRT, instructions, sizeof instructions);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
calltest(ADDB2);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertB(0xFE);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "ADDB2");
}
/**
* negative + negative with overflow
* B=0xC0 + 0xBF becomes 0x7F or 127
*/
static void ADDB3_(void) {
static char instructions[] = {0xCB, 0xBF, RTS};
fprintf(stderr, "=================================================== ADDB3:\n");
setCC(0);
setB(0xC0);
copydata(CODESTRT, instructions, sizeof instructions);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
calltest(ADDB3);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertB(0x7F);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "ADDB3");
}
/**
* positive + negative with negative result
* B=0x02 + 0xFC becomes 0xFE or -2
*/
static void ADDB4_(void) {
static char instructions[] = {0xCB, 0xFC, RTS};
fprintf(stderr, "=================================================== ADDB4:\n");
setCC(0);
setB(0x02);
copydata(CODESTRT, instructions, sizeof instructions);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
calltest(ADDB4);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertB(0xFE);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "ADDB4");
}
/**
* Add 0x02 to A=0x04.
*/
static void ADDANoC_(void) {
static char instructions[] = {
0x8B, /* ADDA */
0x02, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDANoC:\n");
setCC(0);
setA(0x04);
setB(0x05);
callinst(ADDANoC, instructions);
assertA(0x06);
assertB(0x05);
assertCC(0, CC_H);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
}
/**
* The overflow (V) bit indicates signed two’s complement overflow, which occurs when the
* sign bit differs from the carry bit after an arithmetic operation.
* A=0x03 + 0xFF becomes 0x02
*/
static void ADDAWiC_(void) {
static char instructions[] = {
0x8B, /* ADDA */
0xFF, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDAWiC:\n");
setCC(0);
setA(0x03);
copydata(CODESTRT, instructions, sizeof instructions);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(ADDAWiC, instructions);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0x02);
assertCC(0, CC_N);
assertCC(0, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "ADDAWic");
}
/**
* Add 0x02B0 to D=0x0405 becomes 0x6B5.
* positive + positive = positive
*/
static void ADDDNoC_(void) {
static char instructions[] = {
0xC3, /* ADDD */
0x02, /* value */
0xB0, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDDNoC:\n");
setCC(0);
setA(0x04);
setB(0x05);
copydata(CODESTRT, instructions, sizeof instructions);
callinst(ADDDNoC, instructions);
assertA(0x06);
assertB(0xB5);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
}
/**
* Add 0xE2B0 to D=0x8405 becomes 0x66B5.
* negative + negative = positive + overflow
*/
static void ADDD1_(void) {
static char instructions[] = {
0xC3, /* ADDD */
0xE2, /* value */
0xB0, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDD1:\n");
setCC(0);
setA(0x84);
setB(0x05);
copydata(CODESTRT, instructions, sizeof instructions);
callinst(ADDD1, instructions);
assertA(0x66);
assertB(0xB5);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(1, CC_C);
}
/**
* negative + negative = negative
* Add 0xE000 to D=0xD000 becomes 0xB000
*/
static void ADDD2_(void) {
static char instructions[] = {
0xC3, /* ADDD */
0xE0, /* value */
0x00, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDD2:\n");
setCC(0);
setA(0xD0);
setB(0x00);
copydata(CODESTRT, instructions, sizeof instructions);
callinst(ADDD2, instructions);
assertA(0xB0);
assertB(0x00);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
}
/**
* positive + positive = negative + overflow
* Add 0x7000 to D=0x7000 becomes 0xE000
*/
static void ADDD3_(void) {
static char instructions[] = {
0xC3, /* ADDD */
0x70, /* value */
0x00, /* value */
RTS
};
fprintf(stderr, "=================================================== ADDD3:\n");
setCC(0);
setA(0x70);
setB(0x00);
copydata(CODESTRT, instructions, sizeof instructions);
callinst(ADDD3, instructions);
assertA(0xE0);
assertB(0x00);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(0, CC_C);
}
/**
* Increment register A.
*/
static void INCA(void) {
static char instructions[] = {
0x4C, /* INCA */
RTS
};
fprintf(stderr, "=================================================== INCA1:\n");
setCC(0);
setA(0x32);
copydata(CODESTRT, instructions, sizeof instructions);
callinst(INCA1, instructions);
assertA(0x33);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
fprintf(stderr, "--------------------------------------------------- INCA2\n");
/* Test 0x7F - special case */
setCC(0);
setA(0x7F);
copydata(CODESTRT, instructions, sizeof instructions);
calltest(INCA2);
assertA(0x80);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(0, CC_C);
fprintf(stderr, "--------------------------------------------------- INCA3\n");
/* Test 0xFF - special case */
setCC(0);
setA(0xFF);
copydata(CODESTRT, instructions, sizeof instructions);
calltest(INCA3);
assertA(0x00);
assertCC(0, CC_N);
assertCC(1, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
}
/**
* Test indirect mode: CMPA ,Y+
* We're subtracting 0xff from 0xff and incrementing Y
*/
static void CMP1_(void) {
static char testins[] = {0xA1, 0xA0, RTS};
unsigned memloc;
fprintf(stderr, "=================================================== CMP1:\n");
/* Set up a byte to test at address 0x205 */
memloc = setMem(0x205, 0xff);
setCC(0);
/* Set register Y to point to that location */
setRegs(0xff, 0, 0, memloc, 0);
/* Two bytes of instruction */
copydata(CODESTRT, testins, sizeof testins);
callinst(CMP1, testins);
assertRegs(0xff, 0, 0, memloc+1, 0);
/* assertCC(1, CC_H); */
assertCC(1, CC_Z);
}
static void CMP2_(void)
{
/* B = 0xA0, CMPB with 0xA0 */
static char testins[] = {0xC1, 0xA0, RTS};
fprintf(stderr, "=================================================== CMP2:\n");
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setB(0xA0);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(CMP2, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertCC(0, CC_N);
assertCC(1, CC_Z);
assertCC(0, CC_V);
assertCC(0, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "CMP2");
}
static void CMP3_(void)
{
static char testins[] = {0xC1, 0xA0, RTS};
fprintf(stderr, "=================================================== CMP3:\n");
/* B = 0x70, CMPB with 0xA0 */
/* positive - negative = negative + overflow */
setCC(0);
setB(0x70);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(CMP3, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertCC(1, CC_C);
assertCC(1, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "CMP3");
}
/**
* Compare 0x5410 with 0x5410.
*/
static void CMP16_(void)
{
static char testins[] = {0xBC, 0, 0, RTS}; // make a testins properly...
unsigned memloc;
fprintf(stderr, "=================================================== CMP16:\n");
setCC(0x23);
setX(0x5410);
memloc = setMem(0x33, 0x54);
(void)setMem(0x34, 0x10);
testins[1] = memloc >> 8;
testins[2] = memloc & 255;
copydata(CODESTRT, testins, sizeof testins);
callinst(CMP16, testins);
assertX(0x5410);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(1, CC_Z);
assertCC(0, CC_N);
}
/**
* Decrement register A.
*/
static void DECA(void) {
static char testins[] = {0x4A, RTS };
fprintf(stderr, "=================================================== DECA0x32:\n");
setCC(0);
setA(0x32);
copydata(CODESTRT, testins, sizeof testins);
callinst(DECA0x32, testins);
assertA(0x31);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- DECA0x80\n");
/* Test 0x80 - special case */
setA(0x80);
calltest(DECA0x80);
assertA(0x7F);
assertCC(0, CC_C);
assertCC(1, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
fprintf(stderr, "--------------------------------------------------- DECA0x00\n");
/* Test 0x00 - special case */
setA(0x00);
calltest(DECA0x00);
assertA(0xFF);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
/**
* Test the subtraction with carry instruction.
* B=0x35 - addr(0x503)=0x3 - C=1 becomes 0x31
* SBCB dp+03
*/
static void SBCB_(void) {
static char testins[] = {0xD2, 0x03, RTS};
fprintf(stderr, "=================================================== SBCB:\n");
setDP();
writeDPloc(0x03, 0x03);
setB(0x35);
setCC(0);
setCCflag(1, CC_C);
copydata(CODESTRT, testins, sizeof testins);
callinst(SBCB, testins);
assertB(0x31);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
/* assertCC(1, CC_H); */
}
/**
* Test the SBCA instruction.
* A=0xFF - 0xFE - C=1 becomes 0x00
*/
static void SBCA1_(void) {
static char testins[] = {0x82, 0xFE, RTS};
fprintf(stderr, "=================================================== SBCA1:\n");
setCCflag(1, CC_C);
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setA(0xFF);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SBCA1, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0);
assertCC(0, CC_C);
assertCC(0, CC_V);
assertCC(1, CC_Z);
assertCC(0, CC_N);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "SBCA1");
}
/**
* Test the SBCA instruction.
* A=0x00 - 0xFF - C=0 becomes 0x01
*/
static void SBCA2_(void) {
static char testins[] = {0x82, 0xFF, RTS};
fprintf(stderr, "=================================================== SBCA2:\n");
setCCflag(0, CC_C);
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setCCflag(1, CC_V);
setA(0x00);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SBCA2, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0x01);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
//systemf1("head -28 code/%s.c", "SBCA2");
}
/**
* Test the SBCA instruction.
* A=0x00 - 0x01 - C=0 becomes 0xFF
*/
static void SBCA3_(void) {
static char testins[] = {0x82, 0x01, RTS};
fprintf(stderr, "=================================================== SBCA3:\n");
setCCflag(0, CC_C);
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setCCflag(1, CC_V);
setA(0x00);
copydata(CODESTRT, testins, sizeof testins);
callinst(SBCA3, testins);
assertA(0xFF);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(1, CC_N);
}
/**
* Test the SBCA instruction.
* A=0x00 - 0xFF - C=1 becomes 0x00
*/
static void SBCA4_(void) {
static char testins[] = {0x82, 0xFF, RTS};
fprintf(stderr, "=================================================== SBCA4:\n");
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setCCflag(1, CC_V);
setCCflag(1, CC_C);
setA(0x00);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SBCA4, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0x00);
assertCC(0, CC_N);
assertCC(1, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c", "SBCA4");
}
/**
* Test the SUBA instruction.
* The overflow (V) bit indicates signed two’s complement overflow, which
* occurs when the sign bit differs from the carry bit after an arithmetic
* operation.
* A=0x00 - 0xFF becomes 0x01
* positive - negative = positive
*/
static void SUBA1_(void) {
static char testins[] = {0x80, 0xFF, RTS};
fprintf(stderr, "=================================================== SUBA1:\n");
setCCflag(1, CC_C);
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setCCflag(1, CC_V);
setA(0x00);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SUBA1, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertA(0x01);
assertCC(1, CC_C);
assertCC(0, CC_V);
assertCC(0, CC_Z);
assertCC(0, CC_N);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "SUBA1");
}
/**
* A=0x00 - 0x01 becomes 0xFF
* positive - positive = negative
*/
static void SUBA2_(void) {
static char testins[] = {0x80, 0x01, RTS};
fprintf(stderr, "=================================================== SUBA2:\n");
setCCflag(1, CC_C);
setCCflag(1, CC_N);
setCCflag(0, CC_Z);
setCCflag(1, CC_V);
setA(0x00);
copydata(CODESTRT, testins, sizeof testins);
callinst(SUBA2, testins);
assertA(0xFF);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
}
/**
* Test the subtraction instruction.
* IMMEDIATE mode: B=0x02 - 0xB3 becomes 0x4F
* positive - negative = positive
*/
static void SUBB1_(void) {
static char testins[] = {0xC0, 0xB3, RTS};
fprintf(stderr, "=================================================== SUBB1 -> N=0 Z=0 V=0 C=1:\n");
setB(0x02);
setCC(0);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SUBB1, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertB(0x4F);
assertCC(0, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "SUBB1");
}
/**
* Test the subtraction instruction.
* IMMEDIATE mode: B=0x02 - 0x81 becomes 0x81
* positive - negative = negative + overflow
*/
static void SUBB2_(void) {
static char testins[] = {0xC0, 0x81, RTS};
fprintf(stderr, "=================================================== SUBB2: -> N=1 Z=0 V=1 C=1\n");
setB(0x02);
setCC(0);
copydata(CODESTRT, testins, sizeof testins);
//printCtl(CTLMEMSIZE); DEBUG = TRUE;
callinst(SUBB2, testins);
//DEBUG = FALSE; printCtl(CTLMEMSIZE);
assertB(0x81);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(1, CC_V);
assertCC(1, CC_C);
//systemf1("head -28 code/%s.c|grep -v '// FCB'", "SUBB2");
}
/**
* Example from Programming the 6809.
* 0x03 - 0x21 = 0xE2
* positive - positive = negative
*/
static void SUBBY_(void) {
unsigned memloc;
static char testins[] = {0xE0, 0xA4, RTS};
fprintf(stderr, "=================================================== SUBBY: -> N=1 Z=0 V=0 C=1\n");
setB(0x03);
setCC(0);
setCCflag(1, CC_Z);
memloc = setMem(0x21, 0x21);
setY(memloc);
callinst(SUBBY, testins);
assertB(0xE2);
assertCC(1, CC_N);
assertCC(0, CC_Z);
assertCC(0, CC_V);
assertCC(1, CC_C);
}
// indirect.c
/**
*/
static void LEAXpcr_(void)
{
static char instructions[] = {0x30, 0x8C, 0xE4, RTS};
fprintf(stderr, "=================================================== SUBBY: -> N=1 Z=0 V=0 C=1\n");
setCC(0x00);
setX(0x1234);
callinst(LEAXpcr, instructions);
assertX(CODESTRT - 25);
assertCC(0, CC_Z);
}
/*
* Increment X by 2.
*/
static void LEAXincby2_(void)
{
static char instructions[] = {0x30, 0x02, RTS};
fprintf(stderr, "=================================================== LEAXincby2:\n");
setCC(0x00);
setX(0x1234);
callinst(LEAXincby2, instructions);
assertX(0x1236);
assertCC(0, CC_Z);
}
/**
* LEAX from Y with no offset.
*/
static void LEAXno_(void)
{
static char instructions[] = {0x30, 0xA4, RTS};
fprintf(stderr, "=================================================== LEAXno:\n");
setCC(0x00);
setX(0x1234);
setY(0x4321);
callinst(LEAXno, instructions);
assertX(0x4321);
assertCC(0, CC_Z);
}
static void LEAXinc_(void)
{
static char instructions[] = {0x30, 0xA0, RTS};
fprintf(stderr, "=================================================== LEAXinc1:\n");
setCC(0x00);
setX(0x1234);
setY(0x4321);
callinst(LEAXinc1, instructions);
assertX(0x4321);
assertY(0x4322);
assertCC(0, CC_Z);
fprintf(stderr, "--------------------------------------------------- LEAXinc2\n");
setCC(0x00);
setY(0x0);
callinst(LEAXinc2, instructions);
assertX(0x0);
assertY(0x1);
assertCC(1, CC_Z);
}
/**
* LEAX D,Y
*/
static void Doffset_(void)
{
static char instructions[] = {0x30, 0xAB, RTS};
fprintf(stderr, "=================================================== Doffset1:\n");
setCC(0x00);
setX(0xABCD);
setY(0x804F);
setA(0x80);
setB(0x01);
callinst(Doffset1, instructions);
assertX(0x50);
assertCC(0, CC_Z);
fprintf(stderr, "--------------------------------------------------- Doffset2 CC=0x28 X=0EFA Y=0EF8 A=FF B=82 -> X=8E7A Z=0\n");
setCC(0x28);
setX(0x0EFA);
setY(0x0EF8);
setA(0xFF);
setB(0x82);
callinst(Doffset2, instructions);
assertX(0x0E7A);
assertCC(0, CC_Z);
}
int main(int argc, char **argv)
{
setupCtl();
ANDA();
NEG();
BITimm_();
COMA_();
DAA();
DAA8_();
EXGdx_();
TFR();
MUL_();
SEX();
TSTmemory_();
BGT();
BHI();
BLE();
ASRMem_();
ASRB();
LSLA();
LSRA();
ROLB();
RORB();
ABX();
ADCANoC();
ADCAWiC_();
ADCAWiHC_();
ADDB1_();
ADDB2_();
ADDB3_();
ADDB4_();
ADDANoC_();
ADDDNoC_(); // added.
ADDAWiC_();
ADDD1_();
ADDD2_();
ADDD3_();
INCA();
CMP1_();
CMP2_();
CMP3_();
CMP16_();
DECA();
SBCB_();
SBCA1_();
SBCA2_();
SBCA3_();
SBCA4_();
SUBA1_();
SUBA2_();
SUBB1_();
SUBB2_();
SUBBY_();
LEAXpcr_();
LEAXincby2_();
LEAXinc_();
LEAXno_();
Doffset_();
exit(0);
return 0;
}
#ifdef SBT
typedef uint32_t UINT32;
typedef int32_t SINT32;
typedef uint16_t UINT16;
typedef int16_t SINT16;
typedef uint8_t UINT8;
typedef int8_t SINT8;
UINT8 /* memory[0x10000], */ *memory_DP = &memory[0x0000];
// Modify this header to suit your target...
SINT32 res, A, B, /* D, */ C;
UINT16 PC, X, Y, S, U, Z, DP, arg, ea, val;
UINT8 E, F, I, N, H, V, CC, msn, lsn;
#define JUMP continue
// BUG? changing H from 0x10 to 0x20 ... NOW BACK AGAIN
#define simplify_flags() do { N = (((SINT8)N < 0)?1:0); \
V = (((SINT8)V < 0)?1:0); \
Z = ((Z == 0)?1:0); \
C = ((C != 0)?1:0); \
H = (((H & 0x10) != 0)?1:0); \
} while (0)
#define restore_flags() do { N = (N==1 ? 0x80:0); \
V = (V==1 ? 0x80:0); \
Z = (Z==1 ? 0 : 1); \
C = (C==1 ? 0x100 : 0); \
H = (H==1 ? 0x10 : 0); \
} while (0)
#ifdef NEVER
#define restore_flags() do { N = (N ? 0x80:0); \
V = (V ? 0x80:0); \
Z = (Z ? 0 : 1); \
C = (C ? 0x100 : 0); \
H = (H ? 0x20 : 0); \
} while (0)
#endif
void mon(char *str) {
int off=strlen("ENTRYPT PSHS U,Y,X,DP,B,A,CC ; ");
if (!DEBUG) return;
simplify_flags();
CC = (((((((((((((E<<1) | F)<<1) | H)<<1) |I)<<1) | N)<<1) | Z)<<1) | V)<<1) | C;
fprintf(stderr, "PC=%c%c%c%c A=%02x B=%02x X=%04x Y=%04x S=%04x U=%04x CC=%02x DP=%02x E%cF%cH%cI%cC%cZ%cV%cN%c %s",
str[off+0], str[off+1], str[off+2], str[off+3], A, B, X, Y, S, U, CC, (UINT8)(DP>>8),
E+'0', F+'0', H+'0', I+'0', C+'0', Z+'0', V+'0', N+'0', str);
restore_flags();
//printMem(0x046e, 2);fprintf(stderr, "\n");
}
// S = (save_s[0]&255)<<8 | (save_s[1]&255);
#define INITREGS() do { PC = 0x400; \
memory[0x03FE] = 0xFF; memory[0x03FF] = 0xFF; S = 0x3FE; \
A = initregs->rg_a&255; \
B = initregs->rg_b&255; \
X = Host(initregs->rg_x&65535); \
Y = Host(initregs->rg_y&65535); \
U = Host(initregs->rg_u&65535); \
CC = initregs->rg_cc&255; \
C = CC; V = C>>1; Z = V>>1; N = Z>>1; I = N>>1; H = I>>1; F = H>>1; E = (F>>1)&1; F &= 1; H &= 1; I &= 1; N &= 1; Z &= 1; V &= 1; C &= 1; \
restore_flags(); \
DP = (initregs->rg_dp&255) << 8; \
memory_DP = &memory[DP]; \
} while(0)
#define RESTOREREGS() do { ; } while(0)
/*
#define RESTOREREGS() do { \
simplify_flags(); \
CC = (((((((((((((E<<1) | F)<<1) | H)<<1) |I)<<1) | N)<<1) | Z)<<1) | V)<<1) | C; \
initregs->rg_cc = CC; \
initregs->rg_a = A; \
initregs->rg_b = B; \
initregs->rg_dp = (DP>>8)&255; \
initregs->rg_x = Micro(X); \
initregs->rg_y = Micro(Y); \
initregs->rg_u = Micro(U); \
} while(0)
*/
#define DEFPROC(proc) void proc(void) { \
INITREGS(); \
for (;;) { \
switch (PC) {
#define ENDPROC() \
case 0xFFFF: /* fake return address means return to framework.c caller */ \
RESTOREREGS(); \
return; \
\
default: \
fprintf (stderr, "Unknown jump to %04x\n", PC); \
exit (1); \
} \
} \
}
DEFPROC(BGT1)
#include "code/BGT1.c"
ENDPROC()
DEFPROC(BGT2)
#include "code/BGT2.c"
ENDPROC()
DEFPROC(BGT3)
#include "code/BGT3.c"
ENDPROC()
DEFPROC(BGT4)
#include "code/BGT4.c"
ENDPROC()
DEFPROC(BGT5)
#include "code/BGT5.c"
ENDPROC()
DEFPROC(BHI1)
#include "code/BHI1.c"
ENDPROC()
DEFPROC(BLE1)
#include "code/BLE1.c"
ENDPROC()
DEFPROC(BLE2)
#include "code/BLE2.c"
ENDPROC()
DEFPROC(BLE3)
#include "code/BLE3.c"
ENDPROC()
DEFPROC(BLE4)
#include "code/BLE4.c"
ENDPROC()
DEFPROC(BLE5)
#include "code/BLE5.c"
ENDPROC()
DEFPROC(ANDA1)
#include "code/ANDA1.c"
ENDPROC()
DEFPROC(ANDA2)
#include "code/ANDA2.c"
ENDPROC()
DEFPROC(ANDA3)
#include "code/ANDA3.c"
ENDPROC()
DEFPROC(NEG0)
#include "code/NEG0.c"
ENDPROC()
DEFPROC(NEG1)
#include "code/NEG1.c"
ENDPROC()
DEFPROC(NEG2)
#include "code/NEG2.c"
ENDPROC()
DEFPROC(NEG80)
#include "code/NEG80.c"
ENDPROC()
DEFPROC(BITimm)
#include "code/BITimm.c"
ENDPROC()
DEFPROC(COMA)
#include "code/COMA.c"
ENDPROC()
DEFPROC(DAA1)
#include "code/DAA1.c"
ENDPROC()
DEFPROC(DAA2)
#include "code/DAA2.c"
ENDPROC()
DEFPROC(DAA3)
#include "code/DAA3.c"
ENDPROC()
DEFPROC(DAA4)
#include "code/DAA4.c"
ENDPROC()
DEFPROC(DAA5)
#include "code/DAA5.c"
ENDPROC()
DEFPROC(DAA6)
#include "code/DAA6.c"
ENDPROC()
DEFPROC(DAA7)
#include "code/DAA7.c"
ENDPROC()
DEFPROC(DAA8)
#include "code/DAA8.c"
ENDPROC()
DEFPROC(EXGdx)
#include "code/EXGdx.c"
ENDPROC()
DEFPROC(TFRyx)
#include "code/TFRyx.c"
ENDPROC()
DEFPROC(TFRax)
#include "code/TFRax.c"
ENDPROC()
DEFPROC(TFRxb)
#include "code/TFRxb.c"
ENDPROC()
DEFPROC(MUL)
#include "code/MUL.c"
ENDPROC()
DEFPROC(MUL2)
#include "code/MUL2.c"
ENDPROC()
DEFPROC(SEX1)
#include "code/SEX1.c"
ENDPROC()
DEFPROC(SEX2)
#include "code/SEX2.c"
ENDPROC()
DEFPROC(TSTmemory)
#include "code/TSTmemory.c"
ENDPROC()
DEFPROC(ASRMem)
#include "code/ASRMem.c"
ENDPROC()
DEFPROC(ASRB1)
#include "code/ASRB1.c"
ENDPROC()
DEFPROC(ASRB2)
#include "code/ASRB2.c"
ENDPROC()
DEFPROC(LSL1)
#include "code/LSL1.c"
ENDPROC()
DEFPROC(LSL2)
#include "code/LSL2.c"
ENDPROC()
DEFPROC(LSL3)
#include "code/LSL3.c"
ENDPROC()
DEFPROC(LSR1)
#include "code/LSR1.c"
ENDPROC()
DEFPROC(LSR2)
#include "code/LSR2.c"
ENDPROC()
DEFPROC(LSR3)
#include "code/LSR3.c"
ENDPROC()
DEFPROC(ROLB1)
#include "code/ROLB1.c"
ENDPROC()
DEFPROC(ROLB2)
#include "code/ROLB2.c"
ENDPROC()
DEFPROC(ROLB3)
#include "code/ROLB3.c"
ENDPROC()
DEFPROC(RORB1)
#include "code/RORB1.c"
ENDPROC()
DEFPROC(RORB2)
#include "code/RORB2.c"
ENDPROC()
DEFPROC(RORB3)
#include "code/RORB3.c"
ENDPROC()
DEFPROC(ABX1)
#include "code/ABX1.c"
ENDPROC()
DEFPROC(ABX2)
#include "code/ABX2.c"
ENDPROC()
DEFPROC(ADCANoC1)
#include "code/ADCANoC1.c"
ENDPROC()
DEFPROC(ADCANoC2)
#include "code/ADCANoC2.c"
ENDPROC()
DEFPROC(ADCAWiC)
#include "code/ADCAWiC.c"
ENDPROC()
DEFPROC(ADCAWiHC)
#include "code/ADCAWiHC.c"
ENDPROC()
DEFPROC(ADDB1)
#include "code/ADDB1.c"
ENDPROC()
DEFPROC(ADDB2)
#include "code/ADDB2.c"
ENDPROC()
DEFPROC(ADDB3)
#include "code/ADDB3.c"
ENDPROC()
DEFPROC(ADDB4)
#include "code/ADDB4.c"
ENDPROC()
DEFPROC(ADDANoC)
#include "code/ADDANoC.c"
ENDPROC()
DEFPROC(ADDAWiC)
#include "code/ADDAWiC.c"
ENDPROC()
DEFPROC(ADDDNoC)
#include "code/ADDDNoC.c"
ENDPROC()
DEFPROC(ADDD1)
#include "code/ADDD1.c"
ENDPROC()
DEFPROC(ADDD2)
#include "code/ADDD2.c"
ENDPROC()
DEFPROC(ADDD3)
#include "code/ADDD3.c"
ENDPROC()
DEFPROC(INCA1)
#include "code/INCA1.c"
ENDPROC()
DEFPROC(INCA2)
#include "code/INCA2.c"
ENDPROC()
DEFPROC(INCA3)
#include "code/INCA3.c"
ENDPROC()
DEFPROC(CMP1)
#include "code/CMP1.c"
ENDPROC()
DEFPROC(CMP2)
#include "code/CMP2.c"
ENDPROC()
DEFPROC(CMP3)
#include "code/CMP3.c"
ENDPROC()
DEFPROC(CMP16)
#include "code/CMP16.c"
ENDPROC()
DEFPROC(DECA0x32)
#include "code/DECA0x32.c"
ENDPROC()
DEFPROC(DECA0x80)
#include "code/DECA0x80.c"
ENDPROC()
DEFPROC(DECA0x00)
#include "code/DECA0x00.c"
ENDPROC()
DEFPROC(SBCB)
#include "code/SBCB.c"
ENDPROC()
DEFPROC(SBCA1)
#include "code/SBCA1.c"
ENDPROC()
DEFPROC(SBCA2)
#include "code/SBCA2.c"
ENDPROC()
DEFPROC(SBCA3)
#include "code/SBCA3.c"
ENDPROC()
DEFPROC(SBCA4)
#include "code/SBCA4.c"
ENDPROC()
DEFPROC(SUBA1)
#include "code/SUBA1.c"
ENDPROC()
DEFPROC(SUBA2)
#include "code/SUBA2.c"
ENDPROC()
DEFPROC(SUBB1)
#include "code/SUBB1.c"
ENDPROC()
DEFPROC(SUBB2)
#include "code/SUBB2.c"
ENDPROC()
DEFPROC(SUBBY)
#include "code/SUBBY.c"
ENDPROC()
DEFPROC(LEAXpcr)
#include "code/LEAXpcr.c"
ENDPROC()
DEFPROC(LEAXincby2)
#include "code/LEAXincby2.c"
ENDPROC()
DEFPROC(LEAXno)
#include "code/LEAXno.c"
ENDPROC()
DEFPROC(LEAXinc1)
#include "code/LEAXinc1.c"
ENDPROC()
DEFPROC(LEAXinc2)
#include "code/LEAXinc2.c"
ENDPROC()
DEFPROC(Doffset1)
#include "code/Doffset1.c"
ENDPROC()
DEFPROC(Doffset2)
#include "code/Doffset2.c"
ENDPROC()
#endif /* SBT */