English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   solving the CD32 joypad "mystery" (https://eab.abime.net/showthread.php?t=73618)

jotd 06 May 2014 15:44

solving the CD32 joypad "mystery"
 
Hi,

In my long whdload patching career I've tried to fix/adapt games which use/want to use a CD32 joypad and still did not find a perfect way to do so.

First, I found that only lowlevel.library is able to perfectly detect and read CD32 controller data. So for all games using it, no problem.

BUT, in CD32 kit they provided a hardware way to read the joypad amongst other things (direct CD access...)

ex: in James Pond 3

It started by TST.B $BFE001, then shifted through $BFEE01 to read all buttons (too lazy to paste the code here)

This routine only works properly on a CD32. Even on a vanilla A1200 it failed to work, with symptoms: wrong or no buttons detected

I also reckon that to read 2nd button (CD32 & sega) you have to wait at least 1 VBL interrupt or the reading would be wrong.

Anyone has the solution to safely read the buttons on any computer without lowlevel library?

Bonus question: how lowlevel detects that a joystick or a CD32 joypad is connected?

I tried to resource it, but it was so full of cia.resource shit that I gave it up.

Thanks for your answers.

Toni Wilen 06 May 2014 20:03

AFAIK lowlevel.library detects CD32 pad simply by polling all CD32 buttons +2 and checking if non-existing button "8" button is always pressed and "button "9" and later are always not pressed. (This condition is not possible with normal joystick)

EDIT: I can debug the exact sequence using emulation logging.

Toni Wilen 07 May 2014 19:47

I checked CD32 ROM code and it seems to use normal pad read loop + checks 2 "extra buttons".

Code:

Set ciaddra joystick button bit
Clear ciapra joystick button bit

Set POTGO (calls WritePotgo, D0=$2000,D1=$3000 / D0=$0200,D1=$0300. Direct write to POTGO should work fine.)

Jump doit (I have no idea why it skips following 3 waits?)

loop: (9 times)

Delay (3*tst.b cipra)

doit:

Delay (5*tst.b ciapra)

Read POTGOR
Use read value to set bit in button bit mask

Set ciapra joystick bit
Clear ciapra joystick bit

Jump to loop

Set original value to POTGO
Clear ciaddra joystick bit

Check if button "8" is not pressed and button "9" is pressed. If correct, set joystick type to cd32 pad.

There is no need to wait for vblank (CD32 code polls the button in tight loop during intro screen). I guess it needs to be done if POTGO bit 0 is also set but at least official code does not set it.

Asman 07 May 2014 21:28

@Toni Wilen
About "Jump doit (I have no idea why it skips following 3 waits?)"

I think that only reason is speed but is only idea.

@jotd
You can use following asm routine EAB forum link.

jotd 07 May 2014 22:41

thanks. But I still don't understand why this delay works on each CPU since it's CPU dependent. I had the idea that this delay was the cause of bad readings returned by this code.

robinsonb5 08 May 2014 01:26

Quote:

Originally Posted by jotd (Post 953483)
thanks. But I still don't understand why this delay works on each CPU since it's CPU dependent. I had the idea that this delay was the cause of bad readings returned by this code.

The CIA chip runs on the E clock (or Gayle-generated equivalent on A600/A1200/A4000), so each tst.b CIAPRA is guaranteed to take at least 1.4µs (I think - memory might be letting me down here), no matter how fast the CPU might be.

jotd 08 May 2014 07:50

ok, but still when using the code found in some games or even the games themselves there were issues with buttons.
was it a timing issue? what did Bert fix?

thanks for the explanation, its beginning to make sense now.

Asman 08 May 2014 09:21

@jotd
"was it a timing issue? what did Bert fix?"

Yes it was timing issue. I'm think that this initial jump should be removed.

jotd 09 May 2014 07:19

the code you're quoting is not the implementation of ReadJoyPorts.

First, it has a move #1,d0 hardcoded so it reads only port 1
Second, you have to detect kind of joystick first, or this will fail: on a normal joystick you'll get strange readings with 2nd button.

I figured out that testing up to bit 16 (move #16,d1 for the loop counter) helps to know dynamically the joy type

and in the end I test d0


btst #16,d0 ; if this bit is set, then there was a read problem
beq.b .read_ok ; meaning this is not a joypad but a joystick

; button 2 of the joystick

bset #JPB_BUTTON_BLUE,d0 ; fire2/rmb
bra.b .out



But the best would be to autosense at startup, and apply the joystick/joypad relevant routine.

I know there are issues with honeybee competition joypads too. Let's hope the timing fix is enough (I cannot test since I don't have this hardware)

@Toni: I've got a DB9=> USB adapter, is there a faithful way to connect a CD32 joypad to it and get all buttons working?

Toni Wilen 09 May 2014 07:41

Quote:

Originally Posted by jotd (Post 953671)
the code you're quoting is not the implementation of ReadJoyPorts.

I agree, it has few differences and problems.

- does not detect pad, it just assumes it is there
- writes FFFF to POTGO (Why?). This forces it to only work once/frame.
- Different POTGO bits set than Commodore code.

Last two may make it incompatible with some pads.

EDIT: Now I remember that this POTGO stuff is supposed to do.. It uses POTGO bit 0 to reset shift register (instead of setting it directly) after buttons have been read -> first read is unreliable..

Quote:

@Toni: I've got a DB9=> USB adapter, is there a faithful way to connect a CD32 joypad to it and get all buttons working?
No, adapter internally needs to implement extra button handling. (Some pins needs to be output to control CD32 pad shift register and reading needs to be real-time, neither can be done)

Anemos 09 May 2014 08:35

1 Attachment(s)
Hi dunno about coding.. but maybe help you the program "Joytest" on aminet http://aminet.net/search?query=Joytest
Also i found this hardware mod on single Joy,s for working the second fire button for a lot Whdload games like ..
.Bubble and Squeak
.Banshee
.BCKid
.LionHeart
.Leader
.and more..
needed pull-up resistor on pin 9 to working well the second fire button.

Toni Wilen 09 May 2014 08:51

Quote:

Originally Posted by Anemos (Post 953677)
Hi dunno about coding.. but maybe help you the program "Joytest" on aminet

They are all mostly useless for OP's purposes, most likely all test programs that supports CD32 pad use lowlevel.library to read it.

Quote:

needed pull-up resistor on pin 9 to working well the second fire button.
Yeah, it is easiest fix. Reason is quite simple, most games do not adjust POTGO for two button use because KS 1.x did (accidentally I think) set it correctly. KS 2.0+ sets joyport to single button only by default (if there is no pullup resistor).

jotd 09 May 2014 10:28

Thanks for all this useful info.

@Toni: my lowlevel emu code replaces $FFFF => potgo by $CC01 (done a long time ago, don't remember why)

@Toni: it is still possible to map say a USB/PSX controller to CD32 joypad buttons to be able to test CD32 stuff right?

@others: I just tested Banshee whd and it seems OK (I remember I had to fix it, though, like a lot of other 2nd button friendly games that weren't that friendly).

I guess that there were differences between 2-button joysticks. Mine is a wico command control (best joystick ever). I always fixed 2-button control according to my wico.

Thanks for the explanation about difference between potgo in various kickstarts.
I guess in port 0 (mouse), potgo is set properly to be able to read RMB.

@others: can you file one bug at a time in http://mantis.whdload.de to explain which 2nd buttons are not working?
Much better than in the forums

Toni Wilen 09 May 2014 11:46

Quote:

Originally Posted by jotd (Post 953691)
Thanks for all this useful info.

@Toni: my lowlevel emu code replaces $FFFF => potgo by $CC01 (done a long time ago, don't remember why)

Only unused bits are masked out. No functional difference :)

Problem is still bit 0, it is not needed (setting data and direction bits directly works much easier!) and imho must be some hack, perhaps original author didn't know how POTGO hardware internally worked and just tried something until it started to work.. (HRM basic explanation is quite useless)

Setting bit 0 always introduces at least 7 scanline delay, this delay is used to discharge pot caps before charge phase starts.

Quote:

@Toni: it is still possible to map say a USB/PSX controller to CD32 joypad buttons to be able to test CD32 stuff right?
Real CD32? Not without building CD32 shift register hardware first. (Very simple, only 2 TTL chips and some resistors)


Quote:

I guess that there were differences between 2-button joysticks. Mine is a wico command control (best joystick ever). I always fixed 2-button control according to my wico.
Check resistance between second button pin and +5v.

Quote:

I guess in port 0 (mouse), potgo is set properly to be able to read RMB.
Yes, mouse port right button pin is set to output mode.

Asman 09 May 2014 13:35

Hmm... I'm afraid that I'm completly lost, there is many things which I don't understand (in my code too :) ).

About above CD32 ROM Code. Lets focus on initialization first, there is

1.
Set ciaddra joystick button bit
Clear ciapra joystick button bit

But for what is that code ? Is it necessary to do it ?

2.
Set POTGO (calls WritePotgo, D0=$2000,D1=$3000 / D0=$0200,D1=$0300. Direct write to POTGO should work fine.)

As I understand correctly, then direct write to POTGO will be $2000 or $3000 / $0200 or $0300. In other words only pin 9 is set to output, right ?

Toni Wilen 09 May 2014 15:42

I'll try to write short explanation what happens (and why) in CD32 pad side when code pokes CIA and POTGO registers.

jotd 09 May 2014 16:18

thanks Toni. Invaluable info.

So you suggest to replace move.w #$cc01,potgo by the corresponding BSET instructions but not bit #0 that's right?
is that move.w #$cc00
or bset #15 #13 #11 # 9 ?

or remove it (it reckon this causes problem with subsequent readings)

And the fact that I knew that it was not possible to read more than 1 VBL at a time is related to that instruction.

robinsonb5 09 May 2014 18:42

Quote:

Originally Posted by Asman (Post 953722)

1.
Set ciaddra joystick button bit
Clear ciapra joystick button bit

But for what is that code ? Is it necessary to do it ?

The CD32 pad contains a serial shift register (74LS165) which is used to send the status of each button in turn to pin 9 of the gameport (which is the pin usually assigned to the right mouse button, or second button on a two-button pad.) This shift register is clocked using pin 6 of the gameport (which is normally the fire button pin) - so the initialisation code changes that pin from input to output, then pulls it low. The set/clear later on in the main loop sends a clock pulse to the shift register, placing the next button's status on pin 9.

Pin 5 is used as a select line - normally high (in which case only the red button is readable, as a normal fire button), and pulled low by the POTGO stuff to activate the shift register.

jotd 09 May 2014 19:18

That makes me think: what could explain that some games work OK with the joystick, but when you plug in a CD32 joypad, red button is not recognized? (ex: Moktar, and another one I don't remember)

robinsonb5 09 May 2014 19:29

Quote:

Originally Posted by jotd (Post 953763)
That makes me think: what could explain that some games work OK with the joystick, but when you plug in a CD32 joypad, red button is not recognized? (ex: Moktar, and another one I don't remember)

At a guess, the game is writing an ill-considered value to POTGO that results in pin 9 being pulled low. Should be easy enough to verify with the WinUAE monitor.


All times are GMT +2. The time now is 15:21.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.08583 seconds with 11 queries