1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// For MikroC Pro v1.65 http://www.mikroe.com
// Dual Die emulator with PIC12F683, hardware otherwise according to
// http://hackaday.com/2012/10/25/a-pic-powered-pair-of-electronic-dice/
// Internal clock, no clock out 4MHz. 

const char dice[]={0x00,0x02,0x01,0x03,0x11,0x13,0x31};
const char rotate[]={0x12,0x20,0x03};
int t; // fast multiplexer and timer counter - and also "random" value

void setup()
{
  gpio = 0;                         // make all outputs '0'
  option_reg.NOT_GPPU = 0xFF;       // disable weak pull-ups
  trisio = 0b00001000;              // GPx output, GP3 input
  ansel=0;                         // no analog inputs
  CMCON0 = 0x07;                    // comparators off
  INTCON.GIE = 1;                  //Enable Global Interrupt
  INTCON.INTE = 0;                //Disable RB0/INT external Interrupt
  INTCON.GPIE = 1;                //Enable all unmasked peripheral interrupt
  OPTION_REG.INTEDG = 1;         //Interrupt on rising edge
  IOC=0b00001000;                // Unmask interrupt on change for GPIO3
}

void showdice(int howlong, char left,char right)
{
  for (t=0;t<howlong;t++)
  {
   gpio=left+4;                 // +4 selects left dice
   delay_us(10);
   gpio=0;
   delay_us(30);
   gpio= right;
   delay_us(10);
   gpio=0;
   delay_us(30);
   }
 gpio=0;
}


void interrupt()
{
  char left, right;
  if (INTCON.GPIF)
     {
     INTCON.GIE = 0;  // disable interrupts
     left = 1+(t%6);  // "random" value for left side
     t = t >> 6;      // bitshift right six bits
     right  = 1+(t%6); // "random" value for right side
     for (t=0;t<3000;t++) // display results brightly
         {
         GPIO=dice[left]+4;
         delay_us(400);
         GPIO=dice[right];
         delay_us(400);
         }
     GPIO=0;    // turn off leds
     delay_ms(400);  // wait before movin along
     INTCON.GPIF = 0; // re-enable interrupts
     }
}
   
void main()
{
  char d;  // for small counters
  setup();

  do       //main loop
   {
   for (d=0;d<7;d++)  // cycle from 1-6 on left side, 6-1 on the right side
       {
       showdice(3500,dice[d],dice[6-d]);
       delay_ms(100);
       }
   for(d=0;d<20;d++) // rotate clockwise on both sides
      {
      showdice(1000,rotate[d%3],rotate[(d%3)]);
      delay_ms(20);
      }
  }
  while(1);
} // The end.