mirror of
https://github.com/raphnet/4nes4snes
synced 2025-03-11 06:50:17 -04:00
Added fourscore support
This commit is contained in:
parent
b8783c060e
commit
4c4ad386e5
@ -1,3 +1,7 @@
|
|||||||
|
--- v1.2 (May 2, 2009)
|
||||||
|
Added NES fourscore support. When a fourscore is detected in port 1, fourscore
|
||||||
|
mode is entered and ports 1 and 2 are used to read up to 4 NES controllers.
|
||||||
|
|
||||||
--- v1.1 (18 Apr 2007)
|
--- v1.1 (18 Apr 2007)
|
||||||
- Changed report descriptor. There are now four separate report IDs, one
|
- Changed report descriptor. There are now four separate report IDs, one
|
||||||
per controller. This was necessary because even though all axis and buttons
|
per controller. This was necessary because even though all axis and buttons
|
||||||
|
18
Makefile
18
Makefile
@ -5,17 +5,17 @@
|
|||||||
# Tabsize: 4
|
# Tabsize: 4
|
||||||
# Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
# Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
# License: Proprietary, free under certain conditions. See Documentation.
|
# License: Proprietary, free under certain conditions. See Documentation.
|
||||||
# This Revision: $Id: Makefile,v 1.2 2008-03-30 15:21:39 raph Exp $
|
# This Revision: $Id: Makefile,v 1.3 2009-05-02 12:07:45 cvs Exp $
|
||||||
|
|
||||||
UISP = uisp -dprog=stk500 -dpart=atmega8 -dserial=/dev/avr
|
UISP = uisp -dprog=stk500 -dpart=atmega8 -dserial=/dev/avr
|
||||||
COMPILE = avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 #-DDEBUG_LEVEL=1
|
COMPILE = avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 #-DDEBUG_LEVEL=1
|
||||||
COMMON_OBJS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
|
COMMON_OBJS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o
|
||||||
|
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o snes.o devdesc.o
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o snes.o devdesc.o
|
||||||
|
HEXFILE=main.hex
|
||||||
|
|
||||||
# symbolic targets:
|
# symbolic targets:
|
||||||
all: main.hex
|
all: $(HEXFILE)
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(COMPILE) -c $< -o $@
|
$(COMPILE) -c $< -o $@
|
||||||
@ -32,20 +32,20 @@ all: main.hex
|
|||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.bin *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
|
rm -f $(HEXFILE) main.lst main.obj main.cof main.list main.map main.eep.hex main.bin *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
|
||||||
|
|
||||||
# file targets:
|
# file targets:
|
||||||
main.bin: $(COMMON_OBJS) snes.o devdesc.o
|
main.bin: $(COMMON_OBJS) snes.o devdesc.o
|
||||||
$(COMPILE) -o main.bin $(OBJECTS) -Wl,-Map=main.map
|
$(COMPILE) -o main.bin $(OBJECTS) -Wl,-Map=main.map
|
||||||
|
|
||||||
main.hex: main.bin
|
$(HEXFILE): main.bin
|
||||||
rm -f main.hex main.eep.hex
|
rm -f $(HEXFILE) main.eep.hex
|
||||||
avr-objcopy -j .text -j .data -O ihex main.bin main.hex
|
avr-objcopy -j .text -j .data -O ihex main.bin $(HEXFILE)
|
||||||
./checksize main.bin
|
./checksize main.bin
|
||||||
|
|
||||||
flash: all
|
flash: all
|
||||||
#$(UISP) --erase --upload --verify if=main.hex
|
#$(UISP) --erase --upload --verify if=$(HEXFILE)
|
||||||
$(UISP) --erase --upload if=main.hex
|
$(UISP) --erase --upload if=$(HEXFILE)
|
||||||
|
|
||||||
flash_usb:
|
flash_usb:
|
||||||
sudo avrdude -p m8 -P usb -c avrispmkII -Uflash:w:$(HEXFILE) -B 1.0
|
sudo avrdude -p m8 -P usb -c avrispmkII -Uflash:w:$(HEXFILE) -B 1.0
|
||||||
|
126
snes.c
126
snes.c
@ -61,6 +61,45 @@ static unsigned char last_reported_controller_bytes[GAMEPAD_BYTES];
|
|||||||
|
|
||||||
// indicates if a controller is in NES mode
|
// indicates if a controller is in NES mode
|
||||||
static unsigned char nesMode=0; /* Bit0: controller 1, Bit1: controller 2...*/
|
static unsigned char nesMode=0; /* Bit0: controller 1, Bit1: controller 2...*/
|
||||||
|
static unsigned char fourscore_mode = 0;
|
||||||
|
|
||||||
|
static void autoDetectFourScore(void)
|
||||||
|
{
|
||||||
|
unsigned char dat18th_low = 0;
|
||||||
|
unsigned char hc=0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
SNES_LATCH_HIGH();
|
||||||
|
_delay_us(12);
|
||||||
|
SNES_LATCH_LOW();
|
||||||
|
|
||||||
|
for (i=0; i<24; i++)
|
||||||
|
{
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_LOW();
|
||||||
|
|
||||||
|
if (!SNES_GET_DATA1()) {
|
||||||
|
if (i==19) {
|
||||||
|
dat18th_low = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dat18th_low && hc == 23) {
|
||||||
|
// only 18th data bit was low. Looks like a FOUR SCORE.
|
||||||
|
fourscore_mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void snesInit(void)
|
static void snesInit(void)
|
||||||
{
|
{
|
||||||
@ -112,6 +151,8 @@ static void snesInit(void)
|
|||||||
if (last_read_controller_bytes[7]==0xFF)
|
if (last_read_controller_bytes[7]==0xFF)
|
||||||
nesMode |= 8;
|
nesMode |= 8;
|
||||||
|
|
||||||
|
autoDetectFourScore();
|
||||||
|
|
||||||
SREG = sreg;
|
SREG = sreg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +192,58 @@ static void snesUpdate(void)
|
|||||||
_delay_us(12);
|
_delay_us(12);
|
||||||
SNES_LATCH_LOW();
|
SNES_LATCH_LOW();
|
||||||
|
|
||||||
|
if (fourscore_mode)
|
||||||
|
{
|
||||||
|
/* Nes controller buttons are sent in this order:
|
||||||
|
* One byte: A B SEL START UP DOWN LEFT RIGHT */
|
||||||
|
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_LOW();
|
||||||
|
|
||||||
|
// FourScore to be connected to ports 1 and 2
|
||||||
|
tmp1 <<= 1;
|
||||||
|
tmp2 <<= 1;
|
||||||
|
if (!SNES_GET_DATA1()) { tmp1 |= 1; }
|
||||||
|
if (!SNES_GET_DATA2()) { tmp2 |= 1; }
|
||||||
|
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_LOW();
|
||||||
|
|
||||||
|
// FourScore to be connected to ports 1 and 2
|
||||||
|
tmp3 <<= 1;
|
||||||
|
tmp4 <<= 1;
|
||||||
|
if (!SNES_GET_DATA1()) { tmp3 |= 1; }
|
||||||
|
if (!SNES_GET_DATA2()) { tmp4 |= 1; }
|
||||||
|
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_LOW();
|
||||||
|
|
||||||
|
_delay_us(6);
|
||||||
|
SNES_CLOCK_HIGH();
|
||||||
|
}
|
||||||
|
last_read_controller_bytes[0] = tmp1;
|
||||||
|
last_read_controller_bytes[1] = tmp2;
|
||||||
|
last_read_controller_bytes[2] = tmp3;
|
||||||
|
last_read_controller_bytes[3] = tmp4;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i=0; i<8; i++)
|
for (i=0; i<8; i++)
|
||||||
{
|
{
|
||||||
_delay_us(6);
|
_delay_us(6);
|
||||||
@ -166,7 +259,6 @@ static void snesUpdate(void)
|
|||||||
if (!SNES_GET_DATA4()) { tmp4 |= 1; }
|
if (!SNES_GET_DATA4()) { tmp4 |= 1; }
|
||||||
|
|
||||||
_delay_us(6);
|
_delay_us(6);
|
||||||
|
|
||||||
SNES_CLOCK_HIGH();
|
SNES_CLOCK_HIGH();
|
||||||
}
|
}
|
||||||
last_read_controller_bytes[0] = tmp1;
|
last_read_controller_bytes[0] = tmp1;
|
||||||
@ -208,6 +300,10 @@ static char snesChanged(char report_id)
|
|||||||
{
|
{
|
||||||
report_id--; // first report is 1
|
report_id--; // first report is 1
|
||||||
|
|
||||||
|
if (fourscore_mode) {
|
||||||
|
return last_read_controller_bytes[report_id] != last_reported_controller_bytes[report_id];
|
||||||
|
}
|
||||||
|
|
||||||
return memcmp( &last_read_controller_bytes[report_id<<1],
|
return memcmp( &last_read_controller_bytes[report_id<<1],
|
||||||
&last_reported_controller_bytes[report_id<<1],
|
&last_reported_controller_bytes[report_id<<1],
|
||||||
2);
|
2);
|
||||||
@ -246,7 +342,7 @@ static unsigned char snesReorderButtons(unsigned char bytes[2])
|
|||||||
|
|
||||||
static char snesBuildReport(unsigned char *reportBuffer, char id)
|
static char snesBuildReport(unsigned char *reportBuffer, char id)
|
||||||
{
|
{
|
||||||
char idx;
|
int idx;
|
||||||
|
|
||||||
if (id < 0 || id > 4)
|
if (id < 0 || id > 4)
|
||||||
return 0;
|
return 0;
|
||||||
@ -264,8 +360,34 @@ static char snesBuildReport(unsigned char *reportBuffer, char id)
|
|||||||
*
|
*
|
||||||
* [6] : controller 4, 8 first bits
|
* [6] : controller 4, 8 first bits
|
||||||
* [7] : controller 4, 4 extra snes buttons
|
* [7] : controller 4, 4 extra snes buttons
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* last_read_controller_bytes[] structure in FOUR SCORE mode:
|
||||||
|
*
|
||||||
|
* A B SEL START UP DOWN LEFT RIGHT
|
||||||
|
*
|
||||||
|
* [0] : NES controller 1 data
|
||||||
|
* [1] : NES controller 2 data
|
||||||
|
* [2] : NES controller 3 data
|
||||||
|
* [3] : NES controller 4 data
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (fourscore_mode) {
|
||||||
|
idx = id - 1;
|
||||||
|
if (reportBuffer != NULL)
|
||||||
|
{
|
||||||
|
reportBuffer[0]=id;
|
||||||
|
reportBuffer[1]=getX(last_read_controller_bytes[idx]);
|
||||||
|
reportBuffer[2]=getY(last_read_controller_bytes[idx]);
|
||||||
|
reportBuffer[3] = last_read_controller_bytes[idx] & 0xf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_reported_controller_bytes[idx] = last_read_controller_bytes[idx];
|
||||||
|
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
idx = id - 1;
|
idx = id - 1;
|
||||||
if (reportBuffer != NULL)
|
if (reportBuffer != NULL)
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: Proprietary, free under certain conditions. See Documentation.
|
* License: Proprietary, free under certain conditions. See Documentation.
|
||||||
* This Revision: $Id: usbconfig.h,v 1.5 2007-04-18 23:58:01 raph Exp $
|
* This Revision: $Id: usbconfig.h,v 1.6 2009-05-02 12:07:46 cvs Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
@ -102,7 +102,7 @@ must be adapted to your hardware.
|
|||||||
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
* USBID-License.txt!
|
* USBID-License.txt!
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_VERSION 0x01, 0x01
|
#define USB_CFG_DEVICE_VERSION 0x02, 0x01
|
||||||
/* Version number of the device: Minor number first, then major number.
|
/* Version number of the device: Minor number first, then major number.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_VENDOR_NAME 'r', 'a', 'p', 'h', 'n', 'e', 't', '.', 'n', 'e', 't'
|
#define USB_CFG_VENDOR_NAME 'r', 'a', 'p', 'h', 'n', 'e', 't', '.', 'n', 'e', 't'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user