PCE target

The PCE platform corresponds to the NEC PC Engine, also known as the TurboGrafx-16 in the US.

Hardware description

 * CPU: HuC6280 (Rockwell 65C02 derivative with additional opcodes) @ 7.16MHz
 * Redirected zero page at 0x2000, stack at 0x2100
 * Interrupt control and timer
 * Joypad port input/output
 * Memory:
 * 21-bit address space (8-bit bank index, 8 kilobytes per bank)
 * 8 kilobytes of RAM (32 kilobytes on SuperGrafx), bank $F8 onwards
 * Up to 1 megabyte of ROM, banks $00-$7F
 * Memory mapped I/O, bank $FF
 * VDC / VCE: Video Display Controller (handles drawing background and sprites) / Video Color Encoder (converts color indexes to RGB colors)
 * PSG: Programmable Sound Generator

Banking
The PC Engine's address space consists of eight consecutive 8KB banks, numbered from 0 to 7. llvm-mos follows target convention and maps them as follows:

Bank mapping
Given that each 8KB bank can be mapped to five different locations by the user (and more if you're careful), the following method is provided to configure this mapping for LLVM-MOS emitted code:


 * 1) Create a header file to contain all of your bank definitions (for example,  ).
 * 2) Write your bank definitions, using macros of the format.
 * 3) * refers to the ID of the bank; the linker script currently supports IDs from 1 to 127 inclusive. The ROM will automatically be padded with empty banks to fill in any gaps - this is useful if you want to use an external tool to inject data outside of LLVM-MOS later.
 * 4) *  refers to the MPR of the mapping, or the bank's location in the address space (see above) in 8KB units, from 2 to 6 inclusive.
 * 5) * This example, therefore, tells the compiler to map code in bank 1 between $4000 and $5FFF.
 * 6) Create an implementation file (for example,  ). Write the following lines:
 * 7) * - this must become before the include,
 * 8) Include the header file  without defining   in any other file in which you wish to use virtual banks.
 * 1) Include the header file  without defining   in any other file in which you wish to use virtual banks.
 * 1) Include the header file  without defining   in any other file in which you wish to use virtual banks.

A defined virtual bank provides the following convenience methods:


 * - maps bank N to the CPU's address space;
 * - safely maps bank N and calls a function in it;
 * the  section, which the functions and variables stored inside bank N should be placed in - for example, by using.

Fixed area
Index 7 is fixed to bank $00, which is where all code and data not located in any bank is put in. Such code and data is always accessible.

Some code may, however, need a larger fixed area than eight kilobytes; for this, one can use the macro , where   is a value between 1 (8KB) and 6 (48KB). In this configuration, bank indexes starting from 7 and counting down will be dedicated to this fixed area; for example, for a size of  (24 KB), banks 5, 6, and 7 will be fixed.

Note that fixed areas larger than 8KB are non-contiguous in the ROM: the last bank of the fixed area is the first ROM bank, followed by the other banks. For example, for a size of  (32KB), bank   will contain the last 8KB,   the first 8KB,   the second 8KB, and   the third 8KB.

SuperGrafx RAM
The SuperGrafx provides 32 kilobytes of RAM rather than the console's default 8.

Currently, this may be taken advantage of by using the macro, where   is a value between 2 (16KB) and 4 (32KB). This will dedicate bank indexes starting from 2 and counting up for SuperGrafx memory, and allow using them in C code; for example,  will allocate indexes 1 through 4 (addresses $2000 to $9FFF) to C code-visible RAM.

Interrupts
Interrupts are provided in a manner similar to the NES target. The following entrypoints are defined:


 * - IRQ2 (external interrupt),
 * - IRQ1 (VDC),
 * - IRQ0 (timer),
 * - NMI (not emitted on PC Engine).

Interrupt handlers can be written in C by using. This subject is explained in more detail on the C interrupts page.

ELF address space
Note that, for a fixed bank larger than 8KB, the LMA's Bank value refers to its lowest bank. To recover the actual bank and in-bank address from the ELF data, one can use the following equation:

where BankLMA refers to the nearest lower or equal, in terms of value,  symbol - the fixed bank is split into   and.

PC Engine CD
PC Engine CD support is provided via the  target. Developing for it has a few important differences from developing a cartridge-based project, outlined below.

Additional functionality
The PC Engine CD architecture provides an extensive BIOS, the functionality of which is documented in.

The  target does not support resizing the fixed bank or mapping SuperGrafx RAM by default.

Banking
On the PC Engine CD, all data is stored in RAM; as such, instead of  and ,   and   is used itself. The range is also different:


 * PC Engine CD, internal RAM: bank indexes 128 - 135
 * Super System Card, additional RAM: bank indexes 104 - 127

The banks are populated from CD in their totality. To not duplicate RAM usage, the C  section is stored alongside code in the first RAM bank, while   is stored in the console RAM by default.

The first RAM bank used is expected to be fixed at $4000.

Linking
There are four link scripts available, which can be specified by using f.e. :


 * - "raw" PCE CD-ROM binary (64K RAM);
 * - "raw" PCE Super CD-ROM binary (256K RAM);
 * - Initial Program Loader (up to 40KB starting at bank 128), default;
 * - Initial Program Loader, stored in console RAM only (up to 1904 bytes, fits in one CD sector).

"Raw" binaries can be loaded by using the  routine; "IPL" binaries can additionally be placed as the first file loaded on a CD image.

One can also link to contents of other files contained on a CD - see the below section for more information.

Building an ISO
To build an ISO, use the  tool bundled with llvm-mos-sdk. Provide it with an output filename (f.e. ), followed by input files (either ELFs or any binary files). The first input file must be the IPL program.

The  tool resolves the additional symbols in specified ELF files:


 * - the 24-bit sector index of a given file,
 * - the size of a given file in sectors,
 * - the first bank of a given executable file,
 * - the last bank of a given executable file,
 * - the bank count of a given executable file,
 * - for executable files, this can be used to read the value of a symbol from another file.

In addition, one can pass  as any of the input arguments to   - this will read  's contents and use them as filenames.

Note that, as llvm-mos-sdk does not have permission to distribute this file,  requires a file called   in its current working directory - it should be 2048 bytes in size and contain the contents of the first data sector of any PC Engine CD disc.

To add CD audio tracks or run the ISO in most PC Engine CD emulators, one should write a  file to accompany the ISO; an example file is provided below:

FILE output.iso BINARY TRACK 01 MODE1/2048 INDEX 01 00:00:00 FILE output.wav WAV TRACK 02 AUDIO INDEX 01 00:00:00

FAQ

 * Q: Is the "SF2" mapper supported?
 * A: Not at this time. While the LMA is prepared to support it, a dedicated linker configuration and VBank macros have to be written for this configuration.
 * Q: Is the SuperGrafx supported?
 * A: Yes! The VDC routines support using either VDC1 or VDC2, register definitions for the VPC are also available, and the SuperGrafx's extended RAM can be opted into (albeit - at this time - without banking support).


 * Q: Can I safely remap non-User bank indexes?
 * A: It depends:
 * Bank index 0 (memory-mapped I/O) can be unmapped, provided that no user code - including library calls and interrupts - makes use of it.
 * Bank index 2 (RAM) generally cannot be unmapped, as it contains the zero page's imaginary registers and the soft stack.
 * Bank index 7 (fixed ROM) can probably be unmapped safely if IRQs are disabled, provided that no user code - including library calls - makes use of it.
 * Q: What is the ".mlb" file generated alongside the ROM output?
 * A: This generated file is a Mesen label file, containing symbol definitions compatible with Mesen 2's debugger.