6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri May 10, 2024 9:39 pm

All times are UTC




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: SPI EEPROM boot for 6502
PostPosted: Wed Aug 09, 2023 1:12 am 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Hi guys, I'm interested in options for booting a 6502 without a parallel EEPROM. I'm also not personally keen on using a microcontroller. SPI EEPROM is really appealing though, because it's ridiculously simple to get data out of, if all you want is a stream of bits.

I searched the forum for examples of booting this way, but couldn't find much - maybe I used the wrong search terms, but I wondered if you guys remembered any particular projects that worked this way for reference?

The main thing I did find was a really interesting technique refined by Dr Jeffyl 5 years ago to boot a 6502 with very few signal lines, which I think was based on streaming data out of SPI EEPROM to generate those signals, or possibly a microcontroller. Very neat, and more links in his post to past posts it was based on: viewtopic.php?f=4&t=5231&hilit=spi+eeprom+spi+boot

There's also a nice effort to use a 22V10 PLD to provide a certain amount of virtual ROM - I think it was six bits of address space, so rather small, and only worked for certain data due to restrictions on product terms per output bit - I've lost the link I'm afraid so can't post it here.

I didn't find a lot else though, and I'm sure others have already taken this further so it would be great to hear of more examples.

For my purposes I'm not interested in addressable SPI ROM - I don't want to connect the address bus, my only interest is for boot-up, so there should be no need to serialise addresses and feed them into the ROM, we can just read the bytes sequentially. I want something that's not directly coupled to the CPU, or a particular address decoding technique. I don't need a lot of space, I think 256 bytes would be plenty to chain to loading a sector from SD card, which is 512 bytes and can easily take over from there.

Small size SPI EEPROMs seem very easy to use - based on the datasheets I think they can be read simply by feeding them a clock signal, activating chip select and bringing their data-in line high for two clocks then low permanently, and then after about 8 ticks you can start reading bits from the device's data-out line and presenting them to the CPU. I think you could even connect the clock to a 4-bit counter and drive the data-in line from one of the divided clock outputs, which would be high for two ticks then low for two ticks, then repeat that pattern - the EEPROM would start from a funny address, but should otherwise not care about the unwanted signal on its data-in line.

The EEPROM is essentially a bit-stream - byte boundaries don't really mean very much. You could tick the clock 8 times whenever the CPU tries to read from the device, to pull 8 bits, or just keep the clock running all the time and put dummy data in the EEPROM, but only write to the data bus when the CPU is performing a read operation; or just make sure the data you're putting on the data bus is the same data that the CPU will be putting on it. This way it would be fairly simple I think to have this device selected after reset, and serve all addresses above $8000 say, and it can provide the reset address of $8000 followed by a stream of instructions to load registers and save them to various RAM addresses, then jump to RAM. Perhaps the act of jumping to RAM also switches the address decoding into a runtime mode where the SPI EEPROM is no longer addressed.

Another option is to dump the EEPROM contents into RAM during reset, i.e. hold /RESET low while counters count up through all the RAM, writing bytes from the EEPROM using a shift register. I've done this before from parallel EEPROM and it was very effective - however it requires counters, which is a lot more ICs. Having the CPU drive the address bus instead is appealing, and allowing the reset circuit to "bus master" requires adding a lot of exceptions to existing circuits that could be a thorn in their side later on, not worth it just for the sake of handling the reset.

It strikes me that a simple PLD could be enough to gather the bits from the EEPROM and output them to the CPU, with tri-state operation so it can stay off the bus after that point; the PLD might also have resources to manage the data-in line appropriately. CPLDs can do much more, but I'm still interested in sticking to PDIP parts at the moment.

I guess it would be necessary to clock-stretch or arrange for the CPU clock to be 8x slower than the SPI clock, at least during boot-up. Perhaps this actually brings us back to Dr Jeffyl's solution which requires special control of the clock when booting. My "fast" PDIP system could probably do this through clock stretching though rather than having to provide the clock from the bootloader module, which would require something like a multiplexer on the clock line and that's the sort of thing I feel isn't worth compromising for the sake of a non-parallel boot-up.

Anyway this is getting deep into the weeds, there could be better ways that I'm not thinking of, so I'm interested to hear any thoughts or links.


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 2:11 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
I did something similar in Tiny68K where 68000 relinquishes its bus to CPLD and 24C256's 32K contents are loaded into DRAM using state machine in CPLD. The state machine is relatively simple, but it does need to generate 15 addresses to DMA data from CPLD's serial-to-parallel register into DRAM. If I going to do this with 6502, I would not use the the DMA/address generator scheme but feed 6502 the 8-bit data from serial-to-parallel register as stream of 6502 instructions. The scheme is very similar to Prog65 where 6502 executes the incoming parallel data from FT245 as instruction. In serial EPROM boot scenario, there is a serial-to-parallel converter and associated RDY line to signal parallel data ready. In similar fashion Z280RC has a state machine that initialize CF disk to read the master boot record and Z280 executes the parallel data streaming in from CF disk.

