Browse Source

rc2014: complete the EEPROM recipe

pull/102/head
Virgil Dupras 4 years ago
parent
commit
b536d3bfd6
4 changed files with 30 additions and 45 deletions
  1. +5
    -5
      drv/at28.fs
  2. +21
    -39
      recipes/rc2014/eeprom/README.md
  3. +3
    -1
      tools/common.c
  4. +1
    -0
      tools/upload.c

+ 5
- 5
drv/at28.fs View File

@@ -2,12 +2,12 @@
operation while doing the right thing. Checks data integrity
and ABORT on mismatch.
)
( a n -- )
( n a -- )
: AT28!
2DUP C! SWAP
( as long as writing operation is running, IO/6 will toggle at each
read attempt. We know that write is finished when we read the same
value twice. )
2DUP C!
( as long as writing operation is running, IO/6 will toggle at each
read attempt. We know that write is finished when we read the same
value twice. )
BEGIN ( n1 a )
DUP C@ ( n1 a n2 )
OVER C@ ( n1 a n2 n3 )


+ 21
- 39
recipes/rc2014/eeprom/README.md View File

@@ -7,7 +7,8 @@ itself.

## Gathering parts

* A RC2014 Classic that could install the base recipe
* A RC2014 Classic
* `stage3.bin` from the base recipe
* An extra AT28C64B
* 1x 40106 inverter gates
* Proto board, RC2014 header pins, wires, IC sockets, etc.
@@ -32,52 +33,33 @@ in write protection mode, but I preferred building my own module.

I don't think you need a schematic. It's really simple.

## Building the kernel
## Using the at28 driver

For this recipe to work, we need a block device for the `at28w` program to read
from. The easiest way to go around would be to use a SD card, but maybe you
haven't built a SPI relay yet and it's quite a challenge to do so.
The AT28 driver is at `drv/at28.fs` and is a pure forth source file so it's
rather easy to set up from the base Stage 3 binary:

Therefore, for this recipe, we'll have `at28w` read from a memory map and we'll
upload contents to write to memory through our serial link.

`at28w` is designed to be ran as a "user application", but in this case, because
we run from a kernel without a filesystem and that `pgm` can't run without it,
we'll integrate `at28w` directly in our kernel and expose it as an extra shell
command (renaming it to `a28w` to fit the 4 chars limit).

For all this to work, you'll need [glue code that looks like this](glue.asm).
Running `make` in this directory will produce a `os.bin` with that glue code
that you can install in the same way you did with the basic RC2014 recipe.

If your range is different than `0x2000-0x3fff`, you'll have to modify
`AT28W_MEMSTART` before you build.
cat ../stage3.bin ../pre.fs ../../../drv/at28.fs ../run.fs > os.bin
../../../emul/hw/rc2014/classic os.bin

## Writing contents to the AT28

The memory map is configured to start at `0xd000`. The first step is to upload
contents at that address as documented in ["Load code in RAM and run it"][load].

You have to know the size of the contents you've loaded because you'll pass it
as at argument to `a28w`. You can run:
The driver provides `AT28!` which can be plugged in adev's `A!*`.

Collapse OS
> bsel 0
> seek 00 0000
> a28w <size-of-contents>
It's not in the Stage 3 binary, but because it's a small piece of Forth code,
let's just run its definition code:

It takes a little while to write. About 1 second per 0x100 bytes (soon, I'll
implement page writing which should make it much faster).
cat ../../../drv/at28.fs | ./stripfc | ./exec <tty device>

If the program doesn't report an error, you're all good! The program takes care
of verifying each byte, so everything should be in place. You can verify
yourself by `peek`-ing around the `0x2000-0x3fff` range.
Then, upload your binary to some place in memory, for example `a000`. To do so,
run this from your modern computer:

Note that to write a single byte to the AT28 eeprom, you don't need a special
program. You can, while you're in the `0x2000-0x3fff` range, run `poke 1` and
send an arbitrary char. It will work. The problem is with writing multiple
bytes: you have to wait until the eeprom is finished writing before writing to
a new address, something a regular `poke` doesn't do but `at28w` does.
./upload <tty device> a000 <filename>

[load]: ../../../doc/load-run-code.md
Then, activate `AT28!` with `' AT28! A!* !` and then run
`0xa000 0x2000 <size-of-bin> AMOVE`. `AT28!` checks every myte for integrity,
so it there's no error, you should be fine. Your content is now on the EEPROM!

Why not upload content directly to `0x2000` after having activated `AT28!`?
Technically, you could. It was my first idea too. However, at the time of this
writing, I always get weird mismatch errors about halfway through. Maybe that
the ACIA interrupt does something wrong...

+ 3
- 1
tools/common.c View File

@@ -8,7 +8,9 @@
void mread(int fd, char *s, int count)
{
while (count) {
while (read(fd, s, 1) == 0);
while (read(fd, s, 1) == 0) {
usleep(1000);
}
s++;
count--;
}


+ 1
- 0
tools/upload.c View File

@@ -65,6 +65,7 @@ int main(int argc, char **argv)
// we don't exit now because we need to "consume" our whole program.
returncode = 1;
}
usleep(1000); // let it breathe
}
mread(fd, s, 2); // "> " prompt
sendcmdp(fd, "FORGET _");


Loading…
Cancel
Save