// PDInit.bcpl -- PDPrint initialization
// derived from PressInit.bcpl 2/7/83
// errors 200
get "PDInternals.d"
get "Streams.d"
// outgoing procedures
external
[
PDInit
]
// incoming procedures
external
[
//PDPrint
PDPrint
PDUserFinishProc
PDError
PDTrap
DblShift
//PDINSTALL, PDINSTALLUTILS
PDInstall
IndexFile
//METER
MeterInit
//Used for initialization of files, etc. -- removed by Junta
OpenFile
Closes
Gets
Endofs
ReadBlock
Junta
MyFrame
CallersFrame
GotoLabel
//PDML
MulDiv; Ugt
DoubleAdd; DoubleSub; DoubleCop
//SCANSTRINGS
TypeForm
ReadComInit
ReadCom
ReadNumber
//ALLOC
InitializeZone
Allocate
//OS
MoveBlock
Zero
lvUserFinishProc
StartIO
//LOADRAM
LoadRam
SetBLV
//TFS
TFSInit
TFSSetDisk
TFSCreateDDMgr
//FLOAT
FLDI; FML; FTR
//PrintOrbitInit
OrbitInit
//WINDOW and misc.
WindowInit;WindowRead;WindowClose;WindowSetPosition
WindowReadBlock
FileStuff
]
// incoming statics
external
[
BitsFile
PDFile
tridentVec
tridentUsed
FileName
Directive
UserCopies
UserPageStart
UserPageEnd
XOffset
YOffset
printerDevice
ResolutionS
ResolutionB
PaperDimensionS
PaperDimensionB
nScans
nBitsPerScan
DPzero
DoMeter
DoFileMeter
Debug
Verbose
mirrorX
invertMode
PDVersion
Report
UseRam
PDZone
PermanentBottom
OverlayTable
OverlayReloc
OverlayBottom
OverlayTop
RamImage
PDSavedUFP
AltoVersion
]
// internal statics
static
[ tridentDiskBase
]
// File-wide structure and manifest declarations.
//manifests copied from AltoFileSys.d and SysDefs.d because Bcpl
// dictionary was getting too big:
manifest [
lFP=5
levBFSbase=5
levDirectory=9
lTFSDSK=100
]
structure STR[
length byte
char↑1,255 byte
]
// Procedures
let PDInit(userParams, cfa) = valof
[
TypeForm("PDPrint ", 10, PDVersion/256, $., 10, PDVersionŹ, 0)
//Following hint for "PDPrint.State" is overwritten at PDInstall time by fiddling with
// the .Run file. This is the primary mechanism for getting at the installed state
// reasonably quickly. In addition to the FP, there is a "magic" number that is
// written as the first word on the state file. This is to try to guard against un-
// installed systems running wild.
let hintState=table [ 0;0;0;0;0;0 ]
compileif lFP+1 ne 6 then [ foo=nil ]
//See if we are installing PDPrint.
let doInstall=false
ReadComInit()
let str=vec 20
let sw=vec 5
ReadCom(str,sw) //Bypass "PDPRINT" command
for i=1 to sw!0 do switchon sw!i into
[
case $I: doInstall=true; endcase
default: endcase
]
//Very first thing to do is load the RAM:
UseRam=(AltoVersion rshift 12) le 3
if UseRam then
[
let errs=LoadRam(RamImage, true)
unless errs eq 0 then PDError(210)
SetBLV(#177776) //Prepare for a silent boot when finishing.
PDSavedUFP=@lvUserFinishProc
@lvUserFinishProc=PDUserFinishProc //Will boot to restore tasks to ROM
]
if doInstall then PDInstall(cfa, hintState)
//Now set up a temporary zone to hold things that will ultimately
// reside in "permanent" storage at the top of memory.
let rpb=@#335 //Get bottom of stack.
let cpb=rpb+100 //That many statics.
let rp=rpb
let cp=cpb
//Now initialize state vectors and scalars. For the vectors, remember
// a relocation table so that things can be moved to high memory after
// the Junta.
let s=OpenFile("PDPrint.State",ksTypeReadOnly,0,0,hintState)
if s eq 0 % Gets(s) ne hintState!lFP then PDInstall(cfa, hintState) //Not installed!
let passCount=Gets(s); ReadBlock(s, cp, passCount) //Default settings
[
let adr=Gets(s)
if adr eq 0 then break
let len=Gets(s)
test len eq 0
ifso @adr=Gets(s)
ifnot [
ReadBlock(s, cp, len)
@adr=cp
cp=cp+len
@rp=adr
rp=rp+1
]
] repeat
Closes(s)
//Now finish global switch processing. This is done after the statics are restored in case
// some things want to be reset.
for i=1 to sw!0 do switchon sw!i into
[
case $D: Debug= not Debug; endcase
case $M: DoMeter= not DoMeter; endcase
case $V: Verbose= not Verbose; endcase
case $R: mirrorX=not mirrorX;endcase
case $N: invertMode=not invertMode;endcase
default: endcase
]
//Look for other command modifiers:
UserCopies=1
UserPageStart=1; UserPageEnd=2000
let p=vec 3000 //For indexing file
let pz=InitializeZone(p, 3000) //Just to set up Allocate,Free to Call0,Call1
//Init the trident disk, if it is there.
//there are Trident drive nos 0-7, each with up to 3 file systems
//allow user to grab any or all
tridentVec=cp;cp=cp+NTridentDrives*NPartitions
Zero(tridentVec,NTridentDrives*NPartitions)
@rp=lv tridentVec
rp=rp+1
if tridentUsed then
[
let ddmgr=TFSCreateDDMgr(pz)
tridentDiskBase=cp //save to put in permanent area
@rp=lv tridentDiskBase
rp=rp+1
for t=0 to NTridentDrives*NPartitions-1 do
[ tridentVec!t=TFSInit(pz,true,(NPartitions-1-(t rem NPartitions))*#400 + (NTridentDrives-1-(t/NPartitions)),ddmgr)
if tridentVec!t eq 0 then loop
MoveBlock(cp, tridentVec!t, lTFSDSK)
cp=cp+lTFSDSK
]
if tridentDiskBase eq cp then //no trident drives working
[
TypeForm("Trident drive is not on-line. Check it out!")
finish
]
]
//Finish processing the command line:
let rpPDFile = nil;
Directive=0
while ReadCom(str,sw) do
[
let j=Disambiguate(str)
unless j then PDError(201, str)
let num=0
if j ls 20 then
[
unless ReadCom(str,sw) then PDError(202)
num=ReadNumber(str) //Leaves fp result in ac1
]
switchon j into
[
case 1: UserCopies=num; endcase //Copies
case 2: [
ResolutionB = num; //Resolution
ResolutionS=ResolutionB
] ; endcase
case 3: XOffset=num; endcase //Xoffset
case 4: YOffset=num; endcase //Yoffset
case 5: UserPageStart=num; UserPageEnd=num; endcase //Page
case 6: UserPageEnd=num; endcase //To
case 20: // Print -- Find and index the PD file:
[
Directive=dirPrint%dirPDScan
let p = vec 3000;
unless ReadCom(str,sw) then PDError(207)
//Salt away the file name:
FileName=cp
let plen=(str!0 rshift 9)+1
MoveBlock(cp, str, plen)
cp=cp+plen
@rp=lv FileName
rp=rp+1
plen=IndexFile(p, FILEPD, str)
if plen eq 0 then PDError(200, str)
//Salt away the indexed file:
PDFile=cp
MoveBlock(cp, p, plen)
cp=cp+plen
@rp=lv PDFile
rpPDFile = rp;
rp=rp+1
] ; endcase
case 21: Directive=dirPrint ; endcase //Reprint
case 22: Directive=dirPatterns%dirPrint ; endcase //Patterns
case 23: Directive=Directive&(not dirPrint) ; endcase //NoPrint
case 24: Directive=(Directive&(not dirPrint))%dirDisplay ; endcase //Display
]
]
if Debug then DoFileMeter=true
if PDFile eq 0 & Directive eq 0 then PDError(203)
nScans = MulDiv(ResolutionS, PaperDimensionS, 10);
nBitsPerScan = MulDiv(ResolutionB, PaperDimensionB, 10);
//Init the Orbit, if necessary
if printerDevice le printerOrbitLast then OrbitInit()
//Save length of "permanent" area:
cpb!-1=cp-cpb
if Ugt(rp, cpb-1) then PDError(204)
@rp=0 //Terminate relocation list
//Get rid of the operating system:
Junta(levBFSbase, PDInitAux)
]
and
PDInitAux() be
[
//Move "permanent" things up from where we saved them temporarily.
let rp=@#335
let cp=rp+100
let len=cp!-1
let PermanentTop=MyFrame()-3000 //3000 words of stack space
@#335=PermanentTop
PermanentBottom=PermanentTop-len
MoveBlock(PermanentBottom, cp, len)
while @rp ne 0 do
[
@@rp=@@rp+PermanentBottom-cp
rp=rp+1
]
//fix up the trident disk table
if tridentUsed then
[ for t=0 to NTridentDrives*NPartitions-1 do
if tridentVec!t ne 0 then
[ tridentVec!t=tridentDiskBase
tridentDiskBase=tridentDiskBase+lTFSDSK
]
]
//Now allocate any more permanent things you can think of....
let z=vec 2
z>>ZN.Allocate=PermanentAllocate
z>>ZN.Free=PDTrap
PDZone=z
compileif MeterSw then [ if DoMeter then MeterInit() ]
OverlayTop=PDInit
OverlayBottom=PDInit
PDPrint(0) //And run PDPrint!
]
and
PermanentAllocate(zone, siz) = valof
[
PermanentBottom=PermanentBottom-siz
resultis PermanentBottom
]
and
Disambiguate(str) = valof
[
let len=str>>STR.length
let matchNo=nil
let matchCnt=0
for i=1 to 100 do
[
let s=selecton i into
[
case 1: "Copies"
case 2: "Resolution"
case 3: "XOffset"
case 4: "YOffset"
case 5: "Page"
case 6: "To"
case 20: "Print"
case 21: "Reprint"
case 22: "Patterns"
case 23: "NoPrint"
case 24: "Display"
default: 0
]
if s eq 0 % len gr s>>STR.length then loop
let match=true
for j=1 to len do
if ((str>>STR.char↑j xor s>>STR.char↑j)&(not #40)) ne 0 then
match=false
if match then
[
matchCnt=matchCnt+1
matchNo=i
]
]
if matchCnt eq 1 then resultis matchNo
resultis false
]