Storing data to NVRAM

I'm designing an 8 bit computer, and one of the tricky parts is streamlining the loading of the small "OS" (read collection of routines) into the 32kB NVRAM that I will use instead of an EPROM.

I was thinking to use a PIC (interfaced to the PC via USB) to load the NVRAM.

What would be a better way to do this?

-
Can you give us the model number of the NVRAM you're planning to use? Also do you actually have a bit more complicated question? The answer to the one you asked is "Yes, of course, but not me." –  AndrejaKo Oct 1 '11 at 18:59
I got a ST M48Z08-100PC1 that I'm going to try this out with.. –  RA01 Oct 1 '11 at 19:19
Hm... Well since you don't have a specific question, only thing I can say is don't forget the diode, but that's already written in the datasheet. Sorry for not being more helpful. –  AndrejaKo Oct 1 '11 at 19:29
To expand on the question would be if anyone have any practical recommendation for a different solution than using a PIC to load the NVRAM while holding the Halt on the the CPU. –  RA01 Oct 1 '11 at 20:07
I don't think "Anyone tried this before?" is an accepted question for this site. –  Arturo Gurrola Oct 4 '11 at 20:55
show 1 more comment

Since you want to access the memory "behind the CPU's back" while holding it in halt mode, you'll need something else to generate the necessary control and data signals, hopefully while you have a way to tri-state the CPU's bus signals. Conversely, your "something else" will need to tri-state it's lines (except for the halt output) when the CPU is running.

In an earlier era, you would have connected up an 8255 parallel peripheral interface chip to your PC's parallel port, and used that and software to access the NVRAM one byte at at time. Before releasing things to the CPU, you would configure the 8255 to be all inputs (ie, tri-state) and rely on resistors to keep the write signal to the memory from actuating during the handover. You'd have to drive the halt signal from a port that you weren't otherwise using, since you couldn't tri-state it, and the 8255 only lets you control the direction of entire ports except for one port which you can control in two halves.

However, in this era of legacy-free PC's you may not have a parallel port, and so likely instead have to work off of USB. You can use a a simple USB IO chip much as the 8255 would have once been used, using software to generate all the memory cycles. But the USB ports actually have a much higher latency (delay) for a single access than the old printer ports did, so this may prove a very slow way to access your memory.

A better solution in the USB era is to use a small micrcontroller downstream of the USB (or even a USB-serial converter) to generate the memory access cycles, and send it commands such as "read this byte" or "write the following 32 bytes starting at address xx". Use the USB-serial paradigm and make these commands human-readable ASCII and you have something that can be used as a primitive debugger/monitor from a terminal program, or a download tool when driven by a specialized program. You can use a binary interface instead, but USB is so fast at moving bulk data (can emulate serial ports at insane baud rates) that the overhead of ASCII (hex) encoding the payload data is no big deal, and doing so lets you use newline or carriage returns for block synchronization, instead of having to work out a scheme for differentiating framing codes from data bytes.

-

By the sound of it, you want to build an 8-bit microcomputer which will have the code stored in an NVRAM which is external to the processor; the computer will have no non-volatile memory other than the NVRAM, which will be default be uninitialized, and you need a way to boot-strap it.

My recommendation would be to wire the computer so that reading a certain address range will trigger a read cycle from one of FTDI's USB-to-parallel-FIFO interface chips, and provide a means (switch, jumper, or whatever) so that reading the portion of the NVRAM address space holding the reset vector will be redirected to likewise use the FTDI chip. Another address range should allow the 6502 to check whether the FTDI chip is ready (bit 6 set=ready)

Then hold the CPU in reset, feed a short (probably 64 bytes or less) non-looping program into the FTDI chip via the USB port, and release reset. The CPU should fetch from the FTDI chip the instructions that were stuffed into it and execute them. I don't know what CPU you're using, but for the 6502 the code might look something like:

  00 D0  -- Reset vector -- Assumes FTDI chip is mapped at D000-D0FF
A9 2C  -- Load A with #$2C 85 80 -- Store it to$80
A9 00  -- Load A with #$00 85 81 -- Store it to$81
85 86  -- Also to $86 A9 D8 85 82 -- Load A with$D8 and store it to 82
A9 50 85 83 -- Load A with $50 and store it to 83 A9 FB 85 84 -- Load A with$FB and store it to 84
A9 AD 85 85 -- Load A with $AD and store it to 85 A9 D0 85 87 -- Load A with$D0 and store it to 87
A9 48 85 88 -- Load A with $48 and store it to 88 A9 70 85 89 -- Load A with$70 and store it to 89
A2 F5       -- Load X with #$F5 86 8A -- Store X to$8A
AA 00      -- Transfer X to S (second byte is dummy cycle)
4C 80 00   -- Jump to code loaded at $0080  The above code, 49 bytes will store to$0080 the following short program, with the stack pointer initialized to $F5 $0180: 2C 00 D8 : BIT $D800 ; Read status$0183: D8 50    : BVC $0080 ; Branch if not ready$0185: AD 00 D0 : LDA $D000 ; Read data$0188: 48       : PHA
$0189: 70 F5 : BVS$0080 ; Loop


This will read individual bytes from the FTDI chip, checking status before each one, and push them onto the stack. Once enough bytes have been pushed, the next one will overwrite the second byte of the branch instruction (\$008A), and allowing the new code to be executed.

-