Heading:
Proposed Alto-1822 Interface
Page Numbers: Yes X: 527 Y: 10.5"
Inter-Office Memorandum
ToDistributionDateJanuary 2, 1978
FromLarry StewartLocationPalo Alto
SubjectAlto-1822 InterfaceOrganizationSSL
Request for Comments
XEROX
Filed on: [Maxc1]<LStewart>AIdesign.press
Abstract
This memo describes my proposed design for the Alto-1822 interface. A previous memo (November 17, 1977, filed on [IFS]<LStewart>PR>AltoIMP.bravo, AltoIMP.press) gave some preliminary thoughts on implementation and laid down some rough specs. The potential uses for the interface are for a Packet Radio Net gateway, and for a direct MAXC2 Arpanet connection.
Style
The interface is an Alto processor bus device, task driven and should be capable of speeds up to about 1 Megabit. The interface is full duplex.
Emulator - Task interface
An emulator program can wake up the IMP task by executing an SIO instruction with either or both of AC0 bits 5 and 6 set. AC1 is must point to a command block during the execution of the SIO. Possible functions are start receiver, start transmitter, and read status/set control register. The IMP task must run before AC1 can be changed (i.e. the IMP task must be higher priority - which is assured).
Start receiver
The receiver will go off and collect a packet from the IMP. The final buffer location used is returned in lvBuffer. Returns error if the buffer size is zero, if the buffer overflowed, or if the receiver seems to be running already.
LDAAC0,#001000
LDAAC1,readCmdBlock
SIO

readCmdBlock:struct
[
BufferSize/buffer size in words
lvBuffer/buffer pointer
Post/place to leave status
interruptBits/channels to interrupt
/on completion
]
Start transmitter
The transmitter will send a packet (buffer) to the IMP without further attention. Returns error if the buffer size is zero or if the transmitter seems to be running already.
LDAAC0,#002000
LDAAC1,writeCmdBlock
SIO

writeCmdBlock:struct
[
BufferSize/buffer size in words
lvBuffer/buffer pointer
Post/place to leave status
interruptBits/channels to interrupt
/on completion
]
Read Status / Set Control Register
This command allows an emulator program to observe the interface without disturbing it. The command word can do things like reset the interface to ground zero, turn on the Host Ready relay, etc.
LDAAC0,#003000
LDAAC1,CmdBlock
SIO

CmdBlock:struct
[
controlWord/command
Post/place to leave status
interruptBits/channels to interrupt
/on completion
]
Post Data
After the style of the ethernet, on completion of a command, the microcode status occupies the left byte of the Post location and the hardware status occupies the right byte.
Possible microcode status bytes:
00000000-all ok
00000001-hardware seemed to be busy already
00000010-buffer overflow (input only)
00000011-buffer length was zero on entry
Hardware status bits:
struct
[
unusedbit5;
IMPWasDownbit1;
IMPnotReadybit1;
HostnotReadybit1;
]
Command Word
The command word is used to set and clear some control flipflops in the hardware. Some of these, like TestMode and HostReadyRelay, will never be touched by the microcode - they are to be used by an emulator program. Others, like SetLastWord, are intended to be used only by the microcode and should never appear in a command.
Command Bits:
struct
[
unusedbyte;
turnOnReadyRelaybit;
turnOffReadyRelaybit;
turnOnTestModebit;
turnOffTestModebit;
unusedbit;
resetWorldbit;
setLastWordbit;
tryClearingIMPdownFlopbit;
]
Microcode
A copy of my preliminary microcode is attached. The code uses 7 S registers, the longest path between TASKs is about 11 microinstructions. In order to handle the full duplex hardware, the task mostly waits just before a 16-way branch. Two SIO bits and two hardware wakeup bits are OR’ed into NEXT by the branch. The microcode is largely self-explanatory (to those in the know).
Hardware
Attached are the Sil drawings of the proposed design (no pin numbers as yet). The hardware consists of two PROM driven finite state machines, one each for input and output. In addition, there are the parts necessary to interface with the Alto processor bus, a software controlled loop-back feature, and line drivers and receivers appropriate for the 1822 distant-host interface. (They may be used with the Local Host signaling with minimal changes).
I have also included two pages describing the PROM contents. In addition, ensuing following paragraphs offer another explanation of how the finite state machines are supposed to work.
Remarks
I do not claim that the hardware or microcode are bug free, but I think enough of the essentials are there for a preliminary design review.
Presumably, such a review should be set up for sometime.
c: At PARC: Larry Stewart, Dave Boggs, Ed Taft, John Shoch, Ted Strollo, Severo Ornstein, Will Crowther, Butler Lampson, Bert Sutherland.

