Jump to content
Blinky

Cheap 2K/4K X-in-1 menu driven Multicart for Atari 2600

Recommended Posts

Just wanted you to inform of my new project.

 

I designed a menu driven multicart that just uses 2 standard ICs with a couple of other components for the logic. This design suports 2K and 4K games put into a 8K..128K EPROM (another latch could be added to support EPROMs up to 1 Mbyte).

 

mmcb-breadboard.jpg

 

The banking scheme used, uses address range $0800-$0FFF so a LDA $0800-$0FFF can be used

to set the latch(es). I've chosen this range so normal TIA and RIOT access will not interfere

with the banking scheme and for the possibility to patch $F8 (and other banking schemes) games.

A total of 11 address lines are available, 9 are uses for bank select, 1 bit for 2K/4K mode so a 2K bank can be mirrored to 4K and 1 bit to lock the latch(es) for games that interfere with the banking scheme.

 

Heres the BASIC design schematic.

 

mmcb-schematic.gif

 

I wrote a 2K menu for it that displays game titles as 48 pixel wide proportional text. A menu bar to highlight the selected title is controlled by any joystick or B/W, SELECT and RESET switches to select a game. Game titles are stored as graphics and take up a lot of space. I managed to byte bust the menu code into 512 bytes. So there are 248 lines of 48 pixels available for storing game titles.

 

I've made working 8-in 1 version in a 32K EPROM. But there is still a lot to do like a menu for supporting more 500+ games. and a utility to select games, patch the menu and generate a image of it.

 

mmc-menu.jpg

mmc_8_in_1_pal_.zip

Share this post


Link to post
Share on other sites

Very nice. Now if you can change the menu from all bitmapped to individual letters, you should be able to save quite a lot on larger bankswitched cart.

Share this post


Link to post
Share on other sites
Very nice.  Now if you can change the menu from all bitmapped to individual letters, you should be able to save quite a lot on larger bankswitched cart.

 

It could save 66% on the data if I could(16 chars per title instead of 8*6 bytes). The problem is that there is not enough ram to create bitmap data from individual characters for a whole menu page and that there is not enough time available to do it on the fly for each title.

 

Maybe it could be done using fixed spacing characters but then there would be less characters available for a title :(

 

Currently I save space on reducing the height of a title using a different bitmap font. The demo uses 16 lines high titles because there are only 8 titles. but for 31 games I would use 8 lines per title to get 31 titles. By really sqeezing it. I could get 40 titles of 6 lines high.

 

In case of a 1Mbyte rom with only 2K games (are there so many?) the proportional menu would take 13 2K banks leaving 499 for games and a fixed text menu with (12 chars) would just take 4 banks. I think just 9 banks less space for proportional text is not bad. But I'm open for any ideas to save on banks. Especially since I haven't written the menu to support that many games yet.

Share this post


Link to post
Share on other sites

Hi Blinky,

 

I'm not sure which addresses you're using specifically, but be careful. The TIA addresses are mirrored in many locations throughout the 6507's 64K address space. If you haven't already, you might want to take a look at my memory maps, available here. There are a couple of different types of maps there.

 

Cool project, BTW!

 

-Chris

Share this post


Link to post
Share on other sites
Hi Blinky,

 

I'm not sure which addresses you're using specifically, but be careful.  

The TIA addresses are mirrored in many locations throughout the 6507's 64K address space.

 

Hi Chris,

 

I've analysed the schematics and addressing scheme carefully. Adresses should/are only read just like doing with ROM. There is nothing affected by reading any registers (Theres one exception for the RIOTs where the interrupt output pin is cleared. But since it is not implemented in the VCS. it can be ignored) and TIA and RIOT can not be read simmultaniously (because of A7 address line). Doing a write will only change a TIA/RIOT register value.

 

The basic design uses addresses $0800 -$08FF (A7..A0) only. But the full version (which uses an extra 74HCT175) will use $0800-$FFF (A10..A0).

I've choses $0800 as base so normal TIA / RIOT access will not change the selected bank. To be sure that when a game(if any) does access TIA/RIOT in range $0800-$0FFF) the lock bit can be set to prevent the bank from changing.

 

If you haven't already, you might want to take a look at my memory maps, available  here.  There are a couple of different types of maps there.

 

I didn't document it as wel as you did. So I've added yours to my documentations :D

 

Cool project, BTW!

 

Thanks :)

