Zipped Original Memory from Genesis
Draft Version 0.1
(c) Copyright 2008 by David Korth.

================================================================

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".

================================================================

0. Draft Document Notice

WARNING: This document is a draft version of an upcoming file format.
Please do not write an implementation of the file format using this
document, as the file format may change during the draft process, which
may break compatibility with the version described in this document.

================================================================

1. What is Zipped Original Memory from Genesis?

Zipped Original Memory from Genesis, or ZOMG, is a new savestate format
for Sega Genesis emulators. Whereas most savestate formats have hardcoded
offsets for segments, ZOMG uses a Zip file that contains each segment as
a separate file.

The pathname convention used in this document is Unix-style; however,
Windows-style pathnames can be used for emulators running on Windows.

Each system stored in a savestate has its own subdirectory. For example,
if a savestate contained data for both Mega Drive and MegaCD, there would
be two subdirectories: /MD and /MCD .

Save files may have a specified endianness. They are "BE" for Big Endian
(Motorola format) and "LE" for Little Endian (Intel format), along with
an optional word-size specifier

================================================================

2. FORMAT.ini

Every ZOMG archive contains at least one file: /FORMAT.ini
This file is a text file in INI format, encoded using UTF-8.
Line endings may be either Unix-style ("\n") or Windows-style
("\r\n"). Linebreaks may be embedded within values by using the
"\n" escape sequence.

Here is an example FORMAT.ini file:

[ZOMG]
FileType=Zipped Original Memory from Genesis
Version=0.1
System=MD
Creator=Genesis Emulator 2.12.194
Author=Joe the Plumber
ROM=Sonic the Hedgehog.gen
Description=Sample savestate from Sonic 1.
Extensions=

Values: (* indicates required; - indicates optional.)

* FileType: Contains the filetype. Must be "Zipped Original Memory from Genesis".
* Version: ZOMG specification version number.
* System: Systems used for the savestate, comma-separated.
- Creator: Program that created the savestate.
- Author: Person who created the savestate.
- ROM: Filename of the ROM file used to create the savestate.
- Description: A short description of the savestate.
- Extensions: Any extensions to the base format, comma-separated.

For the System value, System may be a combination of more than one system.
Each system is comma-separated.
Acceptable values:
- MD: Mega Drive / Genesis
- MCD: Mega CD / Sega CD
- 32X: Sega 32X

For SegaCD games, the System value would contain "MD,MCD".
SegaCD 32X games would have a System value of "MD,MCD,32X".

The ROM field is for user reference only. It should not be used by an emulator
to determine which ROM to load, or if a savestate is valid for a given ROM.

The Extensions field is usually blank for ZOMG files conforming to the
ZOMG version listed in the Version field. It is included to allow for
custom extensions to the format.

================================================================

3. Optional files in the root directory

The following files are optional, but highly recommended:

/PREVIEW.png: A preview screenshot of the savestate.

================================================================

4. Sega Genesis (Mega Drive) savestate directory

Files contained in the /MD subdirectory:

+---------------+--------------+--------+
| Filename      | Size (bytes) | Endian |
+---------------+--------------+--------+
| M68K_RAM.bin  |       65,536 |  BE16  |
| M68K_DREG.bin |           64 |  BE32  |
| M68K_AREG.bin |           64 |  BE32  |
| M68K_OREG.bin |           10 |   BE   |
| Z80_REG.bin   |           68 |  LE16  |
| VDP_VRAM.bin  |       65,536 |  BE16  |
| VDP_CRAM.bin  |          128 |  BE16  |
| VDP_VSRAM.bin |           80 |   ??   |
| VDP_REG.bin   |           32 |   ??   |
| INPUT1.bin    |     variable |   ??   |
| INPUT2.bin    |     variable |   ??   |
+---------------+--------------+--------+

Main 68000 files:

M68K_RAM.bin: Contains the main 68000 memory.
M68K_DREG.bin: Contains all 8 data registers (D0-D7), in order.
M68K_AREG.bin: Contains all 8 address registers (A0-A7), in order.

M68K_OREG.bin: Contains other registers, in this order:
- PC (4 bytes)
- SR (2 bytes)
- ASP? (4 bytes)

Z80 files:

Z80_REG.bin: Contains Z80 registers, in this order:
- AF (2 bytes)
- BC (2 bytes)
- DE (2 bytes)
- HL (2 bytes)
- IX (2 bytes)
- IY (2 bytes)
- PC (2 bytes)
- SP (2 bytes)
- AF2 (2 bytes)
- BC2 (2 bytes)
- DE2 (2 bytes)
- HL2 (2 bytes)
- IFF (2 bytes)
- R (2 bytes)
- I (1 byte)
- IM (1 byte)
- IntVect (1 byte)
- IntLine (1 byte)
- Status (4 bytes) [TODO]
- TmpSav0 (4 bytes) [TODO]
- TmpSav1 (4 bytes) [TODO]
- CycleCnt (4 bytes) [TODO]
- CycleTD (4 bytes) [TODO]
- CycleIO (4 bytes) [TODO]
- CycleSup (4 bytes) [TODO]
- RetIC (4 bytes) [TODO]
- IntAckC (4 bytes) [TODO]

VDP files:

VDP_VRAM.bin: Contains Video RAM.
VDP_CRAM.bin: Contains Color RAM.
VDP_VSRAM.bin: Contains Vertical Scroll RAM.

VDP_REG.bin: Contains VDP registers, in this order:
- Status (4 bytes)
- Int (4 bytes)
- Current Line (4 bytes)
- Num Lines (4 bytes)
- Num Vis Lines (4 bytes)
- DMAT Length (4 bytes)
- DMAT Type (4 bytes)
- VRAM Flag (4 bytes)

[OPTIONAL] INPUT1.bin, INPUT2.bin:
- Contains controller data for devices plugged into ports 1 and 2.

Offset 0x00: LE32 containing controller type:
- 0x00: No device. (This would also be the end of the file.)
- 0x01: 3-button controller.
- 0x02: 6-button controller.
- 0x03: Teamplayer adapter.

Offset 0x04: (LE16) Controller state.
Offset 0x06: (LE16) Controller "COM".
Offset 0x08: (LE16) Controller counter.
Offset 0x0A: (LE16) Controller delay.

The contents of the rest of the file depends on the controller type.

Controller Types 0x01, 0x02: (3-button, 6-button):
- Offset 0x0C: (LE32) Controller button bitfield.

The button bitfield is in this format: (1 = not pressed; 0 = pressed)
11111111 11111111 1111ZYXM CBASRLDU

For type 0x01 (3-button), Mode, X, Y, and Z are ignored.

Controller Type 0x03: (Teamplayer adapter)
- Offset 0x0C: (LE32) Controller A button bitfield.
- Offset 0x10: (LE32) Controller B button bitfield.
- Offset 0x14: (LE32) Controller C button bitfield.
- Offset 0x18: (LE32) Controller D button bitfield.

The format is the same as with controller types 0x01 and 0x02.
