Subject: Using 6264 in conjunction with 27512 on 64K Cart board

From: "hexbus" <[email-masked]>
Date: Sun, 06 Dec 2009 03:27:22 -0000

There's another set of pins on the 74LS379 on the 64K Cartridge board (D3 and inv Q3).  Is there any way I can piggyback a 6264 SRAM in conjunction with the 27512 EPROM and activate the SRAM when a certain bank is written to?

http://en.wikipedia.org/wiki/6264

This would give Marc Hull and others a way to house 8K of RAM (they can bank switch to it) - we could even probably cut it down to 4K (>7000 to >7FFF) somehow if we run into issues with there needing to be code from the ROM in RAM to keep the program from crashing.  I don't know if you can use the scratchpad as a temporary holding area to hold stuff as it's being copied (if needed) from ROM to RAM, etc.  

Thoughts?  Pros/Cons?  How easy would this be?    Sounds like we need to develop some bank switching routines to share around. :)

Jon

---

From: Marc Hull <[email-masked]>
Date: Sat, 5 Dec 2009 20:32:52 -0800 (PST)

Jon...

I looked at the "IDEA" again earlier this week.  The best I could come up with was a ROM that existed in the first 1K and the last 5K with a 1K chunk of RAM in the middle.  My earlier thought had the Ram at the beginning of the 8K block which might make it  problematic at best.  The undesirables with Ram/Rom on the board is the extra decode logic needed on the PCB and the lost 1K of ROM.   Feel like a redesign ;-)

--- On Sat, 12/5/09, hexbus <[email-masked]> wrote:

From: hexbus <[email-masked]>
Subject: [TI994A] Using 6264 in conjunction with 27512 on 64K Cart board
To: [email-masked]
Date: Saturday, December 5, 2009, 9:27 PM

  

http://en.wikipedia .org/wiki/ 6264

Jon

---

From: "Tursi" <[email-masked]>
Date: Sun, 6 Dec 2009 00:25:57 -0500

> There's another set of pins on the 74LS379 on the 64K Cartridge board (D3 
> and inv Q3).  Is there any way I can piggyback a 6264 SRAM in conjunction 
> with the 27512 EPROM and activate the SRAM when a certain bank is written 
> to?
>
> Thoughts?  Pros/Cons?  How easy would this be?    Sounds like we need to 
> develop some bank switching routines to share around. :)
>

Didn't we just have a huge discussion on this? :) Maybe some of my messages 
didn't get out, I kept forgetting to set the correct 'from' address and just 
ignoring when they bounced. :)

Here's what I previously wrote on it:

10/24/2009 (Re: Something cooking?)

