mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
80 lines
1.6 KiB
C++
80 lines
1.6 KiB
C++
#include "pch.h"
|
|
#include "WS/WsSerial.h"
|
|
#include "WS/WsConsole.h"
|
|
#include "Utilities/Serializer.h"
|
|
|
|
WsSerial::WsSerial(WsConsole* console)
|
|
{
|
|
_console = console;
|
|
}
|
|
|
|
uint8_t WsSerial::Read(uint16_t port)
|
|
{
|
|
switch(port) {
|
|
case 0xB1: return _state.ReceiveBuffer;
|
|
|
|
case 0xB3:
|
|
UpdateState();
|
|
return (
|
|
(_state.HasReceiveData ? 0x01 : 0) |
|
|
(_state.ReceiveOverflow ? 0x02 : 0) |
|
|
(_state.HasSendData ? 0 : 0x04) |
|
|
(_state.HighSpeed ? 0x40 : 0) |
|
|
(_state.Enabled ? 0x80 : 0)
|
|
);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void WsSerial::Write(uint16_t port, uint8_t value)
|
|
{
|
|
switch(port) {
|
|
case 0xB1:
|
|
_state.SendBuffer = value;
|
|
_state.HasSendData = true;
|
|
_state.SendClock = _console->GetMasterClock();
|
|
break;
|
|
|
|
case 0xB3:
|
|
_state.Enabled = value & 0x80;
|
|
_state.HighSpeed = value & 0x40;
|
|
if(value & 0x20) {
|
|
_state.ReceiveOverflow = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WsSerial::UpdateState()
|
|
{
|
|
if(_state.HasSendData) {
|
|
//At 9600 bauds/s, it takes 3200 master clocks to send 1 byte
|
|
//At 38400 (high speed mode), it takes 800 master clocks
|
|
int cyclesPerByte = _state.HighSpeed ? 800 : 3200;
|
|
uint64_t cyclesElapsed = _console->GetMasterClock() - _state.SendClock;
|
|
if(cyclesElapsed > cyclesPerByte) {
|
|
_state.HasSendData = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool WsSerial::HasSendIrq()
|
|
{
|
|
if(_state.HasSendData) {
|
|
UpdateState();
|
|
}
|
|
return _state.Enabled && !_state.HasSendData;
|
|
}
|
|
|
|
void WsSerial::Serialize(Serializer& s)
|
|
{
|
|
SV(_state.Enabled);
|
|
SV(_state.HighSpeed);
|
|
SV(_state.HasReceiveData);
|
|
SV(_state.HasSendData);
|
|
SV(_state.SendBuffer);
|
|
SV(_state.SendClock);
|
|
SV(_state.ReceiveBuffer);
|
|
SV(_state.ReceiveOverflow);
|
|
}
|