psx 0.1.4

Library for developing homebrew for the Sony PS1
Documentation
# psx-sdk-rs

This is a basic SDK to run custom Rust code on a Playstation 1. You'll need to
build the rust compiler from source. Building the compiler is computationally
expensive, so it may take quite a bit of time. See the [system requirements](https://rustc-dev-guide.rust-lang.org/getting-started.html#system-requirements)
for building the rust compiler for more specifics.

## Building the compiler

1. Clone the rust source and checkout this specific commit:

    ```
    git clone https://github.com/rust-lang/rust.git
    cd rust
    git checkout 2c858a7c3f189eb11ad89d9bf9f2e87cac9d2b76
    ```

2. Configure the build script to use `rust-lld` and optionally remove unnecessary targets to speed up the LLVM build:

    ```
    cp config.toml.example config.toml
    # Set lld to true
    sed -i 's/#lld = false/lld = true/' config.toml
    # Only build the MIPS and X86 targets
    sed -i 's/#targets.*$/targets = "Mips;X86"/' config.toml
    # Don't build any experimental targets
    sed -i 's/#experimental-targets.*$/experimental-targets = ""/' config.toml
    ```

3. Optionally patch LLVM to enable the `nightlier` feature. To use this feature set `max_atomic_width: Some(0),` to `Some(16)` in `patches/rustc_psx.patch` before applying it.

    ```
    git submodule update --init --progress src/llvm-project
    cd src/llvm-project
    git apply /path/to/patches/llvm_atomic_fence.patch
    ```


4. Patch the rust compiler. Applying these patches to a different commit may require manual intervention:

    ```
    git apply /path/to/patches/rustc_mips32.patch
    git apply /path/to/patches/rustc_psx.patch
    ```


5. Build the rust compiler:

    ```
    # For the initial build
    ./x.py build -i library/std
    # To rebuild
    ./x.py build -i library/std --keep-stage 1
    ```

6. Create a new toolchain with the patched compiler:

    ```
    rustup toolchain link psx build/x86_64-unknown-linux-gnu/stage1
    ```

    where `psx` is the name for the new toolchain.

## Installing cargo-psx

`cargo-psx` is an optional wrapper for cargo that sets some commonly required
flags and arguments. Basically this lets you just run `cargo psx run` instead of
`cargo run +psx -Z build-std=core,alloc --target mipsel-sony-psx`.

To install:

```
cargo install cargo-psx
```

To uninstall:

```
cargo uninstall cargo-psx
```

For more options:

```
cargo psx --help
```
    
## Usage

The `examples` directory has some demos which have been tested in
[mednafen](https://mednafen.github.io/) with the SCPH7001 BIOS. Getting stdout
may require setting `psx.dbg_level` in `mednafen.cfg` to at least 2. Other BIOS
versions/regions may work but have not been tested. To try out a demo run `cargo
psx run` from its directory. To use a different emulator run `cargo psx build`
then open the .exe in `/target/mipsel-sony-psx/release/`. To use `cargo psx run`
with other emulators change the
[runner](https://doc.rust-lang.org/cargo/reference/config.html#target) for the
`mipsel-sony-psx` target. Note that some examples may require building with
`cargo psx run --alloc` to link in the alloc crate.

### Program template

To create a new program just use `cargo init` and add `psx = "*"` to
`Cargo.toml` under `[dependencies]`. Then replace `src/main.rs` with the
following template

```rust
#![no_std]
#![no_main]

// This can be any import from the `psx` crate.
use psx;

#[no_mangle]
fn main() {
}
```

[`no_std`](https://docs.rust-embedded.org/embedonomicon/smallest-no-std.html#what-does-no_std-mean)
is required to link the `core` crate instead of `std`. `no_main` tells rustc to
make no assumption about the [program's entry
point](https://docs.rust-embedded.org/embedonomicon/smallest-no-std.html#the-code).
The attribute on `main` is required since the entry point defined in the `psx`
crate expects to call an [`unmangled
function`](https://docs.rust-embedded.org/book/interoperability/rust-with-c.html#no_mangle).
The `main` function should not return, but the return type can be either `()`,
`!` or `Result<()>`.

Optionally create a `.cargo` directory and a `config.toml` inside with the
following to allow running with `cargo psx run`

```
[target.mipsel-sony-psx]
runner = "mednafen"
```

## Documentation

See [docs.rs](https://docs.rs/psx/latest/psx/) for documentation. To regenerate documentation for the latest version of `psx`:

```
cd psx
cargo doc --target mipsel-unknown-linux-gnu
```

Then open `target/mipsel-unknown-linux-gnu/doc/psx/index.html` in a browser.