mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
Merge pull request #71 from TomHarte/IRQBenchTest
Introduces a one-cycle cost to setting 6522 timers
This commit is contained in:
commit
e5de9c8607
@ -90,7 +90,7 @@ template <class T> class MOS6522 {
|
||||
_registers.interrupt_flags &= ~InterruptFlag::Timer1;
|
||||
if(address == 0x05)
|
||||
{
|
||||
_registers.timer[0] = _registers.timer_latch[0];
|
||||
_registers.next_timer[0] = _registers.timer_latch[0];
|
||||
_timer_is_running[0] = true;
|
||||
}
|
||||
reevaluate_interrupts();
|
||||
@ -100,7 +100,7 @@ template <class T> class MOS6522 {
|
||||
case 0x8: _registers.timer_latch[1] = value; break;
|
||||
case 0x9:
|
||||
_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;
|
||||
reevaluate_interrupts();
|
||||
break;
|
||||
@ -242,7 +242,9 @@ template <class T> class MOS6522 {
|
||||
else\
|
||||
_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
|
||||
#define phase1() \
|
||||
@ -367,6 +369,7 @@ template <class T> class MOS6522 {
|
||||
struct Registers {
|
||||
uint8_t output[2], input[2], data_direction[2];
|
||||
uint16_t timer[2], timer_latch[2], last_timer[2];
|
||||
int next_timer[2];
|
||||
uint8_t shift;
|
||||
uint8_t auxiliary_control, peripheral_control;
|
||||
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},
|
||||
auxiliary_control(0), peripheral_control(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;
|
||||
|
||||
// control state
|
||||
|
@ -52,7 +52,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
|
||||
|
||||
// 024D = 0 => fast; otherwise slow
|
||||
// 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]);
|
||||
set_value_of_register(CPU6502::A, next_byte);
|
||||
|
@ -24,6 +24,9 @@ class MOS6522Tests: XCTestCase {
|
||||
$0.setValue(10, forRegister: 4)
|
||||
$0.setValue(0, forRegister: 5)
|
||||
|
||||
// complete the setting cycle
|
||||
$0.run(forHalfCycles: 2)
|
||||
|
||||
// run for 5 cycles
|
||||
$0.run(forHalfCycles: 10)
|
||||
|
||||
@ -42,6 +45,9 @@ class MOS6522Tests: XCTestCase {
|
||||
// change the low-byte latch
|
||||
$0.setValue(0x40, forRegister: 8)
|
||||
|
||||
// complete the cycle
|
||||
$0.run(forHalfCycles: 2)
|
||||
|
||||
// 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: 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
|
||||
$0.setValue(0x50, forRegister: 9)
|
||||
|
||||
// complete the cycle
|
||||
$0.run(forHalfCycles: 2)
|
||||
|
||||
// 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: 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 | 0x80, forRegister: 14)
|
||||
|
||||
// complete the cycle to set initial values
|
||||
$0.run(forHalfCycles: 2)
|
||||
|
||||
// run for 16 cycles
|
||||
$0.run(forHalfCycles: 32)
|
||||
|
||||
@ -103,6 +115,9 @@ class MOS6522Tests: XCTestCase {
|
||||
// ask to output 0x8c
|
||||
$0.setValue(0x8c, forRegister: 0)
|
||||
|
||||
// complete the cycle
|
||||
$0.run(forHalfCycles: 2)
|
||||
|
||||
// set current input as 0xda
|
||||
$0.portBInput = 0xda
|
||||
|
||||
|
@ -90,11 +90,12 @@ class Speaker {
|
||||
protected:
|
||||
void enqueue(std::function<void(void)> function)
|
||||
{
|
||||
_queue->enqueue(function);
|
||||
function();
|
||||
// _queue->enqueue(function);
|
||||
}
|
||||
void flush()
|
||||
{
|
||||
_queue->flush();
|
||||
// _queue->flush();
|
||||
}
|
||||
|
||||
std::unique_ptr<int16_t> _buffer_in_progress;
|
||||
|
Loading…
Reference in New Issue
Block a user