This is a cross-referenced version of move.plan, to download the unmodified
source try move.plan.
#PROGRAM /GFMOVE(15AM,22AM,DBM,EBM)
#PAGE
#INCLUDE STACK(/DEFS)
# Move words, coping with overlapping source
# and dest.
# void gfmove (int *from, int *to, int words)
#SET ARGS=0
#DEFINE ARGFROM=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGTO=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGWORDS=ARGS
#SET ARGS=ARGS+1
# Define stack frame
#SET STFRAME=SXFRAME
# First arguments:
#DEFINE STFROM=SXPAR1
#SET STFRAME=STFRAME+1
#DEFINE STTO=SXPAR2
#SET STFRAME=STFRAME+1
#DEFINE STWORDS=SXPAR3
#SET STFRAME=STFRAME+1
#PROGRAM
# First pick up value args
STACK 2
OBEY ARGWORDS(1) [ get # words to move
LDX 0 0(3)
STO 0 STWORDS(2)
# Now get call-by-name args
OBEY ARGFROM(1) [ get source address
ARRAY 3 [ arg is array or elem
STACK 2 [ restore SP
STO 3 STFROM(2)
OBEY ARGTO(1) [ get destination address
ARRAY 3 [ arg is array or elem
STACK 2 [ restore SP
STO 3 STTO(2)
ADN 1 ARGS
# Pascal callable entry point
#CUE GPMOVE
BEGIN 2 3,1,STFRAME
LDX 3 STWORDS(2)
BZE 3 BYE [ do nothing if nothing to do
LDX 4 STFROM(2)
LDX 5 STTO(2)
BZE 4 5,BYE [ move to self is noop
# MOVE moves from low addresses to high addresses,
# so if the starting source address ls less than the
# destination and the last source address is greater
# than or equal to the destination we will overwrite
# the source.
BXGE 4 5,SAFE [ if source >= dest use MOVE
LDX 1 4
ADX 1 3 [ x1 = word past end of source
BXGE 5 1,SAFE [ if dest beyond source use MOVE
# We have to do the move ourselves, moving backwards
# in memory.
STO 3 7 [ get count to X7, we need X3
ADX 3 5 [ point X3 beyond end of dest
BACK SBN 1 1 [ point X6 at source
SBN 3 1 [ point X5 at dest
LDX 0 0(1) [ get word of source
STO 0 0(3) [ move to dest
BCT 7 BACK [ loop 'till done
BRN BYE
# The "easy" case - use MOVE
SAFE MOVEW 45 3
BYE END 2 1,0
#END
#FINISH