From f3ebb822a6c08e7a086851b2205c05d53231ae48 Mon Sep 17 00:00:00 2001 From: edmccard Date: Tue, 10 Apr 2012 19:31:47 -0400 Subject: [PATCH] Split ctfe code from cpu code --- src/Makefile | 2 +- src/{cpu6502.d => cpu/ctfe_d6502.d} | 366 +--------------------------- src/cpu/d6502.d | 179 ++++++++++++++ src/cpu/data_d6502.d | 190 +++++++++++++++ test/cpu.d | 2 +- 5 files changed, 373 insertions(+), 366 deletions(-) rename src/{cpu6502.d => cpu/ctfe_d6502.d} (69%) create mode 100644 src/cpu/d6502.d create mode 100644 src/cpu/data_d6502.d diff --git a/src/Makefile b/src/Makefile index 48e0a18..7136c8f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ LINK_OPTS = -L-lpthread -L-lGL -L-ldl -L-lX11 \ -L-L$(GTKD) -L-lgtkd -L-lgtkdgl \ -L-L$(DERELICT)/lib -L-lDerelictSDL -L-lDerelictUtil \ -ALL_SRC = $(shell find -name "*.d" \! -name "cpu6502.d") +ALL_SRC = $(shell find -name "*.d" \! -path "./cpu/*") ALL_OBJS = $(ALL_SRC:%.d=%.o) all: ${ALL_OBJS} diff --git a/src/cpu6502.d b/src/cpu/ctfe_d6502.d similarity index 69% rename from src/cpu6502.d rename to src/cpu/ctfe_d6502.d index fed6329..df3e97e 100644 --- a/src/cpu6502.d +++ b/src/cpu/ctfe_d6502.d @@ -1,52 +1,7 @@ -/+ - + cpu6502.d - + - + Copyright: 2012 Ed McCardell, 2007 Gerald Stocker - + - + This file is part of twoapple-reboot. - + - + twoapple-reboot is free software; you can redistribute it and/or modify - + it under the terms of the GNU General Public License as published by - + the Free Software Foundation; either version 2 of the License, or - + (at your option) any later version. - + - + twoapple-reboot is distributed in the hope that it will be useful, - + but WITHOUT ANY WARRANTY; without even the implied warranty of - + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - + GNU General Public License for more details. - + - + You should have received a copy of the GNU General Public License - + along with twoapple-reboot; if not, write to the Free Software - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - +/ +module cpu.ctfe_d6502; -module cpu6502; - - -import std.array, std.format; - - -enum Strict : bool -{ - no, yes -} - -enum Cumulative : bool -{ - no, yes -} - - -template is6502(T) -{ - enum is6502 = __traits(getMember, T, "_chip") == "6502"; -} - -template is65C02(T) -{ - enum is65C02 = __traits(getMember, T, "_chip") == "65C02"; -} +import cpu.data_d6502; // The following versions are mutually exclusive. @@ -101,112 +56,6 @@ static if (!__traits(compiles, { bool b = opArray; })) enum opArray = 0; static assert (versionCheck); -final class Cpu(string chip, bool strict, bool cumulative) -{ - static assert(chip == "6502" || chip == "65C02" || chip == "65c02"); - enum _isCpu = true; - enum _chip = (chip == "6502" ? "6502" : "65C02"); - enum _isStrict = strict; - enum _isCumulative = cumulative; - - struct _Mem - { - // Reads a value from system memory. - ubyte delegate(ushort addr) read; - - // Writes a value to system memory. - void delegate(ushort addr, ubyte val) write; - } - _Mem memory; - - struct _Clock - { - static if (cumulative) - /* - * Updates the number of cycles executed. Called just - * prior to the final read/write action of each opcode. - */ - void delegate(int cycles) tick; - else - /* - * Increments the number of cycles executed. Called prior - * to each read/write action. - */ - void delegate() tick; - } - _Clock clock; - - ubyte A, X, Y, S; - ushort PC; - - // The status flags. - ubyte N, Z; - bool V, D, I, C; - - static if (opArray) { mixin(OpArrayDef()); } - - // TODO: other methods for stopping cpu - bool keepRunning; - - this() - { - static if (opArray) mixin(OpArrayInit()); - } - - final void statusFromByte(ubyte p) - { - N = p; - V = ((p & 0x40) != 0); - D = ((p & 0x08) != 0); - I = ((p & 0x04) != 0); - Z = ((p & 0x02) ? 0 : 1); - C = ((p & 0x01) != 0); - } - - final ubyte statusToByte() - { - return (C ? 0x01 : 0) | - ((Z == 0) ? 0x02 : 0) | - (I ? 0x04 : 0) | - (D ? 0x08 : 0) | - 0x30 | // break and reserved both set - (V ? 0x40 : 0) | - (N & 0x80); - } - - final void run(bool continuous) - { - keepRunning = continuous; - // TODO debugging info? - ubyte opcode; - static if (!opArray) - { - static if (cumulative) { int cycles; } - ubyte op1; - ushort address, base; - ubyte data; - } - do { - static if (cumulative && !opArray) - cycles = 1; - // XXX figure out final cycle stuff - static if (!cumulative) - clock.tick(); - // XXX check signals, NMI/IRQ delays, etc. - opcode = memory.read(PC++); - mixin(OpExecute(_chip, strict, cumulative)); - } while (keepRunning); - } - - version(OpDelegates) mixin (OpBodies(_chip, strict, cumulative)); -} - - -enum ushort IRQ_VECTOR = 0xFFFE; - - -private: - string OpArrayDef() { version(OpDelegates) @@ -1266,195 +1115,6 @@ int opExCyc(int op, string chip) } -// Opcode names. -immutable OP_NAMES_6502 = [ - "BRK", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO", - "PHP", "ORA", "ASL", "ANC", "NOP", "ORA", "ASL", "SLO", - "BPL", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO", - "CLC", "ORA", "NOP", "SLO", "NOP", "ORA", "ASL", "SLO", - "JSR", "AND", "KIL", "RLA", "BIT", "AND", "ROL", "RLA", - "PLP", "AND", "ROL", "ANC", "BIT", "AND", "ROL", "RLA", - "BMI", "AND", "KIL", "RLA", "NOP", "AND", "ROL", "RLA", - "SEC", "AND", "NOP", "RLA", "NOP", "AND", "ROL", "RLA", - "RTI", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE", - "PHA", "EOR", "LSR", "ALR", "JMP", "EOR", "LSR", "SRE", - "BVC", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE", - "CLI", "EOR", "NOP", "SRE", "NOP", "EOR", "LSR", "SRE", - "RTS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA", - "PLA", "ADC", "ROR", "ARR", "JMP", "ADC", "ROR", "RRA", - "BVS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA", - "SEI", "ADC", "NOP", "RRA", "NOP", "ADC", "ROR", "RRA", - "NOP", "STA", "NOP", "SAX", "STY", "STA", "STX", "SAX", - "DEY", "NOP", "TXA", "XAA", "STY", "STA", "STX", "SAX", - "BCC", "STA", "KIL", "AHX", "STY", "STA", "STX", "SAX", - "TYA", "STA", "TXS", "TAS", "SHY", "STA", "SHX", "AHX", - "LDY", "LDA", "LDX", "LAX", "LDY", "LDA", "LDX", "LAX", - "TAY", "LDA", "TAX", "LAX", "LDY", "LDA", "LDX", "LAX", - "BCS", "LDA", "KIL", "LAX", "LDY", "LDA", "LDX", "LAX", - "CLV", "LDA", "TSX", "LAS", "LDY", "LDA", "LDX", "LAX", - "CPY", "CMP", "NOP", "DCP", "CPY", "CMP", "DEC", "DCP", - "INY", "CMP", "DEX", "AXS", "CPY", "CMP", "DEC", "DCP", - "BNE", "CMP", "KIL", "DCP", "NOP", "CMP", "DEC", "DCP", - "CLD", "CMP", "NOP", "DCP", "NOP", "CMP", "DEC", "DCP", - "CPX", "SBC", "NOP", "ISC", "CPX", "SBC", "INC", "ISC", - "INX", "SBC", "NOP", "SBC", "CPX", "SBC", "INC", "ISC", - "BEQ", "SBC", "KIL", "ISC", "NOP", "SBC", "INC", "ISC", - "SED", "SBC", "NOP", "ISC", "NOP", "SBC", "INC", "ISC" -]; - -immutable OP_NAMES_65C02 = [ - "BRK", "ORA", "NOP", "NOP", "TSB", "ORA", "ASL", "NOP", - "PHP", "ORA", "ASL", "NOP", "TSB", "ORA", "ASL", "NOP", - "BPL", "ORA", "ORA", "NOP", "TRB", "ORA", "ASL", "NOP", - "CLC", "ORA", "INC", "NOP", "TRB", "ORA", "ASL", "NOP", - "JSR", "AND", "NOP", "NOP", "BIT", "AND", "ROL", "NOP", - "PLP", "AND", "ROL", "NOP", "BIT", "AND", "ROL", "NOP", - "BMI", "AND", "AND", "NOP", "BIT", "AND", "ROL", "NOP", - "SEC", "AND", "DEC", "NOP", "BIT", "AND", "ROL", "NOP", - "RTI", "EOR", "NOP", "NOP", "NOP", "EOR", "LSR", "NOP", - "PHA", "EOR", "LSR", "NOP", "JMP", "EOR", "LSR", "NOP", - "BVC", "EOR", "EOR", "NOP", "NOP", "EOR", "LSR", "NOP", - "CLI", "EOR", "PHY", "NOP", "NOP", "EOR", "LSR", "NOP", - "RTS", "ADC", "NOP", "NOP", "STZ", "ADC", "ROR", "NOP", - "PLA", "ADC", "ROR", "NOP", "JMP", "ADC", "ROR", "NOP", - "BVS", "ADC", "ADC", "NOP", "STZ", "ADC", "ROR", "NOP", - "SEI", "ADC", "PLY", "NOP", "JMP", "ADC", "ROR", "NOP", - "BRA", "STA", "NOP", "NOP", "STY", "STA", "STX", "NOP", - "DEY", "BIT", "TXA", "NOP", "STY", "STA", "STX", "NOP", - "BCC", "STA", "STA", "NOP", "STY", "STA", "STX", "NOP", - "TYA", "STA", "TXS", "NOP", "STZ", "STA", "STZ", "NOP", - "LDY", "LDA", "LDX", "NOP", "LDY", "LDA", "LDX", "NOP", - "TAY", "LDA", "TAX", "NOP", "LDY", "LDA", "LDX", "NOP", - "BCS", "LDA", "LDA", "NOP", "LDY", "LDA", "LDX", "NOP", - "CLV", "LDA", "TSX", "NOP", "LDY", "LDA", "LDX", "NOP", - "CPY", "CMP", "NOP", "NOP", "CPY", "CMP", "DEC", "NOP", - "INY", "CMP", "DEX", "NOP", "CPY", "CMP", "DEC", "NOP", - "BNE", "CMP", "CMP", "NOP", "NOP", "CMP", "DEC", "NOP", - "CLD", "CMP", "PHX", "NOP", "NOP", "CMP", "DEC", "NOP", - "CPX", "SBC", "NOP", "NOP", "CPX", "SBC", "INC", "NOP", - "INX", "SBC", "NOP", "NOP", "CPX", "SBC", "INC", "NOP", - "BEQ", "SBC", "SBC", "NOP", "NOP", "SBC", "INC", "NOP", - "SED", "SBC", "PLX", "NOP", "NOP", "SBC", "INC", "NOP" -]; - - -// Addressing modes. - -enum { IMP, IMM, ZP, ZPX, ZPY, IZX, IZY, ABS, ABX, ABY, IND, REL, - ZPI, ABI, NP1, NP8, KIL } - -immutable ADDR_MODES_6502 = [ - IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, - ABS, IZX, KIL, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, - IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, - IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, IND, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, - IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPY, ZPY, - IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, - IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPY, ZPY, - IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, - IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, - IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, - IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, - REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, - IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX -]; - -immutable ADDR_MODES_65C02 = [ - IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZP, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, ABS, ABX, ABX, NP1, - ABS, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, - IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, NP8, ABX, ABX, NP1, - IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, IND, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, ABI, ABX, ABX, NP1, - REL, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPY, NP1, - IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, - IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPY, NP1, - IMP, ABY, IMP, NP1, ABX, ABX, ABY, NP1, - IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, - IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, - IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, - REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, - IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1 -]; - - -// Page-crossing extra cycles. - -immutable EXTRA_CYCLES_6502 = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, -]; - -immutable EXTRA_CYCLES_65C02 = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -]; - - // Custom string formatting. enum HEX_DIGITS = "0123456789abcdef"; @@ -1490,25 +1150,3 @@ string Fmt(string f, string[] p ...) } return ret ~ f[last..$]; } - - -version(OpFunctions) mixin(OpBodies("6502", vStrict, vCumulative)); -version(OpFunctions) mixin(OpBodies("65C02", vStrict, vCumulative)); - - -//alias Cpu!("6502", false, false) T1; -//alias Cpu!("6502", false, true) T2; -//alias Cpu!("6502", true, false) T3; -//alias Cpu!("6502", true, true) T4; -//alias Cpu!("65C02", false, false) T5; -//alias Cpu!("65C02", false, true) T6; -//alias Cpu!("65C02", true, false) T7; -//alias Cpu!("65C02", true, true) T8; - -/+ -void main() -{ - import std.stdio; - writeln(OpBody(0x11, "6502", true, false)); -} -+/ diff --git a/src/cpu/d6502.d b/src/cpu/d6502.d new file mode 100644 index 0000000..4d923ad --- /dev/null +++ b/src/cpu/d6502.d @@ -0,0 +1,179 @@ +/+ + + cpu/d6502.d + + + + Copyright: 2012 Ed McCardell, 2007 Gerald Stocker + + + + This file is part of twoapple-reboot. + + + + twoapple-reboot is free software; you can redistribute it and/or modify + + it under the terms of the GNU General Public License as published by + + the Free Software Foundation; either version 2 of the License, or + + (at your option) any later version. + + + + twoapple-reboot is distributed in the hope that it will be useful, + + but WITHOUT ANY WARRANTY; without even the implied warranty of + + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public License + + along with twoapple-reboot; if not, write to the Free Software + + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +/ + + +module cpu.d6502; + + +import std.array, std.format; + +import cpu.ctfe_d6502; + + +enum Strict : bool +{ + no, yes +} + +enum Cumulative : bool +{ + no, yes +} + + +template is6502(T) +{ + enum is6502 = __traits(getMember, T, "_chip") == "6502"; +} + +template is65C02(T) +{ + enum is65C02 = __traits(getMember, T, "_chip") == "65C02"; +} + + +final class Cpu(string chip, bool strict, bool cumulative) +{ + static assert(chip == "6502" || chip == "65C02" || chip == "65c02"); + enum _isCpu = true; + enum _chip = (chip == "6502" ? "6502" : "65C02"); + enum _isStrict = strict; + enum _isCumulative = cumulative; + + struct _Mem + { + // Reads a value from system memory. + ubyte delegate(ushort addr) read; + + // Writes a value to system memory. + void delegate(ushort addr, ubyte val) write; + } + _Mem memory; + + struct _Clock + { + static if (cumulative) + /* + * Updates the number of cycles executed. Called just + * prior to the final read/write action of each opcode. + */ + void delegate(int cycles) tick; + else + /* + * Increments the number of cycles executed. Called prior + * to each read/write action. + */ + void delegate() tick; + } + _Clock clock; + + ubyte A, X, Y, S; + ushort PC; + + // The status flags. + ubyte N, Z; + bool V, D, I, C; + + static if (opArray) { mixin(OpArrayDef()); } + + // TODO: other methods for stopping cpu + bool keepRunning; + + this() + { + static if (opArray) mixin(OpArrayInit()); + } + + final void statusFromByte(ubyte p) + { + N = p; + V = ((p & 0x40) != 0); + D = ((p & 0x08) != 0); + I = ((p & 0x04) != 0); + Z = ((p & 0x02) ? 0 : 1); + C = ((p & 0x01) != 0); + } + + final ubyte statusToByte() + { + return (C ? 0x01 : 0) | + ((Z == 0) ? 0x02 : 0) | + (I ? 0x04 : 0) | + (D ? 0x08 : 0) | + 0x30 | // break and reserved both set + (V ? 0x40 : 0) | + (N & 0x80); + } + + final void run(bool continuous) + { + keepRunning = continuous; + // TODO debugging info? + ubyte opcode; + static if (!opArray) + { + static if (cumulative) { int cycles; } + ubyte op1; + ushort address, base; + ubyte data; + } + do { + static if (cumulative && !opArray) + cycles = 1; + // XXX figure out final cycle stuff + static if (!cumulative) + clock.tick(); + // XXX check signals, NMI/IRQ delays, etc. + opcode = memory.read(PC++); + mixin(OpExecute(_chip, strict, cumulative)); + } while (keepRunning); + } + + version(OpDelegates) mixin (OpBodies(_chip, strict, cumulative)); +} + + +enum ushort IRQ_VECTOR = 0xFFFE; + + +private: + +version(OpFunctions) mixin(OpBodies("6502", vStrict, vCumulative)); +version(OpFunctions) mixin(OpBodies("65C02", vStrict, vCumulative)); + + +//alias Cpu!("6502", false, false) T1; +//alias Cpu!("6502", false, true) T2; +//alias Cpu!("6502", true, false) T3; +//alias Cpu!("6502", true, true) T4; +//alias Cpu!("65C02", false, false) T5; +//alias Cpu!("65C02", false, true) T6; +//alias Cpu!("65C02", true, false) T7; +//alias Cpu!("65C02", true, true) T8; + +/+ +void main() +{ + import std.stdio; + writeln(OpBody(0x11, "6502", true, false)); +} ++/ diff --git a/src/cpu/data_d6502.d b/src/cpu/data_d6502.d new file mode 100644 index 0000000..a9a2077 --- /dev/null +++ b/src/cpu/data_d6502.d @@ -0,0 +1,190 @@ +module cpu.data_d6502; + + +// Opcode names. +immutable OP_NAMES_6502 = [ + "BRK", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO", + "PHP", "ORA", "ASL", "ANC", "NOP", "ORA", "ASL", "SLO", + "BPL", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO", + "CLC", "ORA", "NOP", "SLO", "NOP", "ORA", "ASL", "SLO", + "JSR", "AND", "KIL", "RLA", "BIT", "AND", "ROL", "RLA", + "PLP", "AND", "ROL", "ANC", "BIT", "AND", "ROL", "RLA", + "BMI", "AND", "KIL", "RLA", "NOP", "AND", "ROL", "RLA", + "SEC", "AND", "NOP", "RLA", "NOP", "AND", "ROL", "RLA", + "RTI", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE", + "PHA", "EOR", "LSR", "ALR", "JMP", "EOR", "LSR", "SRE", + "BVC", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE", + "CLI", "EOR", "NOP", "SRE", "NOP", "EOR", "LSR", "SRE", + "RTS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA", + "PLA", "ADC", "ROR", "ARR", "JMP", "ADC", "ROR", "RRA", + "BVS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA", + "SEI", "ADC", "NOP", "RRA", "NOP", "ADC", "ROR", "RRA", + "NOP", "STA", "NOP", "SAX", "STY", "STA", "STX", "SAX", + "DEY", "NOP", "TXA", "XAA", "STY", "STA", "STX", "SAX", + "BCC", "STA", "KIL", "AHX", "STY", "STA", "STX", "SAX", + "TYA", "STA", "TXS", "TAS", "SHY", "STA", "SHX", "AHX", + "LDY", "LDA", "LDX", "LAX", "LDY", "LDA", "LDX", "LAX", + "TAY", "LDA", "TAX", "LAX", "LDY", "LDA", "LDX", "LAX", + "BCS", "LDA", "KIL", "LAX", "LDY", "LDA", "LDX", "LAX", + "CLV", "LDA", "TSX", "LAS", "LDY", "LDA", "LDX", "LAX", + "CPY", "CMP", "NOP", "DCP", "CPY", "CMP", "DEC", "DCP", + "INY", "CMP", "DEX", "AXS", "CPY", "CMP", "DEC", "DCP", + "BNE", "CMP", "KIL", "DCP", "NOP", "CMP", "DEC", "DCP", + "CLD", "CMP", "NOP", "DCP", "NOP", "CMP", "DEC", "DCP", + "CPX", "SBC", "NOP", "ISC", "CPX", "SBC", "INC", "ISC", + "INX", "SBC", "NOP", "SBC", "CPX", "SBC", "INC", "ISC", + "BEQ", "SBC", "KIL", "ISC", "NOP", "SBC", "INC", "ISC", + "SED", "SBC", "NOP", "ISC", "NOP", "SBC", "INC", "ISC" +]; + +immutable OP_NAMES_65C02 = [ + "BRK", "ORA", "NOP", "NOP", "TSB", "ORA", "ASL", "NOP", + "PHP", "ORA", "ASL", "NOP", "TSB", "ORA", "ASL", "NOP", + "BPL", "ORA", "ORA", "NOP", "TRB", "ORA", "ASL", "NOP", + "CLC", "ORA", "INC", "NOP", "TRB", "ORA", "ASL", "NOP", + "JSR", "AND", "NOP", "NOP", "BIT", "AND", "ROL", "NOP", + "PLP", "AND", "ROL", "NOP", "BIT", "AND", "ROL", "NOP", + "BMI", "AND", "AND", "NOP", "BIT", "AND", "ROL", "NOP", + "SEC", "AND", "DEC", "NOP", "BIT", "AND", "ROL", "NOP", + "RTI", "EOR", "NOP", "NOP", "NOP", "EOR", "LSR", "NOP", + "PHA", "EOR", "LSR", "NOP", "JMP", "EOR", "LSR", "NOP", + "BVC", "EOR", "EOR", "NOP", "NOP", "EOR", "LSR", "NOP", + "CLI", "EOR", "PHY", "NOP", "NOP", "EOR", "LSR", "NOP", + "RTS", "ADC", "NOP", "NOP", "STZ", "ADC", "ROR", "NOP", + "PLA", "ADC", "ROR", "NOP", "JMP", "ADC", "ROR", "NOP", + "BVS", "ADC", "ADC", "NOP", "STZ", "ADC", "ROR", "NOP", + "SEI", "ADC", "PLY", "NOP", "JMP", "ADC", "ROR", "NOP", + "BRA", "STA", "NOP", "NOP", "STY", "STA", "STX", "NOP", + "DEY", "BIT", "TXA", "NOP", "STY", "STA", "STX", "NOP", + "BCC", "STA", "STA", "NOP", "STY", "STA", "STX", "NOP", + "TYA", "STA", "TXS", "NOP", "STZ", "STA", "STZ", "NOP", + "LDY", "LDA", "LDX", "NOP", "LDY", "LDA", "LDX", "NOP", + "TAY", "LDA", "TAX", "NOP", "LDY", "LDA", "LDX", "NOP", + "BCS", "LDA", "LDA", "NOP", "LDY", "LDA", "LDX", "NOP", + "CLV", "LDA", "TSX", "NOP", "LDY", "LDA", "LDX", "NOP", + "CPY", "CMP", "NOP", "NOP", "CPY", "CMP", "DEC", "NOP", + "INY", "CMP", "DEX", "NOP", "CPY", "CMP", "DEC", "NOP", + "BNE", "CMP", "CMP", "NOP", "NOP", "CMP", "DEC", "NOP", + "CLD", "CMP", "PHX", "NOP", "NOP", "CMP", "DEC", "NOP", + "CPX", "SBC", "NOP", "NOP", "CPX", "SBC", "INC", "NOP", + "INX", "SBC", "NOP", "NOP", "CPX", "SBC", "INC", "NOP", + "BEQ", "SBC", "SBC", "NOP", "NOP", "SBC", "INC", "NOP", + "SED", "SBC", "PLX", "NOP", "NOP", "SBC", "INC", "NOP" +]; + + +// Addressing modes. + +enum { IMP, IMM, ZP, ZPX, ZPY, IZX, IZY, ABS, ABX, ABY, IND, REL, + ZPI, ABI, NP1, NP8, KIL } + +immutable ADDR_MODES_6502 = [ + IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + ABS, IZX, KIL, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMP, IZX, KIL, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, IND, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPY, ZPY, + IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, + IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPY, ZPY, + IMP, ABY, IMP, ABY, ABX, ABX, ABY, ABY, + IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX, + IMM, IZX, IMM, IZX, ZP, ZP, ZP, ZP, + IMP, IMM, IMP, IMM, ABS, ABS, ABS, ABS, + REL, IZY, KIL, IZY, ZPX, ZPX, ZPX, ZPX, + IMP, ABY, IMP, ABY, ABX, ABX, ABX, ABX +]; + +immutable ADDR_MODES_65C02 = [ + IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZP, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, ABS, ABX, ABX, NP1, + ABS, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, + IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, NP8, ABX, ABX, NP1, + IMP, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, IND, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, ABI, ABX, ABX, NP1, + REL, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPY, NP1, + IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, + IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPY, NP1, + IMP, ABY, IMP, NP1, ABX, ABX, ABY, NP1, + IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1, + IMM, IZX, IMM, NP1, ZP, ZP, ZP, NP1, + IMP, IMM, IMP, NP1, ABS, ABS, ABS, NP1, + REL, IZY, ZPI, NP1, ZPX, ZPX, ZPX, NP1, + IMP, ABY, IMP, NP1, ABX, ABX, ABX, NP1 +]; + + +// Page-crossing extra cycles. + +immutable EXTRA_CYCLES_6502 = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, +]; + +immutable EXTRA_CYCLES_65C02 = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +]; diff --git a/test/cpu.d b/test/cpu.d index 3ba9e9a..dd22535 100644 --- a/test/cpu.d +++ b/test/cpu.d @@ -8,7 +8,7 @@ module test.cpu; import std.conv, std.exception, std.random, std.string, std.traits; -public import cpu6502 : Cpu, is6502, is65C02; +public import cpu.d6502 : Cpu, is6502, is65C02; // True if T is the type of a cpu.