Share this post


Link to post
Share on other sites

This is very cool, I've never seen the schematic for a menu-driven multicart before. This would be much easier than pulling out my supercharger or eprom burner every time I want to play a game. About the text, you might want to try storing it as individual letters as previously mentioned. Also, it would be a good idea to add decoupling capacitors to the schematic, as well as pulling up or down the correct address lines for when it starts up.

Share this post


Link to post
Share on other sites
This is very cool, I've never seen the schematic for a menu-driven multicart before.

 

Thats because I've just recently designed it. :)

 

About the text, you might want to try storing it as individual letters as previously mentioned.

 

I'll keep it in mind.

 

Also, it would be a good idea to add decoupling capacitors to the schematic,

 

There could be a couple more I agree.

 

as well as pulling up or down the correct address lines for when it starts up

 

To start up in bank 0 I keep the latch in reset during start-up. I don't see why I should add any morepull ups/downs.

 

For the final design there will be an extra 74HCT175 for support 8Mbit EPROM and a return to menu switch (to reduce wearing of the power switch) if my theory works.

 

I'm also wondering if there is somebody out there that could make a PCB of it. As I don't have the resources for putting it into production.

Share this post


Link to post
Share on other sites
... and a return to menu switch (to reduce wearing of the power switch) if my theory works.

 

Thats interesting :roll:

 

How are you going to return to the menu ? Switching back to bank 0 will certainly just lead to a crash. Can you explain your theory a bit ?

Share this post


Link to post
Share on other sites
How are you going to return to the menu ? Switching back to bank 0 will certainly just lead to a crash. Can you explain your theory a bit ?

 

OK (taking a deep breath)

To be able to return to the menu. All that is needed is a push button and the 1st 2K bank. The button will reset the latches so bank 0 is selected (in 2K mode). The CPU is then going to execute the code in bank 0. To prevent the CPU from a crash, bank 0 is filled with one single byte instruction including the CPU vectors. The only exception are locations FFF6-FFF8 (and echo at F7F6-F7F8) which hold the instruction LDA $0801 which selects bank 1. Code is executed in bank 1 at FFF9 (or F7F9) where a JMP opcode will cause a jump to the NMI/Break vector (in bank 1) which starts the menu.

 

The single byte instruction opcode in bank 0 must have bit 4 set so the vectors wil jump to a rom location where the instructions are executed to reach the LDA instruction.

Share this post


Link to post
Share on other sites

Hmmm.. so far so good, but what if the cpu is just fetching

the target adress of a jump when the "Back to Menu" button

is pressed ?

 

Or if it is in the middle of a fetch, then switching

might mean the cpu gets just rubbish, or ?

Share this post


Link to post
Share on other sites
Hmmm.. so far so good, but what if the cpu is just fetching the target adress of a jump when the "Back to Menu" button

is pressed ?

 

OK the single byte instruction will be CLD which is $D8

if only JMP opcode was fetched it will jump to JMP $D8D8

if JMP and LSB where fetched JMP $D8xx. Both are safe.

 

if bank is switched while CPU is in FFF7-FFF8 area it will perform a

ORA ($08,X) or PHP. :idea: I just see that JMP opcode must be at FFF9 in bank 0 as well to prevent CPU rollover to 0

Share this post


Link to post
Share on other sites

