Expansion bus

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
jwolfram
Posts: 18
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram »

Yesterday I tested it, my test cycle (init, write a sector, read back) works at both 15KHz and 30KHz. I tested 2 cards, a 2GB SD card and a 4GB SDHC card, both are approx 4-6 years old.
So it should be possible to make a half or a complete SCK clock cycle per video line. I hope, this information helps a little bit.

Joerg
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

Thanks, that's great news, it removes the potential roadblock. It makes a lot of sense that it should work in practice, but still...

Now there's a clear but long road ahead, SDcard support will take quite a bit of effort.
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

nutson wrote: 07 Nov 2018, 10:02 I would love to see a board with additional I/O capabilities. I was already planning to assemble a gigatron board with a wire wrap socket for the RAM to be able to connect a hand wired expansion board (with a good old 8255 chip?) on the back of the Gigatron.
Now I looked into 8255. It's a neat beefy chip indeed. I can imagine it sitting on a daughterboard, perhaps combined with a RAM expansion and lots of LEDs for more blinking fun. Initially there's not even a need for a software upgrade, because BASIC can control the pins with PEEK and POKE. It will be biggish. Also the I/O chip is rather expensive, approx. 8 USD, which is a bit scary.

Screenshot 2019-02-20 at 19.12.09.png
Screenshot 2019-02-20 at 19.12.09.png (143.43 KiB) Viewed 7024 times
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

jwolfram wrote: 11 Jan 2019, 08:29 Hardware:
I had to read over this section several times, but I believe I'm starting to grasp it, modulo a couple of details I point out below. I like the direction it's taking!

Note 1: The concept is memory mapped I/O, where:
  1. the SPI hardware gets a small part of the high memory address space to listen to, and
  2. lower address lines encode all SPI parameters: MOSI, SCK (SCLK) and the slave enable lines, and
  3. from the 8-bit code point of view, both SPI reads and SPI writes look like a series of well-crafted memory reads, and
  4. in full Gigatron style, the SPI protocol, every edge transition of it, is fully driven by software.
- 64K (128K) RAM is mandatory
Note 2: The concept for SPI read is that data coming from an SPI slave (over the MISO line) doesn't enter the Gigatron data bus directly. Instead, it first enters the RAM through one of its address lines, and from there the RAM puts the correct bit value on the data bus. This works if the dedicated memory area is initialised properly. The 32K system doesn't have enough free memory space for doing that, so we need 64K. But we don't need a tristate buffer chip with its own enable support logic. Nice.
, probably it should be possible to make the upper 32K switchable if a 128K RAM is used
Note 3: I don't get the 128K story yet, or the upper 32K reference. But that's because lack of trying from my side. I park that for now.
- Fill at startup 0xF000 to F7FF with 0x01, 0xF800 to 0xFFFF with 0x00

Code: Select all

RAM[ 1111.0xxx.xxxx.xxxx ] reads as 1
RAM[ 1111.1xxx.xxxx.xxxx ] reads as 0
          ^
          Derived from MISO
Note 4: There is a data inversion done by the RAM. This undoes the inversion introduced later when calculating A10_RAM.

Note 5: You're using A10 below, but this memory initialisation pivots around A11. Is this a small oversight? I would expect the following initialisation:

Code: Select all

RAM[ 1111.10xx.xxxx.xxxx ] reads as 1
RAM[ 1111.11xx.xxxx.xxxx ] reads as 0
           ^
           Derived from MISO
And therefore:

"- Fill at startup 0xF800 to 0xFBFF with 0x01, 0xFC00 to 0xFFFF with 0x00"

- /IOSEL decoder with 74xx30 /IOSEL = /(A11 & A12 & A13 & A14 & A15 & (inv)OE)
Note 6: We take five address lines A11:A15 to distinguish I/O from RAM access. As stated, we do RAM reads for any I/O (reading or writing). Using the five lines means we have 1/32nd of the 64K address space in use for the I/O extension. So we lose just the top 2K of memory for user applications.

Note 7: The 7430 is an octal NAND, so in the above, 2 of its input pins are unused. We can use those 2 to shrink the lost area from 2K to 512 bytes?

Note 8: Tiny BASIC v2 puts program variables at the top page of the available memory, and it lays out its arrays downwards from the top. This is done so that a 64K system has larger arrays than a 32K system. The memory size check during hard reset only tests memory presence in powers of two. So there is a conflict here to consider.

Note 9: The hard reset sequence in ROM page 0 always walks through the entire 16-bit RAM address space, and reads every byte. It does this to seed the entropy pool. (In the case of a 32K system, it reads every byte twice.) When hitting the top of the address space, this will result in activity on the SPI interface. This activity is deterministic, and perhaps we can arrange the address line mapping in a way to mitigate any unwanted effects of this.
- 74xx175 as register (reset with MR at startup), clock with (inv)/IOSEL

* A7 = MOSI
* A8 -> inverter -> /CS1
* A9 -> inverter -> /CS2
* A10 -> SCK

the delay of the 74xx30 + inverter should be enough to register correct signals.
Note 10: I was expecting to see A6:A9 here, because now A10 has a double meaning. But the way A10 is rewired that's ok. But why not something like A0:A3? (But also see note 13 below...)

