1
0
mirror of https://github.com/raphnet/4nes4snes synced 2025-03-11 06:50:17 -04:00

Added fourscore support

This commit is contained in:
Raphaël Assénat 2009-05-02 12:07:45 +00:00
parent b8783c060e
commit 4c4ad386e5
4 changed files with 139 additions and 13 deletions

View File

@ -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

View File

@ -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
View File

@ -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)
{ {

View File

@ -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'