/*
 * evil wombat
 * 10/30/2008
 * 
 * Fun with old hardware.
 * CPU is dsPIC30F4011
 *
 * HW is a controller board from a ClimbMax machine,
 * with the 80C32 replaced by a dsPIC.
 *
 * Speed is 11.059MHz. 
 *
 * Pin mapping is a bit funky because the chips aren't
 * exactly pin compatible. So, fun with lots of air wires.
 *
 * The original ROM becomes quite useless as well.
 *
 * Damn, the dude who designed that board pulled
 * some pretty nifty tricks... took a while to
 * get all the drivers working.
 *
 * Enjoy
 *
 * */

#include <p30fxxxx.h>

#define byte unsigned char
_FOSC( CSW_FSCM_OFF & XT );
_FWDT ( WDT_OFF );

#define LAT_AN_CP    _LATE3
#define TRIS_AN_CP   _TRISE3

/* Should only be pulled down */
/* LOW = off, TRIS = on */
#define LAT_AN_DA    _LATE4
#define TRIS_AN_DA   _TRISE4

#define LAT_ALPHA_LE    _LATD0
#define TRIS_ALPHA_LE   _TRISD0

#define LAT_MATRIX_LE   _LATE5
#define TRIS_MATRIX_LE  _TRISE5

#define LAT_KP_OE    _LATF6
#define TRIS_KP_OE   _TRISF6

#define TRIS_IN     1
#define TRIS_OUT    0


#define SEG_A   0x0200
#define SEG_B   0x0100
#define SEG_C   0x0080
#define SEG_D   0x0020
#define SEG_E   0x0001
#define SEG_F   0x4000
#define SEG_G   0x0400
#define SEG_H   0x0010
#define SEG_I   0x1000
#define SEG_J   0x0004
#define SEG_K   0x2000
#define SEG_L   0x0800
#define SEG_M   0x0002
#define SEG_N   0x0008
#define SEG_DP  0x0040
#define SEG_LEG 0x8000

