Yet Another RC2014 XR88C681 Board

459 views
Skip to first unread message

Chris Odorjan

unread,
Apr 8, 2020, 11:04:26 PM4/8/20
to retro-comp
So I built a board for the RC2014 bus based upon the XR88C681 dual UART: https://github.com/codorjan/duart

Besides two serial ports the XR88C681 provides a single timer and a bunch of general-purpose output and input lines. The DUART clock can be provided by the system clock or an on-board oscillator (with provision to divide by 1, 2, or 4), or the on-board oscillator can be used as the system clock.

board_empty.jpg



board.jpg



This was indirectly inspired by a post by Tadeusz Pycio a while back and in the meantime the two of us have independently created compatible boards based upon the chip. Mine uses the PLCC version and brings out all the output and input lines, but doesn't use the extended RC80 bus so the second port isn't brought out to the bus (and CLK2 isn't used for anything).

I've done some limited testing with the SCM driver provided by Colin MacArthur in this thread using the on-board divider to provide a 3.6864MHz clock from the system clock. As with Tadeusz' board mine is intended to be consistent with IEI/IEO handling of Steve Cousins' products but IM2 is currently untested. Using a separate oscillator is also untested.

(Fun fact: the XR88C92/192 and similar chips should be almost drop-in replacements but lack IM2 and require software changes regarding the baud rate generator depending on the rate(s) used.)

Proper documentation is currently in progress...

--
Chris Odorjan

Alan Cox

unread,
Apr 9, 2020, 9:00:07 AM4/9/20
to retro-comp

This was indirectly inspired by a post by Tadeusz Pycio a while back and in the meantime the two of us have independently created compatible boards based upon the chip. Mine uses the PLCC version and brings out all the output and input lines, but doesn't use the extended RC80 bus so the second port isn't brought out to the bus (and CLK2 isn't used for anything).

I think that makes three of us - oh well. I just uploaded a related SC26C92 board although I've taken a somewhat different path and used the 7.37MHz clock for the UART so it can do 230Kbit and the like. I didn't do any IM2 stuff and I added glue to split the I/O ports into three bitbang SPI interfaces.

Alan

Steve Cousins

unread,
Apr 9, 2020, 9:17:00 AM4/9/20
to retro-comp
There are so many new developments I can't keep up. I really should update my "modules" spreadsheet but I've got behind the curve and now it is harder to do.

Are any of these designed going to be offered as kits?

Can you post details of I/O address options, suggested default address, and number of I/O addresses occupied.

Steve



Alan Cox

unread,
Apr 9, 2020, 10:12:08 AM4/9/20
to retro-comp

I plan to offer PCBs not kits once the CoVid 19 fun is over. I'm high
risk so not supposed to go posting stuff at the moment. If anyone
wants to turn any of the boards I've done into kits just ask. The only
reason I marked them CC-NC is that in the retro world there have been
a few too many cases where the original open product got tweaked
incompatibly by some vendor and then sold as 'the official' product
with a new brand and marketing so people didn't even know about the
open one.

I am using the following right now

0xC0/C8: 16x50A UARTs (will probably change because of the Z180
issue). Where to go is a good question - I favour 0xA0 as you wouldn't
normally have an ACIA _and_ a 16550A and if you do then you can move
one easily enough. Non Z80 all use 0xC0 and will probably not change
as Ben's original card can't do below 0xC0.

Ben's VIA lives
0x60-0x6F (RW)     Ben's 6522 VIA card (any 0xX?) fully decoded - 6502
relevant only really

Most of my boards defaults are 0xBx to try and pack stuff in

0x3C-0x3F(RW)     82C54 timer card (any 4 port aligned range, fully
decoded) - mainly for non Z80

0xA0-0xAF(RW)    ACIA or SC26C92 (and possibly or 16550 ports) on the
basis you'd usually pick one. Options 80/90/..../F0
0xB2-B3    (W)        Sound with DMA (still debugging) - any 2 aligned
port for 2 ports.
0xXXB4-B7 (RW)    Shared memory (fully decoded, choice is 1X1XX1NN)
(A4, AC, B4, BC, E4, EC, F4, FC) for 4 ports
0xB8/0xB9  (RW)   I/O expander (any address, fully decoded)
0xXXBA      (RW)   QUART (one port, any even numbered port)
0xBB           (RW)   PS/2, Sound. Joystick
0xXXBC-0xXXBF (RW)  Coprocessor card (decodes 111111??), next rev will
probably decode 1111111? so you can get two into BC-BF

0xFC-0xFF  (R) ZX81 keyboard (any port, read only - so can overlap the
MMU) decodes 111111?? so occupies 4 ports. If I do a new
rev it'll occupy 2 ports FE-FF by default.
0xFF (fixed)  (W) 8085 MMU, MMU card, 65C02 and 65C816 protected mode MMU

Not really assigned a port

Gluino (Arduio glue)     1NNN0XXX  where 1XX is actually not used
unless you also fit the optional PCF8584 for I2C


The CPU cards all use 0xFF or have no onboard I/O. The idea being that
you can never have two differing ones anyway.

Alan

Tadeusz Pycio

unread,
Apr 9, 2020, 10:39:17 AM4/9/20
to retro-comp
Hi, Steve
My XR88C681 module in DIP40 is as follows:

There are so many new developments I can't keep up. I really should update my "modules" spreadsheet but I've got behind the curve and now it is harder to do.

Effect of popularity RC2014/RC80 ;)
 

Are any of these designed going to be offered as kits?

In the current situation I do not plan to sell, so I shared Gerber files so that anyone interested could build them themselves. I don't know when they will unblock international shipments in my country.
 
Can you post details of I/O address options, suggested default address, and number of I/O addresses occupied.

I/O addresses: 0x00-0F, 0x20-2F, 0x40-4F, 0x60-6F, 0x80-8F, 0xA0-AF, 0xC0-CF, 0xE0-EF. By default, I use the address 0x60, so that there is no conflict with the existing one on the SIO @ 0x80 bus, but the choice is any of the available ones.

Chris Odorjan

unread,
Apr 9, 2020, 8:33:32 PM4/9/20
to retro-comp
On Thursday, 9 April 2020 10:39:17 UTC-4, Tadeusz Pycio wrote:
Are any of these designed going to be offered as kits?

In the current situation I do not plan to sell, so I shared Gerber files so that anyone interested could build them themselves.

I wasn't planning on offering kits but I also shared the design files in case anyone else wanted to build one. That reminds me to add my latest design to OSH Park...
 
Can you post details of I/O address options, suggested default address, and number of I/O addresses occupied.

I/O addresses: 0x00-0F, 0x20-2F, 0x40-4F, 0x60-6F, 0x80-8F, 0xA0-AF, 0xC0-CF, 0xE0-EF. By default, I use the address 0x60, so that there is no conflict with the existing one on the SIO @ 0x80 bus, but the choice is any of the available ones.

Mine takes up 16 ports starting at any multiple of 16. I arbitrarily went with 0x40-0x4F since there's nothing else there on my system but there's no reason it can't be changed. Should we standardize on one of the common ranges like 0xA0-0xAF?

--
Chris Odorjan

Tadeusz Pycio

unread,
Apr 10, 2020, 2:41:54 AM4/10/20
to retro-comp

Should we standardize on one of the common ranges like 0xA0-0xAF

Hi, Chris

I don't see any obstacles for 0xA0 to become the default setting. Steve's datasheet shows that there is only conflict with the reflection of ACIA RC2014. It can be assumed that no one will use ACIA with DUART.

Alan Cox

unread,
Apr 10, 2020, 1:28:49 PM4/10/20
to retro-comp


On Friday, 10 April 2020 07:41:54 UTC+1, Tadeusz Pycio wrote:

Should we standardize on one of the common ranges like 0xA0-0xAF

Works for me too - it's where the ACIA is, where the 16x50 is now probed for so it's becoming a sort of general "primary address" UART, and it's possible to tell all three apart in software and to tell 88C681 from SC26C92.

Alan

Tadeusz Pycio

unread,
Apr 23, 2020, 4:22:26 PM4/23/20
to retro-comp
Hi, Chris

In accordance with your proposal to change the default address of the DUART modules to 0xA0, I saved the SCM to my SC108 including this change.

PS. Steve won't be thrilled because I forgot to change the build's naming. I will fix it when I finish the software change of baud rate for XR88C681.

SC108.png


Chris Odorjan

unread,
Apr 28, 2020, 10:24:40 AM4/28/20
to retro-comp
This is a preliminary RomWBW driver for the DUART boards by me / Tadeusz Pycio / Alan Cox: https://github.com/codorjan/RomWBW/tree/duart
It's based mostly on the existing UART driver, with bits of SIO in there too.

Right now it detects the presence of a DUART. It should also determine its type, but the INITDEV routine assumes it's working with an XR88C681 because the baud rate tables can be set per-channel there. (Support for chips with MR0 will require more thought as we either need to limit baud rates to those in a single table, or do something like the NetBSD scn driver and switch tables if possible.) It also assumes the input clock is 3.6864MHz (i.e. rates will be doubled if running at 7.3728MHz).

Interrupts aren't used; however, automatic control of /RTS is always enabled and polled I/O seems to work fine at 115200bps. (In fact, I successfully uploaded the ROM image using XMODEM over the DUART itself and flashed it from CP/M.)

Some things are done per-channel that really should be done per-chip. Detection in particular doesn't really need to be done for channel B and sort of only works by accident at the moment. ACR is write-only so I set aside a per-channel shadow register when/if we add timer support that in retrospect should also be per-chip.

A bug that took a while to track down wasn't in my driver per se: the DUART wouldn't work after booting, but was fine after running mode.com. It was as if INITDEV wasn't being called at first. Turns out I had DUART listed first in RomWBW's tables of entry points; the card was being initialized just fine, but then the 16550 UART detection routine running immediately afterwards was stomping on the DUART's clock select register. I've "fixed" this by placing DUART after the 16550 UART in the init and pre-init tables. I expect this will cause similar weirdness on a 16550-type card (I don't have one to test at the moment). A proper solution is probably to have the DUART detection code do a non-destructive test for a 16550-type UART and bail out early. (I'm thinking a write to the counter/timer upper byte register, which should immediately return the value written on a DUART unless the counter/timer's already running at an insanely high speed, but is the read-only modem status register on a 16550.)

TL;DR this isn't really done yet but works well enough that I've been using it as the only serial device in my RC2014 since Sunday...

(RCZ80_std.rom is the ROM image, RCZ80_std.app is an APPBOOT file that should be renamed to a .COM extension before running it in CP/M.)

--
Chris Odorjan
RCZ80_std.rom
RCZ80_std.app

Alan Cox

unread,
Apr 28, 2020, 10:43:32 AM4/28/20
to retro-comp
Right now it detects the presence of a DUART. It should also determine its type, but the INITDEV routine assumes it's working with an XR88C681 because the baud rate tables can be set per-channel there. (Support for chips with MR0 will require more thought as we either need to limit baud rates to those in a single table, or do something like the NetBSD scn driver and switch tables if possible.) It also assumes the input clock is 3.6864MHz (i.e. rates will be doubled if running at 7.3728MHz).

My board is designed to run at 7.37Mhz as the chip can take it, and it means the board can also be my clock generator and reset card if needed - so probably we need to detect that somehow. If you have an RTC it is easy enough to measure.

For Fuzix I check the chip type and go 3.68 or 7.372 accordingly. At the moment I am just using a single table on the 26C92 as it gets most of the useful rates. I do have the code to do split tables (Fuzix on the 68K uses it) but it's bigger and uglier. If you have no timer need you can also just force one channel to use the timer.

A bug that took a while to track down wasn't in my driver per se: the DUART wouldn't work after booting, but was fine after running mode.com. It was as if INITDEV wasn't being called at first. Turns out I had DUART listed first in RomWBW's tables of entry points; the card was being initialized just fine, but then the 16550 UART detection routine running immediately afterwards was stomping on the DUART's clock select register. I've "fixed" this by placing DUART after the 16550 UART in the init and pre-init tables. I expect this will cause similar weirdness on a 16550-type card (I don't have one to test at the moment). A proper solution is probably to have the DUART detection code do a non-destructive test for a 16550-type UART and bail out early. (I'm thinking a write to the counter/timer upper byte register, which should immediately return the value written on a DUART unless the counter/timer's already running at an insanely high speed, but is the read-only modem status register on a 16550.)


I took the simple approach in Fuzix. I probe the possible device types in order. Once I find a device at a given address I don't probe that address for anything else.

Alan

Wayne Warthen

unread,
Apr 28, 2020, 2:13:17 PM4/28/20
to retro-comp
On Tuesday, April 28, 2020 at 7:24:40 AM UTC-7, Chris Odorjan wrote:
This is a preliminary RomWBW driver for the DUART boards by me / Tadeusz Pycio / Alan Cox: https://github.com/codorjan/RomWBW/tree/duart
It's based mostly on the existing UART driver, with bits of SIO in there too.

Very cool.  I thought I was going to need to do this work myself!  :-)

Are you OK if I incorporate your work into the official RomWBW?

A bug that took a while to track down wasn't in my driver per se: the DUART wouldn't work after booting, but was fine after running mode.com. It was as if INITDEV wasn't being called at first. Turns out I had DUART listed first in RomWBW's tables of entry points; the card was being initialized just fine, but then the 16550 UART detection routine running immediately afterwards was stomping on the DUART's clock select register. I've "fixed" this by placing DUART after the 16550 UART in the init and pre-init tables. I expect this will cause similar weirdness on a 16550-type card (I don't have one to test at the moment). A proper solution is probably to have the DUART detection code do a non-destructive test for a 16550-type UART and bail out early. (I'm thinking a write to the counter/timer upper byte register, which should immediately return the value written on a DUART unless the counter/timer's already running at an insanely high speed, but is the read-only modem status register on a 16550.)

This is a deficiency in RomWBW.  Someday I will look into it. 

TL;DR this isn't really done yet but works well enough that I've been using it as the only serial device in my RC2014 since Sunday...

If you are OK with me incorporating your work, could you let me know when you consider it generally done?

Thanks,

Wayne 

Chris Odorjan

unread,
Apr 29, 2020, 2:27:03 PM4/29/20
to retro-comp


On Tuesday, 28 April 2020 14:13:17 UTC-4, Wayne Warthen wrote:

Are you OK if I incorporate your work into the official RomWBW?
If you are OK with me incorporating your work, could you let me know when you consider it generally done?

Of course!

I've just committed some code to weed out 16x50-style UARTs before accidentally overwriting any of their registers. The only other thing is to properly setup the baud rate generator for 26C92-style DUARTs, so once that's done it should be good to go...

--
Chris Odorjan

Chris Odorjan

unread,
Apr 29, 2020, 2:35:20 PM4/29/20
to retro-comp
On Tuesday, 28 April 2020 10:43:32 UTC-4, Alan Cox wrote:
If you have an RTC it is easy enough to measure.

For Fuzix I check the chip type and go 3.68 or 7.372 accordingly.Alan

Looks like the RTC gets initialized before any of the serial I/O devices. The easiest way may be to measure the speed if the RTC exists, otherwise assume a '681 is running at 3.68 and a '92 at 7.37.

--
Chris Odorjan

Wayne Warthen

unread,
Apr 29, 2020, 5:37:30 PM4/29/20
to retro-comp
Looks like the RTC gets initialized before any of the serial I/O devices. The easiest way may be to measure the speed if the RTC exists, otherwise assume a '681 is running at 3.68 and a '92 at 7.37.

RomWBW measures the system clock speed dynamically and records it if an RTC exists.  There are two variables in HBIOS that a driver can use.  CPUMHZ and CPUKHZ.  If there is no RTC, the variables will be set to the speed in the config file.

Thanks,

Wayne

Tadeusz Pycio

unread,
May 7, 2020, 1:56:43 PM5/7/20
to retro-comp
I am sending the SCM 1.0 configuration folder for the SC108 module with support for XR88C681 and/or Z80 SIO. I have to finish at this stage, because the priority is for me to write the software of the Karl #26B module Z280 (many thanks). The naming of the compilation is left to Steve. The software detects attached cards (SIO@80, DUART@A0) and determines their order.

SC108A.png


SC_S3M.zip

Chris Odorjan

unread,
May 21, 2020, 9:53:19 PM5/21/20
to retro-comp
On Wednesday, 29 April 2020 14:27:03 UTC-4, Chris Odorjan wrote: 
I've just committed some code to weed out 16x50-style UARTs before accidentally overwriting any of their registers. The only other thing is to properly setup the baud rate generator for 26C92-style DUARTs, so once that's done it should be good to go...

I've updated my RomWBW driver to work with a 26C92 and have tested it with an XR88C92 (in addition to my usual XR88C681). Right now it never switches baud rate tables on a '92 so the rates are limited; I went with Extended Table 2 with ACR[7]=1 which gives (9600, 19200, 38400, 14400, 28800, 57600, 115200, 230400). This ought to cover most of the rates everyone uses these days. (This leaves out 460800 which is possible using a 7.3728MHz '92 but doesn't seem to be very practical on a Z80.)

There's no detection of the DUART's clock rate; it's assumed a '681 runs at 3.6864MHz and a '92 at 7.3728MHz. The counter/timer isn't used for anything (besides the detection routine).

I've also improved the 16x50 rejection a bit since the original one was also rejecting the XR88C92! (Seems it only updates the counter registers when the counter is actually running? I had to add a counter/timer source which messes with MCR, but that gets saved and restored later.) I don't have a 16550 board (yet) so I've really only tested this with Alan Cox's RC2014 emulator (which emulates a 16450). As such I've made duart a separate configuration for the RCZ80 platform until someone with a 16550 (or 16650, or 16750) can make sure it doesn't try configuring it as a DUART. I'm also hoping someone could test the driver with non-Exar units.

Enclosed is RCZ80_duart.app (rename to .com) and RCZ80_duart.rom based upon 3.1.1-pre.13 in the dev branch from earlier today.

@Wayne, at this point I don't see any reason why this couldn't be incorporated into your repository...

--
Chris Odorjan
RCZ80_duart.app
RCZ80_duart.rom

Alan Cox

unread,
May 22, 2020, 7:53:52 AM5/22/20
to retro-comp

I've also improved the 16x50 rejection a bit since the original one was also rejecting the XR88C92! (Seems it only updates the counter registers when the counter is actually running? I had to add a counter/timer source which messes with MCR, but that gets saved and restored later.) I don't have a 16550 board (yet) so I've really only tested this with Alan Cox's RC2014 emulator (which emulates a 16450). As such I've made duart a separate configuration for the RCZ80 platform until someone with a 16550 (or 16650, or 16750) can make sure it doesn't try configuring it as a DUART. I'm also hoping someone could test the driver with non-Exar units.

For Fuzix at least I just checked for a 16x50 first, then reset and test the 88C92/26C92 if it was not a 16x50. For the 26C92 at least there are a couple of quick sanity checks - both the counter start and stop command read registers always return 0xFF .

Alan

Tadeusz Pycio

unread,
May 22, 2020, 10:20:21 AM5/22/20
to retro-comp
Hi Alan,

You have to be careful when reading 0xFF, non-existent registers in the I/O space also return this result.

Wayne Warthen

unread,
May 22, 2020, 1:24:16 PM5/22/20
to retro-comp
On Thursday, May 21, 2020 at 6:53:19 PM UTC-7, Chris Odorjan wrote:
@Wayne, at this point I don't see any reason why this couldn't be incorporated into your repository...

Great.  Can you provide (or point me to) the the driver source file?

Thanks,

Wayne 

Alan Cox

unread,
May 22, 2020, 1:53:50 PM5/22/20
to retro-comp


On Friday, 22 May 2020 15:20:21 UTC+1, Tadeusz Pycio wrote:
Hi Alan,

You have to be careful when reading 0xFF, non-existent registers in the I/O space also return this result.

Only if you've got something pulling the lines high. A CMOS Z80 tends to float at 0x78 - I've no idea why. Even if it did the other tests would catch it, it's just useful to be able to shortcut probes with simple read tests.


Chris Odorjan

unread,
May 22, 2020, 2:31:40 PM5/22/20
to retro-comp
On Friday, 22 May 2020 13:24:16 UTC-4, Wayne Warthen wrote:
Great.  Can you provide (or point me to) the the driver source file?

It's in the duart branch on my fork on Github right now: https://github.com/codorjan/RomWBW/tree/duart

I've only used git for about a year now and Github for a couple of months, what's the usual procedure? Should I send a pull request?

--
Chris Odorjan

Wayne Warthen

unread,
May 22, 2020, 4:39:14 PM5/22/20
to retro-comp
I've only used git for about a year now and Github for a couple of months, what's the usual procedure? Should I send a pull request?

A pull request would be ideal and help ensure that everyone knows where this work came from.

If you have any trouble generating a pull request, let me know and I will grab the code manually.

Thanks,

Wayne 

Chris Odorjan

unread,
May 22, 2020, 6:03:12 PM5/22/20
to retro-comp
On Friday, 22 May 2020 16:39:14 UTC-4, Wayne Warthen wrote:
I've only used git for about a year now and Github for a couple of months, what's the usual procedure? Should I send a pull request?

Sent!

Thanks,

--
Chris Odorjan

Wayne Warthen

unread,
May 22, 2020, 6:47:32 PM5/22/20
to retro-comp
Thanks Chris.  Nice work following all the RomWBW conventions and integration points.  I did update some of the other config files so they would also compile cleanly even though they do not currently enable the driver.

At present, you have the build set to generate a separate ROM for support of DUART ports.  Since you have supported auto-detection logic, is there any reason the DUART driver cannot just be part of the main RCZ80 config?  That is how the other serial drivers work.

Thanks,

Wayne 
Reply all
Reply to author
Forward
0 new messages