forked from kstenerud/Musashi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqsm.h
122 lines (99 loc) · 3.31 KB
/
qsm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma once
#include <deque>
#include <mutex>
#include "peripheralBase.h"
#include "peripheralTypes.h"
#include "qspi.h"
#include "port.h"
namespace mc68k
{
class Mc68k;
class Qsm final : public PeripheralBase<g_qsmBase, g_qsmSize>
{
public:
using SpiTxCallback = std::function<void(uint16_t, uint8_t)>;
using SpiTxFinishCallback = std::function<void(uint8_t)>;
enum class Sccr1Bits
{
SendBreak,
ReceiverWakeup,
ReceiverEnable,
TransmitterEnable,
IdleLineInterruptEnable,
ReceiverInterruptEnable,
TransmitCompleteInterruptEnable,
TransmitInterruptEnable,
WakeupByAddressMark,
ModeSelect,
ParityEnable,
ParityType,
IdleLineDetectType,
WiredOrModeForSciPins,
LoopMode,
};
enum class ScsrBits
{
ParityError,
FramingError,
NoiseError,
OverrunError,
IdleLineDetected,
ReceiverActive,
ReceiveDataRegisterFull,
TransmitComplete,
TransmitDataRegisterEmpty
};
Qsm(Mc68k& _mc68k);
void write16(PeriphAddress _addr, uint16_t _val) override;
uint16_t read16(PeriphAddress _addr) override;
void write8(PeriphAddress _addr, uint8_t _val) override;
uint8_t read8(PeriphAddress _addr) override;
void injectInterrupt(ScsrBits _scsrBits);
void exec(uint32_t _deltaCycles) override;
uint16_t spcr0() { return PeripheralBase::read16(PeriphAddress::Spcr0); }
uint16_t spcr1() { return PeripheralBase::read16(PeriphAddress::Spcr1); }
uint16_t spcr2() { return PeripheralBase::read16(PeriphAddress::Spcr2); }
uint16_t spcr3() { return PeripheralBase::read16(PeriphAddress::Spcr3); }
uint8_t spsr() { return PeripheralBase::read8(PeriphAddress::Spsr); }
void spcr0(uint16_t _value) { PeripheralBase::write16(PeriphAddress::Spcr0, _value); }
void spcr1(uint16_t _value) { PeripheralBase::write16(PeriphAddress::Spcr1, _value); }
void spcr2(uint16_t _value) { PeripheralBase::write16(PeriphAddress::Spcr2, _value); }
void spcr3(uint16_t _value) { PeripheralBase::write16(PeriphAddress::Spcr3, _value); }
void spsr(uint8_t _value) { PeripheralBase::write8(PeriphAddress::Spsr, _value); }
void writeSciRX(uint16_t _data);
void readSciTX(std::deque<uint16_t>& _dst);
Port& getPortQS() { return m_portQS; }
void setSpiWriteCallback(const SpiTxCallback& _callback);
void setSpiWriteFinishCallback(const SpiTxFinishCallback& _callback);
private:
void startTransmit(bool _startAtZero = false);
void finishTransfer();
void execTransmit();
void cancelTransmit();
static uint16_t bitTest(uint16_t _value, Sccr1Bits _bit);
uint16_t bitTest(Sccr1Bits _bit);
uint16_t bitTest(ScsrBits _bit);
void clear(ScsrBits _bit);
void set(ScsrBits _bit);
uint16_t readSciRX();
static PeriphAddress transmitRamAddr(uint8_t _offset);
static PeriphAddress receiveRamAddr(uint8_t _offset);
void writeSciData(uint16_t _data);
uint16_t readSciStatus();
Mc68k& m_mc68k;
Port m_portQS;
Qspi m_qspi;
uint8_t m_nextQueue = 0xff;
uint32_t m_spiDelay = 0;
std::deque<uint16_t> m_spiTxData;
std::mutex m_mutexSciTx;
std::deque<uint16_t> m_sciTxData;
std::mutex m_mutexSciRx;
std::deque<uint16_t> m_sciRxData;
bool m_sciRxDataEmpty = true;
uint32_t m_sciRxDelay = 0;
uint16_t m_pendingTxDataCounter = 0;
SpiTxCallback m_spiTxCallback = [](uint16_t, uint8_t) {};
SpiTxFinishCallback m_spiTxFinishCallback = [](uint8_t) {};
};
}