Skip to content

Commit 349e7f5

Browse files
committed
Make SoftCDI usable by all board type
1 parent f01dae9 commit 349e7f5

26 files changed

+388
-149
lines changed

src/CDI/CDI.cpp

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "CDI.hpp"
22
#include "boards/Mono3/Mono3.hpp"
3+
#include "boards/Mono3SoftCDI/Mono3SoftCDI.hpp"
34
#include "boards/SoftCDI/SoftCDI.hpp"
45

56
/** \brief Creates a new CD-i instance.
67
* \param board The type of board to use.
8+
* \param useSoftCDI false to use the regular LLE emulator, true to use some SoftCDI modules.
79
* \param systemBios System BIOS data.
810
* \param nvram The initial state of the NVRAM, or an empty span to use a clean NVRAM.
911
* \param config The player configuration.
@@ -18,7 +20,7 @@
1820
*
1921
* User needs to ensure the NVRAM data size corresponds to the NVRAM size in the config (or auto-detected).
2022
*/
21-
std::unique_ptr<CDI> CDI::NewCDI(Boards board, std::span<const uint8_t> systemBios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc)
23+
std::unique_ptr<CDI> CDI::NewCDI(Boards board, bool useSoftCDI, std::span<const uint8_t> systemBios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc)
2224
{
2325
const OS9::BIOS bios(systemBios);
2426

@@ -31,13 +33,22 @@ std::unique_ptr<CDI> CDI::NewCDI(Boards board, std::span<const uint8_t> systemBi
3133
switch(board)
3234
{
3335
case Boards::Mono3:
34-
return NewMono3(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
36+
if(useSoftCDI)
37+
return NewMono3SoftCDI(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
38+
else
39+
return NewMono3(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
3540

3641
case Boards::Mono4:
37-
return NewMono4(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
42+
if(useSoftCDI)
43+
return NewMono4SoftCDI(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
44+
else
45+
return NewMono4(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
3846

3947
case Boards::Roboco:
40-
return NewRoboco(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
48+
if(useSoftCDI)
49+
return NewRobocoSoftCDI(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
50+
else
51+
return NewRoboco(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
4152

4253
case Boards::SoftCDI:
4354
return NewSoftCDI(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
@@ -55,6 +66,14 @@ std::unique_ptr<CDI> CDI::NewMono3(OS9::BIOS bios, std::span<const uint8_t> nvra
5566
return std::make_unique<Mono3>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
5667
}
5768

69+
/** \brief Creates a new Mono3 player with SoftCDI modules.
70+
* See CDI::NewCDI for a description of the parameters.
71+
*/
72+
std::unique_ptr<CDI> CDI::NewMono3SoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc)
73+
{
74+
return std::make_unique<Mono3SoftCDI>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc));
75+
}
76+
5877
/** \brief Creates a new Mono4 player.
5978
* See CDI::NewCDI for a description of the parameters.
6079
*/
@@ -63,6 +82,14 @@ std::unique_ptr<CDI> CDI::NewMono4(OS9::BIOS bios, std::span<const uint8_t> nvra
6382
return std::make_unique<Mono3>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc), "Mono-IV");
6483
}
6584

85+
/** \brief Creates a new Mono4 player with SoftCDI modules.
86+
* See CDI::NewCDI for a description of the parameters.
87+
*/
88+
std::unique_ptr<CDI> CDI::NewMono4SoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc)
89+
{
90+
return std::make_unique<Mono3SoftCDI>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc), "Mono-IV");
91+
}
92+
6693
/** \brief Creates a new Roboco player.
6794
* See CDI::NewCDI for a description of the parameters.
6895
*/
@@ -71,6 +98,14 @@ std::unique_ptr<CDI> CDI::NewRoboco(OS9::BIOS bios, std::span<const uint8_t> nvr
7198
return std::make_unique<Mono3>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc), "Roboco");
7299
}
73100

101+
/** \brief Creates a new Roboco player with SoftCDI modules.
102+
* See CDI::NewCDI for a description of the parameters.
103+
*/
104+
std::unique_ptr<CDI> CDI::NewRobocoSoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc)
105+
{
106+
return std::make_unique<Mono3SoftCDI>(std::move(bios), nvram, std::move(config), std::move(callbacks), std::move(disc), "Roboco");
107+
}
108+
74109
/** \brief Creates a new SoftCDI player.
75110
* See CDI::NewCDI for a description of the parameters.
76111
*/
@@ -173,8 +208,31 @@ CDIDisc& CDI::GetDisc() noexcept
173208
return m_disc;
174209
}
175210

211+
void CDI::Scheduler(const std::stop_token stopToken)
212+
{
213+
m_isRunning = true;
214+
215+
do
216+
{
217+
const SCC68070::InterpreterResult res = m_cpu.SingleStep(25);
218+
const size_t cycles = res.first;
219+
220+
const double ns = cycles * m_cpu.cycleDelay;
221+
IncrementTime(ns);
222+
} while(!stopToken.stop_requested());
223+
224+
m_isRunning = false;
225+
}
226+
176227
void CDI::IncrementTime(const double ns)
177228
{
178229
m_slave->IncrementTime(ns);
179230
m_timekeeper->IncrementClock(ns);
180231
}
232+
233+
void CDI::Reset(bool resetCPU)
234+
{
235+
if(resetCPU)
236+
m_cpu.Reset();
237+
// TODO: reset slave and IRTC too?
238+
}

src/CDI/CDI.hpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ class CDI
3030
std::unique_ptr<ISlave> m_slave{}; /**< The slave processor. */
3131
std::unique_ptr<IRTC> m_timekeeper{}; /**< The NVRAM chip. */
3232

33-
static std::unique_ptr<CDI> NewCDI(Boards board, std::span<const uint8_t> systemBios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
34-
static std::unique_ptr<CDI> NewMono3(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
35-
static std::unique_ptr<CDI> NewMono4(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
36-
static std::unique_ptr<CDI> NewRoboco(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
37-
static std::unique_ptr<CDI> NewSoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
33+
static std::unique_ptr<CDI> NewCDI(Boards board, bool useSoftCDI, std::span<const uint8_t> systemBios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
34+
static std::unique_ptr<CDI> NewMono3(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
35+
static std::unique_ptr<CDI> NewMono3SoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
36+
static std::unique_ptr<CDI> NewMono4(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
37+
static std::unique_ptr<CDI> NewMono4SoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
38+
static std::unique_ptr<CDI> NewRoboco(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
39+
static std::unique_ptr<CDI> NewRobocoSoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
40+
static std::unique_ptr<CDI> NewSoftCDI(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config = DEFAULT_CDICONFIG, Callbacks callbacks = Callbacks(), CDIDisc disc = CDIDisc());
3841

3942
virtual ~CDI() noexcept;
4043

@@ -86,10 +89,12 @@ class CDI
8689
CDI(std::string_view boardName, CDIConfig config, Callbacks callbacks, CDIDisc disc = CDIDisc());
8790

8891
/** \brief Runs in a thread and schedule all the components. */
89-
virtual void Scheduler(std::stop_token stopToken) = 0;
92+
virtual void Scheduler(std::stop_token stopToken);
93+
/** \brief Increments the emulated time of all the components. */
9094
virtual void IncrementTime(double ns);
9195

92-
virtual void Reset(bool resetCPU) = 0;
96+
/** \brief Resets all the components. */
97+
virtual void Reset(bool resetCPU);
9398

9499
virtual uint8_t GetByte(uint32_t addr, BusFlags flags) = 0;
95100
virtual uint16_t GetWord(uint32_t addr, BusFlags flags) = 0;

src/CDI/CDIConfig.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct CDIConfig
1717
};
1818

1919
/** \brief Default configuration used by CDI if no one is provided. */
20-
inline constexpr CDIConfig DEFAULT_CONFIG{
20+
inline constexpr CDIConfig DEFAULT_CDICONFIG {
2121
.PAL = true,
2222
.initialTime = IRTC::DEFAULT_TIME,
2323
.has32KBNVRAM = false,

src/CDI/OS9/BIOS.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,14 @@ bool BIOS::ReplaceModule(std::span<const uint8_t> module)
105105
const char* name = reinterpret_cast<const char*>(&module[getArray32(module, 0x0C)]);
106106
const ModuleIterator old = std::find_if(m_modules.begin(), m_modules.end(), [&] (const ModuleHeader& header) -> bool { return header.name == name; });
107107

108-
if(old != m_modules.end() && module.size() <= old->M_Size) // Overwrite the old module if the new one fits.
109-
{
110-
memset(&m_memory[old->begin], 0, old->M_Size);
111-
memcpy(&m_memory[old->begin], module.data(), module.size());
108+
if(old == m_modules.end() || module.size() > old->M_Size) // Overwrite the old module if the new one fits.
109+
return false;
112110

113-
*old = ModuleHeader(&m_memory[old->begin], old->begin);
114-
return true;
115-
}
111+
memset(&m_memory[old->begin], 0, old->M_Size);
112+
memcpy(&m_memory[old->begin], module.data(), module.size());
116113

117-
return false;
114+
*old = ModuleHeader(&m_memory[old->begin], old->begin);
115+
return true;
118116
}
119117

120118
void BIOS::LoadModules()

src/CDI/OS9/BIOS.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class BIOS
8888

8989
const std::vector<ModuleHeader>& GetModules() const noexcept { return m_modules; }
9090

91+
/** \brief Replaces the module in the BIOS with the given one, matching by name.
92+
* \param module The new module. Must be smaller in size than the original one.
93+
* \return true on success, false on error.
94+
*/
9195
bool ReplaceModule(std::span<const uint8_t> module);
9296

9397
private:

src/CDI/OS9/SystemCalls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ std::string systemCallOutputsToString(const SystemCallType call, const std::map<
385385
case SystemCallType::I_ReadLn: snprintf(args, 256, "d1.l=%u", REG(D1)); break;
386386
case SystemCallType::I_WritLn: snprintf(args, 256, "d1.l=%u", REG(D1)); break;
387387
case SystemCallType::I_GetStt: snprintf(args, 256, "d0.l=%u d1.l=%u d2.l=%u", REG(D0), REG(D1), REG(D2)); break;
388-
case SystemCallType::I_SetStt: return "TODO";
388+
case SystemCallType::I_SetStt: snprintf(args, 256, "d0.l=%u d1.l=%u d2.l=%u", REG(D0), REG(D1), REG(D2)); break;
389389
case SystemCallType::I_Close: return "";
390390
default: snprintf(args, 256, "Unknown system call %d", static_cast<int>(call));
391391
}

src/CDI/boards/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
add_subdirectory(Mono3)
2+
add_subdirectory(Mono3SoftCDI)
23
add_subdirectory(SoftCDI)
4+
add_subdirectory(SoftCDIScheduler)

src/CDI/boards/Mono3/Mono3.cpp

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,17 @@ Mono3::~Mono3() noexcept
2323
Stop(true);
2424
}
2525

26-
void Mono3::Scheduler(const std::stop_token stopToken)
26+
void Mono3::IncrementTime(const double ns)
2727
{
28-
m_isRunning = true;
29-
30-
do
31-
{
32-
const SCC68070::InterpreterResult res = m_cpu.SingleStep(25);
33-
const size_t cycles = res.first;
34-
35-
const double ns = cycles * m_cpu.cycleDelay;
36-
CDI::IncrementTime(ns);
37-
m_mcd212.IncrementTime(ns);
38-
m_ciap.IncrementTime(ns);
39-
} while(!stopToken.stop_requested());
40-
41-
m_isRunning = false;
28+
CDI::IncrementTime(ns);
29+
m_mcd212.IncrementTime(ns);
30+
m_ciap.IncrementTime(ns);
4231
}
4332

4433
void Mono3::Reset(const bool resetCPU)
4534
{
35+
CDI::Reset(resetCPU);
4636
m_mcd212.Reset();
47-
if(resetCPU)
48-
m_cpu.Reset();
4937
}
5038

5139
uint32_t Mono3::GetTotalFrameCount()

src/CDI/boards/Mono3/Mono3.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
#include <span>
99

10-
class Mono3 : public CDI
10+
class Mono3 : virtual public CDI
1111
{
1212
public:
13+
static constexpr size_t BIOS_SIZE = 0x7'FFFF;
14+
1315
Mono3(OS9::BIOS bios, std::span<const uint8_t> nvram, CDIConfig config, Callbacks callbacks, CDIDisc disc = CDIDisc(), std::string_view boardName = "Mono-III");
1416
virtual ~Mono3() noexcept;
1517

16-
virtual void Scheduler(std::stop_token stopToken) override;
18+
virtual void IncrementTime(double ns) override;
1719

1820
virtual void Reset(bool resetCPU) override;
1921

@@ -45,7 +47,7 @@ class Mono3 : public CDI
4547
virtual const Video::Plane& GetBackground() override;
4648
virtual const Video::Plane& GetCursor() override;
4749

48-
private:
50+
protected:
4951
MCD212 m_mcd212;
5052
HLE::CIAP m_ciap;
5153
const uint32_t m_nvramMaxAddress;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
target_sources(CeDImu
2+
PRIVATE
3+
Mono3SoftCDI.cpp
4+
Mono3SoftCDI.hpp
5+
)

0 commit comments

Comments
 (0)