From 0711a6f9d85bb23364c4ed8db9280e7985e04fb9 Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Fri, 17 Aug 2007 15:03:07 +0000 Subject: [PATCH] fixed eeprom documentation --- source/docs/eeprom.txt | 192 +++++++++++++++++++++++++++++------------ source/eeprom.c | 20 +++++ source/eeprom.h | 85 +++++++++++------- source/input.c | 3 +- source/ngc/loadrom.c | 1 + source/state.c | 4 +- source/state.h | 4 +- 7 files changed, 221 insertions(+), 88 deletions(-) diff --git a/source/docs/eeprom.txt b/source/docs/eeprom.txt index 1b617b1..1312505 100644 --- a/source/docs/eeprom.txt +++ b/source/docs/eeprom.txt @@ -1,8 +1,89 @@ -This is the result of testing EEPROM support under Genesis Plus. -Following games use custom external RAM (serial EEPROM) for backup. -It seems that different EEPROM Mapper have been used, depending upon companies. +Here are some notes about EEPROM emulation, which is used in a few Sega Genesis Cartridge as external Backup RAM. + +The protocol used to communicate (read/write) with serial EEPROM is explained below: + + +1/ from 68000 cpu (MASTER), which is running the ROM program, each EEPROM can be managed using only two single lines: + - /SDA is the DATA line, used to send/receive data (READ/WRITE) + - /SCL is the CLOCK line used to synchronize the EEPROM cycles (WRITE ONLY) + + +2/ each line is mapped in the 68000 address space at a specific address as one specific bit (see game mappers below) +and can be set at LOW (bit=0) or HIGH (bit=1) state. + + +3/ each READ/WRITE operation must be initiated with a START condition and terminated by a STOP condition: + - START condition is set when /SDA is changed from HIGH to LOW while /SCL remaining HIGH + - STOP condition is set when /SDA is changed from LOW to HIGH while /SCL remaining HIGH + + +4/ Following the START condition, the Master send one or more 8-bit word through the /SDA line to specify the address +that must be read or write. +Each bit write requires one clock cycle, managed by changing /SCL line state. +There are 3 known EEPROM Modes, each one using different addressing protocol: + + - Mode 1 EEPROMs (24C01 only) have a maximal size of 128bytes (7bits address) and need only one address word. + The 7 first bits specify the memory address to be read/write and the 8th bit indicates if the operation type (READ or WRITE) + + - Mode 2 EEPROMs (24C01 to 24C16) can be linked together (8 slave devices max.), that means in fact one 24C16, two 24C08, four 24C04, + or eight 24C02/24C01, for a maximal size of 2 Kbytes (11bits address max.). + A first word is needed: the first 4 bits are fixed and, depending on the EEPROM size, the next 3bits specify the device address + and eventually the one (24C04), two (24C08) or three (24C16) upper bits of the memory address to be read/write. + As before, the 8th bit specifies the type of the operation (READ or WRITE) + Then a second word is needed to specify the eight lower bits of the address to be read/write. + + - Mode 3 EEPROMS (24C32 and more) work quite the Type 2 EEPROMS excepted that the maximal address size is 64 Kbytes (16bits address max.) + The first word is like in the previous type, bits d3-d1 always specifying the slave device address (8 linked devices max.) + The second word specifies the upper bits of the address to be read/write. + A third word specifies the eight lower bits of the address to be read/write. + + NOTE: In Mode2 and Mode3, before a READ operation, only the SLAVE ADDRESS WORD will be sent, the EEPROM contains an address counter + that maintains the address of the last word to be accessed (from a previous READ or WRITE operation) + + + 5/ Each time a 8bits word has been written (which requires eight clock cycles), the receiver (could be EEPROM or MASTER) send an acknowledge + to the sender by setting /SDA line LOW during the 9th cycle (ACK cycle). + + + 6/ After a WRITE SEQUENCE has been initiated, the MASTER will sent DATA as one or more sequences of 8bits words. + After each written word, the EEPROM must send a ACK and increment the address for the next data word to be written. + Word address will roll up to base address when maximal writepage size has been reached. + If the Master send a STOP condition, the WRITE operation ends. + Otherwise the WRITE operation continues to next address. + + + 7/ After a READ SEQUENCE has been initiated, the MASTER will read DATA as one or more sequence of 8bits words. + After each received word, the MASTER will send a ACK and the EEPROM will increment the address of the next data word to be read. + Word address will roll up to 0 when maximal memory size has been reached. + If the Master does not send a ACK during the 9th cycle, the READ operation ends and the EEPROM waits for STOP condition. + Otherwise, the READ operation continue to next address. + + +This is pretty how I emulate EEPROM access in Genesis Plus (see eeprom.c for technical details). +Thanks a lot to 8bitWizard from Spriteminds.net forums which initially give indications about the various EEPROM types and mappers +that can be found in Sega Genesis games. + +Here are some links to datasheets with should explain everything better than me and my crappy english ;) + +MODE1 (24C01 only): +http://www.icmic.com/datasheets/X24C01.pdf + +MODE2 (24C01 - 24C16): +http://www.atmel.com/dyn/resources/prod_documents/doc0180.pdf + +MODE3 (24C32 and more): +http://www.phys.hawaii.edu/~bryce/component_data/24LC65-ISM.pdf + + +Below are the Sega Genesis games that I found using serial EEPROM as external Backup RAM. +I also give their specific caracteristics (mapper, size, ...), determined when testing my emulation code. + + + +EkeEke +July 2007 + -Eke~Eke - July 2007 ------------------------------------------------------- @@ -19,11 +100,11 @@ header OK ($200001-$200001) TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0xFF (24C02) PAGE_MASK: 0x03 -SDA_IN : 0x200000 (0) -SDA_OUT: 0x200000 (1) -SCL : 0x200000 (1) +SDA_IN : 0x200000 (bit 0) +SDA_OUT: 0x200000 (bit 1) +SCL : 0x200000 (bit 1) -Note: this game uses a different EEPROM mapper than other Acclaim games. +NB: this game uses a different EEPROM mapper than any other Acclaim games. Blockbuster World Video Game Championship II (U) @@ -35,12 +116,16 @@ header KO TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0xFF (24C02) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200000 (0) - -Note: Rev 00 of the game has buggy eeprom support (incorrect data written), game backup only work with Rev01 version (released apparently in 2002, eight years later !) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200000 (bit 0) +NB: Rev 00 of the game has buggy eeprom support and game backup does not seem to work fine, only Rev01 +version will correctly save game data. +For history, Steve Snake, the author of Kega, one of the best Genesis emulator for Win32 platforms, is +the one who originally developped this game. +I assume that he released himself later some kind of patch to fix the backup support. +(from the header informations, rev01 has been released in 2002, eight years after rev00 !) NFL Quarterback Club (JUE) ----------------------------- @@ -50,9 +135,9 @@ header OK ($200000-$200001) TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0xFF (24C02) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200000 (0) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200000 (bit 0) NFL Quarterback Club 96 (UE) @@ -63,9 +148,9 @@ header OK ($200000-$200001) TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0x7FF (24C16) PAGE_MASK: 0x07 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200000 (0) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200000 (bit 0) College Slam (U) @@ -76,9 +161,9 @@ header OK ($200001-$200001) TYPE: 16BITS WORD ADDRESS SIZE_MASK: 0x1FFF (24C64) PAGE_MASK: 0x07 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200000 (0) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200000 (bit 0) Frank Thomas Big Hurt Baseball (UE) @@ -89,9 +174,9 @@ header OK ($200000-$200001) TYPE: 16BITS WORD ADDRESS SIZE_MASK: 0x1FFF (24C64) PAGE_MASK: 0x07 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200000 (0) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200000 (bit 0) @@ -109,9 +194,9 @@ header OK ($200001-$200001) TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200001 (1) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200001 (bit 1) NOTE: the original version of Rockman Mega World (J) uses traditional SRAM, header gives $200000-$203FFF range the alternate version uses a 128bytes serial EEPROM (X24C01) @@ -131,9 +216,9 @@ header KO TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200000 (7) -SDA_OUT: 0x200000 (7) -SCL : 0x200000 (6) +SDA_IN : 0x200000 (bit 7) +SDA_OUT: 0x200000 (bit 7) +SCL : 0x200000 (bit 6) Rings of Power (UE) @@ -144,9 +229,9 @@ header KO TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200000 (7) -SDA_OUT: 0x200000 (7) -SCL : 0x200000 (6) +SDA_IN : 0x200000 (bit 7) +SDA_OUT: 0x200000 (bit 7) +SCL : 0x200000 (bit 6) @@ -162,9 +247,9 @@ header OK ($200001-$200001) TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200001 (1) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200001 (bit 1) Greatest Heavyweights of the Ring (U) @@ -179,9 +264,9 @@ header OK ($200001-$200001) TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200001 (1) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200001 (bit 1) Wonder Boy in Monster World (UE) @@ -193,9 +278,9 @@ header OK ($200001-$200001) TYPE: 7BITS WORD ADDRESS SIZE_MASK: 0x7F (24C01) PAGE_MASK: 0x03 -SDA_IN : 0x200001 (0) -SDA_OUT: 0x200001 (0) -SCL : 0x200001 (1) +SDA_IN : 0x200001 (bit 0) +SDA_OUT: 0x200001 (bit 0) +SCL : 0x200001 (bit 1) @@ -211,12 +296,11 @@ header KO TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0x3FF (24C08) PAGE_MASK: 0x0F -SDA_IN : 0x300000 (0) -SDA_OUT: 0x380001 (7) -SCL : 0x300000 (1) +SDA_IN : 0x300000 (bit 0) +SDA_OUT: 0x380001 (bit 7) +SCL : 0x300000 (bit 1) -Note: this game needs the EEPROM to be initially fullfilled with the string -"PETETEST01234567" otherwise it won't initialize memory with correct data. +NB: this game needs the external RAM to be initialized with 0xFF otherwise it won't initialize memory with correct data. Micro Machines Military (E) (J-Cart) @@ -227,9 +311,9 @@ header KO TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0x3FF (24C08) PAGE_MASK: 0x0F -SDA_IN : 0x300000 (0) -SDA_OUT: 0x380001 (7) -SCL : 0x300000 (1) +SDA_IN : 0x300000 (bit 0) +SDA_OUT: 0x380001 (bit 7) +SCL : 0x300000 (bit 1) Micro Machines Turbo Tournament 96 (E) (J-Cart) @@ -240,6 +324,6 @@ header KO TYPE: TYPE: 8BITS WORD ADDRESS SIZE_MASK: 0x7FF (24C16) PAGE_MASK: 0xF -SDA_IN : 0x300000 (0) -SDA_OUT: 0x380001 (7) -SCL : 0x300000 (1) \ No newline at end of file +SDA_IN : 0x300000 (bit 0) +SDA_OUT: 0x380001 (bit 7) +SCL : 0x300000 (bit 1) \ No newline at end of file diff --git a/source/eeprom.c b/source/eeprom.c index 303cd62..2c3b1ac 100644 --- a/source/eeprom.c +++ b/source/eeprom.c @@ -1,3 +1,23 @@ +/**************************************************************************** + * Serial EEPROM support for Sega Genesis games + * + * Copyright (C) 2007 EkeEKe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + ***************************************************************************/ + #include "shared.h" #include "rominfo.h" diff --git a/source/eeprom.h b/source/eeprom.h index 0c0abd6..7381e08 100644 --- a/source/eeprom.h +++ b/source/eeprom.h @@ -1,4 +1,38 @@ +/**************************************************************************** + * Serial EEPROM support for Sega Genesis games + * + * Copyright (C) 2007 EkeEKe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + ***************************************************************************/ + +typedef enum +{ + STAND_BY = 0, + WAIT_STOP, + GET_SLAVE_ADR, + GET_WORD_ADR_7BITS, + GET_WORD_ADR_HIGH, + GET_WORD_ADR_LOW, + WRITE_DATA, + READ_DATA, + +} T_EEPROM_STATE; + /* this defines the type of EEPROM inside the game cartridge as Backup RAM + * * Here are some notes from 8BitWizard (http://www.spritesmind.net/_GenDev/forum): * * Mode 1 (7-bit) - the chip takes a single byte with a 7-bit memory address and a R/W bit (24C01) @@ -15,43 +49,32 @@ typedef struct { - uint8 address_bits; /* number of bits needed to address the array: 7, 8 or 16 */ - uint16 size_mask; /* size of the array (in bytes) - 1 */ - uint16 pagewrite_mask; /* maximal number of bytes that can be written in a single write cycle - 1*/ - uint32 sda_in_adr; /* 68k address used by SDA_IN signal */ - uint32 sda_out_adr; /* 68k address used by SDA_OUT signal */ - uint32 scl_adr; /* address used by SCL signal */ - uint8 sda_in_bit; /* position of the SDA_IN bit */ - uint8 sda_out_bit; /* position of the SDA_OUT bit */ - uint8 scl_bit; /* position of the SCL bit */ + uint8 address_bits; /* number of bits needed to address memory: 7, 8 or 16 */ + uint16 size_mask; /* depends on the max size of the memory (in bytes) */ + uint16 pagewrite_mask; /* depends on the maximal number of bytes that can be written in a single write cycle */ + uint32 sda_in_adr; /* 68000 memory address mapped to SDA_IN */ + uint32 sda_out_adr; /* 68000 memory address mapped to SDA_OUT */ + uint32 scl_adr; /* 68000 memory address mapped to SCL */ + uint8 sda_in_bit; /* bit offset for SDA_IN */ + uint8 sda_out_bit; /* bit offset for SDA_OUT */ + uint8 scl_bit; /* bit offset for SCL */ } T_EEPROM_TYPE; -typedef enum -{ - STAND_BY = 0, - WAIT_STOP, - GET_SLAVE_ADR, - GET_WORD_ADR_7BITS, - GET_WORD_ADR_HIGH, - GET_WORD_ADR_LOW, - WRITE_DATA, - READ_DATA, - -} T_EEPROM_STATE; typedef struct { - uint8 sda; - uint8 scl; - uint8 old_sda; - uint8 old_scl; - uint8 cycles; - uint8 rw; - uint16 slave_mask; - uint16 word_address; - T_EEPROM_STATE state; - T_EEPROM_TYPE type; + uint8 sda; /* current /SDA line state */ + uint8 scl; /* current /SCL line state */ + uint8 old_sda; /* previous /SDA line state */ + uint8 old_scl; /* previous /SCL line state */ + uint8 cycles; /* current operation cycle number (0-9) */ + uint8 rw; /* operation type (1:READ, 0:WRITE) */ + uint16 slave_mask; /* device address (shifted by the memory address width)*/ + uint16 word_address; /* memory address */ + T_EEPROM_STATE state; /* current operation state */ + T_EEPROM_TYPE type; /* EEPROM characteristics for this game */ + } T_EEPROM; /* global variables */ diff --git a/source/input.c b/source/input.c index 0b2b5c3..1449882 100644 --- a/source/input.c +++ b/source/input.c @@ -16,7 +16,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - NGC port (June 2007): Added various Peripherals emulation (Eke-Eke) + 02/2007: fixed 6BUTTONS gamepad emulation (Eke-Eke) + 06/2007: Added TEAMPLAYER/4WAYPLAY/MENACER emulation (Eke-Eke) */ #include "shared.h" diff --git a/source/ngc/loadrom.c b/source/ngc/loadrom.c index cba2461..e8274a0 100644 --- a/source/ngc/loadrom.c +++ b/source/ngc/loadrom.c @@ -83,6 +83,7 @@ void genesis_set_region () * set specific timings for some games */ extern uint8 alttiming; + extern uint8 vdptiming; extern uint8 sys_type[2]; void detect_game() diff --git a/source/state.c b/source/state.c index 2dfe411..0319816 100644 --- a/source/state.c +++ b/source/state.c @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * STATE MANAGER + * + * Freeze State support (added by EkeEke for the Gamecube's port - Feb,2007) + * ***************************************************************************/ #include "shared.h" diff --git a/source/state.h b/source/state.h index c3bad4d..0cd0482 100644 --- a/source/state.h +++ b/source/state.h @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * STATE MANAGER + * + * Freeze State support (added by EkeEke for the Gamecube's port - Feb,2007) + * ***************************************************************************/ #ifndef _STATE_H_ #define _STATE_H_