/*

 NES.c - read a single byte from a standard NES controller

 Ethan Dicks	<erd@kumiss.UUCP>

 Version 1.0  24-Mar-1992


 This code is a slightly repackaged version of both the Amiga PowerGlove
 code and the original Atari lores PowerGlove code.  It still does not
 properly request the parallel port from the OS, so use it at your
 own risk.  The original comment block from glovehack.c is included
 below, typos and all.

 I AM NOT RESPONSIBLE FOR YOUR HARDWARE.  USE THIS AT YOUR OWN RISK
 NO WARRANTY IS EXPRESSED OR IMPLIED.  USE NO HOOKS.  POST NO BILLS.

*/

 
/**********************************************************************
 
	This ugly hack is based on the ATARI 1040ST power glove
	hack by  manfredo@opal.cs.tu-berlin.de.
 
 	This program is without any WARRANTY use at your OWN risk
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
	This Amiga hack was done by Alan Bland.  It is not directly
	compatible with the AC Tech hack, the BYTE hack, nor the
	ATARI 1040ST hack, but you should be able to modify the
	code to work with any of those hacks.

	The Amiga code is ugly, as was the original ST code.  The
	parallel port hardware is accessed directly without knowledge
	of the operating system.

	Connect NINTENDO POWERGLOVE to Amiga parallel port
          ------
         /   1 |
	| 5  2 |
	| 6  3 |
	| 7  4 |
	--------

	GLOVE                       AMIGA
	=====                       =====

	GND pin1                    pin18 parallel port

	clock pin2                  pin2  parallel port

 	latch pin3                  pin3  parallel port

	data pin4                   pin4  parallel port

	+5V pin7                    pin14 power +5V


**********************************************************************/


#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <hardware/cia.h>
#include <resources/cia.h>

#include <proto/exec.h>

#include "timer.h"
#include "NES.h"

/* bits from parallel port -- Alan's hack */
#define		GDATA           0x04    /* glove data in */
#define		GLATCH          0x02    /* glove latch out */
#define		GCLOCK          0x01    /* glove clock out */
#define		GCLOLAT         (GLATCH|GCLOCK) /* latch and clock */

#define getbit()  	(ciaa.ciaprb & GDATA) >> 2
#define initport()	ciaa.ciaddrb = GCLOLAT

#define     C0L0()       ciaa.ciaprb = 0        /* clock 0 latch 0 */
#define     C0L1()       ciaa.ciaprb = GLATCH   /* clock 0 latch 1 */
#define     C1L0()       ciaa.ciaprb = GCLOCK   /* clock 1 latch 0 */
#define     C1L1()       ciaa.ciaprb = GCLOLAT  /* clock 1 latch 1 */

#define     setporta()	delay(3)
#define     setportb()  delay(3)

/* convert microseconds to cia ticks */
#define delay(usec) timersleep((usec*1397)/1000)

int control_c()
{
	closetimer();
	printf("<<goodbye>>\n");
	return 1; /* causes exit */
}

UBYTE query_NES()
{
	register unsigned char Data = 0;
	register int i;

	setportb();
/*
 * First, send a RESET pulse (L-H-L), a minimum of 4 uSec long.
 */
	C1L0();
	delay(5);			/* 5 us delay */
	C1L1();
	delay(5);			/* 5 us delay */
	C1L0();

/*
 * Now, CLOCK (L-H-L) the data in, at a minimum of 3 uSec per clock pulse
*/
	for (i = 0; i < 8; i++) {
		setporta ();	/* configure port a as input */
		Data <<= 1;	/* read a bit */
		Data |= getbit();
		setportb ();	/* prepare port b as output port */
		C0L0 ();	/* generate a clock pulse */
		delay(3);
		C1L0 ();
		delay(3);
	}
	return ( (unsigned char)(Data & 0377));
}


void init_NES()
{

	opentimer();
	onbreak(control_c);

	/* initialize hardware interface */
	initport();
}
