Skip to content

Commit 074e449

Browse files
committedJul 17, 2023
シリアル通信・割り込みを一部実装
1 parent ebbdc2d commit 074e449

7 files changed

+160
-6
lines changed
 

‎dmge/Main.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "Audio/APU.h"
99
#include "Timer.h"
1010
#include "Joypad.h"
11+
#include "Serial.h"
1112
#include "Interrupt.h"
1213
#include "Address.h"
1314
#include "Timing.h"
@@ -95,7 +96,7 @@ class DmgeApp
9596

9697
showDebugMonitor_ = config_.showDebugMonitor;
9798

98-
mem_.init(&ppu_, &apu_, &timer_, &joypad_, &lcd_, &interrupt_);
99+
mem_.init(&ppu_, &apu_, &timer_, &joypad_, &lcd_, &interrupt_, &serial_);
99100

100101
joypad_.setButtonAssign(config_.gamepadButtonAssign);
101102

@@ -508,6 +509,13 @@ class DmgeApp
508509
timer_.update();
509510
}
510511

512+
// Serial
513+
514+
for (int i : step(cycles))
515+
{
516+
serial_.update();
517+
}
518+
511519
// PPU
512520

513521
for (int i : step(cycles / doubleSpeedFactor))
@@ -587,6 +595,8 @@ class DmgeApp
587595

588596
dmge::Joypad joypad_{ &mem_ };
589597

598+
dmge::Serial serial_{ interrupt_ };
599+
590600
dmge::DebugMonitor debugMonitor_{ &mem_, &cpu_, &apu_, &interrupt_ };
591601

592602
// モード(通常 or トレース)

‎dmge/Memory.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Audio/APU.h"
66
#include "Timer.h"
77
#include "Joypad.h"
8+
#include "Serial.h"
89
#include "Interrupt.h"
910
#include "DebugPrint.h"
1011

@@ -18,12 +19,13 @@ namespace dmge
1819
{
1920
}
2021

