# HG changeset patch # User Paul Boddie # Date 1367182913 -7200 # Node ID 9c2b0bd3083e1d580e3fd864b46774fdfedaeaef # Parent 4d0b268480eb7b0174f596290ec2769a5ca167fe# Parent c7970b37736f303c4989d02dde98a67202ededf3 Merged general changes. diff -r 4d0b268480eb -r 9c2b0bd3083e Electron.txt --- a/Electron.txt Sun Feb 26 23:19:22 2012 +0100 +++ b/Electron.txt Sun Apr 28 23:01:53 2013 +0200 @@ -58,3 +58,12 @@ access four memory chips at once to provide each byte, and it is therefore not possible to just "borrow" one of the chips in order to isolate 8K of RAM for direct access by the CPU. + +Improving Display Capabilities +------------------------------ + +Perhaps the simplest improvement to the display capabilities would be to +permit the RGB output levels to "float" between the current TTL high and low +states, presumably enforced by various circuits. This would permit the choice +of colours beyond the primary and secondary colour selection at a cost of some +extra palette bits in the ULA and an adjustment to the board circuitry. diff -r 4d0b268480eb -r 9c2b0bd3083e ULA.txt --- a/ULA.txt Sun Feb 26 23:19:22 2012 +0100 +++ b/ULA.txt Sun Apr 28 23:01:53 2013 +0200 @@ -1,3 +1,24 @@ +Principal Design and Feature Constraints +---------------------------------------- + +The features of the ULA are limited by the amount of time and resources that +can be allocated to each activity necessary to support such features given the +fundamental obligations of the unit. Maintaining a screen display based on the +contents of RAM itself requires the ULA to have exclusive access to such +hardware resources for a significant period of time. Whilst other elements of +the ULA can in principle run in parallel with this activity, they cannot also +access the RAM. Consequently, other features that might use the RAM must +accept a reduced allocation of that resource in comparison to a hypothetical +architecture where concurrent RAM access is possible. + +Thus, the principal constraint for many features is bandwidth. The duration of +access to hardware resources is one aspect of this; the rate at which such +resources can be accessed is another. For example, the RAM is not fast enough +to support access more frequently than one byte per 2MHz cycle, and for screen +modes involving 80 bytes of screen data per scanline, there are no free cycles +for anything other than the production of pixel output during the active +scanline periods. + Timing ------ @@ -41,6 +62,11 @@ communicate the latter behaviour. In the TM4164EC4 datasheet, it appears that "page mode" provides the appropriate behaviour for that particular product. +See: Acorn Electron Advanced User Guide +See: Acorn Electron Service Manual + http://acorn.chriswhy.co.uk/docs/Acorn/Manuals/Acorn_ElectronSM.pdf +See: http://mdfs.net/Docs/Comp/Electron/Techinfo.htm + Video Timing ------------ @@ -105,8 +131,6 @@ with approximately 15 blank lines above and below the picture. Thus, the start of the picture could be chosen as 38 lines after the start of vsync. -See: Acorn Electron Advanced User Guide -See: http://mdfs.net/Docs/Comp/Electron/Techinfo.htm See: http://en.wikipedia.org/wiki/PAL See: http://en.wikipedia.org/wiki/Analog_television#Structure_of_a_video_signal See: The 625/50 PAL Video Signal and TV Compatible Graphics Modes @@ -115,10 +139,65 @@ http://www.retroleum.co.uk/electronics-articles/pal-tv-timing-and-voltages/ See: Line Standards http://www.pembers.freeserve.co.uk/World-TV-Standards/Line-Standards.html + +RAM Integrated Circuits +----------------------- + +The documentation for the Electron mentions 4164-15 RAM chips for IC4-7, and +the Samsung-produced KM4164 series is apparently equivalent to the Texas +Instruments 4164 chips presumably used in the Electron. + +The TM4164EC4 series combines 4 64K x 1b units into a single package and +appears similar to the TM4164EA4 featured on the Electron's circuit diagram +(in the Advanced User Guide but not the Service Manual), and it also has 22 +pins providing 3 additional inputs and 3 additional outputs over the 16 pins +of the individual 4164-15 modules, presumably allowing concurrent access to +the packaged memory units. + +As far as currently available replacements are concerned, the NTE4164 is a +potential candidate: according to the Vetco Electronics entry, it is +supposedly a replacement for the TMS4164-15 amongst many other parts. Similar +parts include the NTE2164 and the NTE6664, both of which appear to have +largely the same performance and connection characteristics. Meanwhile, the +NTE21256 appears to be a 16-pin replacement with four times the capacity that +maintains the single data input and output pins. Using the NTE21256 as a +replacement for all ICs combined would be difficult because of the single bit +output. + +Another device equivalent to the 4164-15 appears to be available under the +code 41662 from Jameco Electronics as the Siemens HYB 4164-2. The Jameco Web +site lists data sheets for other devices on the same page, but these are +different and actually appear to be provided under the 41574 product code (but +are listed under 41464-10) and appear to be replacements for the TM4164EC4: +the Samsung KM41464A-15 and NEC µPD41464 employ 18 pins, eliminating 4 pins by +employing 4 pins for both input and output. + See: TM4164EC4 65,536 by 4-Bit Dynamic RAM Module http://www.datasheetarchive.com/dl/Datasheets-112/DSAP0051030.pdf -See: Acorn Electron Service Manual - http://acorn.chriswhy.co.uk/docs/Acorn/Manuals/Acorn_ElectronSM.pdf +See: KM4164B 64K x 1 Bit Dynamic RAM with Page Mode + http://images.ihscontent.net/vipimages/VipMasterIC/IC/SAMS/SAMSD020/SAMSD020-45.pdf +See: NTE2164 Integrated Circuit 65,536 X 1 Bit Dynamic Random Access Memory + http://www.vetco.net/catalog/product_info.php?products_id=2806 +See: NTE4164 - IC-NMOS 64K DRAM 150NS + http://www.vetco.net/catalog/product_info.php?products_id=3680 +See: NTE21256 - IC-256K DRAM 150NS + http://www.vetco.net/catalog/product_info.php?products_id=2799 +See: NTE21256 262,144-Bit Dynamic Random Access Memory (DRAM) + http://www.nteinc.com/specs/21000to21999/pdf/nte21256.pdf +See: NTE6664 - IC-MOS 64K DRAM 150NS + http://www.vetco.net/catalog/product_info.php?products_id=5213 +See: NTE6664 Integrated Circuit 64K-Bit Dynamic RAM + http://www.nteinc.com/specs/6600to6699/pdf/nte6664.pdf +See: 4164-150: MAJOR BRANDS + http://www.jameco.com/webapp/wcs/stores/servlet/Product_10001_10001_41662_-1 +See: HYB 4164-1, HYB 4164-2, HYB 4164-3 65,536-Bit Dynamic Random Access Memory (RAM) + http://www.jameco.com/Jameco/Products/ProdDS/41662SIEMENS.pdf +See: KM41464A NMOS DRAM 64K x 4 Bit Dynamic RAM with Page Mode + http://www.jameco.com/Jameco/Products/ProdDS/41662SAM.pdf +See: NEC µ41464 65,536 x 4-Bit Dynamic NMOS RAM + http://www.jameco.com/Jameco/Products/ProdDS/41662NEC.pdf +See: 41464-10: MAJOR BRANDS + http://www.jameco.com/webapp/wcs/stores/servlet/Product_10001_10001_41574_-1 Interrupts ---------- @@ -200,8 +279,8 @@ trivial change). Another pitfall is the complication that might be introduced to software writing bitmaps of character height to the screen. -Region Blanking ---------------- +Enhancement: Region Blanking +---------------------------- The problem of permitting character-oriented blitting in programs whilst scrolling the screen by sub-character amounts could be mitigated by permitting @@ -238,8 +317,12 @@ Thus, in this case, region blanking would impose a 250 line display with the bottom 6 lines blank. -Screen Height Adjustment ------------------------- +See the description of the display suspend enhancement for a more efficient +way of blanking lines whilst allowing the CPU to perform useful work during +the blanking period. + +Enhancement: Screen Height Adjustment +------------------------------------- The height of the screen could be configurable in order to reduce screen memory consumption. This is not quite done in MODE 3 and 6 since the start of @@ -253,8 +336,16 @@ 320 1 240 40 640 &5A80 -> &5A00 320 2 240 80 1280 &3500 -Palette Definition ------------------- +Screen Mode Selection +--------------------- + +Bits 3, 4 and 5 of address &FE*7 control the selected screen mode. For a wider +range of modes, the other bits of &FE*7 (related to sound, cassette +input/output and the Caps Lock LED) would need to be reassigned and bit 0 +potentially being made available for use. + +Enhancement: Palette Definition +------------------------------- Since all memory accesses go via the ULA, an enhanced ULA could employ more specific addresses than &FE*X to perform enhanced functions. For example, the @@ -269,10 +360,92 @@ those outputs are strictly digital and can only be set to a "high" and "low" value, then only the existing eight colours are possible. If a modern ULA were able to output analogue values, it would still need to be assessed whether the -circuitry could successfully handle and propagate such values. +circuitry could successfully handle and propagate such values. Various sources +indicate that only "TTL levels" are supported by the RGB output circuit, and +since there are 74LS08 AND logic gates involved in the RGB component outputs +from the ULA, it is likely that the ULA is expected to provide only "high" or +"low" values. + +Short of adding extra outputs from the ULA (either additional red, green and +blue outputs or a combined intensity output), another approach might involve +some kind of modulation where an output value might be encoded in multiple +pulses at a higher frequency than the pixel frequency. However, this would +demand additional circuitry outside the ULA. + +Flashing Colours +---------------- + +According to the Advanced User Guide, "The cursor and flashing colours are +entirely generated in software: This means that all of the logical to physical +colour map must be changed to cause colours to flash." This appears to suggest +that the palette registers must be updated upon the flash counter - read and +written by OSBYTE &C1 (193) - reaching zero and that some way of changing the +colour pairs to be any combination of colours might be possible, instead of +having colour complements as pairs. + +It is conceivable that the interrupt code responsible does the simple thing +and merely inverts the current values for any logical colours (LC) for which +the associated physical colour (as supplied as the second parameter to the VDU +19 call) has the top bit of its four bit value set. These top bits are not +recorded in the palette registers but are presumably recorded separately and +used to build bitmaps as follows: -Palette Definition Lists ------------------------- + LC 2 colour 4 colour 16 colour 4-bit value for inversion + -- -------- -------- --------- ------------------------- + 0 00010001 00010001 00010001 1, 1, 1 + 1 01000100 00100010 00010001 4, 2, 1 + 2 01000100 00100010 4, 2 + 3 10001000 00100010 8, 2 + 4 00010001 1 + 5 00010001 1 + 6 00100010 2 + 7 00100010 2 + 8 01000100 4 + 9 01000100 4 + 10 10001000 8 + 11 10001000 8 + 12 01000100 4 + 13 01000100 4 + 14 10001000 8 + 15 10001000 8 + + Inversion value calculation: + + 2 colour formula: 1 << (colour * 2) + 4 colour formula: 1 << colour + 16 colour formula: 1 << ((colour & 2) + ((colour & 8) * 2)) + +For example, where logical colour 0 has been mapped to a physical colour in +the range 8 to 15, a bitmap of 00010001 would be chosen as its contribution to +the inversion operation. (The lower three bits of the physical colour would be +used to set the underlying colour information affected by the inversion +operation.) + +An operation in the interrupt code would then combine the bitmaps for all +logical colours in 2 and 4 colour modes, with the 16 colour bitmaps being +combined for groups of logical colours as follows: + + Logical colours + --------------- + 0, 2, 8, 10 + 4, 6, 12, 14 + 5, 7, 13, 15 + 1, 3, 9, 11 + +These combined bitmaps would be EORed with the existing palette register +values in order to perform the value inversion necessary to produce the +flashing effect. + +Thus, in the VDU 19 operation, the appropriate inversion value would be +calculated for the logical colour, and this value would then be combined with +other inversion values in a dedicated memory location corresponding to the +colour's group as indicated above. Meanwhile, the palette channel values would +be derived from the lower three bits of the specified physical colour and +combined with other palette data in dedicated memory locations corresponding +to the palette registers. + +Enhancement: Palette Definition Lists +------------------------------------- It can be useful to redefine the palette in order to change the colours available for a particular region of the screen, particularly in modes where @@ -290,8 +463,8 @@ at the appropriate time. Throughput/bandwidth considerations might impose restrictions on the practical length of such a list, however. -Palette-Free Modes ------------------- +Enhancement: Palette-Free Modes +------------------------------- Palette-free modes might be defined where bit values directly correspond to the red, green and blue channels, although this would mostly make sense only @@ -299,8 +472,8 @@ modes would require more memory than MODE 2 if they were to have an acceptable resolution. -Display Suspend ---------------- +Enhancement: Display Suspend +---------------------------- Especially when writing to the screen memory, it could be beneficial to be able to suspend the ULA's access to the memory, instead producing blank values @@ -313,8 +486,8 @@ that hardware to reduce the load on the system CPU which was responsible for producing the video output. -Hardware Sprites ----------------- +Enhancement: Hardware Sprites +----------------------------- An enhanced ULA might provide hardware sprites, but this would be done in an way that is incompatible with the standard ULA, since no &FE*X locations are @@ -336,8 +509,8 @@ bandwidth is not already fully utilised, this would result in a degradation of performance. -Additional Screen Mode Configurations -------------------------------------- +Enhancement: Additional Screen Mode Configurations +-------------------------------------------------- Alternative screen mode configurations could be supported. The ULA has to produce 640 pixel values across the screen, with pixel doubling or quadrupling @@ -355,7 +528,7 @@ columns is to be supported, compromises must be made such as the introduction of blank pixels either between characters (such as occurs between rows in MODE 3 and 6) or at the end of a scanline (such as occurs at the end of the frame -in MODE 3 and 6). Consider the following configuration: +in MODE 3 and 6). Consider the following configuration: Screen width Columns Scaling Depth Bytes Blank ------------ ------- ------- ----- ------ ----- @@ -366,8 +539,8 @@ generated either at the start or end (or split between the start and end) of each scanline. -Character Attributes --------------------- +Enhancement: Character Attributes +--------------------------------- The BBC Micro MODE 7 employs something resembling character attributes to support teletext displays, but depends on circuitry providing a character @@ -437,8 +610,8 @@ 208 26 x3 26 26 256 &62C0 -> &6200 208 26 x3 26 13 16 &6460 -> &6400 -MODE 7 Emulation using Character Attributes -------------------------------------------- +Enhancement: MODE 7 Emulation using Character Attributes +-------------------------------------------------------- If the scheme of applying attributes to character regions were employed to emulate MODE 7, in conjunction with the MODE 6 display technique, the @@ -454,8 +627,8 @@ at least make a limited 40-column multicolour mode available as a substitute for MODE 7. -Enhanced Graphics and Mode Layouts ----------------------------------- +Enhancement: High Resolution Graphics and Mode Layouts +------------------------------------------------------ Screen modes with different screen memory mappings, higher resolutions and larger colour depths might be possible, but this would in most cases involve @@ -467,11 +640,22 @@ especially since accessing regions of the screen would involve incrementing pointers by amounts that are inconvenient on an 8-bit CPU. -Enhanced Sound --------------- +Enhancement: Genlock Support +---------------------------- -The standard ULA reserves &FE*6 for sound generation and cassette -input/output, thus making it impossible to support multiple channels within +The ULA generates a video signal in conjunction with circuitry producing the +output features necessary for the correct display of the screen image. +However, it appears that the ULA drives the video synchronisation mechanism +instead of reacting to an existing signal. Genlock support might be possible +if the ULA were made to be responsive to such external signals, resetting its +address generators upon receiving synchronisation events. + +Enhancement: Improved Sound +--------------------------- + +The standard ULA reserves &FE*6 for sound generation and cassette input/output +(with bits 1 and 2 of &FE*7 being used to select either sound generation or +cassette I/O), thus making it impossible to support multiple channels within the given framework. The BBC Micro ULA employs &FE40-&FE4F for sound control, and an enhanced ULA could adopt this interface. @@ -481,14 +665,25 @@ See: http://en.wikipedia.org/wiki/Texas_Instruments_SN76489 -Waveform Upload ---------------- +Enhancement: Waveform Upload +---------------------------- As with a hardware sprite function, waveforms could be uploaded or referenced using locations as registers referencing memory regions. -BBC ULA Compatibility ---------------------- +Enhancement: Sound Input/Output +------------------------------- + +Since the ULA already controls audio input/output for cassette-based data, it +would have been interesting to entertain the idea of sampling and output of +sounds through the cassette interface. However, a significant amount of +circuitry is employed to process the input signal for use by the ULA and to +process the output signal for recording. + +See: http://bbc.nvg.org/doc/A%20Hardware%20Guide%20for%20the%20BBC%20Microcomputer/bbc_hw_03.htm#3.11 + +Enhancement: BBC ULA Compatibility +---------------------------------- Although some new ULA functions could be defined in a way that is also compatible with the BBC Micro, the BBC ULA is itself incompatible with the @@ -503,6 +698,27 @@ Electron) and other system-specific functions. Since the location usage is generally incompatible, this region could be reused for other purposes. +Enhancement: Increased RAM, ULA and CPU Performance +--------------------------------------------------- + +More modern implementations of the hardware might feature faster RAM coupled +with an increased ULA clock frequency in order to increase the bandwidth +available to the ULA and to the CPU in situations where the ULA is not needed +to perform work. A ULA employing a 32MHz clock would be able to complete the +retrieval of a byte from RAM in only 250ns and thus be able to enable the CPU +to access the RAM for the following 250ns even in display modes requiring the +retrieval of a byte for the display every 500ns. The CPU could, subject to +timing issues, run at 2MHz even in MODE 0, 1 and 2. + +A scheme such as that described above would have a similar effect to the +scheme employed in the BBC Micro, although the latter made use of RAM with a +wider bandwidth in order to complete memory transfers within 250ns and thus +permit the CPU to run continuously at 2MHz. + +Higher bandwidth could potentially be used to implement exotic features such +as RAM-resident hardware sprites or indeed any feature demanding RAM access +concurrent with the production of the display image. + ULA Pin Functions ----------------- @@ -576,3 +792,8 @@ CAS MO (motor relay output) ÷13 IN (~1200 baud clock input) + +References +---------- + +See: http://bbc.nvg.org/doc/A%20Hardware%20Guide%20for%20the%20BBC%20Microcomputer/bbc_hw.htm diff -r 4d0b268480eb -r 9c2b0bd3083e ula.py --- a/ula.py Sun Feb 26 23:19:22 2012 +0100 +++ b/ula.py Sun Apr 28 23:01:53 2013 +0200 @@ -82,10 +82,10 @@ """ A class representing the RAM circuits (IC4 to IC7). Each circuit - traditionally holds 64 kilobits, with two accesses required to read 2 bits - from each in order to obtain a whole byte. Here, we model the circuits with - a list of 65536 half-bytes with each bit representing a bit stored on a - separate IC. + traditionally holds 64 kilobits, with each access obtaining 1 bit from each + IC, and thus two accesses being required to obtain a whole byte. Here, we + model the circuits with a list of 65536 half-bytes with each bit in a + half-byte representing a bit stored on a separate IC. """ def __init__(self): @@ -98,12 +98,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. @@ -158,15 +164,22 @@ 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 # counter within each 2MHz period + 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.buffer = [BLANK]*8 # pixel buffer for decoded RAM data 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 + + self.cycle[7] = 1 # assert the final latch (asserting the first on update) self.reset_vertical() @@ -310,14 +323,25 @@ access_ram = not self.nmi and self.access == 0 and self.read_pixels() and not self.ssub + # Update the state of the device. + # NOTE: This is not meant to be "nice" Python, but instead models the + # NOTE: propagation of state through the latches. + + self.cycle[0], self.cycle[1], self.cycle[2], self.cycle[3], \ + self.cycle[4], self.cycle[5], self.cycle[6], self.cycle[7] = \ + self.cycle[7], self.cycle[0], self.cycle[1], self.cycle[2], \ + self.cycle[3], self.cycle[4], self.cycle[5], self.cycle[6] + # Set row address (for ULA access only). - if self.cycle == 0: + 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. @@ -329,62 +353,65 @@ # Latch row address, set column address (for ULA access only). - elif self.cycle == 1: + elif self.cycle[1]: + + # Select an address needed by the ULA or CPU. - # NOTE: Permit CPU access here. + 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: + 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: + 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: + 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: + 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: + 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 @@ -394,10 +421,12 @@ self.address += LINES_PER_ROW self.wrap_address() + else: + self.cpu_transfer_low() # Reset addresses. - elif self.cycle == 7: + elif self.cycle[7]: self.ram.column_deselect() self.ram.row_deselect() @@ -405,8 +434,6 @@ self.access = (self.access + 1) % self.access_frequency - self.cycle = (self.cycle + 1) % 8 - # Video signalling. @@ -479,6 +506,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): """