//SilD.bcpl


get "SysDefs.d"
get "Sil.defs"


//the Display area points to the following code, so nothing must be done
//which will cause the display area to be manipulated
//i.e. dont call DisplayObject() etc

let InitBlocks() =valof
[
Dcb = @#420
@#420 = 0 //turn off display for speed and reserve the screen buffer

let NameVec = vec 40
//first get the starting switch from com.cm
let comcm = OpenFile("COM.CM",ksTypeReadOnly,1,0,fpComCm) //bytes
if comcm eq 0 then CallSwat("Can’t open COM.CM")
ReadCmEntry(comcm,NameVec) //throw away name "Sil.run"
let FontSwitch = true
let PrintSw = 0
let InitSwitch = false
let NoSwitchesYet = true
for i = 1 to NameVec>>str.length do
[ //look for /i or font number
let chr = NameVec>>str.char↑i
if chr eq $/ then NoSwitchesYet = false
if NoSwitchesYet then loop
if (chr ge $0)&(chr le $2) then FontSwitch = chr - $0
if chr eq $i then InitSwitch = true
if (chr ge $0)&(chr le $9) then ncopies = ncopies*10 +chr-$0
if chr eq $f then ScanCvrt = -1
if chr eq $p then PrintSw = 1
if chr eq $h then PrintSw = true
]


if PrintSw eq 0 then //reserv a block for the display bit map if not press mode
[
DisplayArea = InitBlocks
@#335 = DisplayArea + (Nwrds*ScreenYmax) + 2
]
//*****DON’T WRITE ENYTHING INTO THE DisplayArea WITHIN THIS CODE ****
//*****DisplayArea POINTS TO THIS CODE! ! ! ! ! ! ! ! ! ****
FontVec = GetSomeMem(4); Zero(FontVec,4) //pointers to .al font definitions
PrFaceVec = GetSomeMem(4); Zero(PrFaceVec,4) //pointers to default printing faces
AlFaceVec = GetSomeMem(4); Zero(AlFaceVec,4) //pointers to .al face enables
WidthVec = GetSomeMem(16); Zero(WidthVec,16) //pointers to mica printing widths
FileVec = GetSomeMem(16); Zero(FileVec,16) //pointers widths in Sil.Fonts
fpSilInit = GetSomeMem(5); Zero(fpSilInit,5) //file pointer to Sil.Fonts
fpAlt = GetSomeMem(5); Zero(fpAlt,5)//file pointer to Alternate text file input if open
Mact = GetSomeMem(Mtsize) //initialize the Macro Definition Table
SelArea = GetSomeMem(5)
RebArea = GetSomeMem(5)
RwArea = GetSomeMem(5)
Lprvec = #20// Library Fps go in memory address #20 through #60
//initialize Paint mask table
MaskTable = #57
MaskTable!0 = 0
for i = 1 to 16 do MaskTable!i = (MaskTable!(i-1) rshift 1) % #100000



test PrintSw eq 0
ifso SilInitCode(InitSwitch,FontSwitch,0)//writes or reads Sil.fps and Sil.fonts
ifnot MakePress(PrintSw,InitSwitch,comcm)// this will never return


//now get a file name if one
ReadCmEntry(comcm,NameVec)
Closes(comcm) //done with com.cm

//initialize the bitmap and dcb
let xDcb = GetSomeMem(9)//8 words plus 1 extra incase Dcb is odd
xDcb=(xDcb+1)𫙰
DisplayArea=(DisplayArea+1)𫙰
//DCB for some blank lines
xDcb!0 = xDcb+4; xDcb!1=0; xDcb!2 = 0; xDcb!3=BlankLines/2
//real DCB
xDcb!4 = 0; xDcb!5=#400+Nwrds; xDcb!6 = DisplayArea; xDcb!7=ScreenYmax/2

//initialize the origin and the mark
OriginObject = GetSomeMem(6)
MakeItem(OriginObject,0,4,0,2,14,Active)//line 4 wide by 2 high

MarkObject = GetSomeMem(6)
MakeItem(MarkObject,0,2,0,7,14,Active)//line 2 wide by 7 high

//initialize the status display
StatusObject = GetSomeMem(75)
MakeItem(StatusObject,mx,mx,my,my,0,Active)//set to value in mx and my
StatusObject>>item.face = PrFaceVec!0 //force face to non bold/italic

//initialize the file name object for i/o
FNameObject = GetSomeMem(FNameLength+5)
MakeItem(FNameObject,0,0,my,my,0,2)
FNameObject>>item.face = PrFaceVec!0 //force face to non bold/italic
//set it to deleted so it won’t be displayed

MoveBlock(lv FNameObject>>item.string,NameVec,FNameLength)

//initialize the mouse buffer
MouseBuffer = GetSomeMem(4) //this is an OsBuf
let v = GetSomeMem(10);Zero(v,10) //room for 5 events, and must be even
MouseBuffer>>OsBUF.First = v
MouseBuffer>>OsBUF.Last = v+10
MouseBuffer>>OsBUF.In = v
MouseBuffer>>OsBUF.Out = v


//initialize the mouse process
@ lvCursorLink = 0 //turn off tracking
SetKeyboardProc(MouseProc,GetSomeMem(50),50) //MouseProc - called 60 times/sec.
@ lvUserFinishProc = CleanUp

//initialize a zone for the file system
//storage required for one disk streem is 256 + ~60 words + ~100 words for OS 17
//we needent allocate an excess since the operationg system
//gives an appropriate message if this is to small
SilZone = InitializeZone(GetSomeMem(430),430) //420 works - 10 words spair
//@lvSysZone,sysZone = SilZone,SilZone -- DORADO
resultis xDcb
]


