EEPROM: Difference between revisions

From WSdev Wiki
Jump to navigationJump to search
(add errata)
(→‎Internal EEPROM Layout: figure out bytes 0x80, 0x81, 0x82)
 
(23 intermediate revisions by 2 users not shown)
Line 31: Line 31:
=== WDS - Write Disable ===
=== WDS - Write Disable ===


TODO
The WDS command prevents issued write and erase commands from having an effect on the EEPROM.


=== WRAL - Write All ===
=== WRAL - Write All ===
Line 47: Line 47:
=== WEN - Write Enable ===
=== WEN - Write Enable ===


TODO
The WEN command restores the effect of issued write and erase commands on the EEPROM disabled using WDS.


== I/O ports ==
== I/O ports ==
Line 53: Line 53:
The I/O ports listed refer to the internal EEPROM; for the cartridge EEPROM port numbers, refer to the [[Bandai 2001|mapper documentation]].
The I/O ports listed refer to the internal EEPROM; for the cartridge EEPROM port numbers, refer to the [[Bandai 2001|mapper documentation]].


Note that on the original/"mono" WonderSwan, the data and command registers can ''only'' be accessed word-wide via even addresses: access to odd addresses whether byte or word-wide don't provide valid data. This has been fixed on the WonderSwan Color, even for "mono" compatibility mode.
It is recommended to only access the data and command ports with aligned word reads/writes; see the ''Errata'' section for more information.


{{Anchor|Internal EEPROM Data}}
{{Anchor|Internal EEPROM Data}}
=== Internal EEPROM Data ($BA, $BB) ===
=== Internal EEPROM Data ($BA, $BB read) ===


<pre>
<pre>
Line 63: Line 63:
  dddd dddd  dddd dddd
  dddd dddd  dddd dddd
  |||| ||||  |||| ||||
  |||| ||||  |||| ||||
  ++++-++++--++++-++++- Data read from/written to the EEPROM.
  ++++-++++--++++-++++- Data read from the EEPROM.
</pre>
</pre>


This port functions as a shared buffer for both "read" and "write" modes. (TODO: Verify)
The read buffer's value changes only once the Read command is completed.
 
=== Internal EEPROM Data ($BA, $BB write) ===
 
<pre>
15  bit  8  7  bit  0
---- ----  ---- ----
dddd dddd  dddd dddd
|||| ||||  |||| ||||
++++-++++--++++-++++- Data to write to the EEPROM.
</pre>
 
The write buffer is latched when a Write command is initiated; further writes to it do not affect the value written by that specific command.
 
The two EEPROM data buffers are not shared; neither writes to the write buffer nor the execution of non-read commands affect the contents of the read buffer.


{{Anchor|Internal EEPROM Command}}
{{Anchor|Internal EEPROM Command}}
=== Internal EEPROM Command ($BC, $BD) ===
=== Internal EEPROM Command ($BC, $BD) ===


Line 92: Line 107:
15  bit  8  7  bit  0  
15  bit  8  7  bit  0  
  ---- ----  ---- ----
  ---- ----  ---- ----
  0000 0001  00ss ....     (1 Kbit - M93LC46)
  0000 0001  00ss .... (¼, 1 Kbit - M93LC06/46)
  0000 0100  ss.. ....  (2, 4 Kbit - M93LC56/66)
  0000 0100  ss.. ....  (2, 4 Kbit - M93LC56/66)
  0001 00ss  .... .... (8, 16 Kbit - M93LC76/86)
  0001 00ss  .... .... (8, 16 Kbit - M93LC76/86)
        ||
      ||||
        ++------------ Sub-Opcode:
      ||++------------ Sub-Opcode:
                        00 - WDS
      ||                00 - WDS
                        01 - WRAL
      ||                01 - WRAL
                        01 - ERAL
      ||                10 - ERAL
                        11 - WEN
      ||                11 - WEN
      ++-------------- Opcode:
                        00
</pre>
</pre>
The value written to this port can be read back; it is not affected by ''EEPROM Control''.


{{Anchor|Internal EEPROM Control}}
{{Anchor|Internal EEPROM Control}}
=== Internal EEPROM Control ($BE, $BF write) ===
=== Internal EEPROM Control ($BE, $BF write) ===


Line 109: Line 129:
15  bit  8  7  bit  0  
15  bit  8  7  bit  0  
  ---- ----  ---- ----
  ---- ----  ---- ----
  .... ....  pswr ....
  .... ....  PSWR ....
             ||||
             ||||
             |||+------ Read mode:  1 for READ command, 0 otherwise
             |||+------ Read operation:  1 for READ command, 0 otherwise
             ||+------- Write mode: 1 for WRITE and WRAL command, 0 otherwise
             ||+------- Write operation: 1 for WRITE and WRAL command, 0 otherwise
             |+-------- Short mode: 1 for ERASE, WDS, ERAL and WEN command, 0 otherwise
             |+-------- Short operation: 1 for ERASE, WDS, ERAL and WEN command, 0 otherwise
             +--------- 1 to enable internal EEPROM write protection.
             +--------- Protection: 1 to enable internal EEPROM write protection.
                      Cannot be cleared once set.  
                                  Cannot be cleared once set.  
</pre>
</pre>


The ''mode'' flags control the behaviour of the EEPROM interface:
* Read operation: Sends 16 bits from Command, then reads 16 bits to Data.
* Write operation: Sends 16 bits from Command, then 16 bits from Data. De-asserts Microwire chip select, then re-asserts it and waits for the EEPROM to confirm command completion.
* Short operation: Sends 16 bits from Command, de-asserts Microwire chip select.
* Protection: Enables internal EEPROM write protection (addresses >= 0x30, or anything after the first 96 bytes, can no longer be written to).


* Read mode: Sends 16 bits from Command, then reads 16 bits to Data.
If more than one of the Read, Write, Short, Protect bits are set, the operation is treated as invalid (all four operation bits are cleared and no communication is done with the EEPROM). Notably, this means that writing, for example, 0x90 does not protect the internal EEPROM if it wasn't already protected, but writing 0x80 does.
* Write mode: Sends 16 bits from Command, then 16 bits from Data. De-asserts Microwire chip select, then re-asserts it and waits for the EEPROM to confirm command completion.
* Short mode: Sends 16 bits from Command, de-asserts Microwire chip select.


Also note that nothing inside the SoC or 2001 checks that the contents of the command register matches the bit set in this register.
The command requested here should match the command sent to the EEPROM in port ''$BC''.


{{Anchor|Internal EEPROM Status}}
{{Anchor|Internal EEPROM Status}}
=== Internal EEPROM Status ($BE, $BF read) ===
=== Internal EEPROM Status ($BE, $BF read) ===


Line 132: Line 154:
15  bit  8  7  bit  0  
15  bit  8  7  bit  0  
  ---- ----  ---- ----
  ---- ----  ---- ----
  .... ....  p... ..RD
  .... ....  P... ..rd
             |      ||
             |      ||
             |      |+- 1 if a READ command has completed.
             |      |+- 0 after a Read command is initiated,
            |      |  1 once a Read command is completed.
            |      |  Unaffected by Write/Erase commands.
             |      +-- 0 if the EEPROM is busy,
             |      +-- 0 if the EEPROM is busy,
             |          1 if a command can be accepted (idle).
             |          1 if a command can be accepted (idle).
Line 168: Line 192:
1 - A<br/>
1 - A<br/>
2 - B<br/>
2 - B<br/>
3 - AB<br/>
3 - 0<br/>
4 - 0
4 - AB
|-
|-
| $76 || 1 | Last booted cartridge developer/publisher ID
| $76 || 1 || Last booted [[ROM header]] byte 6 (developer/publisher ID)
|-
|-
| $77 || 1 | Last booted cartridge game ID
| $77 || 1 || Last booted [[ROM header]] byte 7 (color)
|-
|-
| $78 || 1 | Last booted cartridge game version
| $78 || 1 || Last booted [[ROM header]] byte 8 (game ID)
|-
|-
| $7C || 1 | Stored cartridge ID/version change counter
| $7C || 1 || Stored cartridge ID/version change counter
|-
|-
| $7D || 1 | Owner name change counter
| $7D || 1 || Owner name change counter
|-
|-
| $7E || 2 | System startup counter
| $7E || 2 || System startup counter
|-
|-
| $83 || 1 | Color console configuration
| $80 || 1 || Last booted [[ROM header]] byte 6 (developer/publisher ID) - only changed if byte 7 (color) != 0
|-
|-
| $84 || ? | [[Splash animation|Custom splash animation]], if present
| $81 || 1 || Last booted [[ROM header]] byte 7 (color) - only changed if byte 7 (color) != 0
|-
| $82 || 1 || Last booted [[ROM header]] byte 8 (game ID) - only changed if byte 7 (color) != 0
|-
| $83 || 1 || Color console configuration
|-
| $84 || ? || [[Splash animation|Custom splash animation]], if present
|}
|}


Line 249: Line 279:


While the M93LCx6 family supports byte organization, the WonderSwan always uses word organization. As such, this implementation detail is omitted in this documentation.
While the M93LCx6 family supports byte organization, the WonderSwan always uses word organization. As such, this implementation detail is omitted in this documentation.
The SPHINX SoC family emulates a 93C46 in ASWAN compatibility mode by manipulating the shifted out command value when sending it to the EEPROM (TODO: How exactly?).