const unsigned int font[]={
0x0000,       // Space
SEG_B|SEG_C|SEG_DP,       // !
SEG_F|SEG_B,       // "
0x0000,       // #
SEG_A|SEG_F|SEG_G|SEG_H|SEG_C|SEG_D|SEG_I|SEG_J,       // $
0x0000,       // %
0x0000,       // &
SEG_L,       // '
SEG_L|SEG_N,       // (
SEG_K|SEG_M,       // )
0x0000,       // *
SEG_J|SEG_I|SEG_G|SEG_H,       // +
SEG_M,       // ,
SEG_G|SEG_H,       // -
SEG_DP,       // .
SEG_L|SEG_M,       // /
SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_L|SEG_M,       //0
SEG_L|SEG_B|SEG_C,       //1
SEG_A|SEG_B|SEG_G|SEG_H|SEG_E|SEG_D,       //2
SEG_A|SEG_B|SEG_C|SEG_D|SEG_H|SEG_G,       //3
SEG_F|SEG_G|SEG_H|SEG_B|SEG_C,       //4
SEG_A|SEG_F|SEG_G|SEG_H|SEG_C|SEG_D,       //5
SEG_F|SEG_E|SEG_D|SEG_C|SEG_G|SEG_H,       //6
SEG_A|SEG_B|SEG_C,       //7
SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G|SEG_H,       //8
SEG_A|SEG_B|SEG_C|SEG_G|SEG_H|SEG_F,       //9
0x0000,       //:
0x0000, //;
SEG_L|SEG_N,       //<
SEG_G|SEG_H|SEG_D,//=
SEG_K|SEG_M,       //>
SEG_A|SEG_B|SEG_H|SEG_J,       //?
0X0000,       //@
SEG_E|SEG_F|SEG_A|SEG_B|SEG_C|SEG_G|SEG_H,       //A
SEG_A|SEG_B|SEG_C|SEG_D|SEG_I|SEG_J|SEG_H,       //B
SEG_A|SEG_F|SEG_E|SEG_D,       //C
SEG_A|SEG_B|SEG_C|SEG_D|SEG_I|SEG_J,       //D
SEG_A|SEG_E|SEG_F|SEG_D|SEG_G|SEG_H,       //E
SEG_A|SEG_F|SEG_E|SEG_G|SEG_H,       //F
SEG_A|SEG_F|SEG_E|SEG_D|SEG_C|SEG_H,       //G
SEG_F|SEG_E|SEG_G|SEG_H|SEG_C|SEG_B, //H
SEG_A|SEG_I|SEG_J|SEG_D,       //I
SEG_B|SEG_C|SEG_D|SEG_E, // J
SEG_F|SEG_E|SEG_G|SEG_L|SEG_N, // K
SEG_F|SEG_E|SEG_D, // L
SEG_E|SEG_F|SEG_K|SEG_L|SEG_B|SEG_C, // M
SEG_E|SEG_F|SEG_K|SEG_N|SEG_C|SEG_B, // N
SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F, // O
SEG_E|SEG_F|SEG_A|SEG_B|SEG_H|SEG_G, // P
SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_N, // Q
SEG_E|SEG_F|SEG_A|SEG_B|SEG_H|SEG_G|SEG_N, // R
SEG_A|SEG_F|SEG_G|SEG_H|SEG_C|SEG_D, // S
SEG_A|SEG_I|SEG_J, // T
SEG_F|SEG_E|SEG_D|SEG_C|SEG_B, // U
SEG_F|SEG_E|SEG_M|SEG_L, // V
SEG_F|SEG_E|SEG_M|SEG_N|SEG_C|SEG_B, // W
SEG_K|SEG_L|SEG_M|SEG_N, // X
SEG_G|SEG_H|SEG_J|SEG_F|SEG_B, // Y
SEG_A|SEG_L|SEG_M|SEG_D, // Z

0x0000,0,0,0,0,0,0,0,0,0,0,0,0,0
};

#define FREQ(a) ((11059000/a)/8)

#define A3  FREQ(220.0)
#define Bb3 FREQ(233.0818807590)
#define A4  FREQ(440.0)
#define B4  FREQ(493.8833012561)
#define Bb4 FREQ(466.1637615181)
#define C4  FREQ(523.2511306012)
#define Db4 FREQ(554.3652619537)
#define D4  FREQ(587.3295358348)
#define E4  FREQ(659.2551138257)
#define F4  FREQ(698.4564628660)
#define Gb4 FREQ(739.9888454233)
#define G4  FREQ(783.9908719635)



#define CLRSCR  11
#define BMP1    2
#define BMP2    3
#define BMP3    4
#define BMP4    5
#define BMP5    6
#define BMP6    7
#define BMP7    8
#define BMP8    9
#define BMP9    10

/*
 * Thanks to 256byteram on youtube for putting up source code
 * This is where the notes came from.
 * See "8080 plays portal ending"
 */
