Learn Mips Assembly Programming...

Simple Sample Series

In this series we'll take a look at simple examples to do essential tasks!

Lesson S1 - Bitmap Drawing on the N64
Lets learn how to draw a bitmap onto the screen at a specified location on the N64

N64_Bitmap.asm


Drawing a bitmap

We're going to draw our mascot onto the screen.
Ok, Lets start our program.

First we tell our assembler (ArMips) we're compiling for the N64, we are going to save to "\RelN64\cart.N64", and our cartridge needs to start at memory address 0x80000000
We need to define a header for our cartridge.

This has things like our program name, country and other useful factoids.

It also contains a CRC (calculated Checksum) which needs to be correct, but we'll fix that with 'rn64crc' later.
We need a 'bootstrap' to start up the n64.

We have two options...
1.Code up 1000 lines of code - or
2. patch in a Binary file we 'borrowed' to do the job.

We'll use option 2 - actually many commercial games use the exact same bootstrap!
We want to pad our cartridge to 8Mb, so we add a 'footer' to do this
OK! We need to set up our screen!

Our screen will be 320x240 - 16 bpp (32,768 colors) it will start from memory address 0xA0100000

The video registers start from address 0xA4400000 - the values shown here will set up the screen.
Ok, Now for our little program!

First we'll clear the screen... 'CLS' sets the screen to the color in A0. The color is 15 bit in the format %RRRRRGGGGGBBBBB-

We use 'GetScreenPos' to calculate the VRAM destination for the position we want to draw the bitmap - it returns the VRAM address in A0

We show our character with 'DrawBitmap', this takes a width and height, and a source address for the bitmap

Then we'll stop - ending with an infinite loop
Here is the result

Clearing the screen

Lets clear our screen

Our VRAM starts at 0xA0100000 , and each pixel is one Half (two bytes)... the total screen size is 320*240 pixels

Our colors are defined by 5 bits per channel in the format %RRRRRGGGGGBBBBB-

We write our color to all the pixels.
RAM on the N64 is in BIG ENDIAN format! Meaning that the Half 0x1234 would be stored as 0x12 0x34 in memory.

That doesn't affect CLS, but our bitmap needs to be in the correct format


GetScreenPos

We want to calculate a screen position!

We pass an Xpos in A0 and Ypos in A1 and calculate the final destination in A0

As the first few lines are offscreen, the formula we use to calculate the vram destination is:

Vram = 0xA0100000+320*2*14 + (320 * 2 * Ypos) + (Xpos * 2)

DrawBitmap

We need to create a valid bitmap file to show to the screen.

The pixels are in the format %RRRRRGGGGGBBBBBB-

On the N64 The data is in BigEndian format.
We transfer each line of our source bitmap to the screen.

We do the bitmap line by line, moving our VRAM destination down one 320 pixel line after each line
Need to convert your bitmap? No problem!

My Akusprite Editor can convert bitmap files to the correct format.

Take a look at the MIPS menu -> N64 -> Save Raw Bitmap

It will output a binary file in the correct big endian format for this example
We could make our drawbitmap more efficient if we worked in words (pair of pixels) instead of halves (Pixels), but for clarity we're working in single pixels here.


Lesson S2 - Sprite Movement and Joystick on the N64
Lets draw a sprite to the screen, and move it with the joypad

N64_Joystick.asm


Drawing a bitmap

We're going to draw our mascot onto the screen.

We'll move it around the screen, but limit it so it can't go offscreen.
Ok, Lets start our program.

First we tell our assembler (ArMips) we're compiling for the N64, we are going to save to "\RelN64\cart.N64", and our cartridge needs to start at memory address 0x80000000
We need to define a header for our cartridge.

This has things like our program name, country and other useful factoids.

It also contains a CRC (calculated Checksum) which needs to be correct, but we'll fix that with 'rn64crc' later.
We need a 'bootstrap' to start up the n64.

We have two options...
1.Code up 1000 lines of code - or
2. patch in a Binary file we 'borrowed' to do the job.

We'll use option 2 - actually many commercial games use the exact same bootstrap!
We want to pad our cartridge to 8Mb, so we add a 'footer' to do this
OK! We need to set up our screen!

Our screen will be 320x240 - 16 bpp (32,768 colors) it will start from memory address 0xA0100000

The video registers start from address 0xA4400000 - the values shown here will set up the screen.

GetScreenPos

We want to calculate a screen position!

We pass an Xpos in A0 and Ypos in A1 and calculate the final destination in A0

As the first few lines are offscreen, the formula we use to calculate the vram destination is:

Vram = 0xA0100000+320*2*14-2 + (320 * 2 * Ypos) + (Xpos * 2)

DrawBitmap

We need to create a valid bitmap file to show to the screen.

The pixels are in the format %RRRRRGGGGGBBBBBB-

On the N64 The data is in BigEndian format.
We transfer each line of our source bitmap to the screen.

We XOR with the screen data - this means if we draw twice the sprite will be removed

We do the bitmap line by line, moving our VRAM destination down one 320 pixel line after each line

Reading the joystick

The N64 controllers are connected via the so called 'PIF' chip (Peripheral Interface?)
The base of the PIF registers is at address 0xBFC007C0

To initialize things we first write 0x8 to the status register at 0xBFC007FC
We're going to use the serial interface (SI)  to send data to the PIF,
This is basically a DMA copy, which sends a block of data.

We need to prepare a 96 byte block of data to send to the PIF to initialize things.

We also define 8 bytes to get back the results when we do a read!
OK we need to use the SI to Send the INIT code to the PIF
The SI registers are at 0xA4800000+

We need to calculate our source address (PIF_Init) - but we need the true 'hardware address' we can get this by ANDing with 0x1FFFFFFF
We send the source address to 0xA4800000 (SI_DRAM_ADDR_REG)

We want to transfer to the PIF ram at 0xBFC007C0 (PIF_RAM_START) - we also AND this with 0x1FFFFFFF
We write the destination to the write register at 0xA4800010 (SI_PIF_ADDR_WR64B_REG) - this write also starts the transfer
We define the start XY position for our player.

We draw the player to the screen.
the N64 is FAST!
 
At the start of the main loop We have a crude delay to slow it down and make our example usable!
OK, it's time to read in from the joystick! This time we use the SI to READ from the PIF.

We need to calculate our destination address (PIF_JoyState) - but we need the true 'hardware address' we can get this by ANDing with 0x1FFFFFFF
We send the destination address to 0xA4800000 (SI_DRAM_ADDR_REG) - this is the same as the address for writing

This time we want to transfer FROM to the PIF ram at 0xBFC007C0 (PIF_RAM_START) - we also AND this with 0x1FFFFFFF
We write the source to the read register 0xA4800004 (SI_PIF_ADDR_RD64B_REG) - this write also starts the transfer
We wait for a direction to be pressed...

When one is, we draw the sprite in the same position again, because it's XORed, this removes the sprite.
We now test each direction, Right, Left, Down and Up

If a direction is pressed, we check the position of the sprite.

If the sprite is at the limit of the axis, we cannot move, otherwise we adjust the position accordingly.

We draw in the new location... and repeat!


This is a very crude example, and doesn't use any 3D hardware or anything!

It's just a simple example to get something moving onscreen, so you can play with it as you learn mips!



Lesson S3 - Bitmap Drawing on the PSX
Lets learn how to draw a bitmap onto the screen at a specified location on the Playstation

PSX_Bitmap.asm


Drawing a bitmap


We're going to draw our 'Chibiko' mascot to the screen

Our bitmap is 16bpp in Little Endian in the format %-BBBBBGGGGGRRRRR
Ok, Lets start our program.

First we tell our assembler (ArMips) we're compiling for the PSX, we are going to save to "\BldPSX\Prog.bin", and our cartridge needs to start at memory address 0x80010000
We need to set up our screen.

We use the IO registers from address 0x1F800000+

We set up a 320x240 16bpp screen
Our 'Footer' just contains a close command
Ok, Now for our little program!
First we clear the screen - We load the color command into A0 before calling CLS

Now we draw our sprite
We load A0 with our Xpos,A1 with our Ypos, and the pointer to our bitmap into A2.
We call DrawBitmap

Then we'll stop - ending with an infinite loop

Clearing the screen

we need to command the GPU with port 0x1F801810

We use GFX command 0x2 to fill the screen. Our fill color is defined by 8 bits per channel in the format 0xBBGGRR

The total screen size is 320*240 pixels, we define the fill area with the following 2 commands

The GPU will then clear the screen for us.
We can't actually write directly to the PSX screen - We have to use GFX commands.

