1.1 --- a/ula.py Mon Jun 20 00:15:20 2016 +0200
1.2 +++ b/ula.py Mon Jun 20 15:40:58 2016 +0200
1.3 @@ -374,8 +374,8 @@
1.4
1.5 # Initialise the pixel buffer if appropriate.
1.6
1.7 - if not self.writing_pixels and self.have_pixels:
1.8 - self.buffer_index = 0
1.9 + if self.have_pixels:
1.10 + self.pdata = decode(self.data, self.depth)
1.11 self.writing_pixels = 1
1.12
1.13 # Latch row address, set column address (for ULA access only).
1.14 @@ -443,10 +443,6 @@
1.15 if access_ram:
1.16 self.data = self.data | self.ram.data
1.17 self.have_pixels = 1
1.18 -
1.19 - # Rearrange the byte value.
1.20 -
1.21 - self.pdata = decode(self.data, self.depth)
1.22 else:
1.23 self.cpu_transfer_low()
1.24
1.25 @@ -508,27 +504,31 @@
1.26 # For pixels within the frame, obtain and output the value.
1.27
1.28 else:
1.29 - self.video.colour = self.get_pixel()
1.30 + self.output_colour_value()
1.31
1.32 # Scale pixels horizontally, only accessing the next pixel value
1.33 # after the required number of scan positions.
1.34
1.35 if self.x % self.xscale == 0:
1.36 - self.buffer_index += self.depth
1.37 + self.next_pixel_value()
1.38
1.39 # Finish writing pixels.
1.40
1.41 if self.x % PIXEL_POSITIONS == 0:
1.42 self.writing_pixels = 0
1.43
1.44 - def get_pixel(self):
1.45 + def output_colour_value(self):
1.46
1.47 """
1.48 - Return the current pixel by translating memory content for the current
1.49 - mode.
1.50 + Output the colour value for the current pixel by translating memory
1.51 + content for the current mode.
1.52 """
1.53
1.54 - return self.palette[value_of_bits(self.pdata[self.buffer_index:self.buffer_index+self.depth])]
1.55 + value = value_of_bits(self.pdata, self.depth)
1.56 + self.video.colour = self.palette[value]
1.57 +
1.58 + def next_pixel_value(self):
1.59 + self.pdata = rotate(self.pdata, self.depth)
1.60
1.61 def wrap_address(self):
1.62 if self.address >= SCREEN_LIMIT:
1.63 @@ -548,15 +548,24 @@
1.64 if self.cpu_read:
1.65 self.cpu_data = self.data | self.ram.data
1.66
1.67 -def value_of_bits(bits):
1.68 +def rotate(value, depth):
1.69
1.70 - "Convert the sequence of 'bits' into a value."
1.71 + "Return 'value' rotated by the number of bits given by 'depth'."
1.72
1.73 - value = 0
1.74 - for bit in bits:
1.75 - value *= 2
1.76 - value += bit and 1 or 0
1.77 - return value
1.78 + field = 8 - depth
1.79 + top = value >> field
1.80 + mask = 2 ** (8 - depth) - 1
1.81 + rest = value & mask
1.82 + return (rest << depth) | top
1.83 +
1.84 +def value_of_bits(value, depth):
1.85 +
1.86 + """
1.87 + Convert the upper bits of 'value' to a result, using 'depth' to indicate the
1.88 + number of bits involved.
1.89 + """
1.90 +
1.91 + return value >> (8 - depth)
1.92
1.93 def get_physical_colour(value):
1.94
1.95 @@ -574,14 +583,13 @@
1.96 """
1.97
1.98 if depth == 1:
1.99 - return (value >> 7, value >> 6 & 1, value >> 5 & 1, value >> 4 & 1,
1.100 - value >> 3 & 1, value >> 2 & 1, value >> 1 & 1, value & 1)
1.101 + return value
1.102 elif depth == 2:
1.103 - return (value >> 7, value >> 3 & 1, value >> 6 & 1, value >> 2 & 1,
1.104 - value >> 5 & 1, value >> 1 & 1, value >> 4 & 1, value & 1)
1.105 + return ((value & 128) | ((value & 8) << 3) | ((value & 64) >> 1) | ((value & 4) << 2) |
1.106 + ((value & 32) >> 2) | ((value & 2) << 1) | ((value & 16) >> 3) | (value & 1))
1.107 elif depth == 4:
1.108 - return (value >> 7, value >> 5 & 1, value >> 3 & 1, value >> 1 & 1,
1.109 - value >> 6 & 1, value >> 4 & 1, value >> 2 & 1, value & 1)
1.110 + return ((value & 128) | ((value & 32) << 1) | ((value & 8) << 2) | ((value & 2) << 3) |
1.111 + ((value & 64) >> 3) | ((value & 16) >> 2) | ((value & 4) >> 1) | (value & 1))
1.112 else:
1.113 raise ValueError, "Only depths of 1, 2 and 4 are supported, not %d." % depth
1.114