1.1 --- a/ula.py Mon Feb 13 22:25:37 2012 +0100
1.2 +++ b/ula.py Sun Feb 26 23:19:22 2012 +0100
1.3 @@ -18,7 +18,7 @@
1.4 MAX_PIXELLINE = MIN_PIXELLINE + MAX_HEIGHT
1.5
1.6 MAX_HSYNC = 75 # the number of cycles in each hsync period
1.7 -MIN_PIXELPOS = 264 # the first cycle involving pixel generation
1.8 +MIN_PIXELPOS = 256 # the first cycle involving pixel generation
1.9 MAX_SCANPOS = 1024 # the number of cycles in each scanline
1.10
1.11 MAX_PIXELPOS = MIN_PIXELPOS + MAX_WIDTH
1.12 @@ -72,7 +72,7 @@
1.13
1.14 def update(self):
1.15 if MIN_PIXELLINE <= self.y < MAX_PIXELLINE:
1.16 - if MIN_PIXELPOS <= self.x < MAX_PIXELPOS:
1.17 + if MIN_PIXELPOS + 8 <= self.x < MAX_PIXELPOS + 8:
1.18 self.screen[self.pos] = self.colour[0]; self.pos += 1
1.19 self.screen[self.pos] = self.colour[1]; self.pos += 1
1.20 self.screen[self.pos] = self.colour[2]; self.pos += 1
1.21 @@ -153,6 +153,11 @@
1.22
1.23 "Reset the ULA."
1.24
1.25 + # General state.
1.26 +
1.27 + self.nmi = 0 # no NMI asserted initially
1.28 + self.irq_vsync = 0 # no IRQ asserted initially
1.29 +
1.30 # Internal state.
1.31
1.32 self.cycle = 0 # counter within each 2MHz period
1.33 @@ -160,6 +165,8 @@
1.34 self.ram_address = 0 # address given to the RAM
1.35 self.data = 0 # data read from the RAM
1.36 self.buffer = [BLANK]*8 # pixel buffer for decoded RAM data
1.37 + self.have_pixels = 0 # whether pixel data has been read
1.38 + self.writing_pixels = 0 # whether pixel data can be written
1.39
1.40 self.reset_vertical()
1.41
1.42 @@ -278,8 +285,7 @@
1.43
1.44 def in_frame(self): return MIN_PIXELLINE <= self.y < MAX_PIXELLINE
1.45 def inside_frame(self): return MIN_PIXELLINE < self.y < MAX_PIXELLINE
1.46 - def read_pixels(self): return MIN_PIXELPOS - 8 <= self.x < MAX_PIXELPOS - 8 and self.in_frame()
1.47 - def make_pixels(self): return MIN_PIXELPOS <= self.x < MAX_PIXELPOS and self.in_frame()
1.48 + def read_pixels(self): return MIN_PIXELPOS <= self.x < MAX_PIXELPOS and self.in_frame()
1.49
1.50 def update(self):
1.51
1.52 @@ -302,7 +308,7 @@
1.53
1.54 # Clock management.
1.55
1.56 - access_ram = self.access == 0 and self.read_pixels() and not self.ssub
1.57 + access_ram = not self.nmi and self.access == 0 and self.read_pixels() and not self.ssub
1.58
1.59 # Set row address (for ULA access only).
1.60
1.61 @@ -313,6 +319,14 @@
1.62 if access_ram:
1.63 self.ram_address = (self.address & 0xff80) >> 7
1.64
1.65 + # Initialise the pixel buffer if appropriate.
1.66 +
1.67 + if not self.writing_pixels and self.have_pixels:
1.68 + self.xcounter = self.xscale
1.69 + self.buffer_index = 0
1.70 + self.fill_pixel_buffer()
1.71 + self.writing_pixels = 1
1.72 +
1.73 # Latch row address, set column address (for ULA access only).
1.74
1.75 elif self.cycle == 1:
1.76 @@ -374,6 +388,7 @@
1.77
1.78 if access_ram:
1.79 self.data = self.data | self.ram.data
1.80 + self.have_pixels = 1
1.81
1.82 # Advance to the next column.
1.83
1.84 @@ -402,6 +417,9 @@
1.85 self.hsync()
1.86 if self.y == 0:
1.87 self.vsync()
1.88 + self.irq_vsync = 0
1.89 + elif self.y == MAX_PIXELLINE:
1.90 + self.irq_vsync = 1
1.91
1.92 # Detect the end of hsync.
1.93
1.94 @@ -419,34 +437,27 @@
1.95
1.96 # Detect spacing between character rows.
1.97
1.98 - if not self.make_pixels() or self.ssub:
1.99 + if not self.writing_pixels or self.ssub:
1.100 self.video.colour = BLANK
1.101
1.102 # For pixels within the frame, obtain and output the value.
1.103
1.104 else:
1.105 - # Detect the start of the pixel generation.
1.106
1.107 - if self.x == MIN_PIXELPOS:
1.108 - self.xcounter = self.xscale
1.109 - self.buffer_index = 0
1.110 - self.fill_pixel_buffer()
1.111 + self.xcounter -= 1
1.112 + self.video.colour = self.buffer[self.buffer_index]
1.113
1.114 # Scale pixels horizontally, only accessing the next pixel value
1.115 # after the required number of scan positions.
1.116
1.117 - elif self.xcounter == 0:
1.118 + if self.xcounter == 0:
1.119 self.xcounter = self.xscale
1.120 self.buffer_index += 1
1.121
1.122 - # Fill the pixel buffer, assuming that data is available.
1.123 + # Handle the buffer empty condition.
1.124
1.125 if self.buffer_index >= self.buffer_limit:
1.126 - self.buffer_index = 0
1.127 - self.fill_pixel_buffer()
1.128 -
1.129 - self.xcounter -= 1
1.130 - self.video.colour = self.buffer[self.buffer_index]
1.131 + self.writing_pixels = 0
1.132
1.133 self.x += 1
1.134