MiSTer-devel / Saturn_MiSTer

Sega Saturn for MiSTer
60 stars 17 forks source link

[FEATURE REQUEST] SNAC support #173

Open blue212 opened 8 months ago

blue212 commented 8 months ago

Hi I wrote code to add SNAC support to the saturn core. This would let people use an adapter with the USER port and use Saturn or Gensesis/MD(software must support them) controllers. It currently supports both control modes - SMPC and SH-2 direct modes. I did uncomment and use IOSEL and it does work correctly, it determines which control mode is used(SMPC or SH2).

SH2 mode is only used in a few homebrews and lightgun games when the Stunner is detected. This mode is similar to Gen/MD since the software controls the polling and reading of the controls.

SMPC mode seems to rely on that chip to poll and read controls and put the right values into OREG. All 3 modes are supported in SMPC mode(THTR, TH, 3 line). I used a counter to time setting the select signals(TH, TR) and reading the controls. This may not be how the original chip did it. I couldn't figure out where the select signals came from in this mode, in SH-2 direct mode it they would be PDR1O, PDR2O in the core.

Every frame I check if anything is connected and identify and read the controllers. All controllers are auto detected. Every peripheral will work except the multitaps. The Sega genesis segatap and the Saturn multitaps. They don't work with current code, they use 3 line mode and I had special checks for them to make them work but removed the code to simplify and minimize it. The digital pads, 3d pad, steering wheel, mouse, mission sticks etc have been tested and all work.

There's enough io for snac to act as one port. It is coded to be act as port 1 and usb controller 1 as port 2 when SNAC is turned on in OSD. I had a joyswap function where snac coould be switched to port 2 but commented out most of it. I removed the joyswap code in the OREG section to simplify and try to save space.

Feel free to use any of this code you like, it's ok if you want to rework, rename, optimize, or simplify any of it, just please don't change to pinout in saturn.sv because that would break existing adapters. I over commented the code in the hopes you could figure out what I was trying to do. If you want to use the code as is I can do a pull request.

I used the homebrew "Pseudo Saturn Kai" to view the OREG. it has a "smpc pad test". hit a L or R sholder button then press UDLR then z to unlock the "extra stuff" menu, then choose "smpc pad test".

If you do use it I would like you to look into how the lightgun sensor works if you get a chance. Currently with lightgun games the Stunner is detected and trigger and start button work but the sensor doesn't trigger the right thing in the core so aiming doesn't work. I think EXLE1 or 2 needs to be used so bit 6 - the sensor (TH) can be used to trigger stuff. When it goes low and EXLE(EXternal Latch Enable - it is in SMPC) is high I think that signal causes a pad interrupt (IRQL in SCU) and/or latches HV (EXLAT in VDP2). But I'm unsure how that works exactly.

Here is the code. https://github.com/blue212/Saturn_MiSTer/commit/23124284d39a24994ab0ed5cd8b6361d8a82a2aa

Great job on this and the other cores btw.

gleek12 commented 6 months ago

This sounds amazing! Would this also support the twin sticks for Virtual On?

blue212 commented 2 months ago

Hi thanks for adding snac support. Your rewrite is better than what I had. I left the issue open in case I needed to talk to you about it.

There's a couple things with snac that may be missing that I noticed. First a very minor problem. When nothing is connected I think MD_ID equals 0xF, and 0xF0 should probably be written to OREG for that port. Currently in core it looks like when snac has nothing connected F0 isn't written and whatever Pad 2 option in osd is set to is written to the OREG in the pad 1 spot followed by an extra F0 at the end. You can test this without snac adapter by just turning snac on and looking at the OREG. I used the hidden "smpc pad test" I mentioned before to view OREG https://ppcenter.webou.net/pskai/pskai_release_20240114.7z

Another thing missing is when Stunner is used A0 isn't getting written to OREG. I noticed that the start button on stunner wasn't working when trying a lightgun game, something that I had working before. I determined this was because the game isn't detecting stunner because of the missing A0. I added code so when MD_ID was 0xA A0 gets written to the OREG. This was enough to make gun be detected when testing Virtual Cop 1,2. Start worked, trigger worked, and for the first time sensor worked and you could play the game with the stunner. Meaning the Interrupts you added for me worked!

One problem though with the same code, when testing other games like Area 51 or House of the Dead the gun wasn't detected because start wouldn't work. I determined this was because of some code in PS_START section of SMPC line 799 where it writes F0 when IOSEL is high (meaning it's in SH2-direct mode). When trying Virtua Cop the IOSEL stayed high but Area 51 IOSEL seemed to be toggling. So there may be some difference in the game code making it do this. My theory stunner was detected and writing A0, then setting IOSEL since it detected stunner then F0 was getting wrote and IOSEL was then changed back to 0.

I tried a hack of line 799 - OREG_DATA <= 8'hF0; and changed that to A0. That was enough for stunner to start working in Area 51 and HOTD. I'm unsure that your current code writing F0 when IOSEL is high is correct, it doesn't seem like it. My hack isn't correct either since I found one homebrew that used sh2-direct called SATFLY. https://segaxtreme.net/attachments/satfly-r-zip.7055/ It uses sh-2 direct mode for the regular saturn pad. I believe most retail games use smpc mode and only use sh-2 mode for lightguns.

Here's is the code so you can see how I did it https://github.com/MiSTer-devel/Saturn_MiSTer/compare/main...blue212:Saturn_MiSTer:stunner

One weird thing I noticed House of the Dead booted to a black screen but I was able to either reload or reset a few times and it would load and work. Also Maximum Force booted to a black screen even when snac was off and both ports were set to digital. but it loads on your current core. I didn't see how I broke it, maybe it was just my build that had signaltap enabled.

srg320 commented 2 months ago

Thanks for the notes.

About the Stunner. I don't have a Stunner. It is very hard to add support for a device you don't have. If you have a Stunner, you can add support for it in the core.