21-
void Memory::init(PPU* ppu, APU* apu, dmge::Timer* timer, dmge::Joypad* joypad, LCD* lcd, Interrupt* interrupt)
22+
void Memory::init(PPU* ppu, APU* apu, dmge::Timer* timer, dmge::Joypad* joypad, LCD* lcd, Interrupt* interrupt, Serial* serial)
2223
{
2324
ppu_ = ppu;
2425
apu_ = apu;
2526
timer_ = timer;
2627
joypad_ = joypad;
28+
serial_ = serial;
2729
lcd_ = lcd;
2830
interrupt_ = interrupt;
2931
}
@@ -185,9 +187,8 @@ namespace dmge
185187
{
186188
// Serial
187189
// 0xff01 - 0xff02
188-
// ...
189190

190-
goto Fallback_WriteToMemory;
191+
serial_->writeRegister(addr, value);
191192
}
192193
else if (addr <= 0xff03)
193194
{
@@ -507,7 +508,8 @@ namespace dmge
507508
{
508509
// Serial
509510
// 0xff01 - 0xff02
510-
// ...
511+
512+
return serial_->readRegister(addr);
511513
}
512514
else if (addr <= 0xff03)
513515
{

‎dmge/Memory.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace dmge
1111
class APU;
1212
class Timer;
1313
class Joypad;
14+
class Serial;
1415
class LCD;
1516
class Interrupt;
1617

@@ -21,7 +22,7 @@ namespace dmge
2122

2223
~Memory();
2324

24-
void init(PPU* ppu, APU* apu, dmge::Timer* timer, dmge::Joypad* joypad, LCD* lcd, Interrupt* interrupt);
25+
void init(PPU* ppu, APU* apu, dmge::Timer* timer, dmge::Joypad* joypad, LCD* lcd, Interrupt* interrupt, Serial* serial);
2526

2627
void reset();
2728

@@ -78,6 +79,7 @@ namespace dmge
7879
APU* apu_ = nullptr;
7980
Timer* timer_ = nullptr;
8081
Joypad* joypad_ = nullptr;
82+
Serial* serial_ = nullptr;
8183
LCD* lcd_ = nullptr;
8284
Interrupt* interrupt_ = nullptr;
8385

‎dmge/Serial.cpp

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include "stdafx.h"
2+
#include "Serial.h"
3+
#include "Address.h"
4+
#include "Interrupt.h"
5+
#include "BitMask/InterruptFlag.h"
6+
7+
namespace dmge
8+
{
9+
namespace
10+
{
11+
int SerialClockCycles(SerialClockSpeed speed)
12+
{
13+
return speed == SerialClockSpeed::Normal ? 512 : 16;
14+
}
15+
}
16+
17+
Serial::Serial(Interrupt& interrupt)
18+
: interrupt_{ interrupt }
19+
{
20+
}
21+
22+
void Serial::writeRegister(uint16 addr, uint8 value)
23+
{
24+
switch (addr)
25+
{
26+
case Address::SB:
27+
transferData_ = value;
28+
break;
29+
30+
case Address::SC:
31+
if (value >> 7)
32+
{
33+
remainBits_ = (uint8)8;
34+
clockSpeed_ = static_cast<SerialClockSpeed>((value >> 1) & 1);
35+
clockSource_ = static_cast<SerialClockSource>(value & 1);
36+
37+
clock_ = SerialClockCycles(clockSpeed_);
38+
}
39+
break;
40+
}
41+
}
42+
43+
uint8 Serial::readRegister(uint16 addr) const
44+
{
45+
switch (addr)
46+
{
47+
case Address::SB:
48+
return transferData_;
49+
50+
case Address::SC:
51+
return ((uint8)transfering() << 7) | (((uint8)clockSpeed_) << 1) | ((uint8)clockSource_);
52+
}
53+
54+
return 0;
55+
}
56+
57+
bool Serial::transfering() const
58+
{
59+
return remainBits_.has_value();
60+
}
61+
62+
void Serial::update()
63+
{
64+
if (not transfering()) return;
65+
66+
if (clock_ > 0)
67+
{
68+
if (--clock_ == 0)
69+
{
70+
transferData_ = (transferData_ << 1) | 1;
71+
*remainBits_ -= 1;
72+
73+
if (*remainBits_ == 0)
74+
{
75+
// 転送が終わった
76+
remainBits_.reset();
77+
interrupt_.request(BitMask::InterruptFlagBit::Serial);
78+
}
79+
else
80+
{
81+
clock_ = SerialClockCycles(clockSpeed_);
82+
}
83+
}
84+
}
85+
}
86+
}

‎dmge/Serial.h

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#pragma once
2+
3+
namespace dmge
4+
{
5+
enum class SerialClockSource : uint8
6+
{
7+
External = 0,
8+
Internal = 1
9+
};
10+
11+
enum class SerialClockSpeed : uint8
12+
{
13+
Normal = 0,
14+
Fast = 1
15+
};
16+
17+
class Interrupt;
18+
19+
class Serial
20+
{
21+
public:
22+
Serial(Interrupt& interrupt);
23+
24+
void writeRegister(uint16 addr, uint8 value);
25+
26+
uint8 readRegister(uint16 addr) const;
27+
28+
bool transfering() const;
29+
30+
void update();
31+
32+
private:
33+
Interrupt& interrupt_;
34+
35+
// SB (0xFF01)
36+
uint8 transferData_ = 0;
37+
38+
// SB (0xff02)
39+
40+
Optional<uint8> remainBits_{};
41+
SerialClockSpeed clockSpeed_{};
42+
SerialClockSource clockSource_{};
43+
44+
uint8 clock_ = 0;
45+
};
46+
}

‎dmge/dmge.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
<ClCompile Include="Memory.cpp" />
145145
<ClCompile Include="PPU.cpp" />
146146
<ClCompile Include="RTC.cpp" />
147+
<ClCompile Include="Serial.cpp" />
147148
<ClCompile Include="stdafx.cpp">
148149
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
149150
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
@@ -280,6 +281,7 @@
280281
<ClInclude Include="PPUConstants.h" />
281282
<ClInclude Include="PPUMode.h" />
282283
<ClInclude Include="RTC.h" />
284+
<ClInclude Include="Serial.h" />
283285
<ClInclude Include="stdafx.h" />
284286
<ClInclude Include="TileData.h" />
285287
<ClInclude Include="TileMapAttribute.h" />

‎dmge/dmge.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@
156156
<ClCompile Include="Audio\WaveChannel.cpp">
157157
<Filter>Source Files\Audio</Filter>
158158
</ClCompile>
159+
<ClCompile Include="Serial.cpp">
160+
<Filter>Source Files</Filter>
161+
</ClCompile>
159162
</ItemGroup>
160163
<ItemGroup>
161164
<Image Include="App\icon.ico">
@@ -532,5 +535,8 @@
532535
<ClInclude Include="Version.h">
533536
<Filter>Header Files</Filter>
534537
</ClInclude>
538+
<ClInclude Include="Serial.h">
539+
<Filter>Header Files</Filter>
540+
</ClInclude>
535541
</ItemGroup>
536542
</Project>

0 commit comments

Comments
 (0)
Please sign in to comment.