const static unsigned int portal[]=
{

'T','H','I','S',' ',G4,
'W','A','S',' ',Gb4,
'A',' ',E4,
'T','R','I',E4,
'U','M','P','H',Gb4,

0,0,0,0,0,0,0,0,0,
CLRSCR,0,
 'I','\'','M',' ',A3,
 'M','A',G4,
'K','I','N','G',' ',Gb4,
 'A',' ',E4,
 'N','O','T','E',' ',E4,
0,'H','E','R','E',Gb4,
0,0,CLRSCR,
'H','U','G','E',' ',D4,
0,
'S','U','C',E4,
'C','E','S','S',A3,

0,0,0,0,0,0,0,

CLRSCR,
'I','T','\'','S',' ',A3,
'H','A','R','D',' ',E4,
0,'T','O',' ',Gb4,

'O',G4,
0,0,'V','E','R',E4,
'S','T','A','T','E',Db4,
0,CLRSCR,
'M','Y',' ',D4,
0,0,'S','A',E4,
0,'T','I','S',A3,
'F','A','C',A3,
0, 'T','I','O','N',Gb4,

0,0,0,0,0,0,0,0,0,0,

CLRSCR,BMP1,
'A','P',G4,
'E','R',Gb4,
'T','U','R','E',' ',E4,
'S','C','I',E4,
'E','N','C','E',Gb4,
0,0,0,0,0,0,0,0,0,0,CLRSCR,
'W','E',' ',A3,
'D','O',' ',G4,
'W','H','A','T',' ',Gb4,
'W','E',' ',E4,
'M','U','S','T',E4,

0,0,CLRSCR,
'B','E',Gb4,
'C','A','U','S','E',D4,
0,0,
' ','W','E',E4,
' ','C','A','N',A3,
0,0,0,0,0,0,0,0,CLRSCR,
'F','O','R',' ',E4,0,
'T','H','E',' ',Gb4,
'G','O','O','D',' ',G4,
0,0,
'O','F',E4,
' ','A','L','L',Db4,
0,0,
' ','O','F',D4,
' ','U','S',E4,
0,

CLRSCR,BMP2,
'E','X',A3,
'C','E','P','T',' ',D4,
'T','H','E',E4,
' ','O','N','E','S',F4,
' ','W','H','O',E4,
' ','A','R','E',D4,
' ','D','E','A','D','.',C4,
0,0,CLRSCR,BMP1,



'B','U','T',' ',A3,
'T','H','E','R','E','\'','S',Bb3,
' ','N','O',C4,0,
' ','S','E','N','S','E',F4,
0,
' ','C','R','Y',E4,
'I','N','G',D4,CLRSCR,
'O',D4,
'V','E','R',' ',C4,
'E','V','E',D4,
'R','Y',C4,
' ','M','I','S',C4,
0,
'T','A','K','E','.',C4,
// 133,
0, CLRSCR,
'Y','O','U',' ',A3,
'J','U','S','T',' ',Bb3,

'K','E','E','P',C4,
0,
' ','O','N',F4,
0,


' ','T','R','Y',G4,
// 133,
'I','N','G',F4, CLRSCR,
'T','I','L','L',E4,
' ','Y','O','U',D4,

' ','R','U','N',D4,
' ','O','U','T',E4,
' ','O','F',F4,
0,

' ','C','A','K','E','.',F4,

0,CLRSCR,BMP3,
'A','N','D',' ',G4,
'T','H','E',' ',A4,
'S','C','I',Bb4,
'E','N','C','E',Bb4,
' ','G','E','T','S',A4,
0,
' ','D','O','N','E','.',G4,
// 133,
0,CLRSCR,
'A','N','D',' ',F4,
'Y','O','U',' ',G4, BMP1,

'M','A','K','E',A4,
' ','A',A4,
' ','N','E','A','T',G4,
0,
' ','G','U','N','.',F4,
// 133,
0,CLRSCR,
'F','O','R',' ',D4,
'T','H','E',' ',C4,

'P','E',D4,
'O','P','L','E',F4,
' ','W','H','O',F4,
' ','A','R','E',E4,
0,CLRSCR,
// 133,
'S','T','I','L','L',' ',E4,
'A',Gb4,
'L','I','V','E','.',Gb4,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
//0,0,0,0,0,0,0,0,0,0,0,
CLRSCR,


// 133,
'I','\'','M',' ',A3,
'N','O','T',' ',G4,
'E',Gb4,
'V','E','N',E4,
' ','A','N',E4,
0,
'G','R','Y','.',Gb4,
0,0,0,0,0,0,
0,0,0,0,CLRSCR,
// 133,
'I','\'','M',' ',G4,
'B','E',Gb4,
'I','N','G',' ',E4,
'S','O',E4,
0,0,
' ','S','I','N',Gb4,
'C','E','R','E',D4,
0,
' ','R','I','G','H','T',E4,
0,
' ','N','O','W','.',A3,
0,0,0,0,0,0,0,0,CLRSCR,

'E',E4,
0,
'V','E','N',' ',Gb4,
'T','H','O','U','G','H',' ',G4,
0,
0,
'Y','O','U',E4, BMP4,
0,

' ','B','R','O','K','E',Db4,
0,
' ','M','Y',D4,
' ','H','E','A','R','T',E4,
0,0,CLRSCR,
'A','N','D',A3,
' ','K','I','L','L','E','D',A3,
0,
' ','M','E',Gb4,
0,0,0,0,0,0,
0,0,0,CLRSCR,BMP5,

'A','N','D',' ',A3,
'T','O','R','E',' ',G4,
'M','E',' ',Gb4,
'T','O',E4,
' ','P','I','E',E4,
0,
'C','E','S',Gb4,
0,0,0,0,0,0,
0,0,0,CLRSCR,

// 133,
'A','N','D',' ',A3,
'T','H','R','E','W',' ',G4,
'E','V','E',Gb4,
'R','Y',E4,
' ','P','I','E','C','E',E4,
0,0,
' ','I','N',Gb4,
'T','O',D4,
0,BMP6,
' ','A',E4,
0,
' ','F','I','R','E',A3,
0,0,0,0,0,0,0,0,CLRSCR,
'A','S',' ',E4,
0,
'T','H','E','Y',' ',Gb4,
'B','U','R','N','E','D',G4,
0,
0,
' ','I','T',E4,
0,
' ','H','U','R','T',Db4,
0,
' ','B','E',D4,
'C','A','U','S','E',E4,
0,
CLRSCR,BMP7,
'I',' ',A3,
'W','A','S',' ',D4,
'S','O',' ',E4,

'H','A',F4,
'P','P','Y',E4,
' ','F','O','R',D4,
' ','Y','O','U',C4,
0,
0,CLRSCR,



// 133,
'N','O','W',' ',A3,
'T','H','E','S','E',' ',Bb3,

'P','O','I','N','T','S',C4,
0,
' ','O','F',F4,
0,
' ','D','A',E4,
'T','A',D4,CLRSCR,
// 133,
'M','A','K','E',D4,
' ','A',C4,

' ','B','E','A','U',D4,
'T','I',C4,
'F','U','L',C4,
0,
' ','L','I','N','E',C4,
0,CLRSCR,
// 133,
'A','N','D',' ',A3,
'W','E','\'','R','E',Bb3,

' ','O','U','T',C4,
0,
' ','O','F',' ',F4,
0,
'B','E',G4,
'T','A',F4,
// 133,
CLRSCR,'W','E','\'','R','E',E4,
' ','R','E',D4,
'L','E','A',D4,
'S','I','N','G',E4,
' ','O','N',F4,
0,
' ','T','I','M','E',F4,
0,BMP5,CLRSCR,
'S','O',' ',G4,
'I','\'','M',' ',A4,
'G','L','A','D',Bb4,
' ','I',Bb4,
' ','G','O','T',A4,
0,
' ','B','U','R','N','E','D',G4,
0,BMP3,CLRSCR,

'T','H','I','N','K',' ',F4,
'O','F',' ',G4,
'A','L','L',A4,
' ','T','H','E',A4,
' ','T','H','I','N','G','S',G4,
' ','W','E',F4,
' ','L','E','A','R','N','E','D',F4,
0,BMP1,CLRSCR,
'F','O','R',' ',D4,
'T','H','E',' ',C4,

'P','E','O',D4,
'P','L','E',F4,
' ','W','H','O',F4,
' ','A','R','E',E4,
0,CLRSCR,

'S','T','I','L','L',E4,
' ','A',Gb4,
'L','I','V','E',Gb4,

0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
//0,0,0,0,0,0,0,0,
//0,0,0,0,
CLRSCR,

// 133,
'G','O',' ',G4,
'A','H','E','A','D',Gb4,
' ','A','N','D',E4,
' ','L','E','A','V','E',E4,
0,
' ','M','E',Gb4,
0,0,0,0,0,0,
0,0,0,CLRSCR,
'I',' ',A3,
'T','H','I','N','K',' ',G4,
'I',Gb4,
' ','P','R','E',E4,
'F','E','R',E4,
0,0,CLRSCR,
'T','O',' ',Gb4,
'S','T','A','Y',D4,
0,0,
' ','I','N',E4,
'S','I','D','E',A3,
0,0,0,0,0,
0,0,0,CLRSCR,

// 133,
'M','A','Y',E4,
0,
'B','E',' ',Gb4,
'Y','O','U','\'','L','L',G4,
0,
0,
' ','F','I','N','D',E4,
0,
' ','S','O','M','E',Db4,
0,
'O','N','E',D4,
' ','E','L','S','E',E4,
0,
0,CLRSCR,
'T','O',' ',A3,
'H','E','L','P',' ',A3,
0,
'Y','O','U',Gb4,
0,0,0,0,0,0,
0,0,0,0,CLRSCR,
'M','A','Y',G4,
'B','E',' ',Gb4,BMP8,
'B','L','A','C','K',E4,
' ','M','E',E4,
0,
'S','A',Gb4,
0,0,0,0,0,0,
0,0,0,0,CLRSCR,

'T','H','A','T',' ',G4,
'W','A','S',' ',Gb4,
'A',' ',E4,
'J','O','K','E',E4,
0,
0,CLRSCR,
'H','A',' ',Gb4,
'H','A',' ',D4,
0,
0,CLRSCR,
'F','A','T',' ',E4,
'C','H','A','N','C','E',A3,

0,0,0,0,0,0,0,0,
CLRSCR,


'A',E4,
0,
'N','Y',Gb4,
'W','A','Y',' ',G4,
0,
0,
'T','H','I','S',E4,
0,BMP9,
' ','C','A','K','E',Db4,
0,
' ','I','S',D4,
' ','G','R','E','A','T',E4,
0,CLRSCR,
'I','T','\'','S',' ',A3,
'S','O',' ',D4,
'D','E',E4,
'L','I',F4,
'C','I','O','U','S',E4,
' ','A','N','D',D4,
' ','M','O','I','S','T',C4,
0,
0,CLRSCR,BMP1,


'L','O','O','K',' ',A3,
'A','T',' ',Bb3,
'M','E',' ',C4,
0,
'S','T','I','L','L',F4,
0,
' ','T','A','L',E4,
'K','I','N','G',D4,
BMP2,CLRSCR,
'W','H','E','N',' ',D4,
'T','H','E','R','E','\'','S',C4,
' ','S','C','I',D4,
'E','N','C','E',C4,
' ','T','O',C4,
0,
' ','D','O',C4,
0,CLRSCR,BMP1,
'W','H','E','N',' ',A3,
'I',' ',Bb3,
'L','O','O','K',' ',C4,
0,
'O','U','T',F4,
0,
' ','T','H','E','R','E',G4,CLRSCR,
'I','T',' ',F4,
// 133,
'M','A','K','E','S',' ',E4,
'M','E',' ',D4,
'G','L','A','D',D4,
' ','I','\'','M',E4,
' ','N','O','T',F4,
0,
' ','Y','O','U',F4,
0,CLRSCR,BMP3,

'I','\'','V','E',G4,
' ','E','X',A4,
'P','E',Bb4,
'R','I',Bb4,
'M','E','N','T','S',A4,
' ','T','O',G4,
' ','R','U','N',G4,
0,CLRSCR,BMP5,
'T','H','E','R','E',' ',F4,
'I','S',' ',G4,
'R','E',A4,
'S','E','A','R','C','H',A4,
' ','T','O',' ',G4,
'B','E',' ',F4,
'D','O','N','E',F4,
0,CLRSCR,BMP1,
'O','N',' ',D4,
'T','H','E',' ',C4,
'P','E','O',D4,
'P','L','E',F4,
' ','W','H','O',F4,
' ','A','R','E',E4,
0,CLRSCR,
// 133,
'S','T','I','L','L',E4,
' ','A',Gb4,
'L','I','V','E',Gb4,
0,0,0,0,0,0,CLRSCR,

'A','N','D',' ',A4,
'B','E',A4,
'L','I','E','V','E',' ',B4,
'M','E',A4,
' ','I',Gb4,
' ','A','M',D4,
0,CLRSCR,
// 133,
'S','T','I','L','L',' ',E4,
'A',Gb4,
'L','I','V','E',Gb4,
0,0,0,0,0,CLRSCR,
'I','\'','M',' ',A4,
'D','O',A4,
'I','N','G',' ',A4,
'S','C','I',B4,
'E','N','C','E',A4,
' ','A','N','D',Gb4,
' ','I','\'','M',D4,
0,CLRSCR,
// 133,
'S','T','I','L','L',' ',E4,
'A',Gb4,
'L','I','V','E',Gb4,
0,0,0,0,0,CLRSCR,
'I',' ',A4,
'F','E','E','L',' ',A4,
'F','A','N',A4,
'T','A','S',B4,
'T','I','C',A4,
' ','A','N','D',Gb4,
' ','I','\'','M',D4,
0,CLRSCR,
'S','T','I','L','L',' ',E4,
'A',Gb4,
'L','I','V','E',Gb4,
0,0,0,0,0,0,CLRSCR,
// 133,
'W','H','I','L','E',' ',A4,
'Y','O','U','\'','R','E',' ',A4,
'D','Y',B4,
'I','N','G',A4,
' ','I','\'','L','L',Gb4,
' ','B','E',D4,
0,CLRSCR,
'S','T','I','L','L',' ',E4,
'A',Gb4,
'L','I','V','E',Gb4,
0,0,0,0,0,CLRSCR,
'A','N','D',' ',A4,
'W','H','E','N',' ',A4,
'Y','O','U','\'','R','E',A4,
' ','D','E','A','D',B4,
' ','I',A4,
' ','W','I','L','L',Gb4,
' ','B','E',D4,
0,CLRSCR,
'S','T','I','L','L',E4,
' ','A',Gb4,
'L','I','V','E',Gb4,

0,0,0,0,0,CLRSCR,
'S','T','I','L','L',G4,
' ','A',A4,
'L','I','V','E',A4,

0,0,0,0,0,CLRSCR,
'S','T','I','L','L',G4,
' ','A',Gb4,
'L','I','V','E',Gb4,
1,
0
};


