Sega Genesis Dev Kit (SGDK)
Moderator: Stef
It is a pity.KanedaFr wrote:short answer : no
long answer : not yet.
I have a WIP update for 6 buttons, TPlay, EA and mouse support.
I also bought a pink justifier to add justifier support too (and still looking for a cheap menacer)
But since I can't test it on real hardware, it's waiting on my hard drive for 1 year now
Why not to buy Flash cartridge for the test?
-
- Very interested
- Posts: 2993
- Joined: Fri Aug 17, 2007 9:33 pm
No, more like
Code: Select all
void sleepFrames(u16 frame)
{
while (frames--)
VDP_waitVSync();
}
-
- Very interested
- Posts: 2993
- Joined: Fri Aug 17, 2007 9:33 pm
For six button support, try this:
That should work... it's based on working code and compiles without error - I even examined the generated assembly. However, there's no joystick test example and I'm too lazy to make one.
Remember that JOY_Init() sets both ports to 3 button mode. You need to call JOY_setSupport(port, JOY_SUPPORT_6BTN) to switch to 6 button reading. The function will then return all the buttons as already defined in joy.h. If you read a 3 button stick in 6 button mode, it still works, but it's slower than using 3 button mode. You can tell 3 button sticks from 6 button by reading the port in 6 button mode - if there really is a 6 buttons stick there, the upper nibble is a 1, otherwise it's a 0. So you might do something like this:
That sets port 1 to 6 button, checks if there is a six button pad, and turns it back to 3 button if there isn't.
Code: Select all
static u16 readJoypad(u16 joy)
{
vu8 *pb;
u16 i, j, k;
if (joy < 2)
{
pb = (u8 *) (0xA10003 + (joy * 2));
if (portSupport[joy] == JOY_SUPPORT_3BTN)
{
asm("move.b #0x00,(%2)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%2),%0\n\t"
"move.b #0x40,(%2)\n\t"
"lsl.b #2,%0\n\t"
"andi.w #0xC0,%0\n\t"
"move.b (%2),%1\n\t"
"andi.w #0x3F,%1\n\t"
"or.b %1,%0\n\t"
"eori.b #0xFF,%0\n\t"
: "=d" (i), "=d" (j)
: "a" (pb)
: );
return i;
}
if (portSupport[joy] == JOY_SUPPORT_6BTN)
{
asm("move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%1\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%2\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"andi.w #0x0F00,%0\n\t"
"cmpi.w #0x0F00,%0\n\t"
"beq.b common\n\t"
"move.w #0x010F,%2\n"
"common:\n\t"
"lsl.b #4,%2\n\t"
"lsl.w #4,%2\n\t"
"andi.w #0x303F,%1\n\t"
"move.b %1,%2\n\t"
"lsr.w #6,%1\n\t"
"or.w %1,%2\n\t"
"eori.w #0x1FFF,%2\n\t"
: "=d" (i), "=d" (j), "=d" (k)
: "a" (pb)
: );
return k;
}
}
else if (joy < 6) // teamplay 1
{
// not yet supported
return 0;
}
else if (joy < 9) // teamplay 2
{
// not yet supported
return 0;
}
return 0;
}

