From bb680b40d89296c331bce500f0789c7f24b58bcc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 8 Aug 2018 22:26:57 -0400 Subject: [PATCH] Implements the 65C02's JMPs. --- .../Clock SignalTests/KlausDormannTests.swift | 5 +++++ .../Implementation/6502Implementation.hpp | 19 +++++++++++++------ .../6502/Implementation/6502Storage.cpp | 11 ++++++++++- .../6502/Implementation/6502Storage.hpp | 6 +++++- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift b/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift index 7da2aa683..17928cdbe 100644 --- a/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift +++ b/OSBindings/Mac/Clock SignalTests/KlausDormannTests.swift @@ -77,6 +77,11 @@ class KlausDormannTests: XCTestCase { case 0x0733: return "BBR: branch taken" case 0x2884: return "JMP (abs) exhibited 6502 page-crossing bug" + case 0x16ca: return "JMP (abs, x) failed" + + case 0x2785: return "BRK didn't clear the decimal mode flag" + + case 0x177b: return "INC A didn't function" case 0: return "Didn't find tests" default: return "Unknown error at \(String(format:"%04x", address))" diff --git a/Processors/6502/Implementation/6502Implementation.hpp b/Processors/6502/Implementation/6502Implementation.hpp index 3a3ef35a5..b39122e8b 100644 --- a/Processors/6502/Implementation/6502Implementation.hpp +++ b/Processors/6502/Implementation/6502Implementation.hpp @@ -93,6 +93,10 @@ if(number_of_cycles <= Cycles(0)) break; } break; case CycleFetchOperand: + // This is supposed to produce the 65C02's 1-cycle NOPs; they're + // treated as a special case because they break the rule that + // governs everything else on the 6502: that two bytes will always + // be fetched. if( personality_ == P6502 || (operation_&7) != 3 || @@ -100,8 +104,6 @@ if(number_of_cycles <= Cycles(0)) break; operation_ == 0xdb ) { read_mem(operand_, pc_.full); - } else { - printf("Skipping %02x\n", operation_); } break; @@ -146,7 +148,10 @@ if(number_of_cycles <= Cycles(0)) break; case OperationRSTPickVector: nextAddress.full = 0xfffc; continue; case CycleReadVectorLow: read_mem(pc_.bytes.low, nextAddress.full); break; case CycleReadVectorHigh: read_mem(pc_.bytes.high, nextAddress.full+1); break; - case OperationSetI: inverse_interrupt_flag_ = 0; continue; + case OperationSetI: + inverse_interrupt_flag_ = 0; + if(personality_ != P6502) decimal_flag_ = false; + continue; case CyclePullPCL: s_++; read_mem(pc_.bytes.low, s_ | 0x100); break; case CyclePullPCH: s_++; read_mem(pc_.bytes.high, s_ | 0x100); break; @@ -161,9 +166,11 @@ if(number_of_cycles <= Cycles(0)) break; case OperationSetFlagsFromX: zero_result_ = negative_result_ = x_; continue; case OperationSetFlagsFromY: zero_result_ = negative_result_ = y_; continue; - case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break; - case CycleReadPCLFromAddress: read_mem(pc_.bytes.low, address_.full); break; - case CycleReadPCHFromAddress: address_.bytes.low++; read_mem(pc_.bytes.high, address_.full); break; + case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break; + case CycleReadPCLFromAddress: read_mem(pc_.bytes.low, address_.full); break; + case CycleReadPCHFromAddressLowInc: address_.bytes.low++; read_mem(pc_.bytes.high, address_.full); break; + case CycleReadPCHFromAddressFixed: if(!address_.bytes.low) address_.bytes.high++; read_mem(pc_.bytes.high, address_.full); break; + case CycleReadPCHFromAddressInc: address_.full++; read_mem(pc_.bytes.high, address_.full); break; case CycleReadAndIncrementPC: { uint16_t oldPC = pc_.full; diff --git a/Processors/6502/Implementation/6502Storage.cpp b/Processors/6502/Implementation/6502Storage.cpp index 517a09420..92e200182 100644 --- a/Processors/6502/Implementation/6502Storage.cpp +++ b/Processors/6502/Implementation/6502Storage.cpp @@ -137,7 +137,7 @@ ProcessorStorage::ProcessorStorage(Personality personality) { /* 0x66 ROR zpg */ ZeroReadModifyWrite(OperationROR), /* 0x67 RRA zpg */ ZeroReadModifyWrite(OperationRRA, OperationADC), /* 0x68 PLA */ Program(CycleReadFromS, CyclePullA, OperationSetFlagsFromA), /* 0x69 ADC # */ Immediate(OperationADC), /* 0x6a ROR A */ Implied(OperationROR), /* 0x6b ARR # */ Immediate(OperationARR), - /* 0x6c JMP (abs) */ Program(CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress), + /* 0x6c JMP (abs) */ Program(CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc), /* 0x6d ADC abs */ AbsoluteRead(OperationADC), /* 0x6e ROR abs */ AbsoluteReadModifyWrite(OperationROR), /* 0x6f RRA abs */ AbsoluteReadModifyWrite(OperationRRA, OperationADC), /* 0x70 BVS */ Program(OperationBVS), /* 0x71 ADC ind, y */ IndirectIndexedRead(OperationADC), @@ -260,6 +260,15 @@ ProcessorStorage::ProcessorStorage(Personality personality) { for(int c = 0x02; c <= 0x62; c += 0x10) { Install(c, ImmediateNop()); } + + // Correct JMP (abs) and install JMP (abs, x). + Install(0x6c, Program(CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc, CycleReadPCHFromAddressFixed)); + Install(0x7c, Program( + CycleReadAddressHLoadAddressL, // (3) read second byte of (addr) + CycleAddXToAddressLowRead, // (4) calculate addr+x, read from (addr+x) with high byte not yet calculated + OperationCorrectAddressHigh, CycleReadPCLFromAddress, // (5) read from real (addr+x) + CycleReadPCHFromAddressInc // (6) read from addr+x+1 + )); } #undef Install } diff --git a/Processors/6502/Implementation/6502Storage.hpp b/Processors/6502/Implementation/6502Storage.hpp index bc58eb74a..d77a18103 100644 --- a/Processors/6502/Implementation/6502Storage.hpp +++ b/Processors/6502/Implementation/6502Storage.hpp @@ -35,7 +35,11 @@ class ProcessorStorage { CyclePullX, CyclePullY, CycleNoWritePush, CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL, - CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress, CycleLoadAddressAbsolute, + CycleReadAddressHLoadAddressL, + + CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc, CycleReadPCHFromAddressFixed, CycleReadPCHFromAddressInc, + + CycleLoadAddressAbsolute, OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow, CycleAddYToAddressLow, CycleAddXToAddressLowRead, OperationCorrectAddressHigh, CycleAddYToAddressLowRead, OperationMoveToNextProgram, OperationIncrementPC,