*last version: *
03. Running our first code
Now that we've got our working environment ready to go, let's test and configure it with some simple code to make sure everything's working properly.
Sample code
Create a new file named main.asm under $HOME/my_project/src/ and let's copy/past this piece of code into it:
.SMSHEADER
PRODUCTCODE 26, 7, 2
VERSION 0
REGIONCODE 4
RESERVEDSPACE 0xFF, 0xFF
ROMSIZE 0xC
.ENDSMS
.BANK 0 SLOT 0
.ORG $0000
di ; Disable interrupts.
im 1 ; Interrupt mode 1.
ld sp, $DFF0 ; Init stack pointer.
xor a ; Clear A register.
ld a, $FF ; Load value 255 into register A.
halt ; Stop the CPU until an interrupt occurs.
This code does nothing special except initialize a value in the CPU A register. In the following sections, we will take a look at how the code works.
Sega Header and copy protection
To understand what the SMSHEADER
instructions block does, we need to understand how the console detects and ensures that the cartridge contains a valid game.
On console start-up, the Z80 CPU will start reading instructions from the Sega MPR-12808 that contains the BIOS program. This program is in charge of :
- Displays the Sega logo on screen.
- Checks which slots have anything attached on them. On the Sega Master System 2, there is only the cartridge slot, but on others versions you can have card and expansion slot.
Checking whether a cartridge is inserted is done by checking for the presence of a header at the address $7FF0 in the ROM.
Depending on the console type and bios version, the tasks are different. Some BIOS makes a sound at boot, do an animation with the Sega's logo, or have a secret small game named 'Snail Maze'. See this topic about all BIOS versions.
From the official documentaion, the header is composed of :
- At the address $7FF0: 10 bytes for the string 'TMR SEGA' in ASCII. The last two bytes are called 'Reserved Byte' and can by anything, the official documentation states that the value must be 0x20, but some games give other values like $00 or $FF.
- At the address $7FFA and $7FFB: 2 bytes for the ROM checksum (without these two addresses).
- At the address $7FFC, $7FFD and the high nipple of $7FFE: 20 bits for a serial number, assigned by Sega.
- The low nipple of $7FFE: 4 bits for the software revision number.
- The high nipple of $7FFF: 4 bits for the region code.
- The low nipple of $7FFF: 4 bits for the ROM Size.
Let's take an example with the header from the game Sonic the Hedgehog with the command: hexdump -C -s 0x7FF0 -n 16 Sonic.sms
.
From the official documentation, by Sega, rom size of 0x40 is 256KBytes.
This page goes further in describing the header and all values that can be assigned to: ROM Header.
So, the instructions at the beginning of our code are there to tell wla-dx the values it must set in our binary in order to have a valid header for the Master System. More information in the official wla-dx SMSHEADER documentation.
Side note:
In the 80s, Nintendo imposed on editors the fact that they had to buy a license from them to publish their games on the NES system. The famous Nintendo Seal of Quality was sold as a guarantee of quality for consumers (following what had happened with the Atari 2600 and the many very bad games). To be honest, it was a way too for making money.
To ensure that no publisher circumvents this obligation, they created the 10NES CIC lockout chip. The system consists of two parts: one chip in the console (the "lock") that checks the inserted cartridge for authentication, and a matching chip in the game cartridge (the "key").
Without the chip in the cartridge, your game cannot boot at all on the NES. These chip was patented and if you try to reproduce it or use a counterfeit, Nintendo can sue you for infringement.
For more information about this security measure, check this video: Secrets of the Nintendo CIC Chip by Modern Vintage Gamer.
For sega, the approach was a bit different. On the Genesis/Mega Drive, they have opted for a protection system named Trademark Security System Anti-Tamper. Because the string 'TMR' stands for 'Trade Marks Registry' (I supposed), I'm not sure if it was to use the same protection mechanism with Sega's intellectual property infringement.
You can check:
Memory Bank and slot
Slot: Addressable memory range Bank: 16KB Section of physical memory Page: 8KB section of physical memory