Add Some BARC to Your 8080 - The Description



Name	Address         Function

CLCHR	<*>	123	Compare FIELD1 contents to FIELD2 contents;
DASNT	<*>	010	Double address plus size function entry routine;
DASXR	<*>	034	Double address plus size function execution support routine;
FRXIT	<*>	062	Function routine exit logic;
MVCHR	<*>	110	Move FIELD2 contents to FIELD1;
MVICH	<*>	207	Fill FIELD with immediate character value;
MVSYM	<*>	343	Move FIELD2 contents to FIELD 1 terminating on stop character;
NCHR	<*>	071	Logical AND MASK to FIELD;
NICH	<*>	170	Logical AND immediate character value to all bytes in FIELD;
OCHR	<*>	076	Logical OR MASK to FIELD;
OICH	<*>	175	Logical OR immediate character value to all bytes in FIELD;
SASIX	<*>	135	Single address, size and immed function execution support routine;
SASNT	<*>	000	Single address plus size function entry routine;
SWCHR	<*>	115	Swap contents of FIELD1 with contents of FIELD2;
VALAC	<*>	247	Validate alphabetic character;
VALAS	<*>	244	Validate alphabetic string of characters;
VALFX	<*>	214	Validate string function execution support routine;
VALHC	<*>	327	Validate hexadecimal character;
VALHS	<*>	324	Validate hexadecimal string of characters;
VALNC	<*>	266	Validate numeric character;
VALNS	<*>	263	Validate numeric string of characters;
VALOC	<*>	301	Validate octal character;
VALOS	<*>	276	Validate octal string of characters;
VALXC	<*>	314	Validate alphanumeric character;
VALXS	<*>	311	Validate alphanumeric string of characters;
VALXT	<*>	257	Validate string function exit logic;
XCHR	<*>	103	Logical exclusive OR MASK to FIELD;
XICH	<*>	202	Logical exclusive OR immediate character value to all bytes in FIELD;

Table 1: Alphabetical listing of BARC utility routines and their entry points. The low order addresses refer to listing 1.

CLCHR: Compare Logical Characters

The CLCHR utility routine compares two character strings byte by byte from left to right and terminates upon encountering the first inequality. The condition flags are set according to the relationship of the contents of FIELD1 to the contents of FIELD2. The possible combinations are:
	FIELD1 = FIELD2    Z=1, CY=0
	FIELD1 < FIELD2    Z=0, CY=0
	FIELD1 > FIELD2    Z=0, CY=1
Both strings must be of the same length and may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	CLCHR		Call CLCHR utility routine;
	DW	A(FIELD1)	FIELD1 address;
	DW	A(FIELD2)	FIELD2 address;
	DB	SIZ		Length of fields where 0 means a length of 256;

DASNT: Double Address plus Size, Function Entry Support Routine

The DASNT support routine is used to save the user's register contents and load the parameters following the original user's utility routine call. This routine is called by the function execution routine which was called by the user. The calling sequence for this support routine is:
	XTHL			UDRHL to TOS;USRRET to DRHL;
	CALL	DASNT		Call DASNT routine;
Upon return from the DASNT support routine the user's registers have been saved on the stack and the working registers contain the following:

DRBC=First address parameter following user's call.
DRDE=Second address parameter following user's call.
SRH=Length parameter.
TOS=True user's return point to byte following parameters.

Exit from a function routine which has used DASNT should only be effected by jumping to the FRXIT routine.

DASXR: Double Address plus Size, Function Execution Support Routine

The DASXR support routine is used as a generalized execution routine for the various functions which require two address parameters and a size parameter, operate on the data from left to right and replace the contents of the first operand with the result. (Note: Both fields must be of the same length and may be up to 256 bytes long.) DASXR simply controls the execution of the function by performing the housekeeping and looping involved in controlling the execution. DASXR uses DASNT as its entry logic to preserve the contents of the user registers and to load the parameter values into the working registers. On each iteration of the loop in DASXR it loads the next byte of FIELD2 into SRL and the next byte of FIELD1 into SRA (the accumulator) before turning control over to the logic which will operate on the data. DASXR increments the addresses of the fields and loops until the count is consumed or until the calling program terminates its operation. Exit from DASXR is through the FRXIT exit logic which restores the user registers, with the exception of the program counter and flags, to their original contents. Here's an example of the use of DASXR as the controlling logic for an addition routine where the operands are stored least signtficant byte first:
  1. In line coding in user program
    	CALL	USRTN		Call user written ADD logic;
    	DW	A(FIELD1)	Address of augend and sum;
    	DW	A(FIELD2)	Address of addend;
    	DB	SIZ		Length of fields where 0 means a length of 256;
    
  2. Subroutine in user program called by 1 above
    USRTN	ORA	A		Clear carry;
    	CALL	DASXR		Call DASXR support routine;
    	ADC	L		Add SRL and CARRY to accumulator;
    	DAA			(Decimal adjust only if data is decimal);
    	RET			Return to DASXR support routine;
    
  3. If a premature or abnormal termination of the loop is required as in the CLCHR function routine it should take the following form:
    USRTN	xxx			Setup instructions, if any;
    	CALL	DASXR		Call DASXR support routine;
    	yyy			Function execution instructions
    	yyy			   as required;
    	R(cond)			Conditional return to DASXR to continue;
    	zzz			Instructions to be executed if the condition
    	zzz			   is not met;
    	POP	H		Clear return address to DASXR from Stack;
    	JMP	FRXIT		Jump to the function exit logic for
    				   abnormal or premature return;
    