and GetSomeMem(cnt) = valof
[
let result = @#335
@#335 = result + cnt
resultis result
]
and ReadCmEntry(stream,string) =valof
[
let ch = $*s
let Switches = false
string>>str.length = 0
if Endofs(stream) then resultis 0
until (Endofs(stream)%(ch gr $*s)) do ch = Gets(stream)
if ch le $*s then resultis 0

[
//convert to lower case
test Switches eq true
ifso if (ch ge $A) & (ch le $Z) then ch = ch % #40//make to lower case
ifnot if ch eq $/ then Switches = true
AppendC(ch,string)
if Endofs(stream) then break
ch = Gets(stream)
if ch le $*s then break
] repeat
resultis true
]

and SilInitCode(InitSwitch,FontSwitch,Fonts) be
//get all the stuff that sil needs from a binary file
[
if not InitSwitch then InitS = OpenFile("Sil.fps",ksTypeReadOnly)
if not InitS then
[ MakeInitFile(); InitS = OpenFile("Sil.fps",ksTypeReadOnly) ]
if not InitS then CallSwat("Can’t open Sil scratch file")

let Fprvec = vec 5*DirPreambleSize
for i = 0 to 4*DirPreambleSize-1 do Fprvec!i = Gets(InitS)//read the font fp’s
for i = 0 to 5*DirPreambleSize-1 do Lprvec!i = Gets(InitS)// read the macro fp’s
for i = 0 to 5 do fpSilInit!i = Gets(InitS)// read the fp to Sil.fonts
Closes(InitS)

InitS = OpenFile("Sil.fonts",ksTypeReadOnly,0,0,fpSilInit)
if not InitS then CallSwat("Can’t open Sil fonts scratch file")


if Gets(InitS) ne InitRev then
[ CallSwat("’Init’ file not compatible with this version of Sil - run Sil/I"); finish ]
for i = 0 to 3 do //skip over the font names
[
let str = vec 50 //dummy if not needed
if Fonts ne 0 then str = Fonts+25*i //otherwise put the stuff here
str!0 = Gets(InitS)
for j = 1 to str>>str.length/2 do str!j = Gets(InitS)
Gets(InitS) //skip over spacer
]
for i = 0 to 3 do AlFaceVec!i = Gets(InitS) //press mode wants alto offsets here
for i = 0 to 3 do PrFaceVec!i = Gets(InitS) //printing face defaults
if Fonts ne 0 then [ Closes(InitS); InitS = 0; return ] //got all we nede for press

for i = 0 to 3 do AlFaceVec!i = Gets(InitS) //alto fonts face enables
for i = 0 to 3 do Gets(InitS) //unused - for expansion
mx = Gets(InitS); my = Gets(InitS)
Font3Special = Gets(InitS)

let MaxHeight = 0
for i = 0 to 3 do //now read the alto fonts
[
let Ffpblock = Fprvec + (DirPreambleSize*i)
if Ffpblock!0 eq 0 then loop //font not defined
if (FontSwitch eq true) % (i eq FontSwitch)% (i eq 3) then
if (Ffpblock!0 eq -1) do ReadFont(i,Ffpblock+1)
if (FontVec!i)!-2 gr MaxHeight then MaxHeight = (FontVec!i)!-2
]
for i = 0 to 15 do FileVec!i = Gets(InitS)

for fnt = 0 to 3 do //now read the default font widths
[
if FontVec!fnt eq 0 then loop
let ff = 4*fnt + PrFaceVec!fnt
let FilePtr = FileVec!ff
if FilePtr eq -1 then loop //its already set by a previous font
if FilePtr eq 0 then CallSwat("Impossible Init file error")
if FilePtr ls 32 then [ ff = FilePtr FilePtr = FileVec!ff ]//ptr is indirect
SetFilePos(InitS,0,FilePtr-2)
if Gets(InitS) ne -1 then CallSwat("Not a cosher init file - Run SIL/I again")
let addr = FontVec!fnt+128
for w = 0 to 127 do addr!w = Gets(InitS)
//now set all direct and indirect pointers to these widths to permanent
FileVec!ff = ff%#20; for f = 0 to 15 do
[
if (FileVec!f ge 32) % (FileVec!f eq 0) then loop
FilePtr = FileVec!f & #17
if FilePtr eq ff then [ WidthVec!f = addr; FileVec!f = -1 ]
]
]
Closes(InitS); InitS = 0

for i = 0 to 3 do //now read the alto fonts
[
let Ffp = Fprvec!(DirPreambleSize*i)
if Ffp eq 0 then loop //font not defined
if Ffp eq -1 then loop //font already read in
FontVec!i = FontVec!(Ffp&3)
]

//default any still unspecified fonts to font 0
for i = 1 to 3 do if FontVec!i eq 0 then FontVec!i = FontVec!0

if FontSwitch ne true then
[ let Fptr = FontVec!FontSwitch; for i = 0 to 2 do FontVec!i = Fptr ]

if FontVec!0 eq 0 then [ CallSwat("No Font 0 loaded"); finish ]

// the pointer must point to MaxHeight below memory block and 1 wd above
ItalicsBuff = GetSomeMem(MaxHeight+2)+MaxHeight
for i = 0 to 3 do //now read the alto fonts
[
if FontVec!i eq 0 then loop// no alto font defined
let ChEntry = FontVec!i+#237//find entry in font for "DummyCharacter"
@ChEntry = ItalicsBuff-ChEntry//load Entry with self-relative ptr to ItalicsBuff
]

]