Glitch-free controller reads with DMC?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Fiskbit wrote: Sat Feb 12, 2022 9:57 pm This game does not do OAM DMA last in vblank, so the extra vblank time wasted by reading the mouse is pushing later work that relies on vblank into rendering. You need to move OAM DMA to the end.
Okay, that sounds hopeful! I will see about doing that next. For now, I have an IPS file that does move the cursor on the screen using the SNES mouse. Only to prove the concept so far. The mouse buttons don't work yet and it rolls over instead of bumping into the edges of the screen. You can still click it with controller 1 but not with the mouse. It is very smooth motion, I like it a lot. This game has lots of free ROM space, especially ROM file range $cca0 - $10010. (almost 13 kilobytes) That will require bankswitching to page 3 to get to that big chunk.
Attachments
Shanghai 2 (J) - Mouse.ips
(141 Bytes) Downloaded 35 times
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Updated, everything is working now. I am still not initializing the mouse tracking speed, so it may be inconsistent or not work with real hardware. But the graphical glitches are fixed, following your suggestion fiskbit. I rearranged things to make sure it happens after finishing with all of the PPU stuff and that fixed it. I also made the mouse cursor bump into the edges of the screen instead of rolling over. I used the same original limits from the game, which does make the cursor disappear at the very top. Mouse buttons are working properly. I apply the mouse X/Y and buttons to both players, so multiplayer modes you can both play with just 1 mouse. Controller 1 still does everything it used to do, including moving the cursor. As far as I can tell, this is pretty much done except for initialization. Probably my code could be improved to be more clean and efficient... But it is a hack after all.

This would be REALLY neat to see if it works on real hardware if anyone has a mouse and adapter for controller port 2!
Attachments
Shanghai 2 (J) - Mouse v1.0.ips
(283 Bytes) Downloaded 36 times
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Glitch-free controller reads with DMC?

Post by Pokun »

I have a mouse but no NES, only a Famicom so it would need to support the DA-15 expansion port.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Do you have an adapter that connects an SNES controller (or mouse) to the Famicom expansion port? If so, how is that wired? I believe I just have to use a different bit when reading $4016 or $4017 corresponding how that is wired, but quite likely that will throw off the cycle timing and no longer fit into 1 DMC DMA fetch.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Glitch-free controller reads with DMC?

Post by Fiskbit »

I have an adapter and Hyperkin mouse I can test with maybe tonight. I'm not sure if I'll be able to confirm that deletions aren't happening, though. If this mouse provides 1's after all 32 bits, then I should see slow rightward drift if the code isn't right, but if it provides 0's, then I'm not sure what to do and look for.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Thanks Fiskbit. The mouse controls the cursor VERY smoothly on the screen, frame by frame, very satisfying. I think if you are having bit deletions, you will find some awkward/jerky movements of the cursor on the screen. The DMC is especially active in this game; one of the worst possible (and coolest) real scenarios deleting bits, so I think it will be a very good test.

Here is a game genie code that lets you click any tile. You can even carefully click the edges when they are completely covered! It’s amazing.

APKSPOAU

Normally, the cursor moves in increments of 2 pixels with the d-pad. I programmed no such restriction using the mouse. So there are now 4 times as many clickable pixels as before. The game seems to handle that fine. There may be a way to get to the “odd” pixels with the D-pad by bumping into the edges of the screen or something. I just thought it was interesting — another subtle improvement that wasn’t even intentional.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Glitch-free controller reads with DMC?

Post by Pokun »

Ben Boldt wrote: Tue Feb 15, 2022 10:25 pm Do you have an adapter that connects an SNES controller (or mouse) to the Famicom expansion port? If so, how is that wired? I believe I just have to use a different bit when reading $4016 or $4017 corresponding how that is wired, but quite likely that will throw off the cycle timing and no longer fit into 1 DMC DMA fetch.
I don't have an adapter but I plan to build one using extension cables.

The adapter would have to be built exactly like a NES controller adapter with the pins to their corresponding pins in the DA-15 expansion port, leaving out pin 5 and 6 as they have no corresponding use on a Famicom (and I don't think they are populated on my cheap SNES extension cables anyway).

Code: Select all

SNES controller port:
1 [oooo|ooo) 7  1:+5V  2:Clk  3:Out  4:D0  5:D1  6: I/O  7:Gnd

Famicom DA-15 expansion port:
  1___________________8
   \ o o o o o o o o /
  9 \ o o o o o o o / 15
     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Adapter:
  Famicom       SNES                  Description
  15            1 (both controllers)  +5V
  14            2 (controller 1)      CLK con 1
  9             2 (controller 2)      CLK con 2
  12            3 (both controllers)  strobe
  13            4 (controller 1)      data con 1
  7             4 (controller 2)      data con 2
  1             7 (both controllers)  GND
This is how I think it should be, unless I made any mistakes.
SNES pin 4 is the data pin and would be read from from $4016 D1 and $4017 D1 for SNES controller port 1 and 2 respectively, but otherwise works exactly the same way, so yeah it's just a matter of reading a different bit.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Okay, that sounds about right. Using D0 has an advantage that you can right-shift to get the controller bit into the carry bit (like Fiskbit has done) and that can simplify the code, making it fast enough to read the mouse before a second DMC DMA. I am not seeing how that will remain possible when using D1. An extra 32 shifts would have to occur afaik.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Glitch-free controller reads with DMC?

Post by Fiskbit »

I haven't tested it yet, but regarding using D1, I think you could replace the shift with a compare against #$42. This would rely on open bus behavior, but should work on standard consoles. The bit being checked after reading the 1st byte would also have to change to match (by changing the LSR BCS to AND BNE). Cost-wise, this would be an even trade.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Glitch-free controller reads with DMC?

Post by Fiskbit »

I tested this with the Hyperkin mouse and discovered it does not currently work. According to the wiki, if the Hyperkin mouse is read too quickly, it returns bad values. Reads must be 14 cycles apart, and 28 cycles are needed between the 2nd and 3rd bytes. I don't know if this applies even to the first byte (all 0's), but it poses a significant problem for us. We wait only 4 cycles between reading bits of the 1st byte, and 12, 16, or 20 cycles between the rest of the bits. Fixing this would take 112 more cycles, which I believe can be done safely, but will require care for the bad cycle on rate F.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