The calls to DASXR in 2 and 3 are not used as calls to which a return will be made. They are used to pass the address of the function execution instructions which follow the calls to the DASXR support routine. DASXR stores the passed address of the function execution instructions in the address portion of a call instruction within itself and executes the call within itself once for each iteration of the control loop.
It is very important to realize that the call to DASXR cannot be inline in the coding but must be called by the logic which is called by the inline parameter passing call if it is to function correctly.

FRXIT: Function Routine Exit Logic

The FRXIT routine is used to restore the contents of the original user's registers and to return to the proper address location, following the parameters of the original user's call. FRXIT should always be used when exiting from a function routine which utilized the DASNT or SASNT function entry routines. This logic is entered by jumping to it unconditionally or conditionally when it is desired to return to the original caller. No other commands are required prior to the jump to prime this routine. All registers except the program counter and flags are restored to their original contents prior to returning; the flags are returned to the caller as set by the function execution routine.

MVCHR: Move Characters

The MVCHR utility routine will move a character string up to 256 bytes long from one location to another. The formal of the calling sequence for this utility routine is:
	CALL	MVCHR		Call MVCHR utility routine;
	DW	A(DESTIN)	Address of the destination field;
	DW	A(SOURCE)	Address of the source field;
	DB	SIZ		Length of the fields where 0 is the length code for 256;

MVICH: Move Character Immediate (Character Fill)

The MVICH utility routine will move a specified byte value known as the immediate character value (ICV), to every byte location in a specified field. The specified field may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	MVICH		Call MVICH utility routine;
	DW	A(FIELD)	Address of the receiving field;
	DB	SIZ		Length of the field where 0 means a length of 256;
	DB	ICV		Immediate character value;

MVSYM: Symbolic Move

The MVSYM utility routine will move a character string up to 256  bytes long from one location to another and stop moving when one of two conditions is met:
  1. A character from the sending area is encountered which is equal in value to the ICV known as the stop character (Note: The stop character is not moved).
or
  1. The entire string has been moved according to the specified size and no character was found which was equal in value to the ICV stop character.
In either event when return is made to the user the accumulator (SRA) contains a count of the characters moved. Caution must be exercised when strings of length 256 are moved using MVSYM because if the first character in the string is a stop character, the length moved will be zero and when 256 characters are moved without encountering a stop character, the length moved will also be zero since the size value for 256 is zero; therefore, whenever the length moved for a field which is 256 bytes long is zero, test the first character in the source field to determine if it is a stop character. If it is, then the length moved is really zero, otherwise the length moved is 256. The calling sequence for the MVSYM utility routine is:
	CALL	MVSYM		Call MVSYM utility routine;
	DW	A(DESTIN)	Address of the destination field;
	DW	A(SOURCE)	Address of the source field;
	DB	SIZ		Max length for the move where 0 means a length of 256;
	DB	ICV		The immediate character value is the stop character;

NCHR: Logical AND Character Strings

The NCHR utility routine will logically AND a character string called MASK to another character string known as the FIELD; the result will replace the contents of FIELD. Both strings must be of the same length, which may be up to 256 bytes. The calling sequence for this utility routine is:
	CALL	NCHR		Call NCHR utility routine;
	DW	A(FIELD)	Address of the field string;
	DW	A(MASK)		Address of the mask string;
	DB	SIZ		Length of the fields where 0 means a length of 256;

NICH: Logical AND Characters Immediate

The NICH utility routine will logically AND a specified byte value known as the immediate character value (ICV) to every byte location in a specified FIELD. The specified FIELD may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	NICH		Call NICH utility routine;
	DW	A(FIELD)	Address of FIELD;
	DB	SIZ		Length of FIELD;
	DB	ICV		Immediate character value;