To draw our bitmap, we define a 'window', then stream the pixel bytes into that window


DrawBitmap

We need to create a valid bitmap file to show to the screen.

The pixels are in the format %RRRRRGGGGGBBBBBB-

On the N64 The data is in BigEndian format.
To send our bitmap data we first need to set up the GPU with the parameters of the area we'll draw to.

We use command A0 to select the 'Send image' command

Next send the X,Y pos.
Then we send the Width and Height

We also calculate the word count for sending the bitmap data
We send all the words of our bitmap to the VRAM via the GP0 port
Need to convert your bitmap? No problem!
My Akusprite Editor can convert bitmap files to the correct format.

Take a look at the MIPS menu -> PSX-> Save Raw Bitmap

It will output a binary file in the correct format for this example

Lesson S4 - Sprite Movement and Joystick on the Playstation
Lets draw a sprite to the screen, and move it with the joypad

PSX_Joystick.asm


Drawing a bitmap

We're going to draw our mascot onto the screen.

We'll move it around the screen, but limit it so it can't go offscreen.
Ok, Lets start our program.

First we tell our assembler (ArMips) we're compiling for the PSX, we are going to save to "\BldPSX\Prog.bin", and our cartridge needs to start at memory address 0x80010000
We need to set up our screen.

We use the IO registers from address 0x1F800000+

We set up a 320x240 16bpp screen
Our 'Footer' just contains a close command
OK! We need to set up our screen!

Our screen will be 320x240 - 16 bpp (32,768 colors) it will start from memory address 0xA0100000

The video registers start from address 0xA4400000 - the values shown here will set up the screen.

Drawing the Bitmap

We need to create a valid bitmap file to show to the screen.

The pixels are in the format %-BBBBBGGGGGRRRRR

On the PSX The data is in Little endian format.
When we want to draw our bitmap to the screen we load the X and Y pos from Ram
We need to get the GPU to draw the bitmap data to the screen.

We define the 'window' that our bitmap will occupy on the screen.
We send the bitmap data to the GPU one word (two pixels) at a time

Removing the Bitmap
We use the Fill Area command to remove our character from the screen.

Strangely it seems the start Xpos is limited to a 16 pixel alignment, so we clear an area 16 pixels wider than our sprite.

We shade the removed area dark purple so we can see what was removed.
The Fill seems to be limited to clearing aligned to a 16 pixel boundary.
This is probably related to the internal organization of the VRAM in the GPU

Reading the joystick

We're going to execute the bios functions at address 0xB0 (the so called 'B functions')
We need to call this with a function number in T1 - Here we use 0x12 which is 'Init Pad'
This takes 4 parameters in A0-A3

A0 is the address of the buffer for joypad 1, A1 is the size (Should be 0x22)
A2 is the address of the buffer for joypad 2, A3 is the size (Should be 0x22)
Once we have Initialized the joypad we can start the read process.

We use Bios function 0x13 'Startpad' - which takes no parameters.

This will automatically fill the buffer with the joypad data.
We define the start XY position for our player.

We draw the player to the screen.
the PSX is FAST!
 
At the start of the main loop We have a crude delay to slow it down and make our example usable!
We wait for a direction to be pressed...

When one is, we draw the sprite in the same position again, because it's XORed, this removes the sprite.
We now test each direction, Right, Left, Down and Up

If a direction is pressed, we check the position of the sprite.

If the sprite is at the limit of the axis, we cannot move, otherwise we adjust the position accordingly.

We draw in the new location... and repeat!


This is a very crude example, and doesn't use any 3D hardware or anything!

It's just a simple example to get something moving onscreen, so you can play with it as you learn mips!


 

View Options
Default Dark
Simple (Hide this menu)
Print Mode (white background)

Top Menu
***Main Menu***
Youtube channel
Patreon
Introduction to Assembly (Basics for absolute beginners)
Amazon Affiliate Link
Forum
AkuSprite Editor
ChibiTracker
Dec/Bin/Hex/Oct/Ascii Table

Alt Tech
Archive.org
Bitchute
Odysee
Rumble
DailyMotion
Please note: I wlll upload more content to these alt platforms based on the views they bring in

