the online edition of "A Programmer's Notebook" by David E. Cortesi

Previous Contents  


The programs in this book make extensive use of a library of standard code sections. These sections are inserted into the program source by the INCLUDE command developed in Chapter 6. This appendix contains the complete source text of these included code sections and documents them.

The Subroutines

The interface to each subroutine is documented in Table C-1. For example, the subroutine CmpBD takes an integer in the BC register, another in the DE register, and returns a setting of the machine flags. It preserves all the registers except for A and the flags.

SubroutineInput OutputPreserves
CheckDigitHL->byteZ true if HL->digitBC,DE,HL
CmdCharOptHL->command tailHL->x of "/x.." or 00h
A = x or 00h
Z true if "/x" found
CmdNumOptHL->command tailHL->after "/nnn"
Z true if "/" seen
Cy false if "/n" seen
CmdSlashHL->command tailHL->"/" or to 00h
Z true if "/" seen
CmpBDBC=unsigned integer
DE=unsigned integer
flags as for BC-DEBC,DE,HL
CmpDHDE=unsigned integer
HL=unsigned integer
flags as for DE-HLBC,DE,HL
DE, HL advanced
flags for last [DE]-[HL]
DE, HL advanced
flags for last [DE]-[HL]
string copy in [DE]all
DecToBinaryHL->ascii digitsbinary value in DE
HL advanced
DelimiterHL->byteZ true if [HL]=delimiter
A = byte
Div16by8A=unsigned byte
HL=unsigned integer
HL=quotient HL/A
A=remainder HL/A
DumpOututility I/O variablesoutput buffer writtenall
BC=byte count
byte replicated
FillZeroBC=byte count
00h replicated
FinishOutPututility I/O variablesoutput file closedall
GetCharutility I/O variablesA=next input byteBC,DE,HL
HexDisplayLA=byteA=Ascii display of left hex digit of byteBC,DE,HL
HexDisplayRA=byteA=Ascii display of right hex digit of byteBC,DE,HL
MoveHtoDBC=byte count
text copied
DE, HL advanced by BC
MoveHtoDelimB=byte count
text made uppercase, copied to space to first delimiter or B bytesC
HL->text of fileref
fileref formatted into FCB, Z true if o.k.BC,DE
Put9999HL=integer in 0..9999four decimal digits written via PutCharall
PutBlanknoneAsciiBlank written via call to PutCharall
PutCharA=bytebyte written to utility output file, buffer dumped if necessaryall
PutCRLFnoneCR, LF written via call to PutCharall
PutSintHL=signed integersign and 1..5 digits written via PutChar, A=count of bytes sentBC,DE,HL
PutStringHL->stringstring bytes written via calls to PutCharall
PutTabnoneTAB written via call to PutCharall
PutXXA=bytehex display of byte written via PutCharall
PutXXXXHL=unsigned integerhex display of integer written via PutCharall
PutZZ9A=integer in 0..2551..3 decimal digits written via PutChar, A=count of bytes sentBC,DE,HL
PutZZZZ9HL=unsigned integer1..5 decimal digits written via PutChar, A=count of bytes sentBC,DE,HL
BC=byte count
HL advanced to an equal byte or for BC bytes, Z true if match seenA,DE
HL advanced to a match to byte1 or byte2, A=byte foundBC,DE
SetUpInpututility I/O variablesutility input file open (can abort program)all
SetUpOutpututility I/O variables
BC->default FCB
DE->start of buffer
HL->end of buffer
utility output file open as type .$$$, buffer variables set up.all
ShiftC=byte2B=byte2, next byte from input in C and ADE,HL
byte1 written via call to PutChar, B=byte2, next input byte in A, CDE,HL
SkipWhiteHL->textHL advanced to non-tab, non-blank byte, A=byteBC,DE
SRLDEDE=unsigned integerinteger shifted right with 0-bit in m.s.b.AF,BC,HL
StringLengthHL->stringA=length of stringBC,DE,HL
Type9999HL=integer in 0..9999four decimal digits typed at consoleall
TypeBlanknoneblank typed at consoleall
TypeCharA=bytebyte typed at consoleall
TypeCRLFnoneCR, LF typed at cons.all
TypeMessageDE->message,"$"message typed at cons.all
TypeSintHL=signed integersign, 1..5 digits typed at console, A=count of bytes typed.BC,DE,HL
TypeXXA=bytehex display of byte typed at consoleall
TypeXXXXHL=unsigned integerfour hex digits typed at consoleall
TypeZZ9A=integer in 0..2551..3 digits typed at console, A=count of digits typedBC,DE,HL
TypeZZZZ9HL=unsigned integer1..5 digits typed at console, A=count of digits typedBC,DE,HL
UnpackBCDHL=unsigned integerC,D,E=five BCD digits, as 01,23,45AF,B,HL
UpperCaseA=byteif byte is lowercase, A=uppercase byteBC,DE,HL
WhiteSpaceHL->byteA=byte, Z true if it is a blank or TAB.BC,DE,HL
Table C-1. Summary of the use and calling interface to each included subroutine

The Include Files