void delay()
{
    int i=0;
    for(i=0; i<50; i++);
}



unsigned int segMap[17];
byte bitMap[17];
int curAnode = 0;

void setString(char * s)
{
    int i;
    for(i=0; s[i] != 0; i++)
        segMap[i] = font[s[i]-32];
}


void writeSeg(unsigned int l, unsigned char m)
{
    LAT_ALPHA_LE = 0;
    LAT_MATRIX_LE = 1;
    PORTB = l >> 8;
    LAT_MATRIX_LE = 0;
    PORTB = l & 0xFF;

    _LATD2 = m & 0x80 ? 1 : 0;
    _LATD3 = m & 0x40 ? 1 : 0;
    _LATD1 = m & 0x20 ? 1 : 0;
    _LATE8 = m & 0x10 ? 1 : 0;
    _LATC14 = m & 0x08 ? 1 : 0;
    _LATC13 = m & 0x04 ? 1 : 0;
    _LATF1 = m & 0x02 ? 1 : 0;
    _LATF0 = m & 0x01 ? 1 : 0;

//d2 d3 d1 e8 c14 c13 c15 f0


    LAT_ALPHA_LE = 1;
    LAT_ALPHA_LE = 0;
}

void stepDisplay()
{
    int i;
    if(curAnode >= 16)
    {
        curAnode = 0;
        TRIS_AN_DA = TRIS_OUT;
    } else
        TRIS_AN_DA = TRIS_IN;

    writeSeg(0x0000, 0x00);
    for(i=0; i<10; i++);
    LAT_AN_CP = 0;
    LAT_AN_CP = 1;
    TRIS_AN_DA = TRIS_IN;
    writeSeg(segMap[curAnode], bitMap[curAnode]);
    LAT_AN_CP = 0;

    curAnode++;
}


