This is a cross-referenced version of writespaces.plan, to download the unmodified
source try writespaces.plan.
#PROGRAM /GFWRITESP(15AM,22AM,DBM,EBM)
#PAGE
#INCLUDE IOHEAD(/DEFS)
#INCLUDE STACK(/DEFS)
#PROGRAM
# Write space bit characters. If buffer fills up must
# force a WRITEBUF
# ERR = WRITESPACES(FD, SPACES)
# CALL 1 WRITESPACES
# LDN 3 FD
# LDN 3 LEN [ # of chars to write
#SET ARGS=0
#DEFINE ARGFD=ARGS
#SET ARGS=ARGS+1
#DEFINE ARGLEN=ARGS
#SET ARGS=ARGS+1
# Define stack frame
#SET STFRAME=SXFRAME
# First the arguments
#DEFINE STFD=SXPAR1 [ FD
#SET STFRAME=STFRAME+1
#DEFINE STLEN=SXPAR2 [ len
#SET STFRAME=STFRAME+1
# Then the local variables
#DEFINE STDESC=STFRAME [ saveed FDESC
#SET STFRAME=STFRAME+1
STACK 2
OBEY ARGFD(1)
LDX 0 0(3) [ get FD
STO 0 STFD(2)
OBEY ARGLEN(1) [ get len
LDX 0 0(3)
STO 0 STLEN(2)
ADN 1 ARGS
# Pascal style entry point
#CUE GPWRITESP
BEGIN 2 3,1,STFRAME
LDX 0 STFD(2)
STO 0 SXPAR1(3) [ is FD open?
LDN 0 1 [ in write mode
STO 0 SXPAR2(3)
CALL 1 GPIOCHECK
BNG 6 BYE [ fd is not open
STO 6 STDESC(2)
OUT LDX 6 STLEN(2) [ Amount we want to write
BZE 6 BYE
LDX 7 FDBUFLEN(3) [ get buffer len in chars
SBX 7 FDCHARS(3) [ subtract used to get avail
LDX 1 FDNEXT(3) [ next char pos to write
# Space filling with MVCH is faster than a simple
# loop of DCH/BCHX/BCT but the setup is messy, so
# let's just do it the dumb way for now.
LDN 0 #20
SPACE BZE 7 FLUSH [ jump if no more space left
SBN 7 1 [ decrement space left
DCH 0 0(1) [ write one space
BCHX 1 *+1 [ bump ouput pointer
BCT 6 SPACE [ back to output another space
# All done
BYE STO 1 FDNEXT(3) [ save NEXT
LDX 0 FDBUFLEN(3) [ avail = buflen - chars
SBX 0 7 [ so chars = buflen - avail
STO 0 FDCHARS(3)
END 2 1,0
# Get here if buffer is full, we have to flush it
FLUSH STO 6 STLEN(2) [ save length left to process
LDX 0 FDBUFLEN(3) [ write full buffer
STO 0 FDCHARS(3)
STACK 3
LDX 4 STFD(2)
STO 4 SXPAR1(3)
CALL 1 GPWRITEBUF
BNZ 6 BYE
LDX 3 STDESC(2)
BRN OUT
#END
#FINISH