Now that we have a [basic design for the Flame GPU and display mode 0](https://medium.com/the-ember-project/the-flame-gpu-initial-design-part-2-tilesheets-tilemaps-and-graphics-registers-8c638a19ec4f), we need to write some assembly code to initialize the virtual GPU. We will start by adding a GPU initialization routine called **flame_Init** to the [startup code we wrote for the boot firmware](https://medium.com/the-ember-project/the-ember-console-system-architecture-design-system-software-and-the-boot-process-b56258bc4c86#:~:text=the%20systemInit%20label.-,systemInit,-The%20first%20step) for the Ember Fantasy Console.

This new function doesn’t take any parameters; it just sets various memory-mapped hardware registers in the GPU to default settings to enable Mode 0, which is a simple tiled display mode, using a single playfield tilemap with a one-byte tile index at each memory location, a single tilesheet, and a two-color palette. This mode is ideal for implementing a text mode for testing and simple debugging of the Ember virtual console. Using this mode, we can implement a basic monitor application, or a command-line tool, similar to [WozMon](https://www.sbprojects.net/projects/apple1/wozmon.php), or any other early console terminal on a Commodore 64 or other early personal computer.

**flame_Init**

We first load the **r9** register with a pointer to the starting address of the memory-mapped GPU control registers. In a C or C++ application, this is the equivalent of a pointer to a struct. We will then use this pointer, adding various offsets, when we want to access the values in the struct. Check out the figure below _(_ [_and this post_](https://medium.com/the-ember-project/the-flame-gpu-initial-design-part-2-tilesheets-tilemaps-and-graphics-registers-8c638a19ec4f#:~:text=Zero%2DPage%20GPU%20Registers) _)_ for details on the GPU Control Registers.

Next, we push the **lr**, or **link register**, to the stack. This is a common operation for any Ember function that will call other functions, as we will need to set it back to the return address of the calling function when we are done.

Before we start initializing the GPU hardware, we must ensure it is fully powered up and ready. At this point in the system's initialization, we can assume that power has been recently applied, so the chips on the board may still be in a reset state. We need to wait here in a loop until the GPU reports that it is ready, as indicated by the **GPU_Status** register.

Once the GPU is ready, we will call a series of functions which will perform the initialization, starting with **__flame_DisableDisplay**. Since we have just booted the machine, the GPU display output should already be disabled. However, it is best to confirm this, as changing some hardware registers below while the display is active could cause a system crash.

Next, we call **__flame_SetMode**, passing zero as the mode parameter for default Mode 0, then call **__flame_SetDisplay** to set the display resolution to a valid default such as 1024x768. Ultimately, an application can set it to whatever it needs, but the system can set a standard default that it expects any monitor to be able to handle. Finally, we call **__flame_EnableDisplay** to begin drawing frames, then return using the ret instruction, which will pop the link register off the stack and jump back to the system initialization routine.

At this point, the GPU will begin drawing frames using the data in the Playfield 0 tilemap in VRAM, which we have set to 0s, resulting in a solid color background on a blank display. The GPU is now ready to display a splash screen, render text, or whatever is needed.

**SysCall and Parameter Passing**

A quick note on parameter passing. As part of the Ember ABI _(Application Binary Interface)_, there are three recommended calling conventions: **StdCall**, **TrapCall**, and **SysCall**. **StdCall** is the primary user-facing standard used for application libraries and games. **TrapCall** is used when calling **TRAP** system calls from user mode. Lastly, **SysCall** is a loosely defined standard used internally by system code and libraries to facilitate faster, yet more modular code for system drivers and handlers. We will cover the first two in more detail in the future, but for the GPU driver, we are using the SysCall standard.
