Looking at your code I see two things immediately:
You call Serial.read() without first calling Serial.available() - you must.
You are altering the timer count register TCNT1 within loop() - that's broken,
you are losing counts because of that.
The correct way is to monitor the counter by taking a copy of it regularly and
comparing the successive observed values. So long as you observe it fast enough
that the counter cannot count 2^16 counts between observations you have
complete information and haven't disturbed the counter.
Something like:
unsigned long prev_accurate_time = 0L ;
unsigned long total_count = 0L ;
unsigned long prev_count = 0L ;
unsigned long previous_tick = 0L ;
unsigned int previous = 0 ;
void loop ()
{
// first perform observation
unsigned int now = TCNT1 ;
unsigned long accurate_time = micros () ;
// then update the long counter
unsigned long difference = (now - previous) & 0xFFFFL ; // get unsigned difference
previous = now ;
total_count += difference ;
// check for time passing
if (millis () - previous_tick >= 1000L)
{
previous_tick += 1000L ; // setup for next second.
// calculate accurate values for the approximate 1s interval, pass to be displayed
display (total_count - prev_count,
accurate_time - prev_accurate_time) ;
prev_accurate_time = accurate_time ; // update for next second
prev_count = total_count ;
}
}