# HG changeset patch # User Paul Boddie # Date 1391273757 -3600 # Node ID 6363b9a428654043a5936362bb0d9d685c1aca83 # Parent 5c69742b0242be7a1bb767eac47d3b150ac2cec8 Introduced a shift register abstraction for the ULA's internal state. diff -r 5c69742b0242 -r 6363b9a42865 ula.py --- a/ula.py Sun Nov 17 01:00:40 2013 +0100 +++ b/ula.py Sat Feb 01 17:55:57 2014 +0100 @@ -127,6 +127,33 @@ self.memory[i << 1] = value >> 4 self.memory[i << 1 | 0x1] = value & 0xf +class ShiftRegister: + + """ + A class representing a shift register, used for the internal state of the + ULA within each 2MHz period. + """ + + def __init__(self): + self.state = [0] * 8 + self.input = 0 + + def set_input(self, input): + self.input = input + + def shift(self): + + # NOTE: This is not meant to be "nice" Python, but instead models the + # NOTE: propagation of state through the latches. + + self.state[0], self.state[1], self.state[2], self.state[3], \ + self.state[4], self.state[5], self.state[6], self.state[7] = \ + self.input, self.state[0], self.state[1], self.state[2], \ + self.state[3], self.state[4], self.state[5], self.state[6] + + def __getitem__(self, i): + return self.state[i] + class ULA: """ @@ -172,13 +199,16 @@ # Internal state. - self.cycle = [0]*8 # counter within each 2MHz period represented by 8 latches self.access = 0 # counter used to determine whether a byte needs reading self.have_pixels = 0 # whether pixel data has been read self.writing_pixels = 0 # whether pixel data can be written self.buffer = [BLANK]*8 # pixel buffer for decoded RAM data - self.cycle[7] = 1 # assert the final latch (asserting the first on update) + self.cycle = ShiftRegister() # 8-state counter within each 2MHz period + + self.cycle.set_input(1) # assert the input to set the first state output + self.cycle.shift() + self.cycle.set_input(0) # reset the input since only one state output will be active self.reset_vertical() @@ -322,15 +352,6 @@ access_ram = not self.nmi and self.access == 0 and self.read_pixels() and not self.ssub - # Update the state of the device. - # NOTE: This is not meant to be "nice" Python, but instead models the - # NOTE: propagation of state through the latches. - - self.cycle[0], self.cycle[1], self.cycle[2], self.cycle[3], \ - self.cycle[4], self.cycle[5], self.cycle[6], self.cycle[7] = \ - self.cycle[7], self.cycle[0], self.cycle[1], self.cycle[2], \ - self.cycle[3], self.cycle[4], self.cycle[5], self.cycle[6] - # Set row address (for ULA access only). if self.cycle[0]: @@ -433,6 +454,11 @@ self.access = (self.access + 1) % self.access_frequency + # Update the state of the device. + + self.cycle.set_input(self.cycle[7]) + self.cycle.shift() + # Video signalling.