Sega Genesis Model 2

68K Memory map

Standard

Start addressEnd addressDescription
$000000$3FFFFFCartridge ROM/RAM
$400000$7FFFFFReserved (used by the Sega CD and 32x)
$800000$9FFFFFReserved (used by the 32x?)
$A00000$A0FFFFZ80 addressing space
$A10000$A10001Version register (read-only word-long)
$A10002$A10003Controller 1 data
$A10004$A10005Controller 2 data
$A10006$A10007Expansion port data
$A10008$A10009Controller 1 control
$A1000A$A1000BController 2 control
$A1000C$A1000DExpansion port control
$A1000E$A1000FController 1 serial transmit
$A10010$A10011Controller 1 serial receive
$A10012$A10013Controller 1 serial control
$A10014$A10015Controller 2 serial transmit
$A10016$A10017Controller 2 serial receive
$A10018$A10019Controller 2 serial control
$A1001A$A1001BExpansion port serial transmit
$A1001C$A1001DExpansion port serial receive
$A1001E$A1001FExpansion port serial control
$A10020$A10FFFReserved
$A11000 Memory mode register
$A11002$A110FFReserved
$A11100$A11101Z80 bus request
$A11102$A111FFReserved
$A11200$A11201Z80 reset
$A11202$A13FFFReserved
$A14000$A14003TMSS register
$A14004$BFFFFFReserved
$C00000$C00001VDP data
$C00002$C00003VDP data (mirror)
$C00004$C00005VDP control
$C00006$C00007VDP control (mirror)
$C00008$C00009VDP HV counter
$C0000A$C00010Reserved
$C00011 PSG output
$C00012$FEFFFFReserved
$FF0000$FFFFFF68000 RAM

MegaCD Changes

The following shows changes to the 68K Memory Map with a MegaCD/SegaCD attached:

Sega CD Model 2 attached to a Model 2 Sega Genesis.
Start addressEnd addressDescription
$000000$01FFFFMegaCD BIOS ROM
$020000$03FFFFMegaCD "Program RAM" Bank Access
$200000$23FFFFMegaCD "WORD RAM"
$A12000$A120XXMegaCD "Gate Array"
$FFFD00$FFFDFFMegaCD Interrupt/Exception vectors

MegaCD BIOS ROM is always only visible to the main 68K, and decompresses a separate BIOS for the MegaCD "SubCPU" into "Program RAM". "WORD RAM" access is restricted to one 68K at a time, which is determined by a setting in the "Gate Array". "Program RAM" is $80000 bytes in size, but is only accessible by the Genesis 68K in banks of size $20000, and only when the MegaCD 68K is in "BUSREQ" (stopped). The MegaCD 68K may be stopped/reset, and the available "Program RAM" bank may be set by use of the "Gate Array".

68000 programming considerations

ROM header

The ROM header starts at $000100 and contains information about the cartridge. The following assembly code shows how to declare the header:

  1. dc.b "SEGA GENESIS"
  2. dc.b "(C)SEGA 1992.SEP"
  3. dc.b "YOUR GAME HERE"
  4. dc.b "YOUR GAME HERE"
  5. dc.b "GM XXXXXXXX-XX"
  6. dc.w $D951
  7. dc.b "J"
  8. dc.l 0
  9. dc.l ROM_End
  10. dc.l $FF0000
  11. dc.l $FFFFFF
  12. dc.b (Blank)
  13. dc.b (Blank)
  14. dc.b (Blank)
  15. dc.b (Blank)
  16. dc.b (Blank)
  17. dc.b "JUE"

Explanations for each field:

  1. The name of the console. Should be either "SEGA GENESIS" or "SEGA MEGA DRIVE" (depending on the region you are planning to program your game for). Must be 16 characters long.
  2. Firm name and build date. Must be 16 characters long, firm name is four characters long.
  3. Domestic name. Must be 48 characters long.
  4. International name. Must be 48 characters long.
  5. Program type and serial number. First two characters are either "GM" (game) or "AL" (educational). After the space, a series of eight digits gives the serial number. The final two digits give the version number.
  6. Checksum.
  7. I/O device support (unused)
  8. Start of the ROM. This should always be 0.
  9. End of the ROM. It's best to use a label at the end of your source file to determine this.
  10. Start of RAM. Just about every game starts at $FF0000, but RAM is mirrored at several other places, and you can use those if you want.
  11. End of RAM. Should be $FFFF after the starting point.
  12. Backup RAM ID. Fill this with spaces if there is none, otherwise, use this formula:
    dc.b "RA",%1x1yy000,%0010000
    where x is true when the RAM is for backup and false if not. (I've no idea what the difference is.) yy is 11 if addressing is odd bytes only, 10 if even only, and 00 if both.
  13. Start address of backup RAM. Fill with spaces if there is no backup RAM.
  14. End address of backup RAM.
  15. Modem support. Fill with spaces if there is no modem, otherwise follow this formula:
    "MOxxxxyy.zzz"
    where xxxx is the firm name, yy is the modem number, and zzz is the version number. (This is also unused)
  16. Notes. Put whatever you want here, and fill the empty spaces with zeroes.
  17. Country codes. J is for Japan, U is for the United States, and E is for Europe. You need to fill in the rest of this field with spaces. So, JU for the country code would tell the Sega that the game is for Japan and the US, JUE would tell it that it is for Japan, the US, and Europe

TMSS

Back in 1990, Accolade released a few unlicensed games for the Genesis. Sega was not pleased about this, so they invented TMSS and put it on all new consoles they manufactured. TMSS forces the game to write the ASCII string "SEGA" to $A14000 within a short period of time, or the VDP will be deactivated. On version 0 of the console, this location is reserved, and writing here may cause a crash, so the game has to first make sure that it's running on a console that has TMSS. Sega uses the following routine for that:

         move.b  $A10001,d0
         andi.b  #$0F,d0
         beq.b   version_0
         move.l  #'SEGA',$A14000
version_0:

Checksum

The checksum is a 16-bit number (word) located in the header which is present in all licensed games.It was used to check the integrity of the data by storing a pre-calculated number (the checksum) using the original data and comparing it with the checksum of the existing data in the cart, probably to prevent code changes without authorization (in-house).

The checksum is, basically, the sum of the whole cart, all its bytes, starting at address $200. As you can guess, if only a byte is changed the checksum changes too. Somewhat like the CRC/CRC32 algorithms, though those are much more accurate than this method.

You don't need to implement the checksum if you program your own homebrew rom, because the checksum is exclusively checked by software. But, anyway, this is how a typical checksum routine from a licensed game would look.

		movea.l	#$200,a0
		movea.l	#ROM_End,a1 
		move.l	(a1),d0
		moveq	#0,d1
loop:
		add.w	(a0)+,d1
		cmp.l	a0,d0
		bcc.s	loop
		movea.l	#$18E,a1	; Checksum
		cmp.w	(a1),d1
		bne.w	WrongChecksum

To disable it, comment out that last branch. If you prefer to fix the checksum, grab the Fix Checksum utility from Hacking CulT's download section.

Z80 programming considerations

Memory map

StartEndDescription
0000h1FFFhZ80 RAM
2000h3FFFhReserved
4000h YM2612 A0
4001h YM2612 D0
4002h YM2612 A1
4003h YM2612 D1
4004h5FFFhReserved
6000h Bank register
6001h7F10hReserved
7F11h PSG
7F12h7FFFhReserved
8000hFFFFh68000 memory bank
This article is issued from Wikibooks. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.