I now have a 6502 that is reading the OpCode NOP (EA), causing the program counter to increment the address on the address bus by one, for every two clock cycles. This is effectively a hard-wired program! This is a good proof of concept but what I now want to be able to do is to run different programs. To do this I will need somewhere to store those programs.
ROM (Read Only Memory) is a form of permanent storage. A program can be placed in ROM and will remain there, even if power is removed. There are many types of ROM but the type that I am interested in using here is EEPROM (Electrically Erasable Programmable Read Only Memory). EEPROMs can be reprogrammed by applying specific voltages to them.
The EEPROM that I will be using is a 28256. The 28256 is a flash ROM, with a capacity of 256K (32K x 8).
Like the 6502, the 28256 has a data and address bus. This means that the two can talk to each other by connecting them together. However, there is a difference in the size of the address buses! The 6502 has a 16-bit address bus and the 28256 has a 15-bit address bus! This means that the 6502 can see from 0000000000000000 – 1111111111111111, which is FFFF in hex and the 28256 can see from 000000000000000 – 111111111111111, which is 7FFF in hex. Therefore, if the 6502 tries to access addresses on the 28256 that are higher than 7FFF, it won’t work!
This causes a problem because there will be one pin of the address bus of the 6502 that can not be connected to the address bus of the 28256! There are a few ways to solve this. The solution that I will use is to use the fact that the most significant bit (A15) of the 6502 will be high when at addresses that the 28256 cannot reach. If I connect A15 from the 6502 to the chip select pin on the 28256 (which is active low), when A15 is high, the 28256 will be off.
This solves one problem but creates another! When the 6502 is turned on and has been through its startup sequence, it looks at locations FFFC and FFFD for a program to execute. Any program that I have on the ROM would not be read, since the ROM cannot see anything in that range. One solution is to invert the bit from the A15 connection from the 6502 to the chip select on the 28256. This then alters the addresses that the 28256 can see to the range of 8000 – FFFF.
I can use an inverter to reverse the bit coming from the A15 of the 6502. I have removed the 8 resistors that I used to make the 6502 read NOPs. The circuit now looks like this:
Previously I mentioned that the 6502 that I’m using can work up to 14MHz (and maybe higher) but factors (such as other components) can limit the theoretical speed. The ROM is one of these components! Looking at the datasheet I can see that the read access time is 150ns. This means that the clock speed cannot be faster than 7MHz. Some of you may think that 150ns works out to close to 14MHz but this is not the case with a 6502! This is because the 6502 accesses memory on half of a clock cycle! In theory, I would need a ROM with at least a 70ns read access time. However, it would be interesting to see how much the ROM speed can be pushed. As well as trying to overclock the 6502, another fun addition would be to try and overclock the 28256.
My computer now has additional memory, in the form of ROM, to store programs that I write. It would be good to test that everything is working by writing a program. A good program would be to replicate the NOP in software, instead of hardware. If everything is working correctly, then I should see the same outcome as before – the address is incremented by one, on every two clock cycles.
rom = bytearray([0xea] * 32768)