PDP manual describing coroutines

D. Hugh Redelmeier hugh-pmF8o41NoarQT0dZR+AlfA at public.gmane.org
Sun Nov 3 01:33:45 UTC 2013


| From: Paul Tarvydas <paultarvydas-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>

| Over on the FBP google group, Brad Cox mentioned that he learned about
| coroutines from a PDP-x manual, which described coroutines and subroutines as
| equals.   He thought that it was the PDP-8 assembler manual, but this appears
| not to be the case.
| 
| Does anyone know which manual contained this explanation, and, does anyone
| have a copy of this manual that can be shared?

There was no "the PDP-8 assembler manual" as far as I remember.  There
were books like the 1967 "The Digital Small Computer Handbook", the
somewhat different 1968 book with the same title, and the
"Introduction to programming:  PDP-8 Family Computers".  At least
those are the ones I have in storage.

<https://www.flickr.com/photos/walkingsf/sets/72157628922224107/>
<http://highgate.comm.sfu.ca/pdp8/>

The PDP-10 and PDP-11 also supported coroutines.

See, for example <http://www.inwap.com/pdp10/usenet/coroutines> (random
Google hit).

Coroutines are easy to implement on any machine that doesn't use a
stack discipline.  Once you have a stack, you need some way to kludge
a branching stack, possibly behind the back of the runtime system.

As I remember it, I invented coroutines on the PDP-8 (in 1968).  Not
that I was the first!  But it means that I don't think that those
PDP-8 manuals describe coroutines.  I may only have had the first
book at that time.

The PDP-8 subroutine call instruction
	jms sub
would:
1) store the return address in sub
2) transfer control to sub+1

All addresses are of 12-bit words and all addresses fit in a 12-bit
work.  Note: the return address is stored amongst the instruction
stream.  Supporting recursion takes work.

Coroutines could be coded like this (re-invented just now; may be
wrong or not optimal):

a_entry: .word 0	; entry point and return address
	 jmp @a_yield	; jump to where a_yield points
a_yield: .word a_start	; where to resume a
	 jmp @a_entry	; jump to where a_entry points

; sample body for a.
; Each call of a yields a charcter in the accumulator.
; It yields the characters a, b, c in sequence and then repeats
a_start: cla	; clear the accumulator
	 tad ='a'	; add 'a'
	 jms a_yield	; yield to a's caller
	 cla
	 tad ='b'
	 jms a_yield
	 cla
	 tad ='c'
	 jmp a_start

(I've taken a lot of liberties with the notation to make it look like
conventional modern assembly languages.)

- aentry is the entry point to the corouting (each time).
  To call the routine (from outside): jms aentry

- astart would be the label on the initial starting point of the
  coroutine.

- the coroutine would yield control (return to its caller) by calling
  ayield: jms ayield

- the very first time the coroutine is called, the aentry+1 jmp
  would use the intial content of ayield as the starting point
  of the couroutine.  So it must be suitably initialized (astart).

Notice how, to the body of the coroutine, the caller looks like a
subroutine?  That's the magic of coroutines.

The machine with the easiest implementation of coroutines must be the
RCA CDP-1802.  It had 16 registers.  You could switch which one was
the program counter (SEP command).  So if you had a small number of
coroutines, you could dedicate one register for each to be the program
counter.  To transfer to another coroutine, just switch to that
coroutine's program counter.
--
The Toronto Linux Users Group.      Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists





More information about the Legacy mailing list