Expansion bus

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice.
User avatar
marcelk
Posts: 290
Joined: 13 May 2018, 08:26

Expansion bus

Post by marcelk » 01 Nov 2018, 16:22

As originally designed there is no direct expansion bus on the Gigatron, and that creates a bit of a HW bottleneck especially when wanting to do more serious I/O. One of the great things of the Altair 8800 was of course that it set the S-100 standard. The RC2014 has a similar concept.

Pondering about this from time to time, I dawned upon me that all ingredients seem to be in place to add one, without modifying the board: the RAM socket.

The idea is that it has address lines, data lines, a R/W line, Vcc and GND already. We could put a pin on the breakout point for A15. The RAM gets no clock signal, but there is a test point nearby for CLK1 (next to U16, the OR gates) and we can do the same there.

So the question is: would that work? Make a daughterboard that plugs into the RAM socket, A15 and CLK1. It would have its own socket to reseat the RAM, but also a header connection to break out all of these bus signals. Probably some protection and/or buffers, maybe a decoder for high address lines.

Any thoughts?

nutson
Posts: 2
Joined: 02 Nov 2018, 08:45

Re: Expansion bus

Post by nutson » 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.

My application would be a project with many WS2812B LED's (and a Parallax Propeller driving the 800 KHz LED refresh chain) where the Gigatron in its beautyfull case would shine as the Master controller. As a minimum the Gigatron would need to be able to read a keyboard/joystick (speed/intensity/pattern up/down) and output a (parallel) status word to the Propeller).

jwolfram
Posts: 13
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram » 08 Jan 2019, 11:01

Some thoughts...

Another idea is to use only pages 0xFD-0xFF. So 63K of RAM can be used and it needs only a 74LS30 etc. to decode.
I prefer SPI as communication protocol, so also SPI EEPROM/FLASH can be used as external storage.
If one of the the pages is selected, a ld[y,x] can register 2 chip-select signals from A8/A9 and put new data with
the X register while reading last data into the ACC. For reading I/O data the /OE signal on the RAM should be diasbled
by the inverted Page select signal. Instead, the signals of an input register should be connected to the bus while /OE
is asserted.

As output register I would suggest a 74LS165 for data and a second 74LS165 (with all data HI except DS) for SCK gating.
As input register a 74LS164 + tristate drive should work.

This can be placed to a daughterboard in the RAM socket and needs only an additional clock signal + A15.

A simpler version uses only A7 for data out and D0 for data in, SCK will be provided at (registered) A10. This is slower
(shifting must be done in SW) and only 62K RAM are available. But it's more flexible, allows also to use a SD-Card as
external storage and it needs no additional clock signal.
A 4-bit register can hold A7-A10 and the D0 signal needs only a 1 bit tristate buffer. It should be also possible
to put 2 (32K) RAM sockets on the daughterboard. So the memory can be easy expanded to 62K.

Finally, I think both variants can by emulated without problems by the GTmicro.

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

Re: Expansion bus

Post by marcelk » 09 Jan 2019, 13:42

Thanks, indeed it is wise to seek alignment with some standard. SD card interfacing is an irresistible attracting force. Even beter, it all looks somewhat simpler than PS/2 was.

jwolfram
Posts: 13
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram » 11 Jan 2019, 08:29

Some further ideas:

Hardware:


- 64K (128K) RAM is mandatory, probably it should be possible to make the upper 32K switchable if a 128K RAM is used
- Fill at startup 0xF000 to F7FF with 0x01, 0xF800 to 0xFFFF with 0x00

- /IOSEL decoder with 74xx30 /IOSEL = /(A11 & A12 & A13 & A14 & A15 & (inv)OE)

- 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.

-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.

A10_RAM = A10 & (inv)((inv)/IOSEL & MISO)

So OE remains low between two RAM acesses we can do a second ld[y,x] to compensate the longer access time.

So You will need an additional RAM, a 74xx30, a 75xx175, a 74xx08 and a 74xx04

Software:

At this point I have some questions:

1. where must I place the SYScalls?

Code: Select all

SYS_SPI_NCS:	ld	$F8,Y		;CS 1/2 inactive, SCK low
		ld	[y,x]
		ld	$03,Y
		jmp	Y,$cb
		ld	$f5
		
SYS_SPI_CS1:	ld	$F9,Y		;CS 1 active, SCK low
		ld	[y,x]
		ld	$03,Y
		jmp	Y,$cb
		ld	$f5
		
SYS_SPI_CS2:	ld	$FA,Y		;CS 2 active, SCK low
		ld	[y,x]
		ld	$03,Y
		jmp	Y,$cb
		ld	$f5
How the remaining clocks are calculated? 0xF7 - (2 * instructions_before_ld)?

Single Bit exchange:

Code: Select all

		ld 	[$24],X		;what to send (we unse only Bit 7)
		ld	$FA,Y		;CS 1 active, SCK LOW
		ld	[y,x]		;provide OUT data
		ld	$FE,Y		;CS 1 active, SCK HI,Read data
		ld	[y,x]		;set SCK hi, dummy read
		ld	[y,x]		;read input data
		adda	[$18]		;shift data and add in bit
		adda	[$18]
		st	[$18]
		lda	[$24]		;shift left out value
		adda	[$24]
		st	[$24]

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

