ZX81 ULA Replacement - Version 2.
By Andy Rea.
March 2011.
Disclaimer... this document may contain errors or ommissions and is used entirely at your (zx81's) risk
Way back in the early part of 2007 i created a ULA replacement using just 74XX logic IC's the details of which can be found at
http://homepage.ntlworld.com/deborah.cl ... A/ula.html
it used 22 IC's was power hungry and as much as i would have liked there was no way it was going to fit insdide the ZX81's case.
Fast forward nearly 4 years and the soldering iron is warmed up and ready to go with a smaller ULA replacment, but this time using programable logic chips, 5 off gal16v8 and 1 off gal20v8 and 1 off 74ls374, the basic principal is that no expensive equipment is needed, it's possible to build your own programmer for the 16v8 and 20v8 devices, you can find instructions on the internet, alternativly programmers can be bought for around £30 on eaby but i can't say anything about the quality.
-=-=-=-=-=-=-=-=-=-
Lets outline the project details.
The aim of this project is to create a ZX81 ULA equivalent using easily obtained (50p each [if you shop around]) chips, the only connections to the ZX81 that are allowed is the 40 pins of the original ULA socket. but before we begin lets have a re-cap of the function of each of the ULA pins.
Pin Function mode mode Function Pin
1-- A7' ---------- O ---- P --- +5V -- 40
2 --A8' ---------- O ---- O --- A6' -- 39
3 --A2' ---------- O ---- O --- A5' -- 38
4 --A1' ---------- IO --- O --- A4' -- 37
5 --A0' ---------- IO --- O --- A3' -- 36
6 --/RD --------- I ---- I --- OSC -- 35
7 --/IORQ ------- I ---- P --- GND -- 34
8 --/WR --------- I ---- I --- KBD0 -- 33
9 --/MREQ ------ I ---- IO -- D0 -- 32
10 --/M1 --------- I ---- I --- KBD1 -- 31
11 --A14 --------- I ---- IO -- D1 -- 30
12 --/RAMCS --- O ---- I --- KBD2 -- 29
13 --/ROMCS --- O ---- IO -- D2 -- 28
14 --/CLK ------- O ---- I --- KBD3 -- 27
15 --/NMI ------- O ---- IO -- D3 -- 26
16 --TV-TAPE --- O ---- I --- KBD4 -- 25
17 --/HALT ----- I ---- IO -- D4 -- 24
18 --A15 -------- I ---- IO -- D5 -- 23
19 --D7 --------- IO --- I --- UK/US-- 22
20 --TAPE IN --- I ---- IO -- D6 -- 21
(arrrghh trying to format on here is a night mare

)
O = output, I = inpout, IO = input and output
p = power connection.
in my design i use 5*gal 16v8 1*gal20v8 and 1*74ls374 a total of 7 IC's compared to 22 used in the original all 74xx design. however the logic follows reasonably closely to that of my original design.
Each of the programmable Gals has been given a name, this name is kind of related to it's function.
DECODE :- this chip uses, A0, /RD, /IORQ, /WR, /MREQ, A14, A1 as inputs from the ULA socket and does the memory decoding and the io decoding, including the 2 latches that control Vsync, and NMI pulse generation. it also has 2 inputs not from the ULA, these are a buffered 6.5Mhz clock, used to generate the 3.25Mhz clock that feeds to the CPU, and also /Hsync which is used in conjunction with NMI latch to produce the MNI pulses. it's outputs are 3.25Mhz clock, /NMI, /ROMCS, /RAMCS that are connected to pins on the ULA, it has other outputs used in other parts of the circuit, /FERD (used to trigger a read port $FE) and /Vsync used in tv signal generation.
NMI207 :- this chip is not connected to the ULA pins (apart from power) it is an 8 bit counter that runs off the 3.25Mhz clock, if left free running it will count from 1 to 207 incrementing on each clock cycle, when the output is at count 207 the next clock cycle will trigger it to roll round to a count of 1 missing out zero completely, this gives us a Hsync pulse of 16 cycles as on an original ULA not the 15 that other designs (including my old one) use. it has an additional input that will reset and hold the count at 1 for as long as this input is asserted.
LNC :- line counter, this is used to create the lowest 3 bits of the alternate memory address used during the refresh period in a video cycle, it's actually a state machine, but uses the /Vsync from DECODE along with Bits 7, 6, 4 from the NMI207 count, bits 6 and 7 are used to produce /Hsync and bit 4 is used to time the duration of a back porch region in the video output, it also genrates the /Csync used in the video output. it count output is Tri-stated so the address lines are only fed during the refresh time of a video cycle.
FERD :- a simple but essential part of the design, it has 2 uses first to read port $FE which simply copies the data present at it's inputs (KBD4 thru KBD0, uk/us bit and tape-in signal) and it also forces all the datalines low when a forced NOP is needed.
STATE :- named because when i first thought about the design this was going to be a state machine, however it turned into a counter with a load of combinatorial logic based on the counters output. The counter waits until M1 is asserted and begins to count, during the first memory read it checks whether this M1 cycle should be a video cycle by testing D6, A15 and /HALT if the condition is met a latch is set so that the rest of the video cycle can continue even thought the condition on D6, A15 may change, it then forces a NOP by asserting the FERD chip to do so and at the same time (nano seconds before the data lines are forced low) signals the 74ls374 to latch the current state of the data-bus, after the forced NOP the alternate address lines are enabled and just before the end of the refresh the databus is loaded into the shift register VSHF.
VSHF :- shift register, clocked at 6.5Mhz unless it has recently loaded a databyte it will continuosly output white (high level output) or during the Hsync and back porch region it will always output white, this avoids the display 'messing up' if video cycles are active during the back porch period although i only know of 1 program that does such. during load time the invert input is taken into consideration and if asserted the data bus is inverted before loading the shift register.
i'll include the WinCupl files for any one interested.
Regards Andy
what's that Smell.... smells like fresh flux and solder fumes...