// Free BCPL - LIBHDR Header for all BCPL programs Version 1.5 

global $(GLOB     // params are given for functions, * marks functions that 
                  // will only work with a private RTS (-p) or FBMINRTS (-t)

START        : 1  // ()             - user-defined entry point 
STOP         : 2  // (code)         - stop program with exit code
STACKBASE    : 3  // ()             - return base of BCPL stack
STACKTOP     : 4  // ()             - return top of BCPL stack
GLOBALBASE   : 5  // ()             - return base of BCPL globals
GLOBALTOP    : 6  // ()             - return top of BCPL globals
PROGBASE     : 7  // ()             - return base of program
PROGTOP      : 8  // ()             - return top of program
TERMINATOR   : 9  // #              - set to terminating char of READSTRING

FINDINPUT    : 10 // (name)         - open file for input resultis stream no
FINDOUTPUT   : 11 // (name)         - open file for output resultis stream no
ENDREAD      : 12 // ()             - close current input stream
ENDWRITE     : 13 // ()             - close current output stream
REWIND       : 14 // ()             - rewind current input stream
SEEKPOS      : 15 // (st,pos,hi,lo) - seek on stream st, to offset from pos
SELECTINPUT  : 16 // (st)           - select stream st for input
SELECTOUTPUT : 17 // (st)           - select stream st for output
INPUT        : 18 // ()             - return current input stream no
OUTPUT       : 19 // ()             - return current output stream no

RDCH         : 20 // ()             - read char from current input stream
WRCH         : 21 // (char)         - write char to current output stream
BINRDCH      : 22 // ()             - read char without CRLF -> *N conversion
BINWRCH      : 23 // (char)         - write char without *N -> CRLF conversion
UNRDCH       : 24 // ()             - unread last char (only once)
READREC      : 25 // (buf)          - read record into buf (rec has 2-byte len)
WRITEREC     : 26 // (buf,len)      - write record of specified len from buf 
READSTRING   : 27 // (str,term)     - read string up to *N char or term char
READNUMBER   : 28 // (radix)        - read number of radix specified
READN        : 29 // ()             - read decimal number

WRITED       : 30 // (n,d)          - write decimal number n with d digits width
WRITEOCT     : 31 // (n,d)          - write octal number n with d digits width
WRITEHEX     : 32 // (n,d)          - write hex number n with d digits width
WRITEN       : 33 // (n)            - write decimal number n in minimum width
WRITEO       : 34 // (n)            - write octal number n in 6 digits width
WRITEH       : 35 // (n)            - write hex number n in 4 digits width
WRITES       : 36 // (str)          - write string str with no padding
WRITEF       : 37 // (fmt,a,...)    - write params formatted by string fmt
NEWLINE      : 38 // ()             - write a new line character
NEWPAGE      : 39 // ()             - write a new page character

WRITESTRING  : 40 // (str,w)        - write string str right-padded to w chars
PACKSTRING   : 41 // (v,str)        - pack char-per-word from v into string str
UNPACKSTRING : 42 // (str,v)        - unpack string str into char-per-word in v 
COPYSTRING   : 43 // (s1,s2,idx)    - copy string s2 offset idx to string s1
EQUALSTRING  : 44 // (s1,s2)        - return true if strings s1 and s2 are same
MEMCMP       : 45 // (a,i,b,j,l)    - comp a%i & b%j by length l, res -1,0,1
MEMCPY       : 46 // (a,i,b,j,l)    - copy b%j by length l to a%i
MEMSET       : 47 // (m,i,v,l)      - set m%i by length l to value v
ASCIIN       : 48 // (str,n)        - scan string str%n... for decimal number 
ASCIINUMBER  : 49 // (radix,str,n)  - scan string str%n... for number in radix

ASCIIZ       : 50 // (azstr,str)    - make asciiz string from BCPL string str
ADDEXTN      : 51 // (name,ext)     - append ext string to name string
MAXVEC       : 52 // ()             - resultis maximum vector available on heap
GETVEC       : 53 // (len)          - get vector of length len from heap
FREEVEC      : 54 // (v)            - return vector v to heap
GETARGS      : 55 // ()             - return v - v!1,v!2,... args, v!0 is number
GETDATE      : 56 // (v)            - v!0:=year, v!1:=mon, v!2:=day, v!3:=wkday
GETTIME      : 57 // (v)            - v!0:=hour, v!1:=min, v!2:=sec, v!3:=1/100s
LEVEL        : 58 // ()             - resultis current BCPL stack frame base
LONGJUMP     : 59 // (lev,lab)    * - resets stack to lev and jumps to lab

GETBYTE      : 60 // (v,i)          - resultis the ith byte of vector v
PUTBYTE      : 61 // (v,i,b)        - puts byte b into the ith byte of v
DATE         : 62 // (str)          - return date string in form "Sun 18-11-90"
TIMEOFDAY    : 63 // (str)          - return time string in form "14:23:45"
CAPITALCH    : 64 // (char)         - resultis char where a-z is made A-Z
STARTIO      : 65 // ()             - (re-)initialises heap and i/o streams
ENDIO        : 66 // ()             - closes down all i/o and heap
SPAWN        : 67 // (p,c)          - spawns prog p with cmdline c (c&p strings)
COMMAND      : 68 // (c)            - spawns command.com with cmdline c (string)
GETENV       : 69 // (s,n)          - returns env var named n in s (n&s strings)

MULDIV       : 70 // (a,b,c)        - resultis (a*b)/c with remainder in result2
RESULT2      : 71 // #              - see muldiv() etc.
DOS          : 72 // (ax,bx,cx)     - resultis ax after int 21h of params
DOSIO        : 73 // (ax,bx,cx,dx)  - resultis ax from int 21h or -ve ax if CF
GETSEG       : 74 // (seg)          - resultis es (seg=0), ds/ss (1) or cs (2)
SETES        : 75 // (segval)       - set es to segval
GETESBYTE    : 76 // (off)          - resultis byte at es:off
PUTESBYTE    : 77 // (off,byte)     - put byte into es:off
GETESWORD    : 78 // (off)          - resultis word at es:off
PUTESWORD    : 79 // (off,word)     - put word into es:off

FARGETBYTE   : 80 // (seg,off)      - resultis byte at seg:off
FARGETWORD   : 81 // (seg,off)      - resultis word at seg:off
FARPUTBYTE   : 82 // (seg,off,byte) - put byte at seg:off
FARPUTWORD   : 83 // (seg,off,word) - put word at seg:off
FARGETSTRING : 84 // (str,seg,off)  - BCPL string str set to asciiz at seg:off
IN           : 85 // (port)         - perform in instruction on port
INW          : 86 // (port)         - perform inw instruction on port
OUT          : 87 // (port,byte)    - perform out instruction on port of byte
OUTW         : 88 // (port,byte)    - perform outw instruction on port of word
GETCSSTRING  : 89 // (str,off)      - copy string str from code segment cs:off 

SWINTEXIT    : 90 // ()           * - exit from s/w int handler
SWINTSETUP   : 91 // (intno)      * - set s/w int number to use (resultis old)
SWINT        : 92 // (...)        * - use s/w int to call int handler
EXEC         : 93 // (path,mode,cblk) - dos exec function (see tech. ref.)
EXEC.SS.SAVE : 94 // #              - save space for exec()
EXEC.SP.SAVE : 95 // #              - save space for exec()
EXEC.BP.SAVE : 96 // #              - save space for exec()
APTOVEC      : 97 // (fn,len)     * - resultis fn(v,len) with vec v len long
APPENDSTRING : 98 // (s1,s2,idx)    - append string s2 offset idx to string s1

// reserved  : 99 // see PCDOSHDR
// reserved  :100 // see PCDOSHDR
// reserved  :101 // see PCDOSHDR
// reserved  :102 // see PCDOSHDR
// reserved  :103 // see PCDOSHDR
// reserved  :104 // see PCDOSHDR
// reserved  :105 // see PCDOSHDR
// reserved  :106 // see PCDOSHDR
// reserved  :107 // see PCDOSHDR
// reserved  :108 // see PCDOSHDR
// reserved  :109 // see PCDOSHDR

DEBUG        :110 // (str)          - run before start() if found (writes str)
BINARYIO     :111 // (st)           - set the stream st to binary input/output
CATCHINTVEC  :112 // (vec,func)     - set interrupt vec to point to function
CATCH.OFF.SAVE:113// #              - save space for catchintvec
CATCH.SEG.SAVE:114// #              - save space for catchintvec
CHAININTVEC  :115 // ()             - chain to the catchintvec interrupt vec
INT86        :116 // (num,buf)      - do int num regs copied from buf and back
DELETEFILE   :117 // (name)         - delete file 
// spare     :118 
// spare     :119

// reserved  :120 to :149 for rts extensions 

$)GLOB