OCHR: Logical OR Character Strings

The OCHR utility routine will logically OR a character string called MASK to another character string called the FIELD; the result will replace the contents of the FIELD. Both strings must be of the same length and may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	OCHR		Call OCHR utility routine;
	DW	A(FIELD)	Address of the FIELD;
	DW	A(MASK)		Address of the MASK;
	DB	SIZ		Length of the fields where 0 means a length of 256;

OICH: Logical OR Characters Immediate

The OICH utility routine will logically OR a specified byte value known as the immediate character value (ICV) to every byte location in a specified FIELD. The specified FIELD may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	OICH		Call OICH utility routine;
	DW	A(FIELD)	Address of the FIELD;
	DB	SIZ		Length of the FIELD where 0 means a length of 256;
	DB	ICV		Immediate character value;

SASIX: Single Address, Size and Immediate Character, Function Execution Support Routine

The SASIX support routine is used as a generalized execution routine for the various functions which require one address parameter, a size parameter for one to 256 bytes, and an immediate character value which is used to operate upon the contents of the field, operate on the data from left to right and replace the contents of the field with the result. SASIX does not actually perform the required function; that is the responsibility of the programmer who is using SASIX. SASIX simply controls the execution of the function by performing the housekeeping and looping involved in controlling the execution. SASIX uses SASNT as its entry logic to preserve the contents of the user registers and to load the parameters into the working registers. The immediate character value is loaded into SRL and retained there until altered by the programmer. On each iteration of the loop in SASIX it loads the next byte of the field into accumulator before turning control over to the logic which will operate on the data. SASIX increments the address of the field and loops until the count is consumed or until the programmer busts out of its control. Exit from SASIX is through the FRXIT exit logic which restores the user registers with the exception of the program counter and flags to their original contents. An example of the use of SASIX as the controlling logic for a routine which translates all the spaces in a field to zeros is as follows:
  1. Inline coding in user program:
    	CALL	USRTN		Call user written logic;
    	DW	A(FIELD)	Address of field to be translated;
    	DB	SIZ		Length of field to be translated;
    	DB	' '		Immediate character value of a space;
    
  2. Subroutine in user program called by the above sequence:
    USRTN	CALL	SASIX		Call SASIX support routine;
    	CMP	L		Compare immediate character value (in SRL) to accumulator;
    	RNZ			Return to SASIX if not equal;
    	MVI	A,'0'		Move immediate value of character '0' to accumulator, replacing
    				  occurrence of the immediate character value;
    	RET			Return to SASIX;
    
  3. Should an abnormal or premature return be required, for example, in a situation such as in 2 above where it is desired to translate only the leading spaces into zeros and then stop, it should take the following form:
    USRTN	XXX			Setup instructions, if any;
    	CALL	SASIX		Call SASIX utility routine;
    	CMP	L		Compare SRL to accumulator;
    	MVI	A,'0'		Move a character zero to accumulator to replace
    				  immediate character value;
    	RZ			Return to SASIX if accumulator is equal to the
    				  immediate character value;
    	POP	H		Else clear return to SASIX from Stack;
    	JMP	FRXIT		Jump to exit logic before count is zero;
    
The calls to SASIX above are not used as calls to which a return will be made. They are used to pass the address of the function execution instructions which follow the calls to the SASIX support routine. SASIX stores the passed address of the function execution instructions in the address portion of a call instruction within itself and executes the call within itself once for each iteration of the control loop.
It is very important to realize that the call to SASIX cannot be inline in the coding but must be called by the logic which is called by the inline parameter passing call if it is to function correctly.

SASNT: Single Address Plus Size, Function Entry Routine

The SASNT routine is used to save the user register contents and load the parameters following the original user's utility routine call. This routine is called by the function execution routine which was called by the user. The calling sequence for this support routine is:
	XTHL			UDRHL to TOS; USRRET to DRHL;
	CALL	SASNT		Call SASNT support routine;
Upon return from the SASNT support routine the user's register contents have been saved on the stack and the working registers contain the following:
DRDE=Address parameter following user's call;
SRH=Length or size parameter;
TOS=True user's return point to byte following parameters;
Exit from a function execution routine which has used SASNT should only be effected by jumping to the FRXIT routine which is described above.

SWCHR: Swap Character Strings

The SWCHR utility routine will swap two character strings. The contents of FIELD1 replace the contents of FIELD2 while the contents of FIELD2 are replacing the contents of FIELD1. This routine can be used when writing internal sort routines. Both strings must be of the same length and may be up to 256 bytes long. The calling sequence for the SWCHR routine is:
	CALL	SWCHR		Call SWCHR utility routine;
	DW	A(FIELD1)	Address of one of the fields to be swapped;
	DW	A(FIELD2)	Address of the other field to be swapped;
	DB	SIZ		Length of the fields where 0 means a length of 256;