I use CPLD because I have many hundreds of them; CPLD can have small internal ROM, so I ultimately gravitated toward a small bootstrap ROM in CPLD and load applications from either serial port or CF disk. It is the simplest approach and also easiest to explain.
Bill


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 6:47 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
I put some signposts in this also-related thread:
viewtopic.php?p=65230#p65230

It'd be excellent to see Jeff's idea running in practice, with all the necessary bootloader levels implemented!


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 7:09 am 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
Curiousity question, please? Are you thinking about eliminating the ROM in favor of a 64K RAM system design?

Have you thought about a ROM Emulator where the ROM on the SBC is substituted with RAM from the Emulator?


Attachments:
EPROM EMU Notes #2.png
EPROM EMU Notes #2.png [ 35.42 KiB | Viewed 4592 times ]
Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 8:42 am 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Thanks guys, great references!

Michael, no I hadn't but its interesting. Partly though I'm trying to get away from having to wire or route a wide address bus beyond the RAM. So something like your suggestion could be good for rapid development of the boot code but I'd probably not make it emulate parallel ROM, I'd probably make it just provide the right bytes in sequence like the SPI EEPROMs do.


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 10:22 am 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
Ok. Since you've pretty much dis'ed using a microcontroller, how about using an 8K 74AHCTXL18426 "boot loader" IC in a DIP-14 package (~$1.50)?


Attachments:
Beater v1g1.png
Beater v1g1.png [ 415.4 KiB | Viewed 4567 times ]
Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 10:30 am 
Offline
User avatar

Joined: Sat Jul 24, 2021 1:37 pm
Posts: 282
This has a lot of info: http://mups16.net/detour-coping-rom-to- ... artup.html
He's doing ROM to RAM copy so needs to build addresses, but you can simplify his circuit quite a bit for your use case

_________________
BB816 Computer YouTube series


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 1:22 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Michael wrote:
Ok. Since you've pretty much dis'ed using a microcontroller, how about using an 8K 74AHCTXL18426 "boot loader" IC in a DIP-14 package (~$1.50)?

I'm afraid I don't know what you mean - yes I'm not keen on using a microcontroller for this, and I'm not sure what 74AHCTXL18426 is, did you mean PIC16F18426, or is it the same thing?


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 4:29 pm 
Offline
User avatar

Joined: Mon Mar 06, 2023 9:26 am
Posts: 88
Location: UK
My immediate response is to say "load page FF from the EEPROM and then back off and let the CPU go from there", but that requires generating addresses and tri-stating address lines.

_________________
probably the youngest person on this forum


Top
 Profile  
Reply with quote  
PostPosted: Wed Aug 09, 2023 9:09 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
gfoot wrote:
Michael wrote:
Ok. Since you've pretty much dis'ed using a microcontroller, how about using an 8K 74AHCTXL18426 "boot loader" IC in a DIP-14 package (~$1.50)?

I'm afraid I don't know what you mean - yes I'm not keen on using a microcontroller for this, and I'm not sure what 74AHCTXL18426 is, did you mean PIC16F18426, or is it the same thing?

Yeah, it's a PIC microcontroller and it simply takes advantage of a simple novel interface method to appear to the 6502 as a 'smart' phantom ROM of sorts. Using it to copy an image of your boot loader into memory at startup is one of many ways you might use it. I use it to copy a full 64K image from a slow ROM at a nice leisurely 1-MHz rate into RAM on a 64K RAM system before switching to a fast clock.

Good luck on your project...


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 10, 2023 2:50 pm 
Offline
User avatar

Joined: Tue Oct 25, 2016 8:56 pm
Posts: 360
This is a very interesting idea and one I have vaguely contemplated in the past. SPI EEPROMs are smaller, more readily available, cheaper and more easily programmed than parallel EEPROMs (in the modern context, at least). I also like that you can get them in a variety of reasonable sizes, so you're not "wasting" a whole 8K or 32K EEPROM for a bootloader that would fit in 1K, or less.

The downside, obviously, is how do you get the data out of them and into the processor or RAM without at least some parallel EEPROM for the SPI routine...

I shall cogitate further and hopefully come back with some useful contributions.

_________________
Want to design a PCB for your project? I strongly recommend KiCad. Its free, its multiplatform, and its easy to learn!
Also, I maintain KiCad libraries of Retro Computing and Arduino components you might find useful.


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 10, 2023 5:26 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
I cobbled a few gates together in simulation to generate the necessary sequence of 0x03, 0x00, 0x00 and also to drive a counter and transfer the contents of the SPI eeprom to ram, but decided it was going to be so much bigger than the eeprom it would replace it wasn't worth the candle.