/*
14-Seg:
      A
    _____
 F |\ | /| B
   | \I/ |            I       K\  /L
    -G H-            G H
 E | /J\ | C          J       M/  \N
   |/ | \|
    -----  .
      D

PORTB
Bit 0 = E
Bit 1 = M
Bit 2 = J
Bit 3 = N
Bit 4 = H
Bit 5 = D
Bit 6 = DP
Bit 7 = C
Bit 8 = B
Bit 9 = A
Bit 10 = G
Bit 11 = L
Bit 12 = I
Bit 13 = K
Bit 14 = F
Bit 15 = LEDs

7-Seg:
Bit 0 = E
Bit 1 = D
Bit 2 = C
Bit 3 = DP
Bit 4 = B
Bit 5 = A
Bit 6 = F
Bit 7 = G

*/

void setBitmap(const byte * b)
{
    int i;
    for(i=0; i<16; i++)
        bitMap[i] = b[i];
}


void initPWM()
{
    PTCONbits.PTEN = 0;
    PTCONbits.PTOPS = 0x0000;   /* No postscaler */
    PTCONbits.PTCKPS = 0x0000;  /* No prescaler */
    PTCONbits.PTMOD = 0x00; /* Free running mode */

    PTPER = 1;   /* Period */

    PWMCON1 = 0x0000;
    PWMCON1bits.PEN1H = 1;
/*
    PWMCON2 = 0x0000;
    //DTCON1 = 0x0000;
    //DTCON2 = 0x0000;

    FLTACON = 0x0000;
   // FLTBCON = 0x0000;

    OVDCON = 0x0000;
*/
    PDC1 = 500;


    //FBORPORbits.PWMPIN = 0;

    PTCONbits.PTEN = 1;
}


