1
0
mirror of https://github.com/jscrane/r65emu.git synced 2024-12-21 12:29:51 +00:00
This commit is contained in:
Stephen Crane 2018-08-10 11:13:45 +01:00
parent 30c049e91c
commit 69f7837ac3
13 changed files with 113 additions and 109 deletions

2
CPU.h
View File

@ -3,6 +3,8 @@
#undef PC #undef PC
class Stream;
class CPU: public Checkpointable { class CPU: public Checkpointable {
public: public:
virtual void run(unsigned instructions) =0; virtual void run(unsigned instructions) =0;

View File

@ -1,7 +1,7 @@
r65emu r65emu
====== ======
Emulation library for 6502-based 8-bit microcomputers. Emulation library for 8-bit microcomputers based on 6502, i8080 and z80.
Libraries: Libraries:
--------- ---------
@ -22,4 +22,3 @@ Hardware:
- A 23k256 SPI RAM chip (optional) - A 23k256 SPI RAM chip (optional)
See _hardware.h_ for wiring details and other options. See _hardware.h_ for wiring details and other options.

View File

@ -1,8 +1,8 @@
// TinyFont.c // TinyFont.c
// Font Size : 8x8 // Font Size : 8x8
// Memory usage : 764 bytes // Memory usage : 764 bytes
// # characters : 95 // # characters : 95
const unsigned char TinyFont[764]={ const unsigned char TinyFont[764]={
0x08,0x08,0x20,0x5F, 0x08,0x08,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space> 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space>

2
acia.h
View File

@ -30,7 +30,7 @@ struct acia {
static const byte ws8e1 = 6 << 2; static const byte ws8e1 = 6 << 2;
static const byte ws8o1 = 7 << 2; static const byte ws8o1 = 7 << 2;
static const byte lrts_dti = 0 << 5; // /rts, disable trans irq static const byte lrts_dti = 0 << 5; // /rts, disable trans irq
static const byte lrts_eti = 1 << 5; // /rts, enable static const byte lrts_eti = 1 << 5; // /rts, enable
static const byte hrts_dti = 2 << 5; // rts, disable static const byte hrts_dti = 2 << 5; // rts, disable
static const byte lrts_dti_brk = 3 << 5; // /rts, disable, send brk static const byte lrts_dti_brk = 3 << 5; // /rts, disable, send brk

View File

@ -1,5 +1,5 @@
/* /*
* The hardware configuration of the machine. * The hardware configuration of the machine.
* (This should be the same for all emulated devices.) * (This should be the same for all emulated devices.)
*/ */
#ifndef __HARDWARE_H__ #ifndef __HARDWARE_H__

View File

@ -1,4 +1,5 @@
#include <Energia.h> #include <stdio.h>
#include <Stream.h>
#include "memory.h" #include "memory.h"
#include "CPU.h" #include "CPU.h"
@ -109,7 +110,7 @@ i8080::i8080(Memory &m, PortDevice<i8080> &d): CPU(m)
OP *p = _ops; OP *p = _ops;
// 0x // 0x
*p++ = &i8080::nop; *p++ = &i8080::lxib; *p++ = &i8080::nop; *p++ = &i8080::lxib;
*p++ = &i8080::staxb; *p++ = &i8080::inxb; *p++ = &i8080::staxb; *p++ = &i8080::inxb;
*p++ = &i8080::inrb; *p++ = &i8080::dcrb; *p++ = &i8080::inrb; *p++ = &i8080::dcrb;
*p++ = &i8080::mvib; *p++ = &i8080::rlc; *p++ = &i8080::mvib; *p++ = &i8080::rlc;
@ -119,7 +120,7 @@ i8080::i8080(Memory &m, PortDevice<i8080> &d): CPU(m)
*p++ = &i8080::mvic; *p++ = &i8080::rrc; *p++ = &i8080::mvic; *p++ = &i8080::rrc;
// 1x // 1x
*p++ = &i8080::nop; *p++ = &i8080::lxid; *p++ = &i8080::nop; *p++ = &i8080::lxid;
*p++ = &i8080::staxd; *p++ = &i8080::inxd; *p++ = &i8080::staxd; *p++ = &i8080::inxd;
*p++ = &i8080::inrd; *p++ = &i8080::dcrd; *p++ = &i8080::inrd; *p++ = &i8080::dcrd;
*p++ = &i8080::mvid; *p++ = &i8080::ral; *p++ = &i8080::mvid; *p++ = &i8080::ral;
@ -133,10 +134,10 @@ i8080::i8080(Memory &m, PortDevice<i8080> &d): CPU(m)
*p++ = &i8080::shld; *p++ = &i8080::inxh; *p++ = &i8080::shld; *p++ = &i8080::inxh;
*p++ = &i8080::inrh; *p++ = &i8080::dcrh; *p++ = &i8080::inrh; *p++ = &i8080::dcrh;
*p++ = &i8080::mvih; *p++ = &i8080::daa; *p++ = &i8080::mvih; *p++ = &i8080::daa;
*p++ = &i8080::nop; *p++ = &i8080::dadh; *p++ = &i8080::nop; *p++ = &i8080::dadh;
*p++ = &i8080::lhld; *p++ = &i8080::dcxh; *p++ = &i8080::lhld; *p++ = &i8080::dcxh;
*p++ = &i8080::inrl; *p++ = &i8080::dcrl; *p++ = &i8080::inrl; *p++ = &i8080::dcrl;
*p++ = &i8080::mvil; *p++ = &i8080::cma; *p++ = &i8080::mvil; *p++ = &i8080::cma;
// 3x // 3x
*p++ = &i8080::nop; *p++ = &i8080::lxisp; *p++ = &i8080::nop; *p++ = &i8080::lxisp;

View File

@ -59,13 +59,13 @@ private:
int _irq_pending; int _irq_pending;
PortDevice<i8080> *_ports; PortDevice<i8080> *_ports;
typedef void (i8080::*OP)(); typedef void (i8080::*OP)();
OP _ops[256]; OP _ops[256];
static int parity_table[256]; static int parity_table[256];
inline word _rw(Memory::address a) { inline word _rw(Memory::address a) {
return _mem[a] + (_mem[a+1] << 8); return _mem[a] + (_mem[a+1] << 8);
} }
inline void _sw(Memory::address a, word w) { inline void _sw(Memory::address a, word w) {
_mem[a] = (w & 0xff); _mem[a] = (w & 0xff);
@ -128,7 +128,7 @@ private:
void inrd() { _inc(D); } void inrd() { _inc(D); }
void dcrd() { _dec(D); } void dcrd() { _dec(D); }
void mvid() { D = _mem[PC++]; } void mvid() { D = _mem[PC++]; }
void ral() { void ral() {
byte b = (A << 1) | flags.C; byte b = (A << 1) | flags.C;
flags.C = (A & 0x80) >> 7; flags.C = (A & 0x80) >> 7;
A = b; A = b;

View File

@ -2,6 +2,7 @@
#define __MEMORY_H__ #define __MEMORY_H__
typedef unsigned char byte; typedef unsigned char byte;
typedef unsigned int word;
class Stream; class Stream;
@ -48,7 +49,7 @@ public:
// primary access interface // primary access interface
// //
Device &operator[] (address a) { Device &operator[] (address a) {
Device *d = get (a); Device *d = get (a);
d->access (a); d->access (a);
return *d; return *d;

View File

@ -1,4 +1,4 @@
#include <Energia.h> #include <Arduino.h>
#include "ps2drv.h" #include "ps2drv.h"
#define BUFFER_SIZE 16 #define BUFFER_SIZE 16

View File

@ -26,7 +26,7 @@ byte r6502::flags() {
char *r6502::status(char *buf, size_t n, bool hdr) { char *r6502::status(char *buf, size_t n, bool hdr) {
flags(); flags();
snprintf(buf, n, snprintf(buf, n,
"%s%02x %02x %02x %02x %d%d%d%d%d%d%d%d %04x", "%s%02x %02x %02x %02x %d%d%d%d%d%d%d%d %04x",
hdr? "aa xx yy sp nv_bdizc _pc_\r\n": "", hdr? "aa xx yy sp nv_bdizc _pc_\r\n": "",
A, X, Y, S, P.bits.N, P.bits.V, P.bits._, P.bits.B, A, X, Y, S, P.bits.N, P.bits.V, P.bits._, P.bits.B,
@ -193,69 +193,69 @@ r6502::r6502(Memory &m): CPU(m) {
} }
OP *p = _ops; OP *p = _ops;
*p++=&r6502::brk; *p++=&r6502::ora_ix; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::brk; *p++=&r6502::ora_ix; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::ora_z; *p++=&r6502::asl_z; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::ora_z; *p++=&r6502::asl_z; *p++=&r6502::ill;
*p++=&r6502::php; *p++=&r6502::ora_; *p++=&r6502::asl; *p++=&r6502::ill; *p++=&r6502::php; *p++=&r6502::ora_; *p++=&r6502::asl; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::ora_a; *p++=&r6502::asl_a; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::ora_a; *p++=&r6502::asl_a; *p++=&r6502::ill;
*p++=&r6502::bpl; *p++=&r6502::ora_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bpl; *p++=&r6502::ora_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::ora_zx; *p++=&r6502::asl_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::ora_zx; *p++=&r6502::asl_zx; *p++=&r6502::ill;
*p++=&r6502::clc; *p++=&r6502::ora_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::clc; *p++=&r6502::ora_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::ora_ax; *p++=&r6502::asl_ax; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::ora_ax; *p++=&r6502::asl_ax; *p++=&r6502::ill;
*p++=&r6502::jsr; *p++=&r6502::and_ix; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::jsr; *p++=&r6502::and_ix; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::bit_z; *p++=&r6502::and_z; *p++=&r6502::rol_z; *p++=&r6502::ill; *p++=&r6502::bit_z; *p++=&r6502::and_z; *p++=&r6502::rol_z; *p++=&r6502::ill;
*p++=&r6502::plp; *p++=&r6502::and_; *p++=&r6502::rol; *p++=&r6502::ill; *p++=&r6502::plp; *p++=&r6502::and_; *p++=&r6502::rol; *p++=&r6502::ill;
*p++=&r6502::bit_a; *p++=&r6502::and_a; *p++=&r6502::rol_a; *p++=&r6502::ill; *p++=&r6502::bit_a; *p++=&r6502::and_a; *p++=&r6502::rol_a; *p++=&r6502::ill;
*p++=&r6502::bmi; *p++=&r6502::and_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bmi; *p++=&r6502::and_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::and_zx; *p++=&r6502::rol_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::and_zx; *p++=&r6502::rol_zx; *p++=&r6502::ill;
*p++=&r6502::sec; *p++=&r6502::and_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::sec; *p++=&r6502::and_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::and_ax; *p++=&r6502::rol_ax; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::and_ax; *p++=&r6502::rol_ax; *p++=&r6502::ill;
*p++=&r6502::rti; *p++=&r6502::eor_ix; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::rti; *p++=&r6502::eor_ix; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::eor_z; *p++=&r6502::lsr_z; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::eor_z; *p++=&r6502::lsr_z; *p++=&r6502::ill;
*p++=&r6502::pha; *p++=&r6502::eor_; *p++=&r6502::lsr_; *p++=&r6502::ill; *p++=&r6502::pha; *p++=&r6502::eor_; *p++=&r6502::lsr_; *p++=&r6502::ill;
*p++=&r6502::jmp; *p++=&r6502::eor_a; *p++=&r6502::lsr_a; *p++=&r6502::ill; *p++=&r6502::jmp; *p++=&r6502::eor_a; *p++=&r6502::lsr_a; *p++=&r6502::ill;
*p++=&r6502::bvc; *p++=&r6502::eor_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bvc; *p++=&r6502::eor_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::eor_zx; *p++=&r6502::lsr_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::eor_zx; *p++=&r6502::lsr_zx; *p++=&r6502::ill;
*p++=&r6502::cli; *p++=&r6502::eor_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::cli; *p++=&r6502::eor_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::eor_ax; *p++=&r6502::lsr_ax; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::eor_ax; *p++=&r6502::lsr_ax; *p++=&r6502::ill;
*p++=&r6502::rts; *p++=&r6502::adc_ix; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::rts; *p++=&r6502::adc_ix; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::adc_z; *p++=&r6502::ror_z; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::adc_z; *p++=&r6502::ror_z; *p++=&r6502::ill;
*p++=&r6502::pla; *p++=&r6502::adc_; *p++=&r6502::ror_; *p++=&r6502::ill; *p++=&r6502::pla; *p++=&r6502::adc_; *p++=&r6502::ror_; *p++=&r6502::ill;
*p++=&r6502::jmp_i; *p++=&r6502::adc_a; *p++=&r6502::ror_a; *p++=&r6502::ill; *p++=&r6502::jmp_i; *p++=&r6502::adc_a; *p++=&r6502::ror_a; *p++=&r6502::ill;
*p++=&r6502::bvs; *p++=&r6502::adc_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bvs; *p++=&r6502::adc_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::adc_zx; *p++=&r6502::ror_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::adc_zx; *p++=&r6502::ror_zx; *p++=&r6502::ill;
*p++=&r6502::sei; *p++=&r6502::adc_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::sei; *p++=&r6502::adc_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::adc_ax; *p++=&r6502::ror_ax; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::adc_ax; *p++=&r6502::ror_ax; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::sta_ix; *p++=&r6502::nop2; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::sta_ix; *p++=&r6502::nop2; *p++=&r6502::ill;
*p++=&r6502::sty_z; *p++=&r6502::sta_z; *p++=&r6502::stx_z; *p++=&r6502::ill; *p++=&r6502::sty_z; *p++=&r6502::sta_z; *p++=&r6502::stx_z; *p++=&r6502::ill;
*p++=&r6502::dey; *p++=&r6502::nop2; *p++=&r6502::txa; *p++=&r6502::ill; *p++=&r6502::dey; *p++=&r6502::nop2; *p++=&r6502::txa; *p++=&r6502::ill;
*p++=&r6502::sty_a; *p++=&r6502::sta_a; *p++=&r6502::stx_a; *p++=&r6502::ill; *p++=&r6502::sty_a; *p++=&r6502::sta_a; *p++=&r6502::stx_a; *p++=&r6502::ill;
*p++=&r6502::bcc; *p++=&r6502::sta_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bcc; *p++=&r6502::sta_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::sty_zx; *p++=&r6502::sta_zx; *p++=&r6502::stx_zy; *p++=&r6502::ill; *p++=&r6502::sty_zx; *p++=&r6502::sta_zx; *p++=&r6502::stx_zy; *p++=&r6502::ill;
*p++=&r6502::tya; *p++=&r6502::sta_ay; *p++=&r6502::txs; *p++=&r6502::ill; *p++=&r6502::tya; *p++=&r6502::sta_ay; *p++=&r6502::txs; *p++=&r6502::ill;
*p++=&r6502::ill; *p++=&r6502::sta_ax; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::sta_ax; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::ldy_; *p++=&r6502::lda_ix; *p++=&r6502::ldx_; *p++=&r6502::lax_ix; *p++=&r6502::ldy_; *p++=&r6502::lda_ix; *p++=&r6502::ldx_; *p++=&r6502::lax_ix;
*p++=&r6502::ldy_z; *p++=&r6502::lda_z; *p++=&r6502::ldx_z; *p++=&r6502::lax_z; *p++=&r6502::ldy_z; *p++=&r6502::lda_z; *p++=&r6502::ldx_z; *p++=&r6502::lax_z;
*p++=&r6502::tay; *p++=&r6502::lda_; *p++=&r6502::tax; *p++=&r6502::ill; *p++=&r6502::tay; *p++=&r6502::lda_; *p++=&r6502::tax; *p++=&r6502::ill;
*p++=&r6502::ldy_a; *p++=&r6502::lda_a; *p++=&r6502::ldx_a; *p++=&r6502::lax_a; *p++=&r6502::ldy_a; *p++=&r6502::lda_a; *p++=&r6502::ldx_a; *p++=&r6502::lax_a;
*p++=&r6502::bcs; *p++=&r6502::lda_iy; *p++=&r6502::ill; *p++=&r6502::lax_iy; *p++=&r6502::bcs; *p++=&r6502::lda_iy; *p++=&r6502::ill; *p++=&r6502::lax_iy;
*p++=&r6502::ldy_zx; *p++=&r6502::lda_zx; *p++=&r6502::ldx_zy; *p++=&r6502::lax_zy; *p++=&r6502::ldy_zx; *p++=&r6502::lda_zx; *p++=&r6502::ldx_zy; *p++=&r6502::lax_zy;
*p++=&r6502::clv; *p++=&r6502::lda_ay; *p++=&r6502::tsx; *p++=&r6502::ill; *p++=&r6502::clv; *p++=&r6502::lda_ay; *p++=&r6502::tsx; *p++=&r6502::ill;
*p++=&r6502::ldy_ax; *p++=&r6502::lda_ax; *p++=&r6502::ldx_ay; *p++=&r6502::lax_ay; *p++=&r6502::ldy_ax; *p++=&r6502::lda_ax; *p++=&r6502::ldx_ay; *p++=&r6502::lax_ay;
*p++=&r6502::cpy_; *p++=&r6502::cmp_ix; *p++=&r6502::nop2; *p++=&r6502::ill; *p++=&r6502::cpy_; *p++=&r6502::cmp_ix; *p++=&r6502::nop2; *p++=&r6502::ill;
*p++=&r6502::cpy_z; *p++=&r6502::cmp_z; *p++=&r6502::dec_z; *p++=&r6502::ill; *p++=&r6502::cpy_z; *p++=&r6502::cmp_z; *p++=&r6502::dec_z; *p++=&r6502::ill;
*p++=&r6502::iny; *p++=&r6502::cmp_; *p++=&r6502::dex; *p++=&r6502::ill; *p++=&r6502::iny; *p++=&r6502::cmp_; *p++=&r6502::dex; *p++=&r6502::ill;
*p++=&r6502::cpy_a; *p++=&r6502::cmp_a; *p++=&r6502::dec_a; *p++=&r6502::ill; *p++=&r6502::cpy_a; *p++=&r6502::cmp_a; *p++=&r6502::dec_a; *p++=&r6502::ill;
*p++=&r6502::bne; *p++=&r6502::cmp_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::bne; *p++=&r6502::cmp_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::cmp_zx; *p++=&r6502::dec_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::cmp_zx; *p++=&r6502::dec_zx; *p++=&r6502::ill;
*p++=&r6502::cld; *p++=&r6502::cmp_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::cld; *p++=&r6502::cmp_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::cmp_ax; *p++=&r6502::dec_ax; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::cmp_ax; *p++=&r6502::dec_ax; *p++=&r6502::ill;
*p++=&r6502::cpx_; *p++=&r6502::sbc_ix; *p++=&r6502::nop2; *p++=&r6502::ill; *p++=&r6502::cpx_; *p++=&r6502::sbc_ix; *p++=&r6502::nop2; *p++=&r6502::ill;
*p++=&r6502::cpx_z; *p++=&r6502::sbc_z; *p++=&r6502::inc_z; *p++=&r6502::ill; *p++=&r6502::cpx_z; *p++=&r6502::sbc_z; *p++=&r6502::inc_z; *p++=&r6502::ill;
*p++=&r6502::inx; *p++=&r6502::sbc_; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::inx; *p++=&r6502::sbc_; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::cpx_a; *p++=&r6502::sbc_a; *p++=&r6502::inc_a; *p++=&r6502::ill; *p++=&r6502::cpx_a; *p++=&r6502::sbc_a; *p++=&r6502::inc_a; *p++=&r6502::ill;
*p++=&r6502::beq; *p++=&r6502::sbc_iy; *p++=&r6502::ill; *p++=&r6502::ill; *p++=&r6502::beq; *p++=&r6502::sbc_iy; *p++=&r6502::ill; *p++=&r6502::ill;
*p++=&r6502::nop2; *p++=&r6502::sbc_zx; *p++=&r6502::inc_zx; *p++=&r6502::ill; *p++=&r6502::nop2; *p++=&r6502::sbc_zx; *p++=&r6502::inc_zx; *p++=&r6502::ill;
*p++=&r6502::sed; *p++=&r6502::sbc_ay; *p++=&r6502::nop; *p++=&r6502::ill; *p++=&r6502::sed; *p++=&r6502::sbc_ay; *p++=&r6502::nop; *p++=&r6502::ill;
*p++=&r6502::nop3; *p++=&r6502::sbc_ax; *p++=&r6502::inc_ax; *p++=&r6502::ill; *p++=&r6502::nop3; *p++=&r6502::sbc_ax; *p++=&r6502::inc_ax; *p++=&r6502::ill;
} }

View File

@ -77,7 +77,7 @@ private:
inline void _ldy(byte a) { Z=N=Y=a; } inline void _ldy(byte a) { Z=N=Y=a; }
/* modes */ /* modes */
inline Memory::address _a() { inline Memory::address _a() {
Memory::address a = _mem[PC++]; Memory::address a = _mem[PC++];
return a | (_mem[PC++] << 8); return a | (_mem[PC++] << 8);
} }
@ -86,8 +86,8 @@ private:
inline Memory::address _z() { return _mem[PC++]; } inline Memory::address _z() { return _mem[PC++]; }
inline Memory::address _zx() { return (_z()+X) & 0xff; } inline Memory::address _zx() { return (_z()+X) & 0xff; }
inline Memory::address _zy() { return (_z()+Y) & 0xff; } inline Memory::address _zy() { return (_z()+Y) & 0xff; }
inline Memory::address _i(Memory::address a) { inline Memory::address _i(Memory::address a) {
return (_mem[a+1]<<8)|_mem[a]; return (_mem[a+1]<<8)|_mem[a];
} }
inline Memory::address _ix() { return _i(_zx()); } inline Memory::address _ix() { return _i(_zx()); }
inline Memory::address _iy() { return _i(_mem[PC++])+Y; } inline Memory::address _iy() { return _i(_mem[PC++])+Y; }

19
z80.cpp
View File

@ -1,4 +1,5 @@
#include <Energia.h> #include <stdio.h>
#include <Stream.h>
#include "memory.h" #include "memory.h"
#include "ports.h" #include "ports.h"
@ -7,11 +8,11 @@
char *z80::status(char *buf, size_t n, bool hdr) { char *z80::status(char *buf, size_t n, bool hdr) {
byte op = _mem[PC]; byte op = _mem[PC];
snprintf(buf, n, snprintf(buf, n,
"%s%04x %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %d%d%d " "%s%04x %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %d%d%d "
"%04x %d%d%d%d%d%d%d%d", "%04x %d%d%d%d%d%d%d%d",
hdr? "_pc_ op _af_ _bc_ _de_ _hl_ _af' _bc' _de' _hl' _ir_ imff _sp_ sz5h3pnc\r\n": "", hdr? "_pc_ op _af_ _bc_ _de_ _hl_ _af' _bc' _de' _hl' _ir_ imff _sp_ sz5h3pnc\r\n": "",
PC, op, AF, BC, DE, HL, AF_, BC_, DE_, HL_, IR, _im, _iff1, _iff2, PC, op, AF, BC, DE, HL, AF_, BC_, DE_, HL_, IR, _im, _iff1, _iff2,
SP, flags.S, flags.Z, flags._5, flags.H, flags._3, flags.P, flags.N, flags.C); SP, flags.S, flags.Z, flags._5, flags.H, flags._3, flags.P, flags.N, flags.C);
return buf; return buf;
} }
@ -877,7 +878,7 @@ z80::z80(Memory &m, PortDevice<z80> &ports): CPU(m)
OP *p = _ops; OP *p = _ops;
// 0x00 // 0x00
*p++ = &z80::nop; *p++ = &z80::ldbcpc; *p++ = &z80::nop; *p++ = &z80::ldbcpc;
*p++ = &z80::ldBCa; *p++ = &z80::incbc; *p++ = &z80::ldBCa; *p++ = &z80::incbc;
*p++ = &z80::incb; *p++ = &z80::decb; *p++ = &z80::incb; *p++ = &z80::decb;
*p++ = &z80::ldb; *p++ = &z80::rlca; *p++ = &z80::ldb; *p++ = &z80::rlca;
@ -887,7 +888,7 @@ z80::z80(Memory &m, PortDevice<z80> &ports): CPU(m)
*p++ = &z80::ldc; *p++ = &z80::rrca; *p++ = &z80::ldc; *p++ = &z80::rrca;
// 0x10 // 0x10
*p++ = &z80::djnz; *p++ = &z80::lddepc; *p++ = &z80::djnz; *p++ = &z80::lddepc;
*p++ = &z80::ldDEa; *p++ = &z80::incde; *p++ = &z80::ldDEa; *p++ = &z80::incde;
*p++ = &z80::incd; *p++ = &z80::decd; *p++ = &z80::incd; *p++ = &z80::decd;
*p++ = &z80::ldd; *p++ = &z80::rla; *p++ = &z80::ldd; *p++ = &z80::rla;
@ -901,10 +902,10 @@ z80::z80(Memory &m, PortDevice<z80> &ports): CPU(m)
*p++ = &z80::ldPChl; *p++ = &z80::inchl; *p++ = &z80::ldPChl; *p++ = &z80::inchl;
*p++ = &z80::inch; *p++ = &z80::dech; *p++ = &z80::inch; *p++ = &z80::dech;
*p++ = &z80::ldh; *p++ = &z80::daa; *p++ = &z80::ldh; *p++ = &z80::daa;
*p++ = &z80::jrz; *p++ = &z80::addhlhl; *p++ = &z80::jrz; *p++ = &z80::addhlhl;
*p++ = &z80::ldhlPC; *p++ = &z80::dechl; *p++ = &z80::ldhlPC; *p++ = &z80::dechl;
*p++ = &z80::incl; *p++ = &z80::decl; *p++ = &z80::incl; *p++ = &z80::decl;
*p++ = &z80::ldl; *p++ = &z80::cpl; *p++ = &z80::ldl; *p++ = &z80::cpl;
// 0x30 // 0x30
*p++ = &z80::jrnc; *p++ = &z80::ldsppc; *p++ = &z80::jrnc; *p++ = &z80::ldsppc;

90
z80.h
View File

@ -68,14 +68,14 @@ public:
private: private:
void _handle_interrupt(); void _handle_interrupt();
typedef void (z80::*OP)(); typedef void (z80::*OP)();
void _step(OP ops[]); void _step(OP ops[]);
byte _fetch_op(); byte _fetch_op();
inline void step() { (this->*_ops[_fetch_op()])(); } inline void step() { (this->*_ops[_fetch_op()])(); }
typedef void (z80::*OP_IDX)(byte); typedef void (z80::*OP_IDX)(byte);
void _step_idx(OP_IDX ops[]); void _step_idx(OP_IDX ops[]);
void _ddfd(word &ix, byte &ixL, byte &ixH, OP_IDX ops[]); void _ddfd(word &ix, byte &ixL, byte &ixH, OP_IDX ops[]);
@ -174,8 +174,8 @@ private:
ts(i); ts(i);
} }
inline word _rw(Memory::address a) { inline word _rw(Memory::address a) {
return _rb(a) + (_rb(a+1) << 8); return _rb(a) + (_rb(a+1) << 8);
} }
inline void _sw(Memory::address a, word w) { inline void _sw(Memory::address a, word w) {
@ -399,10 +399,10 @@ private:
void incc() { _inc(C); } void incc() { _inc(C); }
void decc() { _dec(C); } void decc() { _dec(C); }
void ldc() { C = _rb(PC++); } void ldc() { C = _rb(PC++); }
void rrca() { void rrca() {
flags.H = flags.N = 0; flags.H = flags.N = 0;
flags.C = (A & 0x01); flags.C = (A & 0x01);
A = (A >> 1) | (flags.C << 7); A = (A >> 1) | (flags.C << 7);
_35(A); _35(A);
} }
@ -414,16 +414,16 @@ private:
void incd() { _inc(D); } void incd() { _inc(D); }
void decd() { _dec(D); } void decd() { _dec(D); }
void ldd() { D = _rb(PC++); } void ldd() { D = _rb(PC++); }
void rla() { void rla() {
byte b = (A << 1) | flags.C; byte b = (A << 1) | flags.C;
flags.C = (A & 0x80) >> 7; flags.C = (A & 0x80) >> 7;
A = b; A = b;
} }
// 0x18 // 0x18
void jr() { void jr() {
byte b = _rb(PC); byte b = _rb(PC);
_mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1); _mc(PC, 1);
PC = _ads(PC, b+1); PC = _ads(PC, b+1);
} }
void addhlde() { _add16(HL, DE); } void addhlde() { _add16(HL, DE); }
@ -1162,8 +1162,8 @@ private:
void set7a() { A |= 0x80; } void set7a() { A |= 0x80; }
inline void _bitI(int i, word a) { inline void _bitI(int i, word a) {
byte b = _rb(a); byte b = _rb(a);
_mc(a, 1); _mc(a, 1);
_bit(i, b); _bit(i, b);
_35(a >> 8); _35(a >> 8);
} }
@ -1178,8 +1178,8 @@ private:
} }
// 0x00 // 0x00
inline void _rlcIX(byte &b, byte o) { inline void _rlcIX(byte &b, byte o) {
word a = _rbIX(b, o); _rlc(b); _sb(a, b); word a = _rbIX(b, o); _rlc(b); _sb(a, b);
} }
void rlcIXB(byte o) { _rlcIX(B, o); } void rlcIXB(byte o) { _rlcIX(B, o); }
void rlcIXC(byte o) { _rlcIX(C, o); } void rlcIXC(byte o) { _rlcIX(C, o); }
@ -1191,8 +1191,8 @@ private:
void rlcIXA(byte o) { _rlcIX(A, o); } void rlcIXA(byte o) { _rlcIX(A, o); }
// 0x08 // 0x08
inline void _rrcIX(byte &b, byte o) { inline void _rrcIX(byte &b, byte o) {
word a = _rbIX(b, o); _rrc(b); _sb(a, b); word a = _rbIX(b, o); _rrc(b); _sb(a, b);
} }
void rrcIXB(byte o) { _rrcIX(B, o); } void rrcIXB(byte o) { _rrcIX(B, o); }
void rrcIXC(byte o) { _rrcIX(C, o); } void rrcIXC(byte o) { _rrcIX(C, o); }
@ -1204,8 +1204,8 @@ private:
void rrcIXA(byte o) { _rrcIX(A, o); } void rrcIXA(byte o) { _rrcIX(A, o); }
// 0x10 // 0x10
inline void _rlIX(byte &b, byte o) { inline void _rlIX(byte &b, byte o) {
word a = _rbIX(b, o); _rl(b); _sb(a, b); word a = _rbIX(b, o); _rl(b); _sb(a, b);
} }
void rlIXB(byte o) { _rlIX(B, o); } void rlIXB(byte o) { _rlIX(B, o); }
void rlIXC(byte o) { _rlIX(C, o); } void rlIXC(byte o) { _rlIX(C, o); }
@ -1217,8 +1217,8 @@ private:
void rlIXA(byte o) { _rlIX(A, o); } void rlIXA(byte o) { _rlIX(A, o); }
// 0x18 // 0x18
inline void _rrIX(byte &b, byte o) { inline void _rrIX(byte &b, byte o) {
word a = _rbIX(b, o); _rr(b); _sb(a, b); word a = _rbIX(b, o); _rr(b); _sb(a, b);
} }
void rrIXB(byte o) { _rrIX(B, o); } void rrIXB(byte o) { _rrIX(B, o); }
void rrIXC(byte o) { _rrIX(C, o); } void rrIXC(byte o) { _rrIX(C, o); }
@ -1230,8 +1230,8 @@ private:
void rrIXA(byte o) { _rrIX(A, o); } void rrIXA(byte o) { _rrIX(A, o); }
// 0x20 // 0x20
inline void _slaIX(byte &b, byte o) { inline void _slaIX(byte &b, byte o) {
word a = _rbIX(b, o); _sla(b); _sb(a, b); word a = _rbIX(b, o); _sla(b); _sb(a, b);
} }
void slaIXB(byte o) { _slaIX(B, o); } void slaIXB(byte o) { _slaIX(B, o); }
void slaIXC(byte o) { _slaIX(C, o); } void slaIXC(byte o) { _slaIX(C, o); }
@ -1243,8 +1243,8 @@ private:
void slaIXA(byte o) { _slaIX(A, o); } void slaIXA(byte o) { _slaIX(A, o); }
// 0x28 // 0x28
inline void _sraIX(byte &b, byte o) { inline void _sraIX(byte &b, byte o) {
word a = _rbIX(b, o); _sra(b); _sb(a, b); word a = _rbIX(b, o); _sra(b); _sb(a, b);
} }
void sraIXB(byte o) { _sraIX(B, o); } void sraIXB(byte o) { _sraIX(B, o); }
void sraIXC(byte o) { _sraIX(C, o); } void sraIXC(byte o) { _sraIX(C, o); }
@ -1256,8 +1256,8 @@ private:
void sraIXA(byte o) { _sraIX(A, o); } void sraIXA(byte o) { _sraIX(A, o); }
// 0x30 // 0x30
inline void _sllIX(byte &b, byte o) { inline void _sllIX(byte &b, byte o) {
word a = _rbIX(b, o); _sll(b); _sb(a, b); word a = _rbIX(b, o); _sll(b); _sb(a, b);
} }
void sllIXB(byte o) { _sllIX(B, o); } void sllIXB(byte o) { _sllIX(B, o); }
void sllIXC(byte o) { _sllIX(C, o); } void sllIXC(byte o) { _sllIX(C, o); }
@ -1269,8 +1269,8 @@ private:
void sllIXA(byte o) { _sllIX(A, o); } void sllIXA(byte o) { _sllIX(A, o); }
// 0x38 // 0x38
inline void _srlIX(byte &b, byte o) { inline void _srlIX(byte &b, byte o) {
word a = _rbIX(b, o); _srl(b); _sb(a, b); word a = _rbIX(b, o); _srl(b); _sb(a, b);
} }
void srlIXB(byte o) { _srlIX(B, o); } void srlIXB(byte o) { _srlIX(B, o); }
void srlIXC(byte o) { _srlIX(C, o); } void srlIXC(byte o) { _srlIX(C, o); }
@ -1489,8 +1489,8 @@ private:
} }
// 0x00 // 0x00
inline void _rlcIY(byte &b, byte o) { inline void _rlcIY(byte &b, byte o) {
word a = _rbIY(b, o); _rlc(b); _sb(a, b); word a = _rbIY(b, o); _rlc(b); _sb(a, b);
} }
void rlcIYB(byte o) { _rlcIY(B, o); } void rlcIYB(byte o) { _rlcIY(B, o); }
void rlcIYC(byte o) { _rlcIY(C, o); } void rlcIYC(byte o) { _rlcIY(C, o); }
@ -1502,8 +1502,8 @@ private:
void rlcIYA(byte o) { _rlcIY(A, o); } void rlcIYA(byte o) { _rlcIY(A, o); }
// 0x08 // 0x08
inline void _rrcIY(byte &b, byte o) { inline void _rrcIY(byte &b, byte o) {
word a = _rbIY(b, o); _rrc(b); _sb(a, b); word a = _rbIY(b, o); _rrc(b); _sb(a, b);
} }
void rrcIYB(byte o) { _rrcIY(B, o); } void rrcIYB(byte o) { _rrcIY(B, o); }
void rrcIYC(byte o) { _rrcIY(C, o); } void rrcIYC(byte o) { _rrcIY(C, o); }
@ -1515,8 +1515,8 @@ private:
void rrcIYA(byte o) { _rrcIY(A, o); } void rrcIYA(byte o) { _rrcIY(A, o); }
// 0x10 // 0x10
inline void _rlIY(byte &b, byte o) { inline void _rlIY(byte &b, byte o) {
word a = _rbIY(b, o); _rl(b); _sb(a, b); word a = _rbIY(b, o); _rl(b); _sb(a, b);
} }
void rlIYB(byte o) { _rlIY(B, o); } void rlIYB(byte o) { _rlIY(B, o); }
void rlIYC(byte o) { _rlIY(C, o); } void rlIYC(byte o) { _rlIY(C, o); }
@ -1528,8 +1528,8 @@ private:
void rlIYA(byte o) { _rlIY(A, o); } void rlIYA(byte o) { _rlIY(A, o); }
// 0x18 // 0x18
inline void _rrIY(byte &b, byte o) { inline void _rrIY(byte &b, byte o) {
word a = _rbIY(b, o); _rr(b); _sb(a, b); word a = _rbIY(b, o); _rr(b); _sb(a, b);
} }
void rrIYB(byte o) { _rrIY(B, o); } void rrIYB(byte o) { _rrIY(B, o); }
void rrIYC(byte o) { _rrIY(C, o); } void rrIYC(byte o) { _rrIY(C, o); }
@ -1541,8 +1541,8 @@ private:
void rrIYA(byte o) { _rrIY(A, o); } void rrIYA(byte o) { _rrIY(A, o); }
// 0x20 // 0x20
inline void _slaIY(byte &b, byte o) { inline void _slaIY(byte &b, byte o) {
word a = _rbIY(b, o); _sla(b); _sb(a, b); word a = _rbIY(b, o); _sla(b); _sb(a, b);
} }
void slaIYB(byte o) { _slaIY(B, o); } void slaIYB(byte o) { _slaIY(B, o); }
void slaIYC(byte o) { _slaIY(C, o); } void slaIYC(byte o) { _slaIY(C, o); }
@ -1554,8 +1554,8 @@ private:
void slaIYA(byte o) { _slaIY(A, o); } void slaIYA(byte o) { _slaIY(A, o); }
// 0x28 // 0x28
inline void _sraIY(byte &b, byte o) { inline void _sraIY(byte &b, byte o) {
word a = _rbIY(b, o); _sra(b); _sb(a, b); word a = _rbIY(b, o); _sra(b); _sb(a, b);
} }
void sraIYB(byte o) { _sraIY(B, o); } void sraIYB(byte o) { _sraIY(B, o); }
void sraIYC(byte o) { _sraIY(C, o); } void sraIYC(byte o) { _sraIY(C, o); }
@ -1567,8 +1567,8 @@ private:
void sraIYA(byte o) { _sraIY(A, o); } void sraIYA(byte o) { _sraIY(A, o); }
// 0x30 // 0x30
inline void _sllIY(byte &b, byte o) { inline void _sllIY(byte &b, byte o) {
word a = _rbIY(b, o); _sll(b); _sb(a, b); word a = _rbIY(b, o); _sll(b); _sb(a, b);
} }
void sllIYB(byte o) { _sllIY(B, o); } void sllIYB(byte o) { _sllIY(B, o); }
void sllIYC(byte o) { _sllIY(C, o); } void sllIYC(byte o) { _sllIY(C, o); }
@ -1580,8 +1580,8 @@ private:
void sllIYA(byte o) { _sllIY(A, o); } void sllIYA(byte o) { _sllIY(A, o); }
// 0x38 // 0x38
inline void _srlIY(byte &b, byte o) { inline void _srlIY(byte &b, byte o) {
word a = _rbIY(b, o); _srl(b); _sb(a, b); word a = _rbIY(b, o); _srl(b); _sb(a, b);
} }
void srlIYB(byte o) { _srlIY(B, o); } void srlIYB(byte o) { _srlIY(B, o); }
void srlIYC(byte o) { _srlIY(C, o); } void srlIYC(byte o) { _srlIY(C, o); }