a-steps.md
hello.rs
lang.rs
module.s
psp.json
raw.rs
utils.rs
> % rustc hello.rs --target=psp -lpspdebug -lpspdisplay -lpspge -lm -lc -lpspuser -lgcc
> % psp-fixup-imports hello && psp-prxgen hello hello.prx
#![no_std] | |
#![no_main] | |
#![feature(intrinsics, lang_items, linkage)] | |
mod lang; | |
mod raw; | |
mod utils; | |
#[no_mangle] | |
pub extern "C" fn main() { | |
extern { | |
fn pspDebugScreenInit(); | |
} | |
unsafe { | |
pspDebugScreenInit(); | |
} | |
utils::print("Hello World!"); | |
} |
// Lang items and intrinsics | |
#[lang = "copy"] | |
trait Copy {} | |
#[lang = "sized"] | |
trait Sized {} | |
#[lang = "sync"] | |
trait Sync {} | |
extern "rust-intrinsic" { | |
pub fn abort() -> !; | |
pub fn transmute<F, T>(from: F) -> T; | |
} |
.section .lib.ent.top, "a", @progbits | |
.align 2 | |
.word 0 | |
__lib_ent_top: | |
.section .lib.ent.btm, "a", @progbits | |
.align 2 | |
__lib_ent_bottom: | |
.word 0 | |
.section .lib.stub.top, "a", @progbits | |
.align 2 | |
.word 0 | |
__lib_stub_top: | |
.section .lib.stub.btm, "a", @progbits | |
.align 2 | |
__lib_stub_bottom: | |
.word 0 | |
.global __lib_ent_top | |
.global __lib_ent_bottom | |
.global __lib_stub_top | |
.global __lib_stub_bottom |
{ | |
"data-layout": "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32", | |
"llvm-target": "mipsallegrexel-unknown-psp-elf", | |
"target-endian": "little", | |
"target-word-size": "32", | |
"arch": "mips", | |
"os": "psp", | |
"cpu": "mips32", | |
"features": "+eabi,-mips32,-o32", | |
"morestack": false, | |
"no-compiler-rt": true, | |
"executables": true, | |
"linker": "psp-gcc", | |
"position_independant_executables": true, | |
"function-sections": false, | |
"relocation-model": "static", | |
"linker_is_gnu": true, | |
"pre-link-args": [ | |
"-fPIC", | |
"-L/scratch/laden/local/pspsdk/psp/sdk/lib", | |
"-specs=/scratch/laden/local/pspsdk/psp/sdk/lib/prxspecs", | |
"-Wl,-q,-T/scratch/laden/local/pspsdk/psp/sdk/lib/linkfile.prx", | |
"/scratch/laden/local/pspsdk/psp/sdk/lib/prxexports.o", | |
"module.s" | |
] | |
} |
#[allow(dead_code)] | |
#[repr(C)] | |
pub struct SceModuleInfo { | |
mod_attribute: u16, | |
mod_version: [u8, ..2], | |
mod_name: [i8, ..27], | |
terminal: i8, | |
gp_value: *const (), | |
ent_top: *const (), | |
ent_end: *const (), | |
stub_top: *const (), | |
stub_end: *const () | |
} | |
extern { | |
static _gp: *const i8; | |
static __lib_ent_top: *const i8; | |
static __lib_ent_bottom: *const (); | |
static __lib_stub_top: *const (); | |
static __lib_stub_bottom: *const (); | |
} | |
#[no_mangle] | |
#[link_section = ".rodata.sceModuleInfo"] | |
#[linkage = "external"] | |
#[allow(non_upper_case_globals)] | |
pub static module_info: SceModuleInfo = | |
SceModuleInfo { | |
mod_attribute: 0, // 0 - User mode | |
mod_version: [0, 1], | |
mod_name: [0, ..27], | |
terminal: 0, | |
gp_value: &_gp as *const _ as *const (), | |
ent_top: &__lib_ent_top as *const _ as *const (), | |
ent_end: &__lib_ent_bottom as *const _ as *const (), | |
stub_top: &__lib_stub_top as *const _ as *const (), | |
stub_end: &__lib_stub_bottom as *const _ as *const (), | |
}; |
use lang::transmute; | |
static NL: &'static str = "\n\0"; | |
extern { | |
fn printf(format: *const u8, ...) -> i32; | |
fn pspDebugScreenPrintf(format: *const u8, ...); | |
} | |
pub fn print(s: &str) { | |
unsafe { | |
// Get the pointer & size for the passed in string | |
let (ptr, sz): (*const u8, i32) = transmute(s); | |
// The format string for printf | |
let (fptr, _): (*const u8, i32) = transmute("%.*s\0"); | |
//printf(fptr, sz, ptr); | |
pspDebugScreenPrintf(fptr, sz, ptr); | |
} | |
} | |
pub fn println(s: &str) { | |
print(s); | |
unsafe { | |
let (np, _): (*const u8, i32) = transmute(NL); | |
printf(np); | |
} | |
} |