int cp = 0;
int dp = 0;


void clearDisplay()
{
    int i;
    dp = 0;
    for(i=0; i<16; i++)
        segMap[i] = 0;
}

void putChar(unsigned char c)
{
    int i;
    if(dp < 16)
        segMap[dp++] = font[c-32];
    else
    {
        for(i=1; i<16; i++)
            segMap[i-1] = segMap[i];
        segMap[15] = font[c-32];
    }
}

int qh = 0;
int qt = 0;
char qbuf[16];

void qPut(char c)
{
    qh = (qh+1)&0x0F;
    qbuf[qh] = c;
}

int stop = 0;

const static byte bmp1Data[]={0,0,0,0,0x3C,0x76,0xF7,0x87, 0xE1, 0xEF, 0x6E, 0x3C,0,0,0,0,0,0};
const static byte bmp2Data[]={0,0,0,0, 0xC0,0xE0,0xE6, 0x0E, 0x0E, 0xE6, 0xE0,0xC0, 0,0,0,0,0,0};
const static byte bmp3Data[]={0,0, 0x66,0x5A,0x3C,0x6A,0xBD,0xBD,0x6A,0x3C,0x5A,0x66,0,0,0,0,0};
const static byte bmp4Data[]={0,0,  0x1C,0x3E,0x7E,0xFE,0x34,0x00,0xE8,0xFC,0x7E,0x3E,0x1C,0,0,0,0};
const static byte bmp5Data[]={0,0,0, 0x46,0x6C,0x3C,0xFF,0x7E,0x78,0x7C,0xD6,0x90, 0,0,0,0,0};
const static byte bmp6Data[]={0x60,0xF0,0xF8,0x84,0x38,0xFC,0xFE,0xFE,0xFF,0x7E,0x1C,0xC2,0xFE,0x7C,0x38,0,0};
const static byte bmp7Data[]={0, 0x20,0x70,0xF0,0xE0,0xC0,0xE0,0xF0,0x78,0x3C,0x1E,0x0F,0x07,0,0,0,0};
const static byte bmp8Data[]={0,0,0,0, 0x3C,0x42,0x81,0xF1,0xF1,0xF1,0x62,0x3C,0,0,0,0,0,0};
const static byte bmp9Data[]={0,0,0xF0,0x90,0xC8,0x4C,0x44,0x66,0x63,0x27,0x2F,0x3E,0x1C,0,0,0};

