Please note that I have disabled comments on this post purely due to a persistent spammer - Dave 23/04/2021.
Its all very well having an EEPROM chip to store our program for the Z80, but somehow we need to get the code onto it. Enter, the EEPROM programmer. So far I have wired up the EEPROM to the Arduino Mega and I can read from it successfully. Writing to it is easy enough, but just now I can't bulk load a file to it. When I do, go find Part 2 :)Here's a diagram I made using this great tool called Fritizing:
As you can see I've used a 74LS04 Hex Inverter to make sure the 3 control lines are HIGH by default as the pins on the Arduino are LOW by default and as the control pins are 'Active Low' we don't want data overwritten accidentally. It also means that setting the pin to HIGH in the Arduino code means the pin is Active.
Here's the EEPROM Reader code for the Arduino Mega:
/* EEPROM Chip Reader */ #define memsize 8192 int STS = 13; // Status Indicator int AP[16] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52}; int AD[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int DP[8] = {23,25,27,29,31,33,35,37}; int DD[8] = {0,0,0,0,0,0,0,0}; int CE = 4; int OE = 3; int WE = 2; int i; int j; int D; int A; void setup() { // Setup Control Pins pinMode(CE, OUTPUT); pinMode(WE, OUTPUT); pinMode(OE, OUTPUT); // Disable Chip, and disable read and write. digitalWrite(CE, LOW); digitalWrite(WE, LOW); digitalWrite(OE, LOW); Serial.begin(115200); Serial.println("Reading EEPROM..."); pinMode(STS, OUTPUT); digitalWrite(STS,HIGH); // Setup Address Pins for (i=0;i<16;i++) { pinMode(AP[i],OUTPUT); } // Setup Data Pins for (i=0;i<8;i++) { pinMode(DP[i],INPUT); } delay(1000); for (A=0;A<memsize;) { if (A<4096) Serial.print("0"); if (A<256) Serial.print("0"); if (A<16) Serial.print("0"); Serial.print(A,HEX); Serial.print(" "); for (j=0;j<16;j++) { // Setup Address Pins for (i=0;i<16;i++) { if((A&bit(i))>0) { AD[i]=HIGH; } else { AD[i]=LOW; } digitalWrite(AP[i],AD[i]); } digitalWrite(CE,HIGH); // Chip Enabled digitalWrite(OE,HIGH); // Read Enabled // Read Data Pins D=0; for (i=0;i<8;i++) { DD[i]=digitalRead(DP[i]); D=D+bit(i)*DD[i]; } digitalWrite(OE,LOW); // Read Disabled digitalWrite(CE,LOW); // Chip Disabled if (D<16) Serial.print("0"); Serial.print(D,HEX); Serial.print(" "); A++; } Serial.println(); } } void loop() { digitalWrite(STS, HIGH); // set the LED on delay(500); // wait for a second digitalWrite(STS, LOW); // set the LED off delay(500); // wait for a second }
I followed your example for the Arduino Mega (2560) (the board I used) on a 8755A Micro-controller and since this IC was not a programmed IC I was able to read the data from it...which should have been all FF's in Hex and it was...Thank you for your example. My next step is to program this IC but I know I need to figure out how to provide Vdd between 5 and 25 volts for the program and verify functions. Your example helped out so much...once I'm able to actually program this device I will be glad to send the setup and for the read and write procedures for this device using the Arduino Mega 2560
ReplyDeleteGlad you found it useful. I need to get back onto this project and finally build a Z80 computer. There are so many things to learn about and experiment with in electronics that I just end up getting distracted. Distractable Dave my wife calls me lol
DeleteI know the feeling...I've been working on building a 8085 SBC for about two years and finally got around to figuring out how to read/write the EEPROM...but I still need to program some other PROMs too so this is just the start for me. I've been working with electronics and programming for 15+ years at least job wise...on and off hobby wise for too long.
ReplyDeleteThanks for posting this Dave, I was trying to use a standard Arduino, but came up against the lack of data pins. Using your code and circuit it worked first time.
ReplyDeleteThanks for saving me the cost of a dedicated programmer. :)
Hi Dave, thanks for a great Z80 resource.
ReplyDeleteI feel I know the answer but is there anyway I can use my uno for this?
Thanks
Ashley
Hi Ashley, the UNO is slightly limited by the number of outputs. Possible options are:
Delete(a) to use the same output for both data and addresses and use external latches/buffers to hold the data and address values (although maximum address value is still limited by the number of output on the UNO) and you'd need at least 1 more output to switch between the external devices,
or (b) have 8 data outputs and another output to send a pulse to external counter ICs e.g. link 4x 74193 to make a 16 line addresses incrementing by one for each pulse.
Hope that helps.
I realised as I posted this , I am talking about writing to an EEPROM and this post was about reading, so the only difference is the that address needed to be written and the data read so in the case of option (a) this would mean switching the mode of the pins between output for address and input for read. In option (b) the data pins would be inputs and the 'clock' pulse an ouptut.
DeleteThanks for the quick reply Dave, I did a little more research and found the EEPROMMER, I cannot say how it works but I think I might be able to achieve the same with my uno.
DeleteThanks
Ashley
Hi again Dave, sorry I meant to write MEEPROMMER. I have since had time to look at and understand the elegant solution by Mario Keller and it appears to be as you suggested (b) an 8 bit shift register is used for addressing.
DeleteThanks
Ashley
Hi Ash. I just did a blog post about using binary counters that could be used as address lines. See http://z80dave.blogspot.co.uk/2014/02/42-working-with-74193-4-bit-binary.html.
DeleteThanks Dave, that's helpful in understanding the logic.
DeleteAshley
Thanks Dave, I got this working pretty much straight away once I figured I'd wired the NOT gates incorrectly. I changed the program to embed the data in the code for ease. It's also for a Z80 homebrew. I think I'll create a soldered strip board, as I suspect I'll be change the code very often.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteSorry Dave, your schematic seems wrong.
ReplyDeletePlease check pinout of LS04 chip.
Yes you are correct, green wires should be pins 1, 3 and 5 and purple wires 2, 4 and 6. Well done for finding that but I'm sorry but there is no prize for "Spot the deliberate mistake." :D
DeleteThis comment has been removed by the author.
ReplyDeleteHi there
ReplyDeleteI've been reading his useful page a few times now and I have a question, given my ignorance on the subject!
I need to flash an ATMEL AT29C020 and I have an Arduino DUE. The Atmel seems to be very similar to the one you're using here but the datasheet mentions 5V operations while the DUE only works at 3.3V - even though it has a 5V output that can be used.
I'm just wondering whether this project would work with my hardware?
Thanks!
Shit Man .......
ReplyDeleteWhen building it using the diagram it is impossible to work. This is because wrong connectioning the SN72LS04. Outputs and Inputs of the invertergates are used wrong.
you are totally right! I need to see if I still have the Fritzing Project files for that. However there may be a better way to do it as most modern programmable ROMs use I²C or SPI, and require only 3 connections.
ReplyDelete