mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Trying to fix my RDY line emulation. Switched to PAL timings, at least temporarily, since it's starting to make a difference.
This commit is contained in:
parent
e4615cda2e
commit
53dd5c8f16
@ -19,10 +19,10 @@ Machine::Machine()
|
||||
_horizontalTimer = 227;
|
||||
_lastOutputStateDuration = 0;
|
||||
_lastOutputState = OutputState::Sync;
|
||||
_crt = new Outputs::CRT(228, 262, 1, 4);
|
||||
_crt = new Outputs::CRT(228, 312, 1, 4);
|
||||
_piaTimerStatus = 0xff;
|
||||
|
||||
reset();
|
||||
setup6502();
|
||||
}
|
||||
|
||||
Machine::~Machine()
|
||||
@ -142,10 +142,15 @@ void Machine::output_pixels(int count)
|
||||
|
||||
// blank is decoded as 68 counts; sync and colour burst as 16 counts
|
||||
|
||||
// 4 blank
|
||||
// 4 sync
|
||||
// 9 'blank'; colour burst after 4
|
||||
// 40 pixels
|
||||
|
||||
// it'll be about 43 cycles from start of hsync to start of visible frame, so...
|
||||
// guesses, until I can find information: 26 cycles blank, 16 sync, 40 blank, 160 pixels
|
||||
if(_horizontalTimer > 214) state = OutputState::Blank;
|
||||
else if (_horizontalTimer > 188) state = OutputState::Sync;
|
||||
if(_horizontalTimer >= 212) state = OutputState::Blank;
|
||||
else if (_horizontalTimer >= 196) state = OutputState::Sync;
|
||||
else if (_horizontalTimer >= 160) state = OutputState::Blank;
|
||||
else {
|
||||
if(_vBlankEnabled) {
|
||||
@ -334,5 +339,4 @@ void Machine::set_rom(size_t length, const uint8_t *data)
|
||||
length = std::min((size_t)4096, length);
|
||||
memcpy(_rom, data, length);
|
||||
_romMask = length - 1;
|
||||
reset();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class KlausDormannTests: XCTestCase {
|
||||
case 0x36ac, 0x36f6: return "Improper JSR return address on stack"
|
||||
case 0x36e5: return "BRK flag not set on stack"
|
||||
case 0x26d2: return "ASL zpg,x produced incorrect flags"
|
||||
case 0x36c6: return "Unexpected RESET"
|
||||
|
||||
default: return "Unknown error at \(hexAddress)"
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ extern const uint8_t CSTestMachineJamOpcode;
|
||||
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineRegister)reg;
|
||||
- (uint16_t)valueForRegister:(CSTestMachineRegister)reg;
|
||||
|
||||
- (void)reset;
|
||||
//- (void)reset;
|
||||
- (void)returnFromSubroutine;
|
||||
|
||||
@property (nonatomic, readonly) BOOL isJammed;
|
||||
|
@ -68,9 +68,9 @@ class MachineJamHandler: public CPU6502::AllRAMProcessor::JamHandler {
|
||||
_processor.set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
|
||||
}
|
||||
|
||||
- (void)reset {
|
||||
_processor.reset();
|
||||
}
|
||||
//- (void)reset {
|
||||
// _processor.reset();
|
||||
//}
|
||||
|
||||
- (void)runForNumberOfCycles:(int)cycles {
|
||||
_processor.run_for_cycles(cycles);
|
||||
|
@ -36,7 +36,7 @@ enum Flag {
|
||||
};
|
||||
|
||||
enum BusOperation {
|
||||
Read, ReadOpcode, Write, None
|
||||
Read, ReadOpcode, Write, Ready, None
|
||||
};
|
||||
|
||||
#define isReadOperation(v) (v != CPU6502::BusOperation::Write)
|
||||
@ -81,7 +81,7 @@ template <class T> class Processor {
|
||||
OperationTAY, OperationTAX, OperationTSX, OperationARR,
|
||||
OperationSBX, OperationLXA, OperationANE, OperationANC,
|
||||
OperationLAS, CycleAddSignedOperandToPC, OperationSetFlagsFromOperand, OperationSetOperandFromFlagsWithBRKSet,
|
||||
OperationSetFlagsFromA, CycleScheduleJam
|
||||
OperationSetFlagsFromA, CycleReadRSTLow, CycleReadRSTHigh, CycleScheduleJam
|
||||
};
|
||||
|
||||
#define JAM {CycleFetchOperand, CycleScheduleJam, OperationMoveToNextProgram}
|
||||
@ -370,6 +370,8 @@ template <class T> class Processor {
|
||||
|
||||
int _cycles_left_to_run;
|
||||
|
||||
bool _read_line_is_enabled;
|
||||
|
||||
public:
|
||||
Processor()
|
||||
{
|
||||
@ -378,6 +380,21 @@ template <class T> class Processor {
|
||||
_is_jammed = false;
|
||||
_jam_handler = nullptr;
|
||||
_cycles_left_to_run = 0;
|
||||
_read_line_is_enabled = false;
|
||||
}
|
||||
|
||||
const MicroOp *get_reset_program() {
|
||||
static const MicroOp reset[] = {
|
||||
CycleFetchOperand,
|
||||
CycleFetchOperand,
|
||||
CyclePullOperand,
|
||||
CyclePullOperand,
|
||||
CyclePullOperand,
|
||||
CycleReadRSTLow,
|
||||
CycleReadRSTHigh,
|
||||
OperationMoveToNextProgram
|
||||
};
|
||||
return reset;
|
||||
}
|
||||
|
||||
void run_for_cycles(int number_of_cycles)
|
||||
@ -408,6 +425,13 @@ template <class T> class Processor {
|
||||
|
||||
while(_cycles_left_to_run > 0) {
|
||||
|
||||
while (_nextBusOperation != BusOperation::Ready && _cycles_left_to_run > 0) {
|
||||
|
||||
if (_nextBusOperation != BusOperation::None && _nextBusOperation != BusOperation::Ready) {
|
||||
_cycles_left_to_run -= static_cast<T *>(this)->perform_bus_operation(_nextBusOperation, _busAddress, _busValue);
|
||||
_nextBusOperation = BusOperation::None;
|
||||
}
|
||||
|
||||
const MicroOp cycle = _scheduledPrograms[_scheduleProgramsReadPointer][_scheduleProgramProgramCounter];
|
||||
_scheduleProgramProgramCounter++;
|
||||
|
||||
@ -458,6 +482,8 @@ template <class T> class Processor {
|
||||
case CycleReadFromS: throwaway_read(_s | 0x100); break;
|
||||
case CycleReadFromPC: throwaway_read(_pc.full); break;
|
||||
|
||||
case CycleReadRSTLow: read_mem(_pc.bytes.low, 0xfffc); break;
|
||||
case CycleReadRSTHigh: read_mem(_pc.bytes.high, 0xfffd); break;
|
||||
case CycleSetIReadBRKLow: _interruptFlag = Flag::Interrupt; read_mem(_pc.bytes.low, 0xfffe); break;
|
||||
case CycleReadBRKHigh: read_mem(_pc.bytes.high, 0xffff); break;
|
||||
|
||||
@ -498,7 +524,7 @@ template <class T> class Processor {
|
||||
case OperationAND: _a &= _operand; _negativeResult = _zeroResult = _a; break;
|
||||
case OperationEOR: _a ^= _operand; _negativeResult = _zeroResult = _a; break;
|
||||
|
||||
#pragma mark - Load nad Store
|
||||
#pragma mark - Load and Store
|
||||
|
||||
case OperationLDA: _a = _negativeResult = _zeroResult = _operand; break;
|
||||
case OperationLDX: _x = _negativeResult = _zeroResult = _operand; break;
|
||||
@ -837,9 +863,6 @@ template <class T> class Processor {
|
||||
break;
|
||||
}
|
||||
|
||||
if (_nextBusOperation != BusOperation::None) {
|
||||
_cycles_left_to_run -= static_cast<T *>(this)->perform_bus_operation(_nextBusOperation, _busAddress, _busValue);
|
||||
_nextBusOperation = BusOperation::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -869,17 +892,17 @@ template <class T> class Processor {
|
||||
}
|
||||
}
|
||||
|
||||
void reset()
|
||||
void setup6502()
|
||||
{
|
||||
static_cast<T *>(this)->perform_bus_operation(CPU6502::BusOperation::Read, 0xfffc, &_pc.bytes.low);
|
||||
static_cast<T *>(this)->perform_bus_operation(CPU6502::BusOperation::Read, 0xfffd, &_pc.bytes.high);
|
||||
|
||||
// only the interrupt flag is defined upon reset but get_flags isn't going to
|
||||
// mask the other flags so we need to do that, at least
|
||||
_interruptFlag = Flag::Interrupt;
|
||||
_carryFlag &= Flag::Carry;
|
||||
_decimalFlag &= Flag::Decimal;
|
||||
_overflowFlag &= Flag::Overflow;
|
||||
_s = 0;
|
||||
schedule_program(get_reset_program());
|
||||
_nextBusOperation = BusOperation::None;
|
||||
}
|
||||
|
||||
void return_from_subroutine()
|
||||
@ -894,6 +917,10 @@ template <class T> class Processor {
|
||||
}
|
||||
}
|
||||
|
||||
void set_ready_line(bool active)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_jammed()
|
||||
{
|
||||
return _is_jammed;
|
||||
@ -903,7 +930,6 @@ template <class T> class Processor {
|
||||
{
|
||||
_jam_handler = handler;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ using namespace CPU6502;
|
||||
|
||||
AllRAMProcessor::AllRAMProcessor()
|
||||
{
|
||||
reset();
|
||||
setup6502();
|
||||
}
|
||||
|
||||
int AllRAMProcessor::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
|
||||
|
Loading…
x
Reference in New Issue
Block a user