2.1 --- a/ULA.txt Sun Feb 26 23:19:22 2012 +0100
2.2 +++ b/ULA.txt Sun Apr 28 23:01:53 2013 +0200
2.3 @@ -1,3 +1,24 @@
2.4 +Principal Design and Feature Constraints
2.5 +----------------------------------------
2.6 +
2.7 +The features of the ULA are limited by the amount of time and resources that
2.8 +can be allocated to each activity necessary to support such features given the
2.9 +fundamental obligations of the unit. Maintaining a screen display based on the
2.10 +contents of RAM itself requires the ULA to have exclusive access to such
2.11 +hardware resources for a significant period of time. Whilst other elements of
2.12 +the ULA can in principle run in parallel with this activity, they cannot also
2.13 +access the RAM. Consequently, other features that might use the RAM must
2.14 +accept a reduced allocation of that resource in comparison to a hypothetical
2.15 +architecture where concurrent RAM access is possible.
2.16 +
2.17 +Thus, the principal constraint for many features is bandwidth. The duration of
2.18 +access to hardware resources is one aspect of this; the rate at which such
2.19 +resources can be accessed is another. For example, the RAM is not fast enough
2.20 +to support access more frequently than one byte per 2MHz cycle, and for screen
2.21 +modes involving 80 bytes of screen data per scanline, there are no free cycles
2.22 +for anything other than the production of pixel output during the active
2.23 +scanline periods.
2.24 +
2.25 Timing
2.26 ------
2.27
2.28 @@ -41,6 +62,11 @@
2.29 communicate the latter behaviour. In the TM4164EC4 datasheet, it appears that
2.30 "page mode" provides the appropriate behaviour for that particular product.
2.31
2.32 +See: Acorn Electron Advanced User Guide
2.33 +See: Acorn Electron Service Manual
2.34 + http://acorn.chriswhy.co.uk/docs/Acorn/Manuals/Acorn_ElectronSM.pdf
2.35 +See: http://mdfs.net/Docs/Comp/Electron/Techinfo.htm
2.36 +
2.37 Video Timing
2.38 ------------
2.39
2.40 @@ -105,8 +131,6 @@
2.41 with approximately 15 blank lines above and below the picture. Thus, the start
2.42 of the picture could be chosen as 38 lines after the start of vsync.
2.43
2.44 -See: Acorn Electron Advanced User Guide
2.45 -See: http://mdfs.net/Docs/Comp/Electron/Techinfo.htm
2.46 See: http://en.wikipedia.org/wiki/PAL
2.47 See: http://en.wikipedia.org/wiki/Analog_television#Structure_of_a_video_signal
2.48 See: The 625/50 PAL Video Signal and TV Compatible Graphics Modes
2.49 @@ -115,10 +139,65 @@
2.50 http://www.retroleum.co.uk/electronics-articles/pal-tv-timing-and-voltages/
2.51 See: Line Standards
2.52 http://www.pembers.freeserve.co.uk/World-TV-Standards/Line-Standards.html
2.53 +
2.54 +RAM Integrated Circuits
2.55 +-----------------------
2.56 +
2.57 +The documentation for the Electron mentions 4164-15 RAM chips for IC4-7, and
2.58 +the Samsung-produced KM4164 series is apparently equivalent to the Texas
2.59 +Instruments 4164 chips presumably used in the Electron.
2.60 +
2.61 +The TM4164EC4 series combines 4 64K x 1b units into a single package and
2.62 +appears similar to the TM4164EA4 featured on the Electron's circuit diagram
2.63 +(in the Advanced User Guide but not the Service Manual), and it also has 22
2.64 +pins providing 3 additional inputs and 3 additional outputs over the 16 pins
2.65 +of the individual 4164-15 modules, presumably allowing concurrent access to
2.66 +the packaged memory units.
2.67 +
2.68 +As far as currently available replacements are concerned, the NTE4164 is a
2.69 +potential candidate: according to the Vetco Electronics entry, it is
2.70 +supposedly a replacement for the TMS4164-15 amongst many other parts. Similar
2.71 +parts include the NTE2164 and the NTE6664, both of which appear to have
2.72 +largely the same performance and connection characteristics. Meanwhile, the
2.73 +NTE21256 appears to be a 16-pin replacement with four times the capacity that
2.74 +maintains the single data input and output pins. Using the NTE21256 as a
2.75 +replacement for all ICs combined would be difficult because of the single bit
2.76 +output.
2.77 +
2.78 +Another device equivalent to the 4164-15 appears to be available under the
2.79 +code 41662 from Jameco Electronics as the Siemens HYB 4164-2. The Jameco Web
2.80 +site lists data sheets for other devices on the same page, but these are
2.81 +different and actually appear to be provided under the 41574 product code (but
2.82 +are listed under 41464-10) and appear to be replacements for the TM4164EC4:
2.83 +the Samsung KM41464A-15 and NEC µPD41464 employ 18 pins, eliminating 4 pins by
2.84 +employing 4 pins for both input and output.
2.85 +
2.86 See: TM4164EC4 65,536 by 4-Bit Dynamic RAM Module
2.87 http://www.datasheetarchive.com/dl/Datasheets-112/DSAP0051030.pdf
2.88 -See: Acorn Electron Service Manual
2.89 - http://acorn.chriswhy.co.uk/docs/Acorn/Manuals/Acorn_ElectronSM.pdf
2.90 +See: KM4164B 64K x 1 Bit Dynamic RAM with Page Mode
2.91 + http://images.ihscontent.net/vipimages/VipMasterIC/IC/SAMS/SAMSD020/SAMSD020-45.pdf
2.92 +See: NTE2164 Integrated Circuit 65,536 X 1 Bit Dynamic Random Access Memory
2.93 + http://www.vetco.net/catalog/product_info.php?products_id=2806
2.94 +See: NTE4164 - IC-NMOS 64K DRAM 150NS
2.95 + http://www.vetco.net/catalog/product_info.php?products_id=3680
2.96 +See: NTE21256 - IC-256K DRAM 150NS
2.97 + http://www.vetco.net/catalog/product_info.php?products_id=2799
2.98 +See: NTE21256 262,144-Bit Dynamic Random Access Memory (DRAM)
2.99 + http://www.nteinc.com/specs/21000to21999/pdf/nte21256.pdf
2.100 +See: NTE6664 - IC-MOS 64K DRAM 150NS
2.101 + http://www.vetco.net/catalog/product_info.php?products_id=5213
2.102 +See: NTE6664 Integrated Circuit 64K-Bit Dynamic RAM
2.103 + http://www.nteinc.com/specs/6600to6699/pdf/nte6664.pdf
2.104 +See: 4164-150: MAJOR BRANDS
2.105 + http://www.jameco.com/webapp/wcs/stores/servlet/Product_10001_10001_41662_-1
2.106 +See: HYB 4164-1, HYB 4164-2, HYB 4164-3 65,536-Bit Dynamic Random Access Memory (RAM)
2.107 + http://www.jameco.com/Jameco/Products/ProdDS/41662SIEMENS.pdf
2.108 +See: KM41464A NMOS DRAM 64K x 4 Bit Dynamic RAM with Page Mode
2.109 + http://www.jameco.com/Jameco/Products/ProdDS/41662SAM.pdf
2.110 +See: NEC µ41464 65,536 x 4-Bit Dynamic NMOS RAM
2.111 + http://www.jameco.com/Jameco/Products/ProdDS/41662NEC.pdf
2.112 +See: 41464-10: MAJOR BRANDS
2.113 + http://www.jameco.com/webapp/wcs/stores/servlet/Product_10001_10001_41574_-1
2.114
2.115 Interrupts
2.116 ----------
2.117 @@ -200,8 +279,8 @@
2.118 trivial change). Another pitfall is the complication that might be introduced
2.119 to software writing bitmaps of character height to the screen.
2.120
2.121 -Region Blanking
2.122 ----------------
2.123 +Enhancement: Region Blanking
2.124 +----------------------------
2.125
2.126 The problem of permitting character-oriented blitting in programs whilst
2.127 scrolling the screen by sub-character amounts could be mitigated by permitting
2.128 @@ -238,8 +317,12 @@
2.129 Thus, in this case, region blanking would impose a 250 line display with the
2.130 bottom 6 lines blank.
2.131
2.132 -Screen Height Adjustment
2.133 -------------------------
2.134 +See the description of the display suspend enhancement for a more efficient
2.135 +way of blanking lines whilst allowing the CPU to perform useful work during
2.136 +the blanking period.
2.137 +
2.138 +Enhancement: Screen Height Adjustment
2.139 +-------------------------------------
2.140
2.141 The height of the screen could be configurable in order to reduce screen
2.142 memory consumption. This is not quite done in MODE 3 and 6 since the start of
2.143 @@ -253,8 +336,16 @@
2.144 320 1 240 40 640 &5A80 -> &5A00
2.145 320 2 240 80 1280 &3500
2.146
2.147 -Palette Definition
2.148 -------------------
2.149 +Screen Mode Selection
2.150 +---------------------
2.151 +
2.152 +Bits 3, 4 and 5 of address &FE*7 control the selected screen mode. For a wider
2.153 +range of modes, the other bits of &FE*7 (related to sound, cassette
2.154 +input/output and the Caps Lock LED) would need to be reassigned and bit 0
2.155 +potentially being made available for use.
2.156 +
2.157 +Enhancement: Palette Definition
2.158 +-------------------------------
2.159
2.160 Since all memory accesses go via the ULA, an enhanced ULA could employ more
2.161 specific addresses than &FE*X to perform enhanced functions. For example, the
2.162 @@ -269,10 +360,92 @@
2.163 those outputs are strictly digital and can only be set to a "high" and "low"
2.164 value, then only the existing eight colours are possible. If a modern ULA were
2.165 able to output analogue values, it would still need to be assessed whether the
2.166 -circuitry could successfully handle and propagate such values.
2.167 +circuitry could successfully handle and propagate such values. Various sources
2.168 +indicate that only "TTL levels" are supported by the RGB output circuit, and
2.169 +since there are 74LS08 AND logic gates involved in the RGB component outputs
2.170 +from the ULA, it is likely that the ULA is expected to provide only "high" or
2.171 +"low" values.
2.172 +
2.173 +Short of adding extra outputs from the ULA (either additional red, green and
2.174 +blue outputs or a combined intensity output), another approach might involve
2.175 +some kind of modulation where an output value might be encoded in multiple
2.176 +pulses at a higher frequency than the pixel frequency. However, this would
2.177 +demand additional circuitry outside the ULA.
2.178 +
2.179 +Flashing Colours
2.180 +----------------
2.181 +
2.182 +According to the Advanced User Guide, "The cursor and flashing colours are
2.183 +entirely generated in software: This means that all of the logical to physical
2.184 +colour map must be changed to cause colours to flash." This appears to suggest
2.185 +that the palette registers must be updated upon the flash counter - read and
2.186 +written by OSBYTE &C1 (193) - reaching zero and that some way of changing the
2.187 +colour pairs to be any combination of colours might be possible, instead of
2.188 +having colour complements as pairs.
2.189 +
2.190 +It is conceivable that the interrupt code responsible does the simple thing
2.191 +and merely inverts the current values for any logical colours (LC) for which
2.192 +the associated physical colour (as supplied as the second parameter to the VDU
2.193 +19 call) has the top bit of its four bit value set. These top bits are not
2.194 +recorded in the palette registers but are presumably recorded separately and
2.195 +used to build bitmaps as follows:
2.196
2.197 -Palette Definition Lists
2.198 -------------------------
2.199 + LC 2 colour 4 colour 16 colour 4-bit value for inversion
2.200 + -- -------- -------- --------- -------------------------
2.201 + 0 00010001 00010001 00010001 1, 1, 1
2.202 + 1 01000100 00100010 00010001 4, 2, 1
2.203 + 2 01000100 00100010 4, 2
2.204 + 3 10001000 00100010 8, 2
2.205 + 4 00010001 1
2.206 + 5 00010001 1
2.207 + 6 00100010 2
2.208 + 7 00100010 2
2.209 + 8 01000100 4
2.210 + 9 01000100 4
2.211 + 10 10001000 8
2.212 + 11 10001000 8
2.213 + 12 01000100 4
2.214 + 13 01000100 4
2.215 + 14 10001000 8
2.216 + 15 10001000 8
2.217 +
2.218 + Inversion value calculation:
2.219 +
2.220 + 2 colour formula: 1 << (colour * 2)
2.221 + 4 colour formula: 1 << colour
2.222 + 16 colour formula: 1 << ((colour & 2) + ((colour & 8) * 2))
2.223 +
2.224 +For example, where logical colour 0 has been mapped to a physical colour in
2.225 +the range 8 to 15, a bitmap of 00010001 would be chosen as its contribution to
2.226 +the inversion operation. (The lower three bits of the physical colour would be
2.227 +used to set the underlying colour information affected by the inversion
2.228 +operation.)
2.229 +
2.230 +An operation in the interrupt code would then combine the bitmaps for all
2.231 +logical colours in 2 and 4 colour modes, with the 16 colour bitmaps being
2.232 +combined for groups of logical colours as follows:
2.233 +
2.234 + Logical colours
2.235 + ---------------
2.236 + 0, 2, 8, 10
2.237 + 4, 6, 12, 14
2.238 + 5, 7, 13, 15
2.239 + 1, 3, 9, 11
2.240 +
2.241 +These combined bitmaps would be EORed with the existing palette register
2.242 +values in order to perform the value inversion necessary to produce the
2.243 +flashing effect.
2.244 +
2.245 +Thus, in the VDU 19 operation, the appropriate inversion value would be
2.246 +calculated for the logical colour, and this value would then be combined with
2.247 +other inversion values in a dedicated memory location corresponding to the
2.248 +colour's group as indicated above. Meanwhile, the palette channel values would
2.249 +be derived from the lower three bits of the specified physical colour and
2.250 +combined with other palette data in dedicated memory locations corresponding
2.251 +to the palette registers.
2.252 +
2.253 +Enhancement: Palette Definition Lists
2.254 +-------------------------------------
2.255
2.256 It can be useful to redefine the palette in order to change the colours
2.257 available for a particular region of the screen, particularly in modes where
2.258 @@ -290,8 +463,8 @@
2.259 at the appropriate time. Throughput/bandwidth considerations might impose
2.260 restrictions on the practical length of such a list, however.
2.261
2.262 -Palette-Free Modes
2.263 -------------------
2.264 +Enhancement: Palette-Free Modes
2.265 +-------------------------------
2.266
2.267 Palette-free modes might be defined where bit values directly correspond to
2.268 the red, green and blue channels, although this would mostly make sense only
2.269 @@ -299,8 +472,8 @@
2.270 modes would require more memory than MODE 2 if they were to have an acceptable
2.271 resolution.
2.272
2.273 -Display Suspend
2.274 ----------------
2.275 +Enhancement: Display Suspend
2.276 +----------------------------
2.277
2.278 Especially when writing to the screen memory, it could be beneficial to be
2.279 able to suspend the ULA's access to the memory, instead producing blank values
2.280 @@ -313,8 +486,8 @@
2.281 that hardware to reduce the load on the system CPU which was responsible for
2.282 producing the video output.
2.283
2.284 -Hardware Sprites
2.285 -----------------
2.286 +Enhancement: Hardware Sprites
2.287 +-----------------------------
2.288
2.289 An enhanced ULA might provide hardware sprites, but this would be done in an
2.290 way that is incompatible with the standard ULA, since no &FE*X locations are
2.291 @@ -336,8 +509,8 @@
2.292 bandwidth is not already fully utilised, this would result in a degradation of
2.293 performance.
2.294
2.295 -Additional Screen Mode Configurations
2.296 --------------------------------------
2.297 +Enhancement: Additional Screen Mode Configurations
2.298 +--------------------------------------------------
2.299
2.300 Alternative screen mode configurations could be supported. The ULA has to
2.301 produce 640 pixel values across the screen, with pixel doubling or quadrupling
2.302 @@ -355,7 +528,7 @@
2.303 columns is to be supported, compromises must be made such as the introduction
2.304 of blank pixels either between characters (such as occurs between rows in MODE
2.305 3 and 6) or at the end of a scanline (such as occurs at the end of the frame
2.306 -in MODE 3 and 6). Consider the following configuration:
2.307 +in MODE 3 and 6). Consider the following configuration:
2.308
2.309 Screen width Columns Scaling Depth Bytes Blank
2.310 ------------ ------- ------- ----- ------ -----
2.311 @@ -366,8 +539,8 @@
2.312 generated either at the start or end (or split between the start and end) of
2.313 each scanline.
2.314
2.315 -Character Attributes
2.316 ---------------------
2.317 +Enhancement: Character Attributes
2.318 +---------------------------------
2.319
2.320 The BBC Micro MODE 7 employs something resembling character attributes to
2.321 support teletext displays, but depends on circuitry providing a character
2.322 @@ -437,8 +610,8 @@
2.323 208 26 x3 26 26 256 &62C0 -> &6200
2.324 208 26 x3 26 13 16 &6460 -> &6400
2.325
2.326 -MODE 7 Emulation using Character Attributes
2.327 --------------------------------------------
2.328 +Enhancement: MODE 7 Emulation using Character Attributes
2.329 +--------------------------------------------------------
2.330
2.331 If the scheme of applying attributes to character regions were employed to
2.332 emulate MODE 7, in conjunction with the MODE 6 display technique, the
2.333 @@ -454,8 +627,8 @@
2.334 at least make a limited 40-column multicolour mode available as a substitute
2.335 for MODE 7.
2.336
2.337 -Enhanced Graphics and Mode Layouts
2.338 -----------------------------------
2.339 +Enhancement: High Resolution Graphics and Mode Layouts
2.340 +------------------------------------------------------
2.341
2.342 Screen modes with different screen memory mappings, higher resolutions and
2.343 larger colour depths might be possible, but this would in most cases involve
2.344 @@ -467,11 +640,22 @@
2.345 especially since accessing regions of the screen would involve incrementing
2.346 pointers by amounts that are inconvenient on an 8-bit CPU.
2.347
2.348 -Enhanced Sound
2.349 ---------------
2.350 +Enhancement: Genlock Support
2.351 +----------------------------
2.352
2.353 -The standard ULA reserves &FE*6 for sound generation and cassette
2.354 -input/output, thus making it impossible to support multiple channels within
2.355 +The ULA generates a video signal in conjunction with circuitry producing the
2.356 +output features necessary for the correct display of the screen image.
2.357 +However, it appears that the ULA drives the video synchronisation mechanism
2.358 +instead of reacting to an existing signal. Genlock support might be possible
2.359 +if the ULA were made to be responsive to such external signals, resetting its
2.360 +address generators upon receiving synchronisation events.
2.361 +
2.362 +Enhancement: Improved Sound
2.363 +---------------------------
2.364 +
2.365 +The standard ULA reserves &FE*6 for sound generation and cassette input/output
2.366 +(with bits 1 and 2 of &FE*7 being used to select either sound generation or
2.367 +cassette I/O), thus making it impossible to support multiple channels within
2.368 the given framework. The BBC Micro ULA employs &FE40-&FE4F for sound control,
2.369 and an enhanced ULA could adopt this interface.
2.370
2.371 @@ -481,14 +665,25 @@
2.372
2.373 See: http://en.wikipedia.org/wiki/Texas_Instruments_SN76489
2.374
2.375 -Waveform Upload
2.376 ----------------
2.377 +Enhancement: Waveform Upload
2.378 +----------------------------
2.379
2.380 As with a hardware sprite function, waveforms could be uploaded or referenced
2.381 using locations as registers referencing memory regions.
2.382
2.383 -BBC ULA Compatibility
2.384 ----------------------
2.385 +Enhancement: Sound Input/Output
2.386 +-------------------------------
2.387 +
2.388 +Since the ULA already controls audio input/output for cassette-based data, it
2.389 +would have been interesting to entertain the idea of sampling and output of
2.390 +sounds through the cassette interface. However, a significant amount of
2.391 +circuitry is employed to process the input signal for use by the ULA and to
2.392 +process the output signal for recording.
2.393 +
2.394 +See: http://bbc.nvg.org/doc/A%20Hardware%20Guide%20for%20the%20BBC%20Microcomputer/bbc_hw_03.htm#3.11
2.395 +
2.396 +Enhancement: BBC ULA Compatibility
2.397 +----------------------------------
2.398
2.399 Although some new ULA functions could be defined in a way that is also
2.400 compatible with the BBC Micro, the BBC ULA is itself incompatible with the
2.401 @@ -503,6 +698,27 @@
2.402 Electron) and other system-specific functions. Since the location usage is
2.403 generally incompatible, this region could be reused for other purposes.
2.404
2.405 +Enhancement: Increased RAM, ULA and CPU Performance
2.406 +---------------------------------------------------
2.407 +
2.408 +More modern implementations of the hardware might feature faster RAM coupled
2.409 +with an increased ULA clock frequency in order to increase the bandwidth
2.410 +available to the ULA and to the CPU in situations where the ULA is not needed
2.411 +to perform work. A ULA employing a 32MHz clock would be able to complete the
2.412 +retrieval of a byte from RAM in only 250ns and thus be able to enable the CPU
2.413 +to access the RAM for the following 250ns even in display modes requiring the
2.414 +retrieval of a byte for the display every 500ns. The CPU could, subject to
2.415 +timing issues, run at 2MHz even in MODE 0, 1 and 2.
2.416 +
2.417 +A scheme such as that described above would have a similar effect to the
2.418 +scheme employed in the BBC Micro, although the latter made use of RAM with a
2.419 +wider bandwidth in order to complete memory transfers within 250ns and thus
2.420 +permit the CPU to run continuously at 2MHz.
2.421 +
2.422 +Higher bandwidth could potentially be used to implement exotic features such
2.423 +as RAM-resident hardware sprites or indeed any feature demanding RAM access
2.424 +concurrent with the production of the display image.
2.425 +
2.426 ULA Pin Functions
2.427 -----------------
2.428
2.429 @@ -576,3 +792,8 @@
2.430 CAS MO (motor relay output)
2.431
2.432 ÷13 IN (~1200 baud clock input)
2.433 +
2.434 +References
2.435 +----------
2.436 +
2.437 +See: http://bbc.nvg.org/doc/A%20Hardware%20Guide%20for%20the%20BBC%20Microcomputer/bbc_hw.htm
3.1 --- a/ula.py Sun Feb 26 23:19:22 2012 +0100
3.2 +++ b/ula.py Sun Apr 28 23:01:53 2013 +0200
3.3 @@ -82,10 +82,10 @@
3.4
3.5 """
3.6 A class representing the RAM circuits (IC4 to IC7). Each circuit
3.7 - traditionally holds 64 kilobits, with two accesses required to read 2 bits
3.8 - from each in order to obtain a whole byte. Here, we model the circuits with
3.9 - a list of 65536 half-bytes with each bit representing a bit stored on a
3.10 - separate IC.
3.11 + traditionally holds 64 kilobits, with each access obtaining 1 bit from each
3.12 + IC, and thus two accesses being required to obtain a whole byte. Here, we
3.13 + model the circuits with a list of 65536 half-bytes with each bit in a
3.14 + half-byte representing a bit stored on a separate IC.
3.15 """
3.16
3.17 def __init__(self):
3.18 @@ -98,12 +98,18 @@
3.19 self.data = 0
3.20
3.21 def row_select(self, address):
3.22 +
3.23 + "The operation of asserting a row 'address' via RA0...RA7."
3.24 +
3.25 self.row_address = address
3.26
3.27 def row_deselect(self):
3.28 pass
3.29
3.30 def column_select(self, address):
3.31 +
3.32 + "The operation of asserting a column 'address' via RA0...RA7."
3.33 +
3.34 self.column_address = address
3.35
3.36 # Read the data.
3.37 @@ -158,15 +164,22 @@
3.38 self.nmi = 0 # no NMI asserted initially
3.39 self.irq_vsync = 0 # no IRQ asserted initially
3.40
3.41 + # Communication.
3.42 +
3.43 + self.ram_address = 0 # address given to the RAM via RA0...RA7
3.44 + self.data = 0 # data read from the RAM via RAM0...RAM3
3.45 + self.cpu_address = 0 # address selected by the CPU via A0...A15
3.46 + self.cpu_read = 0 # data read/write by the CPU selected using R/W
3.47 +
3.48 # Internal state.
3.49
3.50 - self.cycle = 0 # counter within each 2MHz period
3.51 + self.cycle = [0]*8 # counter within each 2MHz period represented by 8 latches
3.52 self.access = 0 # counter used to determine whether a byte needs reading
3.53 - self.ram_address = 0 # address given to the RAM
3.54 - self.data = 0 # data read from the RAM
3.55 - self.buffer = [BLANK]*8 # pixel buffer for decoded RAM data
3.56 self.have_pixels = 0 # whether pixel data has been read
3.57 self.writing_pixels = 0 # whether pixel data can be written
3.58 + self.buffer = [BLANK]*8 # pixel buffer for decoded RAM data
3.59 +
3.60 + self.cycle[7] = 1 # assert the final latch (asserting the first on update)
3.61
3.62 self.reset_vertical()
3.63
3.64 @@ -310,14 +323,25 @@
3.65
3.66 access_ram = not self.nmi and self.access == 0 and self.read_pixels() and not self.ssub
3.67
3.68 + # Update the state of the device.
3.69 + # NOTE: This is not meant to be "nice" Python, but instead models the
3.70 + # NOTE: propagation of state through the latches.
3.71 +
3.72 + self.cycle[0], self.cycle[1], self.cycle[2], self.cycle[3], \
3.73 + self.cycle[4], self.cycle[5], self.cycle[6], self.cycle[7] = \
3.74 + self.cycle[7], self.cycle[0], self.cycle[1], self.cycle[2], \
3.75 + self.cycle[3], self.cycle[4], self.cycle[5], self.cycle[6]
3.76 +
3.77 # Set row address (for ULA access only).
3.78
3.79 - if self.cycle == 0:
3.80 + if self.cycle[0]:
3.81
3.82 - # NOTE: Propagate CPU address here.
3.83 + # Either assert a required address or propagate the CPU address.
3.84
3.85 if access_ram:
3.86 - self.ram_address = (self.address & 0xff80) >> 7
3.87 + self.init_row_address(self.address)
3.88 + else:
3.89 + self.init_row_address(self.cpu_address)
3.90
3.91 # Initialise the pixel buffer if appropriate.
3.92
3.93 @@ -329,62 +353,65 @@
3.94
3.95 # Latch row address, set column address (for ULA access only).
3.96
3.97 - elif self.cycle == 1:
3.98 + elif self.cycle[1]:
3.99 +
3.100 + # Select an address needed by the ULA or CPU.
3.101
3.102 - # NOTE: Permit CPU access here.
3.103 + self.ram.row_select(self.ram_address)
3.104 +
3.105 + # Either assert a required address or propagate the CPU address.
3.106
3.107 if access_ram:
3.108 - self.ram.row_select(self.ram_address)
3.109 -
3.110 - # NOTE: Propagate CPU address here.
3.111 -
3.112 - if access_ram:
3.113 - self.ram_address = (self.address & 0x7f) << 1
3.114 + self.init_column_address(self.address, 0)
3.115 + else:
3.116 + self.init_column_address(self.cpu_address, 0)
3.117
3.118 # Latch column address.
3.119
3.120 - elif self.cycle == 2:
3.121 + elif self.cycle[2]:
3.122
3.123 - # NOTE: Permit CPU access here.
3.124 + # Select an address needed by the ULA or CPU.
3.125
3.126 - if access_ram:
3.127 - self.ram.column_select(self.ram_address)
3.128 + self.ram.column_select(self.ram_address)
3.129
3.130 # Read 4 bits (for ULA access only).
3.131 # NOTE: Perhaps map alternate bits, not half-bytes.
3.132
3.133 - elif self.cycle == 3:
3.134 + elif self.cycle[3]:
3.135
3.136 - # NOTE: Propagate CPU data here.
3.137 + # Either read from a required address or transfer CPU data.
3.138
3.139 if access_ram:
3.140 self.data = self.ram.data << 4
3.141 + else:
3.142 + self.cpu_transfer_high()
3.143
3.144 # Set column address (for ULA access only).
3.145
3.146 - elif self.cycle == 4:
3.147 + elif self.cycle[4]:
3.148 self.ram.column_deselect()
3.149
3.150 - # NOTE: Propagate CPU address here.
3.151 + # Either assert a required address or propagate the CPU address.
3.152
3.153 if access_ram:
3.154 - self.ram_address = (self.address & 0x7f) << 1 | 0x1
3.155 + self.init_column_address(self.address, 1)
3.156 + else:
3.157 + self.init_column_address(self.cpu_address, 1)
3.158
3.159 # Latch column address.
3.160
3.161 - elif self.cycle == 5:
3.162 + elif self.cycle[5]:
3.163
3.164 - # NOTE: Permit CPU access here.
3.165 + # Select an address needed by the ULA or CPU.
3.166
3.167 - if access_ram:
3.168 - self.ram.column_select(self.ram_address)
3.169 + self.ram.column_select(self.ram_address)
3.170
3.171 # Read 4 bits (for ULA access only).
3.172 # NOTE: Perhaps map alternate bits, not half-bytes.
3.173
3.174 - elif self.cycle == 6:
3.175 + elif self.cycle[6]:
3.176
3.177 - # NOTE: Propagate CPU data here.
3.178 + # Either read from a required address or transfer CPU data.
3.179
3.180 if access_ram:
3.181 self.data = self.data | self.ram.data
3.182 @@ -394,10 +421,12 @@
3.183
3.184 self.address += LINES_PER_ROW
3.185 self.wrap_address()
3.186 + else:
3.187 + self.cpu_transfer_low()
3.188
3.189 # Reset addresses.
3.190
3.191 - elif self.cycle == 7:
3.192 + elif self.cycle[7]:
3.193 self.ram.column_deselect()
3.194 self.ram.row_deselect()
3.195
3.196 @@ -405,8 +434,6 @@
3.197
3.198 self.access = (self.access + 1) % self.access_frequency
3.199
3.200 - self.cycle = (self.cycle + 1) % 8
3.201 -
3.202
3.203
3.204 # Video signalling.
3.205 @@ -479,6 +506,20 @@
3.206 if self.address >= SCREEN_LIMIT:
3.207 self.address -= self.screen_size
3.208
3.209 + def init_row_address(self, address):
3.210 + self.ram_address = (address & 0xff80) >> 7
3.211 +
3.212 + def init_column_address(self, address, offset):
3.213 + self.ram_address = (address & 0x7f) << 1 | offset
3.214 +
3.215 + def cpu_transfer_high(self):
3.216 + if self.cpu_read:
3.217 + self.cpu_data = self.ram.data << 4
3.218 +
3.219 + def cpu_transfer_low(self):
3.220 + if self.cpu_read:
3.221 + self.cpu_data = self.data | self.ram.data
3.222 +
3.223 def get_physical_colour(value):
3.224
3.225 """