mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Implements the 65C02's JMPs.
This commit is contained in:
parent
e3f6da6994
commit
bb680b40d8
@ -77,6 +77,11 @@ class KlausDormannTests: XCTestCase {
|
|||||||
case 0x0733: return "BBR: branch taken"
|
case 0x0733: return "BBR: branch taken"
|
||||||
|
|
||||||
case 0x2884: return "JMP (abs) exhibited 6502 page-crossing bug"
|
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"
|
case 0: return "Didn't find tests"
|
||||||
default: return "Unknown error at \(String(format:"%04x", address))"
|
default: return "Unknown error at \(String(format:"%04x", address))"
|
||||||
|
@ -93,6 +93,10 @@ if(number_of_cycles <= Cycles(0)) break;
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CycleFetchOperand:
|
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(
|
if(
|
||||||
personality_ == P6502 ||
|
personality_ == P6502 ||
|
||||||
(operation_&7) != 3 ||
|
(operation_&7) != 3 ||
|
||||||
@ -100,8 +104,6 @@ if(number_of_cycles <= Cycles(0)) break;
|
|||||||
operation_ == 0xdb
|
operation_ == 0xdb
|
||||||
) {
|
) {
|
||||||
read_mem(operand_, pc_.full);
|
read_mem(operand_, pc_.full);
|
||||||
} else {
|
|
||||||
printf("Skipping %02x\n", operation_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -146,7 +148,10 @@ if(number_of_cycles <= Cycles(0)) break;
|
|||||||
case OperationRSTPickVector: nextAddress.full = 0xfffc; continue;
|
case OperationRSTPickVector: nextAddress.full = 0xfffc; continue;
|
||||||
case CycleReadVectorLow: read_mem(pc_.bytes.low, nextAddress.full); break;
|
case CycleReadVectorLow: read_mem(pc_.bytes.low, nextAddress.full); break;
|
||||||
case CycleReadVectorHigh: read_mem(pc_.bytes.high, nextAddress.full+1); 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 CyclePullPCL: s_++; read_mem(pc_.bytes.low, s_ | 0x100); break;
|
||||||
case CyclePullPCH: s_++; read_mem(pc_.bytes.high, 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 OperationSetFlagsFromX: zero_result_ = negative_result_ = x_; continue;
|
||||||
case OperationSetFlagsFromY: zero_result_ = negative_result_ = y_; continue;
|
case OperationSetFlagsFromY: zero_result_ = negative_result_ = y_; continue;
|
||||||
|
|
||||||
case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break;
|
case CycleIncrementPCAndReadStack: pc_.full++; throwaway_read(s_ | 0x100); break;
|
||||||
case CycleReadPCLFromAddress: read_mem(pc_.bytes.low, address_.full); 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 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: {
|
case CycleReadAndIncrementPC: {
|
||||||
uint16_t oldPC = pc_.full;
|
uint16_t oldPC = pc_.full;
|
||||||
|
@ -137,7 +137,7 @@ ProcessorStorage::ProcessorStorage(Personality personality) {
|
|||||||
/* 0x66 ROR zpg */ ZeroReadModifyWrite(OperationROR), /* 0x67 RRA zpg */ ZeroReadModifyWrite(OperationRRA, OperationADC),
|
/* 0x66 ROR zpg */ ZeroReadModifyWrite(OperationROR), /* 0x67 RRA zpg */ ZeroReadModifyWrite(OperationRRA, OperationADC),
|
||||||
/* 0x68 PLA */ Program(CycleReadFromS, CyclePullA, OperationSetFlagsFromA), /* 0x69 ADC # */ Immediate(OperationADC),
|
/* 0x68 PLA */ Program(CycleReadFromS, CyclePullA, OperationSetFlagsFromA), /* 0x69 ADC # */ Immediate(OperationADC),
|
||||||
/* 0x6a ROR A */ Implied(OperationROR), /* 0x6b ARR # */ Immediate(OperationARR),
|
/* 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),
|
/* 0x6d ADC abs */ AbsoluteRead(OperationADC),
|
||||||
/* 0x6e ROR abs */ AbsoluteReadModifyWrite(OperationROR), /* 0x6f RRA abs */ AbsoluteReadModifyWrite(OperationRRA, OperationADC),
|
/* 0x6e ROR abs */ AbsoluteReadModifyWrite(OperationROR), /* 0x6f RRA abs */ AbsoluteReadModifyWrite(OperationRRA, OperationADC),
|
||||||
/* 0x70 BVS */ Program(OperationBVS), /* 0x71 ADC ind, y */ IndirectIndexedRead(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) {
|
for(int c = 0x02; c <= 0x62; c += 0x10) {
|
||||||
Install(c, ImmediateNop());
|
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
|
#undef Install
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,11 @@ class ProcessorStorage {
|
|||||||
CyclePullX, CyclePullY,
|
CyclePullX, CyclePullY,
|
||||||
CycleNoWritePush,
|
CycleNoWritePush,
|
||||||
CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL,
|
CycleReadAndIncrementPC, CycleIncrementPCAndReadStack, CycleIncrementPCReadPCHLoadPCL, CycleReadPCHLoadPCL,
|
||||||
CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddress, CycleLoadAddressAbsolute,
|
CycleReadAddressHLoadAddressL,
|
||||||
|
|
||||||
|
CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc, CycleReadPCHFromAddressFixed, CycleReadPCHFromAddressInc,
|
||||||
|
|
||||||
|
CycleLoadAddressAbsolute,
|
||||||
OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow,
|
OperationLoadAddressZeroPage, CycleLoadAddessZeroX, CycleLoadAddessZeroY, CycleAddXToAddressLow,
|
||||||
CycleAddYToAddressLow, CycleAddXToAddressLowRead, OperationCorrectAddressHigh, CycleAddYToAddressLowRead,
|
CycleAddYToAddressLow, CycleAddXToAddressLowRead, OperationCorrectAddressHigh, CycleAddYToAddressLowRead,
|
||||||
OperationMoveToNextProgram, OperationIncrementPC,
|
OperationMoveToNextProgram, OperationIncrementPC,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user