"One last tricky idea for this round, you could map the RAM chip in as a
memory bank by using that last flipflop to disable the ROM when the RAM
is active. I can think of two ways to do that... one is to say that all
writes go to RAM regardless of the current page, but you have to page in
the RAM to read it, the other is to have both reads and writes work only
when the RAM is paged. Both would require an additional gate on the
gate, and the bank switch addresses themselves would not be very usable
(but that's not a big loss out of 8k). You'd also need little trampoline
functions in scratchpad to change the bank, read (or write) the value or
values, and change back (this is why I think all writes go to RAM
regardless of bank is the better approach - you only need to trampoline
for reads)."

What I meant by this was, two options. With the simple one, you are putting 
the 8k RAM chip in the last bank (ie: using D3/Q3). You need to manage the 
CS* signal between the EPROM and the RAM chip (since only one or the other 
may respond) - this is where having two chip select/enable lines becomes 
useful.

In the current design, OE* is connected to ground, and CE* is controlled by 
the TI. The easiest way would be to use OE*, since that way you don't also 
need to gate the TI's control of CE*, but either way is fine. So in this 
case, because the flipflop offers both outputs, you just run Q3* to the 
RAM's OE* line - that guarantees that the RAM chip will only be active when 
the fourth bank is selected. Then just run Q3 (non-inverted) to the ROM's 
OE* line -- this guarantees the ROM will be active any time that the RAM is 
not.

There's still a problem here - ANY write will trigger the 379. There are two 
answers for this. The first is just a software decision - you can only write 
to the RAM on addresses that trigger the correct bank. Q3 is tied to bit >10 
(right? that's from memory), so you could only use addresses ending in >10, 
to avoid an unplanned bank switch. All reads are safe. This works, but costs 
a lot of your limited RAM (You end up with just 256 bytes out of 8k) and 
requires the software to be quite careful.

The other way is to restrict the writes to the 379 so that EVERY write won't 
trigger it. To do that, you need more address decode than the port provides. 
Since 5 lines are reserved for switching, you would need to test the other 8 
(13 lines = 8k space). The most straightforward way is to sum the top 8 
cartridge address lines and combine them with the enable on the 379. 
Currently, the E* line is tied to the cartridge select (along with the ROM's 
CE*). The 379's CP line (which triggers it to take the data) is connected 
via resistor to the TI's WE* line (why it is tied through a resistor? And 
through a cap to ground? Not that it's wrong, just a part I don't 
understand.) So the theory here is that the chip inputs are enabled during 
any cartridge port access, and data is taken on any write to that address. 
So the simplest approach may be to sum the 8 address lines and WE* through 
an OR gate - that way only when all of them are low will the CP be 
triggered. I couldn't find any 9-input or even reliable 8-input OR gates 
(NOR, sure, but not OR).. might be easiest to use diodes here and "make" an 
OR gate? Simply run the diodes forward (stripe away from the cart port) so 
they will conduct forward, tie them together, and use a 10k pull-down 
resistor to ground. (Also not tested!). Doing this means only the first 32 
bytes of the RAM are not available (as they are reserved for bank 
switching).

So, to summarize, you can put the RAM chip on the last bank by (note: not 
tested):
1) cut the trace leading to the ROM chip's OE* line, which is pin 24 (runs 
on top of the board, around to pin 16, thick trace) - this is to free up OE*
2) run a wire from this pin to the LS379's Q3 pin, which is pin 15 (not 
connected to anything today), this will disable the EPROM when Q3 is enabled
3) On the 6264 RAM, bend up pins 22 (OE*), 26 (CE2), 27 (R/W), 28 (VCC)
4) piggyback your RAM chip on the EPROM. The 6264 is 2 pins shorter than the 
EPROM, so make sure the base lines up (ie: not pin 1, but the bottom - EPROM 
pin 16 to RAM pin 14).
5) Run a wire from RAM pin 22 (OE*) to 379 pin 14 (Q3*) - this enables the 
RAM chip when Q3 is active
6) Run a wire from RAM pin 26 (CE2) to pin 28 (VCC), and from there to EPROM 
pin 32 (Vcc) - this powers and enables the RAM
7) Run a wire from RAM pin 27 (R/W) to either 379 pin 9 (CP), or directly to 
the cart port pin 32 (top of board, third from the right if looking with the 
fingers facing away from you - runs straight to a through hole). I don't 
quite understand the purpose of the resistor/capacitor circuit feeding CP on 
the 379 and that's why I provide both options here. This tells the RAM if 
you are reading or writing.

And to improve the addressing for bank switch, this is the part I'm least 
sure of. Circuit wise it's fine, but using all the diodes in place of an OR 
I've never tried:
1) cut the trace from cart port pin 32 - easiest place is on the bottom of 
the board where it jumps across two top traces, then goes back to the top. 
This gives you two through-holes to insert the new circuit to
2) Attach switching diodes to the cart port pins 32 (WE*), 16, 18, 20, 22, 
24, 26, 28, 30 (A10-A3). There's a through-hole for pin 32, the rest are 
connected to the EPROM, you could pull from there if you like (EPROM pins 
7,6,5,4,23,25,26,27).
3) connect the other ends of the diodes together. OR gate. ;) Connect a 10k 
resistor from here to ground to ensure a pull down when the diodes aren't 
conducting.
4) Connect a wire from the end of the OR gate to the other side of the cut 
trace, so that it feeds into resistor R1 and eventually to the 379 CP line. 
Now the CP is triggered only when WE* is low, and the selected address lines 
are /also/ low.

