Heading:
Alto-1822 Interface, PROMs
Page Numbers: Yes X: 527 Y: 10.5"
Inter-Office Memorandum
ToTaft, Boggs, Shoch,DateFebruary 7, 1978
Strollo, Stewart, Hunt
FromLarry StewartLocationPalo Alto
SubjectAlto-1822 InterfaceOrganizationSSL
PROM contents
XEROX
Filed on: [Maxc1]<LStewart>AIproms.press
[IFS]<LStewart>AIproms.press
Abstract
The Alto-1822 interface contains three PROM driven finite state machines. This memo presents an updated view of how they are supposed to work. Included are state tables for two of the PROMs, 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
Output is initiated by the SIO start output function. This generates a signal which drops the output machine into the wakeup state.
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.
Wakeup Control
Serves as a priority encoder for the four possible wakeup conditions. Also remembers whether any SIO requests are outstanding.
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
IOStrt011OWake←1

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
//AIproms.bcpl

//last modified February 7, 1978 3:53 AM

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("AIProms.mb",ksTypeWriteOnly,charItem)
DoMemory(256,4,"Control",GenControl)
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 GenControl(address) = valof
//-------------------------------------------------------------------
//an I3601
[
manifest
[
//states
stateIdle = 0
stateStartOutput = 1
stateSetControl = 2
stateStartInput = 3
//wakeups
nothing = 0
wakeupControl = 0
wakeupInputStart = 1
wakeupInputData = 2
wakeupOutputData = 3
//SIO’s
sioSetControl = 3
sioStartInput = 2
sioStartOutput = 1
sioOtherDevice = 0
]

structure Address:
[
blank bit 8
NotSIO bit //A0 pin 5
NotBus bit 2
NotISWakC bit //A0 pin 5
NotIWake bit
NotOWake bit
OldState bit 2
]

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

let SIO = address<<Address.NotSIO eq 0
let Bus = address<<Address.NotBus xor #3
let ISWakC = address<<Address.NotISWakC eq 0
let IWake = address<<Address.NotIWake eq 0
let OWake = address<<Address.NotOWake eq 0
let OldState = address<<Address.OldState
let data = 0
let newState= 0
let NEXTbits= 0

switchon OldState into
[
case stateIdle:
[
test SIO
ifso switchon Bus into
[
case sioSetControl: //Control request
[
newState = stateSetControl
NEXTbits = wakeupControl
]
case sioStartInput: //Input request
[
newState = stateStartInput
NEXTbits = wakeupInputStart
]
case sioStartOutput: //Output request
[
newState = stateStartOutput
NEXTbits = nothing
]
case sioOtherDevice: //Nothing
[
newState = stateIdle
NEXTbits = nothing
]
]
ifnot test IWake
ifso
[
newState = stateIdle
NEXTbits = wakeupInputData
]
ifnot test OWake
ifso
[
newState = stateIdle
NEXTbits = wakeupOutputData
]
ifnot
[
newState = stateIdle
NEXTbits = nothing
]
endcase
]
case stateStartOutput:
[
newState = stateIdle
NEXTbits = nothing
]
case stateSetControl:
[
test ISWakC
ifso
[
newState = stateIdle
NEXTbits = nothing
]
ifnot
[
newState = stateSetControl
NEXTbits = wakeupControl
]
endcase
]
]
data<<Data.NewState = newState
data<<Data.Nextbits = NEXTbits
//cheating to set file bits correctly
data = data xor #170000
// sigh
resultis data
]

//-------------------------------------------------------------------
and GenInput(address) = valof
//-------------------------------------------------------------------
//an I3601
[
manifest
[
//states
stateIdle = 0
stateWaitforBit = 1
stateClock = 5
stateHandshake = 2
stateWakeup = 3
]

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

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

let IRead = address<<Address.NotIRead eq 0
let IIEnbl = address<<Address.NotIIEnbl eq 0
let Pad = address<<Address.Pad ne 0
let IC15 = address<<Address.IC15 ne 0
let TYInBS = address<<Address.TYInBS ne 0
let OldState = address<<Address.OldState
let data = 0
let newState= 0

switchon OldState into
[
case stateIdle:
[
newState = IIEnbl ? stateWaitforBit, stateIdle
endcase
]
case stateWaitforBit:
[
newState = TYInBS ? stateClock, stateWaitforBit
if IRead then newState = stateIdle
endcase
]
case stateClock:
[
newState = stateHandshake
if IRead then newState = stateIdle
endcase
]
case stateHandshake:
[
test IC15
ifso newState = stateWakeup
ifnot test Pad
ifso newState = stateClock
ifnot newState = TYInBS ? stateHandshake, stateWaitforBit
if IRead then newState = stateIdle
endcase
]
case stateWakeup:
[
test IRead
ifnot newState = stateWakeup
ifso newState = Pad ? stateWakeup, stateIdle
endcase
]
default:
[
newState = stateIdle
endcase
]
]
data<<Data.NewState = newState
data<<Data.RFNInB= newState eq stateWaitforBit ? 1, 0
//cheating to set file bits correctly
data = data xor #170000
// sigh
resultis data
]

//-------------------------------------------------------------------
and GenOutput(address) = valof
//-------------------------------------------------------------------
//an I3601
[
manifest
[
//states
stateIdle = 0
stateWaitforRdy = 1
stateClock = 5
stateSendBit = 2
stateWakeup = 3
]

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

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

let IOClr = address<<Address.NotIOClr eq 0
let IWrite = address<<Address.NotIWrite eq 0
let IOStrt = address<<Address.NotIOStrt eq 0
let OC15 = address<<Address.OC15 ne 0
let RFNOBS = address<<Address.NotRFNOBS eq 0
let OldState = address<<Address.OldState
let data = 0
let newState= 0

switchon OldState into
[
case stateIdle:
[
test IOStrt
ifso newState = stateWakeup
ifnot newState = IWrite ? stateWaitforRdy, stateIdle
endcase
]
case stateWaitforRdy:
[
newState = RFNOBS ? stateSendBit, stateWaitforRdy
endcase
]
case stateSendBit:
[
test RFNOBS
ifso newState = stateSendBit
ifnot newState = OC15 ? stateWakeup, stateClock
endcase
]
case stateClock:
[
newState = stateWaitforRdy
endcase
]
case stateWakeup:
[
newState = IWrite ? stateWaitforRdy, stateWakeup
endcase
]
default:
[
newState = stateIdle
endcase
]
]
if IOClr then newState = stateIdle
data<<Data.NewState = newState
data<<Data.TYOB= newState eq stateSendBit ? 1, 0
//cheating to set file bits correctly
data = data xor #170000
// sigh
resultis data
]