Heading:
Proposed Alto-1822 Interface, PROM Update
Page Numbers: Yes X: 527 Y: 10.5"
Inter-Office Memorandum
ToTaft, Boggs, Shoch,DateJanuary 28, 1978
Strollo, Stewart, Hunt
FromLarry StewartLocationPalo Alto
SubjectAlto-1822 InterfaceOrganizationSSL
New PROM contents
XEROX
Filed on: [Maxc1]<LStewart>AInewprom.press
[IFS]<LStewart>AInewprom.press
Abstract
The Alto-1822 interface contains two PROM driven finite state machines. This memo presents an updated view of how the (input and output) machines are supposed to work. Included are state tables for each PROM, DRAW generated state diagrams, and the bcpl program which creates the .MB file for the PROM blower.
Comments
The finite state machines handle the bit by bit handshaking protocol specifies by BBN-1822 for local host and distant host IMP interfaces. The choice of 2-way or 4-way handshaking on the input side is made by a wiring change in the "There’s Your Input Bit" synchronizer. For output, the choice is made by the IMP.
Input
Upon receipt of the task function IIEnbl, the input FSM begins assembly of a 16 bit word from the IMP. Usually, the machine will accept the 16th bit, set the hardware input wakeup signal, and stop. If the "Last Input Bit" signal arrives during the middle of a word, the FSM will fill out the word with zeros before setting the wakeup. In either case, a task function (IRead) must eventually read the input data register. If the hardware or software dies, the Alto reset lines will clear the wakeup.
Output
Upon receipt of the task function IWrite (which loads the output shift register from the bus), the output FSM will transmit a 16 bit word to the IMP. Usually, the machine will transmit the 16th bit, set the hardware output wakeup signal, and stop. If the "Last Word" signal is set during the middle of the word (by a task function), the 1822 "Last Output Bit" signal will be set during transmission of the 16th bit. There is no provision for transmitting partial words. In either case, a task function (IWrite or IOClr) or hardware reset must eventually clear the output wakeup.
Input PROM
StateEventNew StateActions
000IDLEIIEnbl (enable input)001ctr←15
RFNInB←1

001
Wait for bitTYInBS (bit available)101RFNInB←0
Shift
Pad←LInB

101
Clock data(next clock)010ctr←ctr+1

010
HandshakingTYInBS’ & ctr#15001RFNInB←1
wait & Pad’
ctr=15011IWake←1
Pad & ctr#15101Shift

011
Input WakeupIRFct & Pad’000IWake←0
IRFct & Pad011Pad←0
bus←sr
Output PROM
StateEventNew StateActions
000IDLEIWrite (write function)001ctr←0
sr←bus

001
Wait for impRFNOS (Imp ready)010TYOB←1

010
Send a bitRFNOS’ & ctr#15101TYOB←0
Shift
RFNOS’ & ctr=15011TYOB←0
OWake←1

101
Clock bitctr#14001ctr←ctr+1
ctr=14001ctr←ctr+1
LOutB←LastWd

011
WakeupIWFct001OWake←0
sr←bus
IOClr000OWake←0
ROM Generating Program
//AltoImpRoms.bcpl

//last modified January 28, 1978 7:49 PM

get "Streams.d"

external
[
//incoming procedures
OpenFile; Ws; Puts; Closes

//incoming statics
dsp
]

static [ mbFile; memoryNumber ]

structure String [ length byte; char↑1,1 byte ]

//-------------------------------------------------------------------
let AltoImpRoms() be
//-------------------------------------------------------------------
[
mbFile = OpenFile("D1EthRoms.mb",ksTypeWriteOnly,charItem)
DoMemory(256,4,"Input",GenInput)
DoMemory(256,4,"Output",GenOutput)
PutWord(mbFile,0) //end of file
Closes(mbFile)
]