Remember that JOY_Init() sets both ports to 3 button mode. You need to call JOY_setSupport(port, JOY_SUPPORT_6BTN) to switch to 6 button reading. The function will then return all the buttons as already defined in joy.h. If you read a 3 button stick in 6 button mode, it still works, but it's slower than using 3 button mode. You can tell 3 button sticks from 6 button by reading the port in 6 button mode - if there really is a 6 buttons stick there, the upper nibble is a 1, otherwise it's a 0. So you might do something like this:
Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_update();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
Chilly Willy wrote:For six button support, try this:
That should work... it's based on working code and compiles without error - I even examined the generated assembly. However, there's no joystick test example and I'm too lazy to make one.Code: Select all
static u16 readJoypad(u16 joy) { vu8 *pb; u16 i, j, k; if (joy < 2) { pb = (u8 *) (0xA10003 + (joy * 2)); if (portSupport[joy] == JOY_SUPPORT_3BTN) { asm("move.b #0x00,(%2)\n\t" "nop\n\t" "nop\n\t" "move.b (%2),%0\n\t" "move.b #0x40,(%2)\n\t" "lsl.b #2,%0\n\t" "andi.w #0xC0,%0\n\t" "move.b (%2),%1\n\t" "andi.w #0x3F,%1\n\t" "or.b %1,%0\n\t" "eori.b #0xFF,%0\n\t" : "=d" (i), "=d" (j) : "a" (pb) : ); return i; } if (portSupport[joy] == JOY_SUPPORT_6BTN) { asm("move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.w %0,%1\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.w %0,%2\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "andi.w #0x0F00,%0\n\t" "cmpi.w #0x0F00,%0\n\t" "beq.b common\n\t" "move.w #0x010F,%2\n" "common:\n\t" "lsl.b #4,%2\n\t" "lsl.w #4,%2\n\t" "andi.w #0x303F,%1\n\t" "move.b %1,%2\n\t" "lsr.w #6,%1\n\t" "or.w %1,%2\n\t" "eori.w #0x1FFF,%2\n\t" : "=d" (i), "=d" (j), "=d" (k) : "a" (pb) : ); return k; } } else if (joy < 6) // teamplay 1 { // not yet supported return 0; } else if (joy < 9) // teamplay 2 { // not yet supported return 0; } return 0; }
![]()
Remember that JOY_Init() sets both ports to 3 button mode. You need to call JOY_setSupport(port, JOY_SUPPORT_6BTN) to switch to 6 button reading. The function will then return all the buttons as already defined in joy.h. If you read a 3 button stick in 6 button mode, it still works, but it's slower than using 3 button mode. You can tell 3 button sticks from 6 button by reading the port in 6 button mode - if there really is a 6 buttons stick there, the upper nibble is a 1, otherwise it's a 0. So you might do something like this:
That sets port 1 to 6 button, checks if there is a six button pad, and turns it back to 3 button if there isn't.Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN); JOY_update(); if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000) JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
This code doesn't work.
-
- Very interested
- Posts: 2993
- Joined: Fri Aug 17, 2007 9:33 pm
Okay, I'll make an example and check it.
EDIT: Okay - worked out any problems. The assembly was fine, but the Windows gcc included with sgdk doesn't like an empty clobber list, so I stuck in something to get it to pass. Other things I found:
joy.h has BUTTON_X and BUTTON_Z swapped. Reverse them.
You need to wait at least one vblank after setting the port support type for the vblank to automatically call JOY_update() - if you call it yourself, you can wind up with the wrong pad ID since you may wind up calling update just before or just after vblank does, screwing up the six button pad timing for reset for next packet. I wait two vblanks just to be safe.
JOY_init() was setting the directions, but not the values.
So... file changes:
joy.c
and
joy.h
Recompile the library and then here's a joypad test program:
Do all that and it will work fine for three and six button pads. Tested and verified on Fusion, Gens/GS, and on real hardware.
EDIT: Okay - worked out any problems. The assembly was fine, but the Windows gcc included with sgdk doesn't like an empty clobber list, so I stuck in something to get it to pass. Other things I found:
joy.h has BUTTON_X and BUTTON_Z swapped. Reverse them.
You need to wait at least one vblank after setting the port support type for the vblank to automatically call JOY_update() - if you call it yourself, you can wind up with the wrong pad ID since you may wind up calling update just before or just after vblank does, screwing up the six button pad timing for reset for next packet. I wait two vblanks just to be safe.
JOY_init() was setting the directions, but not the values.
So... file changes:
joy.c
Code: Select all
void JOY_init()
{
vu8 *pb;
/* set the port bits direction */
pb = (u8 *) 0xa10009;
*pb = 0x40;
pb += 2;
*pb = 0x40;
pb += 2;
*pb = 0x40;
/* set the port bits value */
pb = (u8 *) 0xa10003;
*pb = 0x40;
pb += 2;
*pb = 0x40;
pb += 2;
*pb = 0x40;
memset(joyState, 0, sizeof(joyState));
portSupport[PORT_1] = JOY_SUPPORT_3BTN;
portSupport[PORT_2] = JOY_SUPPORT_3BTN;
joyEventCB = NULL;
}
Code: Select all
static u16 readJoypad(u16 joy)
{
vu8 *pb;
u16 i, j, k;
if (joy < 2)
{
pb = (u8 *) (0xA10003 + (joy * 2));
if (portSupport[joy] == JOY_SUPPORT_3BTN)
{
asm("move.b #0x00,(%2)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%2),%0\n\t"
"move.b #0x40,(%2)\n\t"
"lsl.b #2,%0\n\t"
"andi.w #0xC0,%0\n\t"
"move.b (%2),%1\n\t"
"andi.w #0x3F,%1\n\t"
"or.b %1,%0\n\t"
"eori.b #0xFF,%0\n\t"
: "=d" (i), "=d" (j)
: "a" (pb)
: "0" );
return i;
}
if (portSupport[joy] == JOY_SUPPORT_6BTN)
{
asm("move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%1\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%2\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"andi.w #0x0F00,%0\n\t"
"cmpi.w #0x0F00,%0\n\t"
"beq.b common\n\t"
"move.w #0x010F,%2\n"
"common:\n\t"
"lsl.b #4,%2\n\t"
"lsl.w #4,%2\n\t"
"andi.w #0x303F,%1\n\t"
"move.b %1,%2\n\t"
"lsr.w #6,%1\n\t"
"or.w %1,%2\n\t"
"eori.w #0x1FFF,%2\n\t"
: "=d" (i), "=d" (j), "=d" (k)
: "a" (pb)
: "0" );
return k;
}
}
else if (joy < 6) // teamplay 1
{
// not yet supported
return 0;
}
else if (joy < 9) // teamplay 2
{
// not yet supported
return 0;
}
return 0;
}
Code: Select all
#define BUTTON_X 0x0400
#define BUTTON_Y 0x0200
#define BUTTON_Z 0x0100
Code: Select all
#include "genesis.h"
static void printButton(char c, u16 state);
static void showPortState();
static u16 posY, posX;
int main(int cold_start)
{
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
VDP_setScreenWidth320();
VDP_setHInterrupt(0);
VDP_setHilightShadow(0);
VDP_setPaletteColor(PAL1, 15, 0x0888);
VDP_setTextPalette(0);
VDP_drawText("Current Joy Port State", 10, 1);
VDP_clearTileMapRect(APLAN, 0, 3, 40, 8);
showPortState();
while(1)
{
showPortState();
VDP_waitVSync();
}
}
static void printButton(char c, u16 state)
{
char temp[2];
temp[0] = c;
temp[1] = 0;
VDP_setTextPalette(state ? 1 : 0);
VDP_drawText(temp, posX, posY);
posX += 2;
}
static void showPortState()
{
u16 i;
posY = 5;
for(i = JOY_1; i <= JOY_2; i++)
{
u16 value;
posX = 2;
VDP_setTextPalette(0);
VDP_drawText((i == JOY_1) ? "port 1:" : "port 2:", posX, posY);
posX += 8;
value = JOY_readJoypad(i);
printButton('U', value & BUTTON_UP);
printButton('D', value & BUTTON_DOWN);
printButton('L', value & BUTTON_LEFT);
printButton('R', value & BUTTON_RIGHT);
printButton('A', value & BUTTON_A);
printButton('B', value & BUTTON_B);
printButton('C', value & BUTTON_C);
printButton('S', value & BUTTON_START);
if ((value & 0xF000) == 0x1000)
{
/* six button pad */
printButton('X', value & BUTTON_X);
printButton('Y', value & BUTTON_Y);
printButton('Z', value & BUTTON_Z);
printButton('M', value & BUTTON_MODE);
}
posY++;
}
}
-
- Very interested
- Posts: 2993
- Joined: Fri Aug 17, 2007 9:33 pm
Actually, part of the start of that test program could be redone like this:
EDIT: Also, that first showPortState() isn't needed, so just make main() this:
Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
Code: Select all
int main(int cold_start)
{
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
VDP_setScreenWidth320();
VDP_setHInterrupt(0);
VDP_setHilightShadow(0);
VDP_setPaletteColor(PAL1, 15, 0x0888);
VDP_setTextPalette(0);
VDP_drawText("Current Joy Port State", 10, 1);
VDP_clearTileMapRect(APLAN, 0, 3, 40, 8);
while(1)
{
showPortState();
VDP_waitVSync();
}
}
-
- Very interested
- Posts: 2993
- Joined: Fri Aug 17, 2007 9:33 pm