#define CSA2_config_p		((unsigned int *) 0xfffff11A)
		/* CSA2 config register */
#define CSA2_config_w		((unsigned int) 0x1f02)
		/* turn off read-only bit */
		/* (default value is 0x1f0a. 0x1f is mask, 0x02 is wait states */
#define PICPSP_p			((unsigned int *) 0x10e00000)
	/* I/O "register" for PIC parallel */
	/* slave port. We use the first word of CSA2's memory space.
	 * we write 16-bit words to an address that triggers CSA2, which is
	 * the PIC's chip-select line. We use 16-bit words because 8-bit
	 * I/O on the Dragonball uses D8-D15, and the PIC is wired to D0-D7.
	 */

/*
#define pic_delay()			{ int _i; for (_i=0; _i<30; _i++);}
#define pic_delay()			{}
*/
#define PIC_MAX_TRIES		200
	/* how many times we'll poll waiting for PIC to reach a given state */

#include <Pilot.h>			/* for the bad-read sound */
#include "fiatSymbols.h"

void statusMessage(char *s);
#include "fiatOperations.h"

void pic_init()
{
	unsigned int *p = CSA2_config_p;	/* CSA2 config register */
	unsigned int w = CSA2_config_w;	/* turn off read-only bit */

	*p = w;
}

int pic_wait_state(int state)
{
	unsigned int *p = PICPSP_p;
	int i, data;

	for (i=0; i<PIC_MAX_TRIES; i++) {
		data = *p;
		if ((data & 0xf0) == state) {
			return (data&0x0f);
		}
	}
	statusMessage("wait_state timed out");
	SndPlaySystemSound(sndClick);
	return -1;	/* timeout */
}

void pic_reset()
{
	pic_wait_state(SYM_ADDR_WAIT);
	/* read junk until we are in ADDR_WAIT state */
	/* this routine is only used if you have some reason to believe
	 * the I/O sequence to the PIC has been messed up. */
}

int pic_read(int addr)
{
	unsigned int *p = PICPSP_p;
	int data_hi, data_lo, data;

	pic_wait_state(SYM_ADDR_WAIT);
	*p = addr;	/* write to PIC register addr to read */
	data_hi = pic_wait_state(SYM_RDHI_RDWAIT);
	if (data_hi == -1)
		return -1;
	data_lo = pic_wait_state(SYM_RDLO_WAIT);
	if (data_hi == -1)
		return -1;
	/* combine data nybbles */
	data = (data_hi<<4) | data_lo;
	return data;
}

int pic_write(int addr, int data)
{
	unsigned int *p = PICPSP_p;
	int rc;

	pic_wait_state(SYM_ADDR_WAIT);
	*p = addr;		/* write to PIC register addr we want to write to */
	rc = pic_wait_state(SYM_RDHI_RDWAIT);
	if (rc == -1)
		return -1;
	*p = data;		/* write to PIC the value we want written */
	return 0;		/* indicate success */
}

int pic_read2(int addr)
{
	int dhi, dlo;

	do {
		dhi = pic_read(addr);
		dlo = pic_read(addr+1);
	} while (pic_read(addr) != dhi);
	return (dhi<<8) | (dlo & 0x0ff);
}

void pic_write2(int addr, int data)
{
	pic_write(addr, (data>>8) & 0xff);
	pic_write(addr+1, data & 0xff);
}