//-------------------------------------------------------------------
and DoMemory(length,width,name,Generator) be
//-------------------------------------------------------------------
//length is 2↑(number of address bits)
//width is the number of output bits
//name is a BCPL string
//generator is a procedure
[
Puts(dsp,$*N); Ws(name)

PutWord(mbFile,4) //declare memory parameters
memoryNumber = memoryNumber +1
PutWord(mbFile,memoryNumber)
PutWord(mbFile,width)
for i = 1 to name>>String.length do Puts(mbFile,name>>String.char↑i)
Puts(mbFile,0) //asciz end of string
if (name>>String.length & 1) eq 0 then Puts(mbFile,0) //pad to word boundry

PutWord(mbFile,2) //set current memory and location
PutWord(mbFile,memoryNumber)
PutWord(mbFile,0) //location = 0

for addr = 0 to length-1 do
[
PutWord(mbFile,1) //memory data word
PutWord(mbFile,0) //source line number (not used)
PutWord(mbFile,Generator(addr))
]
]

//-------------------------------------------------------------------
and PutWord(stream,w) be
//-------------------------------------------------------------------
[
Puts(stream,w rshift 8)
Puts(stream,w)
]

//-------------------------------------------------------------------
and GenInput(address) = valof
//-------------------------------------------------------------------
//an I3601
[
manifest
[
//the correspondence between voltage levels and bits in the .MB file:
high = 0; low = 1
//the correspondence between states and bits in the .MB file:
stateIdle = 17
stateWaitforBit = 6
stateClock = 12
stateHandshake = 15
stateWakeup = 14
]

structure Address:
[
blank bit 8
NotIRead bit //A0 pin 5
NotIIEnbl bit
Pad bit
IC15 bit
TYInBS bit
OldState bit 3
]

structure Data:
[
NewState bit 4 //Q0 pin 12
blank bit 12
]

IRead = not address<<Address.NotIRead
IIEnbl = not address<<Address.NotIIEnbl
Pad = address<<Address.Pad
IC15 = address<<Address.IC15
TYInBS = address<<Address.TYInBS
OldState = address<<Address.OldState

switchon OldState into
[
case stateIdle:
[
data<<Data.NewState = IEnbl ? stateWaitforBit, stateIdle
]
case stateWaitforBit:
[
data<<Data.NewState = TYInBS ? stateClock, stateWaitforBit
if IRead data<<Data.NewState = stateIdle
]
case stateClock:
[
data<<Data.NewState = stateHandshake
if IRead data<<Data.NewState = stateIdle
]
case stateHandshake:
[
test IC15
ifso data<<Data.NewState = stateWakeup
ifnot test Pad
ifso data<<Data.NewState = stateClock
ifnot data<<Data.NewState = TYInBS ? stateHandshake, stateWaitforBit
if IRead data<<Data.NewState = stateIdle
]
case stateWakeup:
[
test IRead
ifnot data<<Data.NewState = stateWakeup
ifso data<<Data.NewState = Pad ? stateWakeup, stateIdle
]
default:
[
data<<Data.NewState = stateIdle
]
]
resultis data
]

//-------------------------------------------------------------------
and GenOutput(address) = valof
//-------------------------------------------------------------------
//an I3601
[
manifest
[
//the correspondence between voltage levels and bits in the .MB file:
high = 0; low = 1
//the correspondence between states and bits in the .MB file:
stateIdle = 17
stateWaitforRdy = 16
stateClock = 12
stateSendBit = 5
stateWakeup = 14
]

structure Address:
[
blank bit 8
NotIOClr bit //A0 pin 5
NotIWrite bit
blank bit
OC15 bit
NotRFNOBS bit
OldState bit 3
]

structure Data:
[
NewState bit 4 //Q0 pin 12
blank bit 12
]

IOClr = not address<<Address.NotIOClr
IWrite = not address<<Address.NotIWrite
OC15 = address<<Address.OC15
RFNOBS = notaddress<<Address.NotRFNOBS
OldState = address<<Address.OldState

switchon OldState into
[
case stateIdle:
[
data<<Data.NewState = IWrite ? stateWaitforRdy, stateIdle
]
case stateWaitforRdy:
[
data<<Data.NewState = RFNOBS ? stateSendBit, stateWaitforRdy
]
case stateSendBit:
[
test RFNOBS
ifso data<<Data.NewState = stateSendBit
ifnot data<<Data.NewState = OC15 ? stateWakeup, stateClock
]
case stateClock:
[
data<<Data.NewState = stateWaitforRdy
]
case stateWakeup:
[
data<<Data.NewState = IWrite ? stateWaitforRdy, stateWakeup
]
default:
[
data<<Data.NewState = stateIdle
]
]
if IOClr data<<Data.NewState = stateIdle
resultis data
]