////////////////////////////////////////////////////////////////
//                LED Clock kijelző driver unit
//             Topor Zoltán - 2007. márc.
//            Módosítva: kettőspont villogás (2025)
////////////////////////////////////////////////////////////////

#define   SHIFT_RESET   PIN_B1
#define   SHIFT_CLOCK   PIN_B3
#define   SHIFT_DATA    PIN_B2

int cursor_pos;
int shift_pos = 0;

int characters[17] = {
/* 0 */  0b11111100,   //0
/* 1 */  0b01100000,   //1
/* 2 */  0b11011010,   //2
/* 3 */  0b11110010,   //3
/* 4 */  0b01100110,   //4
/* 5 */  0b10110110,   //5
/* 6 */  0b10111110,   //6
/* 7 */  0b11100000,   //7
/* 8 */  0b11111110,   //8
/* 9 */  0b11110110,   //9
/* 10 */ 0b00000000,   //szóköz

/* 11 */ 0b10000000,   //:
/* 12 */ 0b11000110,   //° 
/* 13 */ 0b10011100,   //C
/* 14 */ 0b00000010,   //-
};

const int MAX_DISP_LENGTH = 10;

int disp[MAX_DISP_LENGTH];
int disp_length = 0;
int disp2[MAX_DISP_LENGTH];
int disp2_length = 0;
int act_col = 0;
boolean slave_buffer = false;

// Új: kettőspont villogtatáshoz
boolean colon_visible = true;
int colon_counter = 0;

void WriteOutput(int data) {
   output_c(data);
}

void StrobeReset() {
   output_low(SHIFT_RESET);
   output_high(SHIFT_RESET);
   shift_pos = 0;
}

void StrobeClock() {
   output_high(SHIFT_CLOCK);
   output_low(SHIFT_CLOCK);
   shift_pos++;
}

void ClearDisplay() {
   int i;
   for(i=0;i<MAX_DISP_LENGTH;i++) {
      if(slave_buffer) disp[i] = 10;
      else disp2[i] = 10;
   }
   cursor_pos = 0;
   if(slave_buffer) disp_length = 0;
   else disp2_length = 0;
}

void display_putc(int ch) {
   int d = 0xFF;

   if(ch=='\f') {
      ClearDisplay();
   } else
   if(ch>='0' && ch<='9') {
      d = ch-'0';
   } else
   switch(ch) {
      case '.' : d = '.'; break;
      case ':' : d = 11;  break;
      case '°' : d = 12;  break;
      case 'C' : d = 13;  break;
      case '-' : d = 14;  break;
      default  : d = 10;  break;
   }
   if(d!=0xFF && ch!='\f') {
      if(cursor_pos < MAX_DISP_LENGTH) {   // biztonsági ellenőrzés
         if(slave_buffer) disp[cursor_pos] = d;
         else disp2[cursor_pos] = d;
         cursor_pos++;
         if(slave_buffer) disp_length++;
         else disp2_length++;
      }
   }
}

void FlipBuffer() {
   slave_buffer = !slave_buffer;
}

// Új: időzítő megszakítás (1 ms-enként fusson)
#int_timer1
void timer1_isr() {
   colon_counter++;
   if (colon_counter >= 500) {   // 500 ms = fél másodperc
      colon_counter = 0;
      colon_visible = !colon_visible;
   }
}

void RedrawDisplay() {
   int ch,data;
   int16 cap_count;

   if(act_col==0) {
      StrobeReset();
      WriteOutput(0x00);
      output_high(SHIFT_DATA);
   } else WriteOutput(0x00);

   cap_count = 0;
   output_low(CAP_PIN);
   delay_us(7);

   while(!input(CAP_PIN)) {
      cap_count++;
      if(cap_count>=56) break;
      delay_us(10);
   }

   if(!slave_buffer) ch = disp[act_col];
   else ch = disp2[act_col];

   // --- Kettőspont villogtatás kezelése ---
   if (ch == 11 && !colon_visible) {
      data = 0x00; // kikapcsolt kettőspont
   } else {
      data = characters[ch];
   }
   // ---------------------------------------

   if(act_col+1<MAX_DISP_LENGTH) {
      if(!slave_buffer) {
         if(disp[act_col+1]=='.') {bit_set(data,0);act_col++;}
      } else {
         if(disp2[act_col+1]=='.') {bit_set(data,0);act_col++;}
      }
   }

   StrobeClock();
   if((shift_pos==3 || shift_pos==6) && ch!=11) {
      WriteOutput(0x00);
      act_col--;
   } else {
      WriteOutput(data);
   }
   output_low(SHIFT_DATA);
   act_col++;
   if((act_col>=MAX_DISP_LENGTH) || (shift_pos>=8)) {
      act_col = 0;
   }
}

