Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Interrupt driven CP/M?

642 views
Skip to first unread message

bbel...@gmail.com

unread,
Jan 27, 2019, 3:03:36 PM1/27/19
to
Many years ago, I attempted to write an interrupt-driven BIOS for my CP/M 2.2 machine. I gave up when I had on good authority that the CP/M 2.2 BDOS is not re-entrant, and I would never get it to work.
Now that things are going well with CP/M 3, the thought crossed my mind that I might want to try this again, especially since I now have "standardized" PIC hardware in the form of the S-100 Computers PIC/RTC board. In addition, all my hardware now has the capability of asserting the various S-100 hardware interrupts. So it seems to me that this might not be so far-fetched any longer.
Has anyone done any work in this area, creating a BIOS that is interrupt-event driven rather than all the devices running in synchronous polled mode?

Thanks for your input!

Bob Bell

Fred J. Scipione

unread,
Jan 28, 2019, 9:36:21 PM1/28/19
to
[This followup was posted to comp.os.cpm and a copy was sent to the
cited author.]

In article <35cdf94d-8c80-4c76...@googlegroups.com>,
bbel...@gmail.com says...
Nine years ago I wrote:

| In addition, you might want to look at the Conkey CBIOS sources,
| either from the Walnut Creek CDROM, or the last version at
| <http://www.vectorbd.com/bfd/shoebox/cnkyos30.ark>
|
| The Conkey CBIOS is for a (particular) Z80 single board computer,
| uses the I/O Byte, and allows hardware interrupts along with polling
| piggy-backed onto BIOS calls. There are some tricks required for
| interrupts because the CP/M BDOS uses its own, rather small, stack
| space that may be in effect when the interrupt hits. Same thing,
| only more so, for the BIOS polling code if an interrupt hits.
|
| There were attempts to keep the Conkey CBIOS modular and commented,
| plus at least one of the duffers that hacked^H^H^H^H^H^Hworked on it
| is open to enquiries.

Fred J. Scipione

mfebe...@gmail.com

unread,
Jan 29, 2019, 6:45:23 PM1/29/19
to
Not a fully-interrupt-driven CP/M but...

A few years back, I worked with Mike Douglas to create a CP/M for the Polymorphic Engineering Poly-88. The Poly-88's keyboard was only readable with interrupts - there was no way to poll the keyboard without significantly modifying the hardware. I wrote interrupt-driven BIOS I/O routines for the Poly-88 I/O devices that included a decent queue for fast serial port data transfers even while the Poly-88 video scrolled its display the painfully hard way.

The interrupt code is part of a ROM for the Poly-88, and can be found here:

http://deramp.com/downloads/mfe_archive/005-Documentation%20and%20Code%20by%20Martin/010%20Code%20by%20Martin/Polymorphic%20Systems/POLEX/

The Polex ROM plugs into an empty ROM socket on the Poly-88, and gives you decent monitor program as well as providing the necessary interrupt-driven I/O calls.

Note that disk controller accesses are still poled in this implementation. But the console and other I/O devices are interrupt driven, and work great.

