// MICRO Utility Routines
// last edited February 5, 1981  10:01 AM
// Copyright Xerox Corporation 1979, 1981

get "micdecl.d"

external	// O.S.
[	MoveBlock; SetBlock
]

structure
  [	blank bit 15
	odd bit 1		// Least significant bit
   ]


//let unpak(dest,source,count) be
// Unpack an unformatted (non-NOVA/ALTO BCPL) string starting
//	at source into dest for count characters.
// *** In assembly code
//	for i = 0 to count-1 do dest!i = source>>bytes↑i

let pak(dest,source,count) be
// Packs an unformatted string starting at source into
//	dest for count characters.
  [	let sptr,dptr,send = source,dest,source+count-2
	let wd = nil
	while sptr le send do
	  [	wd = @sptr lshift 8
		sptr = sptr + 1
		@dptr = (sptr>>rh) + wd
		sptr = sptr + 1
		dptr = dptr + 1
	   ]
	if count<<odd eq 1 then
		@dptr = @sptr lshift 8
   ]

and num2blk(blk,number,radix) = valof
// Converts number into a block of char.s at blk in base radix.
// Radix must be even.
// Returns number of characters.
  [	let rad = radix rshift 1
	let ptr, num = blk, number
	[ ptr, num = ptr+1, (num rshift 1)/rad
	] repeatuntil num eq 0
	let n = ptr-blk
	num = number
	[ ptr = ptr - 1
	  let num1 = (num rshift 1)/rad
	  @ptr = num-((num1*rad) lshift 1)+$0
	  num = num1
	] repeatuntil num eq 0
	resultis n
   ]

and bcplpak(dest,source,count) be
// Packs an unformatted string of count characters at
//	source into a BCPL string at dest.
  [	@dest = (count lshift 8) + (@source & #377)
	if count ge 2 then
		pak(dest+1,source+1,count-1)
   ]

and length(string) = 
// Number of characters stored in BCPL string.
	string>>lh