Note 11: The 74175 is a quad flip-flop with both Q and /Q outputs. We need flip-flops for stable outputs (just like the OUT/XOUT registers on the main board). Outputs are MISO, SCLK, and the SPI slave enable lines. With 4 flip-flops we therefore can have 2 SPI slaves. But with the 74174 we have 6 flip-flops or 4 slaves (and with octal 74273 we have 6...).

Note 12: I presume /CS1 and /CS2 are the slave select lines (and not RAM selects). Why do we need the inverted outputs to produce /CS1 and /CS2? Can't the driving software handle that inversion?
-if IOSEL=LOW, exchange A10 to the RAM with the MISO signal. This could be critical but we can say, we read only data
if SCK is HIGH. So we can reduce the path to an AND gatter. [gate? -MvK]

A10_RAM = A10 & (inv)((inv)/IOSEL & MISO)
Note 13: Is that why A10 is having the double function? To avoid glitches? But A10 is not the same as SCK. I admit I need to put more thinking in this area.

Note 14: The MAU (Memory Address Unit) is always active, and so it can be glitchy at the beginning of a memory read cycle. That's also one of the reasons why the /WE signal is OR'ed with the clock: to prevent bad writes into memory. If the Y register contains all-ones (for example because we have just done a far jump high into the program memory), and somewhat later we perform a zero-page memory read, isn't it possible to glitch /IOSEL?

Note 15: Timing wise, this is adding nanoseconds to the critical path of a Gigatron cycle. It's perhaps not an issue for the 55ns RAM that comes with the kit edition. It's more likely to become an issue with the 70ns RAM that the Gigatron was originally designed for. Well, so be it. But your next idea solves that concern:
So OE remains low between two RAM acesses we can do a second ld[y,x] to compensate the longer access time.
Note 16: That's a perfectly valid solution! And also the reason why vCPU can't do it, I get it now. SYS functions are a possible solution indeed. We can also think of integrating it with the video/audio loop.
So You will need an additional RAM, a 74xx30, a 75xx175, a 74xx08 and a 74xx04
Note 17: That was a very high information density description, wow! Thank you so much! I do think I want to prototype this, and also look at the general availability of these IC types. From my understanding, we can go to a 4-slave or 6-slave configuration just as easily. The devil is in the details, and it's clear your have thought them through pretty well!

Note 18: I think I would prefer a decoder for driving the SPI selects, rather than independent address lines. This prevents enabling multiple SPI slaves through an accidental memory access from user code. That will become a short circuit, and that's not great? (Or is the MISO open collector, and this is not a concern?)
jwolfram
Posts: 18
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram »

Some further explanantions:
Note 5: You're using A10 below, but this memory initialisation pivots around A11. Is this a small oversight?
Yes, that's right. I wrote this down before the idea of double use of A10 was born.
Note 13: Is that why A10 is having the double function? To avoid glitches? But A10 is not the same as SCK. I admit I need to put more thinking in this area.
The idea for the double function of A10 (SCK, data gate) I had later, the main thought was to reduce the reserved memory area from 4K to 2K.
Note 7: The 7430 is an octal NAND, so 2 of its inputs pins are unused in the above. We can use those 2 to shrink the lost area from 2K to 512 bytes?
I think, not. See my explanation to note 10.
Note 10: I was expecting to see A6:A9 here,...
I considered to not use A0 to A6. So it should be possible to use the X register as output value and put the MSB to MOSI when reading from I/O. So we will put the MSB of X and get the LSB of A in one cycle/command. Another way is to use the lower bits of X with:

Code: Select all

anda    0x80,x 
ora     #ctrl,x
but this needs additional cycles and code. My idea was also to put the SPI handling into the video/audio cycle. There might be a counter variable in the zeropage. If its bit 7 is zero, do audio/LED stuff, if not, exchange a bit via SPI and decrement this variable by 16. So the vCPU writes the byte to send, start code into the counter variable and waits until bit 7 of the counter variable is zero. This can be done with 3 system calls:

A) write data to the exchange variable and 0xF1/0xF2 to the counter variable
B) check if bit 7 of the counter variable is zero (transfer complete)
C) read the exchange variable


this (theoretic) code needs only 3 additional clocks in the video line code for non_spi cycles. Sound is stopped during SPI I/O but in my opinion this shouldn't a problem.

Code: Select all

    ld      [$countvar]
    bge     no_spi
    ld      $spi_routine_h,y
    jmp	     y,$spi_routine_h

no_spi:
    ;here follows the sound code

spi_routine:

    suba    $0x10                 ;next cycle
    st      [$countvar]           ;store back
    ora     $0xFC,y               ;calc Y with clock HI
    ld      [$datvar],x           ;get write data
    ld      [y,x]                 ;spi clock hi
    ld	    [y,x]                 ;read data
    adda    [$datvar]             ;add data
    adda    [$datvar]             ;add again (shift * 2)
    st      [$datvar]             ;write back
    ld      [$countvar]           ;
    ora     $0xF8,y               ;calc Y with clock LOW
    ld      [y,x]                 ;spi clock low

    ;here we can jump to the sound output end...


