Skip to content

Commit 8ee8863

Browse files
committed
whoops
1 parent c45fb93 commit 8ee8863

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed

psp/src/lib.rs

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
#![allow(stable_features)]
2+
#![feature(
3+
alloc_error_handler,
4+
llvm_asm,
5+
global_asm,
6+
untagged_unions,
7+
core_intrinsics,
8+
const_loop,
9+
const_if_match,
10+
const_generics,
11+
c_variadic,
12+
lang_items,
13+
)]
14+
15+
// For unwinding support
16+
#![feature(std_internals, panic_info_message, panic_internals, unwind_attributes)]
17+
#![cfg_attr(not(feature = "stub-only"), feature(panic_unwind))]
18+
19+
// For the `const_generics` feature.
20+
#![allow(incomplete_features)]
21+
22+
#![cfg_attr(not(feature = "std"), no_std)]
23+
24+
#[macro_use] extern crate paste;
25+
#[cfg(not(feature = "stub-only"))] extern crate alloc;
26+
#[cfg(not(feature = "stub-only"))] extern crate panic_unwind;
27+
28+
#[macro_use]
29+
#[doc(hidden)]
30+
#[cfg(not(feature = "stub-only"))]
31+
pub mod debug;
32+
33+
#[macro_use] mod vfpu;
34+
mod eabi;
35+
pub mod math;
36+
pub mod sys;
37+
#[cfg(not(feature = "stub-only"))] pub mod test_runner;
38+
#[cfg(not(feature = "stub-only"))] pub mod vram_alloc;
39+
40+
#[cfg(not(feature = "stub-only"))] mod alloc_impl;
41+
#[cfg(not(feature = "stub-only"))] pub mod panic;
42+
43+
#[cfg(not(feature = "stub-only"))] mod screenshot;
44+
#[cfg(not(feature = "stub-only"))] pub use screenshot::*;
45+
46+
#[cfg(not(feature = "stub-only"))] mod benchmark;
47+
#[cfg(not(feature = "stub-only"))] pub use benchmark::*;
48+
49+
#[cfg(not(feature = "stub-only"))] mod constants;
50+
#[cfg(not(feature = "stub-only"))] pub use constants::*;
51+
52+
#[cfg(not(feature = "std"))]
53+
#[cfg(feature = "stub-only")]
54+
#[panic_handler]
55+
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
56+
57+
#[no_mangle]
58+
extern "C" fn __rust_foreign_exception() -> ! { loop {} }
59+
60+
#[cfg(feature = "std")]
61+
pub use std::panic::catch_unwind;
62+
63+
#[cfg(not(feature = "std"))]
64+
pub use panic::catch_unwind;
65+
66+
#[cfg(feature="embedded-graphics")]
67+
pub mod embedded_graphics;
68+
69+
#[repr(align(16))]
70+
pub struct Align16<T>(pub T);
71+
72+
#[cfg(all(target_os = "psp", not(feature = "stub-only")))]
73+
global_asm!(
74+
r#"
75+
.section .lib.ent.top, "a", @progbits
76+
.align 2
77+
.word 0
78+
.global __lib_ent_top
79+
__lib_ent_top:
80+
.section .lib.ent.btm, "a", @progbits
81+
.align 2
82+
.global __lib_ent_bottom
83+
__lib_ent_bottom:
84+
.word 0
85+
86+
.section .lib.stub.top, "a", @progbits
87+
.align 2
88+
.word 0
89+
.global __lib_stub_top
90+
__lib_stub_top:
91+
.section .lib.stub.btm, "a", @progbits
92+
.align 2
93+
.global __lib_stub_bottom
94+
__lib_stub_bottom:
95+
.word 0
96+
"#
97+
);
98+
99+
/// Declare a PSP module.
100+
///
101+
/// You must also define a `fn psp_main() { ... }` function in conjunction with
102+
/// this macro.
103+
#[macro_export]
104+
macro_rules! module {
105+
($name:expr, $version_major:expr, $version_minor: expr) => {
106+
#[doc(hidden)]
107+
mod __psp_module {
108+
#[no_mangle]
109+
#[link_section = ".rodata.sceModuleInfo"]
110+
#[used]
111+
static MODULE_INFO: $crate::Align16<$crate::sys::SceModuleInfo> = $crate::Align16(
112+
$crate::sys::SceModuleInfo {
113+
mod_attribute: 0,
114+
mod_version: [$version_major, $version_minor],
115+
mod_name: $crate::sys::SceModuleInfo::name($name),
116+
terminal: 0,
117+
gp_value: unsafe { &_gp },
118+
stub_top: unsafe { &__lib_stub_top },
119+
stub_end: unsafe { &__lib_stub_bottom },
120+
ent_top: unsafe { &__lib_ent_top },
121+
ent_end: unsafe { &__lib_ent_bottom },
122+
}
123+
);
124+
125+
extern {
126+
static _gp: u8;
127+
static __lib_ent_bottom: u8;
128+
static __lib_ent_top: u8;
129+
static __lib_stub_bottom: u8;
130+
static __lib_stub_top: u8;
131+
}
132+
133+
#[no_mangle]
134+
#[link_section = ".lib.ent"]
135+
#[used]
136+
static LIB_ENT: $crate::sys::SceLibraryEntry = $crate::sys::SceLibraryEntry {
137+
// TODO: Fix this?
138+
name: core::ptr::null(),
139+
version: ($version_major, $version_minor),
140+
attribute: $crate::sys::SceLibAttr::SCE_LIB_IS_SYSLIB,
141+
entry_len: 4,
142+
var_count: 1,
143+
func_count: 1,
144+
entry_table: &LIB_ENT_TABLE,
145+
};
146+
147+
#[no_mangle]
148+
#[link_section = ".rodata.sceResident"]
149+
#[used]
150+
static LIB_ENT_TABLE: $crate::sys::SceLibraryEntryTable = $crate::sys::SceLibraryEntryTable {
151+
module_start_nid: 0xd632acdb, // module_start
152+
module_info_nid: 0xf01d73a7, // SceModuleInfo
153+
module_start: module_start,
154+
module_info: &MODULE_INFO.0,
155+
};
156+
157+
#[no_mangle]
158+
extern "C" fn module_start(_argc: isize, _argv: *const *const u8) -> isize {
159+
use $crate::sys::ThreadAttributes;
160+
use core::ffi::c_void;
161+
162+
unsafe {
163+
extern fn main_thread(_argc: usize, _argv: *mut c_void) -> i32 {
164+
// TODO: Maybe print any error to debug screen?
165+
let _ = $crate::catch_unwind(|| {
166+
super::psp_main();
167+
});
168+
169+
0
170+
}
171+
172+
let id = $crate::sys::sceKernelCreateThread(
173+
&b"main_thread\0"[0],
174+
main_thread,
175+
// default priority of 32.
176+
32,
177+
// 256kb stack
178+
256 * 1024,
179+
ThreadAttributes::USER,
180+
core::ptr::null_mut(),
181+
);
182+
183+
$crate::sys::sceKernelStartThread(id, 0, core::ptr::null_mut());
184+
}
185+
186+
0
187+
}
188+
}
189+
}
190+
}
191+
192+
/// Enable the home button.
193+
///
194+
/// This API does not have destructor support yet. You can manually setup an
195+
/// exit callback if you need this, see the source code of this function.
196+
pub fn enable_home_button() {
197+
use core::{ptr, ffi::c_void};
198+
use sys::ThreadAttributes;
199+
200+
unsafe {
201+
unsafe extern fn exit_thread(_args: usize, _argp: *mut c_void) -> i32 {
202+
unsafe extern fn exit_callback(_arg1: i32, _arg2: i32, _arg: *mut c_void) -> i32 {
203+
sys::sceKernelExitGame();
204+
0
205+
}
206+
207+
let id = sys::sceKernelCreateCallback(
208+
&b"exit_callback\0"[0],
209+
exit_callback,
210+
ptr::null_mut(),
211+
);
212+
213+
sys::sceKernelRegisterExitCallback(id);
214+
sys::sceKernelSleepThreadCB();
215+
216+
0
217+
}
218+
219+
// Enable the home button.
220+
let id = sys::sceKernelCreateThread(
221+
&b"exit_thread\0"[0],
222+
exit_thread,
223+
32,
224+
0x1000,
225+
ThreadAttributes::empty(),
226+
ptr::null_mut(),
227+
);
228+
229+
sys::sceKernelStartThread(id, 0, ptr::null_mut());
230+
}
231+
}

0 commit comments

Comments
 (0)