To test: try switching banks. The first 64k should select banks in the 
EPROM. Any of the last 64k will just duplicate the 8k of RAM. You should be 
able to read and write the RAM while it's banked in.

A nice improvement on the above circuit, note that all the lines are there. 
If you simply use a 64k SRAM instead of an 8k SRAM, you get full 64k ROM and 
64k RAM, both pagable, without changing the circuit (the pin numbers to bend 
up change, just map out the datasheet).

The one improvement I had in mind for this was to allow writes to /always/ 
select the RAM, this would require another logic gate on the OE* lines, and 
I'll skip describing it for now.

Naturally, this has the problem that your ROM is deselected when the RAM is 
selected. You could copy code in there, though, since you have 8k, to do RAM 
based tasks for you. Otherwise, for basic access you could use a little 
scratchpad routine like so:

* Read a word
* R0 = data returned here
* R1 = address to read from
* R2 = bank to return to
* R11 = return address in source bank
READWD
  MOV R0,@>6010  * Select RAM bank
  MOV *R1,R0    * Get data
  MOV R0,*R2    * restore original bank
  B *R11

* Write a word
* R0 = data to write
* R1 = address to write to
* R2 = bank to return to
* R11 = return address in source bank
WRITEWD
  MOV R0,@>6010  * Select RAM bank
  MOV R0,*R1   * store data
  MOV R0,*R2    * restore original bank
  B *R11

If you wanted to read or write blocks of data without repeatedly switching, 
it would probably be faster to store them in VDP temporarily. You'd have to 
test to see when the threshold of two memory copies beat the constant 
switching.

You can see how adding RAM in a more flexible manner would quickly lead to 
circuits complex enough to justify a CPLD, though. With a CPLD it'd be nice 
to design a small memory mapper. For instance, you could divide the 8k space 
into two 4k bank, and the memory mapper would allow you to map any page from 
ROM or RAM into either bank. This wouldn't be too hard to build. :) But it's 
a new layout, for sure. But we're lucky, we HAVE a read/write line on the 
cart port. Systems like the Coleco or Atari 2600 have to use other schemes 
to fake writes to the cart port. ;)

Hope that's useful - anyone want to try it? ;)

---

From: "sconner3uk" <[email-masked]>
Date: Sun, 06 Dec 2009 10:32:51 -0000

Note that if you're building logic gates out of diodes, it is best to get germanium diodes like the 1N34A rather than silicon diodes like the 1N4148. Germanium diodes have a low voltage drop of ~0.2V. Silicon diodes have a voltage drop of ~0.7V, possibly (edge case conditions) giving you a logic signal with a voltage in the indeterminate range somewhere between a logic 0 and a logic 1.

Stuart.

---

From: "Tursi" <[email-masked]>
Date: Sun, 6 Dec 2009 09:35:18 -0500

> Note that if you're building logic gates out of diodes, it is best to get 
> germanium diodes like the 1N34A rather than silicon diodes like the 
> 1N4148. Germanium diodes have a low voltage drop of ~0.2V. Silicon diodes 
> have a voltage drop of ~0.7V, possibly (edge case conditions) giving you a 
> logic signal with a voltage in the indeterminate range somewhere between a 
> logic 0 and a logic 1.
>

Good tip!

One problem with my circuit did come to mind during tonight's bout of 
insomnia -- since the 379 doesn't come up in a (definitely) known state, the 
RAM chip may be selected on powerup rather than the ROM. And that isn't 
going to work.

