New Buzz! plugin - Help needed
#1
Hi everyone!

I'm trying to write a new usb plugin, using usbnull and usbqemu-wheel as base. The actual usbqemu-buzz plugin is 1 set only (as I said in the dedicated thread) and the more advanced binaries are closed source. The thread opener open source plugin is not working on new PCSX2 version with Windows 10, buzzers are not responsive (slow or sticky).

I'm studying the OHCI protocol, and I'm stuck, maybe you can help me.

My idea is like this: using some high level HID library in C#, I create a .NET DLL that manage all the connection/disconnection stuff with the two sets of buzzers, and simulate a OHCI controller. Because this is simulated (the real connection stuff is done by the HID library), many registers can be faked (some need to be correctly initialited to let the game know how many sets are connected).

At the actual state, I may write a small software that calling this DLL, I can send an array of bytes to light up the lights and I can read the state of the buttons as they are send back by the controllers. 

Now I'm stuck: PCSX2 does calls on the USBwrite32 and USBread32, but they are only for the control register. How PCSX2 sends and receive data bytes? If I understood correctly, there should be:

Write (address, value) and value = read(address), knowing the base (i.e. 12345), when game request byte (12347, I can do 12347-12345=2, ready byte 2 from the buzzers and give back to the emulator).

But I cannot intercept those calls. How I should do? Thank you!

Alby87
Reply

Sponsored links

#2
The OHCI controller is given a region of IOP memory to use, refereed to the Host Controller Communication Area, data referring to connected USB devices is written directly by the OHCI controller and the IOP is then free to read it.

With respect to plugins in PCSX2, you would get a pointer to IOP memory via USBsetRAM, and address for the HCCA via a call to USBwrite32, then you would update the relevant data during calls to USBasync.

Most of the existing open source USB plugins (Including mine) for PCSX2 use code derived from QEMU, and is reasonably solid provided you add extra bounds checks on reads/writes to IOP memory, as during BIOS restarts PCSX2 leaves the usb plugin running and you will end up getting invalid addresses.
Reply
#3
(10-29-2017, 11:50 AM)Ge-Force Wrote: The OHCI controller is given a region of IOP memory to use, refereed to the Host Controller Communication Area, data referring to connected USB devices is written directly by the OHCI controller and the IOP is then free to read it.

With respect to plugins in PCSX2, you would get a pointer to IOP memory via USBsetRAM, and address for the HCCA via a call to USBwrite32, then you would update the relevant data during calls to USBasync.

Most of the existing open source USB plugins  (Including mine) for PCSX2 use code derived from QEMU, and is reasonably solid provided you add extra bounds checks on reads/writes to IOP memory, as during BIOS restarts PCSX2 leaves the usb plugin running and you will end up getting invalid addresses.

Thank you a lot! I made some progress after I made this post, check it out!  Biggrin 

https://github.com/Alby1987/BuzzMultiBuzzersPlugin

It works perfectly except for two games: the BIG quiz and the MEGA quiz  Blink  using the plugin as it is now, continues to pressing the blue button, starting a new game.

Noticed that if I manually set the return of the "_USBirqHandler" function to 0, the game doesn't accept any input, but at least I can (with the debugger), set the return to 1 while pressing a button and it works.

Now I'm trying to connect the event of read data of the HID library to this return, made some progress but it's not perfect yet. Lots of false presses.

Thank you for your help! Laugh
Alby87

EDIT: this happens only when two sets are connected (or the second set is set in the options). With one set of buzzers only it works flawlessly. It's that IRQ return, yesterday I spent a whole day but no results Sad
Reply
#4
More tests done: If I connect the same USB_Buzzer object on the two different ports OHCI via OHCI.ports.attach, it will no get the phantom button pressures. Obviously I cannot use two sets this way.

I think I'm really close to resolve the problem, but I'm just missing this one little thing Sad
Reply
#5
I'm not actually what your issue is. As I don't have a buzz controller I can't easily investigate from my end.
Reply
#6
You could bug Kubax if he will respond. I think he finally got the buzzer to work some what.
For random key presses, I think he changed from the usbqemu-buzzer source
Code:
buf[0]= 0x00;
buf[1]= 0x00;
buf[2]= data[2];
buf[3]= data[3];
buf[4]= data[4];
buf[5]= 0xfd;
to
Code:
buf[0]=0x7F;
buf[1]=0x7F;
buf[2]=data[2];
buf[3]=data[3];
buf[4]=data[4]|0xF0;

data was read with hidapi's hid_read, I think.
Reply
#7
(10-31-2017, 04:59 PM)Ge-Force Wrote: I'm not actually what your issue is. As I don't have a buzz controller I can't easily investigate from my end.

Sorry for being to so clear. When I use two sets of Buzzers, the main menu acts as the blue button is always pressed. This makes the game unplayable. My goal is to make the game work with two sets for 8 players-maximum.

So far, using the code in my github repository, I've made some tests, and there are my results:

1) One set connected, one set activated in the settings
The game works flawlessly, no problems at all (Only one of the OHCI ports have an object, the other one is null

2) One or two set connected, two set activated in the settings
Buttons have minds on their own, lot of false pressings.


If I disable the interrupt (_USQIrqHandler returns 0), no more keys are recognized. Hovewer, if I use "return irqtest", and irqtest is a boolean I change in debug mode, then the game recognizes when to get data and when not. I tried to return this data based on read from the buzzers, but the game is a lot more unresponsive, almost unplayable

-------------------------------
Tried with Jackun advices, but not working, still same problems.

I think that's the control loop that have problems, I'm studying it now.

Thanks all for your helps (I'll try to summon Kubax, but it seems long gone)
Reply
#8
Almost done guys. Just one last insight: I discovered the order of operations

1) _USBIrqHandler returns 0 every time is called
2) Someone press a button
3) _USBIrqHandler return 1
4) Read is called, data is copied in PS2 RAM
5) _USBIrqHandler return 1 to confirm copy is completed
6) _USBIrqHandler returns 0 every time is called

I've just one single problem: how I can understand in the IRQHandler for what device the handler has been called? Or is just one IRQ for all devices? Every time a missfire in the IRQ is captured by the game, a blue button is pressed.
Reply
#9
IRQs are for the OHCI controller, there is no easy way to determine for which controller it's for.

When an IRQ is raised, the USBirq() function is called and the intr_status register is updated accordingly.

PCSX2 then responds by calling the IRQHandler.
Reply
#10
I've made a new release, it should be good enough to play. Hope you like it! Laugh
Reply




Users browsing this thread: 1 Guest(s)