This is a cross-referenced version of unpack8.plan, to download the unmodified
source try unpack8.plan.
#PROGRAM /GFUNPACK8(15AM,22AM,DBM,EBM)
#PAGE
#INCLUDE STACK(/DEFS)
#PROGRAM
# Unpack 8 bit bytes from a buffer
# gf unpack8 (int *from, int pos, int *to, int len)
#SET ARGS=0
#DEFINE ARGFROM=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGPOS=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGTO=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGLEN=ARGS
#SET ARGS=ARGS+1
# Stack frame
#SET STFRAME=SXFRAME
# First the arguments:
#DEFINE STFROM=SXPAR1
#SET STFRAME=STFRAME+1
#DEFINE STPOS=SXPAR2
#SET STFRAME=STFRAME+1
#DEFINE STTO=SXPAR3
#SET STFRAME=STFRAME+1
#DEFINE STLEN=SXPAR4
#SET STFRAME=STFRAME+1
# Now local vars:
# Pick up call by value parameters
STACK 2
OBEY ARGLEN(1)
LDX 0 0(3)
STO 0 STLEN(2)
OBEY ARGPOS(1)
LDX 0 0(3)
STO 0 STPOS(2)
# Pick up call by name parameeters
OBEY ARGFROM(1)
ARRAY 3 [ it's array elem or name
STACK 2 [ restore stack top
STO 3 STFROM(2)
OBEY ARGTO(1)
ARRAY 3 [ array elem or name
STACK 2 [ restore stack top
STO 3 STTO(2)
ADN 1 ARGS
# Now Pascal entry point
#CUE GPUNPACK8
BEGIN 2 3,1,STFRAME
LDX 5 STLEN(2)
SBNC 5 1
BCS BYE [ do nothing if length 0
LDX 1 STFROM(2)
LDX 3 STTO(2)
LDX 7 STPOS(2) [ get input pos
BZE 7 WORD [ optimise frequent case
LDN 0 3
DVS 6 0 [ x7 = pos/3, x6 = remainder
ADX 1 7 [ add word offset to input ptr
BZE 6 WORD [ jump if want leftmost byte
LDX 0 0(1) [ get word
LDN 4 3
SBN 4 6 [ # bytes in 1st word (2 or 1)
SBNC 6 2 [ x6 is 1 (middle) or 2 (right)
BCS *+2
SLL 0 8 [ want bottom byte
SLL 0 8 [ want middle byte
BRN BYTE
WORD LDX 0 0(1) [ get word of 3 bytes
LDN 4 3
BYTE SLC 0 8 [ get MSB to bottom
LDN 6 255
ANDX 6 0 [ get byte to X6
STO 6 0(3)
SBNC 5 1 [ Done?
BCS BYE
ADN 3 1 [ bump output pointer
BCT 4 BYTE [ loop for bytes in word
ADN 1 1 [ bump input pointer
BRN WORD
BYE END 2 1,0
#END
#FINISH