Jump to content
IGNORED

A8PicoCart - UnoCart on a Raspberry Pi Pico


Recommended Posts

Thanks, Robin, for the fine work on this project. I jumped on the project as soon as I saw it, and I have four carts for my efforts. One of the five pico boards received would not take the firmware. I think the bootsel button was not working, but given the investment, I did not spend much time on it. Now to print some carts and get a couple of these in the mail:)

 

Mike

 

Update: After some thought and being stubborn, I revisited that non-cooperative pico board. I was looking at my work but did not look at the board itself. I found a solder bridge on the flash memory chip, ever so small, but a bridge. Once fixed, the board accepted the firmware, and it's good to go.

 

 

0202241605-2.thumb.jpg.6251605e8de34c7da1018301ea32a98b.jpg

  • Like 2
Link to comment
Share on other sites

This new version brings support for reading a ROM from a8picocart at startup in case you need to change something to not use the default menu.

 

You just need to add an 8k file to the root called A8PICOCART .ROM and it will load if the one in the firmware does not appear.

 

Attached is the new firmware and an example of the modified menu with the green background to make a difference.

a8_pico_cart.uf2A8PICOCART.ROM

  • Like 4
  • Thanks 2
Link to comment
Share on other sites

  • 3 weeks later...

First of all - New to this and  i think this project and development has been excellent. Kudos to Electrotrains for this!

 

Ive made a few units with 3D printed shells(and i only need one). Being less than a couple of quid from Ali for the Pico boards and PCB's being less than a fiver from China makes this probably the best bang-for-buck ive seen for A8 modding.

 

 

Ive a couple of questions

 

1. Files are only permissable up 128k, is there a way to go above this? (Space harrier and larger files im thinking of...)

 

2. How is development for the 2600 comming along? (my own wish would be the 7800 version ultimately myself - being a fanboy of this model also ).

 

 

Great work also from all others on this thread who contribute to the development of this also

 

 

Edited by Magic Knight
Link to comment
Share on other sites

1 hour ago, Magic Knight said:

1. Files are only permissable up 128k, is there a way to go above this? (Space harrier and larger files im thinking of...)

Lack of RAM, the Raspberry Pi Pico includes 256KB of RAM. 😉


There are ways to automate it, but it would not be a simple cartridge to put together and the cost would go up.

Link to comment
Share on other sites

12 minutes ago, ascrnet said:

Lack of RAM, the Raspberry Pi Pico includes 256KB of RAM. 😉


There are ways to automate it, but it would not be a simple cartridge to put together and the cost would go up.

Thanks for the quick answer, i'm bit confused, i always thought of the PICO as a storage device (16mb of flash bit etc)  that the ATARI just loads in to it own ram?

 

