Friday, September 15, 2017

devkitSMS Programming Setup

In 2013, we checked out Sega Console Programming, specifically for the Sega Master System (SMS).
The SMS was the last ever 8-bit video game console manufactured by Sega built using the Z80 chip.

However, the process to write Z80 assembly language from scratch for the SMS can be very daunting. Instead, in 2014 we checked out z88dk Programming Setup to write code in C language using z88dk.

All code here worked on emulators but real Sega Master System hardware experienced graphics glitches! Fortunately, there is another way: write game code in C language using devkitSMS and SDCC compiler.
Let’s check it out!

devkitSMS
The devkitSMS is a collection of tools and code built specifically for the Sega Master System but also supports homebrew development using C language for SG-1000, SC-3000 and the Sega Game Gear.

Software
Follow all instructions from the previous post: this documents how to setup the pre-requisite software.

Here is a summary of all required software to be installed:
 Name Version
 Z80 Editor ConTEXT
 Assembler WLA DX
 Emulators Fusion, Meka, Emulicious
 Disassembler SMS Examine
 
 Name Version
 C IDE Editor Visual Studio 2008
 Cross compiler Small Device C Compiler
 Make files Cygwin
 Hex Editor HxD

SDCC
Download and install sdcc-3.6.0-x64-setup.exe to C:\Program Files\SDCC. Choose all features to install. UPDATE: if you build games like Astro Force then I believe you need to upgrade to version sdcc-3.6.9.

There should be no extra configuration except add C:\Program Files\SDCC\bin to the Environment PATH.

Start | Run | cmd. Type sdcc --version. The following should display to confirm SDCC version 3.6.0:

devkitSMS
Navigate to the devkitSMS repository on github. @sverx has full instructions here and advises to copy the following 3x executables into the SDCC bin folder [above]: ihx2sms.exe, assets2banks.exe, folder2c.exe.
# Clone devkitSMS
cd C:\GitHub\sverx
git clone https://github.com/sverx/devkitSMS.git

# Copy 3x files
cd devkitSMS
copy ihx2sms\ihx2sms.exe C:\Program Files\SDCC\bin
copy assets2banks\assets2banks.exe C:\Program Files\SDCC\bin
copy folder2c\folder2c.exe C:\Program Files\SDCC\bin
Note: my preference is to usually copy these 3x files up-top-date as each Master System project is built.


Example
As an example, let's write a simple program that sets the border colors of the screen using devkitSMS. Create new directory: C:\HelloWorld. Copy these files: crt0_sms.rel, SMSlib.h, SMSlib.lib, ihx2sms.exe

main.c
#include "SMSlib.h"
void main (void)
{
  SMS_setSpritePaletteColor(0, RGB(3,3,3));
  SMS_displayOn();
  for (;;)
  {
    SMS_waitForVBlank();
  }
}

SMS_EMBED_SEGA_ROM_HEADER(9999, 0);
SMS_EMBED_SDSC_HEADER(1, 0, 2017, 9, 15, "StevePro Studios", "Hello World", "Simple Sega Master System demo to run on real hardware!");

Build
Manually compile, link and execute the Hello program. Launch command prompt: Start | Run | cmd.

Change directory cd C:\HelloWorld. Next, execute the following 3x commands (in bold):
 ACTION  COMMAND  OUTPUT
 Compile   sdcc -c -mz80 main.c  main.rel
 Link  sdcc -o output.ihx -mz80 --data-loc 0xC000 --no-std-crt0 crt0_sms.rel
 main.rel SMSlib.lib
 output.ihx
 Exceute  ihx2sms output.ihx output.sms  output.sms 

Finally, type output.sms. The Hello program should launch in the Fusion emulator.
Congratulations! You have just written your first SMS program using devkitSMS.

Automate
Let's automate the build process: create C:\HelloWorld\build.bat script file that contains the commands:
@echo off
sdcc -c -mz80 main.c
sdcc -o output.ihx -mz80 --data-loc 0xC000 --no-std-crt0 crt0_sms.rel main.rel SMSlib.lib
ihx2sms output.ihx output.sms
output.sms

Visual Studio
Inspired by this suggestion to use Visual Studio as an IDE to better navigate files in larger projects and help automate the development build system. Download + install Visual Studio 2008 and setup solution.

Launch Visual Studio 2008. File | New | Project... | Visual C++ | Win32 | Win32 Project
 Name:  HelloWorld
 Location:  C:\
 Create directory for solution  UNCHECKED

 Application type:  Console application
 Additional options:  Empty project CHECKED

Navigate to C:\HelloWorld. Copy the following files as before such that they are on the same folder level like HelloWorld.sln: crt0_sms.rel, SMSlib.h, SMSlib.lib, ihx2sms.exe. Add existing: main.c and build.bat.

External Tools
Integrate the build process directly from within Visual Studio 2008 using the External Tools functionality.
Choose Tools menu | External Tools... | Add
 Title:  Run Batch File
 Command:  CMD.EXE
 Arguments:  /c "$(SolutionDir)"build.bat
 Initial directory:  $(SolutionDir)
 Use Output Window  CHECKED
 Close on exit  CHECKED
Click Apply button. Click Move Up button until "Run Batch File" is at the top of the list.

Keyboard Shortcut
Next connect "Run Batch File" command to Ctrl+1 hot key to automatically build, link and execute code!

Choose Tools menu | Options... | Environment | Keyboard. Show command containing: "Tools". Scroll list down to "Tools.ExternalCommand1". In the "Press shortcut keys:" textbox hit Ctrl+1. Click Assign button.

Disassemble
Finally, disassemble the compiled binary file output.sms generated from the Visual Studio batch script.
In directory C:\HelloWorld, copy the 2x files Opcodes.dat and smsexamine.exe from SMS Examine zip.

Launch command prompt, change directory to cd C:\HelloWorld. Type: smsexamine.exe output.sms.
This action will generate output.sms.asm and any data files. Launch ConTEXT. Open output.sms.asm: Follow instructions to setup emulator hotkeys for: F10 (Fusion) F11 (Meka) + HOTKEY F12 (Emulicious).

Press F12 to run program in Emulicious. Ensure VDP constraints are ENABLED to emulate real hardware.

Note: in Emulicious we are able to debug through the HelloWorld source assembly code:

Compare machine code in the debugger with the raw binary output file from output.sms.

Update the build.bat script to include the disassemble step. Clean up and delete any unnecessary files:
@echo off
sdcc -c -mz80 main.c
sdcc -o output.ihx -mz80 --data-loc 0xC000 --no-std-crt0 crt0_sms.rel main.rel SMSlib.lib
ihx2sms output.ihx output.sms
smsexamine.exe output.sms
del *.ihx > nul
del *.lk > nul
del *.lst > nul
del *.map > nul
del *.noi > nul
del *.sym > nul
output.sms

Summary
Now the devkitSMS has been downloaded, installed and setup, it is possible to write full homebrew demos and / or video games to target real Sega Master System hardware! This will be the topic of the next post.