Hmm I just saw that if the JMP or a JSR opcode was at FFF6 or FFF7 (F7F6 orF7F7 when the button is pressed the CPU will probably crash :x

Share this post


Link to post
Share on other sites

If only there was a real reset line to the cart port. :/ Then you could do a forced reset of the CPU so it'd clear out any instruction and restart from the begining of the code.

Share this post


Link to post
Share on other sites
If only there was a real reset line to the cart port.

 

But unfortunately there is none. You could add one to the Atari though.

 

I think the possibility for a crash is very small. I think I can bring down the odds even furter by using some different code.

Share this post


Link to post
Share on other sites
All that is needed is a push button and the 1st 2K bank.

1st 2K bank in 2K mode and 1st 4K bank in 4K mode, right ?

 

The button will reset the latches so bank 0 is selected (in 2K mode).

Should also work in 4K mode, shouldn't it ? You just have to fill 4K in 4K mode ... and put the menu in the second 4K bank .....

 

The CPU is then going to execute the code in bank 0.

Until it reaches the instruction that switches to the menu bank, right ?

(which is LDA $0801)

 

To prevent the CPU from a crash, bank 0 is filled with one single byte instruction including the CPU vectors.

The vectors have to point to your LDA $0801, where you switch to the menu code, right ?

 

The single byte instruction opcode in bank 0 must have bit 4 set so the vectors wil jump to a rom location where the instructions are executed to reach the LDA instruction.

Ok, I see. You want to get 1,3,5,7,9,B,D,or F as the high byte of a jump. But would't that mean that Bit 0 has to be set ? Or am I missing something ....Wouldn't be funny if your jump target would be a ram adress or not adressing the rom ....

 

What about indirect jumps ? Can you prevent indirect jumps to jump to ram ? Maybe only if the RAM location wich has the same address as the value of your opcode and the adress after contained a valid jump vector....Any ideas how to handle this ?

 

I think the possibility for a crash is very small. I think I can bring down the odds even furter by using some different code

 

Keep us informed. Even if it is not 100% safe, it may still work in most of the cases or fail only once per year :D .

Share this post


Link to post
Share on other sites

Quote:  

The single byte instruction opcode in bank 0 must have bit 4 set so the vectors wil jump to a rom location where the instructions are executed to reach the LDA instruction.  

 

Ok, I see. You want to get 1,3,5,7,9,B,D,or F as the high byte of a jump. But would't that mean that Bit 0 has to be set ? Or am I missing something ....Wouldn't be funny if your jump target would be a ram adress or not adressing the rom ....  

 

Damn, you are right of course its bit 4 :-) i was just a bit confused ...

Share this post


Link to post
Share on other sites
If only there was a real reset line to the cart port.

But unfortunately there is none. You could add one to the Atari though.

Which doesn't do any good. Because the cartridge bank switching won't get reset. I had even wired up one to my 7800 before I realized this wouldn't work with the CC2.

Share this post


Link to post
Share on other sites
I wish I could edit my posts ....

Me too.

 

You could add one to the Atari though.

Which doesn't do any good. Because the cartridge bank switching won't get reset.

Yeah you're right I did'nt think it through well

 

Right.

 

What about indirect jumps ?

Can you prevent indirect jumps to jump to ram ?

Maybe only if the RAM location wich has the same address as the value of your opcode and the adress after contained a valid jump vector....Any ideas how to handle this ?

 

JMP JMP() JSR are all the same.

 

I wish I could edit my posts ....

Me too.

 

Which doesn't do any good. Because the cartridge bank switching won't get reset.

Yeah you're right I did'nt think that through well

Share this post


Link to post
Share on other sites
JMP JMP() JSR are all the same.

 

jmp $D8D8 jumps to $D8D8

jmp ($D8D8) jumps to $D8D8 (if you have $D8 in every cell)

 

so the only problem would be if you get rubbish in case you switch, while the cpu is fetching the highbyte of the target, right ?

 

But that is actually VERY unlikely ....

 

