/* Experimental SPI EEPROM interface for the TI89 */
/* http://lekernel.lya-fr.com/ */

#define USE_TI89
#define MIN_AMS 200

#define OPTIMIZE_ROM_CALLS
#define SAVE_SCREEN
#define NO_EXIT_SUPPORT

#include <tigcclib.h>

#define LINK_REGISTER 0x60000C
#define LINK_PORT 0x60000E
#define LINK_CLOCK_BIT 0
#define LINK_DATA_OUT_BIT 1
#define LINK_DATA_IN_BIT 3

#define clock_h() pokeIO_bclr(LINK_PORT, LINK_CLOCK_BIT)
#define clock_l() pokeIO_bset(LINK_PORT, LINK_CLOCK_BIT)
#define data_h() pokeIO_bclr(LINK_PORT, LINK_DATA_OUT_BIT)
#define data_l() pokeIO_bset(LINK_PORT, LINK_DATA_OUT_BIT)
#define data_r() !peekIO_bit(LINK_PORT, LINK_DATA_IN_BIT)

static void SPI_init()
{
  pokeIO(LINK_REGISTER, 0);
  pokeIO_bset(LINK_REGISTER, 6);
  pokeIO(LINK_PORT, 0);
  pokeIO_bset(LINK_PORT, 6);
  
  clock_h();
  data_h();
}

static void SPI_send(char *buffer, unsigned int length)
{
  unsigned int i, j;
 
  for(i=0; i<length; i++) {
    for(j=0; j<8; j++) {
      clock_l();
      if((*buffer & (128 >> j)) != 0) data_h(); else data_l();
      clock_h();
    }
    buffer++;
  }
  data_h();
  clock_l();
}

static void SPI_recv(char *buffer, unsigned int length)
{
unsigned int i, j;
  
  data_h();
  memset(buffer, 0, length);
  for(i=0; i<length; i++) {
    for(j=0; j<8; j++) {
      clock_l();
      clock_h();
      if(data_r()) *buffer |= (128 >> j);
    }
    buffer++;
  }
  clock_l();
}

static void SPI_select()
{
  unsigned int i;
  
  clock_l();
  OSUnregisterTimer(USER_TIMER);
  OSRegisterTimer(USER_TIMER, 1);
  while(!OSTimerExpired(USER_TIMER));
}

static void SPI_deselect()
{
  unsigned int i;
  
  clock_h();
  OSUnregisterTimer(USER_TIMER);
  OSRegisterTimer(USER_TIMER, 1);
  while(!OSTimerExpired(USER_TIMER));
}

static void SPI_done()
{
  OSLinkReset();
}

#define M95256_RDSR 0b00000101
#define M95256_READ 0b00000011

void _main()
{
  unsigned char buffer[256];
  unsigned int i, j;
 
  ClrScr();
  printf("\nDump EEPROM\nAppuyer sur une touche\n");
  SPI_init();
  ngetchx();
  SPI_select();
  buffer[0] = M95256_READ;
  buffer[1] = 0;
  buffer[2] = 0;
  SPI_send(&buffer[0], 3);
  for(i=0; i<125; i++) {
    SPI_recv(&buffer[0], 256);
    for(j=0; j<256; j++) if(buffer[j] != '\n') putchar(buffer[j]);
    if(ngetchx() != KEY_ENTER) break;
  }
  SPI_done();
}