Am i right in that the PICO needs to populate the ram storage with the file as part of its transfer/call-up of the file (so for example a 512k file has to go through the PICO'S ram prior?  

 

or somehting like that?

 

 

Link to comment
Share on other sites

2 hours ago, Magic Knight said:

Thanks for the quick answer, i'm bit confused, i always thought of the PICO as a storage device (16mb of flash bit etc)  that the ATARI just loads in to it own ram?

 

Am i right in that the PICO needs to populate the ram storage with the file as part of its transfer/call-up of the file (so for example a 512k file has to go through the PICO'S ram prior?  

 

or somehting like that?

 

 

First remember that it is a microcontroller that has RAM and storage space.

 

Second the order at high level would be: read the stored file and load it to the RAM and from here it will be sent to the pins. Note in the RAM is not only the read but also the executed firmware.

Link to comment
Share on other sites

2 hours ago, ascrnet said:

Second the order at high level would be: read the stored file and load it to the RAM and from here it will be sent to the pins. Note in the RAM is not only the read but also the executed firmware.

I was actually playing with writing my own firmware for the Pico cart, where I hit the wall was when I tried to emulate the cart directly from the flash memory (essentially a one preloaded cart emulator rather than a multicart), this did not work, even though the program was perfectly valid from the C standpoint. Copying the stuff to RAM with one call to memcpy directly solved the problem, yet I still do not know why...

 

(I have also tripped over one more problem, but that one is too elaborate to bore the public with, solved with a workaround, but the essence of the issue is still a mystery...)

Link to comment
Share on other sites

24 minutes ago, woj said:

I was actually playing with writing my own firmware for the Pico cart, where I hit the wall was when I tried to emulate the cart directly from the flash memory (essentially a one preloaded cart emulator rather than a multicart), this did not work, even though the program was perfectly valid from the C standpoint. Copying the stuff to RAM with one call to memcpy directly solved the problem, yet I still do not know why...

There are two reasons that happened to me when I made the firmware change at runtime.😅

  • Reading in the wrong place in the code.
  • Not identifying well the type of cartridge and the type of banking it uses.
Link to comment
Share on other sites

10 hours ago, Wrathchild said:

Happy to take a look at this and the workaround, is history on github?

No need, found the problem now, I based my development on the AtariMax emulation cart, those react both to read and writes in the CCTL area and data is never used / read / treated / whatever, any access triggers the corresponding action associated with the address. I wanted to have actual data passed and only support writes to gather a small array of scores data, which in principle was a simple change, but I missed that CCTL_GPIO_MASK should be CCTL_RW_GPIO_MASK to filter out reads, without which I was getting some floating bits from the bus (or at least this is my interpretation of the symptoms I was getting). In any case, this did the trick.

 

The inability to work directly with a const uint8_t data[SIZE] array (both with __in_flash and without it) for passing on the data to the cart from it is still a mystery though. I have to declare a separate non-const array and copy the data to it first.  

Link to comment
Share on other sites

1 hour ago, woj said:

The inability to work directly with a const uint8_t data[SIZE] array (both with __in_flash and without it) for passing on the data to the cart from it is still a mystery though. I have to declare a separate non-const array and copy the data to it first.  

Why don't you use the existing one that is a global variable? Or do you want to use a larger dimension? There is a limit to emulate only 128k cartridges. cartridges. 😉

 

 

Link to comment
Share on other sites

15 hours ago, woj said:

The inability to work directly with a const uint8_t data[SIZE] array (both with __in_flash and without it) for passing on the data to the cart from it is still a mystery though. I have to declare a separate non-const array and copy the data to it first.  

Sorry been away for a few weeks - just catching up.

 

I think the on-board SPI flash is too slow to provide random access for the Atari. Hence ROMs must be copied to RAM first, and therefore a limit on the size of emulated cart to 128k.

 

I did a few experiments but never got it running from flash. Its possible there is some other approach that might make it work, but I haven't found it.

 

Robin

Edited by electrotrains
  • Thanks 2
Link to comment
Share on other sites

meh, you wouldn't want to use up all the flash cycles on full cart rom data etc all the time anyway, ram is best. Let flash use and wear leveling be spread out over time for smaller things like score saves/firmware and the cart will be happy much longer anyway.

Edited by _The Doctor__
Link to comment
Share on other sites

1 hour ago, electrotrains said:

I think the on-board SPI flash is too slow to provide random access for the Atari. Hence ROMs must be copied to RAM first

I had this crazy idea to use pipico RAM as a cache for cart banks. 

so cart manager populates RAM with banks that will be used now and _soon_ and then in the second thread replaces the unused with new ones. 

which banks to replace? which load next? I do not know... possibly a generous dose of gameplay would help create some timeline for banks to be copied to RAM.

As far as I can see it'd work for space harrier, but it is conceivable to create a cart that would fail miserably, e.g. by reading a single byte, switching to another bank, reading the next byte, and so on. pipico would be unable to keep up with copying banks, I reckon.

  • Like 1
Link to comment
Share on other sites

2 hours ago, electrotrains said:

I think the on-board SPI flash is too slow to provide random access for the Atari. Hence ROMs must be copied to RAM first, and therefore a limit on the size of emulated cart to 128k.

 

I did a few experiments but never got it running from flash. Its possible there is some other approach that might make it work, but I haven't found it.

 

I was getting worried that my C knowledge and pointer juggling has a flaw in it, but this explains everything and now makes perfect sense. (In fact, I suspected something of this sort, but from the blank behaviour on the Atari side I could not really confirm anything.)

 

1 hour ago, _The Doctor__ said:

meh, you wouldn't want to use up all the flash cycles on full cart rom data etc all the time anyway, ram is best. Let flash use and wear leveling be spread out over time for smaller things like score saves/firmware and the cart will be happy much longer anyway.

Doesn't flash wear out "excessively" only during erase/write cycles? That I do seldom actually, exactly only for score updating.

Link to comment
Share on other sites

25 minutes ago, pirx said:

I had this crazy idea to use pipico RAM as a cache for cart banks. 

so cart manager populates RAM with banks that will be used now and _soon_ and then in the second thread replaces the unused with new ones. 

which banks to replace? which load next? I do not know... possibly a generous dose of gameplay would help create some timeline for banks to be copied to RAM.

As far as I can see it'd work for space harrier, but it is conceivable to create a cart that would fail miserably, e.g. by reading a single byte, switching to another bank, reading the next byte, and so on. pipico would be unable to keep up with copying banks, I reckon.

Yeah, the same idea had crossed my mind, and I ruled it out as impractical 🙂

However, if the game had been coded with the architecture in mind, you could make a VERY big bankswitching cart using the pico.

 

Robin

  • Like 1
Link to comment
Share on other sites

So I have one more small problem. Trying to make the story short, I have my own Pico code that essentially emulates just one cart, for the sake of discussion let's say it is AtariMax 1Mbit emulation (not exactly, but close enough, perhaps this "not exactly" is the problem...), all with minimal code and no electrotrains multicart code on it whatsoever, so no file uploading support, nothing of this sort, just main calling emulate_atarimax_128kb with the cart image directly coded in. All this works fine standalone. What does not work is U1MB SDX waking this complete cart emulation by saying CAR. When I start SDX with the original AtariMax plugged in, I can say CAR, SDX does some magic to activate the cart, and it starts. When I plug the Pico Cart with this one cart fixed emulation, saying CAR results in "Not present!". I remember @flashjazzcat saying something that SDX is doing its magic by "pulling CCTL lines directly", but I am not sure what it means, and I think that whatever this is, my emulation on Pico should account for that. I tired debugging what CAR does in Altirra, but I can only see that it does some writing to D500 and D518 (?), both of which my emulation does react correctly to...

 

EDIT: Right, I still do not have a confident answer to this, but I suspect that the SDX has internal circuitry to control the external cartridge and that's what Jon meant. My wild guess (that I will not test today anymore) is that I either need to have a read on the particular pins in the Pico code to see if there is an external attempt to re-enable the cart (which pins then?), or try to monitor / react to writes to $D5E0 and activate banking when there is $80 written there. On the right track?

Edited by woj
Link to comment
Share on other sites

I ran into the flash timing problems when doing video output experiments with a Pico, worked great until the framebuffer was bigger than 16K and then it blew up, until I moved the buffers to RAM. Apparently people have managed to get just-in-time flash access to work for this kind of scenario, but they have to overclock the heck out of the RP2040 and flash (266MHz/133MHz) and disable the XIP cache to get byte read commands through as fast as possible.

 

(For those who don't know, the Pico uses a serial flash with a 16K, two-way set associative execute-in-place (XIP) cache in front of it. Works great most of the time, but if you miss the cache it is sloooowwwww.)

 

  • Like 3
Link to comment
Share on other sites

Uff, so the whole inability to start the emulated cart with "CAR" from SDX had nothing to do with handling the cartridge lines (I actually got to the point of hooking up the oscilloscope to see what is happening on the lines when I try to say "CAR"). This was all with my own Pico program emulating one single cart. In desperation I uploaded the original A8PicoCart firmware - this one worked fine! Both the multicart menu and with a started emulated AtariMax cart... The weirdness began - very long (still unfinished) story short - my emulated cart works with the "CAR" command depending on the order of code I have in my Pico C program and the dependencies that are pulled in (mostly stuff for internally flashing the score data). Unfortunately, with all the dependencies and code I need it still does not work, but when I comment out a call to the score flashing function (that I never used during these tests) it suddenly starts to work. At the same time, I get regular problems with the cart starting up at boot for the first time after new firmware download, with or without CAR working with SDX. So far I have no clue what it is, my money at the moment is on some weird memory mapping / timing issue / internal fw flash to ram copying of code that I cannot see (I also tried both normal speed and overclocked, this does not seem to change anything). This might also have something to do with my superficial understanding of the Pico, the original A8PicoCart firmware works fine in this respect, and it uses much more memory of both kinds than my simple program... WTF!

 

EDIT: I will leave it here for your entertainment and my public embarrassment. This is probably 4th or so time when writing about my problem allowed me to see the problem through. It was of course a bug, the code that was calling the score flashing was also intercepting $D5Ex writes of SDX and triggering score flashing that was locking down the whole cart (so yes, it was a timing problem in fact). FFS. It seems that for the same reason it was having problems starting off so often. But I am now too tired to be 100% certain about all this, I will review everything tomorrow.

Edited by woj
  • Like 2
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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