1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Merge pull request #71 from TomHarte/IRQBenchTest

Introduces a one-cycle cost to setting 6522 timers
This commit is contained in:
Thomas Harte 2016-11-05 13:00:35 -04:00 committed by GitHub
commit e5de9c8607
4 changed files with 27 additions and 7 deletions

View File

@ -90,7 +90,7 @@ template <class T> class MOS6522 {
_registers.interrupt_flags &= ~InterruptFlag::Timer1; _registers.interrupt_flags &= ~InterruptFlag::Timer1;
if(address == 0x05) if(address == 0x05)
{ {
_registers.timer[0] = _registers.timer_latch[0]; _registers.next_timer[0] = _registers.timer_latch[0];
_timer_is_running[0] = true; _timer_is_running[0] = true;
} }
reevaluate_interrupts(); reevaluate_interrupts();
@ -100,7 +100,7 @@ template <class T> class MOS6522 {
case 0x8: _registers.timer_latch[1] = value; break; case 0x8: _registers.timer_latch[1] = value; break;
case 0x9: case 0x9:
_registers.interrupt_flags &= ~InterruptFlag::Timer2; _registers.interrupt_flags &= ~InterruptFlag::Timer2;
_registers.timer[1] = _registers.timer_latch[1] | (uint16_t)(value << 8); _registers.next_timer[1] = _registers.timer_latch[1] | (uint16_t)(value << 8);
_timer_is_running[1] = true; _timer_is_running[1] = true;
reevaluate_interrupts(); reevaluate_interrupts();
break; break;
@ -242,7 +242,9 @@ template <class T> class MOS6522 {
else\ else\
_registers.timer[0] --;\ _registers.timer[0] --;\
\ \
_registers.timer[1] --; _registers.timer[1] --; \
if(_registers.next_timer[0] >= 0) { _registers.timer[0] = (uint16_t)_registers.next_timer[0]; _registers.next_timer[0] = -1; }\
if(_registers.next_timer[1] >= 0) { _registers.timer[1] = (uint16_t)_registers.next_timer[1]; _registers.next_timer[1] = -1; }\
// IRQ is raised on the half cycle after overflow // IRQ is raised on the half cycle after overflow
#define phase1() \ #define phase1() \
@ -367,6 +369,7 @@ template <class T> class MOS6522 {
struct Registers { struct Registers {
uint8_t output[2], input[2], data_direction[2]; uint8_t output[2], input[2], data_direction[2];
uint16_t timer[2], timer_latch[2], last_timer[2]; uint16_t timer[2], timer_latch[2], last_timer[2];
int next_timer[2];
uint8_t shift; uint8_t shift;
uint8_t auxiliary_control, peripheral_control; uint8_t auxiliary_control, peripheral_control;
uint8_t interrupt_flags, interrupt_enable; uint8_t interrupt_flags, interrupt_enable;
@ -377,7 +380,8 @@ template <class T> class MOS6522 {
output{0, 0}, input{0, 0}, data_direction{0, 0}, output{0, 0}, input{0, 0}, data_direction{0, 0},
auxiliary_control(0), peripheral_control(0), auxiliary_control(0), peripheral_control(0),
interrupt_flags(0), interrupt_enable(0), interrupt_flags(0), interrupt_enable(0),
last_timer{0, 0}, timer_needs_reload(false) {} last_timer{0, 0}, timer_needs_reload(false),
next_timer{-1, -1} {}
} _registers; } _registers;
// control state // control state

View File

@ -52,7 +52,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
// 024D = 0 => fast; otherwise slow // 024D = 0 => fast; otherwise slow
// E6C9 = read byte: return byte in A // E6C9 = read byte: return byte in A
if(address == 0xe6c9 && _use_fast_tape_hack && operation == CPU6502::BusOperation::ReadOpcode) if(address == 0xe6c9 && _use_fast_tape_hack && operation == CPU6502::BusOperation::ReadOpcode && _via.tape->has_tape() && !_via.tape->get_tape()->is_at_end())
{ {
uint8_t next_byte = _via.tape->get_next_byte(!_ram[0x024d]); uint8_t next_byte = _via.tape->get_next_byte(!_ram[0x024d]);
set_value_of_register(CPU6502::A, next_byte); set_value_of_register(CPU6502::A, next_byte);

View File

@ -24,6 +24,9 @@ class MOS6522Tests: XCTestCase {
$0.setValue(10, forRegister: 4) $0.setValue(10, forRegister: 4)
$0.setValue(0, forRegister: 5) $0.setValue(0, forRegister: 5)
// complete the setting cycle
$0.run(forHalfCycles: 2)
// run for 5 cycles // run for 5 cycles
$0.run(forHalfCycles: 10) $0.run(forHalfCycles: 10)
@ -42,6 +45,9 @@ class MOS6522Tests: XCTestCase {
// change the low-byte latch // change the low-byte latch
$0.setValue(0x40, forRegister: 8) $0.setValue(0x40, forRegister: 8)
// complete the cycle
$0.run(forHalfCycles: 2)
// chek that the new latched value hasn't been copied // chek that the new latched value hasn't been copied
XCTAssert($0.value(forRegister: 8) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 8))") XCTAssert($0.value(forRegister: 8) == 0x10, "Low order byte should be 0x10; was \($0.value(forRegister: 8))")
XCTAssert($0.value(forRegister: 9) == 0x20, "High order byte should be 0x20; was \($0.value(forRegister: 9))") XCTAssert($0.value(forRegister: 9) == 0x20, "High order byte should be 0x20; was \($0.value(forRegister: 9))")
@ -49,6 +55,9 @@ class MOS6522Tests: XCTestCase {
// write the low-byte latch // write the low-byte latch
$0.setValue(0x50, forRegister: 9) $0.setValue(0x50, forRegister: 9)
// complete the cycle
$0.run(forHalfCycles: 2)
// chek that the latched value has been copied // chek that the latched value has been copied
XCTAssert($0.value(forRegister: 8) == 0x40, "Low order byte should be 0x50; was \($0.value(forRegister: 8))") XCTAssert($0.value(forRegister: 8) == 0x40, "Low order byte should be 0x50; was \($0.value(forRegister: 8))")
XCTAssert($0.value(forRegister: 9) == 0x50, "High order byte should be 0x40; was \($0.value(forRegister: 9))") XCTAssert($0.value(forRegister: 9) == 0x50, "High order byte should be 0x40; was \($0.value(forRegister: 9))")
@ -63,6 +72,9 @@ class MOS6522Tests: XCTestCase {
$0.setValue(0x40, forRegister: 11) $0.setValue(0x40, forRegister: 11)
$0.setValue(0x40 | 0x80, forRegister: 14) $0.setValue(0x40 | 0x80, forRegister: 14)
// complete the cycle to set initial values
$0.run(forHalfCycles: 2)
// run for 16 cycles // run for 16 cycles
$0.run(forHalfCycles: 32) $0.run(forHalfCycles: 32)
@ -103,6 +115,9 @@ class MOS6522Tests: XCTestCase {
// ask to output 0x8c // ask to output 0x8c
$0.setValue(0x8c, forRegister: 0) $0.setValue(0x8c, forRegister: 0)
// complete the cycle
$0.run(forHalfCycles: 2)
// set current input as 0xda // set current input as 0xda
$0.portBInput = 0xda $0.portBInput = 0xda

View File

@ -90,11 +90,12 @@ class Speaker {
protected: protected:
void enqueue(std::function<void(void)> function) void enqueue(std::function<void(void)> function)
{ {
_queue->enqueue(function); function();
// _queue->enqueue(function);
} }
void flush() void flush()
{ {
_queue->flush(); // _queue->flush();
} }
std::unique_ptr<int16_t> _buffer_in_progress; std::unique_ptr<int16_t> _buffer_in_progress;