polpo / picogus

Emulation of ISA sound cards on Raspberry Pi Pico (GUS, SB/Adlib, MPU-401, Tandy, CMS) with USB mouse/joystick support
GNU General Public License v2.0
551 stars 40 forks source link

Combine all different firmwares in FLASH #39

Closed jeroentaverne closed 2 months ago

jeroentaverne commented 5 months ago

Hi! I like your project! I noticed you have multiple firmware's which need to be reflashed to select the functionality. I have done some coding on the Pi Pico myself, and I made a tool to combine multiple firmware .bin files into one .uf2 file. A small "bootloader" will jump to the requested firmware. This way reprogramming to change functionality isn't needed anymore. If you are interested I can share some code parts with you.

polpo commented 5 months ago

Hi, being able to do that would be amazing. If you have any code examples I'd be very interested!

jeroentaverne commented 5 months ago

Ok, I will create a demo project and put in on public GIT and give you the link.

jeroentaverne commented 5 months ago

Here it is: https://github.com/jeroentaverne/pico_multi_firmware I did not add too many instructions. Let me know if you have any questions. :-)

smymm commented 5 months ago

Hi!

Amazing job, @jeroentaverne

I did a quick-and-dirty mix of your work and polpo's code and got a working multi-firmware picogus (6 firmwares) and modified pgusinit to manage it. Only did quick test with the sb, gus and cms modes, but it seems to be working well. If you want to test, here is the uf2 and pgusinit.exe:

PicoGus-multifw.zip EDIT: Don't use this file, better use the new corrected file picogus-multifw-1.2.5.zip I uploaded in my last comment: https://github.com/polpo/picogus/issues/39#issuecomment-2075821209

The pg-multi.uf2 must be flashed via USB to the pico (it doesn't seem to work with pgusinit built-in flasher). EDIT: better use the new corrected file I uploaded in my last comment. The flashing with pgusinit is fixed there.

Once flashed, to change between modes (firmwares), use:

pgusinit.exe /r x 

where x is the number of the firmware to boot (0=gus, 1=sb, 2=mpu, 3=tandy, 4=cms, 5=joy)

On cold boot, the default firmware is always GUS.

If I get some time I'll upload the (ugly) code changes somewhere.

jeroentaverne commented 5 months ago

I do not own a picogus yet to try it. I will order a few soon. :-)

jfharden commented 5 months ago

Hey @smymm I tried writing your firmware to my picogus (the v2.0 hardware) via USB but it fails to write, after copying the uf2 file over the statuslight on the picogus continually flashes and then when it's in the system pgusinit always just says picogus not found. If there's anything I can do to help debug let me know.

This is such a fantastic feature for a fantastic card

polpo commented 5 months ago

@smymm that's amazing! I'd love to see your code, even if it's ugly. I love ugly code! 😄 I definitely see this being the future of changing modes for PicoGUS.

@jfharden if the status light continually flashes, that could mean there's an issue reading the chip's PSRAM. I wonder what could cause that on this particular firmware...

smymm commented 5 months ago

Hi!

I made some changes and attached new files (uf2 and pgusinit) here:

picogus-multifw-1.2.5.zip

Now flashing pg-multi.uf2 using pgusinit.exe is working. As the size is much bigger, time needed for flash erase has to be bigger too.

@polpo, @jeroentaverne

I zipped the code changes (only the added and modified files!! not the whole project!) and attached here:

picogus-multifw-1.2.5-code-differences.zip

I think I didn't miss any file, but let me know if something is not there. As you can see, it's very simple, all merit is for you two. I just merged both codes with some necessary changes for it to work, and added code to make it useful.

@jfharden,

Check with the new file, and also try with pgusinit flash, now that it works.

I only tested this with a v1.1 board and everything is working here, so if someone could test on other board versions and confirm, that would be great.

Note for @polpo:

I think it would be even better if something could be done to select permanent selection of a firmware at cold-boot (first boot). "Scratch" section used for the mode change is lost when powered off. Maybe some reserved zone in the flash for the # of firmware user wants to boot first could be a good idea.

jeroentaverne commented 5 months ago

Perhaps generic code like firmware flashing and mode selection by pgusinit can be moved to bootloader.c. Firmware sections can be made smaller and firmware flashing quicker.

jfharden commented 5 months ago

@smymm I just tried flashing multifw-1.2.5 via usb and it worked!

