diff --git a/main.py b/main.py
index 57ec0683727c9934b09a55ecf2862b0268a42d17..1f4e82843dc9cbc9622481ced0685260c78221a0 100644
--- a/main.py
+++ b/main.py
@@ -107,11 +107,11 @@ class CacheSimulator():
 
         print('hits:{0} misses:{1} evictions:{2}'.format(self.hits, self.misses, self.evictions))
 
-    def handle_line(self, line, main_cache_line=True):
+    def handle_line(self, line, main_bool=True):
         """
         Handles cache simulation for given line instruction.
         :param line: Line to handle for.
-        :param main_cache_line: Bool to indicate if this is an initial cache line read in or a subquery from one.
+        :param main_bool: Bool to indicate if this is an initial cache line read in or a subquery from one.
                 Note that only initial cache line read ins will print or update missed/skipped/evicted variables.
         """
         split_line = re.split(r'[ ,\n]', line)
@@ -123,9 +123,11 @@ class CacheSimulator():
         else:
             line = line.strip()
 
-            # Not an instruction load. Keep processing. Start by getting address.
-            address = int(split_line[2]) % self.M
-            value_size = int(split_line[3])
+            # Not an instruction load. Keep processing. Start by parsing line info.
+            parsed_data = {}
+            address = int(split_line[2])
+            parsed_data['address'] = address
+            parsed_data['value_size'] = int(split_line[3])
 
             # Get mask values.
             block_mask = self.B - 1
@@ -135,94 +137,26 @@ class CacheSimulator():
             tag_mask = (self.M - 1) ^ set_mask ^ block_mask
 
             # Use masks to get address chunks.
-            block = address & block_mask
+            parsed_data['block'] = address & block_mask
             set = (address & set_mask) >> block_offset
+            parsed_data['set'] = set
             tag = (address & tag_mask) >> (block_offset + set_offset)
+            parsed_data['tag'] = tag
 
             # We have our values. Now compare against the all entries in the cache.
             for index in range(len(self.cache[set])):
                 # Check if match.
                 if self.cache[set][index]['valid'] == True and self.cache[set][index]['tag'] == tag:
                     # Match found.
-                    if main_cache_line:
-                        # Is main cache file line. Update hits/misses/evictions.
-                        self.hits += 1
-
-                        # Print if verbose flag set.
-                        if self.verbose:
-                            print('{0} hit'.format(line))
-
-                    return
+                    return self.process_hit(line, set, main_bool)
                 else:
                     # Not a match. Examine why.
                     if self.cache[set][index]['valid'] == False:
                         # Cache location was not set. Cold miss. We can just set and return.
-                        if main_cache_line:
-                            # Is main cache file line. Update hits/misses/evictions.
-                            self.misses += 1
-
-                            # Print if verbose flag set.
-                            if self.verbose:
-                                print('{0} miss'.format(line))
-
-                        self.cache[set][index]['valid'] = True
-                        self.cache[set][index]['tag'] = tag
-
-                        # Set block values that are "loaded" into memory.
-                        lower_offset = int(address / self.B) * self.B
-                        upper_offset = (int(address / self.B) + 1) * self.B
-                        value_offset = address + value_size
-                        self.cache[set][index]['block'] = []
-                        for i in range(self.B):
-                            self.cache[set][index]['block'].append(lower_offset + i)
-
-                        # Check if size sets address outside of current cache block.
-                        if value_offset >= upper_offset:
-                            # Size sets address outside of current cache block. Update additional blocks as needed.
-                            # Start by getting our new size.
-                            new_size = value_offset - upper_offset
-                            if new_size < 0:
-                                new_size = 0
-
-                            # Pass our new line data.
-                            new_line = ' L {0},{1}'.format(upper_offset, new_size)
-                            self.handle_line(new_line, main_cache_line=False)
-
-                        return
+                        return self.process_miss(line, parsed_data, index, main_bool)
 
             # If we made it this far, cache locations were set, but tags did not match. Conflict miss.
-            if main_cache_line:
-                # Is main cache file line. Update hits/misses/evictions.
-                self.misses += 1
-                self.evictions += 1
-
-                # Print if verbose flag set.
-                if self.verbose:
-                    print('{0} miss eviction'.format(line))
-
-            self.cache[set][0]['tag'] = tag
-
-            # Set block values that are "loaded" into memory.
-            lower_offset = int(address / self.B) * self.B
-            upper_offset = (int(address / self.B) + 1) * self.B
-            value_offset = address + value_size
-            self.cache[set][0]['block'] = []
-            for i in range(self.B):
-                self.cache[set][0]['block'].append(lower_offset + i)
-
-            # Check if size sets address outside of current cache block.
-            if value_offset >= upper_offset:
-                # Size sets address outside of current cache block. Update additional blocks as needed.
-                # Start by getting our new size.
-                new_size = value_offset - upper_offset
-                if new_size < 0:
-                    new_size = 0
-
-                # Pass our new line data.
-                new_line = ' L {0},{1}'.format(upper_offset, new_size)
-                self.handle_line(new_line, main_cache_line=False)
-
-            return
+            return self.process_eviction(line, parsed_data, main_bool)
 
     def print_cache(self):
         """
@@ -235,6 +169,91 @@ class CacheSimulator():
                 print('    Line {0}: {1}'.format(line_index, self.cache[set_index][line_index]))
         print('')
 
+    def process_hit(self, line, parsed_data, main_bool):
+        if main_bool:
+            # Is main cache file line. Update hits/misses/evictions.
+            self.hits += 1
+
+            # Print if verbose flag set.
+            if self.verbose:
+                print('{0} hit'.format(line))
+
+    def process_miss(self, line, parsed_data, index, main_bool):
+        if main_bool:
+            # Is main cache file line. Update hits/misses/evictions.
+            self.misses += 1
+
+            # Print if verbose flag set.
+            if self.verbose:
+                print('{0} miss'.format(line))
+
+        # Pull out relevant data from passed dict.
+        address = parsed_data['address']
+        value_size = parsed_data['value_size']
+        set = parsed_data['set']
+        tag = parsed_data['tag']
+
+        self.cache[set][index]['valid'] = True
+        self.cache[set][index]['tag'] = tag
+
+        # Set block values that are "loaded" into memory.
+        lower_offset = int(address / self.B) * self.B
+        upper_offset = (int(address / self.B) + 1) * self.B
+        value_offset = address + value_size
+        self.cache[set][index]['block'] = []
+        for i in range(self.B):
+            self.cache[set][index]['block'].append(lower_offset + i)
+
+        # Check if size sets address outside of current cache block.
+        if value_offset >= upper_offset:
+            # Size sets address outside of current cache block. Update additional blocks as needed.
+            # Start by getting our new size.
+            new_size = value_offset - upper_offset
+            if new_size < 0:
+                new_size = 0
+
+            # Pass our new line data.
+            new_line = ' L {0},{1}'.format(upper_offset, new_size)
+            self.handle_line(new_line, main_bool=False)
+
+    def process_eviction(self, line, parsed_data, main_bool):
+        if main_bool:
+            # Is main cache file line. Update hits/misses/evictions.
+            self.misses += 1
+            self.evictions += 1
+
+            # Print if verbose flag set.
+            if self.verbose:
+                print('{0} miss eviction'.format(line))
+
+        # Pull out relevant data from passed dict.
+        address = parsed_data['address']
+        value_size = parsed_data['value_size']
+        set = parsed_data['set']
+        tag = parsed_data['tag']
+
+        self.cache[set][0]['tag'] = tag
+
+        # Set block values that are "loaded" into memory.
+        lower_offset = int(address / self.B) * self.B
+        upper_offset = (int(address / self.B) + 1) * self.B
+        value_offset = address + value_size
+        self.cache[set][0]['block'] = []
+        for i in range(self.B):
+            self.cache[set][0]['block'].append(lower_offset + i)
+
+        # Check if size sets address outside of current cache block.
+        if value_offset >= upper_offset:
+            # Size sets address outside of current cache block. Update additional blocks as needed.
+            # Start by getting our new size.
+            new_size = value_offset - upper_offset
+            if new_size < 0:
+                new_size = 0
+
+            # Pass our new line data.
+            new_line = ' L {0},{1}'.format(upper_offset, new_size)
+            self.handle_line(new_line, main_bool=False)
+
 
 if __name__ == '__main__':
     print('Starting program.')