• Please review our updated Terms and Rules here

What I did on my COVID vacation

jlang

Experienced Member
Joined
Sep 25, 2014
Messages
229
Location
central florida
Well I was fine till the rum ran out...

I revived a project I started years ago. A Z80 single board computer.

With all the SBC projects out there why do my own?
It's partly a case of "not invented here" but also none of the projects
have a feature I wanted. I wanted a SCSI interface. I know lots of people hate
SCSI. "It's complicated and unreliable". Well I'll admit SCSI-3 is pretty
complicated but I'm doing CP/M... Single host, multiple targets, no arbitration.
I need 2 commands. read(6) and write(6). It's pretty simple to implement
and reliable. I like SCSI.

My project is on github https://www.github.com/joelang/z80-sbc
it includes rom monitor, boot loader cpm2.2 (ccp and cdos) and cbios.
The KiCad design files are also included.

I'm working on getting ZCPR running since DRI's implementation of SUBMIT
and USER AREA's is deeply flawed. DRI doesn't like system on C: much either.

Let me know what you think

joe lang
 

Attachments

  • IMG_0465.JPG
    IMG_0465.JPG
    100.2 KB · Views: 1
Has Covid ended for you? Lucky dog.

And who hates SCSI? I dont know anyone who HATES the interface. Its friggen amazing..
 
Has Covid ended for you? Lucky dog.

And who hates SCSI? I dont know anyone who HATES the interface. Its friggen amazing..

I sure don't ! and I thank you for the support!
I've seen a lot of unsupport over the years!

Oh no COVID hasn't ended.... In just refuse to accept the new normal.
but I do wear a mask.

joe
 
I sure don't ! and I thank you for the support!
I've seen a lot of unsupport over the years!

Oh no COVID hasn't ended.... In just refuse to accept the new normal.
but I do wear a mask.

joe

unfortunately this will change society and for the worse when its all over. The downtrend of antisocialness will only be heightened to stupid levels of absurdity now.
 
I'm curious if you can go in to your SCSI implementation, and how it works.

I'm keen on looking for a "simple" parallel interface to connect a host CPU (i.e. a Z80, but not necessarily specifically a Z80) to another Smart Controller.

In my use case, this other device would be a something like a Raspberry Pi. The premise is to offload I/O from the main processor to the Smart Controller.

Almost all of the modern connectivity to I/O, outside of a UART, is being done serially today (SPI, I2C, etc.). While these can readily be bit banged on a small processor, it's expensive.

Single bit serial I/O on a slow processor is, well, even slower -- 8 times (at least) slower. A 4Mhz Z80 be lucky to get 100KBps out of a bit banged SPI.