I tried it out (my setup is a little unusual, it's an Amiga 2000 with an A2286 bridgeboard inside (think of it as a 286 PC on a card, but the amiga 2000 mainboard has some ISA slots which can only be used by the bridgeboard, not the amiga)) and it works fantastic! Playing modfiles in gus mode worked a charm, switching to the soundblaster firmware using pgusinit /r 1 worked, and then I played modfiles in soundblaster output, and ran planet x3 using adlib which played fine through the soundblaster firmware too.

Incredible stuff!

I can't test flashing the firmware from DOS unfortunately since that already isn't working on the original 1.2.0 firmware. This specific limitation I have is actually what made me very excited about this work since it fixes my inability to change modes without removing the picogus from the Amiga! Thank you!

smymm commented 5 months ago

@jeroentaverne

About build.sh , it's not needed. Everything is now merged into /sw/release/create_release.sh , it builds the firmwares, the tools you provided and the merge of the firmwares, ...

About code in bootloader. I think it's not great to boot to bootloader and stay there until pgusinit does something. It's important to have a working card working in x mode at boot (gus or whatever) without any program required, asi it is now. That way you can use, for example, an original game that boots from floppy disk and run it with a sound card in an already-working state.

@jfharden,

Hey! great news!! :D Thank you for testing!!

jeroentaverne commented 5 months ago

I thought pgusinit was always required to setup something. But good to know this is not needed. Using the last sector of flash for mode selection and perhaps IO address setting would be great. I would even suggest to use multiple sectors as some kind of wear leveling.

jeroentaverne commented 5 months ago

I have an update on https://github.com/jeroentaverne/pico_multi_firmware The .ld files are now all smaller

smymm commented 5 months ago

Yay! Permanent mode for the multifirmware... Finally got it to work, using one page at the end of a standard pico flash (2MB) to store the setting.

I also made other changes and proper code for the firmware mode change implementation in control register area.

Here is the new uf2 (flash it as usual with pgusinit /f pg-multi.uf2 or via USB), and the new pgusinit.exe:

picogus-multifw-1.2.6.zip

New usage for this version:

    pgusinit   /m x [d]  - change card mode to x (1=gus,2=sb,3=mpu,4=tandy,5=cms,6=joy)
               the optional parameter 'd' makes the mode permanent at boot
               (Only if pg-multi.uf2 is flashed)

Examples of use:

pgusinit /m 2

pgusinit /m 2 d

This way, there is no need to take care of SPI flash wear, because the permanent change would be done only a few times (maybe only one, depending on your preferences)

I tested and it worked very well on my system. Please, test if you can and report :)

I plan to upload the modified sources for this new features very soon. I will try to get used to git (I'm new to it) and fork the project and submit the changes (maybe as a pull request, or what would be the best way..?) EDIT: I created a fork and sent a pull request with the code modifications. It's my first time with git, I hope it's well done. If not, please let me know, thanks! :)

@polpo @jeroentaverne

jeroentaverne commented 5 months ago

Great! What will pgusinit /m 0 do? Other request: Can someone in the EU please supply me with a PicoGUS?

smymm commented 5 months ago

Finally I created the fork and sent the pull request with the modified code. It's my first time with git/github, so I hope erverything is well done.

I uploded the compiled release to my fork, too: https://github.com/smymm/picogus/releases/tag/Multifw

Thanks to everyone here! and sorry for my newbie code!

@jeroentaverne /m 0 does nothing.

skadarnold commented 5 months ago

I just tested this on a v1.2 card, flashed with supplied pgusinit straight from DOS and I can confirm this is working. Switching modes on the fly working in games without reboot.

jfharden commented 5 months ago

I just tested this (the multifw-1.2.6) on a PicoGUS 2.0 (in an Amiga 2000 being used by the A2286 bridgeboard) and it worked great.

I tried using modmxt playing some mod files in both Sound Blaster and GUS mode, I also tried Planet X3 using adlib sound on the sound blaster mode. Finally I tested that the mode survives reboot which worked like a charm.

skadarnold commented 5 months ago

GUS could use an auto initialize after switching modes (and maybe others I haven't tested). That way it saves having to run pgusinit again to initialize or else it won't work.

jeroentaverne commented 5 months ago

Nice! A few small comments: Delay between erase and programming is not needed. Erase will block anyway. Perhaps keep the indents in the code the same. The FLASH sector might also be used to contain IO addresses for all modes. Then complete auto config can be implemented.

polpo commented 5 months ago

The delay(500); between erase and programming is usually not needed. I inserted it to account for erase time on old firmwares using the pgusinit protocol v1 on chipsets that do not tolerate IOCHRDY being held low for too long and release the bus before the operation is complete. It's been a while since firmwares with the v1 protocol have been current... I might take this backwards-compatible flash operation out eventually especially since I'll probably make a protocol v3 to handle storing pgusinit settings permanently in flash.

polpo commented 2 months ago

This has now been released in Firmware v2.0.0. Thank you very much @jeroentaverne and @smymm! This really makes PicoGUS be even more flexible.