1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Implements the 65C02's JMPs.

This commit is contained in:
Thomas Harte 2018-08-08 22:26:57 -04:00
parent e3f6da6994
commit bb680b40d8
4 changed files with 33 additions and 8 deletions

View File

@ -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))"

View File

@ -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;

View File

@ -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
}

View File

@ -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,