[Solved] DualShock code causes games to hang on real hardware

BIOS, Controllers, Memory Cards, Serial I/O, Parallel I/O, etc.
Post Reply
User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

[Solved] DualShock code causes games to hang on real hardware

Post by ArthCarvalho » June 27th, 2016, 10:34 am

Solution:
I was not initializing the CD-ROM subsystem and this was causing the game to crash on real hardware.
You must call CdInit()/DsInit() even if you're not going to use it.

-- Original Topic --

I'm having problems with setting up dualshock without it causing the whole whole system to hang on the original hardware.
This doesn't happen on any emulators, and doesn't happen when testing on a PS2 Slim either.

After compiling and burning to a disc, the program will run for a random ammount of time then hang.

The dualshock code I've copied from here:
http://appleofeden.de-doc.com/index.php ... -handling/

[C]
#define PAD_A 0
#define vibBuffLen 8

static u_char align[6]={0,1,0xFF,0xFF,0xFF,0xFF};
static short connected = 0; // No. controllers connected.
int ctr;
u16 Pad_type, Type;

// pad buffer data
ControllerPacket pad_data[2];
u8 pad_state=PAD_STATE_CHECK, pad_id=INVALID_PAD;
u8 vibBuff[2][vibBuffLen];

void VibCallback();

void InputInit()
{
PadInitDirect((u8*)&pad_data[PAD_A],(u8*)&pad_data[PAD_B]);
PadSetAct(PAD_A,vibBuff[PAD_A],vibBuffLen);
PadStartCom();
}
void InputCheck(void)
{
int ret, i;
int type, set;

ret=PadGetState(0);

switch(ret)
{
case PadStateDiscon: // no pad has been connected
connected = 0;
return;
case PadStateFindPad: // currently finding pad
connected = NO_PADS;
pad_state = PAD_STATE_CHECK;
pad_id = INVALID_PAD;
set = 0;
// loop until it's stable or try next time
for (i = 0; i < 100 || !set; i++)
{
switch(PadGetState(PAD_A))
{
case PadStateStable: // found dual shock or analog
type=PadInfoMode(PAD_A,InfoModeCurID,0);
if(type)
{
// send transmission buffer
PadSetAct(PAD_A,vibBuff[PAD_A],vibBuffLen);
// wait until buffer is aligned
while(PadSetActAlign(PAD_A,align)==0)
for (ret = 0; ret < 6; ret++)
VSync(0);
}
set=1;
break;
case PadStateFindCTP1: // normal controller found
set=1;
}
}
connected=PAD_ONE;
return;
case PadStateStable:
// pad is stable, send vibration signal!
if(PadSetActAlign(PAD_A,align))
pad_state=PAD_STATE_STABLE;
break;
}

VibCallback();
type=PadInfoMode(PAD_A,InfoModeCurExID,0);
// dual shock detected with analog disabled or not
if(type==ANALOG_PAD)
connected=PAD_ONE | IS_DUAL_SHOCK;
// other pad type
else
{
type=PadInfoMode(PAD_A,InfoModeCurID,0);
switch(type)
{
case STD_PAD: // standard pad
case ANALOG_PAD: // old analog or dual shock in digital mode
connected=PAD_ONE;
break;
default: // other pads will be detected as nothing plugged in
connected=NO_PADS;
}
}
}
void VibCallback()
{

}
[/C]

I'm testing this only in a SCPH-103. I do have a SCPH-7000, but I can't test on it because it won't read burned discs.
Also there is the fact that it will run official games using dualshock just fine, so I guess the problem should be in my code.

-edit-

Also, some additional info:
This only happens when I use PadInitDirect(), the rest of my code it runs fine if I replace this with PadInit() and PadRead().
Last edited by ArthCarvalho on January 2nd, 2020, 12:04 am, edited 3 times in total.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » June 27th, 2016, 3:00 pm

I think you need to add some more VSync's in there. I remember when reading the documents the controller timing needed to be delayed to wait for its next interrupt to be ready for execution. As for the logic, I didn't test it because I'm a bit busy at the moment, but try looking at some more examples and comparing what they are doing in each function. Also, if you don't have it already, try adding 'ResetCallback();' to the main function before doing anything else.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » June 28th, 2016, 10:21 am

