# HG changeset patch # User Paul Boddie # Date 1367182401 -7200 # Node ID c7970b37736f303c4989d02dde98a67202ededf3 # Parent 751a7ca72c0549e3b9b7fdd5505166722a908ff0 Added initial support for CPU address and data propagation. diff -r 751a7ca72c05 -r c7970b37736f ula.py --- a/ula.py Sun Apr 28 22:43:13 2013 +0200 +++ b/ula.py Sun Apr 28 22:53:21 2013 +0200 @@ -99,12 +99,18 @@ self.data = 0 def row_select(self, address): + + "The operation of asserting a row 'address' via RA0...RA7." + self.row_address = address def row_deselect(self): pass def column_select(self, address): + + "The operation of asserting a column 'address' via RA0...RA7." + self.column_address = address # Read the data. @@ -157,12 +163,17 @@ self.nmi = 0 # no NMI asserted initially self.irq_vsync = 0 # no IRQ asserted initially + # Communication. + + self.ram_address = 0 # address given to the RAM via RA0...RA7 + self.data = 0 # data read from the RAM via RAM0...RAM3 + self.cpu_address = 0 # address selected by the CPU via A0...A15 + self.cpu_read = 0 # data read/write by the CPU selected using R/W + # 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.ram_address = 0 # address given to the RAM - self.data = 0 # data read from the RAM 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 @@ -324,10 +335,12 @@ if self.cycle[0]: - # NOTE: Propagate CPU address here. + # Either assert a required address or propagate the CPU address. if access_ram: - self.ram_address = (self.address & 0xff80) >> 7 + self.init_row_address(self.address) + else: + self.init_row_address(self.cpu_address) # Initialise the pixel buffer if appropriate. @@ -341,60 +354,63 @@ elif self.cycle[1]: - # NOTE: Permit CPU access here. + # Select an address needed by the ULA or CPU. + + self.ram.row_select(self.ram_address) + + # Either assert a required address or propagate the CPU address. if access_ram: - self.ram.row_select(self.ram_address) - - # NOTE: Propagate CPU address here. - - if access_ram: - self.ram_address = (self.address & 0x7f) << 1 + self.init_column_address(self.address, 0) + else: + self.init_column_address(self.cpu_address, 0) # Latch column address. elif self.cycle[2]: - # NOTE: Permit CPU access here. + # Select an address needed by the ULA or CPU. - if access_ram: - self.ram.column_select(self.ram_address) + self.ram.column_select(self.ram_address) # Read 4 bits (for ULA access only). # NOTE: Perhaps map alternate bits, not half-bytes. elif self.cycle[3]: - # NOTE: Propagate CPU data here. + # Either read from a required address or transfer CPU data. if access_ram: self.data = self.ram.data << 4 + else: + self.cpu_transfer_high() # Set column address (for ULA access only). elif self.cycle[4]: self.ram.column_deselect() - # NOTE: Propagate CPU address here. + # Either assert a required address or propagate the CPU address. if access_ram: - self.ram_address = (self.address & 0x7f) << 1 | 0x1 + self.init_column_address(self.address, 1) + else: + self.init_column_address(self.cpu_address, 1) # Latch column address. elif self.cycle[5]: - # NOTE: Permit CPU access here. + # Select an address needed by the ULA or CPU. - if access_ram: - self.ram.column_select(self.ram_address) + self.ram.column_select(self.ram_address) # Read 4 bits (for ULA access only). # NOTE: Perhaps map alternate bits, not half-bytes. elif self.cycle[6]: - # NOTE: Propagate CPU data here. + # Either read from a required address or transfer CPU data. if access_ram: self.data = self.data | self.ram.data @@ -404,6 +420,8 @@ self.address += LINES_PER_ROW self.wrap_address() + else: + self.cpu_transfer_low() # Reset addresses. @@ -487,6 +505,20 @@ if self.address >= SCREEN_LIMIT: self.address -= self.screen_size + def init_row_address(self, address): + self.ram_address = (address & 0xff80) >> 7 + + def init_column_address(self, address, offset): + self.ram_address = (address & 0x7f) << 1 | offset + + def cpu_transfer_high(self): + if self.cpu_read: + self.cpu_data = self.ram.data << 4 + + def cpu_transfer_low(self): + if self.cpu_read: + self.cpu_data = self.data | self.ram.data + def get_physical_colour(value): """