//MIOC.BCPL

get "mdecl.d"

external [
// OS
Puts; Zero

// MIDAS
PutField; GetField

// MSYM
EvalAText

// MCMD
DisplayError

// Machine Dependent
@MEMFORMS; @REGFORMS; @REGWID; @MEMWID; AltRForms; AltMForms

// Defined here
RTexttoData; MTexttoData; SimpleTexttoDVec
RDatatoStream; MDatatoStream; SimpleDVectoStream
]

//Subroutines for converting TextVec’s to DataVec’s.
//RTexttoData(RegX,TextVec,DataVec) and MTexttoData(RegX,TextVec,DataVec)
//convert a TextVec to a DataVec where the width is gotten from the table
//of register widths or of memory widths, respectively. These routines
//use SimpleTexttoDVec(TextVec,NBits,DataVec) to do the work.

//GenlTexttoDVec(TextVec,Form,DataVec) is not presently used.

let RTexttoData(RegX,TV,DVec) be SimpleTexttoDVec(TV,REGWID!RegX,DVec)


and MTexttoData(MemX,TV,DVec) be SimpleTexttoDVec(TV,MEMWID!MemX,DVec)


and SimpleTexttoDVec(TV,NBits,DVec) be
[
let Bit1 = NBits-3
Zero(DVec,(NBits+15) rshift 4)
if TV!0 eq 0 then return
for I = TV!0 to 1 by -1 do
[ let X = TV!I
if X ne $ do
[ if (X < $0) % (X > $7) do
[ Zero(DVec,(NBits+15) rshift 4)
let AVal = vec size AVal/16; X = 1
if EvalAText(TV,lv X,AVal,false) then
[ if AVal>>AVal.TypeStorage eq MemTypeStorage do
[ let SBit1,DBit1,MBits = nil,nil,nil
test NBits ge 32
ifso [ SBit1,DBit1,MBits = 0,NBits-32,32 ]
ifnot [ SBit1,DBit1,MBits = 32-NBits,0,NBits ]
MoveLongField(lv AVal>>AVal.Addr,SBit1,MBits,DVec,DBit1)
return
]
]
DisplayError("Bad value")
]
test Bit1 < 0
ifso
[ let T = Bit1+3; if T > 0 then
PutField(0,T,DVec,(X-$0) & (table [ 1; 3; 7 ] !T))
return
]
ifnot [ PutField(Bit1,3,DVec,X-$0); Bit1=Bit1-3 ]
]
]
]

//and GenlTexttoDVec(TV, Form, DVec) be
//[
let Field,Ngrps,InGap = vec 5,0,true
//Count the groups
//
for I = 1 to TV!0 do
//
test InGap
//
ifso
//
if TV!I ne $ then
//
[ InGap = false; Ngrps = Ngrps+1 ]
//
ifnot
//
if TV!I eq $ then InGap = true
//
if Ngrps > Form!0 then Ngrps = Form!0

// now put out initial missing groups
//
let FormX = 1
//
Zero(Field,6)
//
for I = 1 to Form!0 - Ngrps do
//
[ MoveLongField(Field,0,Form!(FormX+1),DVec,Form!FormX)
//
FormX = FormX+2
//
]

// now handle groups with text
//
let TVX = 1
//
for I = Form!0-Ngrps+1 to Form!0 do
//
[ let TempTV = vec 30
//
while TV!TVX eq $ do TVX = TVX+1
//
let X = 0
//
while TV!TVX ne $ logand TVX le TV!0 do
//
[ X = X+1
//
if X le 30 then TempTV!X = TV!TVX
//
TVX = TVX+1
//
]
//
TempTV!0 = X
//
SimpleTexttoDVec(TempTV, Form!(FormX+1), Field)
//
MoveLongField(Field,0,Form!(FormX+1),DVec,Form!FormX)
//
FormX = FormX+2
//
]
//]

//RDatatoStream(Stream,RegX,DataVec) and MDatatoStream(Stream,MemX,DataVec)
//are used, respetively, for outputting register values and memory values
//to a stream. The format table for the register or memory is obtained
//from REGFORMS or MEMFORMS. If this is 0, then SimpleDVectoStream is
//used to output a right-justified octal string with leading blank fill
//of a size equal to the width of the register/3. If the REGFORMS or
//MEMFORMS entry is not 0, then GenlDVectoStream is used to do the work.

//GenlDVectoStream accepts a format table whose first entry is the
//number of format groups. This is followed by pairs of integers
//which stand for the left-bit in the DataVec for a group and the
//number of bits in the group.

//SimpleDVectoStream accept a fill character as its last argument.
//If this character is 0, then no fillers are output for leading zeroes
//in the output. The value of the output is the original fill character
//if all of the NBits are 0; otherwise it is 60B = "0". If the fill
//character is 40B = " ", then blank fill is used; if 60B = "0" then
//0-fill is used.

//Note: Leading blanks must be suppressed for mmprgn.bcpl


and RDatatoStream(Stream,RegX,DVec) be
[
test REGFORMS!RegX eq 0
ifso RegX = SimpleDVectoStream(Stream,REGWID!RegX,DVec,0,true)
ifnot GenlDVectoStream(Stream,REGFORMS!RegX,DVec)
]

and MDatatoStream(Stream,MemX,DVec) be
[
test MEMFORMS!MemX eq 0
ifso MemX = SimpleDVectoStream(Stream,MEMWID!MemX,DVec,0,true)
ifnot GenlDVectoStream(Stream,MEMFORMS!MemX,DVec)
]

and SimpleDVectoStream(Stream,NBits,DVec,flush0,LastFlag) = valof
[
let Bit1,Size1,Byte = 0,NBits rem 3,nil
if Size1 eq 0 then Size1 = 3
while Bit1 < NBits-3 do
[ Byte = GetField(Bit1,Size1,DVec)
if Byte ne 0 then flush0 = $0
if flush0 ne 0 then Puts(Stream,Byte+flush0)
Bit1 = Bit1+Size1; Size1 = 3
]
Byte = GetField(Bit1,Size1,DVec)
if Byte ne 0 then flush0 = $0
if (flush0 ne 0) % LastFlag then Puts(Stream,Byte+$0)
resultis flush0
]

and MoveLongField(Source,SBit1,NBits,Dest,DBit1) be
[
while NBits ge 16 do
[ PutField(DBit1,16,Dest,GetField(SBit1,16,Source))
DBit1,SBit1,NBits = DBit1+16,SBit1+16,NBits-16
]
if NBits > 0 then
PutField(DBit1,NBits,Dest,GetField(SBit1,NBits,Source))
]

and GenlDVectoStream(Stream,Form,DVec) be
[
let Field,Foo,flush0 = vec 5,(Form!0)+(Form!0)-1,0
for FormX = 1 to Foo by 2 do
[ if (FormX > 1) & (flush0 ne 0) then Puts(Stream,$ )
MoveLongField(DVec,Form!FormX,Form!(FormX+1),Field,0)
flush0 = SimpleDVectoStream(Stream,Form!(FormX+1),Field,
flush0,((FormX eq Foo) ? true,false))
]
]