100H: /* ARITHMETIC DERIVATIVE - BASED ON THE BASIC SAMPLE */ /* RETURNS TRUE IF A < B, FALSE OTHERWISE WITH A AND B TREATED AS SIGNED */ SIGNED$LT: PROCEDURE( A, B )BYTE; DECLARE ( A, B ) ADDRESS; IF ( A + 32768 ) < ( B + 32768 ) THEN RETURN 0FFH; ELSE RETURN 0; END SIGNED$LT ; /* RETURNS A / B WITH A AND B TREATED AS SIGNED */ SIGNED$DIV: PROCEDURE( AIN, BIN )ADDRESS; DECLARE ( AIN, BIN )ADDRESS; DECLARE ( A, B, SIGN )ADDRESS; SIGN = 1; A = AIN; B = BIN; IF SIGNED$LT( A, 0 ) THEN DO; SIGN = - SIGN; A = - A; END; IF SIGNED$LT( B, 0 ) THEN DO; SIGN = - SIGN; B = - B; END; RETURN ( A / B ) * SIGN; END SIGNED$DIV ; /* CP/M BDOS SYSTEM CALL AND I/O ROUTINES */ BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END; PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END; PR$SIGNED$NUMBER: PROCEDURE( N ); /* PRINTS A SIGNED NUMBER */ DECLARE N ADDRESS; DECLARE V ADDRESS, N$STR ( 9 )BYTE, W BYTE; IF SIGNED$LT( N, 0 ) THEN V = - N; ELSE V = N; DO W = 0 TO LAST( N$STR ); N$STR( W ) = ' '; END; W = LAST( N$STR ); N$STR( W ) = '$'; N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); DO WHILE( ( V := V / 10 ) > 0 ); N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); END; IF SIGNED$LT( N, 0 ) THEN N$STR( W := W - 1 ) = '-'; CALL PR$STRING( .N$STR ); END PR$SIGNED$NUMBER; /* TASK */ DECLARE ( C, N, L, F, Z ) ADDRESS; DO C = 1 TO 200; N = C - 100; L = 0; F = 3; IF SIGNED$LT( N, 0 ) THEN Z = - N; ELSE Z = N; DO WHILE Z >= 2; DO WHILE Z MOD 2 = 0; L = L + SIGNED$DIV( N, 2 ); Z = Z / 2; END; IF F <= Z THEN DO; DO WHILE Z MOD F = 0; L = L + SIGNED$DIV( N, F ); Z = Z / F; END; F = F + 2; END; END; CALL PR$SIGNED$NUMBER( L ); IF C MOD 10 = 0 THEN CALL PR$NL; END; EOF