/************************************************************************/
/*  R instruction format:                                               */
/*  op   rd  rs  rt  N/A                                                */
/*  0000_000_000_000_XXX                                                */
/*                                                                      */
/*  I instruction format:                                               */
/*  op    rd  rs  signed_lit                                            */
/*  0000__000_000_000000                                                */
/*                                                                      */
/*  B/S instruction format:                                             */
/*  op    rt  rs  signed_lit                                            */
/*  0000__000_000_000000                                                */
/*                                                                      */
/*  J instruction format:                                               */
/*  op      unsinged_lit                                                */
/*  0000____000000000000                                                */
/*                                                                      */
/*  Opcodes:                                                            */
/*  0000 NOP  N/A                                   (All  zeros)        */
/*  0001 ADD  $rd = $rs + $rt                       (R   format)        */
/*  0010 ADDi $rd = $rs + lit                       (I   format)        */
/*  0011 SUB  $rd = $rs - $rt                       (R   format)        */
/*  0100 SUBi $rd = $rs - lit                       (I   format)        */
/*  0101 LWr  $rd = mem($rs + $rt)                  (R   format)        */
/*  0110 LW   $rd = mem($rs + lit)                  (I   format)        */
/*  0111 SW   mem($rs + lit) = $rt                  (B/S format)        */
/*  1000 JMP  PC = unsigned_lit                     (J   format)        */
/*  1001 BEQ  if $rs == $rt, PC = PC + 2*signed_lit (B/S format)        */
/*                                                                      */
/*  Underscores can be used to separate                                 */
/*  data bits into logical groups.                                      */
/*                                                                      */
/*  C-style comments can be used to make                                */
/*  the code more readable.                                             */
/*                                                                      */
/*  The data radix is base 2(binary).                                   */
/************************************************************************/

//////////////////////////////////////////////////////////////////////////
//  Find the last occurrence of a value in an array.                    //
//                                                                      //
//  Data memory:                                                        //
//  0x00 = Array base address.                                          //
//  0x04 = Array length in elements.                                    //
//  0x08 = Element value to search for.                                 //
//  0x0C = Start of array.                                              //
//  0x78 = 7 segment display - memory mapped I/O.                       //
//                                                                      //
//  Registers:                                                          //
//  r0 = Zero reference.                                                //
//  r1 = Array base address.                                            //
//  r2 = Array pointer.                                                 //
//  r3 = Element index.                                                 //
//  r4 = Retreived value from memory\comparison results.                //
//  r5 = Value to find.                                                 //
//  r6 = Current array element number.                                  //
//////////////////////////////////////////////////////////////////////////

//Address 0
0101_001_000_000_000 //LWr  $r1, $r0($r0) <- Get array start index.
//Address 2
0110__010_000_000100 //LW   $r2, 4($r0)   <- Get array length in words.
//Address 4
0001_110_010_000_000 //ADD $r6, $r2, $r0  <- Store number of array elements.
//Address 6
0001_010_010_010_000 //ADD  $r2, $r2, $r2 <- *2.
//Address 8
0001_010_010_010_000 //ADD  $r2, $r2, $r2 <- *2, Array length in bytes.
//Address 10
0100__010_010_000100 //SUBi $r2, $r2, 4   <- Subtract 4 to find start of last word.
//Address 12
0011_011_011_011_000 //SUB  $r3, $r3, $r3 <- Zero element index.
//Address 14
0100__011_011_000001 //SUBi $r3, $r3, 1   <- Set index to -1 (not found).
//Address 16
0110__101_000_001000 //LW   $r5, 8($r0)   <- Get value to find.

//FindLoop:

//Address 18
0101_100_001_010_000 //LWr  $r4, $r2($r1) <- Get value from array.
//Address 20
0011_100_100_101_000 //SUB  $r4, $r4, $r5 <- Compare with value to find.
//Address 22
1001__100_000_000100 //BEQ  $r4, $r0, 4   <- Branch if match found.
//Address 24
1001__010_000_000100 //BEQ  $r2, $r0, 4   <- Exit if last index reached.
//Address 26
0100__010_010_000100 //SUBi $r2, $r2, 4   <- Decrement to next array index.
//Address 28
0100__110_110_000001 //SUBi $r6, $r6, 1   <-Decrement current array element.
//Address 30
1000____000000010010 //JMP  FindLoop      <- More work to do, loop.

//MatchFound:

//Address 32
0100_011_110_000001 //SUBi $r3, $r6, 1    <- Match. Save index-1 (count from 0).

//LoopFinished:

//Address 34
0010__010_000_011110 //ADDi $r2, $r0, 30  <- Load register with 30.
//Address 36
0001_010_010_010_000 //ADD  $r2, $r2, $r2 <- *2.
//Address 38
0001_010_010_010_000 //ADD  $r2, $r2, $r2 <- *2, Now contains address 120.
//Address 40
0111__011_010_000000 //SW   $r3, 0($r2)   <-Write results to 7 segment display.

//Spinlock:

//Address 42
1000____000000101110 //JMP  Spinlock      <- Done.