diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Port.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Port.cs index 173314dfb5..14d89e0c43 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Port.cs @@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public int ReadPra(int pra, int ddra) { - return _readPrA(); + return (pra | ~ddra) & ReadExternalPra(); } public int ReadPrb(int prb, int ddrb) @@ -98,7 +98,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public int ReadPra(int pra, int ddra) { - return (pra | ~ddra) & 0xFF; + return (pra | ~ddra) & ReadExternalPra(); } public int ReadPrb(int prb, int ddrb) diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Registers.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Registers.cs index 1215121257..a5b122724b 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Registers.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.Registers.cs @@ -18,18 +18,16 @@ switch (addr) { case 0x0: - _ifr &= 0xE7; + if (_pcrCb2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_NEGATIVE_EDGE && _pcrCb2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_POSITIVE_EDGE) + _ifr &= 0xE7; if (_acrPbLatchEnable) - { return _pbLatch; - } break; case 0x1: - _ifr &= 0xFC; + if (_pcrCa2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_NEGATIVE_EDGE && _pcrCa2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_POSITIVE_EDGE) + _ifr &= 0xFC; if (_acrPaLatchEnable) - { return _paLatch; - } break; case 0x4: _ifr &= 0xBF; @@ -39,6 +37,7 @@ break; case 0xA: _ifr &= 0xFB; + _srCount = 8; break; case 0xF: if (_acrPaLatchEnable) @@ -58,6 +57,7 @@ case 0x0: return _port.ReadPrb(_prb, _ddrb); case 0x1: + case 0xF: return _port.ReadExternalPra(); case 0x2: return _ddrb; @@ -85,8 +85,6 @@ return _ifr; case 0xE: return _ier | 0x80; - case 0xF: - return _port.ReadExternalPra(); } return 0xFF; @@ -98,20 +96,17 @@ switch (addr) { case 0x0: - _ifr &= 0xE7; - if (_pcrCb2Control == PCR_CONTROL_HANDSHAKE_OUTPUT || _pcrCb2Control == PCR_CONTROL_PULSE_OUTPUT) - { + if (_pcrCb2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_NEGATIVE_EDGE && _pcrCb2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_POSITIVE_EDGE) + _ifr &= 0xE7; + if (_pcrCb2Control == PCR_CONTROL_PULSE_OUTPUT) _handshakeCb2NextClock = true; - } WriteRegister(addr, val); break; case 0x1: - _ifr &= 0xFC; - if (_pcrCa2Control == PCR_CONTROL_HANDSHAKE_OUTPUT || _pcrCa2Control == PCR_CONTROL_PULSE_OUTPUT) - { + if (_pcrCa2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_NEGATIVE_EDGE && _pcrCa2Control != PCR_CONTROL_INDEPENDENT_INTERRUPT_INPUT_POSITIVE_EDGE) + _ifr &= 0xFC; + if (_pcrCa2Control == PCR_CONTROL_PULSE_OUTPUT) _handshakeCa2NextClock = true; - } - WriteRegister(addr, val); break; case 0x4: @@ -146,6 +141,7 @@ break; case 0xA: _ifr &= 0xFB; + _srCount = 8; WriteRegister(addr, val); break; case 0xD: @@ -238,7 +234,7 @@ public int EffectivePrB => _prb | ~_ddrb; - public int ActualPrA => _acrPaLatchEnable ? _paLatch : _port.ReadExternalPra(); + public int ActualPrA => _acrPaLatchEnable ? _paLatch : _port.ReadPra(_pra, _ddra); public int ActualPrB => _acrPbLatchEnable ? _pbLatch : _port.ReadPrb(_prb, _ddrb); } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.cs index 147449bf9c..9c3ed0ed3d 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Via.cs @@ -58,6 +58,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS private int _acrSrControl; private int _acrT1Control; private int _acrT2Control; + private int _srCount; private bool _ca1L; private bool _ca2L; @@ -135,6 +136,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS Ca2 = true; Cb1 = true; Cb2 = true; + _srCount = 0; _pb6L = true; _pb6 = true; @@ -151,6 +153,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public void ExecutePhase() { + var _shiftIn = false; + var _shiftOut = false; + // Process delayed interrupts _ifr |= _interruptNextClock; _interruptNextClock = 0; @@ -259,9 +264,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS { _t2C--; if (_t2C == 0) - { _ifr |= 0x20; - } _t2C &= 0xFFFF; } break; @@ -330,24 +333,28 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS // interrupt generation - /* - As long as the CA1 interrupt flag is set, the data on the peripheral pins can change - without affecting the data in the latches. This input latching can be used with any of the CA2 - input or output modes. - It is important to note that on the PA port, the processor always reads the data on the - peripheral pins (as reflected in the latches). For output pins, the processor still reads the - latches. This may or may not reflect the data currently in the ORA. Proper system operation - requires careful planning on the part of the system designer if input latching is combined - with output pins on the peripheral ports. - */ + if (_acrSrControl == ACR_SR_CONTROL_DISABLED) + { + _ifr &= 0xFB; + _srCount = 0; + } + + /* + As long as the CA1 interrupt flag is set, the data on the peripheral pins can change + without affecting the data in the latches. This input latching can be used with any of the CA2 + input or output modes. + It is important to note that on the PA port, the processor always reads the data on the + peripheral pins (as reflected in the latches). For output pins, the processor still reads the + latches. This may or may not reflect the data currently in the ORA. Proper system operation + requires careful planning on the part of the system designer if input latching is combined + with output pins on the peripheral ports. + */ if ((_pcrCa1IntControl == PCR_INT_CONTROL_POSITIVE_EDGE && Ca1 && !_ca1L) || (_pcrCa1IntControl == PCR_INT_CONTROL_NEGATIVE_EDGE && !Ca1 && _ca1L)) { if (_acrPaLatchEnable && (_ifr & 0x02) == 0) - { - _paLatch = _port.ReadExternalPra(); - } + _paLatch = _port.ReadExternalPra(); _ifr |= 0x02; } @@ -362,29 +369,22 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS (_pcrCb1IntControl == PCR_INT_CONTROL_NEGATIVE_EDGE && !Cb1 && _cb1L)) { if (_acrPbLatchEnable && (_ifr & 0x10) == 0) - { - _pbLatch = _port.ReadPrb(_prb, _ddrb); - } + _pbLatch = _port.ReadPrb(_prb, _ddrb); + if (_acrSrControl == ACR_SR_CONTROL_DISABLED) + _shiftIn = true; _ifr |= 0x10; } - switch (_acrSrControl) + if (_shiftIn) { - case ACR_SR_CONTROL_DISABLED: - _ifr &= 0xFB; - break; - default: - break; + _sr <<= 1; + _sr |= Cb2 ? 1 : 0; } if ((_ifr & _ier & 0x7F) != 0) - { _ifr |= 0x80; - } else - { _ifr &= 0x7F; - } _ca1L = Ca1; _ca2L = Ca2; @@ -444,6 +444,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS ser.Sync("T2Delayed", ref _t2Delayed); ser.Sync("ResetPb7NextClock", ref _resetPb7NextClock); ser.Sync("SetPb7NextClock", ref _setPb7NextClock); + ser.Sync("ShiftRegisterCount", ref _srCount); } } }