//AIproms.bcpl
// L. Stewart
//last modified April 19, 1978 9:36 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("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 NOTE: Low bit inverted before reaching NEXT
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
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
endcase
]
case sioStartInput: //Input request
[
newState = stateStartInput
NEXTbits = wakeupInputStart
endcase
]
case sioStartOutput: //Output request
[
newState = stateStartOutput
NEXTbits = nothing
endcase
]
case sioOtherDevice: //Nothing
[
newState = OldState
NEXTbits = nothing
endcase
]
]
ifnot test IWake
ifso
[
newState = stateIdle
NEXTbits = wakeupInputData
]
ifnot test OWake
ifso
[
newState = stateIdle
NEXTbits = wakeupOutputData
]
ifnot
[
newState = OldState
NEXTbits = nothing
]
endcase
]
case stateStartOutput:
[
test SIO
ifnot
[
newState = stateIdle
NEXTbits = nothing
]
ifso
[
newState = OldState
NEXTbits = nothing
]
endcase
]
case stateStartInput:
[
test SIO
ifso
[
newState = OldState
NEXTbits = wakeupInputStart
]
ifnot
[
test ISWakC
ifso
[
newState = stateIdle
NEXTbits = nothing
]
ifnot
[
newState = OldState
NEXTbits = wakeupInputStart
]
]
endcase
]
case stateSetControl:
[
test SIO
ifnot
[
test ISWakC
ifso
[
newState = stateIdle
NEXTbits = nothing
]
ifnot
[
newState = OldState
NEXTbits = wakeupControl
]
]
ifso
[
newState = OldState
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 = 2
stateHandshake = 5
stateWakeup = 7
stateLastWakeup = 3
stateLastWakeupDelay = 6
]
structure Address:
[
blank bit 8
NotIRead bit //A0 pin 5
NotIIEnbl bit
Pad bit
IC15 bit
TYInBS bit
OldState bit 3
]
structure Data:
[
ILastW 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, OldState
if IRead then newState = stateIdle
endcase
]
case stateWaitforBit:
[
newState = TYInBS ? stateClock, OldState
if IIEnbl then newState = OldState
if IRead then newState = stateIdle
endcase
]
case stateClock:
[
newState = stateHandshake
if IRead then newState = stateIdle
endcase
]
case stateHandshake:
[
test TYInBS
ifso newState = OldState
ifnot test IC15
ifso newState = Pad ? stateLastWakeup, stateWakeup
ifnot newState = Pad ? stateClock, stateWaitforBit
if IRead then newState = stateIdle
endcase
]
case stateLastWakeup: //wait for first IREAD
[
newState = IRead ? stateLastWakeupDelay, OldState
endcase
]
case stateLastWakeupDelay: //wait for first IREAD to go away
[
newState = IRead ? OldState, stateWakeup
endcase
]
case stateWakeup: // wait for last IREAD
[
newState = IRead ? stateIdle, OldState
endcase
]
default:
[
newState = stateIdle
endcase
]
]
data<<Data.NewState = newState
data<<Data.ILastW= ((newState eq stateLastWakeup) % (newState eq stateLastWakeupDelay)) ? 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, OldState
endcase
]
case stateWaitforRdy:
[
newState = RFNOBS ? stateSendBit, OldState
if IWrite then newState = OldState
endcase
]
case stateSendBit:
[
test RFNOBS
ifso newState = OldState
ifnot newState = OC15 ? stateWakeup, stateClock
endcase
]
case stateClock:
[
newState = stateWaitforRdy
endcase
]
case stateWakeup:
[
newState = OldState
// if IOClr then newState = stateIdle
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
]