Skip to content

Commit 8edaf75

Browse files
committed
Support little endian system ROM files
1 parent 87bf082 commit 8edaf75

File tree

6 files changed

+26
-3
lines changed

6 files changed

+26
-3
lines changed

src/CDI/CDI.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
/** \brief Creates a new CD-i instance.
55
* \param board The type of board to use.
6-
* \param systemBios System BIOS data.
6+
* \param systemBios System BIOS data (in big endian format).
77
* \param nvram The initial state of the NVRAM, or an empty span to use a clean NVRAM.
88
* \param config The player configuration.
99
* \param callbacks The user callbacks to use.
1010
* \param disc The disc to load (optional).
11-
* \return nullptr if it failed to initialize the new CDI.
11+
* \return nullptr if the BIOS is not supported or if it failed to auto detect the CDI BIOS type.
1212
*
1313
* If \p board is Boards::AutoDetect, then the board type will be guessed from the BIOS data.
1414
* It may not be accurate so when possible, consider providing yourself the board type.

src/CeDImu.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "CeDImu.hpp"
22
#include "GUI/MainFrame.hpp"
33
#include "CDI/CDI.hpp"
4+
#include "CDI/common/utils.hpp"
45
#include "CDI/OS9/SystemCalls.hpp"
56

67
#include <wx/image.h>
@@ -59,6 +60,14 @@ int CeDImu::OnExit()
5960
return 0;
6061
}
6162

63+
/** \brief Swaps each odd and even bytes in the given buffer. */
64+
static constexpr void swapWords(std::span<uint8_t> data) noexcept
65+
{
66+
assert(isEven(data.size()));
67+
for(size_t i = 0; i < data.size(); i += 2)
68+
std::swap(data[i], data[i + 1]);
69+
}
70+
6271
bool CeDImu::InitCDI(const Config::BiosConfig& biosConfig)
6372
{
6473
{
@@ -80,6 +89,8 @@ bool CeDImu::InitCDI(const Config::BiosConfig& biosConfig)
8089

8190
std::unique_ptr<uint8_t[]> bios = std::make_unique<uint8_t[]>(biosSize);
8291
biosFile.read(reinterpret_cast<char*>(bios.get()), biosSize);
92+
if(biosConfig.littleEndianBios)
93+
swapWords({bios.get(), biosSize});
8394

8495
std::unique_ptr<uint8_t[]> nvramBuffer = nullptr;
8596
m_biosName = biosConfig.name;

src/Config.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const BiosConfig defaultBiosConfig {
1414
.boardType = Boards::AutoDetect,
1515
.PAL = false,
1616
.has32KbNvram = false,
17+
.littleEndianBios = false,
1718
};
1819

1920
// Disc
@@ -91,6 +92,9 @@ bool loadConfig()
9192

9293
if(!conf.Read("has32KbNvram", &val)) return false;
9394
entry.has32KbNvram = val;
95+
96+
if(!conf.Read("littleEndianBios", &val)) return false;
97+
entry.littleEndianBios = val;
9498
}
9599

96100
return true;
@@ -130,6 +134,7 @@ bool saveConfig()
130134
if(!conf.Write("boardType", static_cast<int>(entry.boardType))) return false;
131135
if(!conf.Write("PAL", entry.PAL)) return false;
132136
if(!conf.Write("has32KbNvram", entry.has32KbNvram)) return false;
137+
if(!conf.Write("littleEndianBios", entry.littleEndianBios)) return false;
133138
}
134139

135140
return conf.Flush(); // Technically it saves twice, here and in the dtor, but np I hope.

src/Config.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct BiosConfig
1919
Boards boardType;
2020
bool PAL;
2121
bool has32KbNvram;
22+
bool littleEndianBios;
2223
};
2324

2425
extern const BiosConfig defaultBiosConfig;

src/GUI/SettingsFrame.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,14 @@ SettingsFrame::SettingsFrame(MainFrame* parent)
137137
boardChoiceSizer->Add(m_boardChoice, wxSizerFlags(1).Expand());
138138
boardChoiceSizer->Add(boardChoiceText);
139139

140-
// PAL and NVRAM check boxes
140+
// PAL, NVRAM and little endian check boxes
141141
m_palCheckBox = new wxCheckBox(biosConfigPage, wxID_ANY, "PAL");
142142
m_nvramCheckBox = new wxCheckBox(biosConfigPage, wxID_ANY, "32KB NVRAM");
143+
m_littleEndianCheckBox = new wxCheckBox(biosConfigPage, wxID_ANY, "Little endian");
143144
wxBoxSizer* checkBoxSizer = new wxBoxSizer(wxHORIZONTAL);
144145
checkBoxSizer->Add(m_palCheckBox, wxSizerFlags(1).Border());
145146
checkBoxSizer->Add(m_nvramCheckBox, wxSizerFlags(1).Border());
147+
checkBoxSizer->Add(m_littleEndianCheckBox, wxSizerFlags(1).Border());
146148

147149
// Initial timestamp
148150
m_initialTime = new wxTextCtrl(biosConfigPage, wxID_ANY);
@@ -339,6 +341,7 @@ void SettingsFrame::LoadSelection()
339341
m_boardChoice->SetSelection(static_cast<int>(config.boardType));
340342
m_palCheckBox->SetValue(config.PAL);
341343
m_nvramCheckBox->SetValue(config.has32KbNvram);
344+
m_littleEndianCheckBox->SetValue(config.littleEndianBios);
342345
}
343346

344347
void SettingsFrame::SaveSelection()
@@ -354,6 +357,7 @@ void SettingsFrame::SaveSelection()
354357
config.boardType = static_cast<Boards>(m_boardChoice->GetSelection());
355358
config.PAL = m_palCheckBox->GetValue();
356359
config.has32KbNvram = m_nvramCheckBox->GetValue();
360+
config.littleEndianBios = m_littleEndianCheckBox->GetValue();
357361
}
358362

359363
void SettingsFrame::CheckControls()
@@ -367,4 +371,5 @@ void SettingsFrame::CheckControls()
367371
m_boardChoice->Enable(enable);
368372
m_palCheckBox->Enable(enable);
369373
m_nvramCheckBox->Enable(enable);
374+
m_littleEndianCheckBox->Enable(enable);
370375
}

src/GUI/SettingsFrame.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class SettingsFrame : public wxFrame
3131
wxChoice* m_boardChoice;
3232
wxCheckBox* m_palCheckBox;
3333
wxCheckBox* m_nvramCheckBox;
34+
wxCheckBox* m_littleEndianCheckBox;
3435
wxTextCtrl* m_initialTime;
3536

3637
int m_keyUp;

0 commit comments

Comments
 (0)