Well, maybe it’s okay (at least for now) not to support the hyperkin mouse. If we get everything working first with the SNES mouse, detecting which port is connected to, etc, it could be a future challenge to tackle the hyperkin mouse.

I don’t presently have any Nintendo mouse, but HAVE seen them at thrift stores and passed… I will be keeping an eye out from now on!
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Glitch-free controller reads with DMC?

Post by rainwarrior »

Ben Boldt wrote: Tue Feb 15, 2022 10:25 pm Do you have an adapter that connects an SNES controller (or mouse) to the Famicom expansion port? If so, how is that wired? I believe I just have to use a different bit when reading $4016 or $4017 corresponding how that is wired, but quite likely that will throw off the cycle timing and no longer fit into 1 DMC DMA fetch.
I made an adapter that connects 2 NES controllers to the Famicom (NES controller d0 to Famicom d1), and I think many people have created the same adapter before, since it's a good way to use NES controllers with Famicom games.

I also have an SNES to NES adapter, which easily plugs into the other adapter, placing the mouse's data on d1 for Famicom, but d0 for NES. The Japanese Power Glove has a similar relocation between NES and Famicom.

For NESert Golfing I had it look for the mouse on both d0 and d1 on both ports at startup, and just use the one it found after that. Two mouses at once didn't seem worth supporting... though I think someone mentioned that might have undesirable levels of current draw?
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: Glitch-free controller reads with DMC?

Post by Ben Boldt »

rainwarrior wrote: Fri Feb 18, 2022 12:17 am For NESert Golfing I had it look for the mouse on both d0 and d1 on both ports at startup, and just use the one it found after that.
I was thinking of doing exactly that. It makes it so that you can’t hot-plug the mouse, but I think it’s probably not a great idea to hot-plug it anyway.

Did you initialize the tracking speed as part of this process? Would like to see and use your code into this Shanghai II hack with your permission.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Glitch-free controller reads with DMC?

Post by Pokun »

Ben Boldt wrote: Wed Feb 16, 2022 9:08 pm Okay, that sounds about right. Using D0 has an advantage that you can right-shift to get the controller bit into the carry bit (like Fiskbit has done) and that can simplify the code, making it fast enough to read the mouse before a second DMC DMA. I am not seeing how that will remain possible when using D1. An extra 32 shifts would have to occur afaik.
Yeah you need an extra shift per byte, I guess that's not fast enough.
What about doing the usual DMC fortification by reading the device twice and compare if they are equal? Does that not work well with the mouse?


rainwarrior wrote: Fri Feb 18, 2022 12:17 am I made an adapter that connects 2 NES controllers to the Famicom (NES controller d0 to Famicom d1), and I think many people have created the same adapter before, since it's a good way to use NES controllers with Famicom games.

I also have an SNES to NES adapter, which easily plugs into the other adapter, placing the mouse's data on d1 for Famicom, but d0 for NES. The Japanese Power Glove has a similar relocation between NES and Famicom.
I have also built such a NES->Famicom controller adapter. I guess I will go that route and make a SNES->NES controller adapter, that way it works with both NES and Famicom (in conjunction with the other adapter).
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Glitch-free controller reads with DMC?

Post by Quietust »

Pokun wrote: Fri Feb 18, 2022 9:33 am
Ben Boldt wrote: Wed Feb 16, 2022 9:08 pm Okay, that sounds about right. Using D0 has an advantage that you can right-shift to get the controller bit into the carry bit (like Fiskbit has done) and that can simplify the code, making it fast enough to read the mouse before a second DMC DMA. I am not seeing how that will remain possible when using D1. An extra 32 shifts would have to occur afaik.
Yeah you need an extra shift per byte, I guess that's not fast enough.
What about doing the usual DMC fortification by reading the device twice and compare if they are equal? Does that not work well with the mouse?
The act of reading the mouse's state also clears its state, so the second read would report that there was zero movement (but would still report the button states properly).

A similar problem would happen with the Arkanoid paddle controller, since it takes about 7 milliseconds for the controller to convert the analog position into a digital value.
Last edited by Quietust on Fri Feb 18, 2022 10:01 am, edited 2 times in total.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply