Today's Board : A Z80 secondary CPU for RC2014

229 views
Skip to first unread message

Alan Cox

unread,
Sep 7, 2019, 7:02:20 PM9/7/19
to retro-comp
Well actually I've also been failing (still) to work out why the 65C02 and IDE hate each other. Even with RD/WR qualified by IORQ I get deep weirdness on the 65C02 CPU with it. I suspect something deeper is going on as with the WD 65C02 (which has different timings) I see different behaviour and the 512/512 RAM/ROM also doesn't like it.

The main bit of madness I'm now working on bringing up however is the bits to take RC2014 sort of multi-processor. It's a secondary Z80 CPU card where the idea is that the main CPU can control the reset, nmi and interrupt lines via a latch as well as write bytes to the secondary CPU. The secondary meanwhile can control itself via a latch and also talk back to the master. I need to do a bit of work on the IRQ the other way as the initial board boots with the interrupt held down which rather upsets the master.

The secondary runs off the same CPU clock as the master - that's deliberate as it means that the master Z80 can sync with the secondary and then I'm fairly sure ;) I can do an inir and otir with the right timing alignment on the two processors to do fast block transfers. We shall see once I've actually written some test firmware boot the secondary CPU and make it write test signals to the main CPU.

So far I've discovered I pulled up BUSACK not BUSRQ and got the IRQ logic backwards for the secondary to master. The latter I can just disable for the prototype the other I need to fix. I suspect there are more waiting to be found yet.

In CP/M days these boards usually had a bit of I/O decode on the secondary side which I don't. That usually also drove an SCC2691 which provided some control lines, serial ports and a timer. The card in turn ran CP/M (or CP/N) and talked directly over the bus to the master running MP/M and you just added CPU/memory cards to scale the processor power to the user count.

Alan

slave.pdf

Mark T

unread,
Sep 8, 2019, 2:24:25 AM9/8/19
to retro-comp
Interesting that you seem to be using the upper address lines to allow 16 bit output ports, but will that not cause a problem with otir and inir as the b register output to the upper address bits will be decremented on each output.

Mark

Alan Cox

unread,
Sep 8, 2019, 8:04:00 AM9/8/19
to retro-comp


On Sunday, 8 September 2019 07:24:25 UTC+1, Mark T wrote:
Interesting that you seem to be using the upper address lines to allow 16 bit output ports, but will that not cause a problem with otir and inir as the b register output to the upper address bits will be decremented on each output.

Mark


That is why I am using only A13-A15. That way you can do 32 bytes without reloading B. I do want to look further into that but it's already an oversize board. Supporting two addresses would allow it to run with non Z80/8088 style processor cards so you could for example run CP/M on the board on a future 68000 system. Without the clock sync you'd also need a FIFO to bridge the clock domains though - so it all gets a lot more complicated I fear.

Alan

Mark T

unread,
Sep 9, 2019, 5:35:23 PM9/9/19
to retro-comp
You could consider using 74HCT175 instead of 74HCT273, that would be a smaller package size and also includes inverted outputs which might be better to drive /int as the reset would clear them to high level.

Four bits is not quite enough to include the slave driving /int on the master. Maybe that could be driven from the /Halt output of the slave.

Still not sure if block transfer could be achieved without some kind of hardware handshake between the two, even driven from the same clock there would be some offset between the sender and receiver start of block.

Mark

Mark T

unread,
Sep 11, 2019, 1:06:31 PM9/11/19
to retro-comp
I was trying to see if it might be possible to reduce the chip count to make it fit on a standard RC2014 size. I don't think I've achieved that but thought some of the ideas I tried might be interesting.

Modified EPROM enable so that when the EPROM is enabled on reset only EPROM can be read, and RAM can only be written. It should be possible then to copy the entire EPROM to RAM, then disable EPROM and continue running from RAM. This then only uses half of the 74HCT139.

Second half of 74HCT139 is used to separate the IO address for data and control register.

Control register is changed to 74HCT175 as this is a smaller package and provides inverted outputs.

As with Alan's design, there is no IO address decoding on the slave side. In order to separate EPROM and RAM page control I'm using the refresh cycle to latch the I register from A8 to A11, but only when A7 the most significant bit of the refresh register is low. This allows the page control to be disabled if IM2 is being enabled and I register contains the interrupt vector table base address. Using 74HCT173 as this has two gate controls for the clock input. After the LD I,A instruction to set the memory page there should probably be a NOP instruction as the contents of the page register will not be set until the following instructions refresh cycle is performed.

Interface between the two data busses is via a single 74HCT245, with wait controlled by the 74LS156. This is intended to work by inserting wait states to either master or slave processor attempting IO read from the interface, until the other processor performs an IO write, then the 74HCT245 would be enabled and the wait released. Wait states are not applied to IO writes so the processor that is reading data has to be set up to read before the other processor can start writing. This is partly the limit of using the 74LS156, but also depends on Z80 IO timing due to the wait state automatically added to all IO operations.

I think using wait in this way with no latch for the data would still require both processors to run from the same clock source, although due to the Z80 added wait state it may be possible to use up to 2x clock difference.

Decoding for the slave processor reading from the interface is using /SIORQ low and /SWR high, so the slave processor will also wait for data to be written by the master during an interupt acknowledge. I thought maybe the slave could use IM2 and then the vector written by the master could be used to select the function to be performed by the slave.

I didn't include a way for the slave to generate an interrupt to the master cpu, maybe a schottky diode from the slave /HALT to the master /INT could be used.

None of this is tested, and I'm not sure if I might have missed some unintended consequences. I'll probably never try and complete the layout and build this thing.


RC2014_Pipe_v1.png



Mark
RC2014_Pipe_v1.pdf

Alan Cox

unread,
Sep 13, 2019, 3:48:27 PM9/13/19
to retro-comp
Interesting ideas.

I am fairly sure I can sync the two processors. With INI I can be up to 15 clocks out (probably 16 given the relative read and write timings on the latches). more for inir/otir

Something like

                 ld bc,#port
sync:         in a,(c)
                 jp p,sync
                 inir

and
                ld bc,#port
                out (c),a
                jp next
next:        otir

has a worst case variance under that so the sender can write 0x80, kill 10 clocks and begin doing an otir or other matched I/O pattern, so ought to work.

Alan

Bill Shen

unread,
Sep 19, 2019, 8:35:35 AM9/19/19
to retro-comp
I'll be away on a road trip, so I'm musing on two ideas about secondary Z80 processor for RC2014 to entertain myself.  It can be any other processors, but since I have Z80 around, I might as well use it.

* Z80-based logic analyzer.  SBC Z80 with CPLD front end interfacing to RC2014 bus to capture the bus transaction and write to on-board RAM, DMA fashion.  The CPLD will continuously capture the bus cycles until a trigger event, and then it'll capture few more Kbytes of transaction so memory contains pre-trigger and post-trigger data.  Z80 has multi-cycle bus, so the logic analyzer should be able to run at full speed.  On board Z80 shares the same RAM with CPLD.  Z80 bus mastership is taken away until there is a trigger event.  Z80 then reads the captured memory and reformat it to display serially on workstation console.  It is conceivable that the Z80 needs no ROM because its RAM can be initially filled with software using the same DMA mechanism...somehow...give me a flexible logic analyzer, if I can figure out how to do that.  Thinking of using Z84C1516 for this, may be the size of a standard 50mmX100mm RC2014 board

* Z80-based video display.  Another SBC Z80 with a dual-port RAM between RC2014 and a secondary Z80.  On the RC2014 side, it appears as I/O registers; on the Z80 side it is mapped starting from 0x0, so Z80 can boot from the dual port RAM.  This way the video display software can be loaded into dual-port RAM first and then the video data itself--make it a more flexible display processor.  Should be the size of the standard RC2014 board.
  Bill

Alan Cox

unread,
Sep 19, 2019, 9:36:02 AM9/19/19
to retro-comp

> * Z80-based video display.  Another SBC Z80 with a dual-port RAM between RC2014 and a secondary Z80.  On the RC2014 side, it appears as I/O registers; on the Z80 side it is mapped starting from 0x0, so Z80 can boot from the dual port RAM.  This way the video display software can be loaded into dual-port RAM first and then the video data itself--make it a more flexible display processor.  Should be the size of the standard RC2014 board.

