This is a new hardware project that provides several enhancements to the operation of a real ZX81.
It is based on an original project of mine circa 1985 in which I build a user defined video character pattern generator that plugged directly into the ZX81 edge connector. That project required 6 chips including a 2K RAM chip. The whole system was completely transparent and compatible with the ZX81 video circuit. In addition to the normal ZX81 non-inverted video pattern for each character, the circuit generated additional tables of video patterns for the inverted characters (CHR$+128). These were stored in 2K non-volatile RAM which the user had to load from tape. A pushbutton was used to select one of 4 additional tables of 64 lowercase characters, combined with special symbols or game characters that could be shown simultaneously with the original ZX characters on the screen. The additional video pattern tables were mapped over the orginal 1E00 to 1FFF memory space and no additional software was required, as the fonts were manually selected. The system was totally compatible with any other ZX81 software and hardware. The default font on power up was lower case, which used for program listings, looked kind of odd but blew everyone away.
Two decades later, CHR$16 was designed with just 3 chips by using an 8K EPROM to store the video patterns and by making the fonts selectable in software. Just a few pokes are needed to select one of 16 complete sets of 64 characters including the original ZX81 set of 64 normal and inverted characters. This circuit adds 14 new sets of pattern tables of your choice organized as 7 sets of 128 unique characters patterns. Always so much simpler in hindsight.
SO HOW DOES IT WORK?
The CHR$ circuit operation is quite straightforward and is similar to the way the ULA and ROM are used.
The normal ZX81 video is generated as follows:
As the ZX81 generates a live video screen, the Display File at (400C) is scanned by sequentially loading each valid character code in a 6 bit register on the ULA. This is followed by the ULA pulling the data bus low to simulate a NOP which the Z80 loads and executes. During the refresh time of each NOP, the Z80 I register generates the address pointer to the pattern table which is combined with the 6 bit character code and a 3 bit line counter in the ULA to select one byte from the ROM to be loaded into the video shift register. The D7 bit is also loaded into the ULA invert register and inverts the signal shifted from the output of the video shift register at 6.5M bits per second.
The CHR$X16 circuit works as follows:
As the ZX81 generates a live video screen, the Display File at (400C) is scanned by sequentially loading each valid character code in the 8 bit 74HC374 register of the new circuit on the rising edge of each RD. This is followed by the ULA pulling the data bus low to simulate a NOP which the Z80 loads and executes. During the refresh time of each NOP, the Z80 I register generates the address pointer to the pattern table which is combined with the 7 bit character code and the 3 bit line counter of the circuit (74HC192) to select one byte from the new EPROM patterns to be loaded into the video shift register. The D7 bit is also loaded into the ULA invert register and inverts the signal shifted from the output of the video shift register at 6.5M bits per second.
The 27C64 EPROM is mapped over the entire 8K ROM area. This is ok since the EPROM only responds to /RFSH low, while the internal ROM only responds an active low /RD line.
In order, to select a given pattern table the Z80 Interrupt register must be loaded with the upper 8 bits of the starting address of one of eight pattern tables. This requires setting up a 1 REM line with 5 spaces and few pokes to load the 5 byte ML program.
LD A , n
LD I , A
which is then executed with RAND USR 16514 to select the table. Afterwards a single poke of 16515, n x 4 +224, (where table n=0 to 7) and the RAND USER 16514 is all that is needed to change tables on the fly.
Although each table has 128 characters and not the ideal 256, a special table for pseudo hires programs can be added with significant improvement of “resolution” and uniform code to pattern conversions.
Each table is 1024 bytes with the second 512 block selected by D7 of the CHR$ code. This requires that the second half of each table uses complemented data as this will in turn be complemented by the ULA at the video shift register output.
The ZX81 default table will start at address 1C00 and end at 1FFFF. The ZX81 printer will continue to use the normal ROM patterns which is no compromise as other patterns, fonts and hires graphics have always been available for the ZX printer.
THE CHR$ REGISTER
The 74HC374 octal clocked register is used to capture the CHR$ codes from DFILE to be used as part of the pattern lookup address. Unlike the ZX81, this register also captures D7 and as part of the address which doubles the size of each pattern table. The register is loaded on the rising edge of RD and the tristate output is permanently enabled.
THE LINE COUNTER
The 74HC192 is a pre-settable 4 bit counter of which 3 bits are used to select which 1 of 8 lines of patterns is accessed. Each of the 24 rows of characters is made up of 8 lines of 24 pattern bytes. The counter is pre-set to all ones with the NMI line on the PE pin. The NMI generator is turned off at the start of the screen display. Since the first line of the screen display consists of just a N/L (HALT opcode), this causes the counter to increment to zero which is the starting line for the first character row. The subsequent N/L characters at the end of each line, each cause a HALT, each of which clocks the counter to generate the 3 low order pattern table address bits.
THE ADDRESS DECODER
The high order address decoder uses 3 diodes and a resistor to generate a low chip enable for the EPROM CE pin when A13-15 are low. A low level on the RFSH line enables the EPROM data outputs to be loaded into the video shift register.
THE ROMCS DECODER
The ROM must be disabled when the EPROM is active so an emitter follower is used to force the ROMCS line high when the RD line is high, which occurs when the RFSH line is low.
Any general purpose NPN transistor can be used for this application which minimizes the loading of the RD line.
The circuit is assembled on a perforated board with a feed through female and male connector and is attached inline with the ZX81 PCB edge connector.
The ROM patterns are readily available from HIRES programs and from font tables used for the ZX printer. I will combine the best into one EPROM image and the file will be shortly added to this article. Pre-programmed EPROMs will be available to anyone who would like to build this for the price of posting it.