////////////////////////////////////////////////////////////
//	Created:		28 July 2005
//	Author(s):	Tang Tung Yan
// Company:		Softlogic Electronic
//	Revision:	0
//	C-Compiler:	Dynamic C
//
//	Purpose:	Sample Program utilising
//				(1) PLI-004 	RCM2000 series Core Module (Rabbit2000 Microprocessor)
//				(2) PLM-013 	24x5 Dot Matrix

// Dot Matrix Pin:
//	PA0 to PA4	Bit-0 to Bit-4 of LED Row
//	PA5			Data Head
// PA6			Clock
// PA7			Reset

//	Copyrights(c) 2005 	Softlogic Electronic
//								www.slge.com
////////////////////////////////////////////////////////////

#use "slge.lib"

//define for A to Z alphabet
const char ASCII[32][3]={};
const char SPACE[1][3]={{0x00,0x00,0x00}};
const char ASCII2[32][3]={};
const char A_TO_Z[26][3]= {
{0x1e,0x05,0x1e},
{0x18,0x15,0x0a},
{0x0e,0x11,0x11},
{0x1f,0x11,0x0e},
{0x1f,0x15,0x11},
{0x1f,0x05,0x01},
{0x0e,0x15,0x1d},
{0x1f,0x04,0x1f},
{0x11,0x1f,0x11},
{0x09,0x11,0x0f},
{0x1f,0x04,0x1b},
{0x1f,0x10,0x10},
{0x1f,0x02,0x1f},
{0x1f,0x06,0x1f},
{0x0e,0x11,0x0e},
{0x1f,0x05,0x02},
{0x0e,0x19,0x1e},
{0x1f,0x05,0x1a},
{0x12,0x15,0x09},
{0x01,0x1f,0x01},
{0x1f,0x10,0x1f},
{0x0f,0x10,0x0f},
{0x1f,0x08,0x1f},
{0x1b,0x04,0x1b},
{0x03,0x1c,0x03},
{0x19,0x15,0x13}
};
const char ASCII3[165][3]={};

const char acString[]="HELLO WORLD      ";

#define LAST_COL 24
//=============================================================================
init()
{
	WrPortI(PADR, &PADRShadow, 0x00);
   WrPortI(PDDR, &PDDRShadow, 0x00);
   WrPortI(PEDR, &PEDRShadow, 0x00);
}

//=============================================================================
main()
{
	int r;

   char cChar;						//looping for # of char in string
   char cCharByte;				//looping for each display-byte in one ASCII

   char cAsciiCode;				//store single ASCII from string to display
	char cByteDisplay;			//store display-byte to put onto ROW

   int nStartColumn;				//used to mark the Dot-Matrox start COLUMN
   int nStringStartColumn;   //used to mark the STRING start COLUMN

   char cTotalScroll;			//Total scroll of STRING to make before re-loop
   int nScrollDelayCount;		//# of count before scrolling

   char acDisplay[LAST_COL];	//Hold processed BYTEs to be displayed

	WrPortI(SPCR, &SPCRShadow, 0x84);	//Set PortA as output
													//PortB fixed I/O
                                       //PortC fixed I/O
   WrPortI(PDDDR, &PDDDRShadow, 0xff);	//Set PortD as output
   WrPortI(PDDCR, &PDDCRShadow, 0x00);	//Set PortD as normal output
	WrPortI(PEDDR, &PDDDRShadow, 0xff);	//Set PortE as output

   init();

 	nStartColumn=LAST_COL;					//start scrolling from the 24th COLUMN
   nScrollDelayCount=0;
   cTotalScroll=strlen(acString)*4;		//total byte (each char is 3bytes + 1byte blank)
   outH_porta(7);	//NO-RESET

	while (1) {
   	//Determine first column in scrolling ===========================
   	nScrollDelayCount++;
      if (nStartColumn>LAST_COL-cTotalScroll) {
         if (nScrollDelayCount>5) {
	         nStartColumn--;
   	      nScrollDelayCount=0;
         }
      } else {
         nStartColumn=LAST_COL;
      }
   	//=============================================================

   	//Build the 24 column byte=======================================
      //LEADING BLANK
      for (r=0;r<(nStartColumn-1);r++) acDisplay[r]=0x00;

      //GET THE STARTING POINT OF STRING
      if (nStartColumn>0) {
         nStringStartColumn=0;
	      r=(nStartColumn-1);
      } else {
      	nStringStartColumn=abs(nStartColumn)+1;
	      r=0;
      }

      //PROCESSING
      for (;r<LAST_COL;r++) {
	      cChar=nStringStartColumn/4;
         cCharByte=nStringStartColumn%4;
         nStringStartColumn++;

         //One char consists of three byte
         //Display byte1, byte2 and byte3 and last one blank
			switch (cCharByte) {
         case 0:
         case 1:
         case 2:
            //ON ROW
            cAsciiCode=*(acString+cChar);
            cByteDisplay= *(*(ASCII+cAsciiCode)+cCharByte);
            acDisplay[r]=cByteDisplay;
            break;
         case 3:
         	acDisplay[r]=0x00;
         	break;
         }
      }
   	//=============================================================

   	//Display them=================================================
      for (r=0;r<24;r++) {
         //put HIGH onto first COLUMN bit
         if (r==0) outH_porta(5); else outL_porta(5);

       	outH_porta(6); outL_porta(6); //clock
         outL_porta(5);						//LOW subsequent COLUMN

         WrPortI(PADR, &PADRShadow, RdPortI(PADR) | acDisplay[r]);
         delay_tick(1);	//ON for 1-tick duration

			WrPortI(PADR, &PADRShadow, RdPortI(PADR) & 0xe0);	//OFF ROW
      }

      outL_porta(7);	//RESET
      outH_porta(7);	//NO-RESET
   	//=============================================================

	}//end of while
}