Interesting approach to booting it.

There were a few boards of this nature in the S100 era where you wrote commands to a second processor that then did the graphics work (line drawing, fill etc) for you. It doesn't work very well for games unless you have off screen memory on the coprocessor that you can block copy - but for a while it was popular for what was once high end business graphics.

If you are trying to be minimal you might want to look at how the ZX81 did the video generation. In their case to reduce RAM usage it was with the added complexity of being character based but basically the CPU instruction fetch was borrowed for the video. The CPU set itself up and the supporting logic then pulled the CPU side of the data bus down to zero whilst a scan line ran, then the CPU used the hblank either to halt or set up again, and the cycle continued to the end of the visible frame. The frame buffer looked like [video stream][code][video stream][code]...

You can do 512x192 composite quite reasonably that way even with 150ns RAM (the ZX81 is 256x192 but half of the work is taking the byte from the RAM and using it to look up the font)

I did look at putting a design based upon the Jupiter Ace video onto an RC2014 card but when I got to 16 IC's I decided it was maybe something to try in the distant future 8)


Other use for a secondary CPU is sound of course - like the General Sound board for the ZX spectrum compatibles or the modern rather extreme NeoGS.

General sound was a 12MHz Z80 with 4 DACs, volume controls 128K RAM and a 37kHz interrupt signal that used the Z80 to play audio - usually running a mod tracker.


Alan

Bill Shen

unread,
Sep 19, 2019, 10:34:25 AM9/19/19
to retro-comp
Memory is so cheap, the video processor will have its own memory, possibly even banked. The board is basically z80, RAM, dual ported RAM, CPLD, connectors for video and keyboard. Z80 is running at 22MHz, i have good experience with overclock z80 to 24Mhz and beyond that I might be tempted to run the whole thing at 25.175mhz, the VGA dot clock.

Once a framework is setup for dual ported RAM & programmable co-processor and keep it all on a single board, it can be used for sound, motor control, vision, GPS, etc

Bill

Greg Holdren

unread,
Sep 19, 2019, 11:45:18 AM9/19/19
to retro-comp
Bill,

I have some 4KB dual port ram if you need some for the project.

Greg

Colin MacArthur

unread,
Sep 19, 2019, 2:10:32 PM9/19/19
to retro-comp
Have you thought about using a IDT7007 32k x 8 or IDT7008 64k x 8 Dual-Port Static RAM (Mouser has them in stock).
This would allow both CPUs simultaneous access to half or all the ram.
The high address line could be inverted on CPU 2 so each CPU would have its own 0000h space to prevent interrupt issues.
IE
address 0000h for CPU 1 would be 8000h for CPU 2 ... ( one would have to watch the stack location for each CPU)
This would be the ultimate in "Self Modifying Code" and allow commands from CPU 1 to CPU 2 to be sent via NMI...
IE CPU 1 would write to it location 8066h (CPU 2 0066h) and sent a NMI to CPU 2.

CM

Alan Cox

unread,
Sep 20, 2019, 8:26:39 AM9/20/19
to retro-comp
Except in FPGA dual port RAM does seem remarkably expensive. It makes stuff easier (at least it did when I did the socz80 video) but I'm not sure I want to be paying $40 for a 32K memory chip. That's a bit too 1980s 8)

Real high end music sound also needs a surprising amount of CPU. The general sound is running a Z80 at 12MHz with hand optimized player code and a carefully chosen 37.5KHz interrupt and it's not got many free CPU cycles.

It does look like the somewhat cheaper FIFO chips would work for a lot of the graphics though because you can then have the main processor just spew drawing commands into the FIFO and let the secondary CPU just keep eating commands from the FIFO whenever it can.

Now I need to resist designing myself a soundblaster-ish board using Marten's Z80DMA card already in my big machine, a FIFO and a DAC 8)

Alan

Bill Shen

unread,
Sep 24, 2019, 8:16:24 AM9/24/19
to retro-comp
I won't pay $40 for dual port RAM, not even $10.  The dual port I have in mind is 2Kx8 (such as CY7C146).  They are about $3.50 each in quantity of 10.
  Bill
Reply all
Reply to author
Forward
0 new messages