# HG changeset patch # User Paul Boddie # Date 1323044439 -3600 # Node ID 69e7ee0e99dd530760ecb6359ef40573d156bd5d # Parent 4460129be79e86a60bc3cc9f548694504aa95f86 Added spacing between character rows and fixed the number of rows in the modes involved. diff -r 4460129be79e -r 69e7ee0e99dd ula.py --- a/ula.py Sun Dec 04 21:43:45 2011 +0100 +++ b/ula.py Mon Dec 05 01:20:39 2011 +0100 @@ -10,12 +10,13 @@ WIDTH = 640 HEIGHT = 512 +INTENSITY = 255 LINES_PER_ROW = 8 MAX_HEIGHT = 256 SCREEN_LIMIT = 0x8000 MAX_MEMORY = 0x10000 -INTENSITY = 255 +BLANK = (0, 0, 0) def update(screen, ula): @@ -41,8 +42,8 @@ modes = [ (640, 1, 32), (320, 2, 32), (160, 4, 32), # (width, depth, rows) - (640, 1, 24), (320, 1, 32), (160, 2, 32), - (320, 1, 24) + (640, 1, 25), (320, 1, 32), (160, 2, 32), + (320, 1, 25) ] palette = range(0, 8) * 2 @@ -75,15 +76,29 @@ * number of entries in the pixel buffer """ - self.width, self.depth, self.rows = self.modes[mode] + self.width, self.depth, rows = self.modes[mode] + + row_size = (self.width * self.depth * LINES_PER_ROW) / 8 # bits per row -> bytes per row - row_size = (self.width * self.depth * LINES_PER_ROW) / 8 # bits per row -> bytes per row + # Memory access configuration. + + self.screen_size = row_size * rows + self.screen_start = (SCREEN_LIMIT - self.screen_size) & 0xff00 # limitation on positioning + + # Scanline configuration. - self.screen_size = row_size * self.rows - self.screen_start = SCREEN_LIMIT - self.screen_size - self.xscale = WIDTH / self.width # pixel width in display pixels - self.yscale = HEIGHT / (self.rows * LINES_PER_ROW) # pixel height in display pixels - self.spacing = MAX_HEIGHT / self.rows - LINES_PER_ROW # pixels between rows + self.xscale = WIDTH / self.width # pixel width in display pixels + self.yscale = HEIGHT / (rows * LINES_PER_ROW) # pixel height in display pixels + + self.spacing = MAX_HEIGHT / rows - LINES_PER_ROW # pixels between rows + + # Start of unused region. + + self.footer = rows * LINES_PER_ROW + self.margin = MAX_HEIGHT - rows * (LINES_PER_ROW + self.spacing) + self.spacing + + # Internal pixel buffer size. + self.buffer_limit = 8 / self.depth def vsync(self): @@ -93,6 +108,7 @@ self.line_start = self.address = self.screen_start self.line = 0 self.ysub = 0 + self.ssub = 0 self.reset_horizontal() def reset_horizontal(self): @@ -106,6 +122,12 @@ "Signal the end of a line." + # Support spacing between character rows. + + if self.ssub: + self.ssub -= 1 + return + self.reset_horizontal() # Scale pixels vertically. @@ -123,7 +145,9 @@ self.ysub = 0 self.line += 1 - if self.line < LINES_PER_ROW: + # If not on a row boundary, move to the next line. + + if self.line % LINES_PER_ROW: self.address = self.line_start + 1 self.wrap_address() @@ -134,12 +158,17 @@ self.address -= LINES_PER_ROW - 1 self.wrap_address() - self.line_start = self.address + # Test for the footer region. + + if self.spacing and self.line == self.footer: + self.ssub = self.margin * self.yscale + return - # Move on to the next row if appropriate. + # Support spacing between character rows. - if self.line == LINES_PER_ROW: - self.line = 0 + self.ssub = self.spacing * self.yscale + + self.line_start = self.address def get_pixel_colour(self): @@ -147,6 +176,11 @@ Return a pixel colour by reading from the pixel buffer. """ + # Detect spacing between character rows. + + if self.ssub: + return BLANK + # Scale pixels horizontally. if self.xsub == self.xscale: @@ -268,4 +302,17 @@ update(a, ula) mainloop() + # Test MODE 6. + + ula.set_mode(6) + + fill(memory, 0x6000, 0x6f00 + 160, encode((1, 0, 1, 1, 0, 0, 1, 1), 1)) + fill(memory, 0x6f00 + 160, 0x7f40, encode((1, 0, 1, 0, 1, 0, 1, 0), 1)) + update(a, ula) + mainloop() + + ula.screen_start = 0x6f00 + 160 + update(a, ula) + mainloop() + # vim: tabstop=4 expandtab shiftwidth=4