(Polymorphic Engineering's own CP/M was a lot less elegant - they required you to modify the hardware and also to use a special RAM board that worked with their ROM monitor and video at low addresses.)

bbel...@gmail.com

unread,
Jan 29, 2019, 8:26:20 PM1/29/19
to
I have received some very encouraging responses on this and the S-100 Computers forum. Enough that I am thinking I may be able to do this. It has always been an area of interest for me, in fact in my Senior year at Penn State I took a technical writing course and the final paper was on the Interrupt modes of the Z80 CPU. There's just one thing I will have to research a bit before getting started (getting started will still be awhile...) and that is Max's recommendation to use Z80 Mode 2. I don't believe that is possible with the interrupt hardware present on the typical S-100 boards. All the work I ever did on systems that used Interrupt Mode 2 relied on the daisy-chaining of Z80 peripherals - CTC, PIO, DART, SIO, etc. So am I missing some trick or have I forgot something crucial over the years that has me thinking this way?

Bob Bell

Udo Munk

unread,
Jan 30, 2019, 1:17:44 PM1/30/19
to
For using IM 2 the interrupting hardware needs to put a byte onto the data bus
when the CPU acknowledges the interrupt. How the signal comes to the CPU's INT
pin is completely unrelated to interrupt modes.

For example Cromemco's Z80 CROMIX switches the CPU into IM 2, but there is
no Zilog interrupt daisy chain, the TU-ART's aren't using Zilog chips. Instead the
interrupt priority is build with other logic, see manual. You even need to configure
the TU-ART's for 8080 vector interrupts and not for Z80 vector interrupts, which
got me puzzled for a while.

So yes, a typical S100 bus system even with an 8080 interrupt priority controller
can be used in IM 2, but of course you need to understand everything in detail to
make this working.

Edmund Cramp

unread,
Feb 2, 2019, 8:48:43 AM2/2/19
to
Using Interrupts is very efficient - many years ago I wrote an interrupt driven console iodriver for ZCPR that worked with a VT100 and never dropped a key. However Interrupts are hardware specific so the code is always unique to the environment. The issues are:

1. You need hardware to generate the Interrupt.
2. Transfer control to the Interrupt Service Routine.
3. Preserve all the registers
4. Execute the ISR code and do the job as efficiently as possible.
5. Restore all the registers.
6. Return to the original interrupted code.

Good Luck!
Edmund

durga...@gmail.com

unread,
Feb 17, 2019, 3:27:42 AM2/17/19
to
While the BDOS is not re-entrant, using interrupts for I/O completion is entirely possible on CP/M 2.2 - as long as your interrupt routines don't make BDOS calls (there should be no need for that). You just have to make sure you save enough context and restore it when returning from interrupt. Many vendors implemented interrupts in their BIOS. The problem with CP/M 2.2 and 3.0 is that there is nothing else for the OS to do except wait for I/O completion so there is not much point to using interrupts for everything. One exception is keyboard input, which can benefit from being interrupt driven. If you are looking for multitasking/multiuser, then MP/M is what you want. In that case, using interrupts is pretty much mandatory.

dr_...@ntlworld.com

unread,
Feb 18, 2019, 9:59:31 AM2/18/19
to
I'm pretty sure the Superbrain is using an interrupt to refresh the screen, draw a clock (if enabled) and poll for keys (at least one of the BIOSes has a type ahead buffer). I'm not sure if this counts - it is definitely not calling the BDOS; all this is in BIOS space.

The machine is funkey though, having a second CPU to handle disk drive access. You'd think CPU 1 would do something useful while the second CPU was hitting the floppy - apart from servicing the screen / keyboard interrupt - but it appears to be waiting. If you made CP/M 2.2 properly multitasking it might actually have something to do... but then it wouldn't be CP/M any more.

durga...@gmail.com

unread,
Feb 18, 2019, 11:05:44 AM2/18/19
to
On Monday, February 18, 2019 at 8:59:31 AM UTC-6, dr_...@ntlworld.com wrote:
> ... but then it wouldn't be CP/M any more.

Right! it would be MP/M!

I guess we don't know the original reason for the question - was it an attempt to have a multitasking system, or to try and "improve" the system by using interrupts?

Also, using interrupts in a single-user-single-tasking system does not actually improve anything. In fact, it can hurt performance.

Fred J. Scipione

unread,
Feb 18, 2019, 2:55:19 PM2/18/19
to
[This followup was posted to comp.os.cpm and a copy was sent to the
cited author.]

article <0ce55c08-b464-4363...@googlegroups.com>,
dr_...@ntlworld.com says...
>
> I'm pretty sure the Superbrain is using an interrupt to refresh the
> screen, draw a clock (if enabled) and poll for keys
> (at least one of the BIOSes has a type ahead buffer). I'm not sure if
> this counts - it is definitely not calling the BDOS; all this is in
> BIOS space.
... <snip>...

Some miscellaneous facts and observations about interrupts in the
CBIOS and CP/M multi-tasking -

The Conkey CBIOS provided an interrupt-driven software real-time
clock, and a hook for a timer-driven (interrupting) user-space routine.
The CBIOS used timer-driven interrupts to buffer the console and
modem serial ports. The floppy-disk data transfers were NMI driven.
The CBIOS also has a feature that allowed the cold-boot entry to be
re-used as a warm-boot intercept, but it was never used by anything.
It would have enabled some background task and hooks to survive
through warm boots.

Some CP/M CBIOS's had to sync their console output to a hardware
screen-driver's vertical blanking timing. That vertical blanking
was a de-facto (or actual) CBIOS interrupt.

There was at least one CP/M background print-spooler shim that used
CBIOS and BDOS hooks to access and print from a file in a
multi-tasking fashion.

Various Modem and Kermit file transfer programs used the CBIOS I/O
status calls for user-space multi-tasking of keyboard, screen, modem,
and disk activity.

Of course UZI provided unix-like multi-taking on Z80 systems w/
timers and hard-disks. It had some provisions for running
(small TPA requirement) CP/M binaries (in parallel, w/ pipes, etc).

There was at least one program (w/ BDOS and CBIOS hooks, etc.)
that claimed to provide (emulate) piped I/O between running CP/M
binaries (i.e. task swapping).

Forth has its own cooperative multi-tasking system, which I
think works on CP/M versions of (fig) forth.

One problem that CP/M emulator programs often face is that
running CP/M binaries w/ I/O polling loops causes the emulator
to clog the host CPU usage. Work-arounds that free-up the
emulator CPU by slowing-down the I/O status checks could be
applied in a CBIOS to make some elbow room for multi-tasking.

dr_...@ntlworld.com

unread,
Feb 18, 2019, 5:08:56 PM2/18/19
to
That's interesting Fred, thanks.

The Superbrain is definitely updating the screen and maintaining a clock using an interrupt, vectored via RST 38. Also managing a keyboard type ahead buffer (well, the Compustar M30 BIOS - a later iteration of the Superbrain QD does this). It appears to be testing for the CRT blanking period or status (not entirely sure, as I haven't finished analysing it yet). I noticed that when the CPU is halted (for example, by an ICE) the screen goes blank, so it might be refreshing it using the interrupt. I guess the only thing it doesn't do in your list is access the FDD, because there is a separate CPU for that.

bbel...@gmail.com

unread,
Feb 18, 2019, 11:01:40 PM2/18/19
to
As the original poster, I can clarify why I asked the question:
I have all this hardware with interrupt capability, including a Disk controller that can issue interrupts (CCS-2422), a Serial/Parallel board that can issue interrupts (SERCON) and a PIC/RTC board that can bind them together and also provide time-keeping functions. No, I am not trying to re-create MP/M. I just want to utilize the hardware to give me more efficient disk read/write functions, implement a type-ahead keyboard buffer and write a real-time clock routine that I can use in CP/M 3 to date/time stamp files.
I don't know why using interrupts would be less efficient than waiting in waste-time loops for every peripheral to be ready, but now that I have some confidence that I CAN go down this rabbit hole, I suppose I will eventually find out for myself.
Thanks to everyone for providing all the excellent feedback!

Bob Bell

Martin Burmester

unread,
Feb 19, 2019, 10:55:02 AM2/19/19
to
Hi,
Just curious, whats the reasoning behind it? Why is keyboard different
then other things?

Cheers,
Martin

Udo Munk

unread,
Feb 19, 2019, 12:23:54 PM2/19/19
to
On Tuesday, February 19, 2019 at 4:55:02 PM UTC+1, Martin Burmester wrote:
> Just curious, whats the reasoning behind it? Why is keyboard different
> then other things?

The early keyboards had no buffer, you would lose characters when typing
fast. An interrupt driven routine would use a buffer, lets say 16 chars,
problem gone.

Cecil - k5nwa

unread,
Feb 19, 2019, 3:17:27 PM2/19/19
to
Other than the keyboard and serial ports buffering what will you gain
since CP/M is not multitasking or re-entrant so until the sector is
available as an example what can the OS do? The interrupt might be
available but other than those mentioned above what benefit is there?

--

Cecil - k5nwa

Axel Berger

unread,
Feb 19, 2019, 5:13:49 PM2/19/19
to
Cecil - k5nwa wrote:
> Other than the keyboard and serial ports buffering what will you gain
> since CP/M is not multitasking or re-entrant so until the sector is
> available as an example what can the OS do? The interrupt might be
> available but other than those mentioned above what benefit is there?

The original hardware was not fast enough for this, sector writing as
such was a tricky timing problem, but in a logger interrups can ensure
you do not lose any data if they arrive while you are just writing to
disk.

--
/¯\ No | Dipl.-Ing. F. Axel Berger Tel: +49/ 221/ 7771 8067
\ / HTML | Roald-Amundsen-Straße 2a Fax: +49/ 221/ 7771 8069
 X in | D-50829 Köln-Ossendorf http://berger-odenthal.de
/ \ Mail | -- No unannounced, large, binary attachments, please! --

Udo Munk

unread,
Feb 19, 2019, 5:34:18 PM2/19/19
to
With most FDC's you need to disable interrupts while reading/writing a sector.
Even an interrupt routine that does nothing then saving resisters, restoring them
and returning from the interrupt would be enough for a failed read/write. With
an 8080 @ 2MHz the timing is very tight to transfer the bytes in time already
for single density.

David Schultz

unread,
Feb 19, 2019, 5:49:54 PM2/19/19
to
On 2/19/19 9:50 AM, Martin Burmester wrote:
> Just curious, whats the reasoning behind it? Why is keyboard different
> then other things?

Do you always wait patiently for a prompt to appear before typing? I don't.

The 1.2 version of CP/M-68K added a weak version of typeahead. CONOUT
checked to see if the user typed something like CTL-S or CTL-C. That
function (conbrk) was modified so that normal characters were inserted
in the buffer used by the read console buffer function.

Which only worked if you were sending characters.

It helped but I still added buffers and interrupt driven serial I/O.


--
http://home.earthlink.net/~david.schultz
The cheaper the crook, the gaudier the patter. - Sam Spade

Axel Berger

unread,
Feb 19, 2019, 6:17:31 PM2/19/19
to
Udo Munk wrote:
> With an 8080 @ 2MHz

That's what I meant with "original hardware". Today people may well use
much faster and more powerful derivatives.

Udo Munk

unread,
Feb 20, 2019, 5:25:44 AM2/20/19
to
On Wednesday, February 20, 2019 at 12:17:31 AM UTC+1, Axel Berger wrote:
> That's what I meant with "original hardware". Today people may well use
> much faster and more powerful derivatives.

Yep, but OP is using an ancient FDC from 1980:
http://www.s100computers.com/Hardware%20Folder/CCS/FDC/FDC.htm

With this you have to transfer a byte to/from the FDC every few
microseconds, so interrupts disabled while reading/writing a sector.
0 new messages