Kernel

A bit of history

Final Fantasy I, NES and Memory Mappers

The kernel is a throwback to the very first Final Fantasy game for the Nintendo’s original 8-bit system, the Nintendo Entertainment System.

The NES could only natively read 32 Kib of program ROM. To get around this incredible limitation, Nintendo developped “Memory Mappers” that allowed parts of the program to be switched out, or “banked”, and replaced with other parts stored on the game cartridge.

Final Fantasy I used the Nintendo’s Memory Manager Controller #1 chip or MMC1.

The maximum size an MMC1 program’s code could be was 256 Kib, so the controller split the program ROM into 16 sections, each of 16 Kib long. The controller also split the accessible memory from the cartridge into 2 16 Kib sections.

For FF1, the top 16 Kib was switchable but the bottom one could never be switched out and stayed in memory until you shut down the system. The original FF1 kernel was located into this 16 Kib portion of the memory.

Kernel functionalities

First and foremost, the kernel contained the main program loop.

It handled all the low level functions for the game. Some of these included controlling interrupts, banking in and out the appropriate parts of the game, jumping control to a particular module, playing music and other tasks.

Next game generations

As the Final Fantasy franchise grew, so did the size of the games. They all still retained the kernel / module system.

During the porting process of old games to new generation consoles, this did cause a few headaches. For example, Final Fantasy VI was originally developped for the Super Nintendo. When it’s menu module was banked in, it was done with electronic bank switching. The later PSX port banked the data from the CD-ROM, which caused an unexpected lag that one was not used to.

On the PC port of FF7, the menu system was integrated into the main executable.

FF7 Kernel functionalities

The kernel is a threaded multitasking program that manages the whole system.

It uses a simple software based memory manager that handles both RAM and video memory for all the modules in the game.

Assisting the kernel are many statically or dynamically linked libraries.

PSX

PSX used the Psy-Q SDK created by Psygnosis, so the kernel is statically linked to many Psy-Q libraries.

PC port

The PC port replaced the PSX Psy-Q libraries with PC alternatives. For example the SEQ player, used on the PSX to play music, was replaced with a MIDI player. Both accomplish the same tasks, just with different file formats and execution strategies.

RAM management

No matter what module is present in memory, there is a section reserved for all variables for the entire game.

This is the Savemap. A memory map of all elements that represent the state of the current game. When it is time to save a game, this section of memory is copied to non-volatile RAM, such as a memory card (PSX) or a hard disk (PC).

The Savemap is 4380 (0x10F4) bytes long.

It contains 5 banks of 256 bytes of memory that are directly accessible by the Field Scripting Language. These banks can be either accessed by a byte (8 bits) or 2 bytes (16 bits) at a time, depending on the FSL command argument.

It also contains 256 bytes to store temporary field variables. These are not used by field files to share data and are not persisted when the game is saved.

Offset

8 Bit Field Bank

16 Bit Field Bank

Description

0x0000

N/A

N/A

Beginning of the Savemap

0x0BA4

0x1

0x2

Field Script Bank 1

0x0CA4

0x3

0x4

Field Script Bank 2

0x0DA4

0xB

0xC

Field Script Bank 3

0x0EA4

0xD

0xE

Field Script Bank 4

0x0FA4

0xF

0x7

Field Script Bank 5

0x10F4

N/A

N/A

End of Savemap

N/A

0x5

0x6

Temporary field variables (256 bytes)

VRAM management

The kernel is in charge of allocating, caching and displaying pixels as data stored in the Video RAM.

PSX VRAM management

In the case of the PSX, the Playstation only has a 1 Mib of VRAM which make the task a little complex. This is alleviated somewhat by using the PSX’s VRAM caching system.

The PSX video memory can best be seen as a rectangular “surface” made up of 2048x512 pixels. A slight caveat to this mode is that the PSX can hold multiple color depths in VRAM at the same time.

Note

This document represents VRAM as a 1024x512 matrix to allow for some color depth in either direction and to minimize some extreme skewing of the video buffers.

The following is a typical state of VRAM during gameplay.

../_images/vram.png

The two game screens on the left side are the video buffer and the back buffer. The patchwork of graphics on the top right are the field graphics for that scene. The bottom row consists of cached graphics, special effects, and semi-permanent and permanent textures for the game.

The following is the VRAM with an additionnal descriptive frame.

../_images/vram2.png

Here the sections of the VRAM are easier to visualize:

  • The large cyan areas are the video frame buffers. The PSX uses a standard double page buffer to animate the game.

  • The empty areas above and below the frame buffers are blank to allow for a correct V-sync.

  • The dark blue areas to the right of the frame buffers are used when the game plays 24-bit movies. This require a slightly larger display and the first two texture caches are overriden. During time in the game where no movies can take place, such as battles, textures are commonly placed here.

  • The magenta area under the frame buffers is the Color Lookup Table (CLUT). This is where the texture palettes are stored. This also allow the PSX to display multiple color depths at the same time.

  • The red area to the right is extra CLUT space when it is needed and when there are no texture currently cached there.

  • The green area on the right is the permanent menu textures.

  • The yellow area is where the menu font is stored.

  • All the blank rectangles are the texture cache boundaries. In order of volatility: * The top two rows of cache space are overwritten from left to right * Then the bottom rows are overwritten * The texture on the bottom right are therefore barely overwritten except for key places.

CD-ROM management

PSX CD-ROM management

One of the big rules on PSX development is that direct hardware access is prohibited. Everything must go through the BIOS or the program will risk being incompatible with later systems. This means not only to a new generation console like PSX to PS2, but also all the trivial hardware revisions of the current generation as well.

This create a problem for the kernel.

During module transitions (for example, going from Field module to Battle module), the engine actually “preloads” the next module while the current one is still executing.

This loading of data can not be done with a simple open() or read() BIOS syscall: whenever you enter the BIOS, the rest of the system comes to a screeching halt until it is exited.

The problem is solved by FF7 actually controlling the CD-ROM access itself through faster, low-level BIOS calls. In this “quick mode”, the kernel can only load 8 Kib of data at a time and also only references files by what sector of the CD-ROM the data is located on, not by its filename.