1.1 --- a/ula.py Sun Apr 28 22:43:13 2013 +0200
1.2 +++ b/ula.py Sun Apr 28 22:53:21 2013 +0200
1.3 @@ -99,12 +99,18 @@
1.4 self.data = 0
1.5
1.6 def row_select(self, address):
1.7 +
1.8 + "The operation of asserting a row 'address' via RA0...RA7."
1.9 +
1.10 self.row_address = address
1.11
1.12 def row_deselect(self):
1.13 pass
1.14
1.15 def column_select(self, address):
1.16 +
1.17 + "The operation of asserting a column 'address' via RA0...RA7."
1.18 +
1.19 self.column_address = address
1.20
1.21 # Read the data.
1.22 @@ -157,12 +163,17 @@
1.23 self.nmi = 0 # no NMI asserted initially
1.24 self.irq_vsync = 0 # no IRQ asserted initially
1.25
1.26 + # Communication.
1.27 +
1.28 + self.ram_address = 0 # address given to the RAM via RA0...RA7
1.29 + self.data = 0 # data read from the RAM via RAM0...RAM3
1.30 + self.cpu_address = 0 # address selected by the CPU via A0...A15
1.31 + self.cpu_read = 0 # data read/write by the CPU selected using R/W
1.32 +
1.33 # Internal state.
1.34
1.35 self.cycle = [0]*8 # counter within each 2MHz period represented by 8 latches
1.36 self.access = 0 # counter used to determine whether a byte needs reading
1.37 - self.ram_address = 0 # address given to the RAM
1.38 - self.data = 0 # data read from the RAM
1.39 self.have_pixels = 0 # whether pixel data has been read
1.40 self.writing_pixels = 0 # whether pixel data can be written
1.41 self.buffer = [BLANK]*8 # pixel buffer for decoded RAM data
1.42 @@ -324,10 +335,12 @@
1.43
1.44 if self.cycle[0]:
1.45
1.46 - # NOTE: Propagate CPU address here.
1.47 + # Either assert a required address or propagate the CPU address.
1.48
1.49 if access_ram:
1.50 - self.ram_address = (self.address & 0xff80) >> 7
1.51 + self.init_row_address(self.address)
1.52 + else:
1.53 + self.init_row_address(self.cpu_address)
1.54
1.55 # Initialise the pixel buffer if appropriate.
1.56
1.57 @@ -341,60 +354,63 @@
1.58
1.59 elif self.cycle[1]:
1.60
1.61 - # NOTE: Permit CPU access here.
1.62 + # Select an address needed by the ULA or CPU.
1.63 +
1.64 + self.ram.row_select(self.ram_address)
1.65 +
1.66 + # Either assert a required address or propagate the CPU address.
1.67
1.68 if access_ram:
1.69 - self.ram.row_select(self.ram_address)
1.70 -
1.71 - # NOTE: Propagate CPU address here.
1.72 -
1.73 - if access_ram:
1.74 - self.ram_address = (self.address & 0x7f) << 1
1.75 + self.init_column_address(self.address, 0)
1.76 + else:
1.77 + self.init_column_address(self.cpu_address, 0)
1.78
1.79 # Latch column address.
1.80
1.81 elif self.cycle[2]:
1.82
1.83 - # NOTE: Permit CPU access here.
1.84 + # Select an address needed by the ULA or CPU.
1.85
1.86 - if access_ram:
1.87 - self.ram.column_select(self.ram_address)
1.88 + self.ram.column_select(self.ram_address)
1.89
1.90 # Read 4 bits (for ULA access only).
1.91 # NOTE: Perhaps map alternate bits, not half-bytes.
1.92
1.93 elif self.cycle[3]:
1.94
1.95 - # NOTE: Propagate CPU data here.
1.96 + # Either read from a required address or transfer CPU data.
1.97
1.98 if access_ram:
1.99 self.data = self.ram.data << 4
1.100 + else:
1.101 + self.cpu_transfer_high()
1.102
1.103 # Set column address (for ULA access only).
1.104
1.105 elif self.cycle[4]:
1.106 self.ram.column_deselect()
1.107
1.108 - # NOTE: Propagate CPU address here.
1.109 + # Either assert a required address or propagate the CPU address.
1.110
1.111 if access_ram:
1.112 - self.ram_address = (self.address & 0x7f) << 1 | 0x1
1.113 + self.init_column_address(self.address, 1)
1.114 + else:
1.115 + self.init_column_address(self.cpu_address, 1)
1.116
1.117 # Latch column address.
1.118
1.119 elif self.cycle[5]:
1.120
1.121 - # NOTE: Permit CPU access here.
1.122 + # Select an address needed by the ULA or CPU.
1.123
1.124 - if access_ram:
1.125 - self.ram.column_select(self.ram_address)
1.126 + self.ram.column_select(self.ram_address)
1.127
1.128 # Read 4 bits (for ULA access only).
1.129 # NOTE: Perhaps map alternate bits, not half-bytes.
1.130
1.131 elif self.cycle[6]:
1.132
1.133 - # NOTE: Propagate CPU data here.
1.134 + # Either read from a required address or transfer CPU data.
1.135
1.136 if access_ram:
1.137 self.data = self.data | self.ram.data
1.138 @@ -404,6 +420,8 @@
1.139
1.140 self.address += LINES_PER_ROW
1.141 self.wrap_address()
1.142 + else:
1.143 + self.cpu_transfer_low()
1.144
1.145 # Reset addresses.
1.146
1.147 @@ -487,6 +505,20 @@
1.148 if self.address >= SCREEN_LIMIT:
1.149 self.address -= self.screen_size
1.150
1.151 + def init_row_address(self, address):
1.152 + self.ram_address = (address & 0xff80) >> 7
1.153 +
1.154 + def init_column_address(self, address, offset):
1.155 + self.ram_address = (address & 0x7f) << 1 | offset
1.156 +
1.157 + def cpu_transfer_high(self):
1.158 + if self.cpu_read:
1.159 + self.cpu_data = self.ram.data << 4
1.160 +
1.161 + def cpu_transfer_low(self):
1.162 + if self.cpu_read:
1.163 + self.cpu_data = self.data | self.ram.data
1.164 +
1.165 def get_physical_colour(value):
1.166
1.167 """