# HG changeset patch # User Paul Boddie # Date 1466512451 -7200 # Node ID 87b0ccdb9bc4c9eac9f5b17e76a78e537ce5c393 # Parent 05ee520ae9d1e0288a15e6084a25183f6eb2cafa Refined and expanded the RAM access timings, moving data transfers to the negative edge handler. diff -r 05ee520ae9d1 -r 87b0ccdb9bc4 ULA.txt --- a/ULA.txt Mon Jun 20 23:40:11 2016 +0200 +++ b/ULA.txt Tue Jun 21 14:34:11 2016 +0200 @@ -48,26 +48,33 @@ Each 16MHz cycle is approximately 62.5ns. To access the memory, the following patterns corresponding to 16MHz cycles are required: - Time (ns): 0-------------- 500------------ ... - 2 MHz cycle: 0 1 ... - 16 MHz cycle: 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 ... - ~RAS: 0 1 0 1 ... - ~CAS: 0 1 0 1 0 1 0 1 ... - A B C A B C ... - F S F S ... - a b c a b c ... + Time (ns): 0-------------- 500------------- ... + 2 MHz cycle: 0 1 ... + 16 MHz cycle: 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 ... + /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ ... + ~RAS: --\___________/---\___________/- ... + ~CAS: ----\___/-\___/-----\___/-\___/- ... + A B C A B C ... + F S F S ... + a b c a b c ... + f s f s ... - ~WE: ......W ... - PHI OUT: ______________/---------------\ ... - CPU: D L ... - RnW: R ... + ~WE: ......W ... + PHI OUT: ______________/---------------\ ... + CPU (RAM): D L ... + RnW: R ... + + PHI OUT: ______/-------\_______/-------\ ... + CPU (ROM): D L D L ... + RnW: R R ... Here, "A" and "B" respectively indicate the row and first column addresses being latched into the RAM (on a negative edge for ~RAS and ~CAS respectively), and "C" indicates the second column address being latched into the RAM. Presumably, the first and second half-bytes can be read at "F" and "S" respectively, and the row and column addresses must be made available at -"a" and "b" (and "c") respectively at the latest. +"a" and "b" (and "c") respectively at the latest. Data can be read at "f" and +"s" for the first and second half-bytes respectively. For the CPU, "L" indicates the point at which an address is taken from the CPU address bus, on a negative edge of PHI OUT, with "D" being the point at which @@ -79,9 +86,11 @@ brought low. The TM4164EC4-15 has a row address access time of 150ns (maximum) and a column -address access time of 90ns (maximum), which appears to mean that -approximately two 16MHz cycles after the row address is latched, and one and a -half cycles after the column address is latched, the data becomes available. +address access time of 90ns (maximum), which appears to mean that ~RAS must be +held low for at least 150ns and that ~CAS must be held low for at least 90ns +before data becomes available. 150ns is 2.4 cycles (at 16MHz) and 90ns is 1.44 +cycles. Thus, "A" to "F" is 2.5 cycles, "B" to "F" is 1.5 cycles, "C" to "S" +is 1.5 cycles. Note that the Service Manual refers to the negative edge of RAS and CAS, but the datasheet for the similar TM4164EC4 product shows latching on the negative diff -r 05ee520ae9d1 -r 87b0ccdb9bc4 ula.py --- a/ula.py Mon Jun 20 23:40:11 2016 +0200 +++ b/ula.py Tue Jun 21 14:34:11 2016 +0200 @@ -417,16 +417,7 @@ else: self.cpu_transfer_select() - # Read 4 bits (for ULA access only). - - elif self.cycle == 8: - - # Either read from a required address or transfer CPU data. - - if access_ram: - self.data = self.ram.data << 4 - else: - self.cpu_transfer_high() + # Cycle handled in negedge. # Set column address (for ULA access only). @@ -452,14 +443,6 @@ elif self.cycle == 64: - # Either read from a required address or transfer CPU data. - - if access_ram: - self.data = self.data | self.ram.data - self.have_pixels = 1 - else: - self.cpu_transfer_low() - # Advance to the next column even if an NMI is asserted. if would_access_ram: @@ -502,12 +485,44 @@ def negedge(self): - "Update the state of the device." + """ + Update the state of the device. + + Cycles handled: _ _ _ * _ _ * * + """ + + # Clock management. + + would_access_ram = self.access == 0 and self.read_pixels() and self.in_line() + access_ram = not self.nmi and would_access_ram + + # Read 4 bits (for ULA access only). + + if self.cycle == 8: + + # Either read from a required address or transfer CPU data. + + if access_ram: + self.data = self.ram.data << 4 + else: + self.cpu_transfer_high() + + # Read 4 bits (for ULA access only). + + elif self.cycle == 64: + + # Either read from a required address or transfer CPU data. + + if access_ram: + self.data = self.data | self.ram.data + self.have_pixels = 1 + else: + self.cpu_transfer_low() # Initialise the pixel buffer if appropriate. Output starts after # this cycle. - if self.cycle == 128 and self.have_pixels: + elif self.cycle == 128 and self.have_pixels: self.pdata = decode(self.data, self.depth) self.pcycle = 1 self.have_pixels = 0