module Array = struct

  let rec nth (a : int list) (i : int) : int = match a with
    | [] -> 1000+i
    | x :: l -> if i = 0 then x else nth l (i-1)

  let get (a : int list ref) (i : int) : int = 
    nth !a i

  let rec upd (a : int list) (i : int) (v : int) : int list = match a with
    | [] -> []
    | x :: l -> if i = 0 then v :: l else x :: upd l (i-1) v

  let set (a : int list ref) (i : int) (v : int) : unit =
    a := upd !a i v

  let rec listn (n : int) (v : int) : int list = 
    if n = 0 then [] else v :: listn (n-1) v

  let create (n : int) (v : int) : int list ref =
    ref (listn n v)

end

open Array

(* Digit array *)

let digits : int list ref = 
  let tab = create 10 0 in
  set tab 0 63; 
  set tab 1 6;
  set tab 2 91;
  set tab 3 79;
  set tab 4 102;
  set tab 5 109;
  set tab 6 125;
  set tab 7 7;
  set tab 8 127;
  set tab 9 111;
  tab

(* set timer *)

let () = output8 10000; output9 0

(* Watch *)

let su : int ref = ref 0
let st : int ref = ref 0
let mu : int ref = ref 0
let mt : int ref = ref 0
let hu : int ref = ref 0
let ht : int ref = ref 0

let print_watch (a:unit) : unit = 
  output5 (get digits !ht);
  output4 (get digits !hu);
  output3 (get digits !mt);
  output2 (get digits !mu);
  output1 (get digits !st);
  output0 (get digits !su)

let incr (a : int ref) : unit = a := !a+1

let rec watch (a:unit) : unit = 
  if !su <> 9 then incr su else
    (su :=0;
    if !st <> 5 then incr st else
       (st := 0;
       if !mu <> 9 then incr mu else
          (mu := 0;
          if !mt <> 5 then incr mt else
            (mt := 0;
             if !hu <> 9 && (!hu <>3 || !ht <> 2) then incr hu
             else
               (hu := 0;
                if !ht=2 then ht:=0 else incr ht
               )
            )
          )
       )
    );
  print_watch ();
  sleep ();
  watch ()

let () = watch ()
