DGOX3ISBTC7HQKYLNHUFUOJMCIOICC2F4IHHPK6OR3LZOKQIWIXAC Lemma rew_bit n w m eq i :bit (eq_rect n word w m eq) i = bit w (eq_rect m ordinal i n (Logic.eq_sym eq)).Proof. by move: i; case eq => i. Qed.Lemma rew_ord n i m eq:eq_rect n ordinal i m eq =let '(Ordinal i l) := i in Ordinal (eq_rect n (fun m => i < m) l m eq).Proof. by move: i; case eq; case=> m' ltn. Qed.
Lemma pushLowK {n} : cancel pushLow (popLow (n := n)).Proof.move=> [b w].rewrite /popLow; unlock.apply pair_equal_spec; split.- rewrite -{2}[b](pushLow_spec1 b w).rewrite /bool_of_word1 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.- apply wordP => i.rewrite -(pushLow_spec2 b w).rewrite fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.Qed.Lemma popLowK {n} : cancel popLow (pushLow (n := n)).Proof.move=> w.rewrite /popLow; unlock.apply wordP; case /ordLowP.- rewrite pushLow_spec1 /bool_of_word1 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.- move=> i.rewrite pushLow_spec2 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.Qed.
Lemma ordHighP {n} (i : 'I_n.+1) : ordHigh i.Proof.case i => m pf.have: (m == n) = (m == n) by []; case: {-1}(m == n) => [eq | neq].- have->: Ordinal pf = ord_max by apply /eqP; rewrite /eq_op; simpl.apply ordHigh2.- move: (pf) => pf'.rewrite leq_eqVlt eqSS neq -[m.+1]add1n -[n.+1]add1n ltn_add2l in pf.simpl in pf.have->: Ordinal pf' = widen_ord (leqnSn _) (Ordinal pf)by apply /eqP; rewrite /eq_op; simpl.apply ordHigh1.Qed.Definition popHigh {n} (w : word n.+1) : word n * bool.apply locked.refine (let '(w,b) := split _ in (w, bool_of_word1 b)).by rewrite addn1.Defined.Lemma pushHighK {n} : cancel pushHigh (popHigh (n := n)).Proof.move=> [w b].rewrite /popHigh; unlock.apply pair_equal_spec; split.- apply wordP => i.rewrite -(pushHigh_spec1 w b).rewrite fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.- rewrite -{2}[b](pushHigh_spec2 w b).rewrite /bool_of_word1 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl; rewrite addn0.Qed.Lemma popHighK {n} : cancel popHigh (pushHigh (n := n)).Proof.move=> w.rewrite /popHigh; unlock.apply wordP; case /ordHighP.- move=> i.rewrite pushHigh_spec1 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl.- rewrite pushHigh_spec2 /bool_of_word1 fromBitsK rew_bit; f_equal.by apply /eqP; rewrite rew_ord /eq_op; simpl; rewrite addn0.Qed.
From mathcomp Require Import all_ssreflect.Require Import word memory.(* The peripherals attached to the processor in the Atari 2600.These present themselves to the processor via memory addresses.*)(* There are four kinds of peripheral inside the Atari 2600.- ROMThe Atari has 4096 bytes of read-only memory, used to store the game code.These present themselves on addresses `...1 xxxx xxxx xxxx`.(A dot means the bit is ignored.)I don't know what happens if you try to write to it, so I assume anything is possible.- RAMThe Atari has 128 bytes of writable memory, used to store the game state.These present themselves on addresses `...0 ..0. 1xxx xxxx`.- TIA and PIAThe Atari has two other peripherals, for stuff like graphics, player input, et cetera.I don't understand what these do, so I'll assume they can do anything.The TIA is on adresses `...0 .... 0.xx xxxx`.The PIA is on addresses `...0 ..1. 1..x xxxx`.*)Definition ROM := memory 12 (word 8).Inductive state (rom : ROM) := fromRAM of (memory 7 (word 8)).Arguments fromRAM {rom}.Definition RAM {rom} : state rom -> memory 7 (word 8) := fun '(fromRAM ram) => ram.Lemma RAMK {rom} : cancel RAM (fromRAM (rom := rom)). by case. Qed.Lemma fromRAMK {rom} : cancel fromRAM (RAM (rom := rom)). done. Qed.Definition read {rom} (addr : word 16) (s : state rom) (w : word 8) : Prop.Proof.by refine ((* ROM *)if bit addr (Ordinal (m := 12) _)then w = get rom (split (n := 4) _).1(* TIA *)else if ~~ bit addr (Ordinal (m := 7) _)then True(* PIA *)else if bit addr (Ordinal (m := 9) _)then True(* RAM *)else w = get (RAM s) (split (n := 9) _).1).Defined.Definition write {rom} (addr : word 16) (s : state rom) (w : word 8) (s' : state rom) : Prop.Proof.by refine ((* ROM *)if bit addr (Ordinal (m := 12) _)then True(* TIA *)else if ~~ bit addr (Ordinal (m := 7) _)then True(* PIA *)else if bit addr (Ordinal (m := 9) _)then True(* RAM *)else s' = fromRAM (update (RAM s) (fun=>w) (split (n := 9) _).1)).Defined.
From mathcomp Require Import all_ssreflect.Require Import word.(* An efficient implementation of `word n -> V`. *)Fixpoint memory n (V : Type) : Type := match n with| 0 => V| n.+1 => memory n (V * V)end.Definition get {n V} : memory n V -> (word n -> V).Proof.move: V; elim: n.- move=> V v _. exact v.- move=> n recurse V m /popLow [b w].move: (recurse (V*V)%type m w) => [x y].exact (if b then y else x).Defined.Definition fromFun {n V} : (word n -> V) -> memory n V.Proof.move: V; elim: n.- move=> V f. exact (f trivial_word).- move=> n recurse V f.apply recurse.move=> w.split; apply f.+ exact (pushLow (false, w)).+ exact (pushLow (true, w)).Defined.Lemma fromFun_respect_eq1 {n V f g} : f =1 g -> fromFun f = fromFun (n := n) (V := V) g.Proof.move: V f g; elim: n.- simpl. done.- move=> n IH V f g eq. apply IH => w. by rewrite eq eq.Qed.Lemma getK {n V} : cancel get (fromFun (n := n) (V := V)).Proof.move: V; elim: n.- done.- move=> n IH V m.rewrite -{2}(IH _ m).simpl.apply: fromFun_respect_eq1 => w.rewrite pushLowK pushLowK.by apply: injective_projections.Qed.Lemma fromFunK {n V} : forall f, get (fromFun (n := n) (V := V) f) =1 f.Proof.move: V; elim: n.- move=> V f w. by rewrite word0.- move=> n IH V f w.simpl.have: popLow w = popLow w by []; move: {-1}(popLow w) => [b w'] eq.rewrite IH.have: b = b by []; case: {-1}b => <-; move: eq => <-; by rewrite popLowK.Qed.Definition update {n V} : memory n V -> (V -> V) -> word n -> memory n V.Proof.move: V; elim: n.- move=> V m f _. exact (f m).- move=> n recurse V m f /popLow [b w].move: (fun '(x,y) => if b then (x, f y) else (f x, y)) => f'.exact (recurse (V*V)%type m f' w).Defined.Lemma update_spec {n V} (f : V -> V) (w w' : word n) m: get (update m f w') w = if w == w' then f (get m w) else get m w.Proof.move: V f w w' m; elim: n.- move=> V f w w' m. by rewrite word0 word0.- move=> n IH V f w w' m.rewrite -{2}[w]popLowK -{2}[w']popLowK.simpl.move: (popLow w) (popLow w'); clear w w'; move=> [b w] [b' w'].rewrite IH.have->: (pushLow (b, w) == pushLow (b', w')) = andb (b == b') (w == w')by rewrite /pushLow; do 3 (rewrite /eq_op; simpl).move: (get (n := n) m w) => [x y].by case: (w == w'); case: b; case: b'.Qed.