I was thinking about this problem - as well as the somewhat trickier FCTN-= 
problem (since it doesn't toggle a reset line!), and if using a CLPD, one 
simple answer would seem to be to reset the gates when address >6000 is 
read - since the only normal purpose for reading this address is to check 
for the >AA byte, and the TI console is guaranteed to do it every time. The 
advantage of this plan, is instead of needing a full header in every bank of 
your ROM, you only need a header in the first bank (although you lose the 
first word in every bank still - but that's only one word as opposed to a 
full header and startup code). The switch should be fast enough to be done 
before the TI reads the data.

For the existing cart, the minimum needed to make it work is to clear D3 on 
startup. To do so means we'd need to hit D3 and CP in order to clear it. The 
variant with a RESET line would work for power-on restart, but isn't any 
better for soft restarts. (And according to Thierry's page, the reset line 
is an input anyway. That figures.)

Lacking any good ideas, how about a crazy idea?

If nobody plans to create carts that do a lot of work with GROM, the GROM 
Select line (GS*) could be used to trigger the CP line (AND it with the WE* 
line). What good is this? When the console accesses GROM, it will trigger 
the 379 to load the contents of the address bus. The address bus will 
contain either >9800 (GROM Data), >9802 (read GROM Address), or >9C02 (write 
address) (with >9C00, write data, not used by the ROMs). The >9x02 hits will 
naturally cause the 379 to latch >02 (same as >6002 would), but they are 
always followed by read data, at >9800, which will latch >00. This selects 
the highest bank in the ROM, and disables the RAM. Of course it means that 
/any/ access to GROM will also do this, but if you wanted to use GROM (like 
in my code to load the character set), just make sure it resides in that 
powerup bank.

This is, of course, one more gate (the AND gate). Take the existing input to 
CP on the 379, disconnect it from the 379, feed it to one input, connect the 
cart port GS* to the other input, and feed the output to CP. Just one AND 
gate is needed for that.

The end result then gives you:
-guaranteed bank reset on the TI console (both soft and hard) by any GROM 
access
-up to 64k SRAM and 64k ROM
-requires two more logic gates (although it's probably more convenient to 
build the OR from 8 diodes and a resistor, since such large OR gates are 
hard to come by)
-limits the switching space to just 32 bytes

and introduces one caveat:
-any code that wishes to access GROM must reside in the powerup bank

I uploaded a sketch of the concept at 
http://harmlesslion.com/temp/withram.JPG

---

From: "hexbus" <[email-masked]>
Date: Sun, 06 Dec 2009 18:01:29 -0000

> http://harmlesslion.com/temp/withram.JPG

.. and this is why I'm constantly in awe of this community... :-)

Tursi, you rock, man.  I'm so glad that we have mentors in this group that are so well versed in hardware and logic to help along the preschool-level digital electronics folks like myself. :-)

I did buy this book after searching around for one on logic circuits.. hopefully it'll be the next thing on my reading list before the VHDL/CPLD book:  http://www.amazon.com/gp/product/0966498011/ref=ox_ya_oh_product

Jon

---

From: "Tursi" <[email-masked]>
Date: Sun, 6 Dec 2009 16:37:54 -0500

> Tursi, you rock, man.  I'm so glad that we have mentors in this group that 
> are so well versed in hardware and logic to help along the preschool-level 
> digital electronics folks like myself. :-)
>

I can't promise it works! :) It makes sense on paper, but I always give my 
designs a 50:50 chance of surviving the transition to the real world... I'm 
just not much past preschool-level digital electronics myself! :) hehe.

There as a mistake in my schematic - I forgot the resistor on the pull-down 
after the diodes, that would cause a short. I've posted a fixed version, 
please delete the old "withram.JPG" if you have it, and use this instead: 
http://harmlesslion.com/temp/withram_fixed.JPG

I'm starting to think I'd like to do the VHDL for a CPLD version, as I 
discussed... the problem is I have three weeks left to get packed. heh. 
Maybe in January...