# OpenBIOS

## Purpose of this project

There are several goals from the code in this directory.

### Educational

Writing an emulator requires extensive knowledge of the machine being emulated. The BIOS of the PlayStation is part of it, and is obviously required to boot the machine and start games. This work is done so that both the author and the reader can perfect their understanding of its internals.

As a result, the code written here tries to be as close as possible to the original, bugs, quirks and all included. You may notice some anti-patterns while reading the code, like buffer overflows or arithmetic mistakes. They are intentional, and a direct reflection of what the retail BIOS does. Some of these bugs are weird enough that it's difficult to infer the original buggy C code, while still understanding the general intent. Some of these bugs are severe enough that they have been fixed, but mentions are usually added to explain what changed and why.

Note that the generated binary will be nowhere close to the original rom this is inspired from. This is caused by several different factors: codestyle isn't identical for a start, and some optimizations have been put in place still, such as the way syscalls are being issued. Linking order will also throw off some of the mappings. And finally, today's compilers generate much smarter code than before. So the same C code won't generate the same assembly code for two different compilers. There is also some dead or duplicated code in there that'd be useless or meaningless to reproduce. Finally, the shell itself is radically different.

### Ease of distribution

While dumping an original PlayStation disc is something that is fairly easy to do for anyone using any sort of compact disc reader connected to a personal computer, dumping the bios of a retail machine, while not impossible, is a somewhat harder feat. As a result, people are often relying on bios dumps done by third party people, which ought to be considered copyright violation. Also, some emulators have a "HLE" bios, which creates a maintenance burden for each emulator, as well as being a complex mix of LLE and HLE code.

### Testing

Any recent project needs automated testing. Having source code available for all parts of the emulator will improve testing availability and test coverage, hopefully, for both the emulator, and the bios code.

## Building

The currently supported build method for this project requires docker. You can use the `dockermake.sh` script at the root of the repository as a replacement for the `make` command, and use the `Makefile` present here. Under Windows, the `build.bat` can be used. If using [Visual Studio Code](https://code.visualstudio.com/), one can use the task "make_openbios" to compile: CTRL-P then `task make_openbios` to compile.

It is also possible to build using any PS1 compatible compiler, but this isn't the current method used in the CI, so it's mostly untested. Check [PSYQo's getting started](../psyqo/GETTING_STARTED.md) document to install such toolchain in case docker isn't an acceptable solution to build this project.

The result of the compilation should be a file called `openbios.elf` that contains all useful debugging symbols, and a file called `openbios.bin` which can be used in emulators or even burned to a chip and placed on a retail console.

The Makefile features several toggles to mutate the way the compilation works. Don't forget to run `make clean` prior to try a different set of compilation options.

- `BUILD=SmallDebug` will produce a working, yet somewhat debuggable version of the code.
- `BOOT=cart` will build the kernel as an expansion port ROM, bootable from an Action Replay or similar cheat carts. This will disable support for booting from a cart in order to prevent bootlooping.
- `BOARD=system573` will build a kernel that can run on the Konami System 573 arcade board. Note that this option is only useful alongside `EMBED_PSEXE`, as it will force `BOOT=rom` and `BOOT_MODE=psexe` due to the 573's different CD-ROM hardware.
- `EMBED_PSEXE=binary.ps-exe` will embed the specified executable into the kernel and run it before the shell.
- `BOOT_MODE=fast` will skip running the shell and try booting from the CD-ROM after the embedded executable returns, or immediately on boot if `EMBED_PSEXE` is not used. Note that the code will *not* wait for a disc to be inserted after the executable returns. The old `FASTBOOT=true` option is kept for compatibility and is equivalent to `BOOT_MODE=fast`.
- `BOOT_MODE=psexe` will remove the shell and CD-ROM boot code altogether. This is meant to be used alongside `EMBED_PSEXE` to build ROMs for arcade systems and such, which typically use non-standard storage devices and require a custom shell.
- `SPLASH_SCREEN=true` will make the kernel display color bars on screen during initialization. This is also done by some official non-retail BIOS variants and is useful when using the `EMBED_PSEXE` option with a large (100+ KB) binary, as relocating it to RAM will take a couple of seconds.
- `INSTALL_TTY_CONSOLE=true` will make OpenBIOS install a DTL-H2000 host console driver in place of the default "dummy" TTY driver. Note that this is *not* the DUART driver found in a retail BIOS.

## Status

This subproject is fairly functional and usable. OpenBIOS does almost all the same things as the retail BIOS does when booting, and implements most of its features. [Many games](https://docs.google.com/spreadsheets/d/1UNGs7uYb8viAbm7YJaf1CR4dkgX7ZzntUdcowGsjcVc/edit?usp=sharing) are booting and working properly with this code. It can be used in emulators or on the real console, either while replacing the rom chip, or by using the "cart" build and programming the flash chip of a cheat cart with the result.

Please feel free to report bugs encountered while using this project.

## Organization

The BIOS is split in two major parts: the low level code for the bios itself, and the shell, which is the binary that's being loaded into memory at boot time by the bios, to display the SONY sound and logo, and has a small utility menu for playing audio discs, or shuffling around memory cards.

While the first part is the main one that's being targeted here, the second one hasn't been reversed, and fully replaced with a completely different project. This may change in the future, but this isn't currently the focus of this project.

The original code was most likely chunked into several sub-projects, that were all linked together like a giant patchwork. This approach is less readable, and for this reason, we're not going to do this. However this will result in the ROM/RAM split to be less obvious, and slower at times than the original. Tuning of the hot functions is eventually required.

The startup point for the ROM version is the function `_reset` located in [`boot/psx.s`](boot/psx.s) (or [`boot/system573.s`](boot/system573.s) depending on which board the kernel is compiled for). The rom cart version is the function `_cartBoot` in the same file.

## Direction

The primary repository for this project is a subdirectory of PCSX-Redux at the moment, because building, testing and integration as a single bloc of code is much more practical than separate repositories. If the need arise however, it should be possible to move it as a separate repository elsewhere. There is currently a [buildable read-only mirror available](https://github.com/pcsx-redux/nugget/tree/main/openbios).

## Technicalities

The code has been rewritten based off the reverse engineering of a dump of the BIOS of an american SCPH-7001 machine (MD5 `1e68c231d0896b7eadcad1d7d8e76129`). The System 573 specific parts are based on the kernel of the Konami 700B01 ROM (MD5 `d6960997e499f39047b64fa73e6ff382`).

The ghidra database for it is currently being hosted on a server, alongside a few other pieces of software being reversed. Contact one of the authors if you want access.

## Commentary

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.

## Legality

*Disclaimer: the author is not a lawyer, and the following statement hasn't been reviewed by a professional of the law, so the rest of this document cannot be taken as legal advice.*

As explained above, this code has been written using disassembly and reverse engineering of a retail bios the author dumped from a second hand console. The same exact methodology was employed by Connectix for their PS1 bios. The conclusion of [their lawsuit](https://en.wikipedia.org/wiki/Sony_Computer_Entertainment,_Inc._v._Connectix_Corp.), and that of [Sega v. Accolade](https://en.wikipedia.org/wiki/Sega_Enterprises,_Ltd._v._Accolade,_Inc.) seems to indicate that this project here follows and is impacted by the same doctrine.