There is as far as I know a single eeprom with both SPI and parallel interfaces, and it costs a bloody fortune (several hundred dollars last time I looked). Ideal to load code serially and read it direct from the processor, but I think built for the space program and with space program prices.

But the example above suggests an approach - fiddly, because it requires making sure data is always where required but I think possible: load the eeprom with code along the lines of:

Code:
   lda #xx
   sta 0xf000
   lda #xx
   sta 0xf001


So each byte of program code would require at least five bytes of overhead per byte of payload (I haven't looked in detail; it will probably need multiple 'wait' states to ensure that things line up) but the general idea is that it spits out the serialised instruction; that is paralleled and pushed onto the databus and effectively the processor is running the mystery code in the eeprom to store it to ram. When finished, hit a reset and read only from RAM.

Er, I think. I need to contemplate a little longer, I think.

Neil

Alternatives, such as just storing the code desired, require more complex control of the processor. Maybe force an 0xEA onto the processor bus so it keeps incrementing, load the whole 64k in one hit (so you get the reset vectors transferred). More glue logic, though.


Top
 Profile  
Reply with quote  
PostPosted: Thu Aug 10, 2023 9:53 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Even if it's physically bigger, I don't mind too much as the benefit of not having to route all the address lines to it feels like a big win.

AlarmSiren, regarding accessing them without needing software already loaded in parallel RAM/ROM, as barnacle said the protocol is very simple and if all you want to do is read the bytes (well, bits) out one by one, it is fairly easy to kick the process off with just a few parts. I posted an untested schematic here for one brand of EEPROM: viewtopic.php?f=4&t=5231#p102031 and Dr Jeffyl had posted another here for a different brand with slightly different command sequence: viewtopic.php?p=76975#p76975

Unless you're doing something crazy like in the first link I posted there, you still need to somehow generate data for the whole data bus. One way is using a serial-to-parallel shift register, another is to just use 8 EEPROMs, one per bit. They can all be driven by the same clock and data-in signals, and when they are deselected their outputs go tristate - so provided the EEPROMs are as fast as your CPU clock, this ought to work - again with the caveat that all we can do is output a predetermined sequence of data bytes, we can't loop or branch based on user input or anything non-deterministic like that.

There will also be times when we don't really want them driving the bus, e.g. during write operations (to RAM) - we could mirror the data we're expecting the CPU to output but it may be better to just not drive the bus in those cases. Dr Jeffyl's approach to that in the first link above is (more or less) to just put resistors between the EEPROMs and the data bus.

Rereading this, I guess if I could get a sequential-access parallel output EEPROM I'd be happy with that too!


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 11, 2023 7:06 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
A thought, if you can stand having another (more capable!) micro on the board (and surface mount/3v3 only, I fear) is something like one of the STM32l0x range or one of its friends, in a 44 pin package.

My thought there is that the STM provides clock, processor reset, memory override, and also holds the boot image in its flash. It also has an eight-bt parallel output to the data bus.

On reset, the STM jams zeros on the bus and allows the 6502 to start. It resets to 0x0000. The STM then provides ph0 and behaves as above, providing active code as a series of lda #, sta xxxx instructions. During the write phase, the 6502 controls the address and data bus. After finishing the load, the STM relinquishes the busses and restarts the 6502, providing system clock.

There are many advantages:
  • The STM can be programmed on a 3-wire connector (though I usually use six to match the ST-Lite programmer that you get along with a nucleo)
  • There is plenty of space in the STM flash so the entire 6502 memory space could be programmed, if desired. There is no need to interleave the control instructions in the code block; the STM can provide them as part of its output routine
  • No need for an extra reset circuit for the 6502; the STM will handle that
  • After transferring control to the 6502, the STM can provide other facilities. I'm looking at using the SPI interface (with the STM as slave) to provide a UART (STMs have lots of UARTs) interface with a reasonable amount of buffering and an interrupt back to the 6502. But using the same interface, you might consider using the unused IO pins for parallel IO, timer inputs/outputs, ADC inputs, or any of the other facilities the chip provides. You might also use a second SPI port to talk to a memory card and run a file-system on the STM. You can use the STM to talk to a PS/2 keyboard, or if you have the right STM, as a USB host that can handle keyboard, mouse, and bridge.

Sigh... so many ideas, so little time...
Neil


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 11, 2023 7:15 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
My thought on the timing is:
Code:
1   $A9    (lda #)
2   $xx    (byte to be transferred)
3   $8D    (sta llhh)
4   $ll    (low address)
5   $hh    (high address)
6   zz     (high impedance data line while 6502 writes)
7   rinse and repeat...


Neil


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: