The Am29F010-90PC product has been used to test the software and hardware design described here. Device Compatibility ==================== For use with an Acorn Electron ROM cartridge or other board providing a ROM socket, the compatibility of the Am29F010 needs to be assessed in the context of the ROM sockets likely to be provided. Original ROM Pinout Am29F010 Pinout ------------------- --------------- 1 \/ 32 VCC A16 2 31 WE# 1 \/ 28 VCC A15 3 30 A12 2 27 A14 A12 4 29 A14 A7 3 26 A13 A7 5 28 A13 A6 4 25 A8 A6 6 27 A8 A5 5 24 A9 A5 7 26 A9 A4 6 23 A11 A4 8 25 A11 A3 7 22 OE# A3 9 24 OE# A2 8 21 A10 A2 10 23 A10 A1 9 20 CS# A1 11 22 CE# A0 10 19 D7 A0 12 21 DQ7 D0 11 18 D6 DQ0 13 20 DQ6 D1 12 17 D5 DQ1 14 19 DQ5 D2 13 16 D4 DQ2 15 18 DQ4 GND 14 15 D3 GND/VSS 16 17 DQ3 Superimposing the Am29F010 onto a ROM socket would provide compatibility for all pins from A12 to GND/VSS and from A14 to D3/DQ3. Pin 1 in a ROM socket would correspond to A15 but is not necessarily connected, nor, perhaps, is A14 since only 14 bits are required to address 16 kilobytes, although there may be 32 kilobyte sockets connecting A14 and using 15 bits to address 32K. A16 and A15 would probably be connected to ground to ensure correct operation, but could also be wired to a selection mechanism so that the entire contents of the flash memory might be exposed. Pin 28 is a ROM socket would provide power, but the corresponding pin 30 on an Am29F010 is not connected. Thus pin 30 would need routing to pin 32 for the flash device socket. Pin 31 for the Am29F010 would need to be asserted. Thus pin 30 might also be routed to pin 31, so that the device would remain read-only at all times. Dual ROM Adapter Usage ====================== A single Am29F010 device could be wired to two ROM sockets in order to provide data to both. The above wiring guide would be employed, with connections from both sockets being connected to the Am29F010, but additional logic would be required for the CS# signals originating from the sockets in order to expose the appropriate region of flash memory. ROM #1 would be served by a "lower" 16K region; ROM #2 would be served by an "upper" 16K region; A14 would be used to switch between these regions. When ROM #1's CS# signal is low, an attempt to read from ROM #1 would be occurring, and thus A14 would be held low. And when ROM #2's CS# signal is low, an attempt to read from ROM #2 would be occurring, and thus A14 would be held high. Meanwhile, the CS# signal for the two ROM sockets would need to be combined to produce a resultant CE# signal for the Am29F010. ROM #1 CS# ROM #2 CS# Am29F010 A14 Am29F010 CE# ---------- ---------- ------------ ------------ 0 0 Not defined Not defined 0 1 0 0 1 0 1 0 1 1 Not defined 1 It might therefore be possible to connect A14 to ROM #1's CS# signal. And the resultant CE# signal could be the product of an AND gate: Am29F010 CE# = ROM #1 CS# AND ROM #2 CS# ROM #1 ROM #2 74HC08 Am29F010 ------ ------ ------ -------- CS# 1A A14 CS# 1B 1Y CE# Pins ==== A0-A16 17-bit addressing DQ0-DQ7 8-bit data transfer CE# chip enable OE# output enable WE# write enable VCC 5V VSS ground NC (not connected) Low-Level Operations ==================== CE# high standby CE# low read, write or output disable OE# high, WE# high output disable OE# low, WE# high read OE# high, WE# low write Thus, for reading and writing: OE# = not WE# Timing ====== Addresses are latched on the falling edge of the latest of WE# and CE# Data is latched on the rising edge of the latest of WE# and CE# Strategy: 1. Start with CE#, OE#, WE# high (standby, output disable) 2. Bring CE# low (output disable) 3. Set addresses 4. Bring WE# or OE# low for operation (write or read) 5. Read or write data 6. Bring WE# or OE# high (output disable) Operation Modes =============== By default, the device is in read mode, meaning that merely bringing OE# low will produce data for the asserted address. To issue commands to change the mode involves write operations with specific address and data arguments. Sectors ======= A[16...14] selects each 16KB sector and is referred to as the sector address or SA in the documentation. Commands ======== Reset (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$F0) Autoselect (manufacturer) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); (A=$X00; read) => D=$01 Autoselect (device) (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$90); (A=$X01; read) => D=$20 Simple reset (A=$XXXX; D=$F0) Sector erase (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$80); (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=SA; D=$30) Program (A=$5555; D=$AA); (A=$2AAA; D=$55); (A=$5555; D=$A0); (A=PA; D=PD) Progress -------- Programming and erasure commands employ data pins as follows: Programming Erasure DQ7 On completion: DQ7-out On completion: 1 DQ6 During: toggling value During: toggling value DQ5 On failure: 1 On failure: 1 DQ3 Sector erase begun: 1 A read operation is required to obtain these outputs, typically with the same address used to initiate each operation. Arduino Interfacing =================== Arduino can employ at most 14 digital pins, whereas the Am29F010B requires 17 address pins, 8 data pins, plus 3 control pins to be utilised. One solution is to map the 3 control pins directly to the Arduino, then to channel address and data via 8 common pins to latches, and then employ the remaining pins to control the latches. Two pins can be used to select the latches, and when neither latch is selected, the data pins will be used to read or write data from the flash memory. As a result, only 13 pins are needed on the Arduino. 74HC273 Pinout -------------- MR# 1 \/ 20 VCC Q0 2 19 Q7 D0 3 18 D7 D1 4 17 D6 Q1 5 16 Q6 Q2 6 15 Q5 D2 7 14 D5 D3 8 13 D4 Q3 9 12 Q4 GND 10 11 CP Arduino 74HC273 #1 74HC273 #2 Am29F010 ------- ---------- ---------- -------- A5 CE# A4 OE# A3 WE# 2 CP 3 CP 4 D0 D0 DQ0 5 D1 D1 DQ1 6 D2 D2 DQ2 7 D3 D3 DQ3 8 D4 D4 DQ4 9 D5 D5 DQ5 10 D6 D6 DQ6 11 D7 D7 DQ7 Q0 A0 Q1 A1 Q2 A2 Q3 A3 Q4 A4 Q5 A5 Q6 A6 Q7 A7 Q0 A8 Q1 A9 Q2 A10 Q3 A11 Q4 A12 Q5 A13 Q6 A14 Q7 A15 GND A16 (not used) 5V MR# MR# 5V VCC VCC VCC GND GND GND VSS Set Address ----------- 74HC273 #1 CP = 1; 74HC273 #2 CP = 0 74HC273 #1 D[7...0] = A[7...0] 74HC273 #1 CP = 0; 74HC273 #2 CP = 1 74HC273 #2 D[7...0] = A[15...8] Write Data ---------- Configure pins as D[7...0] WE# = 0 74HC273 #1 CP = 0; 74HC273 #2 CP = 0 74HC273 #3 D[7...0] = D[7...0] WE# = 1 Read Data --------- Configure pins as Q[7...0] OE# = 0 74HC273 #1 CP = 1; 74HC273 #2 CP = 0 Q[7...0] = 74HC273 #0 Q[7...0] OE# = 1