At SDD:
Bob Metcalfe, Ron Crane, Yogen Dalal, Hal Murray, Victor Schwartz.
Appendices
Input PROM
StateEventNew StateOutputs
000IDLEIIEFct (input enable)001None

001
Wait for bitTYInBS (bit available)100RFNInB

100
Clock010Shift,Count

010
HandshakingTYInBS’ & Count15’001
wait & Pad’
Count15011
Pad100

011
Input WakeupIRFct000IWake
IRFct & Pad011(special case)
Output PROM
StateEventNew StateOutputs
000IDLEIWFct (write function)001None

001
Wait for impRFNOS (Imp ready)100

010
Send a bitRFNOS’ & Count15’111TYOB
RFNOS’ & Count15110

110
Clock bit001Shift,Count

111
Clock last bit011Shift,Count

011
WakeupIWFct001OWake
Microcode
; Alto 1822 Interface microcode
; Larry Stewart 1/2/78

; 2-way branches using NEXT9
!1,2,IODMOR,IODEND
!1,2,INXT,IODLST
!1,2,IIDMOR,IIDFUL
!1,2,IIDCON,IIDLST
!1,2,IIBLOK,IIBLZ
!1,2,IOBLOK,IOBLZ

; 16-way dispatch using NEXT6,NEXT7,NEXT8,NEXT9
!17,20,INOCMD,IODATA,IIDATA,IIDATB,IOSTRT,IOBAD,IOSTA,IOBADA,IISTRT,IISTA,IIBAD,IIBADA,ICTST,ICTSTA,ICTSTB,ICTSTC;

; Task Specific Function Definitions

$IRFCT $ ; F2-8
Input data
$IWFCT $ ; F1-8
Output data
$IOCFCT$ ; F1-9
Clear hardware output wakeup
$ISWFCT$ ; F1-10
Clear SIO generated wakeup
$IIEFCT$ ; F2-10
Start read (turn on RFNIB)
$IBRFCT$ ; F1-11
16-way branch on wakeup conditions
$IPFCT $ ; F2-11
Post function (gate status to bus)
$ISCFCT$ ; F2-9
Set control functions from bus

;R (S) registers

$IIPTR $R1;
Input buffer pointer
$IICTR $R2;
Input word count
$IICPTR$R3;
Input post location pointer
$IOPTR $R4;
Output buffer pointer
$IOCTR $R5;
Output word count
$IOCPTR$R6;
Output post location pointer
$IWORK $R7;
Spot for saving things

; Task constants

$ISDON $377;
done
$ISBSY $777;
busy
$ISOVF $1377;
buffer overflow (input only)
$ISBLZ $1777;
block length zero

$ICTWO $2;
address computation
$ICSLST$2;
set last word

; Other definitions

$AC1 $R2
;Emulator register


;Main loop. Task waits here when not processing something.

IMLOOP:
T← ICTWO,IBRFCT;handy constant
L← AC1+T,:INOCMD;16-way branch

;[INOCMD,IODATA,IIDATA,IIDATB,IOSTRT,IOBSY,IOSTA,IOBSYA,
; IISTRT,IISTA,IIBSY,IIBSYA,ICTST,ICTSTA,ICTSTB,ICTSTC]

INOCMD:
TASK,:INXT;;Can’t get here!

;Read status and set control register

ICTST:
MAR← AC1,:ICTSTM;Start fetch of args
ICTSTA:
MAR← AC1,:ICTSTM;
ICTSTB:
MAR← AC1,:ICTSTM;
ICTSTC:
MAR← AC1,:ICTSTM;
ICTSTM:
L← AC1+1;
ISCFCT← MD,TASK;Set control flops
IWORK← L;Save post pointer
L← ISDON,ISWFCT,:IPOST;Control done

