Monday, September 15, 2014

z88dk 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.

Here, we built a simple Hello World program similar to how 8-bit video games were written 30 years ago!
(Cartridge-based video games built for 8-bit Sega Retro Gaming consoles were written in pure assembly)

Therefore, the process to write Z80 assembly language from scratch for the SMS can be very daunting.
Fortunately, there is another way: write game code in C language using Z88 Development Kit (z88dk).
     

Let’s check it out!

z88dk
The z88dk is a Z80 / C cross compiler supplied with an assembler, linker and a set of C standard libraries.
The compiler is portable: targets Amiga OS, HP-UX 9, Linux, Mac OS/X, MS-DOS, Windows and the SMS.

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

Text Editor
Download and install ConTEXT. Download the syntax highlighter file. Save to the Highlighters folder.

Assembler
Recommended is the WLA DX assembler. Download compiled binaries and extract to C:\wlaz80win32.
Add C:\wlaz80win32 to PATH environment variable for custom batch scripts to compile Z80 / C code.

Emulators
If you followed the Sega Retro Gaming series then you would have both Fusion and Meka installed:
- Fusion: popular emulator used to play Sega retro games. Download Fusion364.zip and extract.
- Meka: emulator with some excellent debugging features. Download mekaw073.zip and extract.

Disassembler
Recommended is the SMS Examine disassembler. Download smsexamine1_2a.zip and extract.
Note: output is recompilable by WLA DX; thus perfect to reverse engineer binary output files.

Hex Editor
Also, install Hex Editor to inspect binary data generated from the assembler:
Download and extract HxD Hex Editor. Double click the setup.exe to install.

Setup
Follow all instructions from All Things Micro: this documents how to setup the Z80 dev environment.

Cygwin
Download and install Cygwin to C:\cygwin. Accept the default packages location C:\cygwin\packages.
Ensure you install devel package category. This is required to use Linux commands like cp and make.
Finally, add C:\cygwin\bin to PATH environment variable to use Linux commands on Windows:
Right click Computer | Properties | Advanced system settings | Environment Variables | Path
Start | Run | cmd. Enjoy Linux commands on Windows like cp and make!

z88dk
Download and install z88dk-1.8.0-setup.exe to C:\z88dk. Choose full installation all options.
Add C:\z88dk\bin to PATH environment variable. Update Temp directory to C:\Temp\Temp.
Also, ensure the z88dk installation configures the following User environment variables:
 Z80_OZFILES c:\z88dk\lib
 ZCCCFG c:\z88dk\lib\config

Start | Run | cmd. Type cd C:\z88dk\libsrc | Type zcc. The following should display:
Type make clean. Deletes all pre-compiled libraries and objects needed for current platforms.
Type make all. Makes all libraries for all the current platforms; this process may take a while!

Crimson IDE
Recommended is Crimson Emerald Editor. Download and install cedt-286M-setup.exe.
Configure the IDE with custom batch script to compile, link, and run all Z80 / C code.

Hello World
As an example, let's work through the libctest.c "Hello" program found in C:\z88dk\examples\sms.
First, create new directory: C:\HelloWorld. Next, add the following 3x files: test.c, test.s and linkfile.

test.c
#include <sms.h>
#include <stdio.h>

unsigned char pal1[] = {0x00, 0x20, 0x08, 0x28, 0x02, 0x22, 0x0A, 0x2A, 0x15, 0x35, 0x1D, 0x3D, 0x17, 0x37, 0x1F, 0x3F};
unsigned char pal2[] = {0x00, 0x03, 0x08, 0x28, 0x02, 0x22, 0x0A, 0x2A, 0x15, 0x35, 0x1D, 0x3D, 0x17, 0x37, 0x1F, 0x3F};

void main()
{
 set_vdp_reg(VDP_REG_FLAGS1, VDP_REG_FLAGS1_SCREEN);
 load_tiles(standard_font, 0, 255, 1);
 load_palette(pal1, 0, 16);
 load_palette(pal2, 16, 16);

 printf("Hello!");
 for (;;)
 {
  wait_vblank_noint();
 }
}
 
Important: ensure the final blank line is included otherwise an "Unexpected end of file error" may occur.

test.s
.MEMORYMAP
SLOTSIZE $8000
DEFAULTSLOT 0
SLOT 0 $0000
SLOT 1 $8000
.ENDME

.ROMBANKMAP
BANKSTOTAL 1
BANKSIZE $8000
BANKS 1
.ENDRO

.SDSCTAG 1.0, "Hello World", "Obligatory Hello World program", "StevePro Studios"

.EMPTYFILL $C9                ;ret.
.COMPUTESMSCHECKSUM           ;compute sms checksum for this rom.

.BANK 0 SLOT 0
.ORG 0

.INCBIN "test.bin"
linkfile
[objects]
test.o

Note: before continuing, ensure you make the following changes to the C:\wlaz80win32\Compile.bat file:
set WLAPATH=%~dp0

rem Cleanup to avoid confusion
if exist test.o del test.o

rem Compile
"%WLAPATH%wla-z80.exe" -o %1 test.o

rem Make linkfile
echo [objects]>linkfile
echo test.o>>linkfile

rem Link
"%WLAPATH%wlalink.exe" -drvs linkfile output.sms

rem Fixup for eSMS
if exist output.sms.sym del output.sms.sym
ren output.sym output.sms.sym

rem Cleanup to avoid mess
if exist test.o del test.o

Build
Manually compile, assemble and link 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  zcc +sms test.c -o test.bin -m -create-app  test.bin
 Assemble  wla-z80 -o test.s  test.o
 Link  wlalink -v linkfile test.sms  test.sms

Finally, type test.sms. The Hello program should launch in the Fusion emulator.
Congratulations! You have just written your first SMS program in C language.

Automate
Let's automate the build process: create PerformBuild.bat script file that contains the commands.
Configure Crimson IDE to perform build process through Tools menu | Preferences... | User Tools.

Create the following file C:\PerfomBuild.bat.
REM PerfomBuild.bat
zcc +sms test.c -o test.bin -m -create-app
wla-z80 -o test.s
wlalink -v linkfile test.sms
test.sms
Launch Crimson IDE. Navigate to Tools menu | Preferences... | User Tools. Configure Ctrl+1 hot key.
 Menu Text PerformBuild
 Command C:\PerformBuild.bat
 Initial Dir $(FileDir)
 Hot Key None
 Close on exit Checked
 Save before execute Checked

Next, modify the existing file test.c. For example, change print statement to "Hello World!". Hit Ctrl+1.

Disassemble
Finally, disassemble the compiled binary file test.sms generated from the Crimson IDE batch script.
In directory C:\HelloWorld, copy the 2x files Opcodes.dat + smsexamine.exe from SMS Examine zip.

Launch command prompt, change directory cd C:\HelloWorld. Type: smsexamine.exe test.sms.
This action will generate test.sms.asm and any data files. Launch ConTEXT. Open test.sms.asm:

Follow instructions from the previous post to setup hotkeys: F9 (compile) F10 (run) F11 (debug).

Recommended also is the following setting in ConTEXT to "Automatically update changed files":
Options menu | Environment Options | General | Automatically update changed files | Checked

Press F9 to compile and link "test.sms.asm". This generates the "output.sms" binary file.
Press F10 to run program in the Fusion emulator. Press F11 to debug in Meka emulator:

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

Summary
Writing source code in C language and using Z88 Development Kit are an alternative way to produce Z80 assembly language required for 8-bit cartridge-based video games consoles like the Sega Master System!