The PC-FX is a video game system by NEC and Hudson Soft.
I became interested in it in late April 2014. Being a Virtual Boy programmer, it appealed to me as it is based on the NEC V810 architecture. I started collecting information about it and here is a summary of everything I know. I hope this helps those who are interested in writing homebrew software for the PC-FX.
I do not actually own a PC-FX because of the high price and shipping cost.
Currently, this page is a dumping ground, but it may be better organized in the future.
I do not guarantee any accuracy of this information. Use at your own risk.
All of this code requires at least MV810ASM - see Development software below. Also see the rest of this page for more programming notes.
The documentation for the 7up chips is intended for the PC Engine, but it also applies to the PC-FX.
I will primarily concentrate on DOS and Win32, and how to develop using only legally obtainable software (not Hudson's original development software, which is hard to legally obtain).
MV810ASM is my V810 assembler. It is flexible, well-documented, and very easy to use.
You can assemble your code and create a PC-FX CD image with a simple batch file.
@MV810ASM %1 temp.bin %2 %3 %4 %5 %6 %7 %8 %9 @IF NOT ERRORLEVEL 1 PCFX-CDLINK makecd.txt cdout
It requires PCFX-CDLink (makecd.txt is its configuration file) - see below.
PCFX-CDLink (or "pcfx-cdlink" for the nihilistic) is a program by Alex Marshall that generates PC-FX CD images. You will need it regardless of whether you use MV810ASM or GCC. It is part of Eris - see below.
The program requires a text file that specifies the CD metadata. For example:
binary temp.bin name Untitled maker Matej Horvat makerid MH! date 20141223 country 1 version 256
For Win32, there is a precompiled version available. It also runs on DOS with the HX DOS extender.
For other platforms, you will have to get the source code and patches and compile it yourself. Good luck, because I haven't been able to do it on Win32 with Cygwin, OS X, or Haiku. Rumor has it that it cannot be compiled with GCC 3 or later (quality!) and apparently not even Haiku's patched GCC 2.95 is good enough.
Alex Marshall has written a library for GCC called Eris. You can download my precompiled version, which also includes Win32 versions of the BinCat and PCFX-CDLink programs and has makefiles adjusted for use in Windows. Note: my version is based on the revision from March 31, 2012, so you will have to apply any changes made since then yourself (and then please share them with me). Or you can ask nicely and I will do it.
You will probably want to use batch files to automate usage of GCC as much as possible. First, you will have to set environment variables:
@REM Set this to your GCC directory. The variable name is of no significance, @REM but it is used by Eris makefiles. @SET V810DEV=X:\gccpcfx @REM Set your PATH to include GCC and more, e.g. PCFX-CDLink and the MagicKit @REM PC Engine assembler. @SET PATH=%V810DEV%\bin;%PATH% @REM (In the lib directory, the subdirectories "eris" and "eris\low" must exist @REM for Eris.) @SET LIBRARY_PATH=%V810DEV%\lib @SET C_INCLUDE_PATH=%V810DEV%\include
Then, to compile a minimal C project where the whole program fits into RAM and nothing is loaded from the CD (as I haven't experimented with that yet), something like this (assuming that environment variables are already set):
@ECHO OFF REM Compile object files. In this example, we only use one. Using more is left REM as an exercise for the reader. gcc -I%V810DEV%\include -mv810 -O2 main.c -c -o temp.o REM Add libraries and produce an ELF executable. ld temp.o -L%V810DEV%\lib\ -lgcc -T pcfx.ld -o main.elf REM Create a raw executable from ELF. objcopy -O binary -R .stack -R .zdata main.elf temp.bin REM Concatenate (or just pad in this case) the raw executable. REM pcfxout.bin is the output file, pcfxlbas.h contains the CD sector numbers REM of concatenated files. bincat pcfxout.bin pcfxlbas.h temp.bin REM In this example, we do everything in one step, so this file isn't needed: DEL pcfxlbas.h REM Make a CD image (cdout.cue and cdout.bin) with metadata from pcfxcdlk.txt. pcfx-cdlink pcfxcdlk.txt cdout REM Produce a disassembly, if you are curious. objdump -d main.elf > main.lst REM Delete temporary files. DEL temptemp.* DEL pcfxout.bin DEL main.elf
The batch file above depends on this linker script, here called pcfx.ld. Note: if LD complains about a missing _start symbol, change
This assembler is useful because of its ability to convert PCX pictures into the 7up background tile and sprite formats with the
.incbat directives (see its DOC\PCE\USAGE.TXT file for details).
It is distributed as a DOS executable (BIN\PCEAS.EXE in the archive) and comes with source code which should be possible to compile on other platforms as well.
MagicEngine FX appears to be unable to use CD images.
Xe has a nonstandard(?) CD image format that cannot easily be converted from images created with PCFX-CDLink.
This section contains information I've found out myself that isn't explicitly mentioned in other documentation.
All assembly code is for MV810ASM (see above).
The PC-FX can boot in three ways:
Alternatively, one could boot from a CD containing a program that would listen to one of the controller ports (or both). Then, a custom (parallel port?) adapter could be used on a PC to "bit-bang" data to the PC-FX. This might be the most convenient option for development (as long as you can fit everything into RAM, or maybe KRAM), but very awkward otherwise.
The PC-FX can boot from external (but not internal) backup memory. For this, a certain structure must be present on the backup memory:
|0x28||"PCFXBoot" - not "PCFXBOOT" as Alex Marshall's documentation says (8 ASCII characters)|
|0x30||Offset of code on backup memory (word)|
|0x34||RAM address to load to (word)|
|0x38||Number of bytes to load (word)|
|0x3C||Starting PC (word)|
To boot from backup memory in Mednafen:
-physcd -force_module pcfxto force the PC-FX module to be used. Note: since version 0.9.38, Mednafen does not support physical CDs anymore.
The BG2 BAT and CG address registers are 0x28 and 0x29 respectively, not 0x26 and 0x27.
The BG3 BAT and CG address registers are 0x2A and 0x2B respectively, not 0x28 and 0x29.
The gap in register numbers is therefore on 0x26 and 0x27, not 0x2A and 0x2B.
Register 0xF is a word, not a halfword.
These registers specify the resolution and position of the image that the 7up chips produce. According to the Eris source code, they should only be set on 7up A.
Here are some reference values for different Tetsu resolutions:
|Register||256×262 (from Eris 7up sprite example)||320×262 (obtained by me experimentally in Mednafen)|
Note: if you use my values for 320×262, the produced image will exceed the size of the display. To display a sprite at the top-left corner, set its X coordinate to 0x1D and its Y coordinate to 0x40.
The Tetsu chip has a bug which must be worked around when reading the raster position. It must be read twice and it must be ensured that the read values are the same.
Mednafen only ever returns the first or last raster position. The following code shows how you can use the current raster position to wait for the next video frame (for 262-line modes - not tested on others):
pcfxTetsuWaitFrame: ; Waits until the start of the next video frame. ?mov 0x20A0, $12 ; Last raster ?mov 0x3FE0, $13 ; Raster mask ; First, wait until Tetsu is finished with the current frame. .readAgain1: in.h 0x300[$0], $10 in.h 0x300[$0], $11 ; Read twice because of hardware bug and $13, $10 ; Get the raster and $13, $11 cmp $10, $11 bne .readAgain1 cmp $10, $12 bne .readAgain1 ; Then wait until it starts the next frame. .readAgain2: in.h 0x300[$0], $10 in.h 0x300[$0], $11 and $13, $10 and $13, $11 cmp $10, $11 bne .readAgain2 cmp $10, $12 be .readAgain2 ; This line is different! jmp $LP