Learn Multi platform Super-H Assembly Programming... Because Why not?

Hello World Lessons

In this series we'll learn a simple self contained 'Hello World'... Well learn how to compile it, and run on an emulator, We'll then learn a more complex example, which includes a 'monitor' function which will show the status of the registers to screen.

Lesson H1 - Hello World on the Saturn
In this lesson we'll create a minimal example on the Sega Saturn. We'll create a BIN file we can run on our emulator, turn on the screen and show a hello world message.

SAT_HelloWorld.asm


Setting up the Saturn
We're gong to show a simple hello world message to the screen!
Our BIN program needs to start at address $6004000, we do this with an ORG statement.
Next we need to set up a valid screen.

We need to set various registers on VDP2 (the video device for the bitmap screen). Shown here are sample values which will work on our emulator

We need to set up the Ram layout and screen mode.

We set up the scroll postition and map offset.

We set up the bitmap screen size.

Finally we enable the layer and turn on the screen
Our screen is on, but we've not set up any colors!

The color ram is at address $25F00000, The screen is set up to use 5 bits per channel in the format %-BBBBBGGGGGRRRRR

We transfer each of the 4 colors to CRAM to set up our color screen



Showing Hello World
Before we can show anything we need to define some data in memory.

We need some text to show.

We need some bitmap data for our font. The file here is 1 bit per pixel 8x8 (so 8 bytes per char)

