Learn Multi platform PowerPC Assembly Programming... And feel the POWER!

## Simple Samples

In this series we'll learn a how to do simple tasks, with a single small asm file
 Lesson S1 - Sprite Drawing on the GameCube Lets create a simple bitmap example on the Gamecube. Unfortunately the Gamecube stores colors strangely, so we'll draw some sample color blocks, we'll also draw our bitmap twice , once at 1x (with inevitable color alterations) and once at 2x (With no color changes) NGC_Bitmap.asm

Gamecube Graphics!

 In theory the Gamecube has a 640x480 display, however it only uses 4 bytes for every 2 pixels. The gamecube uses a 'YUV' type display, where each pixel has a 8 bit brightness byte, but the color bytes are shared by neighboring pixels. Take a look at the images on the left... The small image was drawn at 1x, the one on the right is 2x... The colors on the left hand image are different in places, because of the shared color information. However If we treat the gamecube screen as 320x240, or 320x640 - halving the X axis, we can write the same color pixel to 4 bytes, and get the 'actual' colors we wanted!

MRGB-> YBR color

There's no way around itWe will need to convert our 24 bit RGB colors into the format for the Gamecube screen!

Color in RGB:
R = (R1+R2)/2
G = (G1+G2)/2
B = (B1+B2)/2

Luminance:
Y1 = (77/256)*R1 + (150/256)*G1 + (29/256)*B1
Y2 = (77/256)*R2 + (150/256)*G2 + (29/256)*B2
Encoded Color:
cB = -(44/256)*R - (87/256)*G + (131/256)*B + 128
cR = (131/256)*R - (110/256)*G - (21/256)*B + 128

Need help with your color maths??? I have a spreadsheet I used for the color conversions!

Our Example on the GameCube
 We're gong to show a simple hello world message to the screen! We're going to use ELF2DOL to convert our program into a DOL binary (It attaches a 256 byte header) We put our code in the '.text' section We need to set the address of our VRAM We're using 0xC0500000 for VRAM - the uncached version of 0x00500000 We write the address to the register 0xCC00201C (TFBL - Top Field Base Register (L) ) We need to clear our screen with CLS ! We load the Color word into R3 - in this case black. We then use QuickBlock to draw a 48x48 color block to test each color. We have a 'GetScreenPos' routine to convert an X,Y co-ordinate into a VRAM destination We use DrawBitmap1x to draw the small bitmap, Due to the way the GameCube shares colors between pixels there will be some color distortion. We use DrawBitmap2x to draw the doublesize version, This version uses 2x2 scaled pixels, so each 'pixel' will have its own unique color.

Drawing routines

 Clearing the screen is easy, we just wipe all 0x25800 thirty two bit words of VRAM from address 0xC0500000 onwards The VRAM base is 0xC0500000, Each line of the screen is 640 pixels, and each pixel is 2 bytes. We multiply our X and Y pos to get the vram destination The QuickBlock routine draws one of the test color blocks. it just fills a square area with the same 32 bit value, then moves across the screen 48 pixels We include the two bitmap files we want to draw as binary files. My Akusprite editor allows for export in the format used by the gamecube, and offers the 'DoubleWidth' export for the 2x file used in this example. Akusprite editor is included in the downloads. We have 2 draw routines, though both are virtually identical. We store the Width in the CTR register. We read 2 pixels (32 bits) from the source (R3) and draw them to the screen (R8) The 2x source file has each pixel doubled horizontally in the file, but to double vertically we draw the same data one line down (offset 1280)

 Lesson S2 - Sprite Drawing on the GameCube Lets create a simple bitmap example on the Gamecube. We'll move two sprites round the screen with the joypad and stick. One will be 1x scaled, the other will be 2x NGC_Joypad.asm

 These simple tutorials always use a single ASM file. This time is slightly different, it's a single ASM file, but by enabling ".equ showtext,1" the joypad output will be shown to the screen - this extra function requires a couple of extra ASM files, but is totally optional.

Here are the Serial Interfaces registers we need to use

 Port Purpose Bits Notes 0xCC006400 SIC0OUTBUF - SI Channel 0 Output Buffer (Joy-channel 1 Command) %--------CCCCCCCC0000000011111111 C=Command 0=Output0 1=Output1 0xCC006404 Joy-channel 1 Buttons 1 %---syxba--lrUDRLXXXXXXXXYYYYYYYY 0xCC006408 Joy-channel 1 Buttons 2 %XXXXXXXXYYYYYYYYLLLLLLLLRRRRRRRR 0xCC00640C SIC1OUTBUF - SI Channel 1 Output Buffer (Joy-channel 2 Command) %--------CCCCCCCC0000000011111111 C=Command 0=Output0 1=Output1 0xCC006410 SIC1INBUFH - SI Channel 1 Input Buffer High (Joy-channel 2 Buttons 1) %---syxba--lrUDRLXXXXXXXXYYYYYYYY 0xCC006414 Joy-channel 2 Buttons 2 %XXXXXXXXYYYYYYYYLLLLLLLLRRRRRRRR 0xCC006418 SIC2OUTBUF - SI Channel 2 Output Buffer (Joy-channel 3 Command) %--------CCCCCCCC0000000011111111 C=Command 0=Output0 1=Output1 0xCC00641C Joy-channel 3 Buttons 1 %---syxba--lrUDRLXXXXXXXXYYYYYYYY 0xCC006420 Joy-channel 3 Buttons 2 %XXXXXXXXYYYYYYYYLLLLLLLLRRRRRRRR 0xCC006424 SIC3OUTBUF - SI Channel 3 Output Buffer (Joy-channel 4 Command) %--------CCCCCCCC0000000011111111 C=Command 0=Output0 1=Output1 0xCC006428 Joy-channel 4 Buttons 1 %---syxba--lrUDRLXXXXXXXXYYYYYYYY 0xCC00642C SIC3INBUFL - SI Channel 3 Input Buffer Low (Joy-channel 4 Buttons 2) %XXXXXXXXYYYYYYYYLLLLLLLLRRRRRRRR 0xCC006430 SIPOLL - SI Poll Register (Joy-channel Control (?) (Calibration gun ?)) %------XXXXXXXXXXYYYYYYYYEEEEVVVV V=Vlbank copy E=Enable port Y=Ytimes X7 X lines 0xCC006434 SICOMCSR - SI Communication Control Status Register (command) %r?--?ccs-mmmmmmm-nnnnnnneb-----? R=Clear Transfer complete interrupt status 0xCC006438 SISR - SI Status Register (channel select & status2) 0xCC00643C SIEXILK - SI EXI Clock Lock 0xCC006480 SI I/O buffer (access by word)

 Reading the joypad in this example is based on the documentation in: YAGCD - Yet Another Gamecube Documentation Unfortunately, it's not clear that the INIT commands is having any effect (the example works without them) It's possible (probable?) that this is emulator limitations