;Common Post routine
; Expects address of post location in IWORK
;
and task status in L

IPOST:
MAR← IWORK;Start double reference
IWORK← L;Save ucode status
T← NWW;
MD← IWORK,IPFCT;Bus AND hardware status
L← MD OR T,TASK;NWW OR interrupt bits
NWW← L,:IMLOOP;

;If a hardware input/output wakeup turns up along with a
;SIO start input/output request, something is awry...

IIBSYA:
IWORK← L,:IBPST;
IIBSY:
IWORK← L,:IBPST;
IOBSYA:
IWORK← L,:IBPST;
IOBSY:
IWORK← L,:IBPST;
IBPST:
L← ISBAD,ISWFCT,:IPOST;Clear wakeup

;Input initialization
;
Buffer pointer, buffer count, and pointer to
;
remaining arguments stored in s regs.

IISTRT:
T← MAR← AC1,:IISTM;Start fetch
IISTA:
T← MAR← AC1,:IISTM;
IISTM:
IICPTR← L;Save post pointer
T← MD,BUS=0;test for zero length
L← MD-1:IIBLOK;[IIBLOK,IIBLZ]
IOBLOK:
IIPTR← L,L← T,ISWFCT;Save arguments
IICTR← L,IIEFCT,TASK,:INXT;length ok,start reader
INXT:
:IMLOOP;continue

IIBLZ:
L← IICPTR,TASK,;
IBLZP:
IWORK← L;
IBLZPA:
L← ISBLZ,ISWFCT,:IPOST;

;Input Main loop

IIDATA:
L← MAR← IIPTR+1,:IIDATM;Start fetch
IIDATB:
L← MAR← IIPTR+1,:IIDATM;
IIDATM:
T← IICTR-1,BUS=0;Buffer full?
IIPTR← L,L← T,:IIDMOR;[IIDMOR,IIDFUL]

IIDMOR:
MD← IRFCT;Read and branch on last word.
;
Except on the last word, this
;
clears the wakeup
IICTR← L,:IIDCON;[IIDCON,IIDLST]

IIDCON:
IIEFCT,TASK,:INXT;clear wakeup, restart

IIDLST:
MAR← IICPTR-1;recall count location
L← IICPTR;
IWORK← L,TASK;this TASK only works
;
because the hardware doesn’t really clear the
;
wakeup until the next IRFCT in this case
MD← IIPTR;store final address
L← ISIDON;input done status
IIDPST:
SINK← IRFCT,:IPOST;clear wakeup

IIDFUL:
L← IICPTR,TASK;set up for post
IWORK← L;
L← ISIOVF,:IIDPST;overflow status

;Output initialization
;
Buffer pointer, buffer count, and pointer to
;
remaining arguments stored in s regs.

IOSTRT:
T← MAR← AC1,:IOSTM;Start fetch
IOSTB:
T← MAR← AC1,:IOSTM;
IOSTM:
IOCPTR← L;Save post pointer
T← MD,BUS=0;test for zero length
L← MD-1,:IOBLOK;[IOBLOK,IOBLZ]
IOBLOK:
IOPTR← L,L←T,TASK;Save arguments
IOCTR← L;length ok
ISWFCT,:IODATA;send first word

IOBLZ:
L← IOCPTR,TASK,:IBLZP;

;Main output loop

IODATA:
L← MAR← IOPTR+1,:IODATM;start fetch
IODATB:
L← MAR← IOPTR+1,:IODATM;
IODATM:
T← IOCTR-1,BUS=0;buffer empty?
IOPTR← L,L← T,:IODMOR;[IODMOR,IODEND]

IODMOR:
IWFCT← MD,SH=0;write, last word?
IOCTR← L,TASK,:INXT;[INXT,IODLST]

;Set last word flop in order to set Last Host Bit

IODLST:
SINK← ICSLST,ISCFCT,:IMLOOP;

IODEND:
L← IOCPTR,TASK;chance to run
IWORK← L;normal end for write
L← ISDON,IOCFCT,:IPOST