manifest $(MAN

// some useful DOS function codes (passed in AH)
// results in AX and/or CF (functions that set CF on error marked **)

DOS.VERSION = #x30  // get DOS version number (return AL=major, AH=minor)
DOS.KEEP    = #x31  // terminate & stay resident (AL=retcode, DX=seg to free)
DOS.MKDIR   = #x39  // make directory (DX=ASCIIZ name) 
DOS.RMDIR   = #x3A  // remove directory (DX=ASCIIZ name) 
DOS.CHDIR   = #x3B  // change directory (DX=ASCIIZ name) 
DOS.CREATE  = #x3C  // create file (AL=access code, CX=attr, DX=ASCIIZ name) 
DOS.OPEN    = #x3D  // open file (AL=access code, DX=ASCIIZ name)           **
DOS.CLOSE   = #x3E  // close file (BX=file handle)                          **
DOS.READ    = #x3F  // read bytes (BX=file handle, CX=count, DX=buffer)     **
DOS.WRITE   = #x40  // write bytes (BX=file handle, CX=count, DX=buffer)    **
DOS.UNLINK  = #x41  // delete file (DX=ASCIIZ name)
DOS.LSEEK   = #x42  // seek (AL=whence, BX=file handle, CX:DX=offset)
DOS.CHMOD   = #x43  // set file attrs (AL=1, CX=attr, DX=ASCIIZ name) 
DOS.IOCTL   = #x44  // i/o control (AL=func, BX=drive/handle, CX=no bytes)  **
DOS.SETBLK  = #x4A  // modify memory block (ES=block to modify, BX=len in paras)
DOS.EXEC    = #x4B  // exec (AL=0/3, DS:DX=progname, ES:BX=execparm) see EXEC()
DOS.TERM    = #x4C  // terminate program (AL=ret code)
DOS.WAIT    = #x4D  // get return code from exec

ERR.BADFUNC     = -1    // DOS RTS error numbers
ERR.NOSUCH      = -2
ERR.NOPATH      = -3
ERR.TOOMANY     = -4
ERR.NOACCESS    = -5
ERR.BADSTREAM   = -6
ERR.BADMEMBLKS  = -7
ERR.NOMEMORY    = -8
ERR.BADADDR     = -9
ERR.BADENV      = -10
ERR.BADFORMAT   = -11
ERR.BADACCESS   = -12
ERR.BADDATA     = -13
ERR.BADDRIVE    = -15
ERR.RMCURDIR    = -16
ERR.DIFFDEV     = -17
ERR.NOMORE      = -18
ERR.EOF         = -255

UG              = 150   // first user global
UNDEFINED       = #X103 // undefined global value
BYTESPERWORD    = 2
MAXINT          = 32767
BITSPERWORD     = 16
ENDSTREAMCH     = ERR.EOF

NOSTREAMS       = 20    // maximum no of files allowed

NULLPTR         = 0     // unlikely pointer value
EOF             = #X1A  // i.e., control/Z

POS.START       = 0     // used in SEEKPOS()
POS.CURRENT     = 1
POS.END         = 2

ES              = 0     // used in GETSEG()/SETSEG()
SS.DS           = 1
CS              = 2     // note this is not program cs with resident rts! 

REGS.AX         = 0     // word offsets (!) used with INT86() buffer
REGS.BX         = 1
REGS.CX         = 2
REGS.DX         = 3
REGS.SI         = 4
REGS.DI         = 5
REGS.FL         = 6
REGS.FL.CF      = 1
REGS.FL.PF      = 4
REGS.FL.AF      = 16
REGS.FL.ZF      = 64
REGS.FL.SF      = 128
REGS.FL.TF      = 256
REGS.FL.IF      = 512
REGS.FL.DF      = 1024
REGS.FL.OF      = 2048
REGS.AL         = 0     // byte offsets (%) used with INT86() buffer
REGS.AH         = 1
REGS.BL         = 2
REGS.BH         = 3
REGS.CL         = 4
REGS.CH         = 5
REGS.DL         = 6
REGS.DH         = 7
REGS.INT86      = 6     // vec length for buffer used in INT86() call

SYSIN           = 0     // default streams 
SYSOUT          = 1
SYSERR          = 2
SYSAUX          = 3
SYSPRN          = 4

$)MAN

