From 3a028fb6219f46dec01e9e00fd70e89df699ed58 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Mon, 20 May 2013 20:20:14 +0200 Subject: [PATCH] Turned sim65 into a lightweight cc65 execution environment. The sim65 source code has been a construction site for over a decade. I was looking for a simple cc65 program execution environment for regression tests. So I decided to re-purpose sim65 for that task by removing about everything but the 6502 emulation. There's no memory mapped i/o emulation whatsoever. Rather exit(), open(), close(), read() and write() calls are supported by mapping them through a thin paravirtualization layer to the corresponding host os functions. Note: The sim65 6502 emulation provides means to switch between 6502 and 65C02 emulation but currently there are no actual 65C02 opcodes implemented. --- src/Makefile | 1 + src/cc65.sln | 9 + src/sim65.vcxproj | 96 + src/sim65/6502.c | 2830 ++++++++++++++++++++++++++ src/sim65/{addrspace.h => 6502.h} | 79 +- src/sim65/addrspace.c | 190 -- src/sim65/callback.c | 191 -- src/sim65/callback.h | 77 - src/sim65/cfgdata.c | 234 --- src/sim65/cfgdata.h | 120 -- src/sim65/chip.c | 419 ---- src/sim65/chip.h | 118 -- src/sim65/chipdata.h | 82 - src/sim65/chipif.h | 52 - src/sim65/chippath.c | 81 - src/sim65/chippath.h | 72 - src/sim65/chips/console.c | 659 ------ src/sim65/chips/ram.c | 266 --- src/sim65/chips/rom.c | 255 --- src/sim65/chips/stdio.c | 289 --- src/sim65/chips/vic2.c | 897 -------- src/sim65/config.c | 393 ---- src/sim65/cpucore.c | 75 - src/sim65/cpucore.h | 83 - src/sim65/cpudata.h | 97 - src/sim65/cpus/6502.c | 3053 ---------------------------- src/sim65/cputype.c | 50 - src/sim65/cputype.h | 64 - src/sim65/global.c | 49 - src/sim65/global.h | 57 - src/sim65/location.c | 174 -- src/sim65/location.h | 97 - src/sim65/main.c | 217 +- src/sim65/memory.c | 89 +- src/sim65/memory.h | 20 - src/sim65/paravirt.c | 255 +++ src/sim65/{config.h => paravirt.h} | 21 +- src/sim65/scanner.c | 530 ----- src/sim65/scanner.h | 180 -- src/sim65/simdata.h | 118 -- src/sim65/system.c | 70 - src/sim65/system.h | 91 - 42 files changed, 3317 insertions(+), 9483 deletions(-) create mode 100644 src/sim65.vcxproj create mode 100644 src/sim65/6502.c rename src/sim65/{addrspace.h => 6502.h} (66%) delete mode 100644 src/sim65/addrspace.c delete mode 100644 src/sim65/callback.c delete mode 100644 src/sim65/callback.h delete mode 100644 src/sim65/cfgdata.c delete mode 100644 src/sim65/cfgdata.h delete mode 100644 src/sim65/chip.c delete mode 100644 src/sim65/chip.h delete mode 100644 src/sim65/chipdata.h delete mode 100644 src/sim65/chipif.h delete mode 100644 src/sim65/chippath.c delete mode 100644 src/sim65/chippath.h delete mode 100644 src/sim65/chips/console.c delete mode 100644 src/sim65/chips/ram.c delete mode 100644 src/sim65/chips/rom.c delete mode 100644 src/sim65/chips/stdio.c delete mode 100644 src/sim65/chips/vic2.c delete mode 100644 src/sim65/config.c delete mode 100644 src/sim65/cpucore.c delete mode 100644 src/sim65/cpucore.h delete mode 100644 src/sim65/cpudata.h delete mode 100644 src/sim65/cpus/6502.c delete mode 100644 src/sim65/cputype.c delete mode 100644 src/sim65/cputype.h delete mode 100644 src/sim65/global.c delete mode 100644 src/sim65/global.h delete mode 100644 src/sim65/location.c delete mode 100644 src/sim65/location.h create mode 100644 src/sim65/paravirt.c rename src/sim65/{config.h => paravirt.h} (87%) delete mode 100644 src/sim65/scanner.c delete mode 100644 src/sim65/scanner.h delete mode 100644 src/sim65/simdata.h delete mode 100644 src/sim65/system.c delete mode 100644 src/sim65/system.h diff --git a/src/Makefile b/src/Makefile index 3f8c47d0f..8c4c6861e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,7 @@ PROGS = ar65 \ grc65 \ ld65 \ od65 \ + sim65 \ sp65 CA65_INC := $(abspath ../asminc) diff --git a/src/cc65.sln b/src/cc65.sln index 2c8a2e197..9d0f2cc2e 100644 --- a/src/cc65.sln +++ b/src/cc65.sln @@ -53,6 +53,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sp65", "sp65.vcxproj", "{43 {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sim65", "sim65.vcxproj", "{002A366E-2863-46A8-BDDE-DDF534AAEC73}" + ProjectSection(ProjectDependencies) = postProject + {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} = {71DC1F68-BFC4-478C-8655-C8E9C9654D2B} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -103,6 +108,10 @@ Global {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Debug|Win32.Build.0 = Debug|Win32 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.ActiveCfg = Release|Win32 {4388D1AF-C7EA-4AD4-8E80-CA1FB7BF76BF}.Release|Win32.Build.0 = Release|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.ActiveCfg = Debug|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Debug|Win32.Build.0 = Debug|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.ActiveCfg = Release|Win32 + {002A366E-2863-46A8-BDDE-DDF534AAEC73}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/sim65.vcxproj b/src/sim65.vcxproj new file mode 100644 index 000000000..06f227d09 --- /dev/null +++ b/src/sim65.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {002A366E-2863-46A8-BDDE-DDF534AAEC73} + Win32Proj + sim65 + + + + true + + + false + true + + + + + + + + + + + + + true + $(SolutionDir)..\bin\ + $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ + + + false + $(SolutionDir)..\bin\ + $(SolutionDir)..\wrk\$(ProjectName)\$(Configuration)\ + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;_CONSOLE;_DEBUG + common + true + + + Console + true + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG + common + true + + + Console + false + $(IntDir)..\..\common\$(Configuration)\common.lib + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/sim65/6502.c b/src/sim65/6502.c new file mode 100644 index 000000000..bb357cbb7 --- /dev/null +++ b/src/sim65/6502.c @@ -0,0 +1,2830 @@ +/*****************************************************************************/ +/* */ +/* 6502.c */ +/* */ +/* CPU core for the 6502 */ +/* */ +/* */ +/* */ +/* (C) 2003-2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include "memory.h" +#include "error.h" +#include "6502.h" +#include "paravirt.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Current CPU */ +CPUType CPU; + +/* Type of an opcode handler function */ +typedef void (*OPFunc) (void); + +/* The CPU registers */ +static CPURegs Regs; + +/* Cycles for the current insn */ +static unsigned Cycles; + +/* Total number of CPU cycles exec'd */ +static unsigned long TotalCycles; + +/* NMI request active */ +static unsigned HaveNMIRequest; + +/* IRQ request active */ +static unsigned HaveIRQRequest; + + + +/*****************************************************************************/ +/* Helper functions and macros */ +/*****************************************************************************/ + + + +/* Return the flags as a boolean value (0/1) */ +#define GET_CF() ((Regs.SR & CF) != 0) +#define GET_ZF() ((Regs.SR & ZF) != 0) +#define GET_IF() ((Regs.SR & IF) != 0) +#define GET_DF() ((Regs.SR & DF) != 0) +#define GET_BF() ((Regs.SR & BF) != 0) +#define GET_OF() ((Regs.SR & OF) != 0) +#define GET_SF() ((Regs.SR & SF) != 0) + +/* Set the flags. The parameter is a boolean flag that says if the flag should be + * set or reset. + */ +#define SET_CF(f) do { if (f) { Regs.SR |= CF; } else { Regs.SR &= ~CF; } } while (0) +#define SET_ZF(f) do { if (f) { Regs.SR |= ZF; } else { Regs.SR &= ~ZF; } } while (0) +#define SET_IF(f) do { if (f) { Regs.SR |= IF; } else { Regs.SR &= ~IF; } } while (0) +#define SET_DF(f) do { if (f) { Regs.SR |= DF; } else { Regs.SR &= ~DF; } } while (0) +#define SET_BF(f) do { if (f) { Regs.SR |= BF; } else { Regs.SR &= ~BF; } } while (0) +#define SET_OF(f) do { if (f) { Regs.SR |= OF; } else { Regs.SR &= ~OF; } } while (0) +#define SET_SF(f) do { if (f) { Regs.SR |= SF; } else { Regs.SR &= ~SF; } } while (0) + +/* Special test and set macros. The meaning of the parameter depends on the + * actual flag that should be set or reset. + */ +#define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0) +#define TEST_SF(v) SET_SF (((v) & 0x80) != 0) +#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0) + +/* Program counter halves */ +#define PCL (Regs.PC & 0xFF) +#define PCH ((Regs.PC >> 8) & 0xFF) + +/* Stack operations */ +#define PUSH(Val) MemWriteByte (0x0100 + Regs.SP--, Val) +#define POP() MemReadByte (0x0100 + ++Regs.SP) + +/* Test for page cross */ +#define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100) + +/* #imm */ +#define AC_OP_IMM(op) \ + Cycles = 2; \ + Regs.AC = Regs.AC op MemReadByte (Regs.PC+1); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* zp */ +#define AC_OP_ZP(op) \ + Cycles = 3; \ + Regs.AC = Regs.AC op MemReadByte (MemReadByte (Regs.PC+1)); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* zp,x */ +#define AC_OP_ZPX(op) \ + unsigned char ZPAddr; \ + Cycles = 4; \ + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \ + Regs.AC = Regs.AC op MemReadByte (ZPAddr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* zp,y */ +#define AC_OP_ZPY(op) \ + unsigned char ZPAddr; \ + Cycles = 4; \ + ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; \ + Regs.AC = Regs.AC op MemReadByte (ZPAddr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* abs */ +#define AC_OP_ABS(op) \ + unsigned Addr; \ + Cycles = 4; \ + Addr = MemReadWord (Regs.PC+1); \ + Regs.AC = Regs.AC op MemReadByte (Addr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 3 + +/* abs,x */ +#define AC_OP_ABSX(op) \ + unsigned Addr; \ + Cycles = 4; \ + Addr = MemReadWord (Regs.PC+1); \ + if (PAGE_CROSS (Addr, Regs.XR)) { \ + ++Cycles; \ + } \ + Regs.AC = Regs.AC op MemReadByte (Addr + Regs.XR); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 3 + +/* abs,y */ +#define AC_OP_ABSY(op) \ + unsigned Addr; \ + Cycles = 4; \ + Addr = MemReadWord (Regs.PC+1); \ + if (PAGE_CROSS (Addr, Regs.YR)) { \ + ++Cycles; \ + } \ + Regs.AC = Regs.AC op MemReadByte (Addr + Regs.YR); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 3 + +/* (zp,x) */ +#define AC_OP_ZPXIND(op) \ + unsigned char ZPAddr; \ + unsigned Addr; \ + Cycles = 6; \ + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \ + Addr = MemReadZPWord (ZPAddr); \ + Regs.AC = Regs.AC op MemReadByte (Addr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* (zp),y */ +#define AC_OP_ZPINDY(op) \ + unsigned char ZPAddr; \ + unsigned Addr; \ + Cycles = 5; \ + ZPAddr = MemReadByte (Regs.PC+1); \ + Addr = MemReadZPWord (ZPAddr) + Regs.YR; \ + Regs.AC = Regs.AC op MemReadByte (Addr); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + Regs.PC += 2 + +/* ADC */ +#define ADC(v) \ + do { \ + unsigned old = Regs.AC; \ + unsigned rhs = (v & 0xFF); \ + if (GET_DF ()) { \ + unsigned lo; \ + int res; \ + lo = (old & 0x0F) + (rhs & 0x0F) + GET_CF (); \ + if (lo >= 0x0A) { \ + lo = ((lo + 0x06) & 0x0F) + 0x10; \ + } \ + Regs.AC = (old & 0xF0) + (rhs & 0xF0) + lo; \ + res = (signed char)(old & 0xF0) + \ + (signed char)(rhs & 0xF0) + \ + (signed char)lo; \ + TEST_ZF (old + rhs + GET_CF ()); \ + TEST_SF (Regs.AC); \ + if (Regs.AC >= 0xA0) { \ + Regs.AC += 0x60; \ + } \ + TEST_CF (Regs.AC); \ + SET_OF ((res < -128) || (res > 127)); \ + } else { \ + Regs.AC += rhs + GET_CF (); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + TEST_CF (Regs.AC); \ + SET_OF (!((old ^ rhs) & 0x80) && \ + ((old ^ Regs.AC) & 0x80)); \ + Regs.AC &= 0xFF; \ + } \ + } while (0) + +/* branches */ +#define BRANCH(cond) \ + Cycles = 2; \ + if (cond) { \ + signed char Offs; \ + unsigned char OldPCH; \ + ++Cycles; \ + Offs = (signed char) MemReadByte (Regs.PC+1); \ + OldPCH = PCH; \ + Regs.PC += 2 + (int) Offs; \ + if (PCH != OldPCH) { \ + ++Cycles; \ + } \ + } else { \ + Regs.PC += 2; \ + } + +/* compares */ +#define CMP(v1, v2) \ + do { \ + unsigned Result = v1 - v2; \ + TEST_ZF (Result & 0xFF); \ + TEST_SF (Result); \ + SET_CF (Result <= 0xFF); \ + } while (0) + + +/* ROL */ +#define ROL(Val) \ + Val <<= 1; \ + if (GET_CF ()) { \ + Val |= 0x01; \ + } \ + TEST_ZF (Val); \ + TEST_SF (Val); \ + TEST_CF (Val) + +/* ROR */ +#define ROR(Val) \ + if (GET_CF ()) { \ + Val |= 0x100; \ + } \ + SET_CF (Val & 0x01); \ + Val >>= 1; \ + TEST_ZF (Val); \ + TEST_SF (Val) + +/* SBC */ +#define SBC(v) \ + do { \ + unsigned old = Regs.AC; \ + unsigned rhs = (v & 0xFF); \ + if (GET_DF ()) { \ + unsigned lo; \ + int res; \ + lo = (old & 0x0F) - (rhs & 0x0F) + GET_CF () - 1; \ + if (lo & 0x80) { \ + lo = ((lo - 0x06) & 0x0F) - 0x10; \ + } \ + Regs.AC = (old & 0xF0) - (rhs & 0xF0) + lo; \ + if (Regs.AC & 0x80) { \ + Regs.AC -= 0x60; \ + } \ + res = Regs.AC - rhs + (!GET_CF ()); \ + TEST_ZF (res); \ + TEST_SF (res); \ + SET_CF (res <= 0xFF); \ + SET_OF (((old^rhs) & (old^res) & 0x80)); \ + } else { \ + Regs.AC -= rhs - (!GET_CF ()); \ + TEST_ZF (Regs.AC); \ + TEST_SF (Regs.AC); \ + SET_CF (Regs.AC <= 0xFF); \ + SET_OF (((old^rhs) & (old^Regs.AC) & 0x80)); \ + Regs.AC &= 0xFF; \ + } \ + } while (0) + + + +/*****************************************************************************/ +/* Opcode handling functions */ +/*****************************************************************************/ + + + +static void OPC_Illegal (void) +{ + Error ("Illegal opcode $%02X at address $%04X", + MemReadByte (Regs.PC), Regs.PC); +} + + + +static void OPC_6502_00 (void) +/* Opcode $00: BRK */ +{ + Cycles = 7; + Regs.PC += 2; + SET_BF (1); + PUSH (PCH); + PUSH (PCL); + PUSH (Regs.SR); + SET_IF (1); + Regs.PC = MemReadWord (0xFFFE); +} + + + +static void OPC_6502_01 (void) +/* Opcode $01: ORA (ind,x) */ +{ + AC_OP_ZPXIND (|); +} + + + +static void OPC_6502_05 (void) +/* Opcode $05: ORA zp */ +{ + AC_OP_ZP (|); +} + + + +static void OPC_6502_06 (void) +/* Opcode $06: ASL zp */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr) << 1; + MemWriteByte (ZPAddr, (unsigned char) Val); + TEST_ZF (Val & 0xFF); + TEST_SF (Val); + SET_CF (Val & 0x100); + Regs.PC += 2; +} + + + +static void OPC_6502_08 (void) +/* Opcode $08: PHP */ +{ + Cycles = 3; + PUSH (Regs.SR & ~BF); + Regs.PC += 1; +} + + + +static void OPC_6502_09 (void) +/* Opcode $09: ORA #imm */ +{ + AC_OP_IMM (|); +} + + + +static void OPC_6502_0A (void) +/* Opcode $0A: ASL a */ +{ + Cycles = 2; + Regs.AC <<= 1; + TEST_ZF (Regs.AC & 0xFF); + TEST_SF (Regs.AC); + SET_CF (Regs.AC & 0x100); + Regs.AC &= 0xFF; + Regs.PC += 1; +} + + + +static void OPC_6502_0D (void) +/* Opcode $0D: ORA abs */ +{ + AC_OP_ABS (|); +} + + + +static void OPC_6502_0E (void) +/* Opcode $0E: ALS abs */ +{ + unsigned Addr; + unsigned Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr) << 1; + MemWriteByte (Addr, (unsigned char) Val); + TEST_ZF (Val & 0xFF); + TEST_SF (Val); + SET_CF (Val & 0x100); + Regs.PC += 3; +} + + + +static void OPC_6502_10 (void) +/* Opcode $10: BPL */ +{ + BRANCH (!GET_SF ()); +} + + + +static void OPC_6502_11 (void) +/* Opcode $11: ORA (zp),y */ +{ + AC_OP_ZPINDY (|); +} + + + +static void OPC_6502_15 (void) +/* Opcode $15: ORA zp,x */ +{ + AC_OP_ZPX (|); +} + + + +static void OPC_6502_16 (void) +/* Opcode $16: ASL zp,x */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr) << 1; + MemWriteByte (ZPAddr, (unsigned char) Val); + TEST_ZF (Val & 0xFF); + TEST_SF (Val); + SET_CF (Val & 0x100); + Regs.PC += 2; +} + + + +static void OPC_6502_18 (void) +/* Opcode $18: CLC */ +{ + Cycles = 2; + SET_CF (0); + Regs.PC += 1; +} + + + +static void OPC_6502_19 (void) +/* Opcode $19: ORA abs,y */ +{ + AC_OP_ABSY (|); +} + + + +static void OPC_6502_1D (void) +/* Opcode $1D: ORA abs,x */ +{ + AC_OP_ABSX (|); +} + + + +static void OPC_6502_1E (void) +/* Opcode $1E: ASL abs,x */ +{ + unsigned Addr; + unsigned Val; + Cycles = 7; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr) << 1; + MemWriteByte (Addr, (unsigned char) Val); + TEST_ZF (Val & 0xFF); + TEST_SF (Val); + SET_CF (Val & 0x100); + Regs.PC += 3; +} + + + +static void OPC_6502_20 (void) +/* Opcode $20: JSR */ +{ + unsigned Addr; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Regs.PC += 2; + PUSH (PCH); + PUSH (PCL); + Regs.PC = Addr; + + ParaVirtualization (&Regs); +} + + + +static void OPC_6502_21 (void) +/* Opcode $21: AND (zp,x) */ +{ + AC_OP_ZPXIND (&); +} + + + +static void OPC_6502_24 (void) +/* Opcode $24: BIT zp */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr); + SET_SF (Val & 0x80); + SET_OF (Val & 0x40); + SET_ZF ((Val & Regs.AC) == 0); + Regs.PC += 2; +} + + + +static void OPC_6502_25 (void) +/* Opcode $25: AND zp */ +{ + AC_OP_ZP (&); +} + + + +static void OPC_6502_26 (void) +/* Opcode $26: ROL zp */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr); + ROL (Val); + MemWriteByte (ZPAddr, Val); + Regs.PC += 2; +} + + + +static void OPC_6502_28 (void) +/* Opcode $28: PLP */ +{ + Cycles = 4; + Regs.SR = (POP () & ~BF); + Regs.PC += 1; +} + + + +static void OPC_6502_29 (void) +/* Opcode $29: AND #imm */ +{ + AC_OP_IMM (&); +} + + + +static void OPC_6502_2A (void) +/* Opcode $2A: ROL a */ +{ + Cycles = 2; + ROL (Regs.AC); + Regs.AC &= 0xFF; + Regs.PC += 1; +} + + + +static void OPC_6502_2C (void) +/* Opcode $2C: BIT abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 4; + Addr = MemReadByte (Regs.PC+1); + Val = MemReadByte (Addr); + SET_SF (Val & 0x80); + SET_OF (Val & 0x40); + SET_ZF ((Val & Regs.AC) == 0); + Regs.PC += 3; +} + + + +static void OPC_6502_2D (void) +/* Opcode $2D: AND abs */ +{ + AC_OP_ABS (&); +} + + + +static void OPC_6502_2E (void) +/* Opcode $2E: ROL abs */ +{ + unsigned Addr; + unsigned Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr); + ROL (Val); + MemWriteByte (Addr, Val); + Regs.PC += 3; +} + + + +static void OPC_6502_30 (void) +/* Opcode $30: BMI */ +{ + BRANCH (GET_SF ()); +} + + + +static void OPC_6502_31 (void) +/* Opcode $31: AND (zp),y */ +{ + AC_OP_ZPINDY (&); +} + + + +static void OPC_6502_35 (void) +/* Opcode $35: AND zp,x */ +{ + AC_OP_ZPX (&); +} + + + +static void OPC_6502_36 (void) +/* Opcode $36: ROL zp,x */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr); + ROL (Val); + MemWriteByte (ZPAddr, Val); + Regs.PC += 2; +} + + + +static void OPC_6502_38 (void) +/* Opcode $38: SEC */ +{ + Cycles = 2; + SET_CF (1); + Regs.PC += 1; +} + + + +static void OPC_6502_39 (void) +/* Opcode $39: AND abs,y */ +{ + AC_OP_ABSY (&); +} + + + +static void OPC_6502_3D (void) +/* Opcode $3D: AND abs,x */ +{ + AC_OP_ABSX (&); +} + + + +static void OPC_6502_3E (void) +/* Opcode $3E: ROL abs,x */ +{ + unsigned Addr; + unsigned Val; + Cycles = 7; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr); + ROL (Val); + MemWriteByte (Addr, Val); + Regs.PC += 2; +} + + + +static void OPC_6502_40 (void) +/* Opcode $40: RTI */ +{ + Cycles = 6; + Regs.SR = POP (); + Regs.PC = POP (); /* PCL */ + Regs.PC |= (POP () << 8); /* PCH */ +} + + + +static void OPC_6502_41 (void) +/* Opcode $41: EOR (zp,x) */ +{ + AC_OP_ZPXIND (^); +} + + + +static void OPC_6502_45 (void) +/* Opcode $45: EOR zp */ +{ + AC_OP_ZP (^); +} + + + +static void OPC_6502_46 (void) +/* Opcode $46: LSR zp */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr); + SET_CF (Val & 0x01); + Val >>= 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_48 (void) +/* Opcode $48: PHA */ +{ + Cycles = 3; + PUSH (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_49 (void) +/* Opcode $49: EOR #imm */ +{ + AC_OP_IMM (^); +} + + + +static void OPC_6502_4A (void) +/* Opcode $4A: LSR a */ +{ + Cycles = 2; + SET_CF (Regs.AC & 0x01); + Regs.AC >>= 1; + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_4C (void) +/* Opcode $4C: JMP abs */ +{ + Cycles = 3; + Regs.PC = MemReadWord (Regs.PC+1); + + ParaVirtualization (&Regs); +} + + + +static void OPC_6502_4D (void) +/* Opcode $4D: EOR abs */ +{ + AC_OP_ABS (^); +} + + + +static void OPC_6502_4E (void) +/* Opcode $4E: LSR abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr); + SET_CF (Val & 0x01); + Val >>= 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +static void OPC_6502_50 (void) +/* Opcode $50: BVC */ +{ + BRANCH (!GET_OF ()); +} + + + +static void OPC_6502_51 (void) +/* Opcode $51: EOR (zp),y */ +{ + AC_OP_ZPINDY (^); +} + + + +static void OPC_6502_55 (void) +/* Opcode $55: EOR zp,x */ +{ + AC_OP_ZPX (^); +} + + + +static void OPC_6502_56 (void) +/* Opcode $56: LSR zp,x */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr); + SET_CF (Val & 0x01); + Val >>= 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_58 (void) +/* Opcode $58: CLI */ +{ + Cycles = 2; + SET_IF (0); + Regs.PC += 1; +} + + + +static void OPC_6502_59 (void) +/* Opcode $59: EOR abs,y */ +{ + AC_OP_ABSY (^); +} + + + +static void OPC_6502_5D (void) +/* Opcode $5D: EOR abs,x */ +{ + AC_OP_ABSX (^); +} + + + +static void OPC_6502_5E (void) +/* Opcode $5E: LSR abs,x */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 7; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr); + SET_CF (Val & 0x01); + Val >>= 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +static void OPC_6502_60 (void) +/* Opcode $60: RTS */ +{ + Cycles = 6; + Regs.PC = POP (); /* PCL */ + Regs.PC |= (POP () << 8); /* PCH */ + Regs.PC += 1; +} + + + +static void OPC_6502_61 (void) +/* Opcode $61: ADC (zp,x) */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadZPWord (ZPAddr); + ADC (MemReadByte (Addr)); + Regs.PC += 2; +} + + + +static void OPC_6502_65 (void) +/* Opcode $65: ADC zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + ADC (MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_66 (void) +/* Opcode $66: ROR zp */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr); + ROR (Val); + MemWriteByte (ZPAddr, Val); + Regs.PC += 2; +} + + + +static void OPC_6502_68 (void) +/* Opcode $68: PLA */ +{ + Cycles = 4; + Regs.AC = POP (); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_69 (void) +/* Opcode $69: ADC #imm */ +{ + Cycles = 2; + ADC (MemReadByte (Regs.PC+1)); + Regs.PC += 2; +} + + + +static void OPC_6502_6A (void) +/* Opcode $6A: ROR a */ +{ + Cycles = 2; + ROR (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_6C (void) +/* Opcode $6C: JMP (ind) */ +{ + unsigned PC, Lo, Hi; + Cycles = 5; + PC = Regs.PC; + Lo = MemReadWord (PC+1); + + /* Emulate the 6502 bug */ + Regs.PC = MemReadByte (Lo); + Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF); + Regs.PC |= (MemReadByte (Hi) << 8); + + /* Output a warning if the bug is triggered */ + if (Hi != Lo + 1) { + Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X", + PC, Lo); + } +} + + + +static void OPC_65C02_6C (void) +/* Opcode $6C: JMP (ind) */ +{ + /* 6502 bug fixed here */ + Cycles = 5; + Regs.PC = MemReadWord (MemReadWord (Regs.PC+1)); +} + + + +static void OPC_6502_6D (void) +/* Opcode $6D: ADC abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + ADC (MemReadByte (Addr)); + Regs.PC += 3; +} + + + +static void OPC_6502_6E (void) +/* Opcode $6E: ROR abs */ +{ + unsigned Addr; + unsigned Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr); + ROR (Val); + MemWriteByte (Addr, Val); + Regs.PC += 3; +} + + + +static void OPC_6502_70 (void) +/* Opcode $70: BVS */ +{ + BRANCH (GET_OF ()); +} + + + +static void OPC_6502_71 (void) +/* Opcode $71: ADC (zp),y */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Addr = MemReadZPWord (ZPAddr); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + ADC (MemReadByte (Addr + Regs.YR)); + Regs.PC += 2; +} + + + +static void OPC_6502_75 (void) +/* Opcode $75: ADC zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + ADC (MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_76 (void) +/* Opcode $76: ROR zp,x */ +{ + unsigned char ZPAddr; + unsigned Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr); + ROR (Val); + MemWriteByte (ZPAddr, Val); + Regs.PC += 2; +} + + + +static void OPC_6502_78 (void) +/* Opcode $78: SEI */ +{ + Cycles = 2; + SET_IF (1); + Regs.PC += 1; +} + + + +static void OPC_6502_79 (void) +/* Opcode $79: ADC abs,y */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + ADC (MemReadByte (Addr + Regs.YR)); + Regs.PC += 3; +} + + + +static void OPC_6502_7D (void) +/* Opcode $7D: ADC abs,x */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.XR)) { + ++Cycles; + } + ADC (MemReadByte (Addr + Regs.XR)); + Regs.PC += 3; +} + + + +static void OPC_6502_7E (void) +/* Opcode $7E: ROR abs,x */ +{ + unsigned Addr; + unsigned Val; + Cycles = 7; + Addr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr); + ROR (Val); + MemWriteByte (Addr, Val); + Regs.PC += 3; +} + + + +static void OPC_6502_81 (void) +/* Opcode $81: STA (zp,x) */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadZPWord (ZPAddr); + MemWriteByte (Addr, Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_84 (void) +/* Opcode $84: STY zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + MemWriteByte (ZPAddr, Regs.YR); + Regs.PC += 2; +} + + + +static void OPC_6502_85 (void) +/* Opcode $85: STA zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + MemWriteByte (ZPAddr, Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_86 (void) +/* Opcode $86: STX zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + MemWriteByte (ZPAddr, Regs.XR); + Regs.PC += 2; +} + + + +static void OPC_6502_88 (void) +/* Opcode $88: DEY */ +{ + Cycles = 2; + Regs.YR = (Regs.YR - 1) & 0xFF; + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 1; +} + + + +static void OPC_6502_8A (void) +/* Opcode $8A: TXA */ +{ + Cycles = 2; + Regs.AC = Regs.XR; + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_8C (void) +/* Opcode $8C: STY abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + MemWriteByte (Addr, Regs.YR); + Regs.PC += 3; +} + + + +static void OPC_6502_8D (void) +/* Opcode $8D: STA abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + MemWriteByte (Addr, Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_8E (void) +/* Opcode $8E: STX abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + MemWriteByte (Addr, Regs.XR); + Regs.PC += 3; +} + + + +static void OPC_6502_90 (void) +/* Opcode $90: BCC */ +{ + BRANCH (!GET_CF ()); +} + + + +static void OPC_6502_91 (void) +/* Opcode $91: sta (zp),y */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1); + Addr = MemReadZPWord (ZPAddr) + Regs.YR; + MemWriteByte (Addr, Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_94 (void) +/* Opcode $94: STY zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + MemWriteByte (ZPAddr, Regs.YR); + Regs.PC += 2; +} + + + +static void OPC_6502_95 (void) +/* Opcode $95: STA zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + MemWriteByte (ZPAddr, Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_96 (void) +/* Opcode $96: stx zp,y */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; + MemWriteByte (ZPAddr, Regs.XR); + Regs.PC += 2; +} + + + +static void OPC_6502_98 (void) +/* Opcode $98: TYA */ +{ + Cycles = 2; + Regs.AC = Regs.YR; + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 1; +} + + + +static void OPC_6502_99 (void) +/* Opcode $99: STA abs,y */ +{ + unsigned Addr; + Cycles = 5; + Addr = MemReadWord (Regs.PC+1) + Regs.YR; + MemWriteByte (Addr, Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_9A (void) +/* Opcode $9A: TXS */ +{ + Cycles = 2; + Regs.SP = Regs.XR; + Regs.PC += 1; +} + + + +static void OPC_6502_9D (void) +/* Opcode $9D: STA abs,x */ +{ + unsigned Addr; + Cycles = 5; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + MemWriteByte (Addr, Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_A0 (void) +/* Opcode $A0: LDY #imm */ +{ + Cycles = 2; + Regs.YR = MemReadByte (Regs.PC+1); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 2; +} + + + +static void OPC_6502_A1 (void) +/* Opcode $A1: LDA (zp,x) */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadZPWord (ZPAddr); + Regs.AC = MemReadByte (Addr); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_A2 (void) +/* Opcode $A2: LDX #imm */ +{ + Cycles = 2; + Regs.XR = MemReadByte (Regs.PC+1); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 2; +} + + + +static void OPC_6502_A4 (void) +/* Opcode $A4: LDY zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + Regs.YR = MemReadByte (ZPAddr); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 2; +} + + + +static void OPC_6502_A5 (void) +/* Opcode $A5: LDA zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + Regs.AC = MemReadByte (ZPAddr); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_A6 (void) +/* Opcode $A6: LDX zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + Regs.XR = MemReadByte (ZPAddr); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 2; +} + + + +static void OPC_6502_A8 (void) +/* Opcode $A8: TAY */ +{ + Cycles = 2; + Regs.YR = Regs.AC; + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 1; +} + + + +static void OPC_6502_A9 (void) +/* Opcode $A9: LDA #imm */ +{ + Cycles = 2; + Regs.AC = MemReadByte (Regs.PC+1); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_AA (void) +/* Opcode $AA: TAX */ +{ + Cycles = 2; + Regs.XR = Regs.AC; + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 1; +} + + + +static void OPC_6502_AC (void) +/* Opcode $Regs.AC: LDY abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + Regs.YR = MemReadByte (Addr); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 3; +} + + + +static void OPC_6502_AD (void) +/* Opcode $AD: LDA abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + Regs.AC = MemReadByte (Addr); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_AE (void) +/* Opcode $AE: LDX abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + Regs.XR = MemReadByte (Addr); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 3; +} + + + +static void OPC_6502_B0 (void) +/* Opcode $B0: BCS */ +{ + BRANCH (GET_CF ()); +} + + + +static void OPC_6502_B1 (void) +/* Opcode $B1: LDA (zp),y */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Addr = MemReadZPWord (ZPAddr); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + Regs.AC = MemReadByte (Addr + Regs.YR); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_B4 (void) +/* Opcode $B4: LDY zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Regs.YR = MemReadByte (ZPAddr); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 2; +} + + + +static void OPC_6502_B5 (void) +/* Opcode $B5: LDA zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Regs.AC = MemReadByte (ZPAddr); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 2; +} + + + +static void OPC_6502_B6 (void) +/* Opcode $B6: LDX zp,y */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; + Regs.XR = MemReadByte (ZPAddr); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 2; +} + + + +static void OPC_6502_B8 (void) +/* Opcode $B8: CLV */ +{ + Cycles = 2; + SET_OF (0); + Regs.PC += 1; +} + + + +static void OPC_6502_B9 (void) +/* Opcode $B9: LDA abs,y */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + Regs.AC = MemReadByte (Addr + Regs.YR); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_BA (void) +/* Opcode $BA: TSX */ +{ + Cycles = 2; + Regs.XR = Regs.SP; + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 1; +} + + + +static void OPC_6502_BC (void) +/* Opcode $BC: LDY abs,x */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.XR)) { + ++Cycles; + } + Regs.YR = MemReadByte (Addr + Regs.XR); + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 3; +} + + + +static void OPC_6502_BD (void) +/* Opcode $BD: LDA abs,x */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.XR)) { + ++Cycles; + } + Regs.AC = MemReadByte (Addr + Regs.XR); + TEST_ZF (Regs.AC); + TEST_SF (Regs.AC); + Regs.PC += 3; +} + + + +static void OPC_6502_BE (void) +/* Opcode $BE: LDX abs,y */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + Regs.XR = MemReadByte (Addr + Regs.YR); + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 3; +} + + + +static void OPC_6502_C0 (void) +/* Opcode $C0: CPY #imm */ +{ + Cycles = 2; + CMP (Regs.YR, MemReadByte (Regs.PC+1)); + Regs.PC += 2; +} + + + +static void OPC_6502_C1 (void) +/* Opcode $C1: CMP (zp,x) */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadZPWord (ZPAddr); + CMP (Regs.AC, MemReadByte (Addr)); + Regs.PC += 2; +} + + + +static void OPC_6502_C4 (void) +/* Opcode $C4: CPY zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + CMP (Regs.YR, MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_C5 (void) +/* Opcode $C5: CMP zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + CMP (Regs.AC, MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_C6 (void) +/* Opcode $C6: DEC zp */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr) - 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_C8 (void) +/* Opcode $C8: INY */ +{ + Cycles = 2; + Regs.YR = (Regs.YR + 1) & 0xFF; + TEST_ZF (Regs.YR); + TEST_SF (Regs.YR); + Regs.PC += 1; +} + + + +static void OPC_6502_C9 (void) +/* Opcode $C9: CMP #imm */ +{ + Cycles = 2; + CMP (Regs.AC, MemReadByte (Regs.PC+1)); + Regs.PC += 2; +} + + + +static void OPC_6502_CA (void) +/* Opcode $CA: DEX */ +{ + Cycles = 2; + Regs.XR = (Regs.XR - 1) & 0xFF; + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 1; +} + + + +static void OPC_6502_CC (void) +/* Opcode $CC: CPY abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + CMP (Regs.YR, MemReadByte (Addr)); + Regs.PC += 3; +} + + + +static void OPC_6502_CD (void) +/* Opcode $CD: CMP abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + CMP (Regs.AC, MemReadByte (Addr)); + Regs.PC += 3; +} + + + +static void OPC_6502_CE (void) +/* Opcode $CE: DEC abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr) - 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +static void OPC_6502_D0 (void) +/* Opcode $D0: BNE */ +{ + BRANCH (!GET_ZF ()); +} + + + +static void OPC_6502_D1 (void) +/* Opcode $D1: CMP (zp),y */ +{ + unsigned ZPAddr; + unsigned Addr; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Addr = MemReadWord (ZPAddr); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + CMP (Regs.AC, MemReadByte (Addr + Regs.YR)); + Regs.PC += 2; +} + + + +static void OPC_6502_D5 (void) +/* Opcode $D5: CMP zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + CMP (Regs.AC, MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_D6 (void) +/* Opcode $D6: DEC zp,x */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr) - 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_D8 (void) +/* Opcode $D8: CLD */ +{ + Cycles = 2; + SET_DF (0); + Regs.PC += 1; +} + + + +static void OPC_6502_D9 (void) +/* Opcode $D9: CMP abs,y */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + CMP (Regs.AC, MemReadByte (Addr + Regs.YR)); + Regs.PC += 3; +} + + + +static void OPC_6502_DD (void) +/* Opcode $DD: CMP abs,x */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.XR)) { + ++Cycles; + } + CMP (Regs.AC, MemReadByte (Addr + Regs.XR)); + Regs.PC += 3; +} + + + +static void OPC_6502_DE (void) +/* Opcode $DE: DEC abs,x */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 7; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr) - 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +static void OPC_6502_E0 (void) +/* Opcode $E0: CPX #imm */ +{ + Cycles = 2; + CMP (Regs.XR, MemReadByte (Regs.PC+1)); + Regs.PC += 2; +} + + + +static void OPC_6502_E1 (void) +/* Opcode $E1: SBC (zp,x) */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Addr = MemReadZPWord (ZPAddr); + SBC (MemReadByte (Addr)); + Regs.PC += 2; +} + + + +static void OPC_6502_E4 (void) +/* Opcode $E4: CPX zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + CMP (Regs.XR, MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_E5 (void) +/* Opcode $E5: SBC zp */ +{ + unsigned char ZPAddr; + Cycles = 3; + ZPAddr = MemReadByte (Regs.PC+1); + SBC (MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_E6 (void) +/* Opcode $E6: INC zp */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Val = MemReadByte (ZPAddr) + 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_E8 (void) +/* Opcode $E8: INX */ +{ + Cycles = 2; + Regs.XR = (Regs.XR + 1) & 0xFF; + TEST_ZF (Regs.XR); + TEST_SF (Regs.XR); + Regs.PC += 1; +} + + + +static void OPC_6502_E9 (void) +/* Opcode $E9: SBC #imm */ +{ + Cycles = 2; + SBC (MemReadByte (Regs.PC+1)); + Regs.PC += 2; +} + + + +static void OPC_6502_EA (void) +/* Opcode $EA: NOP */ +{ + /* This one is easy... */ + Cycles = 2; + Regs.PC += 1; +} + + + +static void OPC_6502_EC (void) +/* Opcode $EC: CPX abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + CMP (Regs.XR, MemReadByte (Addr)); + Regs.PC += 3; +} + + + +static void OPC_6502_ED (void) +/* Opcode $ED: SBC abs */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + SBC (MemReadByte (Addr)); + Regs.PC += 3; +} + + + +static void OPC_6502_EE (void) +/* Opcode $EE: INC abs */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 6; + Addr = MemReadWord (Regs.PC+1); + Val = MemReadByte (Addr) + 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +static void OPC_6502_F0 (void) +/* Opcode $F0: BEQ */ +{ + BRANCH (GET_ZF ()); +} + + + +static void OPC_6502_F1 (void) +/* Opcode $F1: SBC (zp),y */ +{ + unsigned char ZPAddr; + unsigned Addr; + Cycles = 5; + ZPAddr = MemReadByte (Regs.PC+1); + Addr = MemReadZPWord (ZPAddr); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + SBC (MemReadByte (Addr + Regs.YR)); + Regs.PC += 2; +} + + + +static void OPC_6502_F5 (void) +/* Opcode $F5: SBC zp,x */ +{ + unsigned char ZPAddr; + Cycles = 4; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + SBC (MemReadByte (ZPAddr)); + Regs.PC += 2; +} + + + +static void OPC_6502_F6 (void) +/* Opcode $F6: INC zp,x */ +{ + unsigned char ZPAddr; + unsigned char Val; + Cycles = 6; + ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; + Val = MemReadByte (ZPAddr) + 1; + MemWriteByte (ZPAddr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 2; +} + + + +static void OPC_6502_F8 (void) +/* Opcode $F8: SED */ +{ + SET_DF (1); +} + + + +static void OPC_6502_F9 (void) +/* Opcode $F9: SBC abs,y */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.YR)) { + ++Cycles; + } + SBC (MemReadByte (Addr + Regs.YR)); + Regs.PC += 3; +} + + + +static void OPC_6502_FD (void) +/* Opcode $FD: SBC abs,x */ +{ + unsigned Addr; + Cycles = 4; + Addr = MemReadWord (Regs.PC+1); + if (PAGE_CROSS (Addr, Regs.XR)) { + ++Cycles; + } + SBC (MemReadByte (Addr + Regs.XR)); + Regs.PC += 3; +} + + + +static void OPC_6502_FE (void) +/* Opcode $FE: INC abs,x */ +{ + unsigned Addr; + unsigned char Val; + Cycles = 7; + Addr = MemReadWord (Regs.PC+1) + Regs.XR; + Val = MemReadByte (Addr) + 1; + MemWriteByte (Addr, Val); + TEST_ZF (Val); + TEST_SF (Val); + Regs.PC += 3; +} + + + +/*****************************************************************************/ +/* Opcode handler tables */ +/*****************************************************************************/ + + + +/* Opcode handler table for the 6502 */ +static const OPFunc OP6502Table[256] = { + OPC_6502_00, + OPC_6502_01, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_05, + OPC_6502_06, + OPC_Illegal, + OPC_6502_08, + OPC_6502_09, + OPC_6502_0A, + OPC_Illegal, + OPC_Illegal, + OPC_6502_0D, + OPC_6502_0E, + OPC_Illegal, + OPC_6502_10, + OPC_6502_11, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_15, + OPC_6502_16, + OPC_Illegal, + OPC_6502_18, + OPC_6502_19, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_1D, + OPC_6502_1E, + OPC_Illegal, + OPC_6502_20, + OPC_6502_21, + OPC_Illegal, + OPC_Illegal, + OPC_6502_24, + OPC_6502_25, + OPC_6502_26, + OPC_Illegal, + OPC_6502_28, + OPC_6502_29, + OPC_6502_2A, + OPC_Illegal, + OPC_6502_2C, + OPC_6502_2D, + OPC_6502_2E, + OPC_Illegal, + OPC_6502_30, + OPC_6502_31, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_35, + OPC_6502_36, + OPC_Illegal, + OPC_6502_38, + OPC_6502_39, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_3D, + OPC_6502_3E, + OPC_Illegal, + OPC_6502_40, + OPC_6502_41, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_45, + OPC_6502_46, + OPC_Illegal, + OPC_6502_48, + OPC_6502_49, + OPC_6502_4A, + OPC_Illegal, + OPC_6502_4C, + OPC_6502_4D, + OPC_6502_4E, + OPC_Illegal, + OPC_6502_50, + OPC_6502_51, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_55, + OPC_6502_56, + OPC_Illegal, + OPC_6502_58, + OPC_6502_59, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_5D, + OPC_6502_5E, + OPC_Illegal, + OPC_6502_60, + OPC_6502_61, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_65, + OPC_6502_66, + OPC_Illegal, + OPC_6502_68, + OPC_6502_69, + OPC_6502_6A, + OPC_Illegal, + OPC_6502_6C, + OPC_6502_6D, + OPC_6502_6E, + OPC_Illegal, + OPC_6502_70, + OPC_6502_71, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_75, + OPC_6502_76, + OPC_Illegal, + OPC_6502_78, + OPC_6502_79, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_7D, + OPC_6502_7E, + OPC_Illegal, + OPC_Illegal, + OPC_6502_81, + OPC_Illegal, + OPC_Illegal, + OPC_6502_84, + OPC_6502_85, + OPC_6502_86, + OPC_Illegal, + OPC_6502_88, + OPC_Illegal, + OPC_6502_8A, + OPC_Illegal, + OPC_6502_8C, + OPC_6502_8D, + OPC_6502_8E, + OPC_Illegal, + OPC_6502_90, + OPC_6502_91, + OPC_Illegal, + OPC_Illegal, + OPC_6502_94, + OPC_6502_95, + OPC_6502_96, + OPC_Illegal, + OPC_6502_98, + OPC_6502_99, + OPC_6502_9A, + OPC_Illegal, + OPC_Illegal, + OPC_6502_9D, + OPC_Illegal, + OPC_Illegal, + OPC_6502_A0, + OPC_6502_A1, + OPC_6502_A2, + OPC_Illegal, + OPC_6502_A4, + OPC_6502_A5, + OPC_6502_A6, + OPC_Illegal, + OPC_6502_A8, + OPC_6502_A9, + OPC_6502_AA, + OPC_Illegal, + OPC_6502_AC, + OPC_6502_AD, + OPC_6502_AE, + OPC_Illegal, + OPC_6502_B0, + OPC_6502_B1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_B4, + OPC_6502_B5, + OPC_6502_B6, + OPC_Illegal, + OPC_6502_B8, + OPC_6502_B9, + OPC_6502_BA, + OPC_Illegal, + OPC_6502_BC, + OPC_6502_BD, + OPC_6502_BE, + OPC_Illegal, + OPC_6502_C0, + OPC_6502_C1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_C4, + OPC_6502_C5, + OPC_6502_C6, + OPC_Illegal, + OPC_6502_C8, + OPC_6502_C9, + OPC_6502_CA, + OPC_Illegal, + OPC_6502_CC, + OPC_6502_CD, + OPC_6502_CE, + OPC_Illegal, + OPC_6502_D0, + OPC_6502_D1, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_D5, + OPC_6502_D6, + OPC_Illegal, + OPC_6502_D8, + OPC_6502_D9, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_DD, + OPC_6502_DE, + OPC_Illegal, + OPC_6502_E0, + OPC_6502_E1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_E4, + OPC_6502_E5, + OPC_6502_E6, + OPC_Illegal, + OPC_6502_E8, + OPC_6502_E9, + OPC_6502_EA, + OPC_Illegal, + OPC_6502_EC, + OPC_6502_ED, + OPC_6502_EE, + OPC_Illegal, + OPC_6502_F0, + OPC_6502_F1, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_F5, + OPC_6502_F6, + OPC_Illegal, + OPC_6502_F8, + OPC_6502_F9, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_FD, + OPC_6502_FE, + OPC_Illegal, +}; + + + +/* Opcode handler table for the 65C02 */ +static const OPFunc OP65C02Table[256] = { + OPC_6502_00, + OPC_6502_01, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_05, + OPC_6502_06, + OPC_Illegal, + OPC_6502_08, + OPC_6502_09, + OPC_6502_0A, + OPC_Illegal, + OPC_Illegal, + OPC_6502_0D, + OPC_6502_0E, + OPC_Illegal, + OPC_6502_10, + OPC_6502_11, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_15, + OPC_6502_16, + OPC_Illegal, + OPC_6502_18, + OPC_6502_19, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_1D, + OPC_6502_1E, + OPC_Illegal, + OPC_6502_20, + OPC_6502_21, + OPC_Illegal, + OPC_Illegal, + OPC_6502_24, + OPC_6502_25, + OPC_6502_26, + OPC_Illegal, + OPC_6502_28, + OPC_6502_29, + OPC_6502_2A, + OPC_Illegal, + OPC_6502_2C, + OPC_6502_2D, + OPC_6502_2E, + OPC_Illegal, + OPC_6502_30, + OPC_6502_31, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_35, + OPC_6502_36, + OPC_Illegal, + OPC_6502_38, + OPC_6502_39, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_3D, + OPC_6502_3E, + OPC_Illegal, + OPC_6502_40, + OPC_6502_41, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_45, + OPC_6502_46, + OPC_Illegal, + OPC_6502_48, + OPC_6502_49, + OPC_6502_4A, + OPC_Illegal, + OPC_6502_4C, + OPC_6502_4D, + OPC_6502_4E, + OPC_Illegal, + OPC_6502_50, + OPC_6502_51, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_55, + OPC_6502_56, + OPC_Illegal, + OPC_6502_58, + OPC_6502_59, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_5D, + OPC_6502_5E, + OPC_Illegal, + OPC_6502_60, + OPC_6502_61, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_65, + OPC_6502_66, + OPC_Illegal, + OPC_6502_68, + OPC_6502_69, + OPC_6502_6A, + OPC_Illegal, + OPC_65C02_6C, + OPC_6502_6D, + OPC_6502_6E, + OPC_Illegal, + OPC_6502_70, + OPC_6502_71, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_75, + OPC_6502_76, + OPC_Illegal, + OPC_6502_78, + OPC_6502_79, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_7D, + OPC_6502_7E, + OPC_Illegal, + OPC_Illegal, + OPC_6502_81, + OPC_Illegal, + OPC_Illegal, + OPC_6502_84, + OPC_6502_85, + OPC_6502_86, + OPC_Illegal, + OPC_6502_88, + OPC_Illegal, + OPC_6502_8A, + OPC_Illegal, + OPC_6502_8C, + OPC_6502_8D, + OPC_6502_8E, + OPC_Illegal, + OPC_6502_90, + OPC_6502_91, + OPC_Illegal, + OPC_Illegal, + OPC_6502_94, + OPC_6502_95, + OPC_6502_96, + OPC_Illegal, + OPC_6502_98, + OPC_6502_99, + OPC_6502_9A, + OPC_Illegal, + OPC_Illegal, + OPC_6502_9D, + OPC_Illegal, + OPC_Illegal, + OPC_6502_A0, + OPC_6502_A1, + OPC_6502_A2, + OPC_Illegal, + OPC_6502_A4, + OPC_6502_A5, + OPC_6502_A6, + OPC_Illegal, + OPC_6502_A8, + OPC_6502_A9, + OPC_6502_AA, + OPC_Illegal, + OPC_6502_AC, + OPC_6502_AD, + OPC_6502_AE, + OPC_Illegal, + OPC_6502_B0, + OPC_6502_B1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_B4, + OPC_6502_B5, + OPC_6502_B6, + OPC_Illegal, + OPC_6502_B8, + OPC_6502_B9, + OPC_6502_BA, + OPC_Illegal, + OPC_6502_BC, + OPC_6502_BD, + OPC_6502_BE, + OPC_Illegal, + OPC_6502_C0, + OPC_6502_C1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_C4, + OPC_6502_C5, + OPC_6502_C6, + OPC_Illegal, + OPC_6502_C8, + OPC_6502_C9, + OPC_6502_CA, + OPC_Illegal, + OPC_6502_CC, + OPC_6502_CD, + OPC_6502_CE, + OPC_Illegal, + OPC_6502_D0, + OPC_6502_D1, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_D5, + OPC_6502_D6, + OPC_Illegal, + OPC_6502_D8, + OPC_6502_D9, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_DD, + OPC_6502_DE, + OPC_Illegal, + OPC_6502_E0, + OPC_6502_E1, + OPC_Illegal, + OPC_Illegal, + OPC_6502_E4, + OPC_6502_E5, + OPC_6502_E6, + OPC_Illegal, + OPC_6502_E8, + OPC_6502_E9, + OPC_6502_EA, + OPC_Illegal, + OPC_6502_EC, + OPC_6502_ED, + OPC_6502_EE, + OPC_Illegal, + OPC_6502_F0, + OPC_6502_F1, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_F5, + OPC_6502_F6, + OPC_Illegal, + OPC_6502_F8, + OPC_6502_F9, + OPC_Illegal, + OPC_Illegal, + OPC_Illegal, + OPC_6502_FD, + OPC_6502_FE, + OPC_Illegal, +}; + + + +/* Tables with opcode handlers */ +static const OPFunc* Handlers[2] = {OP6502Table, OP65C02Table}; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void IRQRequest (void) +/* Generate an IRQ */ +{ + /* Remember the request */ + HaveIRQRequest = 1; +} + + + +void NMIRequest (void) +/* Generate an NMI */ +{ + /* Remember the request */ + HaveNMIRequest = 1; +} + + + +void Reset (void) +/* Generate a CPU RESET */ +{ + /* Reset the CPU */ + HaveIRQRequest = 0; + HaveNMIRequest = 0; + Regs.SR = 0; + Regs.PC = MemReadWord (0xFFFC); +} + + + +unsigned ExecuteInsn (void) +/* Execute one CPU instruction */ +{ + /* If we have an NMI request, handle it */ + if (HaveNMIRequest) { + + HaveNMIRequest = 0; + PUSH (PCH); + PUSH (PCL); + PUSH (Regs.SR); + SET_IF (1); + Regs.PC = MemReadWord (0xFFFA); + Cycles = 7; + + } else if (HaveIRQRequest && GET_IF () == 0) { + + HaveIRQRequest = 0; + PUSH (PCH); + PUSH (PCL); + PUSH (Regs.SR); + SET_IF (1); + Regs.PC = MemReadWord (0xFFFE); + Cycles = 7; + + } else { + + /* Normal instruction - read the next opcode */ + unsigned char OPC = MemReadByte (Regs.PC); + + /* Execute it */ + Handlers[CPU][OPC] (); + } + + /* Count cycles */ + TotalCycles += Cycles; + + /* Return the number of clock cycles needed by this insn */ + return Cycles; +} + + + +unsigned long GetCycles (void) +/* Return the total number of cycles executed */ +{ + /* Return the total number of cycles */ + return TotalCycles; +} diff --git a/src/sim65/addrspace.h b/src/sim65/6502.h similarity index 66% rename from src/sim65/addrspace.h rename to src/sim65/6502.h index ae8228fdf..6a640fae1 100644 --- a/src/sim65/addrspace.h +++ b/src/sim65/6502.h @@ -1,8 +1,8 @@ /*****************************************************************************/ /* */ -/* addrspace.h */ +/* 6502.h */ /* */ -/* CPU address space for the 6502 simulator */ +/* CPU core for the 6502 */ /* */ /* */ /* */ @@ -33,8 +33,8 @@ -#ifndef ADDRSPACE_H -#define ADDRSPACE_H +#ifndef _6502_H +#define _6502_H @@ -44,20 +44,36 @@ -/* Forwards */ -struct CPUData; -struct ChipInstance; +/* Supported CPUs */ +typedef enum CPUType { + CPU_6502, + CPU_65C02 +} CPUType; -/* Forwards */ -typedef struct AddressSpace AddressSpace; -struct AddressSpace { - - struct CPU* CPU; /* Backpointer to CPU */ - unsigned Size; /* Address space size */ - struct ChipInstance* Data[1]; /* Pointer to chips, dynamically! */ +/* Current CPU */ +extern CPUType CPU; +/* 6502 CPU registers */ +typedef struct CPURegs CPURegs; +struct CPURegs { + unsigned AC; /* Accumulator */ + unsigned XR; /* X register */ + unsigned YR; /* Y register */ + unsigned ZR; /* Z register */ + unsigned SR; /* Status register */ + unsigned SP; /* Stackpointer */ + unsigned PC; /* Program counter */ }; +/* Status register bits */ +#define CF 0x01 /* Carry flag */ +#define ZF 0x02 /* Zero flag */ +#define IF 0x04 /* Interrupt flag */ +#define DF 0x08 /* Decimal flag */ +#define BF 0x10 /* Break flag */ +#define OF 0x40 /* Overflow flag */ +#define SF 0x80 /* Sign flag */ + /*****************************************************************************/ @@ -66,34 +82,25 @@ struct AddressSpace { -AddressSpace* NewAddressSpace (unsigned Size); -/* Allocate a new address space and return it */ - -void ASWrite (AddressSpace* AS, unsigned Addr, unsigned char Val); -/* Write a byte to a given location */ - -unsigned char ASRead (AddressSpace* AS, unsigned Addr); -/* Read a byte from a location */ +void Reset (void); +/* Generate a CPU RESET */ -void ASWriteCtrl (AddressSpace* AS, unsigned Addr, unsigned char Val); -/* Write a byte to a given location */ +void IRQRequest (void); +/* Generate an IRQ */ -unsigned char ASReadCtrl (AddressSpace* AS, unsigned Addr); -/* Read a byte from a location */ +void NMIRequest (void); +/* Generate an NMI */ -void ASAssignChip (AddressSpace* AS, struct ChipInstance* CI, - unsigned Addr, unsigned Range); -/* Assign a chip instance to memory locations */ +unsigned ExecuteInsn (void); +/* Execute one CPU instruction. Return the number of clock cycles for the + * executed instruction. + */ -struct ChipInstance* ASGetChip (const AddressSpace* AS, unsigned Addr); -/* Get the chip that is located at the given address (may return NULL). */ +unsigned long GetCycles (void); +/* Return the total number of clock cycles executed */ -/* End of addrspace.h */ +/* End of 6502.h */ #endif - - - - diff --git a/src/sim65/addrspace.c b/src/sim65/addrspace.c deleted file mode 100644 index 8cb663e50..000000000 --- a/src/sim65/addrspace.c +++ /dev/null @@ -1,190 +0,0 @@ -/*****************************************************************************/ -/* */ -/* addrspace.c */ -/* */ -/* CPU address space for the 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -/* common */ -#include "check.h" -#include "xmalloc.h" - -/* sim65 */ -#include "chip.h" -#include "cpucore.h" -#include "error.h" -#include "addrspace.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -AddressSpace* NewAddressSpace (unsigned Size) -/* Allocate a new address space and return it */ -{ - unsigned I; - - /* Allocate memory */ - AddressSpace* AS = xmalloc (sizeof (AddressSpace) + - (Size - 1) * sizeof (ChipInstance*)); - - /* Initialize the struct */ - AS->CPU = 0; - AS->Size = Size; - for (I = 0; I < Size; ++I) { - AS->Data[I] = 0; - } - - /* Return the new struct */ - return AS; -} - - - -void ASWrite (AddressSpace* AS, unsigned Addr, unsigned char Val) -/* Write a byte to a given location */ -{ - const ChipInstance* CI; - - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr < AS->Size); - - /* Get the instance of the chip at this address */ - CI = AS->Data[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Break ("Writing to unassigned memory at $%06X", Addr); - } else { - CI->C->Data->Write (CI->Data, Addr - CI->Addr, Val); - } -} - - - -unsigned char ASRead (AddressSpace* AS, unsigned Addr) -/* Read a byte from a location */ -{ - const ChipInstance* CI; - - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr < AS->Size); - - /* Get the instance of the chip at this address */ - CI = AS->Data[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Break ("Reading from unassigned memory at $%06X", Addr); - return 0xFF; - } else { - return CI->C->Data->Read (CI->Data, Addr - CI->Addr); - } -} - - - -void ASWriteCtrl (AddressSpace* AS, unsigned Addr, unsigned char Val) -/* Write a byte to a given location */ -{ - const ChipInstance* CI; - - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr < AS->Size); - - /* Get the instance of the chip at this address */ - CI = AS->Data[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Break ("Writing to unassigned memory at $%06X", Addr); - } else { - CI->C->Data->WriteCtrl (CI->Data, Addr - CI->Addr, Val); - } -} - - - -unsigned char ASReadCtrl (AddressSpace* AS, unsigned Addr) -/* Read a byte from a location */ -{ - const ChipInstance* CI; - - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr < AS->Size); - - /* Get the instance of the chip at this address */ - CI = AS->Data[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Break ("Reading from unassigned memory at $%06X", Addr); - return 0xFF; - } else { - return CI->C->Data->ReadCtrl (CI->Data, Addr - CI->Addr); - } -} - - -void ASAssignChip (AddressSpace* AS, ChipInstance* CI, - unsigned Addr, unsigned Range) -/* Assign a chip instance to memory locations */ -{ - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr + Range <= AS->Size); - - /* Assign the chip instance */ - while (Range--) { - CHECK (AS->Data[Addr] == 0); - AS->Data[Addr++] = CI; - } - - /* Set the backpointer to us */ - CI->AS = AS; -} - - -ChipInstance* ASGetChip (const AddressSpace* AS, unsigned Addr) -/* Get the chip that is located at the given address (may return NULL). */ -{ - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr < AS->Size); - - /* Return the chip instance */ - return AS->Data[Addr]; -} - - - diff --git a/src/sim65/callback.c b/src/sim65/callback.c deleted file mode 100644 index 8dea9ade7..000000000 --- a/src/sim65/callback.c +++ /dev/null @@ -1,191 +0,0 @@ -/*****************************************************************************/ -/* */ -/* callback.c */ -/* */ -/* Chip callbacks */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -/* common */ -#include "xmalloc.h" - -/* sim65 */ -#include "error.h" -#include "callback.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -struct Callback { - Callback* Next; /* Next entry in list */ - unsigned Ticks; /* Remaining ticks */ - CallbackFunc UserFunc; /* User function */ - void* UserData; /* User data */ -}; - -/* Delta list that keeps existing callbacks */ -static Callback* List = 0; - - - -/*****************************************************************************/ -/* Routines that handle the delta list */ -/*****************************************************************************/ - - - -static void InsertCallback (Callback* C, unsigned Ticks) -/* Insert the callback C into the delta list */ -{ - /* Search for the insertion point */ - Callback* N; - Callback** L = &List; - while ((N = *L) != 0) { - /* Check if the next callback in the list has a higher wait time */ - if (N->Ticks > Ticks) { - /* Insert before this callback */ - N->Ticks -= Ticks; - break; - } else { - /* Insert behind this callback */ - Ticks -= N->Ticks; - L = &N->Next; - } - } - - /* Insert the new task */ - C->Ticks = Ticks; - C->Next = N; - *L = C; -} - - - -static void RemoveCallback (Callback* C) -/* Remove a callback from the list. If the callback is not in the list, this - * is a fatal error. - */ -{ - Callback* N; - Callback** L = &List; - while ((N = *L) != 0) { - if (N == C) { - /* Found, remove it */ - if (C->Next) { - /* Adjust the counter of the following callback */ - C->Next->Ticks += C->Ticks; - } - *L = C->Next; - return; - } else { - L = &N->Next; - } - } - - /* Callback was not found */ - Internal ("RemoveCallback: Callback not found in list!"); -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -Callback* NewCallback (unsigned Ticks, CallbackFunc Func, void* Data) -/* Create a callback for function F to be called in Ticks ticks. */ -{ - /* Allocate memory */ - Callback* C = xmalloc (sizeof (Callback)); - - /* Initialize the fields */ - C->UserFunc = Func; - C->UserData = Data; - - /* Insert the callback into the delta list */ - InsertCallback (C, Ticks); - - /* Return the new callback */ - return C; -} - - - -void FreeCallback (Callback* C) -/* Delete a callback (remove from the queue) */ -{ - /* Remove the callback from the list */ - RemoveCallback (C); - - /* Delete it */ - xfree (C); -} - - - -void HandleCallbacks (unsigned TicksSinceLastCall) -/* Handle the callback queue */ -{ - while (List) { - - /* Check if this one is due */ - if (List->Ticks <= TicksSinceLastCall) { - - /* Calclulate the tick offset */ - int TickOffs = ((int) List->Ticks) - ((int) TicksSinceLastCall); - - /* Retrieve the first callback from the list */ - Callback* C = List; - List = C->Next; - - /* Call the user function */ - C->UserFunc (TickOffs, C->UserData); - - /* Delete the callback */ - xfree (C); - - } else { - - List->Ticks -= TicksSinceLastCall; - break; - - } - } -} - - - diff --git a/src/sim65/callback.h b/src/sim65/callback.h deleted file mode 100644 index 0797a9604..000000000 --- a/src/sim65/callback.h +++ /dev/null @@ -1,77 +0,0 @@ -/*****************************************************************************/ -/* */ -/* callback.h */ -/* */ -/* Chip callbacks */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CALLBACK_H -#define CALLBACK_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Type of a callback function */ -typedef void (*CallbackFunc) (int TickOffs, void* UserData); - -/* Forward */ -typedef struct Callback Callback; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -Callback* NewCallback (unsigned Ticks, CallbackFunc Func, void* Data); -/* Create a callback for function F to be called in Ticks ticks. */ - -void FreeCallback (Callback* C); -/* Delete a callback (remove from the queue) */ - -void HandleCallbacks (unsigned TicksSinceLastCall); -/* Handle the callback queue */ - - - -/* End of callback.h */ - -#endif - - - diff --git a/src/sim65/cfgdata.c b/src/sim65/cfgdata.c deleted file mode 100644 index 00a9ef744..000000000 --- a/src/sim65/cfgdata.c +++ /dev/null @@ -1,234 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cfgdata.c */ -/* */ -/* Config data structure */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include - -/* common */ -#include "strutil.h" -#include "xmalloc.h" - -/* sim65 */ -#include "error.h" -#include "scanner.h" -#include "cfgdata.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -CfgData* NewCfgData (void) -/* Create and intialize a new CfgData struct, then return it. The function - * uses the current output of the config scanner. - */ -{ - /* Allocate memory */ - CfgData* D = xmalloc (sizeof (CfgData) + SB_GetLen (&CfgSVal)); - - /* Initialize the fields */ - D->Type = CfgDataInvalid; - D->Line = CfgErrorLine; - D->Col = CfgErrorCol; - memcpy (D->Attr, SB_GetConstBuf (&CfgSVal), SB_GetLen (&CfgSVal) + 1); - - /* Return the new struct */ - return D; -} - - - -void FreeCfgData (CfgData* D) -/* Free a config data structure */ -{ - if (D->Type == CfgDataId || D->Type == CfgDataString) { - /* Free the string value */ - xfree (D->V.SVal); - } - /* Free the structure */ - xfree (D); -} - - - -void CfgDataCheckType (const CfgData* D, unsigned Type) -/* Check the config data type and print an error message if it has the wrong - * type. - */ -{ - if (D->Type != Type) { - Error ("%s(%u): Attribute `%s' has invalid type", - CfgGetName (), D->Line, D->Attr); - } -} - - - -int CfgDataFind (const Collection* Attributes, const char* AttrName) -/* Find the attribute with the given name and return its index. Return -1 if - * the attribute was not found. - */ -{ - unsigned I; - - /* Walk through the attributes checking for a "mirror" attribute */ - for (I = 0; I < CollCount (Attributes); ++I) { - - /* Get the next attribute */ - const CfgData* D = CollConstAt (Attributes, I); - - /* Compare the name */ - if (StrCaseCmp (D->Attr, AttrName) == 0) { - /* Found */ - return I; - } - } - - /* Not found */ - return -1; -} - - - -CfgData* CfgDataGetTyped (Collection* Attributes, const char* Name, unsigned Type) -/* Find the attribute with the given name and type. If found, remove it from - * Attributes and return it. If not found or wrong type, return NULL. - */ -{ - CfgData* D; - - /* Search for the attribute */ - int I = CfgDataFind (Attributes, Name); - if (I < 0) { - /* Not found */ - return 0; - } - - /* Get the attribute */ - D = CollAtUnchecked (Attributes, I); - - /* Check the type */ - if (D->Type != Type) { - /* Wrong type. ### Warn here? */ - return 0; - } - - /* Remove the attribute and return it */ - CollDelete (Attributes, I); - return D; -} - - - -int CfgDataGetId (Collection* Attributes, const char* Name, char** Id) -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, copy it into Buf and return - * true. If not found, return false. - */ -{ - CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataId); - if (D == 0) { - /* Not found or wrong type */ - return 0; - } - - /* Use the string value and invalidate the type, so FreeCfgData won't - * delete the string. - */ - *Id = D->V.SVal; - D->Type = CfgDataInvalid; - - /* Delete the config data struct */ - FreeCfgData (D); - - /* Success */ - return 1; -} - - - -int CfgDataGetStr (Collection* Attributes, const char* Name, char** S) -/* Search CfgInfo for an attribute with the given name and type "string". - * If found, remove it from the configuration, copy it into Buf and return - * true. If not found, return false. - */ -{ - CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataString); - if (D == 0) { - /* Not found or wrong type */ - return 0; - } - - /* Use the string value and invalidate the type, so FreeCfgData won't - * delete the string. - */ - *S = D->V.SVal; - D->Type = CfgDataInvalid; - - /* Delete the config data struct */ - FreeCfgData (D); - - /* Success */ - return 1; -} - - - -int CfgDataGetNum (Collection* Attributes, const char* Name, long* Val) -/* Search CfgInfo for an attribute with the given name and type "number". - * If found, remove it from the configuration, copy it into Val and return - * true. If not found, return false. - */ -{ - CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataNumber); - if (D == 0) { - /* Not found or wrong type */ - return 0; - } - - /* Return the value to the caller */ - *Val = D->V.IVal; - - /* Delete the config data struct */ - FreeCfgData (D); - - /* Success */ - return 1; -} - - - diff --git a/src/sim65/cfgdata.h b/src/sim65/cfgdata.h deleted file mode 100644 index 1d43d4789..000000000 --- a/src/sim65/cfgdata.h +++ /dev/null @@ -1,120 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cfgdata.h */ -/* */ -/* Config data structure */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CFGDATA_H -#define CFGDATA_H - - - -/* common */ -#include "coll.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -typedef struct CfgData CfgData; -struct CfgData { - enum { - CfgDataInvalid, - CfgDataId, - CfgDataNumber, - CfgDataString - } Type; /* Type of the value */ - union { - char* SVal; /* String or id value */ - long IVal; /* Integer value */ - } V; - unsigned Line; /* Line where the attribute was defined */ - unsigned Col; /* Column of attribute definition */ - char Attr[1]; /* The attribute name */ -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -CfgData* NewCfgData (void); -/* Create and intialize a new CfgData struct, then return it. The function - * uses the current output of the config scanner. - */ - -void FreeCfgData (CfgData* D); -/* Free a config data structure */ - -void CfgDataCheckType (const CfgData* D, unsigned Type); -/* Check the config data type and print an error message if it has the wrong - * type. - */ - -int CfgDataFind (const Collection* Attributes, const char* AttrName); -/* Find the attribute with the given name and return its index. Return -1 if - * the attribute was not found. - */ - -int CfgDataGetId (Collection* Attributes, const char* Name, char** Id); -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, copy it into Buf and return - * true. If not found, return false. - */ - -int CfgDataGetStr (Collection* Attributes, const char* Name, char** S); -/* Search CfgInfo for an attribute with the given name and type "string". - * If found, remove it from the configuration, copy it into Buf and return - * true. If not found, return false. - */ - -int CfgDataGetNum (Collection* Attributes, const char* Name, long* Val); -/* Search CfgInfo for an attribute with the given name and type "number". - * If found, remove it from the configuration, copy it into Val and return - * true. If not found, return false. - */ - - - -/* End of cfgdata.h */ - -#endif - - - diff --git a/src/sim65/chip.c b/src/sim65/chip.c deleted file mode 100644 index 2b5ae940b..000000000 --- a/src/sim65/chip.c +++ /dev/null @@ -1,419 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chip.c */ -/* */ -/* Interface for the chip plugins */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include - -/* common */ -#include "coll.h" -#include "fname.h" -#include "print.h" -#include "xmalloc.h" - -/* sim65 */ -#include "cfgdata.h" -#include "chip.h" -#include "chipdata.h" -#include "cpucore.h" -#include "error.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int GetCfgId (void* CfgInfo, const char* Name, char** Id); -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in Id must be free by a call to - * Free(); - */ - -static int GetCfgStr (void* CfgInfo, const char* Name, char** S); -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in S must be free by a call to - * Free(); - */ - -static int GetCfgNum (void* CfgInfo, const char* Name, long* Val); -/* Search CfgInfo for an attribute with the given name and type "number". - * If found, remove it from the configuration, copy it into Val and return - * true. If not found, return false. - */ - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Sorted list of all chip data structures */ -static Collection Chips = STATIC_COLLECTION_INITIALIZER; - -/* A collection containing all libraries */ -static Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER; - -/* SimData instance */ -static const SimData Sim65Data = { - 1, /* MajorVersion */ - 1, /* MinorVersion */ - xmalloc, - xfree, - Warning, - Error, - Internal, - GetCfgId, - GetCfgStr, - GetCfgNum, - 0, - 0, - Break, - IRQRequest, - NMIRequest, -}; - - - -/*****************************************************************************/ -/* Helper functions */ -/*****************************************************************************/ - - - -static int GetCfgId (void* CfgInfo, const char* Name, char** Id) -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in Id must be free by a call to - * Free(); - */ -{ - return CfgDataGetId (CfgInfo, Name, Id); -} - - - -static int GetCfgStr (void* CfgInfo, const char* Name, char** S) -/* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in S must be free by a call to - * Free(); - */ -{ - return CfgDataGetStr (CfgInfo, Name, S); -} - - - -static int GetCfgNum (void* CfgInfo, const char* Name, long* Val) -/* Search CfgInfo for an attribute with the given name and type "number". - * If found, remove it from the configuration, copy it into Val and return - * true. If not found, return false. - */ -{ - return CfgDataGetNum (CfgInfo, Name, Val); -} - - - -static int CmpChips (void* Data attribute ((unused)), - const void* lhs, const void* rhs) -/* Compare function for CollSort */ -{ - /* Cast the object pointers */ - const Chip* Left = (const Chip*) rhs; - const Chip* Right = (const Chip*) lhs; - - /* Do the compare */ - return strcmp (Left->Data->ChipName, Right->Data->ChipName); -} - - - -static Chip* FindChip (const char* Name) -/* Find a chip by name. Returns the Chip data structure or NULL if the chip - * could not be found. - */ -{ - unsigned I; - - /* ## We do a linear search for now */ - for (I = 0; I < CollCount (&Chips); ++I) { - - /* Get the chip at this position */ - Chip* C = CollAt (&Chips, I); - - /* Compare the name */ - if (strcmp (Name, C->Data->ChipName) == 0) { - /* Found */ - return C; - } - } - - /* Not found */ - return 0; -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static ChipLibrary* NewChipLibrary (const char* PathName) -/* Create, initialize and return a new ChipLibrary structure */ -{ - /* Allocate memory */ - ChipLibrary* L = xmalloc (sizeof (ChipLibrary)); - - /* Initialize the fields */ - L->LibName = xstrdup (FindName (PathName)); - L->PathName = xstrdup (PathName); - L->Handle = 0; - L->Chips = EmptyCollection; - - /* Return the allocated structure */ - return L; -} - - - -static void FreeChipLibrary (ChipLibrary* L) -/* Free a ChipLibrary structure */ -{ - /* Free the names */ - xfree (L->LibName); - xfree (L->PathName); - - /* If the library is open, close it. Discard any errors. */ - if (L->Handle) { - dlclose (L->Handle); - (void) dlerror (); - } - - /* We may have to handle the Chip pointers, but currently the function - * is never called with a non empty Chips collection, so we don't care - * for now. - */ - xfree (L); -} - - - -static Chip* NewChip (ChipLibrary* Library, const ChipData* Data) -/* Allocate a new chip structure, initialize and return it */ -{ - /* Allocate memory */ - Chip* C = xmalloc (sizeof (Chip)); - - /* Initialize the fields */ - C->Lib = Library; - C->Data = Data; - C->Instances = EmptyCollection; - - /* Insert the new chip into the collection of all chips */ - CollAppend (&Chips, C); - - /* Return the structure */ - return C; -} - - - -ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr, - unsigned Size, Collection* Attributes) -{ - ChipInstance* CI; - - /* Find the chip with the given name */ - Chip* C = FindChip (ChipName); - if (C == 0) { - Error ("No chip `%s' found for address $%06X", ChipName, Addr); - } - - /* Allocate a new ChipInstance structure */ - CI = xmalloc (sizeof (*CI)); - - /* Initialize the fields */ - CI->C = C; - CI->AS = 0; - CI->Addr = Addr; - CI->Size = Size; - CI->Data = C->Data->CreateInstance (Addr, Size, Attributes); - - /* Assign the chip instance to the chip */ - CollAppend (&C->Instances, CI); - - /* Return the new instance struct */ - return CI; -} - - - -ChipInstance* MirrorChipInstance (const ChipInstance* Orig, unsigned Addr) -/* Generate a chip instance mirror and return it. */ -{ - /* Allocate a new ChipInstance structure */ - ChipInstance* CI = xmalloc (sizeof (*CI)); - - /* Initialize the fields */ - CI->C = Orig->C; - CI->AS = 0; - CI->Addr = Addr; - CI->Size = Orig->Size; - CI->Data = Orig->Data; - - /* Assign the chip instance to the chip */ - CollAppend (&CI->C->Instances, CI); - - /* Return the new instance struct */ - return CI; -} - - - -void SortChips (void) -/* Sort all chips by name. Called after loading */ -{ - /* Last act: Sort the chips by name */ - CollSort (&Chips, CmpChips, 0); -} - - - -void LoadChipLibrary (const char* LibName) -/* Load a chip library. This includes loading the shared libary, allocating - * and initializing the data structure, and loading all chip data from the - * library. - */ -{ - const char* Msg; - int (*GetChipData) (const struct ChipData**, unsigned*); - int ErrorCode; - const ChipData* Data; /* Pointer to chip data */ - unsigned ChipCount; /* Number of chips in this library */ - unsigned I; - - - /* Allocate a new ChipLibrary structure */ - ChipLibrary* L = NewChipLibrary (LibName); - - /* Open the library */ - L->Handle = dlopen (L->PathName, RTLD_GLOBAL | RTLD_LAZY); - - /* Check for errors */ - Msg = dlerror (); - if (Msg) { - Error ("Cannot open `%s': %s", L->PathName, Msg); - FreeChipLibrary (L); - return; - } - - /* Locate the GetChipData function */ - GetChipData = dlsym (L->Handle, "GetChipData"); - - /* Check the error message */ - Msg = dlerror (); - if (Msg) { - /* We had an error */ - Error ("Cannot find export `GetChipData' in `%s': %s", L->LibName, Msg); - FreeChipLibrary (L); - return; - } - - /* Call the function to read the chip data */ - ErrorCode = GetChipData (&Data, &ChipCount); - if (ErrorCode != 0) { - Error ("Function `GetChipData' in `%s' returned error %d", L->LibName, ErrorCode); - FreeChipLibrary (L); - return; - } - - /* Remember the library */ - CollAppend (&ChipLibraries, L); - - /* Print some information */ - Print (stderr, 1, "Opened chip library `%s'\n", L->PathName); - - /* Create the chips */ - for (I = 0; I < ChipCount; ++I) { - - Chip* C; - - /* Get a pointer to the chip data */ - const ChipData* D = Data + I; - - /* Check if the chip data has the correct version */ - if (D->MajorVersion != CHIPDATA_VER_MAJOR) { - Warning ("Version mismatch for `%s' (%s), expected %u, got %u", - D->ChipName, L->LibName, - CHIPDATA_VER_MAJOR, D->MajorVersion); - /* Ignore this chip */ - continue; - } - - /* Initialize the chip passing the simulator data */ - D->InitChip (&Sim65Data); - - /* Generate a new chip */ - C = NewChip (L, D); - - /* Insert a reference to the chip into the library exporting it */ - CollAppend (&L->Chips, C); - - /* Output chip name and version to keep the user happy */ - Print (stdout, 1, - " Found %s `%s', version %u.%u in library `%s'\n", - (D->Type == CHIPDATA_TYPE_CHIP)? "chip" : "cpu", - D->ChipName, - D->MajorVersion, - D->MinorVersion, - L->LibName); - } -} - - - diff --git a/src/sim65/chip.h b/src/sim65/chip.h deleted file mode 100644 index d45f8c1f7..000000000 --- a/src/sim65/chip.h +++ /dev/null @@ -1,118 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chip.h */ -/* */ -/* Interface for the chip plugins */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CHIP_H -#define CHIP_H - - - -/* common.h */ -#include "coll.h" - -/* sim65 */ -#include "chipdata.h" -#include "simdata.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Forwards */ -struct AddressSpace; -struct CfgData; -typedef struct ChipInstance ChipInstance; -typedef struct Chip Chip; -typedef struct ChipLibrary ChipLibrary; - -/* One instance of a chip */ -struct ChipInstance { - Chip* C; /* Pointer to corresponding chip */ - struct AddressSpace* AS; /* Pointer to address space */ - unsigned Addr; /* Start address of range */ - unsigned Size; /* Size of range */ - void* Data; /* Chip instance data */ -}; - -/* Chip structure */ -struct Chip { - struct ChipLibrary* Lib; /* Pointer to library data structure */ - const ChipData* Data; /* Chip data as given by the library */ - Collection Instances; /* Pointer to chip instances */ -}; - -/* ChipLibrary structure */ -struct ChipLibrary { - char* LibName; /* Name of the library as given */ - char* PathName; /* Name of library including path */ - void* Handle; /* Pointer to libary handle */ - Collection Chips; /* Chips in this library */ -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr, - unsigned Size, Collection* Attributes); -/* Allocate a new chip instance for the chip. */ - -ChipInstance* MirrorChipInstance (const ChipInstance* Orig, unsigned Addr); -/* Generate a chip instance mirror and return it. */ - -void SortChips (void); -/* Sort all chips by name. Called after loading */ - -void LoadChipLibrary (const char* LibName); -/* Load a chip library. This includes loading the shared libary, allocating - * and initializing the data structure, and loading all chip data from the - * library. - */ - - - -/* End of chip.h */ - -#endif - - - diff --git a/src/sim65/chipdata.h b/src/sim65/chipdata.h deleted file mode 100644 index 916a718ff..000000000 --- a/src/sim65/chipdata.h +++ /dev/null @@ -1,82 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chipdata.h */ -/* */ -/* Chip description data structure */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CHIPDATA_H -#define CHIPDATA_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Chip type and version information. */ -#define CHIPDATA_TYPE_CHIP 0U -#define CHIPDATA_TYPE_CPU 1U -#define CHIPDATA_VER_MAJOR 1U -#define CHIPDATA_VER_MINOR 0U - -/* Forwards */ -struct CfgData; -struct SimData; - -/* ChipDesc structure */ -typedef struct ChipData ChipData; -struct ChipData { - const char* ChipName; /* Name of the chip */ - unsigned Type; /* Type of the chip */ - unsigned MajorVersion; /* Version information */ - unsigned MinorVersion; - - /* -- Exported functions -- */ - int (*InitChip) (const struct SimData* Data); - void* (*CreateInstance) (unsigned Addr, unsigned Range, void* CfgInfo); - void (*DestroyInstance) (void* Data); - void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val); - void (*Write) (void* Data, unsigned Offs, unsigned char Val); - unsigned char (*ReadCtrl) (void* Data, unsigned Offs); - unsigned char (*Read) (void* Data, unsigned Offs); -}; - - - -/* End of chipdata.h */ - -#endif - - - diff --git a/src/sim65/chipif.h b/src/sim65/chipif.h deleted file mode 100644 index f5f1ab102..000000000 --- a/src/sim65/chipif.h +++ /dev/null @@ -1,52 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chipif.h */ -/* */ -/* Interface header file for chip plugins - unused by sim65 */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CHIPIF_H -#define CHIPIF_H - - - -/* sim65 */ -#include "chipdata.h" -#include "simdata.h" - - - -/* End of chipif.h */ - -#endif - - - diff --git a/src/sim65/chippath.c b/src/sim65/chippath.c deleted file mode 100644 index 88fc7d5f2..000000000 --- a/src/sim65/chippath.c +++ /dev/null @@ -1,81 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chippath.h */ -/* */ -/* Chip path handling for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2000-2010, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#if defined(_MSC_VER) -/* Microsoft compiler */ -# include -#else -/* Anyone else */ -# include -#endif - -/* sim65 */ -#include "chippath.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -SearchPath* ChipSearchPath; /* Search paths for chip libs */ - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void InitChipPaths (void) -/* Initialize the chip search path list */ -{ - /* Create the search path list */ - ChipSearchPath = NewSearchPath (); - - /* Add the current directory to the search path */ - AddSearchPath (ChipSearchPath, ""); - -} - - - - - diff --git a/src/sim65/chippath.h b/src/sim65/chippath.h deleted file mode 100644 index be61bb517..000000000 --- a/src/sim65/chippath.h +++ /dev/null @@ -1,72 +0,0 @@ -/*****************************************************************************/ -/* */ -/* chippath.h */ -/* */ -/* Chip path handling for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2000-2010, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CHIPPATH_H -#define CHIPPATH_H - - - -/* common */ -#include "searchpath.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -extern SearchPath* ChipSearchPath; /* Search paths for chip libs */ - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void InitChipPaths (void); -/* Initialize the chip search path list */ - - - -/* End of chippath.h */ - -#endif - - - diff --git a/src/sim65/chips/console.c b/src/sim65/chips/console.c deleted file mode 100644 index 526cc04f1..000000000 --- a/src/sim65/chips/console.c +++ /dev/null @@ -1,659 +0,0 @@ -/*****************************************************************************/ -/* */ -/* console.c */ -/* */ -/* Console plugin for the sim65 simulator */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include - -#include -#include -#include -#include - -/* common */ -#include "attrib.h" - -/* sim65 */ -#include "chipif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int ScreenInitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* ScreenCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void ScreenDestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void ScreenWrite (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char ScreenRead (void* Data, unsigned Offs); -/* Read user data */ - -static void ScreenDrawBorder (void); -/* Draw the complete border */ - -static void ScreenDrawChar (unsigned Offs); -/* Draw one character at the given position */ - -static void ScreenDrawAllChars (void); -/* Redraw the complete interior screen */ - -static void ScreenEventLoop (void); -/* Get all waiting events and handle them */ - - - -/*****************************************************************************/ -/* Global data */ -/*****************************************************************************/ - - - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* Control data passed to the main program */ -static const struct ChipData CData[] = { - { - "VIDEOSCREEN", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - ScreenInitChip, - ScreenCreateInstance, - ScreenDestroyInstance, - ScreenWrite, - ScreenWrite, - ScreenRead, - ScreenRead - }, -}; - -/* Defines for console screen */ -static const XColor GreenColor = { - 0, 32*256, 141*256, 32*256, 0, 0 /* green */ -}; -static const XColor AmberColor = { - 0, 255*256, 204*256, 51*256, 0, 0 /* amber */ -}; -static const XColor WhiteColor = { - 0, 224*256, 224*256, 224*256, 0, 0 /* white */ -}; -static const XColor BgColor = { - 0, 0*256, 0*256, 0*256, 0, 0 /* black */ -}; - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Screen instance data */ -typedef struct ScreenInstance ScreenInstance; -struct ScreenInstance { - - /* Settings passed from the simulator */ - unsigned Addr; /* Address of the chip */ - unsigned Range; /* Memory range */ - - /* X variables */ - Display* ScreenDisplay; - Window ScreenWindow; - int Screen; - GC ScreenGC; - - /* Windows rows and columns */ - unsigned Rows; - unsigned Cols; - - /* Window dimensions, determined by char resolution and char set */ - unsigned XTotal; - unsigned YTotal; - - /* Usable area within the window */ - unsigned XSize; - unsigned YSize; - - /* Offset of the usable area */ - unsigned XOffs; - unsigned YOffs; - - /* Character height */ - unsigned CharHeight; - - /* Fore- and background color */ - XColor FgColor; - XColor BgColor; - - /* A list of 4 rectangles used to draw the border */ - XRectangle Border[4]; - - /* The virtual screen we are writing to. */ - unsigned MemSize; - unsigned char* Mem; - - /* The font data */ - unsigned FontDataSize; - unsigned char* FontData; - -}; - -/* If we have a video ram window, place it's instance data here */ -static ScreenInstance* VScreen = 0; - - - -/*****************************************************************************/ -/* Exported function */ -/*****************************************************************************/ - - - -int GetChipData (const ChipData** Data, unsigned* Count) -{ - /* Pass the control structure to the caller */ - *Data = CData; - *Count = sizeof (CData) / sizeof (CData[0]); - - /* Call was successful */ - return 0; -} - - - -/*****************************************************************************/ -/* Helper functions */ -/*****************************************************************************/ - - - -static long CfgGetNum (void* CfgInfo, const char* AttrName, long Min, long Max, long Def) -/* Read a number from the attributes. Check against Min/Max. Return the - * number or Def if it doesn't exist. - */ -{ - long Val; - - /* Read the attribute if it does exist */ - if (Sim->GetCfgNum (CfgInfo, AttrName, &Val)) { - /* Check it */ - if (Val < Min || Val > Max) { - Sim->Error ("Range error for attribute `%s'", AttrName); - } - - /* Return it */ - return Val; - - } else { - - /* Return the default */ - return Def; - - } -} - - - -/*****************************************************************************/ -/* Console screen */ -/*****************************************************************************/ - - - -static int ScreenInitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* ScreenCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo) -/* Create a new chip instance */ -{ - char* Name; - FILE* F; - unsigned ColorDepth; - Colormap CM; - XSizeHints SizeHints; - XWMHints WMHints; - Cursor C; - unsigned CharColor; - - - /* Allocate the instance data */ - ScreenInstance* V = VScreen = Sim->Malloc (sizeof (ScreenInstance)); - - /* Remember a few settings */ - V->Addr = Addr; - V->Range = Range; - - /* Character height is 8 or given as attribute */ - V->CharHeight = (unsigned) CfgGetNum (CfgInfo, "charheight", 8, 16, 8); - - /* Allocate memory for the font */ - V->FontDataSize = V->CharHeight * 256; - V->FontData = Sim->Malloc (V->FontDataSize); - - /* We must have a "fontdata" attribute. Get it. */ - if (Sim->GetCfgStr (CfgInfo, "fontdata", &Name) == 0) { - /* Attribute not found */ - Sim->Error ("Attribute `fontdata' missing"); /* ### */ - } - - /* Open the file with the given name */ - F = fopen (Name, "rb"); - if (F == 0) { - Sim->Error ("Cannot open `%s': %s", Name, strerror (errno)); - } - - /* Read the file into the memory */ - if (fread (V->FontData, 1, V->FontDataSize, F) != V->FontDataSize) { - Sim->Warning ("Font data file `%s' seems to be corrupt", Name); - } - - /* Close the file */ - fclose (F); - - /* Free the file name */ - Sim->Free (Name); - - /* Read screen rows and columns */ - V->Rows = (unsigned) CfgGetNum (CfgInfo, "rows", 15, 75, 25); - V->Cols = (unsigned) CfgGetNum (CfgInfo, "cols", 32, 132, 80); - - /* Allocate screen memory and clear it */ - V->MemSize = V->Rows * V->Cols; - V->Mem = Sim->Malloc (V->MemSize); - memset (V->Mem, ' ', V->MemSize); - - /* Setup the window geometry */ - V->XSize = V->Cols * 8; - V->YSize = V->Rows * V->CharHeight; - V->XTotal = V->XSize + 20; - V->YTotal = V->YSize + 20; - V->XOffs = (V->XTotal - V->XSize) / 2; - V->YOffs = (V->YTotal - V->YSize) / 2; - - /* Setup the rectanges used to draw the exterior */ - V->Border[0].x = 0; - V->Border[0].y = 0; - V->Border[0].width = V->XTotal; - V->Border[0].height = V->YOffs; - V->Border[1].x = 0; - V->Border[1].y = V->YOffs + V->YSize; - V->Border[1].width = V->XTotal; - V->Border[1].height = V->YOffs; - V->Border[2].x = 0; - V->Border[2].y = V->YOffs; - V->Border[2].width = V->XOffs; - V->Border[2].height = V->YSize; - V->Border[3].x = V->XOffs + V->XSize; - V->Border[3].y = V->YOffs; - V->Border[3].width = V->XOffs; - V->Border[3].height = V->YSize; - - /* Open the X display. */ - V->ScreenDisplay = XOpenDisplay (""); - if (V->ScreenDisplay == NULL) { - Sim->Error ("Screen: Cannot open X display"); - } - - /* Get a screen */ - V->Screen = DefaultScreen (V->ScreenDisplay); - - /* Check the available colors. For now, we expect direct colors, so we - * will check for a color depth of at least 16. - */ - ColorDepth = XDefaultDepth (V->ScreenDisplay, V->Screen); - if (ColorDepth < 16) { - /* OOPS */ - Sim->Error ("Screen: Need color display"); - } - - /* Determine the character color */ - CharColor = (unsigned) CfgGetNum (CfgInfo, "charcolor", 0, 2, 0); - - /* Get all needed colors */ - switch (CharColor) { - case 1: V->FgColor = AmberColor; break; - case 2: V->FgColor = WhiteColor; break; - default: V->FgColor = GreenColor; break; - } - V->BgColor = BgColor; - CM = DefaultColormap (V->ScreenDisplay, V->Screen); - if (XAllocColor (V->ScreenDisplay, CM, &V->FgColor) == 0) { - Sim->Error ("Screen: Cannot allocate foreground color"); - } - if (XAllocColor (V->ScreenDisplay, CM, &V->BgColor) == 0) { - Sim->Error ("Screen: Cannot allocate background color"); - } - - /* Set up the size hints structure */ - SizeHints.x = 0; - SizeHints.y = 0; - SizeHints.flags = PPosition | PSize | PMinSize | PMaxSize | PResizeInc; - SizeHints.width = V->XTotal; - SizeHints.height = V->YTotal; - SizeHints.min_width = V->XTotal; - SizeHints.min_height = V->YTotal; - SizeHints.max_width = V->XTotal; - SizeHints.max_height = V->YTotal; - SizeHints.width_inc = 0; - SizeHints.height_inc = 0; - WMHints.flags = InputHint; - WMHints.input = True; - - /* Create the window */ - V->ScreenWindow = XCreateSimpleWindow (V->ScreenDisplay, - DefaultRootWindow (V->ScreenDisplay), - SizeHints.x, - SizeHints.y, - SizeHints.width, - SizeHints.height, - 5, - V->FgColor.pixel, - V->BgColor.pixel); - - /* Set the standard window properties */ - XSetStandardProperties (V->ScreenDisplay, /* Display */ - V->ScreenWindow, /* Window */ - "sim65 console screen", /* Window name */ - "sim65 console screen", /* Icon name */ - None, /* Icon Pixmap */ - 0, /* argv */ - 0, /* argc */ - &SizeHints); /* Hints */ - XSetWMHints (V->ScreenDisplay, V->ScreenWindow, &WMHints); - - /* GC creation and initialization */ - V->ScreenGC = XCreateGC (V->ScreenDisplay, V->ScreenWindow, 0, 0); - - /* Set the cursor to show over the console window */ - C = XCreateFontCursor (V->ScreenDisplay, XC_pirate); - XDefineCursor (V->ScreenDisplay, V->ScreenWindow, C); - - /* Select input events */ - XSelectInput (V->ScreenDisplay, V->ScreenWindow, ExposureMask | StructureNotifyMask | KeyPressMask); - - /* Show the window */ - XMapRaised (V->ScreenDisplay, V->ScreenWindow); - - /* Handle events */ - ScreenEventLoop (); - - /* Return the instance data */ - return V; -} - - - -static void ScreenDestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the data pointer */ - ScreenInstance* V = Data; - - /* Free X resources */ - XUndefineCursor (V->ScreenDisplay, V->ScreenWindow); - XFreeGC (V->ScreenDisplay, V->ScreenGC); - XDestroyWindow (V->ScreenDisplay, V->ScreenWindow); - XCloseDisplay (V->ScreenDisplay); - - /* Clear the global pointer */ - VScreen = 0; - - /* Free the instance data */ - Sim->Free (V->FontData); - Sim->Free (V->Mem); - Sim->Free (V); -} - - - -static void ScreenWrite (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - ScreenInstance* V = Data; - - /* Check the offset */ - if (Offs >= V->MemSize) { - Sim->Break ("Screen: Accessing invalid memory at $%06X", V->Addr + Offs); - return; - } - - /* Write the value */ - V->Mem[Offs] = Val; - - /* Schedule a redraw */ - ScreenDrawChar (Offs); - - /* Call the event loop */ - ScreenEventLoop (); -} - - - -static unsigned char ScreenRead (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - ScreenInstance* V = Data; - - /* Check the offset */ - if (Offs >= sizeof (V->Mem)) { - Sim->Break ("Screen: Accessing invalid memory at $%06X", V->Addr + Offs); - return 0xFF; - } else { - return V->Mem[Offs]; - } -} - - - -static void ScreenDrawBorder (void) -/* Draw the complete border */ -{ - if (VScreen) { - /* Set the border color */ - XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->BgColor.pixel); - - /* Fill all rectangles that make the border */ - XFillRectangles (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC, - VScreen->Border, sizeof (VScreen->Border) / sizeof (VScreen->Border[0])); - } -} - - - -static void ScreenDrawChar (unsigned Offs) -/* Draw one character at the given position */ -{ - unsigned Row, Col; - XPoint Points[128]; - unsigned PCount; - - /* Get the character from the video RAM */ - unsigned char C = VScreen->Mem[Offs]; - - /* Calculate the offset for the character data in the character ROM */ - unsigned char* D = VScreen->FontData + (C * VScreen->CharHeight); - - /* Calculate the coords for the output */ - unsigned X = VScreen->XOffs + (Offs % VScreen->Cols) * 8; - unsigned Y = VScreen->YOffs + (Offs / VScreen->Cols) * VScreen->CharHeight; - - /* Clear the character area with the background color */ - XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->BgColor.pixel); - XFillRectangle (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC, X, Y, 8, VScreen->CharHeight); - - /* Prepare the foreground pixels */ - PCount = 0; - for (Row = 0; Row < VScreen->CharHeight; ++Row) { - - /* Get next byte from char rom */ - unsigned Data = *D++; - - /* Make pixels from this byte */ - for (Col = 0; Col < 8; ++Col) { - if (Data & 0x80) { - /* Foreground pixel */ - Points[PCount].x = X + Col; - Points[PCount].y = Y + Row; - ++PCount; - } - Data <<= 1; - } - } - if (PCount) { - /* Set the character color */ - XSetForeground (VScreen->ScreenDisplay, VScreen->ScreenGC, VScreen->FgColor.pixel); - - /* Draw the pixels */ - XDrawPoints (VScreen->ScreenDisplay, VScreen->ScreenWindow, VScreen->ScreenGC, - Points, PCount, CoordModeOrigin); - } -} - - - -static void ScreenDrawArea (unsigned X1, unsigned Y1, unsigned X2, unsigned Y2) -/* Update an area of the interior screen */ -{ - unsigned X, Y; - - /* Check if we have to draw anything */ - if (X2 < VScreen->XOffs || Y2 < VScreen->YOffs || - X1 >= VScreen->XOffs + VScreen->XSize || - Y1 >= VScreen->YOffs + VScreen->YSize) { - /* Completely outside */ - return; - } - - /* Make the coordinates relative to the interior */ - X1 -= VScreen->XOffs; - Y1 -= VScreen->YOffs; - X2 -= VScreen->XOffs; - Y2 -= VScreen->YOffs; - - /* Loop updating characters */ - for (Y = Y1; Y <= Y2; Y += 8) { - for (X = X1; X <= X2; X += 8) { - ScreenDrawChar ((Y / 8) * 40 + (X / 8)); - } - } -} - - - -static void ScreenDrawAllChars (void) -/* Redraw the complete interior screen */ -{ - unsigned I; - for (I = 0; I < 25*40; ++I) { - ScreenDrawChar (I); - } -} - - - -static void ScreenEventLoop (void) -/* Get all waiting events and handle them */ -{ - unsigned X1, Y1, X2, Y2; - - /* Read input events */ - while (XEventsQueued (VScreen->ScreenDisplay, QueuedAfterFlush) != 0) { - - /* Read an event */ - XEvent Event; - XNextEvent (VScreen->ScreenDisplay, &Event); - - switch (Event.type) { - - case Expose: - /* Calculate the area to redraw, then update the screen */ - X1 = Event.xexpose.x; - Y1 = Event.xexpose.y; - X2 = Event.xexpose.x + Event.xexpose.width - 1; - Y2 = Event.xexpose.y + Event.xexpose.height - 1; - if (X1 < VScreen->XOffs || X2 > VScreen->XOffs + VScreen->XSize || - Y1 < VScreen->YOffs || Y2 > VScreen->YOffs + VScreen->YSize) { - /* Update the border */ - ScreenDrawBorder (); - } - ScreenDrawArea (X1, Y1, X2, Y2); - break; - - case MappingNotify: - XRefreshKeyboardMapping (&Event.xmapping); - break; - - case KeyPress: - break; - - default: - /* Ignore anything else */ - break; - - } - } - - /* Flush the outgoing event queue */ - XFlush (VScreen->ScreenDisplay); -} - - - diff --git a/src/sim65/chips/ram.c b/src/sim65/chips/ram.c deleted file mode 100644 index 61691aaa8..000000000 --- a/src/sim65/chips/ram.c +++ /dev/null @@ -1,266 +0,0 @@ -/*****************************************************************************/ -/* */ -/* ram.c */ -/* */ -/* RAM plugin for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include - -/* sim65 */ -#include "chipif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void DestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val); -/* Write control data */ - -static void Write (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char ReadCtrl (void* Data, unsigned Offs); -/* Read control data */ - -static unsigned char Read (void* Data, unsigned Offs); -/* Read user data */ - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Control data passed to the main program */ -static const struct ChipData CData[1] = { - { - "RAM", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - InitChip, - CreateInstance, - DestroyInstance, - WriteCtrl, - Write, - ReadCtrl, - Read - } -}; - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* Possible RAM attributes */ -#define ATTR_INITIALIZED 0x01 /* RAM cell is intialized */ -#define ATTR_WPROT 0x02 /* RAM cell is write protected */ - -/* Data for one RAM instance */ -typedef struct InstanceData InstanceData; -struct InstanceData { - unsigned BaseAddr; /* Base address */ - unsigned Range; /* Memory range */ - unsigned char* MemAttr; /* Memory attributes */ - unsigned char* Mem; /* The memory itself */ -}; - - - -/*****************************************************************************/ -/* Exported function */ -/*****************************************************************************/ - - - -int GetChipData (const ChipData** Data, unsigned* Count) -{ - /* Pass the control structure to the caller */ - *Data = CData; - *Count = sizeof (CData) / sizeof (CData[0]); - - /* Call was successful */ - return 0; -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo) -/* Create a new chip instance */ -{ - long Val; - - /* Allocate a new instance structure */ - InstanceData* D = Sim->Malloc (sizeof (InstanceData)); - - /* Initialize the structure, allocate RAM and attribute memory */ - D->BaseAddr = Addr; - D->Range = Range; - D->MemAttr = Sim->Malloc (Range * sizeof (D->MemAttr[0])); - D->Mem = Sim->Malloc (Range * sizeof (D->Mem[0])); - - /* Check if a value is given that should be used to clear the RAM. - * Otherwise use random values. - */ - if (Sim->GetCfgNum (CfgInfo, "fill", &Val) == 0) { - /* No "fill" attribute */ - unsigned I; - for (I = 0; I < Range; ++I) { - D->Mem[I] = (unsigned char) rand (); - } - } else { - /* Got a "fill" attribute */ - memset (D->Mem, (int) Val, Range); - } - - /* Clear the attribute memory */ - memset (D->MemAttr, 0, Range * sizeof (D->MemAttr[0])); - - /* Done, return the instance data */ - return D; -} - - - -static void DestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Free memory and attributes */ - Sim->Free (D->Mem); - Sim->Free (D->MemAttr); - - /* Free the instance data itself */ - free (D); -} - - - -static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val) -/* Write control data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Do the write and remember the cell as initialized */ - D->Mem[Offs] = Val; - D->MemAttr[Offs] |= ATTR_INITIALIZED; -} - - - -static void Write (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Check for a write to a write protected cell */ - if (D->MemAttr[Offs] & ATTR_WPROT) { - Sim->Break ("Writing to write protected memory at $%04X", D->BaseAddr+Offs); - } - - /* Do the write and remember the cell as initialized */ - D->Mem[Offs] = Val; - D->MemAttr[Offs] |= ATTR_INITIALIZED; -} - - - -static unsigned char ReadCtrl (void* Data, unsigned Offs) -/* Read control data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - -static unsigned char Read (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Check for a read from an uninitialized cell */ - if ((D->MemAttr[Offs] & ATTR_INITIALIZED) == 0) { - /* We're reading a memory cell that was never written to */ - Sim->Break ("Reading from uninitialized memory at $%04X", D->BaseAddr+Offs); - } - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - - diff --git a/src/sim65/chips/rom.c b/src/sim65/chips/rom.c deleted file mode 100644 index fb88b9e5d..000000000 --- a/src/sim65/chips/rom.c +++ /dev/null @@ -1,255 +0,0 @@ -/*****************************************************************************/ -/* */ -/* rom.c */ -/* */ -/* ROM plugin for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include - -/* sim65 */ -#include "chipif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void DestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val); -/* Write control data */ - -static void Write (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char ReadCtrl (void* Data, unsigned Offs); -/* Read control data */ - -static unsigned char Read (void* Data, unsigned Offs); -/* Read user data */ - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Control data passed to the main program */ -static const struct ChipData CData[1] = { - { - "ROM", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - InitChip, - CreateInstance, - DestroyInstance, - WriteCtrl, - Write, - ReadCtrl, - Read - } -}; - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* Data for one ROM instance */ -typedef struct InstanceData InstanceData; -struct InstanceData { - unsigned BaseAddr; /* Base address */ - unsigned Range; /* Memory range */ - unsigned char* Mem; /* The memory itself */ -}; - - - -/*****************************************************************************/ -/* Exported function */ -/*****************************************************************************/ - - - -int GetChipData (const ChipData** Data, unsigned* Count) -{ - /* Pass the control structure to the caller */ - *Data = CData; - *Count = sizeof (CData) / sizeof (CData[0]); - - /* Call was successful */ - return 0; -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo) -/* Create a new chip instance */ -{ - char* Name; - FILE* F; - - /* Allocate a new instance structure */ - InstanceData* D = Sim->Malloc (sizeof (InstanceData)); - - /* Initialize the structure, allocate RAM and attribute memory */ - D->BaseAddr = Addr; - D->Range = Range; - D->Mem = Sim->Malloc (Range); - - /* We must have a "file" attribute. Get it. */ - if (Sim->GetCfgStr (CfgInfo, "file", &Name) == 0) { - /* Attribute not found */ - Sim->Error ("Attribute `file' missing"); /* ### */ - } - - /* Open the file with the given name */ - F = fopen (Name, "rb"); - if (F == 0) { - Sim->Error ("Cannot open `%s': %s", Name, strerror (errno)); - } - - /* Read the file into the memory */ - if (fread (D->Mem, 1, D->Range, F) != D->Range) { - Sim->Warning ("Cannot read %u bytes from file `%s'", D->Range, Name); - } - - /* Close the file */ - fclose (F); - - /* Free the file name */ - Sim->Free (Name); - - /* Done, return the instance data */ - return D; -} - - - -static void DestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Free the ROM memory */ - Sim->Free (D->Mem); - - /* Free the instance data itself */ - free (D); -} - - - -static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val) -/* Write control data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Do the write */ - D->Mem[Offs] = Val; -} - - - -static void Write (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Print a warning */ - Sim->Break ("Writing to write protected memory at $%04X (value = $%02X)", - D->BaseAddr+Offs, Val); -} - - - -static unsigned char ReadCtrl (void* Data, unsigned Offs) -/* Read control data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - -static unsigned char Read (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - InstanceData* D = (InstanceData*) Data; - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - diff --git a/src/sim65/chips/stdio.c b/src/sim65/chips/stdio.c deleted file mode 100644 index ec3403f98..000000000 --- a/src/sim65/chips/stdio.c +++ /dev/null @@ -1,289 +0,0 @@ -/*****************************************************************************/ -/* */ -/* stdio.c */ -/* */ -/* STDIO plugin for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2002-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include - -/* common */ -#include "attrib.h" - -/* sim65 */ -#include "chipif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void DestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val); -/* Write control data */ - -static void Write (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char ReadCtrl (void* Data, unsigned Offs); -/* Read control data */ - -static unsigned char Read (void* Data, unsigned Offs); -/* Read user data */ - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* Control data passed to the main program */ -static const struct ChipData CData[1] = { - { - "STDIO", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - InitChip, - CreateInstance, - DestroyInstance, - WriteCtrl, - Write, - ReadCtrl, - Read - } -}; - -/* Screen instance data */ -typedef struct InstanceData InstanceData; -struct InstanceData { - /* The memory area used for data */ - unsigned char* Mem[32]; -}; - -/* Function opcodes */ -enum { - F_open, - F_close, - F_write, - F_read, - F_lseek, - F_unlink, - F_chdir, - F_getcwd, - F_mkdir, - F_rmdir, -}; - - - -/*****************************************************************************/ -/* Exported function */ -/*****************************************************************************/ - - - -int GetChipData (const ChipData** Data, unsigned* Count) -{ - /* Pass the control structure to the caller */ - *Data = CData; - *Count = sizeof (CData) / sizeof (CData[0]); - - /* Call was successful */ - return 0; -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static int InitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* CreateInstance (unsigned Addr, unsigned Range, void* CfgInfo) -/* Initialize a new chip instance */ -{ - /* Allocate the instance data */ - InstanceData* D = Sim->Malloc (sizeof (InstanceData)); - - /* Initialize the instance data */ - memset (D->Mem, 0x00, sizeof (D->Mem)); - - /* Return the instance data */ - return D; -} - - - -static void DestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the instance data pointer */ - InstanceData* D = Data; - - /* Free the instance data */ - Sim->Free (D); -} - - - -static void WriteCtrl (void* Data attribute, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the instance data pointer */ - InstanceData* D = Data; - - /* Write to the memory */ - D->Mem[Offs] = Val; -} - - - -static void Write (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the instance data pointer */ - InstanceData* D = Data; - - /* Write to the memory */ - D->Mem[Offs] = Val; - - /* Now check the offset. Zero is special because it will trigger the - * action - */ - if (Offs == 0) { - - /* The action is determined by the value that is written */ - switch (Val) { - - case F_open: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_close: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_write: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_read: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_lseek: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_unlink: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_chdir: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_getcwd: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_mkdir: - Sim->Break ("Unsupported function $%02X", Val); - break; - - case F_rmdir: - Sim->Break ("Unsupported function $%02X", Val); - break; - - } - } -} - - - -static unsigned char ReadCtrl (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the instance data pointer */ - InstanceData* D = Data; - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - -static unsigned char Read (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the instance data pointer */ - InstanceData* D = Data; - - /* Read the cell and return the value */ - return D->Mem[Offs]; -} - - - diff --git a/src/sim65/chips/vic2.c b/src/sim65/chips/vic2.c deleted file mode 100644 index 98e9d8df8..000000000 --- a/src/sim65/chips/vic2.c +++ /dev/null @@ -1,897 +0,0 @@ -/*****************************************************************************/ -/* */ -/* vic2.c */ -/* */ -/* VIC II plugin for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include - -#include -#include -#include -#include - -/* common */ -#include "attrib.h" - -/* sim65 */ -#include "chipif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static int VicInitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* VicCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void VicDestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void VicWrite (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char VicRead (void* Data, unsigned Offs); -/* Read user data */ - -static int VRamInitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* VRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void VRamDestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void VRamWrite (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char VRamRead (void* Data, unsigned Offs); -/* Read user data */ - -static void VRamDrawBorder (void); -/* Draw the complete border */ - -static void VRamDrawChar (unsigned Offs); -/* Draw one character at the given position */ - -static void VRamDrawAllChars (void); -/* Redraw the complete interior screen */ - -static void VRamEventLoop (void); -/* Get all waiting events and handle them */ - -static int CRamInitChip (const struct SimData* Data); -/* Initialize the chip, return an error code */ - -static void* CRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo); -/* Create a new chip instance */ - -static void CRamDestroyInstance (void* Data); -/* Destroy a chip instance */ - -static void CRamWrite (void* Data, unsigned Offs, unsigned char Val); -/* Write user data */ - -static unsigned char CRamRead (void* Data, unsigned Offs); -/* Read user data */ - - - -/*****************************************************************************/ -/* Global data */ -/*****************************************************************************/ - - - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* Control data passed to the main program */ -static const struct ChipData CData[] = { - { - "VIC2", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - VicInitChip, - VicCreateInstance, - VicDestroyInstance, - VicWrite, - VicWrite, - VicRead, - VicRead - }, - { - "VIC2-VIDEORAM", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - VRamInitChip, - VRamCreateInstance, - VRamDestroyInstance, - VRamWrite, - VRamWrite, - VRamRead, - VRamRead - }, - { - "VIC2-COLORRAM", /* Name of the chip */ - CHIPDATA_TYPE_CHIP, /* Type of the chip */ - CHIPDATA_VER_MAJOR, /* Version information */ - CHIPDATA_VER_MINOR, - - /* -- Exported functions -- */ - CRamInitChip, - CRamCreateInstance, - CRamDestroyInstance, - CRamWrite, - CRamWrite, - CRamRead, - CRamRead - } -}; - -/* Defines for the VIC chip */ -#define VIC_COLOR_COUNT 16 -#define VIC_BLACK 0 -#define VIC_WHITE 1 - -/* The application color map. VIC II color values are taken from - * http://www.pepto.de/projects/colorvic/ (Philip "Pepto" Timmermann) - */ -static XColor VicColors [VIC_COLOR_COUNT] = { - { 0, 0*256, 0*256, 0*256, 0, 0 }, /* black */ - { 0, 255*256, 255*256, 255*256, 0, 0 }, /* white */ - { 0, 104*256, 55*256, 43*256, 0, 0 }, /* red */ - { 0, 112*256, 163*256, 178*256, 0, 0 }, /* cyan */ - { 0, 111*256, 61*256, 134*256, 0, 0 }, /* purple */ - { 0, 88*256, 141*256, 67*256, 0, 0 }, /* green */ - { 0, 53*256, 40*256, 121*256, 0, 0 }, /* blue */ - { 0, 184*256, 199*256, 111*256, 0, 0 }, /* yellow */ - { 0, 111*256, 79*256, 37*256, 0, 0 }, /* orange */ - { 0, 67*256, 57*256, 0*256, 0, 0 }, /* brown */ - { 0, 154*256, 103*256, 89*256, 0, 0 }, /* light red */ - { 0, 68*256, 68*256, 68*256, 0, 0 }, /* dark grey */ - { 0, 108*256, 108*256, 108*256, 0, 0 }, /* grey */ - { 0, 154*256, 210*256, 132*256, 0, 0 }, /* light green */ - { 0, 108*256, 94*256, 181*256, 0, 0 }, /* light blue */ - { 0, 149*256, 149*256, 149*256, 0, 0 } /* light grey */ -}; - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* VIC II instance data */ -typedef struct VicInstance VicInstance; -struct VicInstance { - unsigned Addr; /* Address of the chip */ - unsigned Range; /* Memory range */ - unsigned char Regs[47]; /* VIC registers */ -}; - -/* Video RAM instance data */ -typedef struct VRamInstance VRamInstance; -struct VRamInstance { - - /* Settings passed from the simulator */ - unsigned Addr; /* Address of the chip */ - unsigned Range; /* Memory range */ - - /* X variables */ - Display* VicDisplay; - Window VicWindow; - int VicScreen; - GC VicGC; - - /* Window dimensions, 384*288 (PAL) */ - unsigned XTotal; - unsigned YTotal; - - /* Usable area within the window */ - unsigned XSize; - unsigned YSize; - - /* Offset of the usable area */ - unsigned XOffs; - unsigned YOffs; - - /* The window color map. */ - XColor Colors [VIC_COLOR_COUNT]; - - /* A list of 4 rectangles used to draw the border */ - XRectangle Border[4]; - - /* The virtual screen we are writing to. */ - unsigned char Mem[0x400]; - - /* The character ROM data */ - unsigned char CharRom[0x1000]; - -}; - -typedef struct CRamInstance CRamInstance; -struct CRamInstance { - - /* Settings passed from the simulator */ - unsigned Addr; /* Address of the chip */ - unsigned Range; /* Memory range */ - - /* The memory we are writing to. */ - unsigned char Mem[0x400]; -}; - -/* If we have a video ram window, place it's instance data here */ -static VicInstance* Vic = 0; -static VRamInstance* VRam = 0; -static CRamInstance* CRam = 0; - - - -/*****************************************************************************/ -/* Exported function */ -/*****************************************************************************/ - - - -int GetChipData (const ChipData** Data, unsigned* Count) -{ - /* Pass the control structure to the caller */ - *Data = CData; - *Count = sizeof (CData) / sizeof (CData[0]); - - /* Call was successful */ - return 0; -} - - - -/*****************************************************************************/ -/* VIC II Chip */ -/*****************************************************************************/ - - - -static int VicInitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* VicCreateInstance (unsigned Addr, unsigned Range, - void* CfgInfo attribute ((unused))) -/* Initialize a new chip instance */ -{ - /* Allocate a new instance structure */ - VicInstance* V = Vic = Sim->Malloc (sizeof (VicInstance)); - - /* Initialize the structure, allocate RAM and attribute memory */ - V->Addr = Addr; - V->Range = Range; - memset (V->Regs, 0, sizeof (V->Regs)); - - /* Done, return the instance data */ - return V; -} - - - -static void VicDestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the data pointer */ - VicInstance* V = Data; - - /* Free the instance data */ - Sim->Free (V); -} - - - -static void VicWrite (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - VicInstance* V = Data; - - /* Check for a write outside our range */ - if (Offs >= sizeof (V->Regs)) { - Sim->Break ("Writing to invalid VIC register at $%04X", V->Addr+Offs); - } else { - - /* Do the write */ - V->Regs[Offs] = Val; - - /* Handle special registers */ - switch (Offs) { - case 32: - /* Exterior color */ - if (VRam) { - VRamDrawBorder (); - } - break; - case 33: - /* Background color #0 */ - if (VRam) { - VRamDrawAllChars (); - } - break; - - } - - /* Handle the event queue */ - if (VRam) { - VRamEventLoop (); - } - } -} - - - -static unsigned char VicRead (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - VicInstance* V = Data; - - /* Simulate the rasterline register */ - if (V->Regs[17] & 0x80) { - if (++V->Regs[18] == (312 & 0xFF)) { - V->Regs[17] &= 0x7F; - V->Regs[18] = 0; - } - } else { - if (++V->Regs[18] == 0) { - V->Regs[17] |= 0x80; - } - } - - /* Check for a read outside our range */ - if (Offs >= sizeof (V->Regs)) { - - Sim->Break ("Reading invalid VIC register at $%04X", V->Addr+Offs); - return 0xFF; - - } else { - - /* Do the read */ - return V->Regs[Offs]; - - } -} - - - -/*****************************************************************************/ -/* Video RAM */ -/*****************************************************************************/ - - - -static int VRamInitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* VRamCreateInstance (unsigned Addr, unsigned Range, void* CfgInfo) -/* Create a new chip instance */ -{ - char* Name; - FILE* F; - unsigned ColorDepth; - Colormap CM; - unsigned CIdx; - XSizeHints SizeHints; - XWMHints WMHints; - Cursor C; - - /* Allocate the instance data */ - VRamInstance* V = VRam = Sim->Malloc (sizeof (VRamInstance)); - - /* Remember a few settings */ - V->Addr = Addr; - V->Range = Range; - - /* Setup the window geometry */ - V->XTotal = 384; /* PAL */ - V->YTotal = 288; - V->XSize = 320; - V->YSize = 200; - V->XOffs = (V->XTotal - V->XSize) / 2; - V->YOffs = (V->YTotal - V->YSize) / 2; - - /* Setup the rectanges used to draw the exterior */ - V->Border[0].x = 0; - V->Border[0].y = 0; - V->Border[0].width = V->XTotal; - V->Border[0].height = V->YOffs; - V->Border[1].x = 0; - V->Border[1].y = V->YOffs + V->YSize; - V->Border[1].width = V->XTotal; - V->Border[1].height = V->YOffs; - V->Border[2].x = 0; - V->Border[2].y = V->YOffs; - V->Border[2].width = V->XOffs; - V->Border[2].height = V->YSize; - V->Border[3].x = V->XOffs + V->XSize; - V->Border[3].y = V->YOffs; - V->Border[3].width = V->XOffs; - V->Border[3].height = V->YSize; - - /* We must have a "file" attribute. Get it. */ - if (Sim->GetCfgStr (CfgInfo, "file", &Name) == 0) { - /* Attribute not found */ - Sim->Error ("Attribute `file' missing"); /* ### */ - } - - /* Open the file with the given name */ - F = fopen (Name, "rb"); - if (F == 0) { - Sim->Error ("Cannot open `%s': %s", Name, strerror (errno)); - } - - /* Read the file into the memory */ - if (fread (V->CharRom, 1, sizeof (V->CharRom), F) != sizeof (V->CharRom)) { - Sim->Warning ("Char ROM `%s' seems to be corrupt", Name); - } - - /* Close the file */ - fclose (F); - - /* Free the file name */ - Sim->Free (Name); - - /* Open the X display. */ - V->VicDisplay = XOpenDisplay (""); - if (V->VicDisplay == NULL) { - Sim->Error ("VRAM: Cannot open X display"); - } - - /* Get a screen */ - V->VicScreen = DefaultScreen (V->VicDisplay); - - /* Check the available colors. For now, we expect direct colors, so we - * will check for a color depth of at least 16. - */ - ColorDepth = XDefaultDepth (V->VicDisplay, V->VicScreen); - if (ColorDepth < 16) { - /* OOPS */ - Sim->Error ("VRAM: Need color display"); - } - - /* Get all needed colors */ - memcpy (V->Colors, VicColors, sizeof (V->Colors)); - CM = DefaultColormap (V->VicDisplay, V->VicScreen); - for (CIdx = 0; CIdx < VIC_COLOR_COUNT; CIdx++) { - if (XAllocColor (V->VicDisplay, CM, &V->Colors [CIdx]) == 0) { - Sim->Error ("VRAM: Cannot allocate color"); - } - } - - /* Set up the size hints structure */ - SizeHints.x = 0; - SizeHints.y = 0; - SizeHints.flags = PPosition | PSize | PMinSize | PMaxSize | PResizeInc; - SizeHints.width = V->XTotal; - SizeHints.height = V->YTotal; - SizeHints.min_width = V->XTotal; - SizeHints.min_height = V->YTotal; - SizeHints.max_width = V->XTotal; - SizeHints.max_height = V->YTotal; - SizeHints.width_inc = 0; - SizeHints.height_inc = 0; - WMHints.flags = InputHint; - WMHints.input = True; - - /* Create the window */ - V->VicWindow = XCreateSimpleWindow (V->VicDisplay, - DefaultRootWindow (V->VicDisplay), - SizeHints.x, - SizeHints.y, - SizeHints.width, - SizeHints.height, - 5, - V->Colors [VIC_WHITE].pixel, - V->Colors [VIC_BLACK].pixel); - - /* Set the standard window properties */ - XSetStandardProperties (V->VicDisplay, /* Display */ - V->VicWindow, /* Window */ - "sim65 VIC screen", /* Window name */ - "sim65 VIC screen", /* Icon name */ - None, /* Icon Pixmap */ - 0, /* argv */ - 0, /* argc */ - &SizeHints); /* Hints */ - XSetWMHints (V->VicDisplay, V->VicWindow, &WMHints); - - /* GC creation and initialization */ - V->VicGC = XCreateGC (V->VicDisplay, V->VicWindow, 0, 0); - - /* Set the cursor to show over the Vic window */ - C = XCreateFontCursor (V->VicDisplay, XC_pirate); - XDefineCursor (V->VicDisplay, V->VicWindow, C); - - /* Select input events */ - XSelectInput (V->VicDisplay, V->VicWindow, ExposureMask | StructureNotifyMask); - - /* Show the window */ - XMapRaised (V->VicDisplay, V->VicWindow); - - /* Handle events */ - VRamEventLoop (); - - /* Return the instance data */ - return V; -} - - - -static void VRamDestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Cast the data pointer */ - VRamInstance* V = Data; - - /* Free X resources */ - XUndefineCursor (V->VicDisplay, V->VicWindow); - XFreeGC (V->VicDisplay, V->VicGC); - XDestroyWindow (V->VicDisplay, V->VicWindow); - XCloseDisplay (V->VicDisplay); - - /* Clear the global pointer */ - VRam = 0; - - /* Free the instance data */ - Sim->Free (V); -} - - - -static void VRamWrite (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - VRamInstance* V = Data; - - /* Check the offset */ - if (Offs >= sizeof (V->Mem)) { - Sim->Break ("VRAM: Accessing invalid memory at $%06X", V->Addr + Offs); - return; - } - - /* Write the value */ - V->Mem[Offs] = Val; - - /* If this changes the visible part of the screen, schedule a redraw */ - if (Offs < 40*25) { - - /* Schedule a redraw */ - VRamDrawChar (Offs); - - /* Call the event loop */ - VRamEventLoop (); - } -} - - - -static unsigned char VRamRead (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - VRamInstance* V = Data; - - /* Check the offset */ - if (Offs >= sizeof (V->Mem)) { - Sim->Break ("VRAM: Accessing invalid memory at $%06X", V->Addr + Offs); - return 0xFF; - } else { - return V->Mem[Offs]; - } -} - - - -static void VRamDrawBorder (void) -/* Draw the complete border */ -{ - if (Vic) { - /* Set the border color */ - XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Vic->Regs[32]].pixel); - - /* Fill all rectangles that make the border */ - XFillRectangles (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC, - VRam->Border, sizeof (VRam->Border) / sizeof (VRam->Border[0])); - } -} - - - -static void VRamDrawChar (unsigned Offs) -/* Draw one character at the given position */ -{ - unsigned Row, Col; - XPoint Points[64]; - unsigned PCount; - unsigned Color; - - /* Get the character from the video RAM */ - unsigned char C = VRam->Mem[Offs]; - - /* Calculate the offset for the character data in the character ROM */ - unsigned char* D = VRam->CharRom + (C * 8); - - /* Calculate the coords for the output */ - unsigned X = VRam->XOffs + (Offs % 40) * 8; - unsigned Y = VRam->YOffs + (Offs / 40) * 8; - - /* Clear the character area with the background color */ - XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Vic->Regs[33]].pixel); - XFillRectangle (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC, X, Y, 8, 8); - - /* Set the character color */ - Color = CRam? CRam->Mem[Offs] & 0x0F : VIC_WHITE; - XSetForeground (VRam->VicDisplay, VRam->VicGC, VRam->Colors[Color].pixel); - - /* Draw the foreground pixels */ - PCount = 0; - for (Row = 0; Row < 8; ++Row) { - - /* Get next byte from char rom */ - unsigned Data = *D++; - - /* Make pixels from this byte */ - for (Col = 0; Col < 8; ++Col) { - if (Data & 0x80) { - /* Foreground pixel */ - Points[PCount].x = X + Col; - Points[PCount].y = Y + Row; - ++PCount; - } - Data <<= 1; - } - } - if (PCount) { - XDrawPoints (VRam->VicDisplay, VRam->VicWindow, VRam->VicGC, - Points, PCount, CoordModeOrigin); - } -} - - - -static void VRamDrawArea (unsigned X1, unsigned Y1, unsigned X2, unsigned Y2) -/* Update an area of the interior screen */ -{ - unsigned X, Y; - - /* Check if we have to draw anything */ - if (X2 < VRam->XOffs || Y2 < VRam->YOffs || - X1 >= VRam->XOffs + VRam->XSize || - Y1 >= VRam->YOffs + VRam->YSize) { - /* Completely outside */ - return; - } - - /* Make the coordinates relative to the interior */ - X1 -= VRam->XOffs; - Y1 -= VRam->YOffs; - X2 -= VRam->XOffs; - Y2 -= VRam->YOffs; - - /* Loop updating characters */ - for (Y = Y1; Y <= Y2; Y += 8) { - for (X = X1; X <= X2; X += 8) { - VRamDrawChar ((Y / 8) * 40 + (X / 8)); - } - } -} - - - -static void VRamDrawAllChars (void) -/* Redraw the complete interior screen */ -{ - unsigned I; - for (I = 0; I < 25*40; ++I) { - VRamDrawChar (I); - } -} - - - -static void VRamEventLoop (void) -/* Get all waiting events and handle them */ -{ - unsigned X1, Y1, X2, Y2; - - /* Read input events */ - while (XEventsQueued (VRam->VicDisplay, QueuedAfterFlush) != 0) { - - /* Read an event */ - XEvent Event; - XNextEvent (VRam->VicDisplay, &Event); - - switch (Event.type) { - - case Expose: - /* Calculate the area to redraw, then update the screen */ - X1 = Event.xexpose.x; - Y1 = Event.xexpose.y; - X2 = Event.xexpose.x + Event.xexpose.width - 1; - Y2 = Event.xexpose.y + Event.xexpose.height - 1; - if (X1 < VRam->XOffs || X2 > VRam->XOffs + VRam->XSize || - Y1 < VRam->YOffs || Y2 > VRam->YOffs + VRam->YSize) { - /* Update the border */ - VRamDrawBorder (); - } - VRamDrawArea (X1, Y1, X2, Y2); - break; - - case MappingNotify: - XRefreshKeyboardMapping (&Event.xmapping); - break; - - } - } - - /* Flush the outgoing event queue */ - XFlush (VRam->VicDisplay); -} - - - -/*****************************************************************************/ -/* Color RAM */ -/*****************************************************************************/ - - - -static int CRamInitChip (const struct SimData* Data) -/* Initialize the chip, return an error code */ -{ - /* Remember the pointer */ - Sim = Data; - - /* Always successful */ - return 0; -} - - - -static void* CRamCreateInstance (unsigned Addr, unsigned Range, - void* CfgInfo attribute ((unused))) -/* Create a new chip instance */ -{ - /* Allocate the instance data */ - CRamInstance* C = CRam = Sim->Malloc (sizeof (CRamInstance)); - - /* Remember a few settings */ - C->Addr = Addr; - C->Range = Range; - - /* Clear the color RAM memory */ - memset (C->Mem, 0x00, sizeof (C->Mem)); - - /* Return the instance data */ - return C; -} - - - -static void CRamDestroyInstance (void* Data) -/* Destroy a chip instance */ -{ - /* Clear the global pointer */ - CRam = 0; - - /* Free the instance data */ - Sim->Free (Data); -} - - - -static void CRamWrite (void* Data, unsigned Offs, unsigned char Val) -/* Write user data */ -{ - /* Cast the data pointer */ - CRamInstance* C = Data; - - /* Check the offset */ - if (Offs >= sizeof (C->Mem)) { - Sim->Break ("CRAM: Accessing invalid memory at $%06X", C->Addr + Offs); - return; - } - - /* Write the value */ - C->Mem[Offs] = Val & 0x0F; - - /* If this changes the visible part of the screen, schedule a redraw */ - if (Offs < 40*25) { - - /* Schedule a redraw */ - VRamDrawChar (Offs); - - /* Call the event loop */ - VRamEventLoop (); - } -} - - - -static unsigned char CRamRead (void* Data, unsigned Offs) -/* Read user data */ -{ - /* Cast the data pointer */ - CRamInstance* C = Data; - - /* Check the offset */ - if (Offs >= sizeof (C->Mem)) { - Sim->Break ("CRAM: Accessing invalid memory at $%06X", C->Addr + Offs); - return 0xFF; - } else { - return C->Mem[Offs] | 0xF0; - } -} - - - diff --git a/src/sim65/config.c b/src/sim65/config.c deleted file mode 100644 index f595361fc..000000000 --- a/src/sim65/config.c +++ /dev/null @@ -1,393 +0,0 @@ -/*****************************************************************************/ -/* */ -/* config.c */ -/* */ -/* Configuration file parsing for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include - -/* common */ -#include "check.h" -#include "bitops.h" -#include "print.h" -#include "strutil.h" -#include "xmalloc.h" - -/* sim65 */ -#include "addrspace.h" -#include "cfgdata.h" -#include "chip.h" -#include "error.h" -#include "global.h" -#include "location.h" -#include "scanner.h" -#include "config.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name) -/* Check if the item is already defined. Print an error if so. If not, set - * the marker that we have a definition now. - */ -{ - if (*Flags & Mask) { - CfgError ("%s is already defined", Name); - } - *Flags |= Mask; -} - - - -static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name) -/* Check that a mandatory attribute was given */ -{ - if ((Attr & Mask) == 0) { - CfgError ("%s attribute is missing", Name); - } -} - - - -static void ParseCPU (void) -/* Parse a CPU section */ -{ - static const IdentTok Attributes [] = { - { "TYPE", CFGTOK_TYPE }, - { "ADDRSPACE", CFGTOK_ADDRSPACE }, - }; - - enum { - atNone = 0x0000, - atType = 0x0001, - atAddrSpace = 0x0002 - }; - unsigned Attr = 0; - unsigned long Size = 0; - - - while (CfgTok == CFGTOK_IDENT) { - - cfgtok_t AttrTok; - CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute"); - AttrTok = CfgTok; - - /* An optional assignment follows */ - CfgNextTok (); - CfgOptionalAssign (); - - /* Check which attribute was given */ - switch (AttrTok) { - - case CFGTOK_TYPE: - FlagAttr (&Attr, atType, "TYPE"); - CfgAssureIdent (); - /* ### */ - break; - - case CFGTOK_ADDRSPACE: - FlagAttr (&Attr, atAddrSpace, "ADDRSPACE"); - CfgAssureInt (); - CfgRangeCheck (0x1000, 0x1000000); - Size = CfgIVal; - break; - - default: - FAIL ("Unexpected attribute token"); - - } - - /* Skip the attribute value and an optional comma */ - CfgNextTok (); - CfgOptionalComma (); - } - - /* Must have some attributes */ - AttrCheck (Attr, atType, "TYPE"); - AttrCheck (Attr, atAddrSpace, "ADDRSPACE"); - - /* Create the system using the specified CPU */ - System = NewSystem (NewCPU ("6502", Size)); - - /* Skip the semicolon */ - CfgConsumeSemi (); -} - - - -static void ParseAddrSpace (void) -/* Parse a ADDRSPACE section */ -{ - unsigned I; - - /* CPU must be defined before the address space */ - if (System == 0) { - CfgError ("CPU must be defined before address space definitions"); - } - - /* Parse addresses */ - while (CfgTok == CFGTOK_INTCON) { - - Location* L; - - /* Remember the start address and skip it */ - unsigned long Start = CfgIVal; - CfgNextTok (); - - /* .. must follow */ - CfgConsume (CFGTOK_DOTDOT, "`..' expected"); - - /* End address must follow and must be greater than start */ - CfgAssureInt (); - if (CfgIVal < Start) { - CfgError ("Start address must be greater than end address"); - } - - /* Create a new location and add it to the list */ - L = NewLocation (Start, CfgIVal); - CollAppend (&Locations, L); - - /* Skip the end address and the following colon */ - CfgNextTok (); - CfgConsumeColon (); - - /* Parse attributes terminated by a semicolon */ - while (CfgTok == CFGTOK_IDENT) { - - /* Generate a new attribute with the given name, then skip it */ - CfgData* D = NewCfgData (); - CfgNextTok (); - - /* An optional assignment follows */ - CfgOptionalAssign (); - - /* Check and assign the attribute value */ - switch (CfgTok) { - - case CFGTOK_INTCON: - D->Type = CfgDataNumber; - D->V.IVal = CfgIVal; - break; - - case CFGTOK_STRCON: - D->Type = CfgDataString; - D->V.SVal = xstrdup (CfgSVal); - break; - - case CFGTOK_IDENT: - D->Type = CfgDataId; - D->V.SVal = xstrdup (CfgSVal); - break; - - default: - CfgError ("Invalid attribute type"); - } - - /* Add the attribute to the location */ - CollAppend (&L->Attributes, D); - - /* Skip the attribute value and an optional comma */ - CfgNextTok (); - CfgOptionalComma (); - } - - /* Skip the semicolon */ - CfgConsumeSemi (); - } - - /* Sort all memory locations */ - LocationSort (&Locations); - - /* Check the locations for overlaps and other problems */ - LocationCheck (&Locations); - - /* Now create the chip instances. Since we can only mirror existing chips, - * we will first create all real chips and the mirrors in a second run. - */ - for (I = 0; I < CollCount (&Locations); ++I) { - - int Index; - CfgData* D; - unsigned Range; /* Address range for this chip */ - ChipInstance* CI; - - /* Get this location */ - Location* L = CollAtUnchecked (&Locations, I); - - /* Skip mirrors */ - if (LocationIsMirror (L)) { - continue; - } - - /* The chip must have an attribute "name" of type string */ - Index = LocationGetAttr (L, "name"); - D = CollAt (&L->Attributes, Index); - CfgDataCheckType (D, CfgDataString); - - /* Remove the "name" attribute from the attribute list */ - CollDelete (&L->Attributes, Index); - - /* Create the chip instance for the address range */ - Range = L->End - L->Start + 1; - CI = NewChipInstance (D->V.SVal, L->Start, Range, &L->Attributes); - - /* Delete the "name" attribute */ - FreeCfgData (D); - - /* Assign the chip instance to address space */ - ASAssignChip (CPUInstance->AS, CI, L->Start, Range); - } - - /* Create the mirrors */ - for (I = 0; I < CollCount (&Locations); ++I) { - - const CfgData* D; - unsigned MirrorAddr; /* Mirror address */ - unsigned Range; /* Address range for this chip */ - unsigned Offs; /* Offset of the mirror */ - const ChipInstance* CI; /* Original chip instance */ - ChipInstance* MCI; /* Mirrored chip instance */ - - /* Get this location */ - const Location* L = CollAtUnchecked (&Locations, I); - - /* Skip non mirrors */ - if (!LocationIsMirror (L)) { - continue; - } - - /* Calculate the address range */ - Range = L->End - L->Start; - - /* Get the mirror address */ - D = CollConstAt (&L->Attributes, 0); - MirrorAddr = (unsigned) D->V.IVal; - - /* For simplicity, get the chip instance we're mirroring from the - * memory, instead of searching for the range in the list. - */ - CI = ASGetChip (MirrorAddr); - if (CI == 0) { - /* We are mirroring an unassigned address */ - Error ("%s(%u): Mirroring an unassigned address", - CfgGetName (), L->Line); - } - - /* Make sure we're mirroring the correct chip */ - CHECK (MirrorAddr >= CI->Addr && MirrorAddr < CI->Addr + CI->Size); - - /* Calculate the offset of the mirror */ - Offs = MirrorAddr - CI->Addr; - - /* Check if the mirror range is ok */ - if (Offs + Range > CI->Size) { - Error ("%s(%u): Mirror range is too large", CfgGetName (), L->Line); - } - - /* Clone the chip instance for the new location */ - MCI = MirrorChipInstance (CI, L->Start - Offs); - - /* Assign the chip instance to address space */ - ASAssignChip (CPUInstance->AS, MCI, L->Start, Range); - } -} - - - -static void ParseConfig (void) -/* Parse the config file */ -{ - static const IdentTok BlockNames [] = { - { "ADDRSPACE", CFGTOK_ADDRSPACE }, - { "CPU", CFGTOK_CPU }, - }; - cfgtok_t BlockTok; - - do { - - /* Read the block ident */ - CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames), "Block identifier"); - BlockTok = CfgTok; - CfgNextTok (); - - /* Expected a curly brace */ - CfgConsume (CFGTOK_LCURLY, "`{' expected"); - - /* Read the block */ - switch (BlockTok) { - - case CFGTOK_ADDRSPACE: - ParseAddrSpace (); - break; - - case CFGTOK_CPU: - ParseCPU (); - break; - - default: - FAIL ("Unexpected block token"); - - } - - /* Skip closing brace */ - CfgConsumeRCurly (); - - } while (CfgTok != CFGTOK_EOF); -} - - - -void CfgRead (void) -/* Read the configuration */ -{ - /* If we have a config name given, open the file, otherwise we will read - * from a buffer. - */ - CfgOpenInput (); - - /* Parse the file */ - ParseConfig (); - - /* Close the input file */ - CfgCloseInput (); -} - - - diff --git a/src/sim65/cpucore.c b/src/sim65/cpucore.c deleted file mode 100644 index 87f349ec7..000000000 --- a/src/sim65/cpucore.c +++ /dev/null @@ -1,75 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cpucore.c */ -/* */ -/* CPU definition for the simulator */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include - -/* common */ -#include "xmalloc.h" - -/* sim65 */ -#include "cpucore.h" -#include "error.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -CPUCore* NewCPUCore (const char* Name, unsigned AddrSpaceSize) -/* Create and return a new CPU including it's address space */ -{ - CPUCore* C; - - /* Make sure this is a 6502 CPU for now */ - if (strcmp (Name, "6502") != 0) { - Error ("Unknown CPU type `%s'", Name); - } - - /* Allocate memory */ - C = xmalloc (sizeof (*C)); - - /* Initialize the data */ - C->Handle = 0; /* ### */ - C->AddressSize = AddrSpaceSize; - - /* Return the new CPU core */ - return C; -} - - - diff --git a/src/sim65/cpucore.h b/src/sim65/cpucore.h deleted file mode 100644 index b312f56e5..000000000 --- a/src/sim65/cpucore.h +++ /dev/null @@ -1,83 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cpucore.h */ -/* */ -/* CPU definition for the simulator */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CPUCORE_H -#define CPUCORE_H - - - -/* sim65 */ -#include "addrspace.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* CPU core structure */ -typedef struct CPUCore CPUCore; -struct CPUCore { - void* Handle; /* Pointer to shared lib handle */ - unsigned AddressSize; /* Size of the address space */ - - /* Callback functions */ - - - -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -CPUCore* NewCPUCore (const char* Name, unsigned AddrSpaceSize); -/* Create and return a new CPU including it's address space */ - - - -/* End of cpucore.h */ - -#endif - - - - diff --git a/src/sim65/cpudata.h b/src/sim65/cpudata.h deleted file mode 100644 index c060fe3f0..000000000 --- a/src/sim65/cpudata.h +++ /dev/null @@ -1,97 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cpudata.h */ -/* */ -/* CPU data passed from the CPU plugins */ -/* */ -/* */ -/* */ -/* (C) 2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CPUDATA_H -#define CPUDATA_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Version defines */ -#define CPUDATA_VER_MAJOR 1U -#define CPUDATA_VER_MINOR 0U - -/* Forwards */ -struct SimData; - -/* CPUData structure */ -typedef struct CPUData CPUData; -struct CPUData { - const char* CPUName; /* Name of the chip */ - unsigned MajorVersion; /* Version information */ - unsigned MinorVersion; - - /* -- Exported functions -- */ - - void (*Init) (const struct SimData* Data); - /* Initialize the CPU module */ - - void* (*CreateInstance) (void* CfgInfo); - /* Create an instance of the CPU. Return the instance data pointer */ - - void (*DestroyInstance) (void* Data); - /* Destroy an instance of the CPU */ - - void (*Reset) (void* Data); - /* Generate a CPU RESET */ - - void (*IRQRequest) (void* Data); - /* Generate an IRQ */ - - void (*NMIRequest) (void* Data); - /* Generate an NMI */ - - unsigned (*ExecuteInsn) (void* Data); - /* Execute one CPU instruction. Return the number of clock cycles for the - * executed instruction. - */ - - unsigned long (*GetCycles) (void* Data); - /* Return the total number of clock cycles executed */ -}; - - - -/* End of cpudata.h */ - -#endif - - - diff --git a/src/sim65/cpus/6502.c b/src/sim65/cpus/6502.c deleted file mode 100644 index 5eaeb659c..000000000 --- a/src/sim65/cpus/6502.c +++ /dev/null @@ -1,3053 +0,0 @@ -/*****************************************************************************/ -/* */ -/* 6502.c */ -/* */ -/* CPU core for the 6502 */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include - -/* common */ -#include "abend.h" -#include "attrib.h" -#include "print.h" -#include "strbuf.h" - -/* sim65 */ -#include "cpuif.h" - - - -/*****************************************************************************/ -/* Forwards */ -/*****************************************************************************/ - - - -static void Init (const SimData* D); -/* Initialize the module */ - -static void* Create6502Instance (void* CfgInfo); -/* Create an instance of a 6502 CPU */ - -static void* Create65C02Instance (void* CfgInfo); -/* Create an instance of a 65C02 CPU */ - -static void DestroyInstance (void* Instance); -/* Destroy an instance of a CPU */ - -static void IRQRequest (void* Data); -/* Generate an IRQ */ - -static void NMIRequest (void* Data); -/* Generate an NMI */ - -static void Reset (void* Data); -/* Generate a CPU RESET */ - -static unsigned ExecuteInsn (void* Data); -/* Execute one CPU instruction */ - -static unsigned long GetCycles (void* Data); -/* Return the total number of cycles executed */ - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* The SimData pointer we get when InitChip is called */ -static const SimData* Sim; - -/* 6502 CPU registers */ -typedef struct CPURegs CPURegs; -struct CPURegs { - unsigned AC; /* Accumulator */ - unsigned XR; /* X register */ - unsigned YR; /* Y register */ - unsigned ZR; /* Z register */ - unsigned SR; /* Status register */ - unsigned SP; /* Stackpointer */ - unsigned PC; /* Program counter */ -}; - -/* Status register bits */ -#define CF 0x01 /* Carry flag */ -#define ZF 0x02 /* Zero flag */ -#define IF 0x04 /* Interrupt flag */ -#define DF 0x08 /* Decimal flag */ -#define BF 0x10 /* Break flag */ -#define OF 0x40 /* Overflow flag */ -#define SF 0x80 /* Sign flag */ - -/* Type of an opcode handler function */ -struct CPUInstance; -typedef void (*OPFunc) (struct CPUInstance* D); - - - -/* Control data passed to the main program */ -static const struct CPUData CData[] = { - { - "6502", /* Name of the CPU */ - CPUDATA_VER_MAJOR, /* Version information */ - CPUDATA_VER_MINOR, - - /* -- Exported functions -- */ - Init, - Create6502Instance, - DestroyInstance, - Reset, - IRQRequest, - NMIRequest, - ExecuteInsn, - GetCycles - },{ - "65C02", /* Name of the CPU */ - CPUDATA_VER_MAJOR, /* Version information */ - CPUDATA_VER_MINOR, - - /* -- Exported functions -- */ - Init, - Create65C02Instance, - DestroyInstance, - Reset, - IRQRequest, - NMIRequest, - ExecuteInsn, - GetCycles - }, -}; - - -/* CPU instance data */ -typedef struct CPUInstance CPUInstance; -struct CPUInstance { - const OPFunc* Handlers; /* Table with opcode handlers */ - - CPURegs Regs; /* The CPU registers */ - - unsigned Cycles; /* Cycles for the current insn */ - unsigned long TotalCycles; /* Total number of CPU cycles exec'd */ - - unsigned StackPage; /* Allows to move the stack page */ - - unsigned HaveNMIRequest; /* NMI request active */ - unsigned HaveIRQRequest; /* IRQ request active */ - unsigned CPUHalted; /* CPU is halted */ -}; - - -/*****************************************************************************/ -/* Helper functions and macros */ -/*****************************************************************************/ - - - -/* Return the flags as a boolean value (0/1) */ -#define GET_CF() ((D->Regs.SR & CF) != 0) -#define GET_ZF() ((D->Regs.SR & ZF) != 0) -#define GET_IF() ((D->Regs.SR & IF) != 0) -#define GET_DF() ((D->Regs.SR & DF) != 0) -#define GET_BF() ((D->Regs.SR & BF) != 0) -#define GET_OF() ((D->Regs.SR & OF) != 0) -#define GET_SF() ((D->Regs.SR & SF) != 0) - -/* Set the flags. The parameter is a boolean flag that says if the flag should be - * set or reset. - */ -#define SET_CF(f) do { if (f) { D->Regs.SR |= CF; } else { D->Regs.SR &= ~CF; } } while (0) -#define SET_ZF(f) do { if (f) { D->Regs.SR |= ZF; } else { D->Regs.SR &= ~ZF; } } while (0) -#define SET_IF(f) do { if (f) { D->Regs.SR |= IF; } else { D->Regs.SR &= ~IF; } } while (0) -#define SET_DF(f) do { if (f) { D->Regs.SR |= DF; } else { D->Regs.SR &= ~DF; } } while (0) -#define SET_BF(f) do { if (f) { D->Regs.SR |= BF; } else { D->Regs.SR &= ~BF; } } while (0) -#define SET_OF(f) do { if (f) { D->Regs.SR |= OF; } else { D->Regs.SR &= ~OF; } } while (0) -#define SET_SF(f) do { if (f) { D->Regs.SR |= SF; } else { D->Regs.SR &= ~SF; } } while (0) - -/* Special test and set macros. The meaning of the parameter depends on the - * actual flag that should be set or reset. - */ -#define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0) -#define TEST_SF(v) SET_SF (((v) & 0x80) != 0) -#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0) - -/* Program counter halves */ -#define PCL (D->Regs.PC & 0xFF) -#define PCH ((D->Regs.PC >> 8) & 0xFF) - -/* Stack operations */ -#define PUSH(Val) MemWriteByte (D->StackPage + D->Regs.SP--, Val) -#define POP() MemReadByte (D->StackPage + ++D->Regs.SP) - -/* Test for page cross */ -#define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100) - -/* #imm */ -#define AC_OP_IMM(op) \ - D->Cycles = 2; \ - D->Regs.AC = D->Regs.AC op MemReadByte (D->Regs.PC+1); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* zp */ -#define AC_OP_ZP(op) \ - D->Cycles = 3; \ - D->Regs.AC = D->Regs.AC op MemReadByte (MemReadByte (D->Regs.PC+1));\ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* zp,x */ -#define AC_OP_ZPX(op) \ - unsigned char ZPAddr; \ - D->Cycles = 4; \ - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; \ - D->Regs.AC = D->Regs.AC op MemReadByte (ZPAddr); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* zp,y */ -#define AC_OP_ZPY(op) \ - unsigned char ZPAddr; \ - D->Cycles = 4; \ - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.YR; \ - D->Regs.AC = D->Regs.AC op MemReadByte (ZPAddr); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* abs */ -#define AC_OP_ABS(op) \ - unsigned Addr; \ - D->Cycles = 4; \ - Addr = MemReadWord (D->Regs.PC+1); \ - D->Regs.AC = D->Regs.AC op MemReadByte (Addr); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 3 - -/* abs,x */ -#define AC_OP_ABSX(op) \ - unsigned Addr; \ - D->Cycles = 4; \ - Addr = MemReadWord (D->Regs.PC+1); \ - if (PAGE_CROSS (Addr, D->Regs.XR)) { \ - ++D->Cycles; \ - } \ - D->Regs.AC = D->Regs.AC op MemReadByte (Addr + D->Regs.XR); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 3 - -/* abs,y */ -#define AC_OP_ABSY(op) \ - unsigned Addr; \ - D->Cycles = 4; \ - Addr = MemReadWord (D->Regs.PC+1); \ - if (PAGE_CROSS (Addr, D->Regs.YR)) { \ - ++D->Cycles; \ - } \ - D->Regs.AC = D->Regs.AC op MemReadByte (Addr + D->Regs.YR); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 3 - -/* (zp,x) */ -#define AC_OP_ZPXIND(op) \ - unsigned char ZPAddr; \ - unsigned Addr; \ - D->Cycles = 6; \ - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; \ - Addr = MemReadZPWord (ZPAddr); \ - D->Regs.AC = D->Regs.AC op MemReadByte (Addr); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* (zp),y */ -#define AC_OP_ZPINDY(op) \ - unsigned char ZPAddr; \ - unsigned Addr; \ - D->Cycles = 5; \ - ZPAddr = MemReadByte (D->Regs.PC+1); \ - Addr = MemReadZPWord (ZPAddr) + D->Regs.YR; \ - D->Regs.AC = D->Regs.AC op MemReadByte (Addr); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - D->Regs.PC += 2 - -/* ADC */ -#define ADC(v) \ - do { \ - unsigned old = D->Regs.AC; \ - unsigned rhs = (v & 0xFF); \ - if (GET_DF ()) { \ - unsigned lo; \ - int res; \ - lo = (old & 0x0F) + (rhs & 0x0F) + GET_CF (); \ - if (lo >= 0x0A) { \ - lo = ((lo + 0x06) & 0x0F) + 0x10; \ - } \ - D->Regs.AC = (old & 0xF0) + (rhs & 0xF0) + lo; \ - res = (signed char)(old & 0xF0) + \ - (signed char)(rhs & 0xF0) + \ - (signed char)lo; \ - TEST_ZF (old + rhs + GET_CF ()); \ - TEST_SF (D->Regs.AC); \ - if (D->Regs.AC >= 0xA0) { \ - D->Regs.AC += 0x60; \ - } \ - TEST_CF (D->Regs.AC); \ - SET_OF ((res < -128) || (res > 127)); \ - } else { \ - D->Regs.AC += rhs + GET_CF (); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - TEST_CF (D->Regs.AC); \ - SET_OF (!((old ^ rhs) & 0x80) && \ - ((old ^ D->Regs.AC) & 0x80)); \ - D->Regs.AC &= 0xFF; \ - } \ - } while (0) - -/* branches */ -#define BRANCH(cond) \ - D->Cycles = 2; \ - if (cond) { \ - signed char Offs; \ - unsigned char OldPCH; \ - ++D->Cycles; \ - Offs = (signed char) MemReadByte (D->Regs.PC+1); \ - OldPCH = PCH; \ - D->Regs.PC += 2 + (int) Offs; \ - if (PCH != OldPCH) { \ - ++D->Cycles; \ - } \ - } else { \ - D->Regs.PC += 2; \ - } - -/* compares */ -#define CMP(v1, v2) \ - do { \ - unsigned Result = v1 - v2; \ - TEST_ZF (Result & 0xFF); \ - TEST_SF (Result); \ - SET_CF (Result <= 0xFF); \ - } while (0) - - -/* ROL */ -#define ROL(Val) \ - Val <<= 1; \ - if (GET_CF ()) { \ - Val |= 0x01; \ - } \ - TEST_ZF (Val); \ - TEST_SF (Val); \ - TEST_CF (Val) - -/* ROR */ -#define ROR(Val) \ - if (GET_CF ()) { \ - Val |= 0x100; \ - } \ - SET_CF (Val & 0x01); \ - Val >>= 1; \ - TEST_ZF (Val); \ - TEST_SF (Val) - -/* SBC */ -#define SBC(v) \ - do { \ - unsigned old = D->Regs.AC; \ - unsigned rhs = (v & 0xFF); \ - if (GET_DF ()) { \ - unsigned lo; \ - int res; \ - lo = (old & 0x0F) - (rhs & 0x0F) + GET_CF () - 1; \ - if (lo & 0x80) { \ - lo = ((lo - 0x06) & 0x0F) - 0x10; \ - } \ - D->Regs.AC = (old & 0xF0) - (rhs & 0xF0) + lo; \ - if (D->Regs.AC & 0x80) { \ - D->Regs.AC -= 0x60; \ - } \ - res = D->Regs.AC - rhs + (!GET_CF ()); \ - TEST_ZF (res); \ - TEST_SF (res); \ - SET_CF (res <= 0xFF); \ - SET_OF (((old^rhs) & (old^res) & 0x80)); \ - } else { \ - D->Regs.AC -= rhs - (!GET_CF ()); \ - TEST_ZF (D->Regs.AC); \ - TEST_SF (D->Regs.AC); \ - SET_CF (D->Regs.AC <= 0xFF); \ - SET_OF (((old^rhs) & (old^D->Regs.AC) & 0x80)); \ - D->Regs.AC &= 0xFF; \ - } \ - } while (0) - - - -static unsigned char MemReadByte (unsigned Addr) -/* Read a byte from a memory location */ -{ - return Sim->Read (Addr); -} - - - -static unsigned MemReadWord (unsigned Addr) -/* Read a word from a memory location */ -{ - unsigned W = Sim->Read (Addr); - return (W | (Sim->Read (Addr + 1) << 8)); -} - - - -static unsigned MemReadZPWord (unsigned Addr) -/* Read a word from the zero page. This function differs from ReadMemW in that - * the read will always be in the zero page, even in case of an address - * overflow. - */ -{ - unsigned W = Sim->Read (Addr & 0xFF); - return (W | (Sim->Read ((Addr + 1) & 0xFF) << 8)); -} - - - -static void MemWriteByte (unsigned Addr, unsigned char Val) -/* Write a byte to a memory location */ -{ - Sim->Write (Addr, Val); -} - - - -/*****************************************************************************/ -/* CPUInstance */ -/*****************************************************************************/ - - - -static CPUInstance* NewCPUInstance (const OPFunc FuncTable[256], void* CfgInfo) -/* Create and return a new CPU instance struct */ -{ - /* Allocate memory */ - CPUInstance* D = Sim->Malloc (sizeof (*D)); - - /* Initialize the fields */ - D->Handlers = FuncTable; /* Table with opcode handlers */ - D->StackPage = 0x100; /* Allows to move the stack page */ - D->HaveNMIRequest = 0; /* NMI request active */ - D->HaveIRQRequest = 0; /* IRQ request active */ - D->CPUHalted = 0; /* CPU is halted */ - - /* Return the new struct */ - return D; -} - - - -static void DeleteCPUInstance (CPUInstance* Instance) -/* Delete a CPU instance */ -{ - /* Just free the memory */ - Sim->Free (Instance); -} - - - -/*****************************************************************************/ -/* Opcode handling functions */ -/*****************************************************************************/ - - - -static void OPC_Illegal (CPUInstance* D) -{ - Sim->Warning ("Illegal opcode $%02X at address $%04X\n", - MemReadByte (D->Regs.PC), D->Regs.PC); -} - - - -static void OPC_6502_00 (CPUInstance* D) -/* Opcode $00: BRK */ -{ - D->Cycles = 7; - D->Regs.PC += 2; - SET_BF (1); - PUSH (PCH); - PUSH (PCL); - PUSH (D->Regs.SR); - SET_IF (1); - D->Regs.PC = MemReadWord (0xFFFE); -} - - - -static void OPC_6502_01 (CPUInstance* D) -/* Opcode $01: ORA (ind,x) */ -{ - AC_OP_ZPXIND (|); -} - - - -static void OPC_6502_05 (CPUInstance* D) -/* Opcode $05: ORA zp */ -{ - AC_OP_ZP (|); -} - - - -static void OPC_6502_06 (CPUInstance* D) -/* Opcode $06: ASL zp */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr) << 1; - MemWriteByte (ZPAddr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - D->Regs.PC += 2; -} - - - -static void OPC_6502_08 (CPUInstance* D) -/* Opcode $08: PHP */ -{ - D->Cycles = 3; - PUSH (D->Regs.SR & ~BF); - D->Regs.PC += 1; -} - - - -static void OPC_6502_09 (CPUInstance* D) -/* Opcode $09: ORA #imm */ -{ - AC_OP_IMM (|); -} - - - -static void OPC_6502_0A (CPUInstance* D) -/* Opcode $0A: ASL a */ -{ - D->Cycles = 2; - D->Regs.AC <<= 1; - TEST_ZF (D->Regs.AC & 0xFF); - TEST_SF (D->Regs.AC); - SET_CF (D->Regs.AC & 0x100); - D->Regs.AC &= 0xFF; - D->Regs.PC += 1; -} - - - -static void OPC_6502_0D (CPUInstance* D) -/* Opcode $0D: ORA abs */ -{ - AC_OP_ABS (|); -} - - - -static void OPC_6502_0E (CPUInstance* D) -/* Opcode $0E: ALS abs */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr) << 1; - MemWriteByte (Addr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - D->Regs.PC += 3; -} - - - -static void OPC_6502_10 (CPUInstance* D) -/* Opcode $10: BPL */ -{ - BRANCH (!GET_SF ()); -} - - - -static void OPC_6502_11 (CPUInstance* D) -/* Opcode $11: ORA (zp),y */ -{ - AC_OP_ZPINDY (|); -} - - - -static void OPC_6502_15 (CPUInstance* D) -/* Opcode $15: ORA zp,x */ -{ - AC_OP_ZPX (|); -} - - - -static void OPC_6502_16 (CPUInstance* D) -/* Opcode $16: ASL zp,x */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr) << 1; - MemWriteByte (ZPAddr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - D->Regs.PC += 2; -} - - - -static void OPC_6502_18 (CPUInstance* D) -/* Opcode $18: CLC */ -{ - D->Cycles = 2; - SET_CF (0); - D->Regs.PC += 1; -} - - - -static void OPC_6502_19 (CPUInstance* D) -/* Opcode $19: ORA abs,y */ -{ - AC_OP_ABSY (|); -} - - - -static void OPC_6502_1D (CPUInstance* D) -/* Opcode $1D: ORA abs,x */ -{ - AC_OP_ABSX (|); -} - - - -static void OPC_6502_1E (CPUInstance* D) -/* Opcode $1E: ASL abs,x */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 7; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr) << 1; - MemWriteByte (Addr, (unsigned char) Val); - TEST_ZF (Val & 0xFF); - TEST_SF (Val); - SET_CF (Val & 0x100); - D->Regs.PC += 3; -} - - - -static void OPC_6502_20 (CPUInstance* D) -/* Opcode $20: JSR */ -{ - unsigned Addr; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - D->Regs.PC += 2; - PUSH (PCH); - PUSH (PCL); - D->Regs.PC = Addr; -} - - - -static void OPC_6502_21 (CPUInstance* D) -/* Opcode $21: AND (zp,x) */ -{ - AC_OP_ZPXIND (&); -} - - - -static void OPC_6502_24 (CPUInstance* D) -/* Opcode $24: BIT zp */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & D->Regs.AC) == 0); - D->Regs.PC += 2; -} - - - -static void OPC_6502_25 (CPUInstance* D) -/* Opcode $25: AND zp */ -{ - AC_OP_ZP (&); -} - - - -static void OPC_6502_26 (CPUInstance* D) -/* Opcode $26: ROL zp */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr); - ROL (Val); - MemWriteByte (ZPAddr, Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_28 (CPUInstance* D) -/* Opcode $28: PLP */ -{ - D->Cycles = 4; - D->Regs.SR = (POP () & ~BF); - D->Regs.PC += 1; -} - - - -static void OPC_6502_29 (CPUInstance* D) -/* Opcode $29: AND #imm */ -{ - AC_OP_IMM (&); -} - - - -static void OPC_6502_2A (CPUInstance* D) -/* Opcode $2A: ROL a */ -{ - D->Cycles = 2; - ROL (D->Regs.AC); - D->Regs.AC &= 0xFF; - D->Regs.PC += 1; -} - - - -static void OPC_6502_2C (CPUInstance* D) -/* Opcode $2C: BIT abs */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 4; - Addr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (Addr); - SET_SF (Val & 0x80); - SET_OF (Val & 0x40); - SET_ZF ((Val & D->Regs.AC) == 0); - D->Regs.PC += 3; -} - - - -static void OPC_6502_2D (CPUInstance* D) -/* Opcode $2D: AND abs */ -{ - AC_OP_ABS (&); -} - - - -static void OPC_6502_2E (CPUInstance* D) -/* Opcode $2E: ROL abs */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr); - ROL (Val); - MemWriteByte (Addr, Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_30 (CPUInstance* D) -/* Opcode $30: BMI */ -{ - BRANCH (GET_SF ()); -} - - - -static void OPC_6502_31 (CPUInstance* D) -/* Opcode $31: AND (zp),y */ -{ - AC_OP_ZPINDY (&); -} - - - -static void OPC_6502_35 (CPUInstance* D) -/* Opcode $35: AND zp,x */ -{ - AC_OP_ZPX (&); -} - - - -static void OPC_6502_36 (CPUInstance* D) -/* Opcode $36: ROL zp,x */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr); - ROL (Val); - MemWriteByte (ZPAddr, Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_38 (CPUInstance* D) -/* Opcode $38: SEC */ -{ - D->Cycles = 2; - SET_CF (1); - D->Regs.PC += 1; -} - - - -static void OPC_6502_39 (CPUInstance* D) -/* Opcode $39: AND abs,y */ -{ - AC_OP_ABSY (&); -} - - - -static void OPC_6502_3D (CPUInstance* D) -/* Opcode $3D: AND abs,x */ -{ - AC_OP_ABSX (&); -} - - - -static void OPC_6502_3E (CPUInstance* D) -/* Opcode $3E: ROL abs,x */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 7; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr); - ROL (Val); - MemWriteByte (Addr, Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_40 (CPUInstance* D) -/* Opcode $40: RTI */ -{ - D->Cycles = 6; - D->Regs.SR = POP (); - D->Regs.PC = POP (); /* PCL */ - D->Regs.PC |= (POP () << 8); /* PCH */ -} - - - -static void OPC_6502_41 (CPUInstance* D) -/* Opcode $41: EOR (zp,x) */ -{ - AC_OP_ZPXIND (^); -} - - - -static void OPC_6502_45 (CPUInstance* D) -/* Opcode $45: EOR zp */ -{ - AC_OP_ZP (^); -} - - - -static void OPC_6502_46 (CPUInstance* D) -/* Opcode $46: LSR zp */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_48 (CPUInstance* D) -/* Opcode $48: PHA */ -{ - D->Cycles = 3; - PUSH (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_49 (CPUInstance* D) -/* Opcode $49: EOR #imm */ -{ - AC_OP_IMM (^); -} - - - -static void OPC_6502_4A (CPUInstance* D) -/* Opcode $4A: LSR a */ -{ - D->Cycles = 2; - SET_CF (D->Regs.AC & 0x01); - D->Regs.AC >>= 1; - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_4C (CPUInstance* D) -/* Opcode $4C: JMP abs */ -{ - D->Cycles = 3; - D->Regs.PC = MemReadWord (D->Regs.PC+1); -} - - - -static void OPC_6502_4D (CPUInstance* D) -/* Opcode $4D: EOR abs */ -{ - AC_OP_ABS (^); -} - - - -static void OPC_6502_4E (CPUInstance* D) -/* Opcode $4E: LSR abs */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_50 (CPUInstance* D) -/* Opcode $50: BVC */ -{ - BRANCH (!GET_OF ()); -} - - - -static void OPC_6502_51 (CPUInstance* D) -/* Opcode $51: EOR (zp),y */ -{ - AC_OP_ZPINDY (^); -} - - - -static void OPC_6502_55 (CPUInstance* D) -/* Opcode $55: EOR zp,x */ -{ - AC_OP_ZPX (^); -} - - - -static void OPC_6502_56 (CPUInstance* D) -/* Opcode $56: LSR zp,x */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_58 (CPUInstance* D) -/* Opcode $58: CLI */ -{ - D->Cycles = 2; - SET_IF (0); - D->Regs.PC += 1; -} - - - -static void OPC_6502_59 (CPUInstance* D) -/* Opcode $59: EOR abs,y */ -{ - AC_OP_ABSY (^); -} - - - -static void OPC_6502_5D (CPUInstance* D) -/* Opcode $5D: EOR abs,x */ -{ - AC_OP_ABSX (^); -} - - - -static void OPC_6502_5E (CPUInstance* D) -/* Opcode $5E: LSR abs,x */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 7; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr); - SET_CF (Val & 0x01); - Val >>= 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_60 (CPUInstance* D) -/* Opcode $60: RTS */ -{ - D->Cycles = 6; - D->Regs.PC = POP (); /* PCL */ - D->Regs.PC |= (POP () << 8); /* PCH */ - D->Regs.PC += 1; -} - - - -static void OPC_6502_61 (CPUInstance* D) -/* Opcode $61: ADC (zp,x) */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Addr = MemReadZPWord (ZPAddr); - ADC (MemReadByte (Addr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_65 (CPUInstance* D) -/* Opcode $65: ADC zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - ADC (MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_66 (CPUInstance* D) -/* Opcode $66: ROR zp */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr); - ROR (Val); - MemWriteByte (ZPAddr, Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_68 (CPUInstance* D) -/* Opcode $68: PLA */ -{ - D->Cycles = 4; - D->Regs.AC = POP (); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_69 (CPUInstance* D) -/* Opcode $69: ADC #imm */ -{ - D->Cycles = 2; - ADC (MemReadByte (D->Regs.PC+1)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_6A (CPUInstance* D) -/* Opcode $6A: ROR a */ -{ - D->Cycles = 2; - ROR (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_6C (CPUInstance* D) -/* Opcode $6C: JMP (ind) */ -{ - unsigned PC, Lo, Hi; - D->Cycles = 5; - PC = D->Regs.PC; - Lo = MemReadWord (PC+1); - - /* Emulate the 6502 bug */ - D->Regs.PC = MemReadByte (Lo); - Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF); - D->Regs.PC |= (MemReadByte (Hi) << 8); - - /* Output a warning if the bug is triggered */ - if (Hi != Lo + 1) { - Sim->Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X", - PC, Lo); - } -} - - - -static void OPC_65C02_6C (CPUInstance* D) -/* Opcode $6C: JMP (ind) */ -{ - /* 6502 bug fixed here */ - D->Cycles = 5; - D->Regs.PC = MemReadWord (MemReadWord (D->Regs.PC+1)); -} - - - -static void OPC_6502_6D (CPUInstance* D) -/* Opcode $6D: ADC abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - ADC (MemReadByte (Addr)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_6E (CPUInstance* D) -/* Opcode $6E: ROR abs */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr); - ROR (Val); - MemWriteByte (Addr, Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_70 (CPUInstance* D) -/* Opcode $70: BVS */ -{ - BRANCH (GET_OF ()); -} - - - -static void OPC_6502_71 (CPUInstance* D) -/* Opcode $71: ADC (zp),y */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - ADC (MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_75 (CPUInstance* D) -/* Opcode $75: ADC zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - ADC (MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_76 (CPUInstance* D) -/* Opcode $76: ROR zp,x */ -{ - unsigned char ZPAddr; - unsigned Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr); - ROR (Val); - MemWriteByte (ZPAddr, Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_78 (CPUInstance* D) -/* Opcode $78: SEI */ -{ - D->Cycles = 2; - SET_IF (1); - D->Regs.PC += 1; -} - - - -static void OPC_6502_79 (CPUInstance* D) -/* Opcode $79: ADC abs,y */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - ADC (MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_7D (CPUInstance* D) -/* Opcode $7D: ADC abs,x */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.XR)) { - ++D->Cycles; - } - ADC (MemReadByte (Addr + D->Regs.XR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_7E (CPUInstance* D) -/* Opcode $7E: ROR abs,x */ -{ - unsigned Addr; - unsigned Val; - D->Cycles = 7; - Addr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr); - ROR (Val); - MemWriteByte (Addr, Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_81 (CPUInstance* D) -/* Opcode $81: STA (zp,x) */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Addr = MemReadZPWord (ZPAddr); - MemWriteByte (Addr, D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_84 (CPUInstance* D) -/* Opcode $84: STY zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - MemWriteByte (ZPAddr, D->Regs.YR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_85 (CPUInstance* D) -/* Opcode $85: STA zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - MemWriteByte (ZPAddr, D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_86 (CPUInstance* D) -/* Opcode $86: STX zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - MemWriteByte (ZPAddr, D->Regs.XR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_88 (CPUInstance* D) -/* Opcode $88: DEY */ -{ - D->Cycles = 2; - D->Regs.YR = (D->Regs.YR - 1) & 0xFF; - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_8A (CPUInstance* D) -/* Opcode $8A: TXA */ -{ - D->Cycles = 2; - D->Regs.AC = D->Regs.XR; - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_8C (CPUInstance* D) -/* Opcode $8C: STY abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - MemWriteByte (Addr, D->Regs.YR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_8D (CPUInstance* D) -/* Opcode $8D: STA abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - MemWriteByte (Addr, D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_8E (CPUInstance* D) -/* Opcode $8E: STX abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - MemWriteByte (Addr, D->Regs.XR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_90 (CPUInstance* D) -/* Opcode $90: BCC */ -{ - BRANCH (!GET_CF ()); -} - - - -static void OPC_6502_91 (CPUInstance* D) -/* Opcode $91: sta (zp),y */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1); - Addr = MemReadZPWord (ZPAddr) + D->Regs.YR; - MemWriteByte (Addr, D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_94 (CPUInstance* D) -/* Opcode $94: STY zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - MemWriteByte (ZPAddr, D->Regs.YR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_95 (CPUInstance* D) -/* Opcode $95: STA zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - MemWriteByte (ZPAddr, D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_96 (CPUInstance* D) -/* Opcode $96: stx zp,y */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.YR; - MemWriteByte (ZPAddr, D->Regs.XR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_98 (CPUInstance* D) -/* Opcode $98: TYA */ -{ - D->Cycles = 2; - D->Regs.AC = D->Regs.YR; - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 1; -} - - - -static void OPC_6502_99 (CPUInstance* D) -/* Opcode $99: STA abs,y */ -{ - unsigned Addr; - D->Cycles = 5; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.YR; - MemWriteByte (Addr, D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_9A (CPUInstance* D) -/* Opcode $9A: TXS */ -{ - D->Cycles = 2; - D->Regs.SP = D->Regs.XR; - D->Regs.PC += 1; -} - - - -static void OPC_6502_9D (CPUInstance* D) -/* Opcode $9D: STA abs,x */ -{ - unsigned Addr; - D->Cycles = 5; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - MemWriteByte (Addr, D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_A0 (CPUInstance* D) -/* Opcode $A0: LDY #imm */ -{ - D->Cycles = 2; - D->Regs.YR = MemReadByte (D->Regs.PC+1); - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A1 (CPUInstance* D) -/* Opcode $A1: LDA (zp,x) */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Addr = MemReadZPWord (ZPAddr); - D->Regs.AC = MemReadByte (Addr); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A2 (CPUInstance* D) -/* Opcode $A2: LDX #imm */ -{ - D->Cycles = 2; - D->Regs.XR = MemReadByte (D->Regs.PC+1); - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A4 (CPUInstance* D) -/* Opcode $A4: LDY zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - D->Regs.YR = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A5 (CPUInstance* D) -/* Opcode $A5: LDA zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - D->Regs.AC = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A6 (CPUInstance* D) -/* Opcode $A6: LDX zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - D->Regs.XR = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_A8 (CPUInstance* D) -/* Opcode $A8: TAY */ -{ - D->Cycles = 2; - D->Regs.YR = D->Regs.AC; - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_A9 (CPUInstance* D) -/* Opcode $A9: LDA #imm */ -{ - D->Cycles = 2; - D->Regs.AC = MemReadByte (D->Regs.PC+1); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_AA (CPUInstance* D) -/* Opcode $AA: TAX */ -{ - D->Cycles = 2; - D->Regs.XR = D->Regs.AC; - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_AC (CPUInstance* D) -/* Opcode $D->Regs.AC: LDY abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - D->Regs.YR = MemReadByte (Addr); - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_AD (CPUInstance* D) -/* Opcode $AD: LDA abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - D->Regs.AC = MemReadByte (Addr); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_AE (CPUInstance* D) -/* Opcode $AE: LDX abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - D->Regs.XR = MemReadByte (Addr); - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_B0 (CPUInstance* D) -/* Opcode $B0: BCS */ -{ - BRANCH (GET_CF ()); -} - - - -static void OPC_6502_B1 (CPUInstance* D) -/* Opcode $B1: LDA (zp),y */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - D->Regs.AC = MemReadByte (Addr + D->Regs.YR); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_B4 (CPUInstance* D) -/* Opcode $B4: LDY zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - D->Regs.YR = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_B5 (CPUInstance* D) -/* Opcode $B5: LDA zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - D->Regs.AC = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 2; -} - - - -static void OPC_6502_B6 (CPUInstance* D) -/* Opcode $B6: LDX zp,y */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.YR; - D->Regs.XR = MemReadByte (ZPAddr); - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 2; -} - - - -static void OPC_6502_B8 (CPUInstance* D) -/* Opcode $B8: CLV */ -{ - D->Cycles = 2; - SET_OF (0); - D->Regs.PC += 1; -} - - - -static void OPC_6502_B9 (CPUInstance* D) -/* Opcode $B9: LDA abs,y */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - D->Regs.AC = MemReadByte (Addr + D->Regs.YR); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_BA (CPUInstance* D) -/* Opcode $BA: TSX */ -{ - D->Cycles = 2; - D->Regs.XR = D->Regs.SP; - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_BC (CPUInstance* D) -/* Opcode $BC: LDY abs,x */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.XR)) { - ++D->Cycles; - } - D->Regs.YR = MemReadByte (Addr + D->Regs.XR); - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_BD (CPUInstance* D) -/* Opcode $BD: LDA abs,x */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.XR)) { - ++D->Cycles; - } - D->Regs.AC = MemReadByte (Addr + D->Regs.XR); - TEST_ZF (D->Regs.AC); - TEST_SF (D->Regs.AC); - D->Regs.PC += 3; -} - - - -static void OPC_6502_BE (CPUInstance* D) -/* Opcode $BE: LDX abs,y */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - D->Regs.XR = MemReadByte (Addr + D->Regs.YR); - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 3; -} - - - -static void OPC_6502_C0 (CPUInstance* D) -/* Opcode $C0: CPY #imm */ -{ - D->Cycles = 2; - CMP (D->Regs.YR, MemReadByte (D->Regs.PC+1)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_C1 (CPUInstance* D) -/* Opcode $C1: CMP (zp,x) */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Addr = MemReadZPWord (ZPAddr); - CMP (D->Regs.AC, MemReadByte (Addr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_C4 (CPUInstance* D) -/* Opcode $C4: CPY zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - CMP (D->Regs.YR, MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_C5 (CPUInstance* D) -/* Opcode $C5: CMP zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - CMP (D->Regs.AC, MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_C6 (CPUInstance* D) -/* Opcode $C6: DEC zp */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr) - 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_C8 (CPUInstance* D) -/* Opcode $C8: INY */ -{ - D->Cycles = 2; - D->Regs.YR = (D->Regs.YR + 1) & 0xFF; - TEST_ZF (D->Regs.YR); - TEST_SF (D->Regs.YR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_C9 (CPUInstance* D) -/* Opcode $C9: CMP #imm */ -{ - D->Cycles = 2; - CMP (D->Regs.AC, MemReadByte (D->Regs.PC+1)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_CA (CPUInstance* D) -/* Opcode $CA: DEX */ -{ - D->Cycles = 2; - D->Regs.XR = (D->Regs.XR - 1) & 0xFF; - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_CC (CPUInstance* D) -/* Opcode $CC: CPY abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - CMP (D->Regs.YR, MemReadByte (Addr)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_CD (CPUInstance* D) -/* Opcode $CD: CMP abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - CMP (D->Regs.AC, MemReadByte (Addr)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_CE (CPUInstance* D) -/* Opcode $CE: DEC abs */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr) - 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_D0 (CPUInstance* D) -/* Opcode $D0: BNE */ -{ - BRANCH (!GET_ZF ()); -} - - - -static void OPC_6502_D1 (CPUInstance* D) -/* Opcode $D1: CMP (zp),y */ -{ - unsigned ZPAddr; - unsigned Addr; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Addr = MemReadWord (ZPAddr); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - CMP (D->Regs.AC, MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_D5 (CPUInstance* D) -/* Opcode $D5: CMP zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - CMP (D->Regs.AC, MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_D6 (CPUInstance* D) -/* Opcode $D6: DEC zp,x */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr) - 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_D8 (CPUInstance* D) -/* Opcode $D8: CLD */ -{ - D->Cycles = 2; - SET_DF (0); - D->Regs.PC += 1; -} - - - -static void OPC_6502_D9 (CPUInstance* D) -/* Opcode $D9: CMP abs,y */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - CMP (D->Regs.AC, MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_DD (CPUInstance* D) -/* Opcode $DD: CMP abs,x */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.XR)) { - ++D->Cycles; - } - CMP (D->Regs.AC, MemReadByte (Addr + D->Regs.XR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_DE (CPUInstance* D) -/* Opcode $DE: DEC abs,x */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 7; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr) - 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_E0 (CPUInstance* D) -/* Opcode $E0: CPX #imm */ -{ - D->Cycles = 2; - CMP (D->Regs.XR, MemReadByte (D->Regs.PC+1)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_E1 (CPUInstance* D) -/* Opcode $E1: SBC (zp,x) */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Addr = MemReadZPWord (ZPAddr); - SBC (MemReadByte (Addr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_E4 (CPUInstance* D) -/* Opcode $E4: CPX zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - CMP (D->Regs.XR, MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_E5 (CPUInstance* D) -/* Opcode $E5: SBC zp */ -{ - unsigned char ZPAddr; - D->Cycles = 3; - ZPAddr = MemReadByte (D->Regs.PC+1); - SBC (MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_E6 (CPUInstance* D) -/* Opcode $E6: INC zp */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Val = MemReadByte (ZPAddr) + 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_E8 (CPUInstance* D) -/* Opcode $E8: INX */ -{ - D->Cycles = 2; - D->Regs.XR = (D->Regs.XR + 1) & 0xFF; - TEST_ZF (D->Regs.XR); - TEST_SF (D->Regs.XR); - D->Regs.PC += 1; -} - - - -static void OPC_6502_E9 (CPUInstance* D) -/* Opcode $E9: SBC #imm */ -{ - D->Cycles = 2; - SBC (MemReadByte (D->Regs.PC+1)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_EA (CPUInstance* D) -/* Opcode $EA: NOP */ -{ - /* This one is easy... */ - D->Cycles = 2; - D->Regs.PC += 1; -} - - - -static void OPC_6502_EC (CPUInstance* D) -/* Opcode $EC: CPX abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - CMP (D->Regs.XR, MemReadByte (Addr)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_ED (CPUInstance* D) -/* Opcode $ED: SBC abs */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - SBC (MemReadByte (Addr)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_EE (CPUInstance* D) -/* Opcode $EE: INC abs */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 6; - Addr = MemReadWord (D->Regs.PC+1); - Val = MemReadByte (Addr) + 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -static void OPC_6502_F0 (CPUInstance* D) -/* Opcode $F0: BEQ */ -{ - BRANCH (GET_ZF ()); -} - - - -static void OPC_6502_F1 (CPUInstance* D) -/* Opcode $F1: SBC (zp),y */ -{ - unsigned char ZPAddr; - unsigned Addr; - D->Cycles = 5; - ZPAddr = MemReadByte (D->Regs.PC+1); - Addr = MemReadZPWord (ZPAddr); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - SBC (MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_F5 (CPUInstance* D) -/* Opcode $F5: SBC zp,x */ -{ - unsigned char ZPAddr; - D->Cycles = 4; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - SBC (MemReadByte (ZPAddr)); - D->Regs.PC += 2; -} - - - -static void OPC_6502_F6 (CPUInstance* D) -/* Opcode $F6: INC zp,x */ -{ - unsigned char ZPAddr; - unsigned char Val; - D->Cycles = 6; - ZPAddr = MemReadByte (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (ZPAddr) + 1; - MemWriteByte (ZPAddr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 2; -} - - - -static void OPC_6502_F8 (CPUInstance* D) -/* Opcode $F8: SED */ -{ - SET_DF (1); -} - - - -static void OPC_6502_F9 (CPUInstance* D) -/* Opcode $F9: SBC abs,y */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.YR)) { - ++D->Cycles; - } - SBC (MemReadByte (Addr + D->Regs.YR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_FD (CPUInstance* D) -/* Opcode $FD: SBC abs,x */ -{ - unsigned Addr; - D->Cycles = 4; - Addr = MemReadWord (D->Regs.PC+1); - if (PAGE_CROSS (Addr, D->Regs.XR)) { - ++D->Cycles; - } - SBC (MemReadByte (Addr + D->Regs.XR)); - D->Regs.PC += 3; -} - - - -static void OPC_6502_FE (CPUInstance* D) -/* Opcode $FE: INC abs,x */ -{ - unsigned Addr; - unsigned char Val; - D->Cycles = 7; - Addr = MemReadWord (D->Regs.PC+1) + D->Regs.XR; - Val = MemReadByte (Addr) + 1; - MemWriteByte (Addr, Val); - TEST_ZF (Val); - TEST_SF (Val); - D->Regs.PC += 3; -} - - - -/*****************************************************************************/ -/* Opcode handler tables */ -/*****************************************************************************/ - - - -/* Opcode handler table for the 6502 */ -static const OPFunc OP6502Table[256] = { - OPC_6502_00, - OPC_6502_01, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_05, - OPC_6502_06, - OPC_Illegal, - OPC_6502_08, - OPC_6502_09, - OPC_6502_0A, - OPC_Illegal, - OPC_Illegal, - OPC_6502_0D, - OPC_6502_0E, - OPC_Illegal, - OPC_6502_10, - OPC_6502_11, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_15, - OPC_6502_16, - OPC_Illegal, - OPC_6502_18, - OPC_6502_19, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_1D, - OPC_6502_1E, - OPC_Illegal, - OPC_6502_20, - OPC_6502_21, - OPC_Illegal, - OPC_Illegal, - OPC_6502_24, - OPC_6502_25, - OPC_6502_26, - OPC_Illegal, - OPC_6502_28, - OPC_6502_29, - OPC_6502_2A, - OPC_Illegal, - OPC_6502_2C, - OPC_6502_2D, - OPC_6502_2E, - OPC_Illegal, - OPC_6502_30, - OPC_6502_31, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_35, - OPC_6502_36, - OPC_Illegal, - OPC_6502_38, - OPC_6502_39, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_3D, - OPC_6502_3E, - OPC_Illegal, - OPC_6502_40, - OPC_6502_41, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_45, - OPC_6502_46, - OPC_Illegal, - OPC_6502_48, - OPC_6502_49, - OPC_6502_4A, - OPC_Illegal, - OPC_6502_4C, - OPC_6502_4D, - OPC_6502_4E, - OPC_Illegal, - OPC_6502_50, - OPC_6502_51, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_55, - OPC_6502_56, - OPC_Illegal, - OPC_6502_58, - OPC_6502_59, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_5D, - OPC_6502_5E, - OPC_Illegal, - OPC_6502_60, - OPC_6502_61, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_65, - OPC_6502_66, - OPC_Illegal, - OPC_6502_68, - OPC_6502_69, - OPC_6502_6A, - OPC_Illegal, - OPC_6502_6C, - OPC_6502_6D, - OPC_6502_6E, - OPC_Illegal, - OPC_6502_70, - OPC_6502_71, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_75, - OPC_6502_76, - OPC_Illegal, - OPC_6502_78, - OPC_6502_79, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_7D, - OPC_6502_7E, - OPC_Illegal, - OPC_Illegal, - OPC_6502_81, - OPC_Illegal, - OPC_Illegal, - OPC_6502_84, - OPC_6502_85, - OPC_6502_86, - OPC_Illegal, - OPC_6502_88, - OPC_Illegal, - OPC_6502_8A, - OPC_Illegal, - OPC_6502_8C, - OPC_6502_8D, - OPC_6502_8E, - OPC_Illegal, - OPC_6502_90, - OPC_6502_91, - OPC_Illegal, - OPC_Illegal, - OPC_6502_94, - OPC_6502_95, - OPC_6502_96, - OPC_Illegal, - OPC_6502_98, - OPC_6502_99, - OPC_6502_9A, - OPC_Illegal, - OPC_Illegal, - OPC_6502_9D, - OPC_Illegal, - OPC_Illegal, - OPC_6502_A0, - OPC_6502_A1, - OPC_6502_A2, - OPC_Illegal, - OPC_6502_A4, - OPC_6502_A5, - OPC_6502_A6, - OPC_Illegal, - OPC_6502_A8, - OPC_6502_A9, - OPC_6502_AA, - OPC_Illegal, - OPC_6502_AC, - OPC_6502_AD, - OPC_6502_AE, - OPC_Illegal, - OPC_6502_B0, - OPC_6502_B1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_B4, - OPC_6502_B5, - OPC_6502_B6, - OPC_Illegal, - OPC_6502_B8, - OPC_6502_B9, - OPC_6502_BA, - OPC_Illegal, - OPC_6502_BC, - OPC_6502_BD, - OPC_6502_BE, - OPC_Illegal, - OPC_6502_C0, - OPC_6502_C1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_C4, - OPC_6502_C5, - OPC_6502_C6, - OPC_Illegal, - OPC_6502_C8, - OPC_6502_C9, - OPC_6502_CA, - OPC_Illegal, - OPC_6502_CC, - OPC_6502_CD, - OPC_6502_CE, - OPC_Illegal, - OPC_6502_D0, - OPC_6502_D1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_D5, - OPC_6502_D6, - OPC_Illegal, - OPC_6502_D8, - OPC_6502_D9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_DD, - OPC_6502_DE, - OPC_Illegal, - OPC_6502_E0, - OPC_6502_E1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_E4, - OPC_6502_E5, - OPC_6502_E6, - OPC_Illegal, - OPC_6502_E8, - OPC_6502_E9, - OPC_6502_EA, - OPC_Illegal, - OPC_6502_EC, - OPC_6502_ED, - OPC_6502_EE, - OPC_Illegal, - OPC_6502_F0, - OPC_6502_F1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_F5, - OPC_6502_F6, - OPC_Illegal, - OPC_6502_F8, - OPC_6502_F9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_FD, - OPC_6502_FE, - OPC_Illegal, -}; - - - -/* Opcode handler table for the 65C02 */ -static const OPFunc OP65C02Table[256] = { - OPC_6502_00, - OPC_6502_01, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_05, - OPC_6502_06, - OPC_Illegal, - OPC_6502_08, - OPC_6502_09, - OPC_6502_0A, - OPC_Illegal, - OPC_Illegal, - OPC_6502_0D, - OPC_6502_0E, - OPC_Illegal, - OPC_6502_10, - OPC_6502_11, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_15, - OPC_6502_16, - OPC_Illegal, - OPC_6502_18, - OPC_6502_19, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_1D, - OPC_6502_1E, - OPC_Illegal, - OPC_6502_20, - OPC_6502_21, - OPC_Illegal, - OPC_Illegal, - OPC_6502_24, - OPC_6502_25, - OPC_6502_26, - OPC_Illegal, - OPC_6502_28, - OPC_6502_29, - OPC_6502_2A, - OPC_Illegal, - OPC_6502_2C, - OPC_6502_2D, - OPC_6502_2E, - OPC_Illegal, - OPC_6502_30, - OPC_6502_31, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_35, - OPC_6502_36, - OPC_Illegal, - OPC_6502_38, - OPC_6502_39, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_3D, - OPC_6502_3E, - OPC_Illegal, - OPC_6502_40, - OPC_6502_41, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_45, - OPC_6502_46, - OPC_Illegal, - OPC_6502_48, - OPC_6502_49, - OPC_6502_4A, - OPC_Illegal, - OPC_6502_4C, - OPC_6502_4D, - OPC_6502_4E, - OPC_Illegal, - OPC_6502_50, - OPC_6502_51, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_55, - OPC_6502_56, - OPC_Illegal, - OPC_6502_58, - OPC_6502_59, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_5D, - OPC_6502_5E, - OPC_Illegal, - OPC_6502_60, - OPC_6502_61, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_65, - OPC_6502_66, - OPC_Illegal, - OPC_6502_68, - OPC_6502_69, - OPC_6502_6A, - OPC_Illegal, - OPC_65C02_6C, - OPC_6502_6D, - OPC_6502_6E, - OPC_Illegal, - OPC_6502_70, - OPC_6502_71, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_75, - OPC_6502_76, - OPC_Illegal, - OPC_6502_78, - OPC_6502_79, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_7D, - OPC_6502_7E, - OPC_Illegal, - OPC_Illegal, - OPC_6502_81, - OPC_Illegal, - OPC_Illegal, - OPC_6502_84, - OPC_6502_85, - OPC_6502_86, - OPC_Illegal, - OPC_6502_88, - OPC_Illegal, - OPC_6502_8A, - OPC_Illegal, - OPC_6502_8C, - OPC_6502_8D, - OPC_6502_8E, - OPC_Illegal, - OPC_6502_90, - OPC_6502_91, - OPC_Illegal, - OPC_Illegal, - OPC_6502_94, - OPC_6502_95, - OPC_6502_96, - OPC_Illegal, - OPC_6502_98, - OPC_6502_99, - OPC_6502_9A, - OPC_Illegal, - OPC_Illegal, - OPC_6502_9D, - OPC_Illegal, - OPC_Illegal, - OPC_6502_A0, - OPC_6502_A1, - OPC_6502_A2, - OPC_Illegal, - OPC_6502_A4, - OPC_6502_A5, - OPC_6502_A6, - OPC_Illegal, - OPC_6502_A8, - OPC_6502_A9, - OPC_6502_AA, - OPC_Illegal, - OPC_6502_AC, - OPC_6502_AD, - OPC_6502_AE, - OPC_Illegal, - OPC_6502_B0, - OPC_6502_B1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_B4, - OPC_6502_B5, - OPC_6502_B6, - OPC_Illegal, - OPC_6502_B8, - OPC_6502_B9, - OPC_6502_BA, - OPC_Illegal, - OPC_6502_BC, - OPC_6502_BD, - OPC_6502_BE, - OPC_Illegal, - OPC_6502_C0, - OPC_6502_C1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_C4, - OPC_6502_C5, - OPC_6502_C6, - OPC_Illegal, - OPC_6502_C8, - OPC_6502_C9, - OPC_6502_CA, - OPC_Illegal, - OPC_6502_CC, - OPC_6502_CD, - OPC_6502_CE, - OPC_Illegal, - OPC_6502_D0, - OPC_6502_D1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_D5, - OPC_6502_D6, - OPC_Illegal, - OPC_6502_D8, - OPC_6502_D9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_DD, - OPC_6502_DE, - OPC_Illegal, - OPC_6502_E0, - OPC_6502_E1, - OPC_Illegal, - OPC_Illegal, - OPC_6502_E4, - OPC_6502_E5, - OPC_6502_E6, - OPC_Illegal, - OPC_6502_E8, - OPC_6502_E9, - OPC_6502_EA, - OPC_Illegal, - OPC_6502_EC, - OPC_6502_ED, - OPC_6502_EE, - OPC_Illegal, - OPC_6502_F0, - OPC_6502_F1, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_F5, - OPC_6502_F6, - OPC_Illegal, - OPC_6502_F8, - OPC_6502_F9, - OPC_Illegal, - OPC_Illegal, - OPC_Illegal, - OPC_6502_FD, - OPC_6502_FE, - OPC_Illegal, -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static void Init (const SimData* S) -/* Initialize the module */ -{ - /* Remember the data pointer */ - Sim = S; -} - - - -static void* Create6502Instance (void* CfgInfo) -/* Create an instance of a 6502 CPU */ -{ - return NewCPUInstance (OP6502Table, CfgInfo); -} - - - -static void* Create65C02Instance (void* CfgInfo) -/* Create an instance of a 65C02 CPU */ -{ - return NewCPUInstance (OP65C02Table, CfgInfo); -} - - - -static void DestroyInstance (void* Instance) -/* Destroy an instance of a CPU */ -{ - /* Free the instance */ - DeleteCPUInstance (Instance); -} - - - -static void IRQRequest (void* Data) -/* Generate an IRQ */ -{ - /* Cast the pointer */ - CPUInstance* D = (CPUInstance*) Data; - - /* Remember the request */ - D->HaveIRQRequest = 1; -} - - - -static void NMIRequest (void* Data) -/* Generate an NMI */ -{ - /* Cast the pointer */ - CPUInstance* D = (CPUInstance*) Data; - - /* Remember the request */ - D->HaveNMIRequest = 1; -} - - - -static void Reset (void* Data) -/* Generate a CPU RESET */ -{ - /* Cast the pointer */ - CPUInstance* D = (CPUInstance*) Data; - - /* Reset the CPU */ - D->HaveIRQRequest = 0; - D->HaveNMIRequest = 0; - D->CPUHalted = 0; - D->Regs.SR = 0; - D->Regs.PC = MemReadWord (0xFFFC); -} - - - -static unsigned ExecuteInsn (void* Data) -/* Execute one CPU instruction */ -{ - /* Cast the pointer */ - CPUInstance* D = (CPUInstance*) Data; - - /* If the CPU is halted, do nothing */ - if (D->CPUHalted) { - return 0; - } - - /* If we have an NMI request, handle it */ - if (D->HaveNMIRequest) { - - D->HaveNMIRequest = 0; - PUSH (PCH); - PUSH (PCL); - PUSH (D->Regs.SR); - SET_IF (1); - D->Regs.PC = MemReadWord (0xFFFA); - D->Cycles = 7; - - } else if (D->HaveIRQRequest && GET_IF () == 0) { - - D->HaveIRQRequest = 0; - PUSH (PCH); - PUSH (PCL); - PUSH (D->Regs.SR); - SET_IF (1); - D->Regs.PC = MemReadWord (0xFFFE); - D->Cycles = 7; - - } else { - - /* Normal instruction - read the next opcode */ - unsigned char OPC = MemReadByte (D->Regs.PC); - - /* Execute it */ - D->Handlers[OPC] (D); - - } - - /* Count cycles */ - D->TotalCycles += D->Cycles; - - /* Return the number of clock cycles needed by this insn */ - return D->Cycles; -} - - - -static unsigned long GetCycles (void* Data) -/* Return the total number of cycles executed */ -{ - /* Cast the pointer */ - CPUInstance* D = (CPUInstance*) Data; - - /* Return the total number of cycles */ - return D->TotalCycles; -} - - - diff --git a/src/sim65/cputype.c b/src/sim65/cputype.c deleted file mode 100644 index 0a06d36d8..000000000 --- a/src/sim65/cputype.c +++ /dev/null @@ -1,50 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cputype.h */ -/* */ -/* CPU type definitions */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include "cputype.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Current CPU */ -CPUType CPU = CPU_6502; - - - diff --git a/src/sim65/cputype.h b/src/sim65/cputype.h deleted file mode 100644 index 88f3d7a14..000000000 --- a/src/sim65/cputype.h +++ /dev/null @@ -1,64 +0,0 @@ -/*****************************************************************************/ -/* */ -/* cputype.h */ -/* */ -/* CPU type definitions */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef CPUTYPE_H -#define CPUTYPE_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Supported CPUs */ -typedef enum CPUType { - CPU_6502, - CPU_65C02 -} CPUType; - -/* Current CPU */ -extern CPUType CPU; - - - -/* End of cputype.h */ - -#endif - - - - diff --git a/src/sim65/global.c b/src/sim65/global.c deleted file mode 100644 index bd3756229..000000000 --- a/src/sim65/global.c +++ /dev/null @@ -1,49 +0,0 @@ -/*****************************************************************************/ -/* */ -/* global.c */ -/* */ -/* Global variables for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include "global.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -unsigned char Debug = 0; /* Debug mode */ - - - diff --git a/src/sim65/global.h b/src/sim65/global.h deleted file mode 100644 index a7434e225..000000000 --- a/src/sim65/global.h +++ /dev/null @@ -1,57 +0,0 @@ -/*****************************************************************************/ -/* */ -/* global.h */ -/* */ -/* Global variables for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef GLOBAL_H -#define GLOBAL_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -extern unsigned char Debug; /* Debug mode */ - - - -/* End of global.h */ - -#endif - - - - diff --git a/src/sim65/location.c b/src/sim65/location.c deleted file mode 100644 index e7985ee34..000000000 --- a/src/sim65/location.c +++ /dev/null @@ -1,174 +0,0 @@ -/*****************************************************************************/ -/* */ -/* location.c */ -/* */ -/* Memory location description */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -/* common.h */ -#include "coll.h" -#include "xmalloc.h" - -/* sim65 */ -#include "cfgdata.h" -#include "error.h" -#include "scanner.h" -#include "location.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* List of all memory locations */ -Collection Locations = STATIC_COLLECTION_INITIALIZER; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -Location* NewLocation (unsigned long Start, unsigned long End) -/* Create a new location, initialize and return it */ -{ - /* Allocate memory */ - Location* L = xmalloc (sizeof (Location)); - - /* Initialize the fields */ - L->Start = Start; - L->End = End; - L->Attributes = EmptyCollection; - L->Line = CfgErrorLine; - L->Col = CfgErrorCol; - - /* Return the new struct */ - return L; -} - - - -static int CmpLocations (void* Data attribute ((unused)), - const void* lhs, const void* rhs) -/* Compare function for CollSort */ -{ - /* Cast the object pointers */ - const Location* Left = (const Location*) rhs; - const Location* Right = (const Location*) lhs; - - /* Do the compare */ - if (Left->Start < Right->Start) { - return 1; - } else if (Left->Start > Right->Start) { - return -1; - } else { - return 0; - } -} - - - -int LocationGetAttr (const Location* L, const char* AttrName) -/* Find the attribute with the given name and return it. Call Error() if the - * attribute was not found. - */ -{ - int I = CfgDataFind (&L->Attributes, AttrName); - if (I < 0) { - Error ("%s(%u): Attribute `%s' missing", CfgGetName(), L->Line, AttrName); - } - return I; -} - - - -int LocationIsMirror (const Location* L) -/* Return true if the given location is a mirror of another one. */ -{ - /* Find the "mirror" attribute */ - return (CfgDataFind (&L->Attributes, "mirror") >= 0); -} - - - -void LocationSort (Collection* Locations) -/* Sort all locations by address */ -{ - /* Sort all memory locations */ - CollSort (Locations, CmpLocations, 0); -} - - - -void LocationCheck (const Collection* Locations) -/* Check all locations for problems */ -{ - unsigned I; - - /* Check for overlaps and other problems */ - const Location* Last = 0; - for (I = 0; I < CollCount (Locations); ++I) { - - /* Get this location */ - const Location* L = CollConstAt (Locations, I); - - /* Check for an overlap with the following location */ - if (Last && Last->End >= L->Start) { - Error ("%s(%u): Address range overlap (overlapping entry is in line %u)", - CfgGetName(), L->Line, Last->Line); - } - - /* If the location is a mirror, it must not have other attributes, - * and the mirror attribute must be an integer. - */ - if (LocationIsMirror (L)) { - const CfgData* D; - if (CollCount (&L->Attributes) > 1) { - Error ("%s(%u): Location at address $%06X is a mirror " - "but has attributes", CfgGetName(), L->Line, L->Start); - } - D = CollConstAt (&L->Attributes, 0); - CfgDataCheckType (D, CfgDataNumber); - } - - /* Remember this entry */ - Last = L; - } -} - - - - diff --git a/src/sim65/location.h b/src/sim65/location.h deleted file mode 100644 index aea46e8c1..000000000 --- a/src/sim65/location.h +++ /dev/null @@ -1,97 +0,0 @@ -/*****************************************************************************/ -/* */ -/* location.h */ -/* */ -/* Memory location description */ -/* */ -/* */ -/* */ -/* (C) 2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef LOCATION_H -#define LOCATION_H - - - -/* common.h */ -#include "coll.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* List of all memory locations */ -extern Collection Locations; - -/* One memory location */ -typedef struct Location Location; -struct Location { - unsigned Start; /* Start of memory location */ - unsigned End; /* End memory location */ - Collection Attributes; /* Attributes given */ - unsigned Line; /* Line in config file */ - unsigned Col; /* Column in config file */ -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -Location* NewLocation (unsigned long Start, unsigned long End); -/* Create a new location, initialize and return it */ - -int LocationGetAttr (const Location* L, const char* AttrName); -/* Find the attribute with the given name and return it. Call Error() if the - * attribute was not found. - */ - -int LocationIsMirror (const Location* L); -/* Return true if the given location is a mirror of another one. */ - -void LocationSort (Collection* Locations); -/* Sort all locations by address */ - -void LocationCheck (const Collection* Locations); -/* Check all locations for problems */ - - - -/* End of location.h */ - -#endif - - - diff --git a/src/sim65/main.c b/src/sim65/main.c index 3608be3f7..2e2c2085b 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -33,31 +33,31 @@ -#include #include #include #include -#include -#include /* common */ #include "abend.h" #include "cmdline.h" -#include "filestat.h" #include "print.h" #include "version.h" -#include "xmalloc.h" /* sim65 */ -#include "chip.h" -#include "chippath.h" -#include "config.h" -#include "cpucore.h" -#include "cputype.h" +#include "6502.h" #include "error.h" -#include "global.h" #include "memory.h" -#include "scanner.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Name of program file */ +const char* ProgramFile; @@ -71,18 +71,11 @@ static void Usage (void) { printf ("Usage: %s [options] file\n" "Short options:\n" - " -C name\t\tUse simulator config file\n" - " -L dir\t\tSet a chip directory search path\n" - " -V\t\t\tPrint the simulator version number\n" - " -d\t\t\tDebug mode\n" " -h\t\t\tHelp (this text)\n" " -v\t\t\tIncrease verbosity\n" + " -V\t\t\tPrint the simulator version number\n" "\n" "Long options:\n" - " --chipdir dir\t\tSet a chip directory search path\n" - " --config name\t\tUse simulator config file\n" - " --cpu type\t\tSet cpu type\n" - " --debug\t\tDebug mode\n" " --help\t\tHelp (this text)\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the simulator version number\n", @@ -91,98 +84,6 @@ static void Usage (void) -static void OptChipDir (const char* Opt attribute ((unused)), const char* Arg) -/* Handle the --chipdir option */ -{ - struct dirent* E; - - /* Get the length of the directory name */ - unsigned DirLen = strlen (Arg); - - /* Open the directory */ - DIR* D = opendir (Arg); - if (D == 0) { - AbEnd ("Cannot read directory `%s': %s", Arg, strerror (errno)); - } - - /* Read in all files and treat them as libraries */ - while ((E = readdir (D)) != 0) { - - char* Name; - struct stat S; - - /* ### Ignore anything but *.so files */ - unsigned NameLen = strlen (E->d_name); - if (NameLen <= 3) { - continue; - } - if (strcmp (E->d_name + NameLen - 3, ".so") != 0) { - continue; - } - - /* Create the full file name */ - Name = xmalloc (DirLen + 1 + NameLen + 1); - strcpy (Name, Arg); - strcpy (Name + DirLen, "/"); - strcpy (Name + DirLen + 1, E->d_name); - - /* Stat the file */ - if (FileStat (Name, &S) != 0) { - Warning ("Cannot stat `%s': %s", Name, strerror (errno)); - xfree (Name); - continue; - } - - /* Check if this is a regular file */ - if (S_ISREG (S.st_mode)) { - /* Treat it as a library */ - LoadChipLibrary (Name); - } - - /* Free the name */ - xfree (Name); - } - - /* Close the directory */ - closedir (D); -} - - - -static void OptCPU (const char* Opt, const char* Arg) -/* Handle the --cpu option */ -{ - if (strcmp (Arg, "6502") == 0) { - CPU = CPU_6502; - } else if (strcmp (Arg, "65C02") == 0) { - CPU = CPU_65C02; - } else { - AbEnd ("Invalid argument for %s: `%s'", Opt, Arg); - } -} - - - -static void OptConfig (const char* Opt attribute ((unused)), const char* Arg) -/* Define the config file */ -{ - if (CfgAvail ()) { - Error ("Cannot use -C twice"); - } - CfgSetName (Arg); -} - - - -static void OptDebug (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) -/* Simulator debug mode */ -{ - Debug = 1; -} - - - static void OptHelp (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print usage information and exit */ @@ -204,21 +105,58 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) -/* Print the assembler version */ +/* Print the simulator version */ { fprintf (stderr, "sim65 V%s\n", GetVersionAsString ()); } +static void ReadProgramFile (void) +/* Load program into memory */ +{ + int Val; + unsigned Addr = 0x0200; + + /* Open the file */ + FILE* F = fopen (ProgramFile, "rb"); + if (F == 0) { + Error ("Cannot open `%s': %s", ProgramFile, strerror (errno)); + } + + /* Get the CPU type from the file header */ + if ((Val = fgetc(F)) != EOF) { + if (Val != CPU_6502 && Val != CPU_65C02) { + Error ("`%s': Invalid CPU type", ProgramFile); + } + CPU = Val; + } + + /* Read the file body into memory */ + while ((Val = fgetc(F)) != EOF) { + if (Addr == 0xFF00) { + Error ("`%s': To large to fit into $0200-$FFF0", ProgramFile); + } + MemWriteByte (Addr++, (unsigned char) Val); + } + + /* Check for errors */ + if (ferror (F)) { + Error ("Error reading from `%s': %s", ProgramFile, strerror (errno)); + } + + /* Close the file */ + fclose (F); + + Print (stdout, 1, "Loaded `%s' at $0200-$%04X\n", ProgramFile, Addr - 1); +} + + + int main (int argc, char* argv[]) { /* Program long options */ static const LongOpt OptTab[] = { - { "--chipdir", 1, OptChipDir }, - { "--config", 1, OptConfig }, - { "--cpu", 1, OptCPU }, - { "--debug", 0, OptDebug }, { "--help", 0, OptHelp }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, @@ -226,15 +164,9 @@ int main (int argc, char* argv[]) unsigned I; - /* Initialize the output file name */ - const char* InputFile = 0; - /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "sim65"); - /* Initialize the chip library search paths */ - InitChipPaths (); - /* Parse the command line */ I = 1; while (I < ArgCount) { @@ -251,10 +183,6 @@ int main (int argc, char* argv[]) LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); break; - case 'd': - OptDebug (Arg, 0); - break; - case 'h': case '?': OptHelp (Arg, 0); @@ -264,14 +192,6 @@ int main (int argc, char* argv[]) OptVerbose (Arg, 0); break; - case 'C': - OptConfig (Arg, GetArg (&I, 2)); - break; - - case 'L': - OptChipDir (Arg, GetArg (&I, 2)); - break; - case 'V': OptVersion (Arg, 0); break; @@ -281,10 +201,11 @@ int main (int argc, char* argv[]) break; } } else { - if (InputFile) { - fprintf (stderr, "additional file specs ignored\n"); + /* Filename. Check if we already had one */ + if (ProgramFile) { + AbEnd ("Don't know what to do with `%s'", Arg); } else { - InputFile = Arg; + ProgramFile = Arg; } } @@ -292,29 +213,21 @@ int main (int argc, char* argv[]) ++I; } - /* Sort the already loaded chips */ - SortChips (); - - /* Check if we have a valid configuration */ - if (!CfgAvail ()) { - Error ("Simulator configuration missing"); + /* Do we have a program file? */ + if (ProgramFile == 0) { + AbEnd ("No program file"); } - /* Initialize the simulated CPU memory */ MemInit (); - /* Read the config file */ - CfgRead (); + ReadProgramFile (); - CPUInit (); + Reset (); while (1) { - CPURun (); + ExecuteInsn (); } /* Return an apropriate exit code */ return EXIT_SUCCESS; } - - - diff --git a/src/sim65/memory.c b/src/sim65/memory.c index e141fdf7a..42f4f7be7 100644 --- a/src/sim65/memory.c +++ b/src/sim65/memory.c @@ -33,18 +33,8 @@ -#include #include -#include -/* common */ -#include "coll.h" -#include "xmalloc.h" - -/* sim65 */ -#include "chip.h" -#include "cputype.h" -#include "error.h" #include "memory.h" @@ -55,9 +45,8 @@ -/* Pointer to our memory */ -static const ChipInstance** MemData = 0; -unsigned MemSize = 0; +/* THE memory */ +static unsigned char Mem[0x10000]; @@ -70,15 +59,7 @@ unsigned MemSize = 0; void MemWriteByte (unsigned Addr, unsigned char Val) /* Write a byte to a memory location */ { - /* Get the instance of the chip at this address */ - const ChipInstance* CI = MemData[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Warning ("Writing to unassigned memory at $%06X", Addr); - } else { - CI->C->Data->Write (CI->Data, Addr - CI->Addr, Val); - } + Mem[Addr] = Val; } @@ -86,16 +67,7 @@ void MemWriteByte (unsigned Addr, unsigned char Val) unsigned char MemReadByte (unsigned Addr) /* Read a byte from a memory location */ { - /* Get the instance of the chip at this address */ - const ChipInstance* CI = MemData[Addr]; - - /* Check if the memory is mapped */ - if (CI == 0) { - Warning ("Reading from unassigned memory at $%06X", Addr); - return 0xFF; - } else { - return CI->C->Data->Read (CI->Data, Addr - CI->Addr); - } + return Mem[Addr]; } @@ -121,54 +93,13 @@ unsigned MemReadZPWord (unsigned char Addr) -void MemAssignChip (const ChipInstance* CI, unsigned Addr, unsigned Range) -/* Assign a chip instance to memory locations */ -{ - /* Make sure, the addresses are in a valid range */ - PRECONDITION (Addr + Range <= MemSize); - - /* Assign the chip instance */ - while (Range--) { - CHECK (MemData[Addr] == 0); - MemData[Addr++] = CI; - } -} - - - -const struct ChipInstance* MemGetChip (unsigned Addr) -/* Get the chip that is located at the given address (may return NULL). */ -{ - /* Make sure, the address is valid */ - PRECONDITION (Addr < MemSize); - - /* Return the chip instance */ - return MemData[Addr]; -} - - - void MemInit (void) /* Initialize the memory subsystem */ { - unsigned I; - - /* Allocate memory depending on the CPU type */ - switch (CPU) { - case CPU_6502: - case CPU_65C02: - MemSize = 0x10000; - break; - default: - Internal ("Unexpected CPU type: %d", CPU); - } - MemData = xmalloc (MemSize * sizeof (ChipInstance*)); - - /* Clear the memory */ - for (I = 0; I < MemSize; ++I) { - MemData[I] = 0; - } -} - - + /* Fill momory with illegal opcode */ + memset (Mem, 0xFF, sizeof (Mem)); + /* Set RESET vector to 0x0200 */ + Mem[0xFFFC] = 0x00; + Mem[0xFFFD] = 0x02; +} diff --git a/src/sim65/memory.h b/src/sim65/memory.h index dc20efff7..5e234c561 100644 --- a/src/sim65/memory.h +++ b/src/sim65/memory.h @@ -38,20 +38,6 @@ -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Forwards */ -struct ChipInstance; - -/* Memory size of the CPU */ -extern unsigned MemSize; - - - /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -73,12 +59,6 @@ unsigned MemReadZPWord (unsigned char Addr); * overflow. */ -void MemAssignChip (const struct ChipInstance* CI, unsigned Addr, unsigned Range); -/* Assign a chip instance to memory locations */ - -const struct ChipInstance* MemGetChip (unsigned Addr); -/* Get the chip that is located at the given address (may return NULL). */ - void MemInit (void); /* Initialize the memory subsystem */ diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c new file mode 100644 index 000000000..2de8f4775 --- /dev/null +++ b/src/sim65/paravirt.c @@ -0,0 +1,255 @@ +/*****************************************************************************/ +/* */ +/* paravirt.c */ +/* */ +/* Paravirtualization for the sim65 6502 simulator */ +/* */ +/* */ +/* */ +/* (C) 2013-2013 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include +#include +#if defined(_MSC_VER) +/* Microsoft compiler */ +# include +# pragma warning(disable : 4996) +# define O_INITIAL O_BINARY +#else +/* Anyone else */ +# include +# define O_INITIAL 0 +#endif + +/* common */ +#include "print.h" +#include "xmalloc.h" + +/* sim65 */ +#include "6502.h" +#include "memory.h" +#include "paravirt.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +typedef void (*PVFunc) (CPURegs* Regs); + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static unsigned char Pop (CPURegs* Regs) +{ + return MemReadByte (0x0100 + ++Regs->SP); +} + + + +static unsigned PopParam (unsigned char Incr) +{ + unsigned SP = MemReadZPWord (0x00); + unsigned Val = MemReadWord (SP); + SP += Incr; + MemWriteByte (0x00, SP); + SP >>= 8; + MemWriteByte (0x01, SP); + return Val; +} + + + +static void PVExit (CPURegs* Regs) +{ + Print (stdout, 1, "PVExit ($%02X)\n", Regs->AC); + + exit (Regs->AC); +} + + + +static void PVOpen (CPURegs* Regs) +{ + char Path[1024]; + int OFlag = O_INITIAL; + unsigned RetVal, I = 0; + + unsigned Mode = PopParam (Regs->YR - 4); + unsigned Flags = PopParam (2); + unsigned Name = PopParam (2); + + do { + Path[I] = MemReadByte (Name++); + } + while (Path[I++]); + + Print (stdout, 2, "PVOpen (\"%s\", $%04X)\n", Path, Flags); + + switch (Flags & 0x03) { + case 0x01: + OFlag |= O_RDONLY; + break; + case 0x02: + OFlag |= O_WRONLY; + break; + case 0x03: + OFlag |= O_RDWR; + break; + } + if (Flags & 0x10) { + OFlag |= O_CREAT; + } + if (Flags & 0x20) { + OFlag |= O_TRUNC; + } + if (Flags & 0x40) { + OFlag |= O_APPEND; + } + if (Flags & 0x80) { + OFlag |= O_EXCL; + } + + /* Avoid gcc warning */ + (void) Mode; + + RetVal = open (Path, OFlag); + + Regs->AC = RetVal & 0xFF; + RetVal >>= 8; + Regs->XR = RetVal & 0xFF; +} + + + +static void PVClose (CPURegs* Regs) +{ + unsigned RetVal; + + unsigned FD = Regs->AC + (Regs->XR << 8); + + Print (stdout, 2, "PVClose ($%04X)\n", FD); + + RetVal = close (FD); + + Regs->AC = RetVal & 0xFF; + RetVal >>= 8; + Regs->XR = RetVal & 0xFF; +} + + + +static void PVRead (CPURegs* Regs) +{ + unsigned char* Data; + unsigned RetVal, I = 0; + + unsigned Count = Regs->AC + (Regs->XR << 8); + unsigned Buf = PopParam (2); + unsigned FD = PopParam (2); + + Print (stdout, 2, "PVRead ($%04X, $%04X, $%04X)\n", FD, Buf, Count); + + Data = xmalloc (Count); + + RetVal = read (FD, Data, Count); + + if (RetVal != (unsigned) -1) { + while (I < RetVal) { + MemWriteByte (Buf++, Data[I++]); + } + } + xfree (Data); + + Regs->AC = RetVal & 0xFF; + RetVal >>= 8; + Regs->XR = RetVal & 0xFF; +} + + + +static void PVWrite (CPURegs* Regs) +{ + unsigned char* Data; + unsigned RetVal, I = 0; + + unsigned Count = Regs->AC + (Regs->XR << 8); + unsigned Buf = PopParam (2); + unsigned FD = PopParam (2); + + Print (stdout, 2, "PVWrite ($%04X, $%04X, $%04X)\n", FD, Buf, Count); + + Data = xmalloc (Count); + while (I < Count) { + Data[I++] = MemReadByte (Buf++); + } + + RetVal = write (FD, Data, Count); + + xfree (Data); + + Regs->AC = RetVal & 0xFF; + RetVal >>= 8; + Regs->XR = RetVal & 0xFF; +} + + + +static const PVFunc Hooks[] = { + PVExit, + PVOpen, + PVClose, + PVRead, + PVWrite, +}; + + + +void ParaVirtualization (CPURegs* Regs) +/* Potentially execute paravirtualization hook */ +{ + /* Check for paravirtualization address range */ + if (Regs->PC < 0xFFF0 || + Regs->PC >= 0xFFF0 + sizeof (Hooks) / sizeof (Hooks[0])) { + return; + } + + /* Call paravirtualization hook */ + Hooks[Regs->PC - 0xFFF0] (Regs); + + /* Simulate RTS */ + Regs->PC = Pop(Regs) + (Pop(Regs) << 8) + 1; +} diff --git a/src/sim65/config.h b/src/sim65/paravirt.h similarity index 87% rename from src/sim65/config.h rename to src/sim65/paravirt.h index a6446c624..bf483e29f 100644 --- a/src/sim65/config.h +++ b/src/sim65/paravirt.h @@ -1,12 +1,12 @@ /*****************************************************************************/ /* */ -/* config.h */ +/* paravirt.h */ /* */ -/* Configuration file parsing for the sim65 6502 simulator */ +/* Paravirtualization for the sim65 6502 simulator */ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ +/* (C) 2013-2013 Ullrich von Bassewitz */ /* Römerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -33,8 +33,8 @@ -#ifndef CONFIG_H -#define CONFIG_H +#ifndef PARAVIRT_H +#define PARAVIRT_H @@ -44,16 +44,11 @@ -void CfgRead (void); -/* Read the configuration */ +void ParaVirtualization (CPURegs* Regs); +/* Potentially execute paravirtualization hook */ -/* End of config.h */ +/* End of paravirt.h */ #endif - - - - - diff --git a/src/sim65/scanner.c b/src/sim65/scanner.c deleted file mode 100644 index b07c0cc72..000000000 --- a/src/sim65/scanner.c +++ /dev/null @@ -1,530 +0,0 @@ -/*****************************************************************************/ -/* */ -/* scanner.c */ -/* */ -/* Configuration file scanner for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#include -#include -#include -#include -#include - -/* common */ -#include "chartype.h" -#include "xsprintf.h" - -/* sim65 */ -#include "error.h" -#include "scanner.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Current token and attributes */ -cfgtok_t CfgTok; -StrBuf CfgSVal = STATIC_STRBUF_INITIALIZER; -unsigned long CfgIVal; - -/* Error location */ -unsigned CfgErrorLine; -unsigned CfgErrorCol; - -/* Input sources for the configuration */ -static const char* CfgName = 0; -static const char* CfgBuf = 0; - -/* Other input stuff */ -static int C = ' '; -static unsigned InputLine = 1; -static unsigned InputCol = 0; -static FILE* InputFile = 0; - - - -/*****************************************************************************/ -/* Error handling */ -/*****************************************************************************/ - - - -void CfgWarning (const char* Format, ...) -/* Print a warning message adding file name and line number of the config file */ -{ - char Buf [512]; - va_list ap; - - va_start (ap, Format); - xvsprintf (Buf, sizeof (Buf), Format, ap); - va_end (ap); - - Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf); -} - - - -void CfgError (const char* Format, ...) -/* Print an error message adding file name and line number of the config file */ -{ - char Buf [512]; - va_list ap; - - va_start (ap, Format); - xvsprintf (Buf, sizeof (Buf), Format, ap); - va_end (ap); - - Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf); -} - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static void NextChar (void) -/* Read the next character from the input file */ -{ - if (CfgBuf) { - /* Read from buffer */ - C = (unsigned char)(*CfgBuf); - if (C == 0) { - C = EOF; - } else { - ++CfgBuf; - } - } else { - /* Read from the file */ - C = getc (InputFile); - } - - /* Count columns */ - if (C != EOF) { - ++InputCol; - } - - /* Count lines */ - if (C == '\n') { - ++InputLine; - InputCol = 0; - } -} - - - -static unsigned DigitVal (int C) -/* Return the value for a numeric digit */ -{ - if (isdigit (C)) { - return C - '0'; - } else { - return toupper (C) - 'A' + 10; - } -} - - - -void CfgNextTok (void) -/* Read the next token from the input stream */ -{ - unsigned I; - - -Again: - /* Skip whitespace */ - while (isspace (C)) { - NextChar (); - } - - /* Remember the current position */ - CfgErrorLine = InputLine; - CfgErrorCol = InputCol; - - /* Identifier? */ - if (C == '_' || IsAlpha (C)) { - - /* Read the identifier */ - I = 0; - while (C == '_' || IsAlNum (C)) { - if (I < CFG_MAX_IDENT_LEN) { - CfgSVal [I++] = C; - } - NextChar (); - } - CfgSVal [I] = '\0'; - CfgTok = CFGTOK_IDENT; - return; - } - - /* Hex number? */ - if (C == '$') { - NextChar (); - if (!isxdigit (C)) { - Error ("%s(%u): Hex digit expected", CfgName, InputLine); - } - CfgIVal = 0; - while (isxdigit (C)) { - CfgIVal = CfgIVal * 16 + DigitVal (C); - NextChar (); - } - CfgTok = CFGTOK_INTCON; - return; - } - - /* Decimal number? */ - if (isdigit (C)) { - CfgIVal = 0; - while (isdigit (C)) { - CfgIVal = CfgIVal * 10 + DigitVal (C); - NextChar (); - } - CfgTok = CFGTOK_INTCON; - return; - } - - /* Other characters */ - switch (C) { - - case '{': - NextChar (); - CfgTok = CFGTOK_LCURLY; - break; - - case '}': - NextChar (); - CfgTok = CFGTOK_RCURLY; - break; - - case ';': - NextChar (); - CfgTok = CFGTOK_SEMI; - break; - - case '.': - NextChar (); - if (C == '.') { - NextChar (); - CfgTok = CFGTOK_DOTDOT; - } else { - CfgTok = CFGTOK_DOT; - } - break; - - case ',': - NextChar (); - CfgTok = CFGTOK_COMMA; - break; - - case '=': - NextChar (); - CfgTok = CFGTOK_EQ; - break; - - case ':': - NextChar (); - CfgTok = CFGTOK_COLON; - break; - - case '\"': - NextChar (); - I = 0; - while (C != '\"') { - if (C == EOF || C == '\n') { - Error ("%s(%u): Unterminated string", CfgName, InputLine); - } - if (I < CFG_MAX_IDENT_LEN) { - CfgSVal [I++] = C; - } - NextChar (); - } - NextChar (); - CfgSVal [I] = '\0'; - CfgTok = CFGTOK_STRCON; - break; - - case '#': - /* Comment */ - while (C != '\n' && C != EOF) { - NextChar (); - } - if (C != EOF) { - goto Again; - } - CfgTok = CFGTOK_EOF; - break; - - case EOF: - CfgTok = CFGTOK_EOF; - break; - - default: - Error ("%s(%u): Invalid character `%c'", CfgName, InputLine, C); - - } -} - - - -void CfgConsume (cfgtok_t T, const char* Msg) -/* Skip a token, print an error message if not found */ -{ - if (CfgTok != T) { - CfgError ("%s", Msg); - } - CfgNextTok (); -} - - - -void CfgConsumeSemi (void) -/* Consume a semicolon */ -{ - CfgConsume (CFGTOK_SEMI, "`;' expected"); -} - - - -void CfgConsumeColon (void) -/* Consume a colon */ -{ - CfgConsume (CFGTOK_COLON, "`:' expected"); -} - - - -void CfgConsumeRCurly (void) -/* Consume a right curly brace */ -{ - CfgConsume (CFGTOK_RCURLY, "`}' expected"); -} - - - -void CfgOptionalComma (void) -/* Consume a comma if there is one */ -{ - if (CfgTok == CFGTOK_COMMA) { - CfgNextTok (); - } -} - - - -void CfgOptionalAssign (void) -/* Consume an equal sign if there is one */ -{ - if (CfgTok == CFGTOK_EQ) { - CfgNextTok (); - } -} - - - -void CfgAssureInt (void) -/* Make sure the next token is an integer */ -{ - if (CfgTok != CFGTOK_INTCON) { - CfgError ("Integer constant expected"); - } -} - - - -void CfgAssureStr (void) -/* Make sure the next token is a string constant */ -{ - if (CfgTok != CFGTOK_STRCON) { - CfgError ("String constant expected"); - } -} - - - -void CfgAssureIdent (void) -/* Make sure the next token is an identifier */ -{ - if (CfgTok != CFGTOK_IDENT) { - CfgError ("Identifier expected"); - } -} - - - -void CfgRangeCheck (unsigned long Lo, unsigned long Hi) -/* Check the range of CfgIVal */ -{ - if (CfgIVal < Lo || CfgIVal > Hi) { - CfgError ("Range error"); - } -} - - - -void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) -/* Map an identifier to one of the special tokens in the table */ -{ - unsigned I; - - /* We need an identifier */ - if (CfgTok == CFGTOK_IDENT) { - - /* Make it upper case */ - I = 0; - while (CfgSVal [I]) { - CfgSVal [I] = toupper (CfgSVal [I]); - ++I; - } - - /* Linear search */ - for (I = 0; I < Size; ++I) { - if (strcmp (CfgSVal, Table [I].Ident) == 0) { - CfgTok = Table [I].Tok; - return; - } - } - - } - - /* Not found or no identifier */ - Error ("%s(%u): %s expected", CfgName, InputLine, Name); -} - - - -void CfgBoolToken (void) -/* Map an identifier or integer to a boolean token */ -{ - static const IdentTok Booleans [] = { - { "YES", CFGTOK_TRUE }, - { "NO", CFGTOK_FALSE }, - { "TRUE", CFGTOK_TRUE }, - { "FALSE", CFGTOK_FALSE }, - }; - - /* If we have an identifier, map it to a boolean token */ - if (CfgTok == CFGTOK_IDENT) { - CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean"); - } else { - /* We expected an integer here */ - if (CfgTok != CFGTOK_INTCON) { - CfgError ("Boolean value expected"); - } - CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE; - } -} - - - -void CfgSetName (const char* Name) -/* Set a name for a config file */ -{ - CfgName = Name; -} - - - -const char* CfgGetName (void) -/* Get the name of the config file */ -{ - if (CfgName) { - return CfgName; - } else if (CfgBuf) { - return "[builtin config]"; - } else { - return ""; - } -} - - - -void CfgSetBuf (const char* Buf) -/* Set a memory buffer for the config */ -{ - CfgBuf = Buf; -} - - - -int CfgAvail (void) -/* Return true if we have a configuration available */ -{ - return CfgName != 0 || CfgBuf != 0; -} - - - -void CfgOpenInput (void) -/* Open the input file if we have one */ -{ - /* If we have a config name given, open the file, otherwise we will read - * from a buffer. - */ - if (!CfgBuf) { - - /* Open the file */ - InputFile = fopen (CfgName, "r"); - if (InputFile == 0) { - Error ("Cannot open `%s': %s", CfgName, strerror (errno)); - } - - } - - /* Initialize variables */ - C = ' '; - InputLine = 1; - InputCol = 0; - - /* Start the ball rolling ... */ - CfgNextTok (); -} - - - -void CfgCloseInput (void) -/* Close the input file if we have one */ -{ - /* Close the input file if we had one */ - if (InputFile) { - (void) fclose (InputFile); - InputFile = 0; - } -} - - - diff --git a/src/sim65/scanner.h b/src/sim65/scanner.h deleted file mode 100644 index bd8bbcfca..000000000 --- a/src/sim65/scanner.h +++ /dev/null @@ -1,180 +0,0 @@ -/*****************************************************************************/ -/* */ -/* scanner.h */ -/* */ -/* Configuration file scanner for the sim65 6502 simulator */ -/* */ -/* */ -/* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef SCANNER_H -#define SCANNER_H - - - -/* common */ -#include "attrib.h" -#include "strbuf.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Config file tokens */ -typedef enum { - CFGTOK_NONE, - CFGTOK_INTCON, - CFGTOK_STRCON, - CFGTOK_IDENT, - CFGTOK_LCURLY, - CFGTOK_RCURLY, - CFGTOK_SEMI, - CFGTOK_COMMA, - CFGTOK_EQ, - CFGTOK_COLON, - CFGTOK_DOT, - CFGTOK_DOTDOT, - CFGTOK_EOF, - - /* Primary blocks */ - CFGTOK_CPU, - CFGTOK_ADDRSPACE, - - /* Secondary stuff */ - CFGTOK_TYPE, - - /* Special identifiers */ - CFGTOK_TRUE, - CFGTOK_FALSE - -} cfgtok_t; - - - -/* Mapping table entry, special identifier --> token */ -typedef struct IdentTok IdentTok; -struct IdentTok { - const char* Ident; /* Identifier */ - cfgtok_t Tok; /* Token for identifier */ -}; -#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0])) - - - -/* Current token and attributes */ -extern cfgtok_t CfgTok; -extern StrBuf CfgSVal; -extern unsigned long CfgIVal; - -/* Error location */ -extern unsigned CfgErrorLine; -extern unsigned CfgErrorCol; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void CfgWarning (const char* Format, ...) attribute((format(printf,1,2))); -/* Print a warning message adding file name and line number of the config file */ - -void CfgError (const char* Format, ...) attribute((format(printf,1,2))); -/* Print an error message adding file name and line number of the config file */ - -void CfgNextTok (void); -/* Read the next token from the input stream */ - -void CfgConsume (cfgtok_t T, const char* Msg); -/* Skip a token, print an error message if not found */ - -void CfgConsumeSemi (void); -/* Consume a semicolon */ - -void CfgConsumeColon (void); -/* Consume a colon */ - -void CfgConsumeRCurly (void); -/* Consume a right curly brace */ - -void CfgOptionalComma (void); -/* Consume a comma if there is one */ - -void CfgOptionalAssign (void); -/* Consume an equal sign if there is one */ - -void CfgAssureInt (void); -/* Make sure the next token is an integer */ - -void CfgAssureStr (void); -/* Make sure the next token is a string constant */ - -void CfgAssureIdent (void); -/* Make sure the next token is an identifier */ - -void CfgRangeCheck (unsigned long Lo, unsigned long Hi); -/* Check the range of CfgIVal */ - -void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name); -/* Map an identifier to one of the special tokens in the table */ - -void CfgBoolToken (void); -/* Map an identifier or integer to a boolean token */ - -void CfgSetName (const char* Name); -/* Set a name for a config file */ - -const char* CfgGetName (void); -/* Get the name of the config file */ - -void CfgSetBuf (const char* Buf); -/* Set a memory buffer for the config */ - -int CfgAvail (void); -/* Return true if we have a configuration available */ - -void CfgOpenInput (void); -/* Open the input file if we have one */ - -void CfgCloseInput (void); -/* Close the input file if we have one */ - - - -/* End of scanner.h */ -#endif - - - diff --git a/src/sim65/simdata.h b/src/sim65/simdata.h deleted file mode 100644 index d0669ea59..000000000 --- a/src/sim65/simdata.h +++ /dev/null @@ -1,118 +0,0 @@ -/*****************************************************************************/ -/* */ -/* simdata.h */ -/* */ -/* Simulator data passed to the chip plugins */ -/* */ -/* */ -/* */ -/* (C) 2002-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef SIMDATA_H -#define SIMDATA_H - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* SimData structure */ -typedef struct SimData SimData; -struct SimData { - unsigned MajorVersion; - unsigned MinorVersion; - - /* -- Callback functions -- */ - - void* (*Malloc) (size_t Size); - /* Allocate a memory block of the given size */ - - void (*Free) (void* Block); - /* Free an allocated memory block */ - - void (*Warning) (const char* Format, ...); - /* Print a warning */ - - void (*Error) (const char* Format, ...); - /* Print an error and terminate the program */ - - void (*Internal) (const char* Format, ...); - /* Print an internal program error and terminate */ - - int (*GetCfgId) (void* CfgInfo, const char* Name, char** Id); - /* Search CfgInfo for an attribute with the given name and type "id". If - * found, remove it from the configuration, pass a pointer to a dynamically - * allocated string containing the value to Id, and return true. If not - * found, return false. The memory passed in Id must be free by a call to - * Free(); - */ - - int (*GetCfgStr) (void* CfgInfo, const char* Name, char** S); - /* Search CfgInfo for an attribute with the given name and type "string". - * If found, remove it from the configuration, pass a pointer to a - * dynamically allocated string containing the value to S, and return - * true. If not found, return false. The memory passed in S must be free - * by a call to Free(); - */ - - int (*GetCfgNum) (void* CfgInfo, const char* Name, long* Val); - /* Search CfgInfo for an attribute with the given name and type "number". - * If found, remove it from the configuration, copy it into Val and return - * true. If not found, return false. - */ - - unsigned char (*ReadCtrl) (unsigned Addr); - /* Read from the given address without triggering any additional action */ - - void (*WriteCtrl) (unsigned Addr, unsigned char Val); - /* Write to the given address without triggering additional action */ - - void (*Break) (const char* Format, ...); - /* Stop the CPU and display the given message */ - - void (*IRQ) (void); - /* Issue an irq request */ - - void (*NMI) (void); - /* Issue an nmi request */ - - - -}; - - - -/* End of simdata.h */ - -#endif - - - diff --git a/src/sim65/system.c b/src/sim65/system.c deleted file mode 100644 index b898e3974..000000000 --- a/src/sim65/system.c +++ /dev/null @@ -1,70 +0,0 @@ -/*****************************************************************************/ -/* */ -/* system.c */ -/* */ -/* Description of the simulated system */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -/* common.h */ -#include "xmalloc.h" - -/* sim65 */ -#include "system.h" - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -System* NewSystem (CPUCore* CPU) -/* Create and initialize a new System struct. The function will read the size - * of the address space from the CPU, and also create a new AddressSpace - * object. No chips are assigned, however. - */ -{ - /* Allocate memory */ - System* Sys = xmalloc (sizeof (System)); - - /* Initialize the fields */ - Sys->CPU = CPU; - Sys->AS = NewAddressSpace (CPU->AddressSize); - Sys->ChipInstances = AUTO_COLLECTION_INITIALIZER; - - /* Return the new system */ - return Sys; -} - - - - diff --git a/src/sim65/system.h b/src/sim65/system.h deleted file mode 100644 index abe75e178..000000000 --- a/src/sim65/system.h +++ /dev/null @@ -1,91 +0,0 @@ -/*****************************************************************************/ -/* */ -/* system.h */ -/* */ -/* Description of the simulated system */ -/* */ -/* */ -/* */ -/* (C) 2003-2012, Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ -/* */ -/* */ -/* This software is provided 'as-is', without any expressed or implied */ -/* warranty. In no event will the authors be held liable for any damages */ -/* arising from the use of this software. */ -/* */ -/* Permission is granted to anyone to use this software for any purpose, */ -/* including commercial applications, and to alter it and redistribute it */ -/* freely, subject to the following restrictions: */ -/* */ -/* 1. The origin of this software must not be misrepresented; you must not */ -/* claim that you wrote the original software. If you use this software */ -/* in a product, an acknowledgment in the product documentation would be */ -/* appreciated but is not required. */ -/* 2. Altered source versions must be plainly marked as such, and must not */ -/* be misrepresented as being the original software. */ -/* 3. This notice may not be removed or altered from any source */ -/* distribution. */ -/* */ -/*****************************************************************************/ - - - -#ifndef SYSTEM_H -#define SYSTEM_H - - - -/* common.h */ -#include "coll.h" - -/* sim65 */ -#include "addrspace.h" -#include "cpucore.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Forwards */ -struct CPUCore; - -/* */ -typedef struct System System; -struct System { - CPUCore* CPU; /* The CPU in the system */ - AddressSpace* AS; /* The CPU address space */ - Collection ChipInstances; /* Instances of all the chips */ -}; - -/* Global pointer to simulated system */ -extern System* System; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -System* NewSystem (CPUCore* CPU); -/* Create and initialize a new System struct. The function will read the size - * of the address space from the CPU, and also create a new AddressSpace - * object. No chips are assigned, however. - */ - - - -/* End of system.h */ - -#endif - - - -- 2.39.5