Skip to content

Commit 32e74e5

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fuckit
2 parents 6b43700 + b77eed3 commit 32e74e5

31 files changed

+397
-268
lines changed

.github/workflows/macos-build.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ jobs:
4646
- uses: n1hility/cancel-previous-runs@v2
4747
with:
4848
token: ${{ secrets.GITHUB_TOKEN }}
49-
- name: Update brew
50-
run: |
51-
brew update --preinstall
5249
- name: Install dependencies
5350
run: ./.github/scripts/install-brew-dependencies.sh
5451
- name: Fetch submodules

src/core/psxmem.cc

Lines changed: 124 additions & 146 deletions
Large diffs are not rendered by default.

src/core/psxmem.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,19 @@ class Memory {
223223

224224
IO<MemoryAsFile> getMemoryAsFile() { return m_memoryAsFile; }
225225

226+
bool isiCacheEnabled() { return m_BIU == 0x1e988; }
227+
226228
private:
227229
friend class MemoryAsFile;
228230
IO<MemoryAsFile> m_memoryAsFile;
229231

230-
int m_writeok = 1;
231232
uint32_t m_biosCRC = 0;
232233

233234
// Shared memory wrappers, pointers below point to these where appropriate
234235
SharedMem m_wramShared;
235236

237+
uint32_t m_BIU = 0;
238+
236239
// hopefully this should become private eventually, with only certain classes having direct access.
237240
public:
238241
uint8_t *m_wram = nullptr; // Kernel & User Memory (8 Meg)

src/gui/gui.cc

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ static void drop_callback(GLFWwindow* window, int count, const char** paths) {
170170

171171
void LoadImguiBindings(lua_State* lState);
172172

173-
ImFont* PCSX::GUI::loadFont(const PCSX::u8string& name, int size, ImGuiIO& io, const ImWchar* ranges, bool combine) {
173+
ImFont* PCSX::GUI::loadFont(const PCSX::u8string& name, int size, ImGuiIO& io, const ImWchar* ranges, bool combine,
174+
bool isBaseFont) {
175+
if (!ranges) ranges = io.Fonts->GetGlyphRangesDefault();
176+
174177
const System::Range knownRange = System::Range(reinterpret_cast<uintptr_t>(ranges));
175178
if (knownRange == System::Range::KOREAN) ranges = io.Fonts->GetGlyphRangesKorean();
176179
if (knownRange == System::Range::JAPANESE) ranges = io.Fonts->GetGlyphRangesJapanese();
@@ -180,6 +183,28 @@ ImFont* PCSX::GUI::loadFont(const PCSX::u8string& name, int size, ImGuiIO& io, c
180183
if (knownRange == System::Range::THAI) ranges = io.Fonts->GetGlyphRangesThai();
181184
if (knownRange == System::Range::VIETNAMESE) ranges = io.Fonts->GetGlyphRangesVietnamese();
182185

186+
static std::vector<ImWchar> rangesVector;
187+
188+
if (isBaseFont) {
189+
for (unsigned i = 0; ranges[i] != 0; i++) {
190+
rangesVector.push_back(ranges[i]);
191+
}
192+
193+
rangesVector.push_back(0x2190); // ←: U+2190 ↑: U+2191
194+
rangesVector.push_back(0x2193); // →: U+2192 ↓: U+2193
195+
rangesVector.push_back(0x25b3); // △: U+25B3
196+
rangesVector.push_back(0x25b3);
197+
rangesVector.push_back(0x25ef); // ◯: U+25EF
198+
rangesVector.push_back(0x25ef);
199+
rangesVector.push_back(0x2610); // ☐: U+2610
200+
rangesVector.push_back(0x2610);
201+
rangesVector.push_back(0x2715); // ✕: U+2715
202+
rangesVector.push_back(0x2715);
203+
204+
rangesVector.push_back(0);
205+
ranges = rangesVector.data();
206+
}
207+
183208
decltype(s_imguiUserErrorFunctor) backup = [](const char*) {};
184209
std::swap(backup, s_imguiUserErrorFunctor);
185210
ImFontConfig cfg;
@@ -852,15 +877,15 @@ void PCSX::GUI::startFrame() {
852877
io.Fonts->AddFontDefault();
853878
for (auto& scale : scales) {
854879
m_mainFonts[scale] = loadFont(MAKEU8("NotoSans-Regular.ttf"), settings.get<MainFontSize>().value * scale,
855-
io, g_system->getLocaleRanges());
880+
io, g_system->getLocaleRanges(), false, true);
856881
for (auto e : g_system->getLocaleExtra()) {
857-
loadFont(e.first, settings.get<MainFontSize>().value * scale, io, e.second, true);
882+
loadFont(e.first, settings.get<MainFontSize>().value * scale, io, e.second, true, false);
858883
}
859884
// try loading the japanese font for memory card manager
860885
m_hasJapanese = loadFont(MAKEU8("NotoSansCJKjp-Regular.otf"), settings.get<MainFontSize>().value * scale,
861-
io, reinterpret_cast<const ImWchar*>(PCSX::System::Range::JAPANESE), true);
862-
m_monoFonts[scale] =
863-
loadFont(MAKEU8("NotoMono-Regular.ttf"), settings.get<MonoFontSize>().value * scale, io, nullptr);
886+
io, reinterpret_cast<const ImWchar*>(PCSX::System::Range::JAPANESE), true, false);
887+
m_monoFonts[scale] = loadFont(MAKEU8("NotoMono-Regular.ttf"), settings.get<MonoFontSize>().value * scale,
888+
io, nullptr, false, false);
864889
}
865890
io.Fonts->Build();
866891
io.FontDefault = m_mainFonts.begin()->second;

src/gui/gui.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ class GUI final : public UI {
440440
bool m_hasJapanese = false;
441441
float m_currentScale = 1.0f;
442442

443-
ImFont *loadFont(const PCSX::u8string &name, int size, ImGuiIO &io, const ImWchar *ranges, bool combine = false);
443+
ImFont *loadFont(const PCSX::u8string &name, int size, ImGuiIO &io, const ImWchar *ranges, bool combine,
444+
bool isBaseFont);
444445

445446
bool m_reloadFonts = true;
446447
Widgets::ShaderEditor m_outputShaderEditor = {"output"};

src/mips/common/hardware/flushcache.s

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
3+
MIT License
4+
5+
Copyright (c) 2024 PCSX-Redux authors
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
*/
26+
27+
.include "common/hardware/hwregs.inc"
28+
29+
/* This version of the cache flush routine is designed to be used from
30+
the main ram, and is completely position-independent. This is inspired
31+
from a main-ram version of FlushCache found in the PAL game TOCA World
32+
Touring Cars, SLES-02572. The order of operations is important: the
33+
BIU_CONFIG register has to be modified *after* changing cop0 Status.
34+
Note that normally, nops are required after mutating cop0 Status or
35+
BIU_CONFIG, but since we are running from uncached ram, the pipeline
36+
stalls caused by accessing the SDRAM are enough. */
37+
38+
.section .text.flushCache, "ax", @progbits
39+
.align 2
40+
.set noreorder
41+
.global flushCache
42+
.type flushCache, @function
43+
44+
flushCache:
45+
/* Saves $ra to $t6, and the current cop0 Status register to $t0, and ensure we
46+
are running from uncached ram. */
47+
li $t1, 0xa0000000
48+
move $t6, $ra
49+
bal 1f
50+
mfc0 $t0, $12
51+
1:
52+
or $t1, $ra, $t1
53+
addiu $t1, 4 * 4 /* Jumps to the next instruction after the delay slot. */
54+
jr $t1
55+
56+
/* First, disables interrupts. */
57+
mtc0 $0, $12
58+
59+
/* Writes 0x0001e90c to the BIU_CONFIG register at 0xfffe0130.
60+
This will let us continue to run from uncached memory, while
61+
allowing us to access the i-cache. We keep the constant in
62+
$t2, so we can reuse it later when re-enabling the i-cache. */
63+
li $t5, BIU_CONFIG
64+
li $t2, 0x0001e90c
65+
sw $t2, 0($t5)
66+
67+
/* Isolates the cache, and disables interrupts. */
68+
li $t1, 0x10000
69+
mtc0 $t1, $12
70+
71+
/* Clears only the relevant parts of the i-cache. */
72+
li $t3, 0
73+
li $t4, 0x0f80
74+
75+
1:
76+
sw $0, 0x00($t3)
77+
sw $0, 0x10($t3)
78+
sw $0, 0x20($t3)
79+
sw $0, 0x30($t3)
80+
sw $0, 0x40($t3)
81+
sw $0, 0x50($t3)
82+
sw $0, 0x60($t3)
83+
sw $0, 0x70($t3)
84+
bne $t3, $t4, 1b
85+
addiu $t3, 0x80
86+
87+
/* First, un-isolate the cache. */
88+
mtc0 $0, $12
89+
/* Then, restore the BIU_CONFIG register to 0x0001e988. */
90+
addiu $t2, 0x7c
91+
sw $t2, 0($t5)
92+
/* Finally, restore the cop0 Status register, and return. It
93+
might be unwise to do the mtc0 in the jr delay slot, in
94+
case we arrive back at a cop2 instruction, but further
95+
testing could be useful. */
96+
mtc0 $t0, $12
97+
jr $t6
98+
nop

src/mips/openbios/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ The ghidra database for it is currently being hosted on a server, alongside a fe
6363

6464
## Commentary
6565

66-
The retail PlayStation BIOS code is a constellation of bugs and bad design. It is very obvious the code has been written hastily, likely by different teams having little to no communication with each other, under heavy time pressure. The fact that the retail console boots at all is nothing short of a miracle. Half of the provided libc in the A0 table is buggy. The BIOS code is barely able to initialize the CD-Rom, and read the game's binary off of it to boot it; anything beyond that will be crippled with bugs. And this only is viable if you respect a very strict method to create your CD-Rom. The memory card and gamepad code is a steaming-hot heap of human excrement. The provided GPU stubs are inefficient at best. The only sane thing that any software running on the PlayStation ought to do is to immediately disable interrupts, grab the function pointer located at 0x00000310 for `FlushCache`, in order put it inside a wrapper that disables interrupts before calling it, and then trash the whole memory to install its own code. The only reason `FlushCache` is required from the retail code is because since the function will unplug the main memory bus off the CPU in order to work, it HAS to run from the 0xbfc0 memory map, which will still be connected. Anything else from the retail code is virtually useless, and shouldn't be relied upon. That being said, doing so will prevent tools from functioning properly, like cheat software, unirom, or even emulators that are sniffing the kernel to do debugging and reporting.
66+
The retail PlayStation BIOS code is a constellation of bugs and bad design. It is very obvious the code has been written hastily, likely by different teams having little to no communication with each other, under heavy time pressure. The fact that the retail console boots at all is nothing short of a miracle. Half of the provided libc in the A0 table is buggy. The BIOS code is barely able to initialize the CD-Rom, and read the game's binary off of it to boot it; anything beyond that will be crippled with bugs. And this only is viable if you respect a very strict method to create your CD-Rom. The memory card and gamepad code is a steaming-hot heap of human excrement. The provided GPU stubs are inefficient at best. The only sane thing that any software running on the PlayStation ought to do is to immediately disable interrupts, and then trash the whole memory to install its own code. Anything from the retail code is virtually useless, and shouldn't be relied upon. That being said, doing so will prevent tools from functioning properly, like cheat software, unirom, or even emulators that are sniffing the kernel to do debugging and reporting.
6767

6868
## Legality
6969

src/mips/openbios/boot/boot.s

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ _reset:
4444
sw $t0, RAM_SIZE
4545

4646
/* this may be here to let the hardware pick up the new bus settings
47-
before moving on with the actual code. */
47+
before moving on with the actual code. Also, some tools like IDA
48+
or even PCSX-Redux use it as a signature to detect this is a PS1
49+
BIOS file. */
4850
nop
4951
nop
5052
nop
@@ -71,7 +73,7 @@ _reset:
7173

7274
.ascii "OpenBIOS"
7375

74-
.section .text, "ax", @progbits
76+
.section .text._boot, "ax", @progbits
7577
.align 2
7678
.global _boot
7779
.type _boot, @function
@@ -106,14 +108,6 @@ _boot:
106108
li $t0, 0x80777
107109
sw $t0, SBUS_DEV8_CTRL
108110

109-
/* Extra from OpenBIOS, not in the original BIOS:
110-
in case we booted from a cart, we move the
111-
flushCache pointer at 0x310 to our own storage,
112-
so we can use it later. */
113-
lw $t0, 0x310($0)
114-
lui $t1, %hi(__flush_cache_real_bios_ptr)
115-
sw $t0, %lo(__flush_cache_real_bios_ptr)($t1)
116-
117111
/* clearing out all registers */
118112
.set push
119113
.set noat
@@ -227,54 +221,12 @@ bss_init_skip:
227221
stop:
228222
b stop
229223

224+
.section .text._cartBoot, "ax", @progbits
230225
.set noreorder
231226
.global _cartBoot
232-
.global cartBootCop0Hook
233227
.type _cartBoot, @function
234228

235229
_cartBoot:
236-
/* place a rough breakpoint at 0x314, which will capture
237-
the memcpy call writing the A0 table, after it's done
238-
copying the flushCache pointer in memory */
239-
lui $t0, 0b1100101010000000
240-
li $t1, 0x0314
241-
li $t2, 0xffff
242-
mtc0 $0, $7
243-
mtc0 $t1, $5
244-
mtc0 $t2, $9
245-
mtc0 $t0, $7
246-
lui $t9, %hi(cartBootCop0Hook)
247-
lw $t0, (%lo(cartBootCop0Hook)+0x00)($t9)
248-
lw $t1, (%lo(cartBootCop0Hook)+0x04)($t9)
249-
lw $t2, (%lo(cartBootCop0Hook)+0x08)($t9)
250-
lw $t3, (%lo(cartBootCop0Hook)+0x0c)($t9)
251-
sw $t0, 0x40($0)
252-
sw $t1, 0x44($0)
253-
sw $t2, 0x48($0)
254-
/* ironically, what we just did technically requires
255-
calling flushCache, but since our whole point here
256-
is to grab its pointer, we obviously cannot, and
257-
we're going to rely on determinicity instead, which
258-
means some emulators may break on this */
259-
jr $ra
260-
sw $t3, 0x4c($0)
261-
262-
cartBootCop0Hook:
263-
/* and finally, after the above breakpoint triggers,
264-
we jump to _reset in order to boot our own
265-
version of the bios and kernel, but don't
266-
forget to disable the breakpoint, otherwise
267-
we'll be in trouble */
268230
la $t0, _reset
269231
j $t0
270232
mtc0 $0, $7
271-
272-
.global flushCacheFromRealBios
273-
.type flushCacheFromRealBios, @function
274-
275-
flushCacheFromRealBios:
276-
lui $t0, %hi(__flush_cache_real_bios_ptr)
277-
lw $t0, %lo(__flush_cache_real_bios_ptr)($t0)
278-
nop
279-
jr $t0
280-
nop

src/mips/openbios/kernel/flushcache.s

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,73 @@ SOFTWARE.
2626

2727
.include "common/hardware/hwregs.inc"
2828

29-
.section .text, "ax", @progbits
29+
/* This flushCache is a variant of the one found in the common/hardware/flushcache.s
30+
file. It is a bit more straightforward as there is no need to ensure that the
31+
code is run from the 0xbfc bios space, since the syscall will ensure that. */
32+
33+
.section .text.flushCache, "ax", @progbits
34+
.align 2
35+
.set noreorder
36+
.global flushCache
37+
.type flushCache, @function
38+
39+
flushCache:
40+
/* Saves the cop0 Status register to $t0. */
41+
mfc0 $t0, $12
42+
/* First, disables interrupts. */
43+
mtc0 $0, $12
44+
45+
/* Writes 0x0001e90c to the BIU_CONFIG register at 0xfffe0130.
46+
This will let us continue to run from uncached memory, while
47+
allowing us to access the i-cache. We keep the constant in
48+
$t2, so we can reuse it later when re-enabling the i-cache. */
49+
li $t5, BIU_CONFIG
50+
li $t2, 0x0001e90c
51+
sw $t2, 0($t5)
52+
53+
/* Isolates the cache, and disables interrupts. */
54+
li $t1, 0x10000
55+
mtc0 $t1, $12
56+
57+
/* Clears only the relevant parts of the i-cache. */
58+
li $t3, 0
59+
li $t4, 0x0f80
60+
61+
1:
62+
sw $0, 0x00($t3)
63+
sw $0, 0x10($t3)
64+
sw $0, 0x20($t3)
65+
sw $0, 0x30($t3)
66+
sw $0, 0x40($t3)
67+
sw $0, 0x50($t3)
68+
sw $0, 0x60($t3)
69+
sw $0, 0x70($t3)
70+
bne $t3, $t4, 1b
71+
addiu $t3, 0x80
72+
73+
/* First, un-isolate the cache. */
74+
mtc0 $0, $12
75+
/* Then, restore the BIU_CONFIG register to 0x0001e988. */
76+
addiu $t2, 0x7c
77+
sw $t2, 0($t5)
78+
/* Finally, restore the cop0 Status register, and return. It
79+
might be unwise to do the mtc0 in the jr delay slot, in
80+
case we arrive back at a cop2 instruction, but further
81+
testing could be useful. */
82+
mtc0 $t0, $12
83+
jr $ra
84+
nop
85+
86+
/* The code below is still kept as a reference, since it was directly reversed
87+
from the retail bios, but it is not used anymore. */
88+
89+
.section .text.flushCacheOriginal, "ax", @progbits
3090
.align 2
31-
.global flushCacheImpl
32-
.type flushCacheImpl, @function
91+
.set reorder
92+
.global flushCacheOriginal
93+
.type flushCacheOriginal, @function
3394

34-
flushCacheImpl:
95+
flushCacheOriginal:
3596
mfc0 $t3, $12
3697
nop
3798

0 commit comments

Comments
 (0)