Do you think it could be a good idea to watch databus bit 4

and prevent the menu switch, when it is not set ?

Share this post


Link to post
Share on other sites
so the only problem would be if you get rubbish in case you switch, while the cpu is fetching the highbyte of the target, right ?

The high byte with bit 4 reset.

 

But that is actually VERY unlikely ....

 

Yes indeed. VERY unlikely.

 

Do you think it could be a good idea to watch databus bit 4

and prevent the menu switch, when it is not set ?

 

then its to late already because the JMP opcode and LSB are already fetched.

 

Using A12 or A10 could be used so the button would only work when a TIA/RIOT address or rom address below 1K is accessed. But I can't just hook the button to it and the latch reset because of the reset RC delay. So another chip would be needed which isn't worth it.

Share this post


Link to post
Share on other sites

Maybe I'm not understanding you. On my multipacs I hook the reset on the 273 to the reset line of the cpu and then to a button. I didn't worry about it in this case since just toggling the power switch works.

 

This design is pretty much like mine. I had some occasional glitches in the banking and ended up changing mine to a write instead of a read.

 

IIRC I'm using similar addresses but only the lower half x00-x7f. Mine has 16 bits of registers to handle different bank switching schemes. I'm using a xilinx cpld for the logic. I have 2 ttl chips to try get the timing right on the banking and the ram chip.

 

Mine looks kind of like this one.

http://cgi.ebay.com/ws/eBayISAPI.dll?ViewI...item=8131178262

Share this post


Link to post
Share on other sites
Maybe I'm not understanding you.  On my multipacs I hook the reset on the 273 to the reset line of the cpu and then to a button.

 

My cart design is for the 2600 which does not have a reset line on the cart connector.

 

 I didn't worry about it in this case since just toggling the power switch works.

 

It works, But those powerswitches will have a shorter live span with a lot of toggling. Having only JRs with poor powerswitches. I like the idea of a button on the cart.

 

This design is pretty much like mine.  I had some occasional glitches in the  banking and ended up changing mine to a write instead of a read.

 

I find reading easier, maybe because I'm using no PLDs. Reading does have the advantage of having more addresslines available for the latches.

 

IIRC I'm using similar addresses but only the lower half x00-x7f.  Mine has 16 bits of registers to handle different bank switching schemes.  I'm using a xilinx cpld for the logic.  I have 2 ttl chips to try get the timing right on the banking and the ram chip.

 

Nice. How are you addressing the 16 bits registers? multiplexing ? I noticed (having a look at that auction) that there is a SARA superchip

do you use part of its bankswitching logic or only with the PLD ?

Share this post


Link to post
Share on other sites

I was refering to the mentioned possibility of adding a line to the cpu.

 

 

It's probably because of the cpld but I was getting occasional spurious bank switches. I ended up making a seperate lock register, that required 7 bits to be written correctly before it would unlock. That helped but it still occasionaly unlocked and banked during the menu. That's when I changed it to a write, now if the data bits aren't correct I ignore any writes. This is the first project I did with cpld's and it was very annoying in that the timing is different, things just don't work the same.

 

 

There's actually 4 different registers of varing sizes up to 8. Origianlly 4xx was 1 register, 5xx another etc. When I changed to write I had to alter that slightly.

 

It's just a standard 2k ram. It works reasonably well for most people. I'd say around 80-90% The timing on the write line is a problem. Adding a buffer to the lowest 8 address bits helped a lot. But it really needs a much shorter pulse to work on every machine.

 

If I were to continue development I would probably work on that first. Also I've connected the required lines for 3f and pb banking, it just needs to be coded. I say "just" like it'd be easy, but I'm assuming there'd be timing problems there too.

 

BTW, I can do your boards for ~$6 but I'd have to order 50. If you just want a prototype I can probably work it into the next panel I'm doing for a reasonable cost. If you start adding features though you might want to look at cpld's, they aren't that much more.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...