100H: DECLARE MAX$REP LITERALLY '32'; DECLARE FALSE LITERALLY '0'; DECLARE TRUE LITERALLY '1'; DECLARE CR LITERALLY '0DH'; DECLARE LF LITERALLY '0AH'; /* CP/M BDOS SYSTEM CALL */ BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; /* PRINTS A BYTE AS A CHARACTER */ PRINT$CHAR: PROCEDURE( CH ); DECLARE CH BYTE; CALL BDOS( 2, CH ); END; /* PRINTS A $ TERMINATED STRING */ PRINT$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; /* PRINTS A BYTE AS A NUMBER */ PRINT$BYTE: PROCEDURE( N ); DECLARE N BYTE; DECLARE ( V, D2, D3 ) BYTE; V = N; D3 = V MOD 10; IF ( V := V / 10 ) <> 0 THEN DO; D2 = V MOD 10; IF ( V := V / 10 ) <> 0 THEN CALL PRINT$CHAR( '0' + V ); CALL PRINT$CHAR( '0' + D2 ); END; CALL PRINT$CHAR( '0' + D3 ); END PRINT$BYTE; /* PRINTS A FIXED LENGTH STRING */ PRINT$SUBSTRING: PROCEDURE( S$PTR, LEN ); DECLARE S$PTR ADDRESS, LEN BYTE, S BASED S$PTR ( MAX$REP )BYTE; DECLARE S$POS BYTE; DO S$POS = 0 TO LEN - 1; CALL PRINT$CHAR( S( S$POS ) ); END; END PRINT$SUBSTRING; /* RETURNS THE LENGTH OF A $ TERMINATED STRING */ STR$LENGTH: PROCEDURE( S$PTR )BYTE; DECLARE S$PTR ADDRESS, S BASED S$PTR ( MAX$REP )BYTE; DECLARE RESULT BYTE; RESULT = 0; DO WHILE( S( RESULT ) <> '$' ); RESULT = RESULT + 1; END; RETURN RESULT; END STR$LENGTH; /* RETURNS THE LENGTH OF THE LONGEST REP-STRING IN S$PTR, */ LONGEST$REP$STRING: PROCEDURE( S$PTR )BYTE; DECLARE S$PTR ADDRESS, S BASED S$PTR ( MAX$REP )BYTE; DECLARE ( S$LEN, RESULT, S$POS, R$POS, I, FOUND ) BYTE; RESULT = 0; FOUND = FALSE; S$LEN = STR$LENGTH( S$PTR ); S$POS = ( S$LEN / 2 ) - 1; /* IF ( S$LEN / 2 ) = 0, S$POS WILL BE 255 */ DO WHILE( NOT FOUND AND S$POS < 255 ); /* AS BYTE/ADDRESS ARE UNSIGNED */ /* CHECK THE POTENTIAL REP-STRING REPEATED A SUFFICIENT NUMBER */ /* OF TIMES (TRUNCATED IF NECESSARY) EQUALS THE ORIGINAL STRING */ FOUND = TRUE; R$POS = S$POS + 1; DO WHILE( FOUND AND R$POS < S$LEN AND FOUND ); I = 0; DO WHILE( I <= S$POS AND R$POS < S$LEN AND FOUND ); FOUND = S( R$POS ) = S( I ); R$POS = R$POS + 1; I = I + 1; END; END; IF NOT FOUND THEN DO; /* HAVEN'T FOUND A REP-STRING, TRY A SHORTER ONE */ S$POS = S$POS - 1; /* S$POS WILL BECOME 255 IF S$POS = 0 */ END; END; IF FOUND THEN DO; RESULT = S$POS + 1; END; RETURN RESULT; END LONGEST$REP$STRING; DECLARE ( TEST$NUMBER, REP$STRING$LEN ) BYTE; DECLARE TESTS ( 11 )ADDRESS; TESTS( 0 ) = .'1001110011$'; TESTS( 1 ) = .'1110111011$'; TESTS( 2 ) = .'0010010010$'; TESTS( 3 ) = .'1010101010$'; TESTS( 4 ) = .'1111111111$'; TESTS( 5 ) = .'0100101101$'; TESTS( 6 ) = .'0100100$'; TESTS( 7 ) = .'101$'; TESTS( 8 ) = .'11$'; TESTS( 9 ) = .'00$'; TESTS( 10 ) = .'1$'; DO TEST$NUMBER = 0 TO LAST( TESTS ); REP$STRING$LEN = LONGEST$REP$STRING( TESTS( TEST$NUMBER ) ); CALL PRINT$STRING( TESTS( TEST$NUMBER ) ); IF REP$STRING$LEN = 0 THEN DO; CALL PRINT$STRING( .': NO REP STRING$' ); END; ELSE DO; CALL PRINT$STRING( .': LONGEST REP STRING: $' ); CALL PRINT$SUBSTRING( TESTS( TEST$NUMBER ), REP$STRING$LEN ); END; CALL PRINT$STRING( .( CR, LF, '$' ) ); END; EOF