Joerg
jwolfram
Posts: 18
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram »

Further thoughts:

1. My emulation is not fast enough to distinguish between RAM and SPI acess, so its a good idea to use an 'unique' command for SPI access. For instance, ora [y,x]. This operation is currently not used by the GIGATRON ROM and there is no problem with compatibility.

2. For Note 14: We can add a dummy zeropage access to reset the IOSEL signal.

3. The SCK signal should be slightly delayed (for instance by 2 inverters) to get a setup time for MOSI.

Code: Select all


spi_routine:

    suba    $0x10                 ;next cycle
    st      [$countvar]           ;store back
    ora     $0xFC,y               ;calc Y with clock HI
    ld      [$datvar],x           ;get write data
    ora     [y,x]                 ;spi clock hi
    ld      [$datvar]             ;get data
    adda    [$datvar]             ;add (shift * 2)
    ora     [y,x]                 ;spi read data
    st      [$datvar]             ;write back
    ld      [$countvar]           ;
    ora     $0xF8,y               ;calc Y with clock LOW
    ora     [y,x]                 ;spi clock low
    ld      [0x00]                ;this is a dummy read to disable IOSEL
    ...
Joerg
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

jwolfram wrote: 22 Feb 2019, 07:39 2. For Note 14: We can add a dummy zeropage access to reset the IOSEL signal.
My concern with note 14 is primarily that the extra logic might trigger spurious SPI events from regular code: e.g. reads (or actually any instruction) elsewhere in the Gigatron. After all, the MAU output isn't clocked. It can glitch at the beginning of the Gigatron cycle while switching between addressing modes. And Y has a double function, so it can hold arbitrary values. This combination of factors might trigger /IOSEL. At least, I see that as a potential risk.
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

I decided to measure it on a standard Gigatron with 32K and ROM v3. Primary probe (yellow) on the A15 breakout. Secondary probe (blue) on CLK1 so we have a frame of reference. During normal operation one expects A15 always to remain low, because the software isn't trying to access non-existing RAM (except during hard reset).

A non-zero value for A15 can only come from the Y-register, and Y is also used for addressing the ROM. So we start the Pictures application:

IMG_4818.jpeg
IMG_4818.jpeg (389.94 KiB) Viewed 6940 times

Pictures also isn't trying to read or write into non-existing RAM. Still glitches appear on A15 while Jupiter is scrolling in (the yellow spikes). When the Parrot is scrolling in, there are no glitches. This is consistent with the theory: the data for the Parrot image is fully contained in the lower half of the ROM address space. The Jupiter image data protrudes into the upper half.

DS1Z_QuickPrint2.png
DS1Z_QuickPrint2.png (49.36 KiB) Viewed 6940 times

Zooming in, these are about 15 ns in duration, and occur ~42 nanoseconds into the Gigatron cycle, in the first phase (φ1). The glitch ends just before φ2 of the clock cycle... Apparently it can take that long for the addressing mode to settle.


DS1Z_QuickPrint1.png
DS1Z_QuickPrint1.png (46.49 KiB) Viewed 6940 times
User avatar
marcelk
Posts: 488
Joined: 13 May 2018, 08:26

Re: Expansion bus

Post by marcelk »

I think visually, so I converted your original proposal to a schematic. I believe it's pretty much a correct transcription, but not 100.0% sure of that. Also PDF and KiCAD files attached. [I spent most time fighting the standard KiCAD component library, as the 74LS30 has its output declared as input there.]

Please shoot... I need to give this a rest for a couple of days. But I believe we're gravitating towards something.

Inline image
Inline image
Expansion1.png (764.39 KiB) Viewed 6931 times

PS: Lets ignore the differences between 74LS and 74HC(T) for now. The standard library only has the 74LS variety.
Attachments
Expansion1.zip
KiCAD files
(13.34 KiB) Downloaded 311 times
Expansion1.pdf
Print version
(133.75 KiB) Downloaded 310 times
monsonite
Posts: 101
Joined: 17 May 2018, 07:17

Re: Expansion bus

Post by monsonite »

Hi Marcel, Joerg,

The concept is really starting to take shape - like Marcel I like a diagram to help explain things - thanks for the pdf.

Regarding parallel I/O - might I suggest the MCP23S17 which is a 16 bit port expander driven from the SPI bus.

http://ww1.microchip.com/downloads/en/d ... 01952c.pdf

It has two independent 8-bit bidirectional ports (similar to 8255) and is available in a 300mil wide 28 pin DIP.

The price for 1 off is about 1.14 euro + tax



Capture.JPG
Capture.JPG (23.46 KiB) Viewed 6918 times

May I also offer the suggestion that the expansion board has a suitable connector that will accept a ribbon cable. Once the bus is freely available, it would be good to have the means to connect other things to it - I am thinking of a multislot backplane - as inspired by the RC2014 - which is cheap and easy to work with.
Backplane5_Tindie-300x200.jpg
Backplane5_Tindie-300x200.jpg (11.24 KiB) Viewed 6918 times

regards


Ken
Post Reply