I'll try to replace the code on this one from that DUALSHOCK.ZIP example from Sony and see if it will work.
But I think the last time I tried, I got the same random freezes that are happening right now.

Yesterday I left my PSone on all night running my program, and it didn't crash, but once I shut it down and powered up again, it crashed 10 seconds in.

Also, I'm calling InputCheck() at the beginning of my main loop, could it affect anything? Should I move it after the VSync() call?

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » June 29th, 2016, 7:59 am

Sorry for double posting, but I found something when I tried to run my project using NO$PSX:
Nocash PSX Kernel (c) 2008-2014 Martin Korth.
KERNEL SETUP!
Configuration : EvCB=10h TCB=04h
Read Path Table

BOOTSTRAP LOADER Type C Ver 2.1 03-JUL-1994
Read Directory 1
KERNEL SETUP!
Configuration : EvCB=10h TCB=04h
boot file : cdrom:PSX.EXE;1
EXEC:PC0(80017C20h) T_ADDR(80010000h) T_SIZE(00077800h)
boot address : 80017C20h 801FFF00h
Execute !

S_ADDR(801FFF00h) S_SIZE(00000000h)
ResetGraph:jtb=80087108,env=80087150
*** Simulated known Patch: missing_cop0r13 (6-opcode variant)
*** Simulated known Patch: suppress pad_card_auto_ack (even if enabled) (with nops)
*** Simulated known Patch: suppress_pad_error_handling (and get pad_enable) (nops)

PS-X Control PAD Driver Ver 3.0
Outdated PAD Stuff: TYPE 6 free button or flying-V form (ok)
Maybe it is related?

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » June 29th, 2016, 5:25 pm

You're using the NO$PSX kernel/BIOS. Anyway, no, that shouldn't be the reason why it's freezing. I never used the "InputCheck" function. If you send me your program, I will test it out for you and see if I can find anything. I will try it on my H2000 so I can see where it's freezing for you and what function is doing it.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 541
Joined: Nov 12, 2012
Contact:

Post by nocash » June 29th, 2016, 9:16 pm

The PSX Kernel allows to access controllers in two different ways, the "outdated" ones aren't supporting analog/dualshock controllers (unless the pads are in "digital" mode), see http://problemkaputt.de/psx-spx.htm#biosjoypadfunctions for details.
If you want to get the kernel to write data to the controller (ie. auto-activate analog mode, or control rumble motors), then you should also need the "patch_optional_pad_output:", see http://problemkaputt.de/psx-spx.htm#biospatches for details.
I don't know what exactly you want to do with the dualshock - but theoretically features like rumble & analog input shouldn't work with the outdated functions, and without the patch. I am only familar with hardware/kernel side, and don't know what one would have to do on compiler/library side.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » June 30th, 2016, 1:17 pm

Shadow,
That InputCheck() function is just something I wrote to handle the input stuff in my project, I guess it is the culprit here.
I'll try to replace it with the one you posted here:
http://www.psxdev.net/forum/viewtopic.p ... 5096#p5078
and see if it will work.

nocash,
Thanks for the links, I found out that I left a PadInit() call in a leftover function from when I didn't implement DualShock yet, once I removed the PadInit() call the "outdated" message didn't show up when booting the exe in no$psx.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » November 20th, 2019, 9:48 am

This problem came back to haunt me, even 3 years later.
I just tested my code on a real PlayStation just now, and again, I'm getting those crashes, it's a complete hang of the system.
They are the same symptoms: It will hang randomly, either right away, or a few moments later.

