This is a cross-referenced version of fhalloc.plan, to download the unmodified
source try fhalloc.plan.
#PROGRAM /GPFHALLOC(15AM,22AM,DBM,EBM)
#PAGE
#INCLUDE IOHEAD(/DEFS)
#INCLUDE STACK(/DEFS)
#PROGRAM
# Allocate a *FH device
# fd = fhalloc (fd, unit, type, read, write)
# fd: requested FD or -1
# unit: *FHn
# type: *FR, *FW, or *FH
# read: #1 or nothing
# write: #2, or #22 or nothing
# Returns FD in X6, or -ve on error
# returns FDESC in X3 if no error
# Local stack frame:
#SET STFRAME=SXFRAME
# First the arguments:
#DEFINE STFD=SXPAR1
#SET STFRAME=STFRAME+1
#DEFINE STUNIT=SXPAR2
#SET STFRAME=STFRAME+1
#DEFINE STTYPE=SXPAR3
#SET STFRAME=STFRAME+1
#DEFINE STREAD=SXPAR4
#SET STFRAME=STFRAME+1
#DEFINE STWRITE=SXPAR5
#SET STFRAME=STFRAME+1
# Then the local variables:
#DEFINE STREDTAPE=STFRAME
#SET STFRAME=STFRAME+1
#DEFINE STPERI=STFRAME
#DEFINE STREPLY=STPERI+1
#DEFINE STCOUNT=STPERI+2
#DEFINE STADDR=STPERI+3
#DEFINE STBUF=STPERI+4
#SET STFRAME=STFRAME+5
BEGIN 2 3,1,STFRAME
LDX 4 STUNIT(2)
LDX 3 STTYPE(2)
NGN 6 EBADF
ALLOT 4 256(3) [ is *Fxn assigned?
LDXC 0 9 [ allot reply in word 9!
BCS OUT [ not assigned, return -ve
LDCT 0 256(3) [ move type+256 to count
ADN 0 #12 [ mode #12 = enquire
STO 0 STPERI(2)
LDN 0 1 [ 1 word
STO 0 STCOUNT(2)
LDN 0 STBUF(2) [ buffer addr
STO 0 STADDR(2)
PERI 4 STPERI(2) [ get file type
LDXC 0 STREPLY(2) [ finished?
BCC *+2 [ yup
SUSBY 4 256(3) [ assume it works
LDN 5 0 [ No red tape
NGN 7 1 [ amorphous
LDXC 0 STBUF(2) [ B0 clear if AMORPHOUS
BCC ALLO
LDN 5 #0041 [ set initial red tape
LDN 7 0 [ unshifted
ANDN 0 #7777 [ get low bits of reply
SBN 0 #12 [ is it GRAPHIC?
BZE 0 ALLO
LDN 5 #7441 [ it's a shift file
LDN 7 #74 [ set initial shift
ALLO STO 5 STREDTAPE(2) [ save red tape
LDN 6 2004 [ record length for *FHn is 2004
LDN 0 #22 [ block read?
BXU 0 STREAD(2),*+2 [ jif not
LDN 6 2048 [ read whole block
STACK 1
LDX 0 STFD(2)
STO 0 SXPAR1(1) [ fd wanted
STO 7 SXPAR2(1) [ initial shift
STO 3 SXPAR3(1) [ device type
STO 4 SXPAR4(1) [ Unit #
LDX 0 STREAD(2) [ get read mode
STO 0 SXPAR5(1)
LDX 0 STWRITE(2) [ get write mode
STO 0 SXPAR6(1)
STO 6 SXPAR7(1) [ buffer length
CALL 1 GPFDALLOC
BNG 6 OUT
# FDALLOC leaves FDESC in X3
LDX 0 FDWRITE(3) [ can we write?
BZE 0 READ [ if not don't want red tape
LDX 5 STREDTAPE(2) [ get red tape
BZE 5 OUT [ nothing to do if none
STO 5 FDREDTAPE(3) [ set red tape
LDN 0 FLAGWRITE
ANDX 0 FDFLAGS(3) [ are we in read mode?
BNZ 0 WRITE [ need space for redtape if not
# For block mode we need to set FDRECORD to point to
# start of buffer and zero out the length field.
READ LDN 0 #22 [ block read?
BXU 0 STREAD(2),OUT [ jif not
LDX 1 FDADDR(3) [ get buffer addr
STO 1 FDRECORD(3) [ save as next rec for blockmode
STOZ 0(1) [ which is empty
BRN OUT
# Leave space in buffer for red tape
WRITE LDN 5 4 [ 4 chars used in buf
ADS 5 FDCHARS(3)
LDN 5 1
ADS 5 FDNEXT(3) [ next word for output
OUT END 2 1,0
#END
#FINISH