If I need to interface the CPU to something like a SPI accelerator (i.e. some kind of 8 bit parallel interface to something that can talk SPI at much higher speeds, something I can't find, mind), and THEN connect that to, say, a USB controller, or network interface, well, the chip count goes up.

However, if I can talk parallel to something like a Raspberry Pi, or some other micro controller, with appropriate software loaded of course, well I get a boat load of "fast" I/O with a $5 part.

The question is how to interface to the RPi.

I've considered SCSI, in that I've glanced at it. I've looked at GPIB. I'm leaning towards IEEE 1284.4 (which is a kind of socket protocol), which runs over an "Enhanced Parallel Port".

I don't actually need to be signal compliant with an EPP to do the interface. The RPi only has so many GPIO lines, but I think I can cram enough of the signals out of a 2 byte I/O port to make it work.

But I am curious about how you went about your SCSI interface.
 
There's a limited SASI (forerunner of SCSI) interface on the Philips P2000C and from the schematics it looks to be implemented in standard 7400 series logic chips - no 40 pin LSI chip present. I managed to get a SD2SCSI card working with it.

I think you can never have too many Z80 SBCs. Having one with a SCSI interface is to my mind novel and interesting.

Regarding having CP/M system on C:, I'm not sure what you mean, as it always boots from whatever device you set up in the BIOS (cold / warm). Yes, the BDOS attempts to log in A: at start up if you don't alter it, but I've done this with my Superbrain uIDE CP/M and it works fine. So, it boots off the IDE device's track zero, and the prompt shows C:> immediately. (On my system I have A: and B: as floppies, then all subsequent logical drives as IDE partitions.)
 
I'm curious if you can go in to your SCSI implementation, and how it works.

I'm keen on looking for a "simple" parallel interface to connect a host CPU (i.e. a Z80, but not necessarily specifically a Z80) to another Smart Controller.

In my use case, this other device would be a something like a Raspberry Pi. The premise is to offload I/O from the main processor to the Smart Controller.

Almost all of the modern connectivity to I/O, outside of a UART, is being done serially today (SPI, I2C, etc.). While these can readily be bit banged on a small processor, it's expensive.

Single bit serial I/O on a slow processor is, well, even slower -- 8 times (at least) slower. A 4Mhz Z80 be lucky to get 100KBps out of a bit banged SPI.

If I need to interface the CPU to something like a SPI accelerator (i.e. some kind of 8 bit parallel interface to something that can talk SPI at much higher speeds, something I can't find, mind), and THEN connect that to, say, a USB controller, or network interface, well, the chip count goes up.

However, if I can talk parallel to something like a Raspberry Pi, or some other micro controller, with appropriate software loaded of course, well I get a boat load of "fast" I/O with a $5 part.

The question is how to interface to the RPi.

I've considered SCSI, in that I've glanced at it. I've looked at GPIB. I'm leaning towards IEEE 1284.4 (which is a kind of socket protocol), which runs over an "Enhanced Parallel Port".

I don't actually need to be signal compliant with an EPP to do the interface. The RPi only has so many GPIO lines, but I think I can cram enough of the signals out of a 2 byte I/O port to make it work.

But I am curious about how you went about your SCSI interface.

For a Z80 under CP/M I can't see how you could benefit from an I/O processor, as CP/M does not use interrupts as such. It spends most of its time waiting for user input. Even if you implemented DMA it would still wait. But if you want to interface to the Pi I'd implement a buffered bidirectional parallel interface using the Pi's GPIO pins. Buffered I/O is the norm (although my own IDE and RTC interfaces aren't buffered, I'm ashamed to say). I think you just need an 8 bit latch each way between the Z80 data bus and GPIO, with voltage level translation. Plus some address decoding logic to trigger the latch on reads and writes. You can connect multiple sets of latches that get enabled on different I/O addresses.

Me not being an expert though, I'd wait for wiser folk to comment!
 
Almost all of the modern connectivity to I/O, outside of a UART, is being done serially today (SPI, I2C, etc.). While these can readily be bit banged on a small processor, it's expensive.

Single bit serial I/O on a slow processor is, well, even slower -- 8 times (at least) slower. A 4Mhz Z80 be lucky to get 100KBps out of a bit banged SPI.

If I need to interface the CPU to something like a SPI accelerator (i.e. some kind of 8 bit parallel interface to something that can talk SPI at much higher speeds, something I can't find, mind), and THEN connect that to, say, a USB controller, or network interface, well, the chip count goes up.
I keep thinking about doing a parallel-to-SPI interface in a CPLD for this purpose. Have you considered something like this already? If the voltage levels are compatible then it doesn't appear to be too difficult. As far as the logic, a brief search turned up this: https://www.digikey.com/eewiki/pages/viewpage.action?pageId=4096096
 
There is a TTL chip which has a bidrectional 8 bit register/latch and buffer: the 74HC646 and there seems to be a 74LVC646A which is 5 Volt tolerant on a 3.3 Volt supply.

I used the HC variety to connect an 8048 to an (emulated) Z80 (Philips Videopac+ Basic module emulator)
It is basically two HC245 and two HC374 in a single package.
Handshaking was done by a pair of flipflops (set by writing to the register from one side and reset by the reading of the other side)
On the Z80 side the writing from the 8048 also triggered an interrupt.
 
bakemono: There are several HDL SPI controllers available but most of them are quite generalized which takes extra CPLD / FPGA space and adds complication. A more dedicated SPI controller will fit in a small CPLD and is pretty straightforward.

whartung: Perhaps I need more coffee but I think I'm missing something here. Unless you're talking about adding fast I/O to an existing slow Z80 system (i.e. 4MHz) then I think you should be considering the overall architecture, what devices you're trying to connect to and your fundamental objectives. While adding a $35-$75 Pi as an I/O processor to a cheap 4MHz Z80 would work, does it really improve the overall performance metric you're looking for or just add cost and complication? Others have already implemented Arduinos as Z80 I/O processors and they're less expensive than PI's.

CPU performance and I/O throughput are two possible metrics and obviously a 4MHz CPU with a bit-banged interface isn't going to do well at either. Raw Z80 CPU performance on current Zilog silicon can be significantly increased by going to a 20MHz Z80, a 33MHz Z180 or a 50MHz eZ80.

I/O throughput is going to be CPU speed and I/O device dependant unless you go to DMA in which case the DMA controller and/or memory speed can also introduce bottlenecks. The actual I/O device(s) will determine the required interface whether it be I2C (very slow at 100 or 400KHz / 8 + overhead), SPI, QSPI, SD, ATA, SCSI, SATA etc.

I've built most of these permutations and found the simplest combination with good "disk" performance to be the Z180 at 33MHz with a SPI and/or ATA I/O controller inside a CPLD which can also include a high-speed DMA controller. Although it's possible to to use this combination for ATA with UDMA 7 at 167 MB/Sec, I've been finding that my 25MHz SPI/uSD interface (~3MB/Sec) is both compact and plenty fast for working with CP/M. Driver software which requires blocking / deblocking can also have quite a performance impact and can use various schemes such as deferred writes, buffer pools etc. to improve performance.
 
"I'm curious if you can go in to your SCSI implementation, and how it works."

It works really well... Oh you want more details than that? OK.

The hardware is based in the Z53C8003VSG SCSI interface IC. It's a direct
decendant of the NCR5380. It includes open drain buffers to directly
drive the SCSI bus, handshake logic and latches for data and status.
It provides everything needed to interface to the SCSI bus.
The best part is it's still a current part. I bought some a few months back
from Mouser.

The software is best understood looking at the CBOOT file. It's the second
stage loader brought into memory by the ROM.
It implements the SCSI protocol but without the CP/M stuff that the CBIOS
needs.

CBOOT reads 13 blocks starting at LBN 1 into memory and jumps to COLD start.

The SCSI code starts at s_go: The process starts by selecting the target
device. It will time out if busy takes too long (non existing target)
After busy sets, the protocol is controlled by the target.
The common mistake I see in SCSI drivers is assuming the phase order and/or
counting bytes. Don't do that. Trust the target!

The target will set the I/O C/D MSG status lines to what it is asking for
then set REQ (request). The host decodes the lines and provides/accepts
the requested data. (ACK)

The SCSI chip has logic to detect "phase change" so phase decoding isn't needed
for every byte. look at s_read and s_writ. As long as the phase has not
changed they will continue to loop. busy loss or phase change will exit
the loop.
The code in CBIOS is identical. I have added an extra CBIOS entry point
(CBIOS+0x33) This allows programs to do SCSI IO directly.
it's useful for things like format or tape backup or accessing custom
hardware. (not that I have done any of that)

Build a IO table
Build a command block
point IX to IO table
call CBIOS+033

Bingo you are doing SCSI!

joe
 
For a Z80 under CP/M I can't see how you could benefit from an I/O processor, as CP/M does not use interrupts as such. It spends most of its time waiting for user input. Even if you implemented DMA it would still wait. But if you want to interface to the Pi I'd implement a buffered bidirectional parallel interface using the Pi's GPIO pins. Buffered I/O is the norm (although my own IDE and RTC interfaces aren't buffered, I'm ashamed to say). I think you just need an 8 bit latch each way between the Z80 data bus and GPIO, with voltage level translation. Plus some address decoding logic to trigger the latch on reads and writes. You can connect multiple sets of latches that get enabled on different I/O addresses.

Me not being an expert though, I'd wait for wiser folk to comment!

In (single user) CP/M, nothing else needs to happen once a request for I/O is started. So system speed depends on how fast you can complete the I/O. Interrupts only slow things down, although not always by much. Modern solid-state media, though, can go much faster. DMA is useful because a DMA controller can transfer data from the device much faster than the CPU can. A decent DMA controller can move the data at 3-4 cycles per byte. The best the Z80 can do is 21-22 cycles per byte.

I'll also throw support towards a CPLD (or equivalent hardware) to do the SPI at CPU clock speed. I abhor bit-banging in software, for all the standard reasons. Including the fact that you probably can't get a (standard) DMA controller to bit-bang. Although, the SPI controller probably can't keep up with a DMA controller, so you've got some flow control to do.
 
There's a limited SASI (forerunner of SCSI) interface on the Philips P2000C and from the schematics it looks to be implemented in standard 7400 series logic chips - no 40 pin LSI chip present. I managed to get a SD2SCSI card working with it.

I think you can never have too many Z80 SBCs. Having one with a SCSI interface is to my mind novel and interesting.

Regarding having CP/M system on C:, I'm not sure what you mean, as it always boots from whatever device you set up in the BIOS (cold / warm). Yes, the BDOS attempts to log in A: at start up if you don't alter it, but I've done this with my Superbrain uIDE CP/M and it works fine. So, it boots off the IDE device's track zero, and the prompt shows C:> immediately. (On my system I have A: and B: as floppies, then all subsequent logical drives as IDE partitions.)

Yes I don't have the A: connected all the time, so I had to patch CDOS to reset to C: not A:
Don't get me started on USER areas....
joe
 
Unless you're talking about adding fast I/O to an existing slow Z80 system (i.e. 4MHz) then I think you should be considering the overall architecture, what devices you're trying to connect to and your fundamental objectives.

I've gone in circles about this in my head for some time.

First assumptions: I am not a hardware guy. I'm a software guy. I struggle to get a header placed in things like KiCad.

Now I'll go through my base thought processes.

Where this reared its head first was when I discovered the CH376 chip, which is a nice little chip that will let you talk to DOS file systems on USB mass storage.

It is imperfect, but this chip "solves" a bunch of issues for a simple CPU in todays world. Simple mass storage, "Free" file system, "standard" file system, etc. It's also a USB host to which you can connect, well, "everything". But, it's SPI.

The idea of bit banging SPI on a 4MHz Z80 or a 2MHz 6502 for I/O is just, well, painful. It's effective, it'll work, and having used things like Ataris with the 19.2K serial busses in the past, it's "usable". It's simply not desirable.

So, now if you want to get some more performance, you need a glue chip to let the SPI run "very fast" in order to make data available to the CPU in 8-Bit chunks and closer to bus speed. Naively, such a chip gives you "8x" performance for the I/O. That's a nice benefit.

But, now, we have this extra chip (or logic). I'm sure there are folks here or around that can scribe something like this on a napkin. I can't. I can't even spell CPLD. (Software guy).

What this told me was if I needed an "I/O" chip to actually access the REAL "I/O", then, why not think a little bit bigger.

Next up, there's the "cost" situation. I'm not scraping pennies, but I'm as cost sensitive as the next guy. But I'm also "value oriented".

I remember seeing someone talking about hex digit display driver chips, something like that. And the chips for that cost, like, $7 or $10 or somesuch thing. To render a hex digit in LEDs (and it didn't even include the LED!).

Meanwhile, in the other hand, you can get a Pi Zero of $5-10. Soooo....for $10 I can get a hex digit driver chip, or I can get a USB/Serial/Video/Wifi/Keyboard driver "chip". THAT, my friend, is "value".

That's more value than the CH376.

So, the next trick is how to drive the Pi.

I can't mate it to the bus (somebody may be able to, I can't). I don't need DMA, the Pi doesn't have the pins for it anyway. What I need is "8 Bit SPI" essentially. FT1248 (by the FTDI folks) is essentially this, I haven't looked at it in enough detail.

But what I also want is I want the Pi to be able to interrupt the host when pushing data back. I don't want it to be a pure slave that's polled. The host will "drive" the conversation, i.e. the host will drive the master SPI clock, but the Pi should be able to let the host know that data is ready to be loaded.

The beauty of something SPIish is that it's robust in timing because of the handshaking. As I understand it, the Pi is not a particularly good citizen for "real time". It likes to go off on pauses and such on a whim, so I'm told, so having a handshake driven protocol lets the Pi head out to lunch and not break anything at the wrong time.

I feel that when the host sets up two "async" channels, one reading a file, the other downloading the home page from Yahoo, and "simultaneously" having 2 blocks of data delivered, one from each, then the project is successful.

So thus my curiosity in 8 Bit busses and protocols. Pretty sure this problem has been thought about before by folks smarter than me.

SCSI is one of those solutions. EPP, Enhanced Parallel Port (IEEE-1248), is another. IEEE-488 GPIB is another. FT1248 (what a coincedental number...) is obviously a modern and up to date protocol. I don't need several devices, don't need to daisy chain them, I just need the one, so that simplifies things. I'm not going to have 12 foot cables, so I don't have any real electrical considerations to worry about.

The IEEE-1248.4 is a wire protocol with channels and such to handle multiple data streams over the connection.

The dark side, of course, is that the Pi is a behemoth (this is good and bad). Out of the box have to boot up a linux kernel, etc. etc. just to bring the device on line. But short term, bang for the buck, it can work out. I figure the Pi side can be written, naively in, well, anything. C, Python, whatever. The Pi has the performance to be "faster than the host" even with sloppy code, which is great for prototyping. Long term someone could just make it bare metal, skipping Linux entirely.

I have not looked at other controllers (like the Arduino you mentioned). The Pi is as much exemplar than necessarily normative.

But in the end, you get a CPU (Z80, 6502, 65816, etc.) that connects to an I/O processor, with, ideally, little more than 2 8 bit ports (and perhaps some level shifters) which opens up the world of modern peripherals: USB storage, networking, printers, etc. Which, arguably, is what the SCSI chip did back in the day. SCSI disk drive, SCSI scanners, SCSI plotters, SCSI network interfaces.

So, that's where my head is at. And why I'm curious how other people address it.
 
Although my background is also in software (mostly assembler), I've been doing more and more hardware since that is what allows me to create a truly unique system with the features I want. Most of my recent activities have been based around the Z80 and derivatives. I've wandered through the development path of various I/O peripherals such as ATA, SD, USB, I2C, SPI, serial flash arrays, etc. In the end, it always comes back to architecture and objectives.

With a CP/M-based Z80 there's a need for a console, "disk" storage and application I/O devices such as graphics, sound, ethernet etc. Although ultimate performance / throughput is a fun endeavour, once a basic level has been achieved it really doesn't become a factor until moving up to MP/M with it's multi-tasking and possibly multiple users.

A basic console is simplest to create via serial I/O which offloads the processor from things like scrolling and display timings. There are dedicated terminals or one can simply use a terminal emulator connected via RS-232 or serial-USB. Although 115200 baud can scroll a full 24x80 screen in about 1/5 of a second, if that's not fast enough you can move up to a parallel USB connection.

The "disk" requirements depend upon overall objectives and can range from diskless (i.e. all code in ROM) through to huge amounts for data logging applications. The various alternatives have physical size, power, speed and cost factors. The fastest and most compact is likely parallel MRAM with the slowest being a genuine IBM 33FD floppy. Having done both these extremes and many in between, my preference is for uSD cards ... compact, cheap, large capacity and relatively fast with a CPLD-based SPI controller. I can barely read the file names when doing a full disk copy via PIP *.*.

Like any well-planned project, I recommend starting with the basics of objectives and requirements. Since you don't appear to be wanting to design hardware-based solutions that leaves easily connected common solutions which will have their own interface requirements such as parallel, I2C, SPI, etc. Something like the Pi with it's built in I/O support or an Arduino with it's plethora of shields is an alternative. You can also look at all the various I/O boards offered by Sparkfun or Adafruit that typically are connected via I2C or SPI.

One multi-processor alternative that hasn't been discussed is dual-ported SRAM. Using that will allow the host processor (i.e. Z80) and the I/O processor to each operate at their maximum speeds with the only handshaking required being a basic command structure and some way to notify of request / completion (i.e. interrupt) and status. Think of this in terms of a simple memory-based ATA interface.

P.S. Even though TIL311 hex LEDs are relatively expensive, I still like them for extremely simple SW & HW interfacing and debugging ... just connect them to the bus, add a chip select signal and software OUTput instructions. I looked at building my own alternative with a PIC and realized it wasn't worth my time and effort.
 
For a Z80 under CP/M I can't see how you could benefit from an I/O processor

There are a couple of reasons for an I/O processor:

Device abstraction- CP/M doesn't need to know the details about how to control a device it only sees the abstract interface. (SCSI in this case)
This allows a higher level interface. It's simpler to code.

CBIOS code size- The same block of code can be used for more than one type of device. Floppy and hard disk look the same and use the same
small block of code. In my CBIOS the SCSI code is only about 260 bytes.

I'm not just offloading I/O processing. I'm offloading code space.

joe
 
Back
Top