== Errata ==
== Errata ==
Line 256: Line 288:
On the ASWAN SoC, accessing the internal EEPROM command ports as bytes only works correctly for even addresses. For odd addresses, these accesses return open bus; this means that unaligned word accesses also don't work, as they are converted to one odd and one even byte access internally.
On the ASWAN SoC, accessing the internal EEPROM command ports as bytes only works correctly for even addresses. For odd addresses, these accesses return open bus; this means that unaligned word accesses also don't work, as they are converted to one odd and one even byte access internally.


As such, it is recommended to only use word port accesses to talk to the internal EEPROM.
It is recommended to only use aligned word port accesses to talk to the internal EEPROM.


This issue is not present on the SPHINX and newer SoCs, including in "mono" emulation mode, as well as the cartridge bus (which is always forced to be accessed per byte).
This issue is not present on the SPHINX and newer SoCs, including in "mono" emulation mode, as well as the cartridge bus (which is always forced to be accessed per byte).

Latest revision as of 09:27, 5 August 2024

The WonderSwan utilizes M93LCx6-compatible EEPROMs:

  • in the SoC:
    • 1 Kbit internal EEPROM (M93LC46-compatible) on the WonderSwan,
    • 16 Kbit internal EEPROM (M93LC86-compatible) on the WonderSwan Color,
  • on cartridges:
    • 1 Kbit cartridge EEPROM (M93LC46-compatible)
    • 8 Kbit cartridge EEPROM (M93LC76-compatible)
    • 16 Kbit cartridge EEPROM (M93LC86-compatible)

Additional variants exists which were not seen on any production cartridge:

  • 256 bit EEPROM (M93LC06-compatible)
  • 2 Kbit EEPROM (M93LC56-compatible)
  • 4 Kbit EEPROM (M93LC66-compatible)

Commands

READ - Read Word

The READ command takes an address of a word (address 0 => bytes 0, 1; address 1 => bytes 2, 3; ...) and returns the word at that address.

WRITE - Write Word

The WRITE command takes an address of a word (address 0 => bytes 0, 1; address 1 => bytes 2, 3; ...) and the word to write to it, then writes the word.

ERASE - Erase Word

The ERASE command takes an address of a word (address 0 => bytes 0, 1; address 1 => bytes 2, 3; ...) and erases the word at that address, setting it to 0xFFFF.

WDS - Write Disable

The WDS command prevents issued write and erase commands from having an effect on the EEPROM.

WRAL - Write All

This command is not guaranteed to be present on all EEPROMs.

TODO

ERAL - Erase All

This command is not guaranteed to be present on all EEPROMs.

TODO

WEN - Write Enable

The WEN command restores the effect of issued write and erase commands on the EEPROM disabled using WDS.

I/O ports

The I/O ports listed refer to the internal EEPROM; for the cartridge EEPROM port numbers, refer to the mapper documentation.

It is recommended to only access the data and command ports with aligned word reads/writes; see the Errata section for more information.

Internal EEPROM Data ($BA, $BB read)

15  bit  8  7  bit  0
 ---- ----  ---- ----
 dddd dddd  dddd dddd
 |||| ||||  |||| ||||
 ++++-++++--++++-++++- Data read from the EEPROM.

The read buffer's value changes only once the Read command is completed.

Internal EEPROM Data ($BA, $BB write)

15  bit  8  7  bit  0
 ---- ----  ---- ----
 dddd dddd  dddd dddd
 |||| ||||  |||| ||||
 ++++-++++--++++-++++- Data to write to the EEPROM.

The write buffer is latched when a Write command is initiated; further writes to it do not affect the value written by that specific command.

The two EEPROM data buffers are not shared; neither writes to the write buffer nor the execution of non-read commands affect the contents of the read buffer.

Internal EEPROM Command ($BC, $BD)

  Command Pattern 1

15  bit  8  7  bit  0 
 ---- ----  ---- ----
 0000 0001  ooaa aaaa  (¼, 1 Kbit - M93LC06/46)
 0000 01oo  aaaa aaaa  (2, 4 Kbit - M93LC56/66)
 0001 ooaa  aaaa aaaa (8, 16 Kbit - M93LC76/86)
      ||||  |||| ||||
      ||++--++++-++++- Address (MSb .. LSb)
      ++-------------- Opcode:
                         01 - WRITE
                         10 - READ
                         11 - ERASE
  Command Pattern 2

15  bit  8  7  bit  0 
 ---- ----  ---- ----
 0000 0001  00ss ....  (¼, 1 Kbit - M93LC06/46)
 0000 0100  ss.. ....  (2, 4 Kbit - M93LC56/66)
 0001 00ss  .... .... (8, 16 Kbit - M93LC76/86)
      ||||
      ||++------------ Sub-Opcode:
      ||                 00 - WDS
      ||                 01 - WRAL
      ||                 10 - ERAL
      ||                 11 - WEN
      ++-------------- Opcode:
                         00