The code sections are organized into six files. Each file has a filetype of ".INC" and a filename meant to suggest the kind of code sections it contains. Each file contains a number of named units. Each unit contains one or more subroutines. Table C-2 lists all the subroutines, showing for each the name of the file and the smallest section that contains it. Look up the subroutine name "CmpBD," for example. It is in the file ARITHLIB.INC, which is displayed in listing C-1. The CmpBD subroutine is contained in the unit of the same name. If the CmpBD subroutine is to be part of a program, the program must have a line containing the command "#include Arithlib.inc,CmpBD."

SubroutineFilename (Listing)Unitname
CheckDigitTextlib (C-4)CheckDigit
CmdCharOptCmdparse (C-2)CmdCharOpt
CmdNumOptCmdparse (C-2)CmdNumOpt
CmdSlashCmdparse (C-2)CmdSlash
CmpBDArithlib (C-1)CmpBD
CmpDHArithlib (C-1)CmpDH
CmpStringTextlib (C-4)CmpString
CmpStrTextTextlib (C-4)CmpStrText
CopyStringTextlib (C-4)CopyString
DecToBinaryArithlib (C-1)DecToBinary
DelimiterTextlib (C-4)Delimiter
Div16by8Arithlib (C-1)Div16by8
DumpOutUtilio (C-6)DumpOut
FillATextlib (C-4)FillA
FillZeroTextlib (C-4)FillZero
FinishOutPutUtilio (C-6)SetUpOutput
GetCharUtilio (C-6)GetChar
HexDisplayLArithlib (C-1)HexDisplay
HexDisplayRArithlib (C-1)HexDisplay
MoveHtoDTextlib (C-4)MoveHtoD
MoveHtoDelimCmdparse (C-4)MoveHtoDelim
ParseFileRefCmdparse (C-2)ParseFileRef
Put9999Putsubs (C-3)Put9999
PutBlankPutsubs (C-3)PutCommon
PutCharUtilio (C-6)PutChar
PutCRLFPutsubs (C-3)PutCommon
PutSintPutsubs (C-3)PutDecimal
PutStringPutsubs (C-3)PutCommon
PutTabPutsubs (C-3)PutTab
PutXXPutsubs (C-3)PutXX
PutXXXXPutsubs (C-3)PutXXXX
PutZZ9Putsubs (C-3)PutDecimal
PutZZZZ9Putsubs (C-3)PutDecimal
ScanForATextlib (C-4)ScanForA
ScanForBCCmdParse (C-2)ScanForBC
SetUpInputUtilio (C-6)SetUpInput
SetUpOutputUtilio (C-6)SetUpOutput
ShiftUtilio (C-6)Shift
ShoutUtilio (C-6)Shift
SkipWhiteTextlib (C-4)SkipWhite
SRLDEArithlib (C-1)SRLDE
StringLengthTextlib (C-4)StringLength
Type9999TypeSubs (C-5)Type9999
TypeBlankTypeSubs (C-5)TypeCommon
TypeCharTypeSubs (C-5)TypeChar
TypeCRLFTypeSubs (C-5)TypeCommon
TypeMessageTypeSubs (C-5)TypeCommon
TypeSintTypeSubs (C-5)TypeDecimal
TypeXXTypeSubs (C-5)TypeXX
TypeXXXXTypeSubs (C-5)TypeXXXX
TypeZZ9TypeSubs (C-5)TypeDecimal
TypeZZZZ9TypeSubs (C-5)TypeDecimal
UnpackBCDArithlib (C-1)UnpackBCD
UpperCaseTextlib (C-4)UpperCase
WhiteSpaceTextlib (C-4)WhiteSpace
Table C-2. Organization of subroutines into .INC include files. Click the links to display the listings.

As noted in Chapter 6, the INCLUDE command allows named units to be nested within each other. The include files here are organized to take advantage of that fact. Often when the code in one unit calls upon code from another unit, the second unit is simply contained within the first one. This nesting of units is conceptually economical, but it makes it hard to document the relationship between units. After a number of experiments with tables more elaborate than Table C-1, I decided that the nesting of units could only be documented graphically.

Each of the six file listings in this appendix is preceded by a Figure that shows how the named units are nested within the file. For an example, turn to Listing C-3. It displays the code of the units in PUTSUBS.INC, and it is preceded by a Figure C-3 that shows relationships of those units graphically.

PUTSUBS contains six named units. Each one is shown in Figure C-3 as a rectangular outline. The name of a unit is shown outside its outline, at the upper left corner. The names of the subroutines contained in the unit are shown within the outline. The subroutine names end in colons. For instance, the PutCommon unit contains the code of three subroutines: PutBlank, PutCRLF, and PutString.

PutXX, one of the units in PUTSUBS, is nested inside another one (PutXXXX). If a program includes the PutXXXX unit, it will automatically include a copy of PutXX as well, because the smaller unit is part of the larger one.

The PutDecimal section doesn't contain another unit, but it does include another unit. This is indicated by a broad arrow followed by a file and unit name. Figure C-3 shows that within the code of PutDecimal there is a statement "#include Arithlib.inc,UnpackBCD." Within the code of PutXX there is an include for unit HexDisplay of file ARITHLIB. The Figure also shows that the Put9999 unit has two include commands—one for UnpackBCD from ARITHLIB, and one for PutXXXX from the PUTSUBS file.

As you can see from this discussion, the Figures contained in the listings of this appendix document a number of aspects of the files far more concisely than could be done by words or tables. With them you can answer such questions as "What is included with section so-and-so?" and "If unit X is included, does unit Y need to be included also?"