VALAC: Validate Alphabetic Character

The VALAC utility routine tests the character in the accumulator to determine if it is an alphabetic character or a space. Upon return, if the ZERO flag is equal to a 1, the character is valid as tested; if the ZERO flag is 0, it is invalid. The calling sequence for this routine is:
	CALL	VALAC		Call VALAC utility routine;

VALAS: Validate Alphabetic Character String

The VALAS routine tests the characters in a specified string to determine if they are all alphabetic characters or spaces. Examination proceeds from left to right one byte at a time; the routine terminates if an invalid character is found. Upon return, the Z flag is 1, all characters in the string satisfied the validation requirements; otherwise the Z flag is 0. The calling sequence for this utility routine is:
	CALL	VALAS		Call VALAS utility routine;
	DW	A(FIELD)	Address of the string to be tested;
	DB	SIZ		Length of the field to be tested;

VALFX: Validate String, Function Execution Support Routine

The VALFX Support routine is used as a generalized execution routine for the various string validation functions. These functions require a single address parameter for the field to be validated and a size parameter which specifies the length of the field which may be up to 256 bytes long. The contents of the field are not changed. VALFX does not actually perform the required function, for that is the responsibility of the programmer who is using VALFX. VALFX simply supplies the characters in the field one at a time, starting with the lefthand end, in the accumulator and controls the execution of the function by performirig the housekeeping and looping involved in controlling the execution. VALFX increments the address of the field and loops until the count is consumed or the character which is invalid to the fest is encountered. If the programmer who has coded the test logic returns to VALFX with a Z flag value of 1, VALFX will supply the next character in the string; otherwise it terminates execution and exits via FRXIT to the calling point with a Z flag value of 0. If all characters in the string were valid, return is made to the calling point with the Z flag equal to 1 via FRXIT. VALFX uses SASNT as its entry logic to preserve the contents of the user registers and to load the parameters into the working registers; FRXIT is used as the exit logic to restore the user registers, with the exception of the program counter and flags, to their original contents. An example of the use of VALFX as the controlling logic for a routine which validates that all of the characters in a field are letters of the Greek alphabet, as implemented on the Digital Group System, would be as follows:
  1. Inline coding in user program:
    	CALL	USRTN		Call user written logic;
    	DW	A(FIELD)	Address of field to be validated;
    	DB	SIZ		Length of field to be validated where 0 means a length of 256;
    
  2. 2. Subroutine in user program called by 1 above:
    USRTN	CALL	VALFX		Call VALFX function execution routine;
    	CPI	'α'		Compare accumulator to a Greek alpha;
    	RC			Return if accumulator less;
    	CPI	'Ω'		Compare accumulator to an omega, end of Greeks;
    *	RZ			Return if accumulator equal to omega, valid;
    *	RNC			Return if accumulator greater than omega, invalid;
    *	CMP	A		Force Z=1, if 'α' <= accumulator <= 'Ω'; valid;
    *	RET			Return to VALFX with valid conditions;
    
    Note: For range of value tests like this one the instructions marked with asterisks (*) above may be replaced by the following instruction which jumps to an identical instruction sequence within the validation utility routines:
    	JMP	VALXT		Jump to the validation test logic;
    
  3. If it were desired to determine that the field to be validated contained only Greek alphas and omegas and nothing else, the subroutine in the user program called by 1 above would be as follows:
    USRTN	CALL	VALFX		Call VALFX function execution routine;
    	CPI	'α'		Compare accumulator to an alpha;
    	RZ			Return if equal;
    	CPI	'Ω'		Compare accumulator to an omega;
    	RET			Return to VALFX with conditions set;
    
The preceding calls to VALFX are not used as calls to which a return will be made. They are used to pass the address of the function execution instructions which follow the calls to the VALFX support routine. VALFX stores the passed address of the function execution instructions in the address portion of a call instruction within itself and executes that call once for each iteration of the control loop.
It is very important to realize that the call to VALFX cannot be inline in the coding but must be called by the logic which is called by the inline parameter passing CALL if it is to function correctly.

VALHC: Validate Hexadecimal Digit Character

The VALHC routine tests the character in the accumulator to determine if it is one of the 16 characters (0 to 9 or A to F) which are used to represent radix 16 (hexadecimal) digits. Upon return, if the Z flag is 1, the character in the accumulator is a hexadecimal digit; otherwise Z is 0. The calling sequence for this utility routine is:
	CALL	VALHC		Call VALHC utility routine;