The value written to this port can be read back; it is not affected by EEPROM Control.

Internal EEPROM Control ($BE, $BF write)

15  bit  8  7  bit  0 
 ---- ----  ---- ----
 .... ....  PSWR ....
            ||||
            |||+------ Read operation:  1 for READ command, 0 otherwise
            ||+------- Write operation: 1 for WRITE and WRAL command, 0 otherwise
            |+-------- Short operation: 1 for ERASE, WDS, ERAL and WEN command, 0 otherwise
            +--------- Protection: 1 to enable internal EEPROM write protection.
                                   Cannot be cleared once set. 
  • Read operation: Sends 16 bits from Command, then reads 16 bits to Data.
  • Write operation: Sends 16 bits from Command, then 16 bits from Data. De-asserts Microwire chip select, then re-asserts it and waits for the EEPROM to confirm command completion.
  • Short operation: Sends 16 bits from Command, de-asserts Microwire chip select.
  • Protection: Enables internal EEPROM write protection (addresses >= 0x30, or anything after the first 96 bytes, can no longer be written to).

If more than one of the Read, Write, Short, Protect bits are set, the operation is treated as invalid (all four operation bits are cleared and no communication is done with the EEPROM). Notably, this means that writing, for example, 0x90 does not protect the internal EEPROM if it wasn't already protected, but writing 0x80 does.

The command requested here should match the command sent to the EEPROM in port $BC.

Internal EEPROM Status ($BE, $BF read)

15  bit  8  7  bit  0 
 ---- ----  ---- ----
 .... ....  P... ..rd
            |      ||
            |      |+- 0 after a Read command is initiated,
            |      |   1 once a Read command is completed.
            |      |   Unaffected by Write/Erase commands.
            |      +-- 0 if the EEPROM is busy,
            |          1 if a command can be accepted (idle).
            +--------- Internal EEPROM write protection:
                       0 = disabled, 1 = enabled

Internal EEPROM Layout

Offset Length Contents
$00 96 Program data. Can be written by programs even if write protection has been enabled.
$60 16 Owner name, custom character set.
$70 1 Owner birthday year, BCD, first/higher two digits
$71 1 Owner birthday year, BCD, last/lower two digits
$72 1 Owner birthday month, BCD
$73 1 Owner birthday day, BCD
$74 1 Owner gender:

0 - ?
1 - Male
2 - Female

$75 1 Owner blood type:

0 - ?
1 - A
2 - B
3 - 0
4 - AB

$76 1 Last booted ROM header byte 6 (developer/publisher ID)
$77 1 Last booted ROM header byte 7 (color)
$78 1 Last booted ROM header byte 8 (game ID)
$7C 1 Stored cartridge ID/version change counter
$7D 1 Owner name change counter
$7E 2 System startup counter
$80 1 Last booted ROM header byte 6 (developer/publisher ID) - only changed if byte 7 (color) != 0
$81 1 Last booted ROM header byte 7 (color) - only changed if byte 7 (color) != 0
$82 1 Last booted ROM header byte 8 (game ID) - only changed if byte 7 (color) != 0
$83 1 Color console configuration
$84 ? Custom splash animation, if present

Owner name character set

.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
0. 0 1 2 3 4 5 6 7 8 9 A B C D E
1. F G H I J K L M N O P Q R S T U
2. V W X Y Z + - ? .

Color console configuration

7  bit  0
---- ----
sc.. ..vv
||     ||
||     ++- Volume level
|+-------- Contrast (WSC): 0 = Low, 1 = High
+--------- Custom splash animation enabled

Hardware notes

EEPROM command bits are shifted out starting from the most significant bit of the port.

    +----> EEPROM Serial Data
    |
   [0] <= [0000 0001 ooaa aaaa]
           EEPROM Command Port

While the M93LCx6 family supports byte organization, the WonderSwan always uses word organization. As such, this implementation detail is omitted in this documentation.

The SPHINX SoC family emulates a 93C46 in ASWAN compatibility mode by manipulating the shifted out command value when sending it to the EEPROM (TODO: How exactly?).

Errata

Non-word access on ASWAN

On the ASWAN SoC, accessing the internal EEPROM command ports as bytes only works correctly for even addresses. For odd addresses, these accesses return open bus; this means that unaligned word accesses also don't work, as they are converted to one odd and one even byte access internally.

It is recommended to only use aligned word port accesses to talk to the internal EEPROM.

This issue is not present on the SPHINX and newer SoCs, including in "mono" emulation mode, as well as the cartridge bus (which is always forced to be accessed per byte).

Links