Z80 Content
***Z80 Tutorial List***
Learn Z80 Assembly (2021)
Learn Z80 Assembly (old)
Hello World
Simple Samples
Advanced Series
Multiplatform Series
Platform Specific Series
ChibiAkumas Series
Grime Z80
Z80 Downloads
Z80 Cheatsheet
Sources.7z
DevTools kit
Z80 Platforms
Amstrad CPC
Elan Enterprise
Gameboy & Gameboy Color
Master System & GameGear
MSX & MSX2
Sam Coupe
TI-83
ZX Spectrum
Spectrum NEXT
Camputers Lynx

6502 Content
***6502 Tutorial List***
Learn 6502 Assembly
Advanced Series
Platform Specific Series
Hello World Series
Simple Samples
Grime 6502
6502 Downloads
6502 Cheatsheet
Sources.7z
DevTools kit
6502 Platforms
Apple IIe
Atari 800 and 5200
Atari Lynx
BBC Micro
Commodore 64
Commodore PET
Commander x16
Super Nintendo (SNES)
Nintendo NES / Famicom
PC Engine (Turbografx-16)
Vic 20

68000 Content
***68000 Tutorial List***
Learn 68000 Assembly
Hello World Series
Platform Specific Series
Simple Samples
Grime 68000
68000 Downloads
68000 Cheatsheet
Sources.7z
DevTools kit
68000 Platforms
Amiga 500
Atari ST
Neo Geo
Sega Genesis / Mega Drive
Sinclair QL
X68000 (Sharp x68k)

8086 Content
Learn 8086 Assembly
Platform Specific Series
Hello World Series
Simple Samples
8086 Downloads
8086 Cheatsheet
Sources.7z
DevTools kit
8086 Platforms
Wonderswan
MsDos

ARM Content
Learn ARM Assembly
Learn ARM Thumb Assembly
Platform Specific Series
Hello World
Simple Samples
ARM Downloads
ARM Cheatsheet
Sources.7z
DevTools kit
ARM Platforms
Gameboy Advance
Nintendo DS
Risc Os

Risc-V Content
Learn Risc-V Assembly
Risc-V Downloads
Risc-V Cheatsheet
Sources.7z
DevTools kit

MIPS Content
Learn Risc-V Assembly
Platform Specific Series
Hello World
Simple Samples
MIPS Downloads
MIPS Cheatsheet
Sources.7z
DevTools kit
MIPS Platforms
Playstation
N64

PDP-11 Content
Learn PDP-11 Assembly
Platform Specific Series
Simple Samples
PDP-11 Downloads
PDP-11 Cheatsheet
Sources.7z
DevTools kit
PDP-11 Platforms
PDP-11
UKNC

TMS9900 Content
Learn TMS9900 Assembly
Platform Specific Series
Hello World
TMS9900 Downloads
TMS9900 Cheatsheet
Sources.7z
DevTools kit
TMS9900 Platforms
Ti 99

6809 Content
Learn 6809 Assembly
Learn 6309 Assembly
Platform Specific Series
Hello World Series
Simple Samples
6809 Downloads
6809/6309 Cheatsheet
Sources.7z
DevTools kit
6809 Platforms
Dragon 32/Tandy Coco
Fujitsu FM7
TRS-80 Coco 3
Vectrex

65816 Content
Learn 65816 Assembly
Hello World
Simple Samples
65816 Downloads
65816 Cheatsheet
Sources.7z
DevTools kit
65816 Platforms
SNES

eZ80 Content
Learn eZ80 Assembly
Platform Specific Series
eZ80 Downloads
eZ80 Cheatsheet
Sources.7z
DevTools kit
eZ80 Platforms
Ti84 PCE

IBM370 Content
Learn IBM370 Assembly
Simple Samples
IBM370 Downloads
IBM370 Cheatsheet
Sources.7z
DevTools kit

Super-H Content
Learn SH2 Assembly
Hello World Series
Simple Samples
SH2 Downloads
SH2 Cheatsheet
Sources.7z
DevTools kit
SH2 Platforms
32x
Saturn

PowerPC Content
Learn PowerPC Assembly
Hello World Series
Simple Samples
PowerPC Downloads
PowerPC Cheatsheet
Sources.7z
DevTools kit
PowerPC Platforms
Gamecube

Work in Progress
ChibiAndroids

Misc bits
Ruby programming









Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book



Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!












































































































Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book



Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!












































































































Buy my Assembly programming book
on Amazon in Print or Kindle!


Buy my Assembly programming book



Available worldwide!
Search 'ChibiAkumas' on
your local Amazon website!
Click here for more info!