VALHS: Validate Hexadecimal Digit String

The VALHS routine tests the characters in a specified string to determine if they are all valid hexadecimal digits. Examination proceeds from left to right one byte at a time; the routine terminates if an invalid character is found. Upon return, if the Z flag is 1, all characters in the string were hexadecimal digits; otherwise the Z flag is 0. The calling sequence for this utility routine is:
	CALL	VALHS		Call VALHS utility routine;
	DW	A(FIELD)	Address of the field to be validated;
	DB	SIZ		Length of the field where 0 means a length of 256;

VALNC: Validate Numeric Character

The VALNC routine tests the character in the accumulator to determine if it is one of the digits in the decimal numbering system. Upon return, if the Z flag is 1, the character in the accumulator is one of the digits 0 through 9, otherwise the Z flag is 0. The calling sequence for this utility routine is:
	CALL	VALNC		Call VALNC utility routine;

VALNS: Validate Numeric String

The VALNS routine tests the characters in a specified string to determine if they are all valid decimal digits. Examination proceeds from left to right one byte at a time; the routine terminates if an invalid character is found. Upon return, if the Z flag is 1, all of the characters in the field were valid decimal digits; otherwise the Z flag is 0. The calling sequence for this utility routine is:
	CALL	VALNS		Call VALNS utility routine;
	DW	A(FIELD)	Address of the field to be validated;
	DB	SIZ		Length of the field where 0 means a value of 256;

VALOC: Validate Octal Character

The VALOC routine tests the character in the accumulator to determine if it is one of the digits in the octal numbering system. Upon return, if the Z flag is 1, the character in the accumulator is a valid octal digit; otherwise Z is 0. The calling sequence for this utility routine is:
	CALL	VALOC		Call VALOC utility routine;

VALOS: Validate Octal String

The VALOS routine tests the characters in a specified string to determine if they are all valid octal digits. Examination proceeds from left to right one byte at a time; the routine terminates if an invalid character is found. Upon return, if the Z flag is 1, all characters in the string were found to be valid octal digits; otherwise Z is set to 0. The calling sequence for this utility routine is:
	CALL	VALOS		Call VALOS utility routine;
	DW	A(FIELD)	Address of the field to be validated;
	DB	SIZ		Length of the field where 0 means a length of 256;

VALXC: Validate Alphanumeric Character

The VALXC routine tests the character in the accumulator to determine if it is one of the characters A to Z, 0 to 9, or space. Upon return, if the Z flag is equal to 1, the character in the accumulator satisfied the validity requirements; otherwise Z is set to 0. The calling sequence for this utility routine is:
	CALL	VALXC		Call VALXC utility routine;

VALXS: Validate Alphanumeric String

The VALXS routine tests the characters in a specified string to determine if they are all alphabetics, numerics or spaces. Examination proceeds from left to right one byte at a time; the routine terminates if an invalid character is encountered. Upon return, if the Z flag is equal to 1, all of the characters in the string satisfied the test conditions; otherwise Z is set to 0. The calling sequence for this utility routine is:
	CALL	VALXS		Call VALXS utility routine;
	DW	A(FIELD)	Address of the field tobe validated;
	DB	SIZ		Length of the field where 0 means a length of 256;

VALXT: Validate Test Function Exit Logic

The VALXT logic is used to set the condition codes when a validation test is testing for a closed range of values. This routine is entered by a jump command immediately following the upper limit compare, assuming of course that the upper limit is tested last. VALXT forces the Z flag to have a value of 1 when the tested character falls within the range. See the example given in the VALFX routine description.

XCHR: Logical Exclusive OR Characters

The XCHR utility routine will logically exclusive OR a character string known as the MASK to another character string known as the FIELD; the result will replace the contents of the field. Both strings must be of the same length and may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	XCHR		Call XCHR utility routine;
	DW	A(FIELD)	Address of the FIELD and the result;
	DW	A(MASK)		Address of the MASK string;
	DB	SIZ		Length of the fields where 0 means a length of 256;

XICH: Logical Exclusive OR Characters Immediate

The XICH utility routine will logically exclusive OR a specified byte value known as the immediate character value (ICV) to every byte location in a specified field. The specified field may be up to 256 bytes long. The calling sequence for this utility routine is:
	CALL	XICH		Call XICH utility routine;
	DW	A(FIELD)	Address of the field;
	DB	SIZ		Length of the field where 0 means a length of 256;
	DB	ICV		Immediate character value;

Scanned by Werner Cirsovius
September 2002
© BYTE Publications Inc.