Adding instructions to the sound thing should not be causing video corruption wtf.
Need to check that later, currently phoneposting on a tram amd i'll get sick if i stare at the phone.
Ok, I will check later. The audio did make video worse (maybe power noise effect again on video, but this time the whole scanline glitches, more like software timing error).
Can you post what timing values you have right now? Will check them at home.
(Wow I'm queasy even now. The tram lines here are really violent, they take hills and 90° turns at full speed like they're nothing and I'm prone to handheld-screen-in-moving-vehicle-related motion sickness)
Not sure which timing you wanted exactly, but ok
For PSRAM:
' For PSRAM (either type)
PSRAM_CLK = 56
PSRAM_SELECT = 57
PSRAM_BASE = 40
PSRAM_BANKS = 4 ' Only used to stop further banks from interfering
PSRAM_WAIT = 5
PSRAM_DELAY = 16
PSRAM_SYNC_CLOCK = false
PSRAM_SYNC_DATA = true
' Uncomment for slower memory clock
#define USE_PSRAM_SLOW
For video timing it's:
timing_lcd24_640x480
long VIDEO_CLKFREQ ' CLKFREQ
long 2 ' active line multiplier
long 10 ' V front porch
long 32 ' V sync
long 2 ' V back porch
long 64 ' extra pillar
long 640 ' blank line
long 14 ' H front porch
long 8 ' H sync
long 20 ' H back porch
long $08000000 ' Sync NCO
long $08000000 ' Pixel NCO
long 0 ' Alt-res NCO
long 16 + (16>>1)<<16 ' pixel clock pulses
long 1
For audio sample timing it's this:
DSP_SAMPLE_RATE = 32_000
DAC_SCALE = $FF00
DAC_CENTER = $8000 'DAC_SCALE/2
DAC_SCAS = $4000 'DAC_SCALE/4
dsp_dosample
' Output last sample to DAC, then compute next one
mov pa,dsp_daccenter
scas dsp_lsample,dsp_dacscas
setword pa,0-0, #1
mov pb,dsp_daccenter
scas dsp_rsample,dsp_dacscas
setword pb,0-0, #1
bitnot pa, #31
bitnot pb, #31
wypin pa,dsp_lpin
wypin pb,dsp_rpin
' setword pa,dsp_lsample,#0
' setword pa,dsp_rsample,#1
' cmps dsp_dpin,#0 wc
nop
' if_nc wxpin pa,dsp_dpin
addct1 audio_timestamp, ##_CLKFREQ/DSP_SAMPLE_RATE
dsp_run_ptch jmp #\dsp_run
.no_spcload
}
' setup pins (MEGA TODO FOR TIMING)
' Use PWM mode despite non-multiple-of-256 period
' It's just better.
wrpin ##P_NCO_DUTY|P_OE,dsp_lpin
wrpin ##P_NCO_DUTY|P_OE,dsp_rpin
wxpin #20,dsp_lpin
wxpin #20,dsp_rpin
wypin ##$8000_0000,dsp_lpin
wypin ##$8000_0000,dsp_rpin
drvl dsp_lpin
drvl dsp_rpin
' Setup event on left pin ready
mov pa,#%001_000000
add pa,dsp_lpin
setse1 pa
getct audio_timestamp
addct1 audio_timestamp, ##_CLKFREQ/DSP_SAMPLE_RATE
jmp #\sp_nextop '' GO!
Video glitches now seem fixed once I did this change below with an added waitx #15 to phase adjust the clock edge (so it may not be audio related, although it seemed to make a difference before):
' setup CLK pin (abuse breezeway entry)
debug(ubin_long(dira,dirb,outa,outb))
setcfrq nco_sync
getbyte pb,extravpins,#0
drvl pb
wypin bit31,pb
waitx #15 '****--- experimental waitx to sync clock
xinit ##$fffc,blank_color ' enter dummy command to ensure it stays in sync
waitx #511
jmp #video_entry
Thought you might think that but no, that was already done below. For a 16 clock pixel period waitx #15 is effectively like a "waitx -1" (which is not possible). So in this case the pixel clock is better one P2 clock earlier for the data to be read reliably. What is strange is that it's such a narrow window of good phases. For only ~20MHz clocking I'd expect far wider eye for good clocking. Maybe there's a lot of signal bouncing going on before things stabilize for all the parallel RGB data bits to be clocked - need to probe colour pins.
I realized I should try to dig up my old P2 tablet (800x480 res) and try to run this LCD test code too with necessary tweaks. It also uses a parallel 24 bit LCD interface but I'm not sure which P2 pins I ended up putting the sync's on though - might have been why I generated PWM outputs for Hsync/DE signals. That system has a 4 bit PSRAM so might be able to run something too. It does also have a VGA output and a USB host port.
Try a game with HiRes modes (Trials of Mana uses Mode 5 heavily - check if the text is readable. Make sure you have the newer ~6MB collection ROM or the japenese original - the older ~4MB english patch versions don't actually have hires fonts)
Just tested that and the hi-res text line is clear and readable and looks good. 👍 MisoYume seems pretty good, tried a bunch of things and some games fail to start up but I think that is to be expected. In general I think this is pretty decent on and sounds great too, especially on headphones. I went back to setting #5 for the WXPIN param and video is still okay with that other waitx change I made earlier.
Tried MegaYume, for some strange reason there are a lot of blank lines at the top of the menu pushing it down (maybe by design) and they are also seen in games. This seems weird as I only have 2 back porch lines in the timing so it should be able to start earlier on the screen. Here's some pics of that.
timing_lcd24_640x480
long VIDEO_CLKFREQ ' CLKFREQ
long 2 ' active line multiplier
long 10 ' V front porch
long 32 ' V sync
long 2 ' V back porch
long 0 ' extra pillar
long 640 ' blank line
long 16 ' H front porch
long 8 ' H sync
long 20 ' H back porch
long $0888888A ' Sync NCO
long $0888888A>>1 ' Pixel NCO
long 0 ' Alt-res NCO
long 15 + (15>>1)<<16 ' pixel clock pulses
long 1
I also needed to do a waitx #14 to get a decent image with the clock pin also inverted. Based on this and the other emulators I think we probably need a custom phase delay parameter in config.spin that people could tweak to do this waitx #phase_delay whenever it's set to non-negative values for example - like your other pin settings etc.
' setup CLK pin (abuse breezeway entry)
debug(ubin_long(dira,dirb,outa,outb))
setcfrq nco_sync
getbyte pb,extravpins,#0
drvl pb
wypin bit31,pb
waitx #14 '##### ----- needed this to get stable video output
xinit ##$fffc,blank_color ' enter dummy command to ensure it stays in sync
waitx #511
jmp #video_entry
@Wuerfel_21 said:
Yeah that shouldn't be that far down
Something seemed a little different there when you render your horizontal lines vs other emulators (start or end of sync difference perhaps?). But I fixed it just now with this timing (your original default values are shown commented out).
I also just got audio working too on MegaYume now so I'm quite happy about that too. All three of your main P2 game system emulators pretty much appear to work ok now on this system.
timing_lcd24_640x480
long VIDEO_CLKFREQ ' CLKFREQ
long 2 ' active line multiplier
long 41 '10 ' V front porch
long 1 '32 ' V sync
long 2 ' V back porch
...
I think I added controller support at some point? Reply hazy.
Is quite certainly behind on USBnew versions, so maybe cop the latest one from somewhere else.
@Wuerfel_21 said:
I think I added controller support at some point? Reply hazy.
Is quite certainly behind on USBnew versions, so maybe cop the latest one from somewhere else.
Ok. Plus I already have a hard coded p2videodrv file that could work instead of the existing one.
Seems the audio for this game runs from an ISR triggered off the DAC ready event. Will need to make that a timer based one now, that's the trickiest part to modify plus I'm not too familiar with how sca/scas work so I tend to hack about with modifying various DAC offsets etc until I get something sort of running in P_NCO_DUTY mode.
Getting a build error - regarding FAT32 stuff: (I took the latest code from your mega.nz link today). Does something else need special configuration somewhere?
EDIT: okay using Flexspin 7.5.0 fixed it.
❯ !.
./build.sh
Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2025 Total Spectrum Software Inc. and contributors
Version 7.0.0 Compiled on: Jan 16 2025
hexagon.spin
|-platform.spin
|-|-p2videodrv.spin2
|-VJET_p2beta_rendering.spin2
|-p2videodrv.spin2
|-usbnew.spin2
|-padmap_parser.spin2
|-SimpleSerial.spin
|-VJET_p2beta_displaylist.spin2
|-hexfont.spin2
|-hexagon_sdda.spin2
|-|-FAT32.spin2
|-|-|-sdspi_with_audio.spin2
|-|-sdspi_with_audio.spin2
|-|-platform.spin
|-|-jm_nstr.spin2
|-evilfloatmath.c
|-jm_nstr.spin2
hexagon.spin:831: warning: variable clip_angle may be used before it is set in function update
ieee32.c
hexagon.p2asm
hexagon.p2asm:14015: error: Unknown symbol '_FAT32_addressDIREntry'
Done.
Oh yeah - sounds a little distorted but it runs. I might have overdriven the audio a bit, but I can tweak from here. Very difficult game to master. Having a crisp VGA res LCD in this handheld is awesome.
(Also IIRC the SD/sound driver has a bug where it sometimes drops commands, not sure if that still exists, but if it happens, be rest assured it's "normal")
Also I think that's the last weird sound driver, the other ones all use the fine and normal loop structure.
Probably good to collect them all when you're done so I can figure out how to move forward with all that (using a timer is ostensibly better than relying on the DAC buffer, since that'd enable pure HDMI audio without real DAC pins, too)
Yeah it makes sense for me to bundle the changes so you might find a clean way to nicely integrate these different options for some audio/video and pin settings etc.
I've got 4 of your games/emulators essentially running now and can zip them up so you can diff against your branch. However I need to remove the hard coded hack from my own video driver and essentially integrate my own parallel LCD support - I'd already done some of work in that area previously but it needs to be resurrected and completed like HDMI. (That means it may take a while )
Should be easy to get Tempest 2000 and P1CC into the mix, they should just werk ( though t2k has rather interesting build requirements)
(I'm once again busy in other endeavours today, possibly involving black magic and board games, so probably no real-time tech support on those - still haven't had time to pull out the logic analyzer setup for this, either)
Just thinking about a way to put together a starting screen emulator/game menu to try out - it won't necessarily be real pretty but just functional at this time..
I would like to present a group of game emulators in a text or graphics mode screen, and when a game emulator is selected via up/down button then L&R button could choose a game from a scrolling list (or vice versa for buttons) and the Start/primary fire button would run it. Looking through the emulator code bases it would appear that in general when the P2 starts the emulator the code checks for a game name via an ARGV string put up in $FC000... memory. So in my simple brain it would appear we could just load a new 512k flash image saved at some simple flash memory boundary that indexes the emulator, and also pass a game name from SD to $FC000 and it could then run it.
To exit it looks like both Misoyume and Megayume already poll for down+select to restart. However that could be modified to to restart the P2 from flash again (or could reload the flash image into RAM and run again leaving IO pins intact - less brutal). NeoYume doesn't seem to have this done the same way as there is not a SPIN2 COG left running once the game emulator starts up.
Some complications I forsee: SD card re-init issues (esp. after flash startup), audio clicks/pops (could control pins to try to reduce that), and video screen glitches from IO pin changes and PLL restarts - (probably would have to just ignore these minor A/V issues for now). I also already know that some SD cards already have a problem when I reload (serially) after a reset so that sequence probably may need to be improved to make it more robust if possible. A dedicated SD card interface that can shutoff power like my 4 bit SD mode interface does would really be preferable here (and could possible end up as a requirement over the shared Flash/SD card interface design on a standard P2 board).
May try to hack something up to test this concept. Will have to get more familiar with setting up boot flash again - been ages since I did that probably only once before and I know there were programming issues getting it working nicely related to full 512kB image sizes etc.
UPDATE: New loadp2 installed which appear to write the emulator image to flash fine which is great. I think I must have been out of the flexspin loop for too long with respect to the whole image compression thing too. Amazed at how the binary image can be compressed now. Seems like a very useful feature and could help speed up the load time too I'd imagine.
Audio shouldn't click when turning off and when turning on, we can de-click it - though that's assuming DACs, IDK how this weird digital amp thing'll react. Flash boot is also quite fast, so I don't think anything more involved than a regular soft-reset is needed to implement return-to-loader. SD card/flash interaction oddities are likely the #1 problem (solved by SD4 I/F).
Adding return-to-loader / soft-power to NeoYume is probably best done by hijacking the part around here: https://git.sr.ht/~wuerfel_21/NeoYume/tree/master/item/neoyume_lower.spin2#L3678 where it handles generating the vertical blanking interrupt. Normally it'd then go to .scan_done (doing no actual work), but could be detoured to run some other stuff. The SD is only used read-only, so it should always be fine to reset the machine.
Note that the ARGv thing has become integrated into Eric's tooling (I didn't even do that). You can use the -a switch with loadp2 to set arguments when doing serial boot, I think I've explained how to elsewhere.
You can also write a C program with the usual int main(int argc, char **argv) thing and the C runtime will populate that appropriately.
The compression flag works really well for the emulators in particular, because the uncompressed binary is full of alignment padding. That compresses down very well. The actual compression ratio achieved on machine code is somewhat low because it can only really compress repeating sequences >= 4 bytes. It doesn't have any symbol entropy coding. But that's what makes it simple and fast.
Audio shouldn't click when turning off and when turning on, we can de-click it - though that's assuming DACs, IDK how this weird digital amp thing'll react. Flash boot is also quite fast, so I don't think anything more involved than a regular soft-reset is needed to implement return-to-loader. SD card/flash interaction oddities are likely the #1 problem (solved by SD4 I/F).
It mainly creates noise when the output pin floats for a while and the video is enabled (which I think may enable the amp) - noise gets louder over time (seconds). A brief pause may not be so bad, but I'll find out soon. The menu app can probably drive the pin high or low before it runs the emulator and frees the pin.
Adding return-to-loader / soft-power to NeoYume is probably best done by hijacking the part around here: https://git.sr.ht/~wuerfel_21/NeoYume/tree/master/item/neoyume_lower.spin2#L3678 where it handles generating the vertical blanking interrupt. Normally it'd then go to .scan_done (doing no actual work), but could be detoured to run some other stuff. The SD is only used read-only, so it should always be fine to reset the machine.
Thanks for the tips - I'll try to hook something in. A reset is nice and simple so if SD isn't used for NeoYume in game that'll probably work out better that way.
Note that the ARGv thing has become integrated into Eric's tooling (I didn't even do that). You can use the -a switch with loadp2 to set arguments when doing serial boot, I think I've explained how to elsewhere.
You probably did, but I've been out of the loop a bit more than normal on the forums this year due to other things and haven't kept up with a lot of developments.
You can also write a C program with the usual int main(int argc, char **argv) thing and the C runtime will populate that appropriately.
That's cool. Arguments make testing things via CLI interactivity or automation easier, so it's very handy.
The compression flag works really well for the emulators in particular, because the uncompressed binary is full of alignment padding. That compresses down very well. The actual compression ratio achieved on machine code is somewhat low because it can only really compress repeating sequences >= 4 bytes. It doesn't have any symbol entropy coding. But that's what makes it simple and fast.
Very nice. For lots of (reasonably large) blocks in the file that type of decompression method should save some boot time in most cases. Great that it helps the compressible emulators boot faster from flash - I've already tested MisoYume alone from boot and it boots up to the menu almost right after I slide the power on switch - it's really quick! Ultimately it just needs a fancier front end and it'll be a really polished portable device.
@Wuerfel_21
Dumb question: how can I safely start your flexspin emulator image just read in from FLASH and loaded into HUBRAM at address 0 without doing a fresh COG init and messing up the IO pin states? I sort of want to assume control by reloading my existing PASM COG and restarting from 0 (like a software reset instead of hardware reset). Maybe I just jump up into some LUTRAM then do a setq #0 and rdlong burst read of 502 longs into COGRAM address 0 with PTRA, PTRB set to something sane and then jump directly to COGRAM addr 0 to avoid the IO and PLL changes? Can that even work? I guess I'll try it out...
Though there's essentially no way to avoid it doing 2 coginits (lz4stub -> lower boot stub -> upper compiled code) and 2 PLL setups (flexspin defaults to setting 200MHz -> then the video driver changes it again) on its own time. I think the first PLL setup could be skipped by getting flexspin to omit it somehow.
EDIT: seems you can't not emit the code, but if clkfreq (at $14) is not zero it doesn't do it -> 200000 cycles saved? In that case it'd have to be set to something in the lower source though (because that whole area gets rewritten by lz4stub, you can't pre-set it). Probably 25000000 or whatever the nominal RCFAST boot frequency is.
Ok, I think that boot code is similar to what I was going to do, I'll just leave outa/outb and ina alone and see what happens. It's probably not that important what I'm doing, and future COG loads will probably break it, but I was just trying to keep the IO pins managed for longer. Won't make much difference in the end it would seem plus your emulator is gonna change the PLL too from 252MHz - I could just effectively do a coginit(cogid(), 0, 0) or something equivalent to that from PASM2.
Now the proof of concept prototype worked out, progress has begun on the actual P2 FireAnt board and this (unfinished) PCB is intended to fit inside the GPi case 2W cartridge and can contain up to 64MB of PSRAM and a microSD card reader operating in 4 bit SD mode. It will work in conjunction with another small P2 board also under development that sits above it. This way it's easier to make it all fit.
@Wuerfel_21 I've assigned the Port A pins for parallel RGB as before but with the LSByte now modified and holding audio as well (see below). Do we need to keep bit 0 free if the P2 VGA output mode uses it for HSYNC or should we just make use of this for the LCD panel anyway? If bit 0 needs to be kept free for other reasons like your DIGITAL_BASEPIN assignment I can always move things up or rearrange this byte. I should really double check our pixel clock output idea can work on port A for real. I do still have a free pin on port B I could assign it if needed, or I could split the clocks and realize two independent 8 bit PSRAM banks with one chip select and one clock each which can be combined for 16 bit operation because the pairs are adjacent. It might also alleviate the high fanout for the PSRAM clock otherwise going to 8 chips but could cause different timing between banks (which my driver can handle), and the second bank of chips are slightly further away from the P2.
P0 - HSYNC
P1 - VSYNC
P2 - PIXEL_CLK
P3 - DE
P4 - LEFT_PWM
P5 - RIGHT_PWM
P6 - free for now
P7 - free for now
P8, P9 - GPi power and shutdown
P10-P15 - BLUE
P16, P17 - USB D-/D+
P18-P23 - GREEN
P24, P25 - chip selects for PSRAM
P26-P31 - RED
Comments
Adding instructions to the sound thing should not be causing video corruption wtf.
Need to check that later, currently phoneposting on a tram amd i'll get sick if i stare at the phone.
Ok, I will check later. The audio did make video worse (maybe power noise effect again on video, but this time the whole scanline glitches, more like software timing error).
Can you post what timing values you have right now? Will check them at home.
(Wow I'm queasy even now. The tram lines here are really violent, they take hills and 90° turns at full speed like they're nothing and I'm prone to handheld-screen-in-moving-vehicle-related motion sickness)
Not sure which timing you wanted exactly, but ok
For PSRAM:
For video timing it's:
For audio sample timing it's this:
Video glitches now seem fixed once I did this change below with an added waitx #15 to phase adjust the clock edge (so it may not be audio related, although it seemed to make a difference before):
Wait, isn't that the same as inverting the clock polarity?
Thought you might think that but no, that was already done below. For a 16 clock pixel period waitx #15 is effectively like a "waitx -1" (which is not possible). So in this case the pixel clock is better one P2 clock earlier for the data to be read reliably. What is strange is that it's such a narrow window of good phases. For only ~20MHz clocking I'd expect far wider eye for good clocking. Maybe there's a lot of signal bouncing going on before things stabilize for all the parallel RGB data bits to be clocked - need to probe colour pins.
I realized I should try to dig up my old P2 tablet (800x480 res) and try to run this LCD test code too with necessary tweaks. It also uses a parallel 24 bit LCD interface but I'm not sure which P2 pins I ended up putting the sync's on though - might have been why I generated PWM outputs for Hsync/DE signals. That system has a 4 bit PSRAM so might be able to run something too. It does also have a VGA output and a USB host port.
Just tested that and the hi-res text line is clear and readable and looks good. 👍 MisoYume seems pretty good, tried a bunch of things and some games fail to start up but I think that is to be expected. In general I think this is pretty decent on and sounds great too, especially on headphones. I went back to setting #5 for the WXPIN param and video is still okay with that other waitx change I made earlier.
Tried MegaYume, for some strange reason there are a lot of blank lines at the top of the menu pushing it down (maybe by design) and they are also seen in games. This seems weird as I only have 2 back porch lines in the timing so it should be able to start earlier on the screen. Here's some pics of that.
I also needed to do a waitx #14 to get a decent image with the clock pin also inverted. Based on this and the other emulators I think we probably need a custom phase delay parameter in config.spin that people could tweak to do this waitx #phase_delay whenever it's set to non-negative values for example - like your other pin settings etc.
Yeah that shouldn't be that far down
Something seemed a little different there when you render your horizontal lines vs other emulators (start or end of sync difference perhaps?). But I fixed it just now with this timing (your original default values are shown commented out).
I also just got audio working too on MegaYume now so I'm quite happy about that too. All three of your main P2 game system emulators pretty much appear to work ok now on this system.
Weird that that makes a difference.
But yeah beyond that we just got the couple standalone games. Spin Hexagon blocked on your video driver, etc etc
You didn't mention Spin Hexagon in the list. I should try it out with my video driver at VGA resolution if that works.
I didn't mention it because I didn't apply any patch to that one.
Though another case of the whacky audio drivers lurks therein.
(The Tempest2000 one and the P1CC ones are all ostensibly normal).
Would it work ok with the USB controller or does it need a keyboard?
I think I added controller support at some point? Reply hazy.
Is quite certainly behind on USBnew versions, so maybe cop the latest one from somewhere else.
Ok. Plus I already have a hard coded p2videodrv file that could work instead of the existing one.
Seems the audio for this game runs from an ISR triggered off the DAC ready event. Will need to make that a timer based one now, that's the trickiest part to modify plus I'm not too familiar with how sca/scas work so I tend to hack about with modifying various DAC offsets etc until I get something sort of running in P_NCO_DUTY mode.
Getting a build error - regarding FAT32 stuff: (I took the latest code from your mega.nz link today). Does something else need special configuration somewhere?
EDIT: okay using Flexspin 7.5.0 fixed it.
❯ !.
./build.sh
Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2025 Total Spectrum Software Inc. and contributors
Version 7.0.0 Compiled on: Jan 16 2025
hexagon.spin
|-platform.spin
|-|-p2videodrv.spin2
|-VJET_p2beta_rendering.spin2
|-p2videodrv.spin2
|-usbnew.spin2
|-padmap_parser.spin2
|-SimpleSerial.spin
|-VJET_p2beta_displaylist.spin2
|-hexfont.spin2
|-hexagon_sdda.spin2
|-|-FAT32.spin2
|-|-|-sdspi_with_audio.spin2
|-|-sdspi_with_audio.spin2
|-|-platform.spin
|-|-jm_nstr.spin2
|-evilfloatmath.c
|-jm_nstr.spin2
hexagon.spin:831: warning: variable clip_angle may be used before it is set in function update
ieee32.c
hexagon.p2asm
hexagon.p2asm:14015: error: Unknown symbol '_FAT32_addressDIREntry'
Done.
Oh yeah - sounds a little distorted but it runs. I might have overdriven the audio a bit, but I can tweak from here. Very difficult game to master. Having a crisp VGA res LCD in this handheld is awesome.

At some point I added checking the P1 version (amongst other things) to the flexspin CI, because it just keeps breaking like that.
(Also IIRC the SD/sound driver has a bug where it sometimes drops commands, not sure if that still exists, but if it happens, be rest assured it's "normal")
Also I think that's the last weird sound driver, the other ones all use the fine and normal loop structure.
Probably good to collect them all when you're done so I can figure out how to move forward with all that (using a timer is ostensibly better than relying on the DAC buffer, since that'd enable pure HDMI audio without real DAC pins, too)
Yeah it makes sense for me to bundle the changes so you might find a clean way to nicely integrate these different options for some audio/video and pin settings etc.
)
I've got 4 of your games/emulators essentially running now and can zip them up so you can diff against your branch. However I need to remove the hard coded hack from my own video driver and essentially integrate my own parallel LCD support - I'd already done some of work in that area previously but it needs to be resurrected and completed like HDMI. (That means it may take a while
Should be easy to get Tempest 2000 and P1CC into the mix, they should just werk ( though t2k has rather interesting build requirements)
(I'm once again busy in other endeavours today, possibly involving black magic and board games, so probably no real-time tech support on those - still haven't had time to pull out the logic analyzer setup for this, either)
Just thinking about a way to put together a starting screen emulator/game menu to try out - it won't necessarily be real pretty but just functional at this time..
I would like to present a group of game emulators in a text or graphics mode screen, and when a game emulator is selected via up/down button then L&R button could choose a game from a scrolling list (or vice versa for buttons) and the Start/primary fire button would run it. Looking through the emulator code bases it would appear that in general when the P2 starts the emulator the code checks for a game name via an ARGV string put up in $FC000... memory. So in my simple brain it would appear we could just load a new 512k flash image saved at some simple flash memory boundary that indexes the emulator, and also pass a game name from SD to $FC000 and it could then run it.
To exit it looks like both Misoyume and Megayume already poll for down+select to restart. However that could be modified to to restart the P2 from flash again (or could reload the flash image into RAM and run again leaving IO pins intact - less brutal). NeoYume doesn't seem to have this done the same way as there is not a SPIN2 COG left running once the game emulator starts up.
Some complications I forsee: SD card re-init issues (esp. after flash startup), audio clicks/pops (could control pins to try to reduce that), and video screen glitches from IO pin changes and PLL restarts - (probably would have to just ignore these minor A/V issues for now). I also already know that some SD cards already have a problem when I reload (serially) after a reset so that sequence probably may need to be improved to make it more robust if possible. A dedicated SD card interface that can shutoff power like my 4 bit SD mode interface does would really be preferable here (and could possible end up as a requirement over the shared Flash/SD card interface design on a standard P2 board).
May try to hack something up to test this concept. Will have to get more familiar with setting up boot flash again - been ages since I did that probably only once before and I know there were programming issues getting it working nicely related to full 512kB image sizes etc.
UPDATE: New loadp2 installed which appear to write the emulator image to flash fine which is great. I think I must have been out of the flexspin loop for too long with respect to the whole image compression thing too. Amazed at how the binary image can be compressed now. Seems like a very useful feature and could help speed up the load time too I'd imagine.
Yeah that sounds roughly right.
Audio shouldn't click when turning off and when turning on, we can de-click it - though that's assuming DACs, IDK how this weird digital amp thing'll react. Flash boot is also quite fast, so I don't think anything more involved than a regular soft-reset is needed to implement return-to-loader. SD card/flash interaction oddities are likely the #1 problem (solved by SD4 I/F).
Adding return-to-loader / soft-power to NeoYume is probably best done by hijacking the part around here: https://git.sr.ht/~wuerfel_21/NeoYume/tree/master/item/neoyume_lower.spin2#L3678 where it handles generating the vertical blanking interrupt. Normally it'd then go to
.scan_done
(doing no actual work), but could be detoured to run some other stuff. The SD is only used read-only, so it should always be fine to reset the machine.Note that the ARGv thing has become integrated into Eric's tooling (I didn't even do that). You can use the -a switch with loadp2 to set arguments when doing serial boot, I think I've explained how to elsewhere.
You can also write a C program with the usual
int main(int argc, char **argv)
thing and the C runtime will populate that appropriately.The compression flag works really well for the emulators in particular, because the uncompressed binary is full of alignment padding. That compresses down very well. The actual compression ratio achieved on machine code is somewhat low because it can only really compress repeating sequences >= 4 bytes. It doesn't have any symbol entropy coding. But that's what makes it simple and fast.
It mainly creates noise when the output pin floats for a while and the video is enabled (which I think may enable the amp) - noise gets louder over time (seconds). A brief pause may not be so bad, but I'll find out soon. The menu app can probably drive the pin high or low before it runs the emulator and frees the pin.
Thanks for the tips - I'll try to hook something in. A reset is nice and simple so if SD isn't used for NeoYume in game that'll probably work out better that way.
You probably did, but I've been out of the loop a bit more than normal on the forums this year due to other things and haven't kept up with a lot of developments.
That's cool. Arguments make testing things via CLI interactivity or automation easier, so it's very handy.
Very nice. For lots of (reasonably large) blocks in the file that type of decompression method should save some boot time in most cases. Great that it helps the compressible emulators boot faster from flash - I've already tested MisoYume alone from boot and it boots up to the menu almost right after I slide the power on switch - it's really quick! Ultimately it just needs a fancier front end and it'll be a really polished portable device.
@Wuerfel_21
Dumb question: how can I safely start your flexspin emulator image just read in from FLASH and loaded into HUBRAM at address 0 without doing a fresh COG init and messing up the IO pin states? I sort of want to assume control by reloading my existing PASM COG and restarting from 0 (like a software reset instead of hardware reset). Maybe I just jump up into some LUTRAM then do a setq #0 and rdlong burst read of 502 longs into COGRAM address 0 with PTRA, PTRB set to something sane and then jump directly to COGRAM addr 0 to avoid the IO and PLL changes? Can that even work? I guess I'll try it out...
Refer to what the coginit boot ROM does: https://p2docs.github.io/mirror/p2silicon.html#boot-rom--debug-rom
Though there's essentially no way to avoid it doing 2 coginits (lz4stub -> lower boot stub -> upper compiled code) and 2 PLL setups (flexspin defaults to setting 200MHz -> then the video driver changes it again) on its own time. I think the first PLL setup could be skipped by getting flexspin to omit it somehow.
EDIT: seems you can't not emit the code, but if clkfreq (at $14) is not zero it doesn't do it -> 200000 cycles saved? In that case it'd have to be set to something in the lower source though (because that whole area gets rewritten by lz4stub, you can't pre-set it). Probably 25000000 or whatever the nominal RCFAST boot frequency is.
Ok, I think that boot code is similar to what I was going to do, I'll just leave outa/outb and ina alone and see what happens. It's probably not that important what I'm doing, and future COG loads will probably break it, but I was just trying to keep the IO pins managed for longer. Won't make much difference in the end it would seem plus your emulator is gonna change the PLL too from 252MHz - I could just effectively do a coginit(cogid(), 0, 0) or something equivalent to that from PASM2.
Now the proof of concept prototype worked out, progress has begun on the actual P2 FireAnt board and this (unfinished) PCB is intended to fit inside the GPi case 2W cartridge and can contain up to 64MB of PSRAM and a microSD card reader operating in 4 bit SD mode. It will work in conjunction with another small P2 board also under development that sits above it. This way it's easier to make it all fit.

@Wuerfel_21 I've assigned the Port A pins for parallel RGB as before but with the LSByte now modified and holding audio as well (see below). Do we need to keep bit 0 free if the P2 VGA output mode uses it for HSYNC or should we just make use of this for the LCD panel anyway? If bit 0 needs to be kept free for other reasons like your DIGITAL_BASEPIN assignment I can always move things up or rearrange this byte. I should really double check our pixel clock output idea can work on port A for real. I do still have a free pin on port B I could assign it if needed, or I could split the clocks and realize two independent 8 bit PSRAM banks with one chip select and one clock each which can be combined for 16 bit operation because the pairs are adjacent. It might also alleviate the high fanout for the PSRAM clock otherwise going to 8 chips but could cause different timing between banks (which my driver can handle), and the second bank of chips are slightly further away from the P2.
P0 - HSYNC
P1 - VSYNC
P2 - PIXEL_CLK
P3 - DE
P4 - LEFT_PWM
P5 - RIGHT_PWM
P6 - free for now
P7 - free for now
P8, P9 - GPi power and shutdown
P10-P15 - BLUE
P16, P17 - USB D-/D+
P18-P23 - GREEN
P24, P25 - chip selects for PSRAM
P26-P31 - RED