(It's the same code as above, if anyone could test it for me with a debugger, I can send the compiled EXE or the source code)

Edit:

I tried another code and it locks up even faster:

Code: Select all

static unsigned char padbuff[2][34];
static unsigned char align[6]= {
    0, 1, 0xFF, 0xFF, 0xFF, 0xFF
};

unsigned char* padi;
u_long padd;
int state;
int ids;

u_long g_pad;

/* Connected Controller Type */
static char* padstr[] = {
	"NO CONTROLLER", "MOUSE", "NEGI-CON", "KONAMI-GUN", "STANDARD CONTROLLER",
	"ANALOG STICK",	"NAMCO-GUN", "ANALOG CONTROLLER"
};

void InputInit()
{  
	PadInitDirect(padbuff[0],padbuff[1]);
	PadStartCom();
}

void InputCheck(void)
{
	padi = padbuff[0];
  padd = ~((padi[2]<<8) | (padi[3]));
  
  state = PadGetState(0x00);
  if(state == PadStateDiscon) {
    FntPrint("NO CONTROLLER\n" );
  } else {
    FntPrint("[%0d] %s\n", ids, padstr[ids] );
    switch((ids=PadInfoMode(0x00,InfoModeCurID,0))) {
      /* Digital Controller */
      case 4:
      FntPrint("STATE: %08x\n",padd);
      break;
      /* Analog Controller */
      case 7:
      if (PadInfoMode(0x00,InfoModeCurExID,0)) {

        /*// DUAL SHOCK //*/
        FntPrint("%02x %02x %02x %02x\n", padi[4], padi[5], padi[6], padi[7] );
        FntPrint("STATE: %08x\n",padd);
      }
      break;
      default:
      break;
    }
  }  
  g_pad = padd;
  
}

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » November 21st, 2019, 1:37 am

The controller logic is actually quite tricky to get functioning perfectly. It's best to look at the Sony examples and add printf's so you can see exactly where the lockup happens :)
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » November 21st, 2019, 3:55 am

I copied that code from sample\PAD\DUNGEON (the previous code was also from the samples, actually)
Even though I could add printfs it would do me no good, because the hang/crash only happens on my consoles (which are retail units, I have no way to see the debug messages coming from them) and even worse is the fact that the code works fine on all emulators I tested it on, the problem only happens when running on a real console.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » November 21st, 2019, 9:58 pm

Make a serial cable and add "AddSIO(9600)" after "ResetCallback()".
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » November 22nd, 2019, 4:09 am

I guess I'll have to mod it to add a serial cable internally then, Can't find any serial cables for the PS1.
I sent my PS1 phat for repair (SCPH-7001) and I'll ask the repair guy if he can mod a RS232 port in it.

Which one would you recommend me for the serial mod? The SCPH-7001 (has a serial and parallel port in the back) or the newer SCPH-103 (has no ports besides the video output and power connector)?

Now, the repair is going to take a while, since where I live the PS1 is still surprisingly popular (I found it out today at the repair shop), the repair is going to take up to a month.
Meanwhile maybe I could try something else,
What are the chances that this is being caused by PSY-Q itself? Maybe my PSY-Q installation is bad or maybe has mixed versions of the library in it, is it worth trying a clean install?

By the way, the same funny behavior still happens:
If it doesn't crash in the first minute, it won't crash at all. Left it running all night after it didn't crash in the first minute, and indeed it didn't crash at all.

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » November 22nd, 2019, 7:30 am

You can solder in an FTDI board and that will give you USB serial communications. Just need to solder Rx, Tx and GND. Search the forums. The info is all here for you. As for the code issue, you'll have to work it out because it could be anything that's causing the crash.
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

User avatar
ArthCarvalho
Active PSXDEV User
Active PSXDEV User
Posts: 45
Joined: Jan 29, 2016
I am a: Artist, Programmer
PlayStation Model: SCPH-103

Post by ArthCarvalho » January 1st, 2020, 11:58 pm

I think I found the solution for this one. It was my fault of course, still, I think it is important to point this out for anyone else that might be having the same problem as me:

I had commented out the CdInit() function because I thought I didn't need to initialize it since I was not loading files, and mednafen will crash if CdInit() is called and you load an EXE directly, but apparently the game will crash on real hardware if you don't.

So if you want to test your game using Mednafen (And by extension, RetroArch with Beetle PSX HW) without building an ISO, you need to comment out CdInit/DsInit() for it to work. If you are building an ISO, even if you don't use it, you will still need to initialize the CD-ROM subsytem or the game will crash 99% of the time.

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests