// Phryxus.bcpl
// Program to ship a run-encoded ".ram" file from an Alto
// disk to a Ramtek plotter: (Phryxus = mythological ram driver )
// Written as `Aries’ by Rich Pasco July 1981
// Last modified: October 15, 1981 11:06 AM
get "streams.d"
get "altodefs.d"
get "altofilesys.d"
static
[run
left
right
lineCount
pixelCount
]
external
[
//OS
CallSwat
Closes
Endofs
Gets
keys
OpenFile
Wo
Wl
Wss
Ws
//GP
SetupReadParam
ReadParam
//Time
CONVUDT
]
manifest
[
//Ramtek parameters
rPixelsPerLine=918
rLinesPerSwath=9
//Ramtek control bytes
rEnterGraphicMode=#5
rBell=#7
rLineFeed=#12
rFormFeed=#14
rCarriageReturn=#15
rEndBuffer=#24
rEndLine=#25
rAbortGraphicMode=#26
rChangeTextParams=#30
rEscape=#33
//Ramtek-Diablo port cabling
rDataStrobe=#100000
rInputPrime=#040000
]
structure STIPPLE :
[
Countbyte
Leftbit 4
Rightbit 4
]
structure RSTATUS : //Ramtek Status
[
//Ramtek-Diablo port cabling
AckBarbit
Busybit
PaperEmptybit
OnLinebit
FaultBarbit
Sparebit
OtherIO bit 10
]
let Phryxus() be
[
Wl("Phryxus, Ramtek plotting of October 15, 1981")
let ramFileName = vec 50
let timeStamp = vec 50
SetupReadParam()
let prompt = "Ram file name: "
let ramFile=ReadParam("IW",prompt,ramFileName)
PrimePrinter()
// set form-feeds to 11" (=default), also sets top-of-form since // Ramtek power-up-initialization doesn’t
// SendPrinter(rEscape); SendPrinter(rFormFeed); SendPrinter(22);
until ramFile eq true do
[SendPrinterString(" File ")
SendPrinterString(ramFileName)
SendPrinterString(" printed ")
SendPrinterString(CONVUDT(timeStamp,0))
SendPrinter(rCarriageReturn)
SendPrinter(rLineFeed)
SendPrinter(rEnterGraphicMode)
let stip = nil
lineCount = 0
pixelCount = 0
until Endofs(ramFile) do
[stip=Gets(ramFile)
CheckPrinterStatus()
test stip eq 0
ifso
[
if pixelCount ls rPixelsPerLine then SendPrinter(rEndLine)
pixelCount = 0
lineCount = lineCount+1
if lineCount eq rLinesPerSwath then
[lineCount = 0
SendPrinter(rEnterGraphicMode)
]
]
ifnot
[run = stip<<STIPPLE.Count
left = stip<<STIPPLE.Left
right = stip<<STIPPLE.Right
if pixelCount+(2*run) gr rPixelsPerLine then
run = (rPixelsPerLine-pixelCount)/2
pixelCount = pixelCount+(2*run)
for i=1 to run do
[SendPrinter(left)
SendPrinter(right)
]
]
]
SendPrinter(rEndBuffer)//print partly full buffer
//SendPrinter(rFormFeed)
for i=1 to 30 do SendPrinter(rLineFeed)
ramFile=ReadParam("IW",prompt,ramFileName,0,true)
]
]
and PrimePrinter() be
[
// Logic 1 results in TTL low on Diablo output port.
// Briefly pulse InputPrime high, keeping other wires low.
@utilOut=not rInputPrime
@utilOut=not 0
]
and SendPrinter(Data) be
[
// Logic 1 results in TTL low on Diablo output port.
// DataStrobe is normally high, briefly pulled low then high.
// Other wires (eg InputPrime) must stay low.
let DataNot = (not Data) xor rDataStrobe
while utilIn>>RSTATUS.Busy do []
until utilIn>>RSTATUS.AckBar do []
@utilOut = DataNot
@utilOut = DataNot xor rDataStrobe
@utilOut = DataNot
]
and CheckPrinterStatus() be
[
if utilIn>>RSTATUS.PaperEmpty do
[Wl("Printer paper is empty")
GetCR()
loop
]
unless utilIn>>RSTATUS.OnLine do
[Wl("Printer is off line")
loop
]
unless utilIn>>RSTATUS.FaultBar do
[CallSwat("Printer Fault"); loop
]
break
] repeat
and GetCR() be
[Ws("CR or ESC to proceed, DEL to abort: ")
[let ch = Gets(keys)
if ch eq 177B abort
if ch eq rCarriageReturn break
if ch eq rEscape break
] repeat
Wl("")
]
and SendPrinterString(str) be
[for i=1 to str>>STRING.length do SendPrinter(str>>STRING.char↑i)
]