We also need to remember the 'Cursor Position' (the next place to draw a character. This is stored in a few bytes of memory we define as 'UserRam'
Before we try to print anything we need to ensure our cursor is reset to pos 0,0
Our PrintString routine will print a Char 255 terminated string to the screen. We load the address of the string in R13


After we're done, we drop into an infinite loop
Our print string routine loads a byte into R0,

it compares this character to 255, when -1 (255) is found, the string has ended and we return.

Otherwise we print the character to the screen with the PrintChar routine

Printing a character
Most of the difficulty is printing a character!

First we back up all the registers we will use onto the stack
Next we calculate the offset in our bitmap font for the character in R0

Our font has no character below 32 (space)

Each character uses 8 bytes (one byte per 8 pixel line)
We need to calculate the VRAM destination for our drawing

While not all are visible, Our screen is 512 bytes wide, each pixel is 1 byte
The screen base is $25e00000

So our formula is:

VRAM= $25e00000 + Ypos*512 + Xpos

However our Cursor Xpos and Ypos are measured in characters, so we multiply them by 8 via 3 shifts first.
one screen byte is a pixel... but in our font one bit is a pixel! We shift bits out of the right of our source byte, so we work right to left on our screen.

To do this we add 7 to our Vram destination, to move to the rightmost pixel of the line.

We load a byte from our font into R3,

We shift bits our R3, test them and write the correct color (1 or 0) to the screen in R6.

After a line, we move down the screen by adding 512 (+8 to compensate for the moves)

We repeat until our character is drawn
We're done! so we restore all the registers from the stack.


Compiling and Running
these tutorials use ASW as an assembler, it's free and open source!

We assemble it on the command line with the following command:



ASM Source file... %BuildFile% is the source file in this example it's a batch variable, but you may just want SAT_HelloWorld.asm here.
Cpu Type... We specify the SH7600 , another name for the SH2!
Listing file... You don't need one, but a listing file shows what the assembler did, and can help with debugging.
Defined Symbol... I'm defining 'BuildSat' on the command line, my code uses this with conditional assembly to allow the multiplatform examples to run on multiple systems.
The Output file... This is the built program, but it's not in a format our emulator can run just yet!


We use P2BIN to convert the intermediate file (Prog.bld) into the finished binary file (Prog.bin)


Our program is done, so we launh it from the command line with our emulator Yabause
Here is the result

Bonus! Extending with a Monitor
In these tutorials we use some software debugging tools,

A Monitor which shows the state of the registers,
a Mem Dump which shows some lines of the memory
Here is the result

Monitor Code
The monitor functions need a newline command.

It sets Y=Y+1, X=0
The monitor uses a PUSHALL and POPALL macro to easily back up and restore registers.

These are defined in a separate asm file.
We need to include the monitor tools as a separate file.
Writing your own monitor tools may seem a bit odd, but writing our own means we don't have to worry about the functionality our emulator does or does not provide.

The Monitor tools are pretty complex, so we're not going to discuss their workings here!



Lesson H2 - Hello World on the 32x
In this lesson we'll create a minimal example on the 32x. We'll create a cartridge, which contains a Genesis 'bootstrap' and a 32x program which does the actual work!

32X_HelloWorld.asm
MDHeader_Min.asm


Normally in these Hello World tutorials we would have a single ASM file, but this time we need two because of how the 32x works.

The first is a Megadrive/Genesis 68000 'boot strap' which starts up the system, before starting up the 32x part.
We'll assemble the genesis 68000 part with VASM
We'll assemble the 32x part with ASW

The Genesis bootstrap

At the start of the 68000 memory map is the 'exception table', however on the 32x, this is moved to $00000200

The old table is filled with branches to the 32x startup routine are $000003F0
Next we have our cartridge header, this just contains the description of our cartridge, and a few other bits.
The exception table is now at address $00000200

We only need the reset address, which points to the program code for the 68000 Genesis processor
We now have the 32x header.

Address $000003D4 has the address of the 32x program code in the genesis cartridge
This will be copied to the 32x memory

$3E0 and $3E4 have the execution address of the 32x code for the two SH2 processors. These should be at address $06000000+


 
At address $3F0+ we have the 32x startup code.

As a security feature, Much of this has to byte match the same code in the 32x rom, so is included as binary data.
Our Geneisis 68000 program is very basic, we release the video hardware to the SH2, and drop into an infinate loop
In the rom file, After our 68000 code we will 'attach' the assembled 32x binary.

We do this 'combining' with a batch file.


This is a 'bare minimum' 68000 program, Actually we'll probably want more, as to access the Joypads and all of the sound hardware we have use code on the Genesis!

We'll cover that kind of thing in the 'Simple series'

The 32x bootstrap!

When it's loaded into the 32x memory, our SH2 program will start at address $06000000

We specified the secondary SH2 would start executing this address... we don't actually plan to use that CPU, so we lock it into an infinite loop.
CPU 1's entry point was defined as $06000004 in the 32x header.

First we wait for the 68000 to release the VDP
We use the Bitmap Mode Register $20004100 to turn on the screen.

Here we select a 256 color screen mode.

The SH2 screen memory needs to start with a 'Line Table'

This defines the memory addresses that are used for each line of the screen. We do this twice, once for each screen buffer.

We'll take a look at this in a moment!
Our screen is nearly ready, it's on, but we need to set up it's colors.

Each color is defined by 16 bits, from address $20004200 - The bits are in the format %-BBBBBGGGGGRRRRR




Graphics routines.

The Line table starts at $24000000, each entry is one word - 224 line entries in total , and contains the offset IN WORDS for the bitmap data of that line.

Effectively we write $100+(Line*160)  repeating for 224 lines.
To force a page flip, we need to flip bit 0 of $2000410A.

This transfers the buffer fat address $24000000 into VRAM.

But there's a catch! the flip won't actually occur until VBLANK, so once we attempt the flip, we wait until it actually occurs by waiting for the read back bit to match the one we wrote.

Showing Hello World
Before we can show anything we need to define some data in memory.

We need some text to show.

We need some bitmap data for our font. The file here is 1 bit per pixel 8x8 (so 8 bytes per char)

We also need to remember the 'Cursor Position' (the next place to draw a character. This is stored in a few bytes of memory we define as 'UserRam'
Before we try to print anything we need to ensure our cursor is reset to pos 0,0
Our PrintString routine will print a Char 255 terminated string to the screen. We load the address of the string in R13


On the 32x we have to send the VRAM buffer to the VDP via our 'Pageflip' command

After we're done, we drop into an infinite loop
Our print string routine loads a byte into R0,

it compares this character to 255, when -1 (255) is found, the string has ended and we return.

Otherwise we print the character to the screen with the PrintChar routine

Printing a character
Most of the difficulty is printing a character!

First we back up all the registers we will use onto the stack
Next we calculate the offset in our bitmap font for the character in R0

Our font has no character below 32 (space)

Each character uses 8 bytes (one byte per 8 pixel line)
We need to calculate the VRAM destination for our drawing

While not all are visible, Our screen is 320  bytes wide, each pixel is 1 byte
The screen base is $24000200

So our formula is:

VRAM= $24000200 + Ypos*320 + Xpos

However our Cursor Xpos and Ypos are measured in characters, so we multiply them by 8 via 3 shifts first.
one screen byte is a pixel... but in our font one bit is a pixel! We shift bits out of the right of our source byte, so we work right to left on our screen.

To do this we add 7 to our Vram destination, to move to the rightmost pixel of the line.

We load a byte from our font into R3,

We shift bits our R3, test them and write the correct color (1 or 0) to the screen in R6.

After a line, we move down the screen by adding 320 (+8 to compensate for the moves)

We repeat until our character is drawn
We're done! so we restore all the registers from the stack.

Compiling and Running
these tutorials use ASW as an SH2 assembler, and VASM for 68000 , both are free and open source!


We assemble the 68000 part  on the command line with the following command:



ASM Source file... %BuildFile% is the source file in this example it's a batch variable, but you may just want MDHeader_Min.asm here.
Listing file... You don't need one, but a listing file shows what the assembler did, and can help with debugging.
Checking options... We disable case sensitivity, and ask the assembler to check if labels look like commands (if we forget a tab on our command)
Defined Symbol... I'm defining 'BuildGen' and 'Vasm' on the command line, my code uses this with conditional assembly to allow the multiplatform examples to run on multiple systems.
The Output file... This is the built program, It's a binary, but we need the SH2 part too!


We assemble the SH2 part on the command line with the following command:



ASM Source file... %BuildFile% is the source file in this example it's a batch variable, but you may just want 32x_HelloWorld.asm here.
Cpu Type... We specify the SH7600 , another name for the SH2!
Listing file... You don't need one, but a listing file shows what the assembler did, and can help with debugging.
Defined Symbol... I'm defining 'BuildSat' on the command line, my code uses this with conditional assembly to allow the multiplatform examples to run on multiple systems.
The Output file... This is the built program, but it's not in a format our emulator can run just yet!


We use P2BIN to convert the intermediate SH2 file (Prog.bld) into the finished binary file (Prog.bin)

We then use Copy /B (Copy Binary) To attach the 32x part to the SH2 part



Our program is done, so we launh it from the command line with our emulator Yabause
Here is the result

Bonus! Extending with a Monitor
In these tutorials we use some software debugging tools,

A Monitor which shows the state of the registers,
a Mem Dump which shows some lines of the memory
Here is the result

Monitor Code
The monitor functions need a newline command.

It sets Y=Y+1, X=0
The monitor uses a PUSHALL and POPALL macro to easily back up and restore registers.

These are defined in a separate asm file.
We need to include the monitor tools as a separate file.
Writing your own monitor tools may seem a bit odd, but writing our own means we don't have to worry about the functionality our emulator does or does not provide.

The Monitor tools are pretty complex, so we're not going to discuss their workings here!




 

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
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!


























































































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!