diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 309eaeceb..d9c250db3 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -16,28 +16,74 @@ namespace MOS { template class MOS6522 { public: - MOS6522() : _data_direction{0, 0} {} + MOS6522() : + _data_direction{0, 0}, + _timer_is_running{false, false} + {} void set_register(int address, uint8_t value) { printf("6522: %d <- %02x\n", address, value); -// switch(address) -// { -// case 0x11: _auxiliary_control_register = value; break; -// } + address &= 0xf; + switch(address) + { + // Timer 1 + case 0x06: case 0x04: _interval_timer_latch[0] = (_interval_timer_latch[0]&0xff00) | value; break; + case 0x05: case 0x07: + _interval_timer_latch[0] = (_interval_timer_latch[0]&0x00ff) | (uint16_t)(value << 8); + // TODO: clear interrupt flag + if(address == 0x05) + { + _interval_timer[0] = _interval_timer_latch[0]; + _timer_is_running[0] = true; + } + break; + + // Timer 2 + case 0x08: _interval_timer_latch[1] = value; break; + case 0x09: + // TODO: clear interrupt flag + _interval_timer[1] = _interval_timer_latch[1] | (uint16_t)(value << 8); + _timer_is_running[1] = true; + break; + + case 0x11: _auxiliary_control_register = value; break; + } } + uint8_t get_register(int address) { printf("6522: %d\n", address); + address &= 0xf; + switch(address) + { + // Timer 1 + case 0x04: + // TODO: clear interrupt flag + return _interval_timer[0] & 0x00ff; + case 0x05: return _interval_timer[0] >> 8; + case 0x06: return _interval_timer_latch[0] & 0x00ff; + case 0x07: return _interval_timer_latch[0] >> 8; + } + return 0xff; } + void run_for_cycles(unsigned int number_of_cycles) + { + _interval_timer[0] -= number_of_cycles; + _interval_timer[1] -= number_of_cycles; + // TODO: interrupts, potentially reload of the first timer, other status effects + } + private: - uint16_t _interval_timers[2]; + uint16_t _interval_timer[2], _interval_timer_latch[2]; uint8_t _shift_register; - uint8_t _input_latches[2]; + uint8_t _input_latch[2]; uint8_t _data_direction[2]; + bool _timer_is_running[2]; + uint8_t _interrupt_flag_register, _interrupt_enable_register; uint8_t _peripheral_control_register, _auxiliary_control_register; }; diff --git a/Components/6560/6560.cpp b/Components/6560/6560.cpp index 2ebba2aa7..f0b09adc7 100644 --- a/Components/6560/6560.cpp +++ b/Components/6560/6560.cpp @@ -56,12 +56,14 @@ MOS6560::MOS6560() : "uint iPhase = c & 7u;" "float phaseOffset = 6.283185308 * float(iPhase + 8u) / 8.0;" // TODO: appropriate phaseOffset - "return mix(step(1, c) * y, step(2, c) * sin(phase + phaseOffset), amplitude);" // TODO: square wave (step(3.141592654, mod(phase + phaseOffset, 6.283185308))?) + // sin(phase + phaseOffset) + "return mix(step(1, c) * y, step(2, c) * step(3.141592654, mod(phase + phaseOffset, 6.283185308)) * 2.0, amplitude);" // TODO: square wave (step(3.141592654, mod(phase + phaseOffset, 6.283185308))?) "}"); } void MOS6560::set_register(int address, uint8_t value) { + address &= 0xf; _registers[address] = value; switch(address) { @@ -114,7 +116,13 @@ void MOS6560::set_register(int address, uint8_t value) uint8_t MOS6560::get_register(int address) { - return _registers[address]; + address &= 0xf; + switch(address) + { + default: return _registers[address]; + case 0x03: return ((_vertical_counter >> 1) & 0x80) | (_registers[3] & 0x7f); + case 0x04: return _vertical_counter & 0xff; + } } diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Vic-20/Vic20.cpp index 389ae7580..3f32b44b8 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Vic-20/Vic20.cpp @@ -12,7 +12,9 @@ using namespace Vic20; -Machine::Machine() +Machine::Machine() : + _userPortVIA(new UserPortVIA()), + _keyboardVIA(new KeyboardVIA()) { set_reset_line(true); } @@ -58,10 +60,10 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin { _keyboardVIA->set_register(address - 0x9120, *value); } - - // TODO: the 6522 } + _userPortVIA->run_for_cycles(1); + _keyboardVIA->run_for_cycles(1); return 1; }