void step()
{
    if(stop==1)
        return;

    unsigned int cs = 0;
    while(1)
    {
        cs = portal[cp++];

        if(cs == 1)
        {
            stop = 1;
            return;
        }

        if(cs == 0)
            return;

        if(cs > 500) // >= G4 && cs <= A3 || cs == 0) /* Music */
        {
            PTPER = cs;
            return;
        }
        else
        {
            if((cs >= 'A' && cs <= 'Z') || cs == '\'' || cs == ' ' || cs == '.')
            {
                //putChar(cs);
                qPut(cs);
            }

            if(cs == CLRSCR)
                clearDisplay();

            if(cs == BMP1)
                setBitmap(bmp1Data);

            if(cs == BMP2)
                setBitmap(bmp2Data);

            if(cs == BMP3)
                setBitmap(bmp3Data);

            if(cs == BMP4)
                setBitmap(bmp4Data);

            if(cs == BMP5)
                setBitmap(bmp5Data);

            if(cs == BMP6)
                setBitmap(bmp6Data);

            if(cs == BMP7)
                setBitmap(bmp7Data);

            if(cs == BMP8)
                setBitmap(bmp8Data);

            if(cs == BMP9)
                setBitmap(bmp9Data);

        }
    }
}




int main()
{
    int i=0, j=0, k=0;
    _TRISE1 = TRIS_IN;
    ADPCFG = 0xFFFF;
    LAT_KP_OE = 1;
    TRIS_KP_OE = TRIS_OUT;

    LAT_AN_DA = 0;
    TRIS_AN_DA = TRIS_IN;

    LAT_AN_CP = 0;
    TRIS_AN_CP = TRIS_OUT;

    LAT_ALPHA_LE = 0;
    TRIS_ALPHA_LE = TRIS_OUT;

    LAT_MATRIX_LE = 0;
    TRIS_MATRIX_LE = TRIS_OUT;


    _TRISD2 = TRIS_OUT;
    _TRISD3 = TRIS_OUT;
    _TRISD1 = TRIS_OUT;
    _TRISE8 = TRIS_OUT;
    _TRISC14 = TRIS_OUT;
    _TRISC13= TRIS_OUT;
    _TRISF1= TRIS_OUT;
    _TRISF0 = TRIS_OUT;

    TRISB = 0;


    initPWM();

    for(i=0; i<16; i++)
    {
        segMap[i] = 0;
        bitMap[i] = 0;
    }

    i = 0;

    //PTPER = Db4;

   // setString("FEED ME A CAT");
    j = 0;

//    clearDisplay();
    while(1)
    {
        if(i++ == 400)
        {
            i = 0;
            step();
        }

        if(i == 350)
        {
            PTPER = 1;
        }

        if(k++ == 20)
        {
            k = 0;
            if(qh != qt)
            {
                qt = (qt+1)&0x0F;
                putChar(qbuf[qt]);
            }
        }

        stepDisplay();
        delay();
        delay();
        delay();
        delay();
    }
}