Re: Expansion bus

Post by marcelk » 11 Jan 2019, 14:29

Thanks. I'll see if I can study the hardware side this weekend. I'm brushing up my knowledge on SPI and SDcard interfaces in the meantime.
jwolfram wrote:
11 Jan 2019, 08:29
At this point I have some questions:

1. where must I place the SYScalls?
It can live anywhere you like in the ROM address space. But once we release it in a formal ROM version, and if we make it part of the formal application interface (interface.json), the address can't change anymore for compatibility reasons. But we're not there yet...

Code: Select all

SYS_SPI_NCS:	ld	$F8,Y		;CS 1/2 inactive, SCK low
		ld	[y,x]
		ld	$03,Y
		jmp	Y,$cb
		ld	$f5
In source form this could look like this:

Code: Select all

label('SYS_SPI_NCS_22')

ld(0xf8, Y);                    C('CS 1/2 inactive, SCK low')#15
ld([Y,X])                       #16
ld(hi('REENTER'), Y)            #17
jmpy('REENTER')                 #18
ld(-22/2)                       #19
For this specific action no new SYS function is needed, as it can be done with a PEEK instruction in vCPU of course.
How the remaining clocks are calculated? 0xF7 - (2 * instructions_before_ld)?
There are two places where vCPU needs to do something with this.

When returning, a SYS function must load the actual number of elapsed vCPU ticks in AC, but as a negative number. A vCPU tick is 2 Gigatron cycles and all vCPU instructions and SYS functions are made to execute in an even number of such cycles.

Code: Select all

T = -nrActualCyclesFromNEXTtoNEXT / 2
Once we enter the SYS function, 15 Gigatron cycles have elapsed already since the last passing of NEXT. And we get 2 more from going through REENTER to return to the next passing of NEXT. So here the total duration will be 22 cycles, so T = -22/2 = 0xf5 indeed.

When calling a SYS function, the maximum expected number of ticks must be known as well. vCPU needs this to decide if it can complete the call in the current time slice, or if it must wait for a later time slice and let the audio/video loop go first. [Convention is to slap this worst-case duration to the function name as well, because the caller must provide it (or a larger number) as an operand(*) to the SYS call. It is then handy for reviewing the correctness of the invocation to carry it in the name.]

(*) Actually, the operand for the SYS instruction is 270-max(14,cycles/2). The GCL compiler makes this conversion on your behalf when you type "22!" for calling a 22-cycle SYS function.

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

Re: Expansion bus

Post by marcelk » 14 Jan 2019, 23:28

I've found the attached SPI and SD card explanation online. The software stack to make the FAT file system accessible will be a substantial effort. But it will be worth it, and with a bit of planning we can make the EPROM contents appear as a file system as well.

A bit more worrisome is the statement that SD cards must be clocked at 100 kHz or higher:
To ensure the proper operation of the SD card, the SD CLK signal should have a frequency in the range of 100 to 400 kHz.
That will be difficult to combine with VGA generation: horizontal sync is at 31.25 kHz. So I think it's good to understand if this 100 kHz is a true lower speed limit in reality. Or is there is a possibility to lower the SPI mode frequency for SD card access substantially, to align better with video? (E.g. one SCLK per horizontal pulse, or even one per 4 pulses.)

We could always blank the screen during SD card access, even while maintaining the VGA sync signals active (just don't send pixel data). But it would be nice if this is not really needed... (We might still have to mute sound however.)
Attachments
SPI_and_SD_card.pdf
(741.55 KiB) Downloaded 26 times

jwolfram
Posts: 13
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram » 15 Jan 2019, 12:49

The frequency limitation is only valid within the init phase, after the init is done, You can use SPI frequencies up to 20MHz and more. My suggestion is to use an image file, which contents a number of "0-padded" GT1 files of, for example, 64K or snapshots. During init, which should be done at startup if video is not active, the gigatron can determine the start sector of the image file and write this to system variables. If the support is limited to only SDHC cards, this sector number can be used directly for the read/write commends and no byte position must be calculated. If no card is detected, leave the start sector at 0x0000 or 0xFFFF.
Later, a smaller subroutine can determine easily the start sector from a particular GT1 file without knowledge of the whole FAT bloat and without any additional RAM buffer. I've used this principle at my AX81 and AX82 emulators. It needs a small program on the PC to pack and extract the particular files from the image but this can easier be done as supporting the fat filesystem on the gigatron completely.

But, file handling on the gigatron is another construction area...

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

Re: Expansion bus

Post by marcelk » 15 Jan 2019, 15:42

Yes, but I like to go below 100 kHz in an attempt to keep VGA alive. Will that work? What can be reason/source/justification for that apparent SD card limit of 100 kHz? Handwaving or real?

jwolfram
Posts: 13
Joined: 07 Jan 2019, 20:11

Re: Expansion bus

Post by jwolfram » 23 Jan 2019, 09:15

I can make a test next time to determine which is the lowest speed for communication with the SD cards. But I think, only the upper limit is important.

Joerg

Post Reply