mirror of
https://github.com/jscrane/r65emu.git
synced 2025-04-22 17:37:08 +00:00
parent
3a8e387a09
commit
3ed571e8f2
@ -1,6 +1,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include "hardware.h"
|
||||
#include "debugging.h"
|
||||
#include "memory.h"
|
||||
#include "display.h"
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
#include "debugging.h"
|
||||
|
||||
#if defined(USE_SPIFFS)
|
||||
#include <SPIFFS.h>
|
||||
|
@ -26,6 +26,6 @@ int hardware_interval_timer(uint32_t dt, std::function<void(void)> cb);
|
||||
int hardware_oneshot_timer(uint32_t dt, std::function<void(void)> cb);
|
||||
void hardware_cancel_timer(int timer);
|
||||
|
||||
#if defined(__SPIRAM_H__) && defined(USE_SPIRAM)
|
||||
#if defined(USE_SPIRAM)
|
||||
extern class spiram sram;
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@ public:
|
||||
void run(unsigned);
|
||||
void reset();
|
||||
void raise(int);
|
||||
void irq(uint8_t b) { raise(b); }
|
||||
char *status(char *buf, size_t n, bool hdr=false);
|
||||
|
||||
void checkpoint(Stream &);
|
||||
|
143
src/z80.h
143
src/z80.h
@ -1442,6 +1442,7 @@ private:
|
||||
flags.P = flags.N = flags.H = 0;
|
||||
}
|
||||
inline void cpir() {
|
||||
#ifdef Z80TEST
|
||||
uint8_t b = _rb(HL);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
@ -1465,8 +1466,40 @@ private:
|
||||
} else
|
||||
_memptr++;
|
||||
HL++;
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
b = _rb(HL);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
uint8_t a = A;
|
||||
uint8_t carry = (flags.C != 0);
|
||||
_sub(b);
|
||||
BC--;
|
||||
b = A;
|
||||
A = a;
|
||||
flags.C = carry;
|
||||
flags.P = (BC != 0);
|
||||
if (!flags.Z && flags.P) {
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
|
||||
_mc(PC-2, 4);
|
||||
DBG_MEM(printf("%5ld MR %04x %02x\n", _ts, PC-2, (uint8_t)_mem[PC-2]));
|
||||
_mc(PC-1, 4);
|
||||
DBG_MEM(printf("%5ld MR %04x %02x\n", _ts, PC-1, (uint8_t)_mem[PC-1]));
|
||||
R += 2;
|
||||
}
|
||||
HL++;
|
||||
} while (!flags.Z && flags.P);
|
||||
if (flags.H) b--;
|
||||
flags._3 = (b & 0x08) != 0;
|
||||
flags._5 = (b & 0x02) != 0;
|
||||
_memptr = PC;
|
||||
#endif
|
||||
}
|
||||
inline void inir() {
|
||||
#ifdef Z80TEST
|
||||
_mc(IR, 1);
|
||||
uint8_t b = _inr();
|
||||
_sb(HL, b);
|
||||
@ -1484,8 +1517,29 @@ private:
|
||||
_int_prot = true;
|
||||
}
|
||||
HL++;
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
_mc(IR, 1);
|
||||
b = _inr();
|
||||
_sb(HL, b);
|
||||
_memptr = BC+1;
|
||||
B--;
|
||||
if (B) {
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
}
|
||||
HL++;
|
||||
} while (B);
|
||||
uint8_t c = b + C + 1;
|
||||
flags.N = (c & 0x80) != 0;
|
||||
flags.C = flags.H = (c < b);
|
||||
flags.P = parity((c & 0x07) ^ B);
|
||||
_sz35(B);
|
||||
#endif
|
||||
}
|
||||
inline void outir() {
|
||||
#ifdef Z80TEST
|
||||
_mc(IR, 1);
|
||||
uint8_t b = _rb(HL);
|
||||
B--;
|
||||
@ -1503,6 +1557,26 @@ private:
|
||||
PC -= 2;
|
||||
_int_prot = true;
|
||||
}
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
_mc(IR, 1);
|
||||
b = _rb(HL);
|
||||
B--;
|
||||
_memptr = BC+1;
|
||||
_outr(b);
|
||||
HL++;
|
||||
if (B) {
|
||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||
_mc(BC, 1); _mc(BC, 1);
|
||||
}
|
||||
} while (B);
|
||||
uint8_t c = b + L;
|
||||
flags.N = (b & 0x80) != 0;
|
||||
flags.C = flags.H = (c < b);
|
||||
flags.P = parity((c & 0x07) ^ B);
|
||||
_sz35(B);
|
||||
#endif
|
||||
}
|
||||
inline void lddr() {
|
||||
uint8_t b;
|
||||
@ -1531,6 +1605,7 @@ private:
|
||||
flags.P = flags.N = flags.H = 0;
|
||||
}
|
||||
inline void cpdr() {
|
||||
#ifdef Z80TEST
|
||||
uint8_t b = _rb(HL);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
@ -1555,8 +1630,35 @@ private:
|
||||
} else
|
||||
_memptr--;
|
||||
HL--;
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
b = _rb(HL);
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
uint8_t a = A;
|
||||
uint8_t carry = (flags.C != 0);
|
||||
_sub(b);
|
||||
BC--;
|
||||
b = A;
|
||||
A = a;
|
||||
flags.C = carry;
|
||||
flags.P = (BC != 0);
|
||||
if (!flags.Z && flags.P) {
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
}
|
||||
HL--;
|
||||
} while (!flags.Z && flags.P);
|
||||
if (flags.H) b--;
|
||||
flags._3 = (b & 0x08) != 0;
|
||||
flags._5 = (b & 0x02) != 0;
|
||||
flags.N = 1;
|
||||
_memptr = PC-1;
|
||||
#endif
|
||||
}
|
||||
inline void indr() {
|
||||
#ifdef Z80TEST
|
||||
_mc(IR, 1);
|
||||
uint8_t b = _inr();
|
||||
_sb(HL, b);
|
||||
@ -1574,8 +1676,29 @@ private:
|
||||
_int_prot = true;
|
||||
}
|
||||
HL--;
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
_mc(IR, 1);
|
||||
b = _inr();
|
||||
_sb(HL, b);
|
||||
_memptr = BC-1;
|
||||
B--;
|
||||
if (B) {
|
||||
_mc(HL, 1); _mc(HL, 1); _mc(HL, 1);
|
||||
_mc(HL, 1); _mc(HL, 1);
|
||||
}
|
||||
HL--;
|
||||
} while (B);
|
||||
uint8_t c = b + C - 1;
|
||||
flags.N = (b & 0x80) != 0;
|
||||
flags.C = flags.H = (c < b);
|
||||
flags.P = parity((c & 0x07) ^ B);
|
||||
_sz35(B);
|
||||
#endif
|
||||
}
|
||||
inline void outdr() {
|
||||
#ifdef Z80TEST
|
||||
_mc(IR, 1);
|
||||
uint8_t b = _rb(HL);
|
||||
B--;
|
||||
@ -1593,6 +1716,26 @@ private:
|
||||
PC -= 2;
|
||||
_int_prot = true;
|
||||
}
|
||||
#else
|
||||
uint8_t b;
|
||||
do {
|
||||
_mc(IR, 1);
|
||||
b = _rb(HL);
|
||||
B--;
|
||||
_outr(b);
|
||||
_memptr = BC-1;
|
||||
HL--;
|
||||
if (B) {
|
||||
_mc(BC, 1); _mc(BC, 1); _mc(BC, 1);
|
||||
_mc(BC, 1); _mc(BC, 1);
|
||||
}
|
||||
} while (B);
|
||||
uint8_t c = b + L;
|
||||
flags.N = (b & 0x80) != 0;
|
||||
flags.C = flags.H = (c < b);
|
||||
flags.P = parity((c & 0x07) ^ B);
|
||||
_sz35(B);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 0xDDCB extended instructions
|
||||
|
@ -1,4 +1,4 @@
|
||||
CPPFLAGS=-I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x'
|
||||
CPPFLAGS=-I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -DZ80TEST
|
||||
CXXFLAGS=-g -fno-operator-names -Wall
|
||||
|
||||
all: z80test tests.me sum
|
||||
|
@ -4,11 +4,20 @@ z80test
|
||||
A test harness for a z80 processor emulator; based on, and using tests from,
|
||||
the excellent [FUSE 1.5.7](http://fuse-emulator.sourceforge.net/).
|
||||
|
||||
Some of these tests depend on a FUSE-compatible implementation of certain ed-prefixed instructions.
|
||||
These are indicated by the ```#ifdef Z80TEST``` in ```z80.h```.
|
||||
|
||||
This is because the tests can specify a bound on the number of timestates to run:
|
||||
```c++
|
||||
while (cpu.ts() < (uint32_t)end_ts)
|
||||
cpu.run(1);
|
||||
```
|
||||
|
||||
```bash
|
||||
$ make
|
||||
g++ -g -fno-operator-names -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -c -o z80test.o z80test.cc
|
||||
g++ -g -fno-operator-names -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -o z80.o -c ../z80.cpp
|
||||
g++ -g -fno-operator-names -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -o memory.o -c ../memory.cpp
|
||||
g++ -g -fno-operator-names -Wall -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -DZ80TEST -c -o z80test.o z80test.cc
|
||||
g++ -g -fno-operator-names -Wall -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -DZ80TEST -o z80.o -c ../z80.cpp
|
||||
g++ -g -fno-operator-names -Wall -I.. -DDEBUGGING=0x41 -DUNDOCUMENTED_OPS -DNO_CHECKPOINT -D'PRINTER(x)=x' -DZ80TEST -o memory.o -c ../memory.cpp
|
||||
g++ -o z80test z80test.o z80.o memory.o
|
||||
./z80test tests.in > tests.me
|
||||
md5sum tests.me
|
||||
|
Loading…
x
Reference in New Issue
Block a user