The Damm algorithm is a checksum algorithm which detects all single digit errors and adjacent transposition errors.



The algorithm is named after H. Michael Damm.



Task

Verify the checksum, stored as last digit of an input.



100H:
 
/* DAMM CHECKSUM FOR DECIMAL NUMBER IN GIVEN STRING */
CHECK$DAMM: PROCEDURE (PTR) BYTE;
    DECLARE PTR ADDRESS, CH BASED PTR BYTE;
    DECLARE DAMM DATA
        ( 0,3,1,7,5,9,8,6,4,2,
          7,0,9,2,1,5,4,8,6,3,
          4,2,0,6,8,7,1,3,5,9,
          1,7,5,0,9,8,3,4,2,6,
          6,1,2,3,0,4,5,9,7,8,
          3,6,7,4,2,0,9,5,8,1,
          5,8,6,9,7,2,0,1,3,4,
          8,9,4,5,3,6,2,0,1,7,
          9,4,3,8,6,1,7,2,0,5,
          2,5,8,1,4,3,6,7,9,0 );
    DECLARE I BYTE;
    I = 0;
    DO WHILE CH <> '$';
        I = DAMM((I*10) + (CH-'0'));
        PTR = PTR + 1;
    END;
    RETURN I = 0;
END CHECK$DAMM;
 
/* CP/M BDOS CALLS */
BDOS: PROCEDURE (FN, ARG);
    DECLARE FN BYTE, ARG ADDRESS;
    GO TO 5;
END BDOS;
 
PRINT: PROCEDURE (STR);
    DECLARE STR ADDRESS;
    CALL BDOS(9, STR);
END PRINT;
 
/* TESTS */
DECLARE TEST (4) ADDRESS;
TEST(0) = .'5724$';
TEST(1) = .'5727$';
TEST(2) = .'112946$';
TEST(3) = .'112949$';
 
DECLARE N BYTE;
DO N = 0 TO LAST(TEST);
    CALL PRINT(TEST(N));
    CALL PRINT(.': $');
    IF CHECK$DAMM(TEST(N)) THEN
        CALL PRINT(.'PASS$');
    ELSE
        CALL PRINT(.'FAIL$');
    CALL PRINT(.(13,10,'$'));
END;
 
CALL BDOS(0,0);
EOF