;*; Updated on 17-Sep-92 at 5:55 AM by James A. Jarboe I V; edit time: 0:13:42
;
; TBXHS1 - Demonstrates bug in TOOLBX  hashing routine,
;
; This program will create a hash for a number and then compare that
; hash against a sequence of hashes for all numbers between that number
; and a maximum number. This program uses ESP style hashing.
;
; If a match is found withing that sequence then the bell will ring and
; the number will be output in low intensity.
;
; The bright number is the one we are checking against.
;
; [100] 17-Sep-92 by James A. Jarboe IV


       SEARCH  SYS
       SEARCH  SYSSYM


DEFINE  PRTTAB  ROW, COL
       MOVW    #<ROW_8.+COL>, D1
       TCRT
ENDM

       VMAJOR  =       1
       VMINOR  =       0
       VEDIT   =       100.            ; 17-Sep-92

       S..BOT  =       10000.          ; Starting number
       S..TOP  =       20000.          ; Top number.

; impure storage area.
;
OFINI
OFDEF   TT.HSH, 4                       ; Saved hash value.
OFDEF   TT.NEW, 4                       ; New hash value.
OFDEF   TT.NUM, 12.                     ; String.
OFDEF   TT.OCR, 4                       ; Number of matches.
OFSIZ   TT.SIZ                          ; Impure size.

; Really Demonstrate TOOLBX hashing problem.
;
START:
       PHDR    -1,0,PH$REE!PH$REU
       GETIMP  TT.SIZ, A5

       PRTTAB  -1,0                    ; Clear screen
       TYPECR  <Testing TOOLBX Hashing routine to demonstrate bug.>
       TYPECR  <Using ESP style hashing.>
       CRLF                            ; Bump line

       TYPECR  <String   Hash            Hash >
       CRLF

       MOV     #S..BOT, D3             ; Set starting number.

; Loop for string to check against.
;
5$:     CTRLC   QUIT                    ; Quit on ^C.
       CRLF                            ; Bump line
       INC     D3                      ; Bump number
       CMP     D3, #S..TOP             ; Greater than top?
       JEQ     QUIT                    ; Yes..quit.
       PRTTAB  -1,12.                  ; Set bright.
       MOV     D3, D1                  ; Set number to convert.
       LEA     A2, TT.NUM(A5)          ; Index buffer.
       DCVT    0,OT$MEM                ; Make ASCII.
       LEA     A6, TT.NUM(A5)          ; Index first string.
       MOV     #5, D6                  ; Set number of chars.
       CALL    DO.IT                   ; Do hashing and display.

       MOV     #S..BOT, D4             ; Set starting number.

; Loop to create hash for all numbers between s..bot & s..top to compare
; against number we are checking.
;
10$:
       CTRLC   99$                     ; Exit on ^C
       INC     D4                      ; Bump count.
       CMP     D3, D4                  ; Same as number we are checking.
       BEQ     10$                     ; Try another.
       CMP     D4, #S..TOP             ; At top yet?
       BEQ     99$                     ; Then stop and do next.
       MOV     D4, D1                  ; Set number/
       LEA     A2, TT.NUM(A5)          ; Index buffer.
       DCVT    0,OT$MEM                ; Make ascii.
       CLRB    @A2                     ; Clear end of buffer.
       LEA     A6, TT.NUM(A5)          ; Index number.
       MOV     #5., D6                 ; Set number of char.
       CALL    TBXHSH                  ; Call hashing.
       MOV     D6, TT.NEW(A5)          ; Save number.
       CMP     D6, TT.HSH(A5)          ; Same as number we are testing?
       BNE     10$                     ; No..try next.
       PRTTAB  -1,11.
       LEA     A6, TT.NUM(A5)          ; Yes..index buffer.
       MOV     #5, D6                  ; Set size.
       CALL    DO.IT                   ; Display hash match.
       MOV     #7, D1                  ; Ring bell.
       TTY
       ADD     #1, TT.OCR(A5)          ; Bump match count.
       BR      10$                     ; Try again.

99$:
       JMP     5$                      ; Try next number sequence.


QUIT:   CRLF
       TYPE    <Total Duplicates = >
       MOV     TT.OCR(A5), D1
       DCVT    0,OT$TRM
       CRLF
       EXIT


; Do hashing and display.
;
; Incoming:
;               D6 =: Number of chars to hash
;               A6 -> Indexes buffer of string to hash.
; Outgoing:
;               D6 =: Hash total of string.
;               A6 -> Indexes end of buffer.
;
DO.IT:
       PUSH    A6                      ; Save buffer address.
       CALL    TBXHSH                  ; Call hashing routine.
       MOV     D6, D1                  ; Save hash total
       MOV     D1, TT.HSH(A5)          ; Save hash total.
       POP     A6                      ; Restore buffer address.
       TTYL    @A6                     ; Output string.
       TYPE    < = >                   ; Output seperator.
       DCVT    0, OT$TRM               ; Output in decimal.
       TAB                             ;
       OCVT    0,OT$TRM                ; Output in current base.
       CRLF                            ; Bump line.
       RTN                             ; Return to caller.


; What appears to be TOOLBX's Hashing routine.
;
; Incoming:
;               D6 =: Number of characters to hash.
;
;               A6 -> Indexes buffer to hash.
;
; Outgoing:
;               D6 =: Hash total of field.
;               A6 -> Indexes end of buffer.

TBXHSH:

; It appears that the first step is to save the number of char in a field
; in the high byte of the low word and then save the total ASCII value
; of the string in the low byte of the low word, then save all of that
; in the high word.

       MOV     D6, D7                  ; Save number of chars.
       BEQ     99$                     ; Opps..none there..quit.
       SUB     #1, D7                  ; Dbf adjust count.
       ASL     D6, #8.                 ; Mul * 256.
       SAVE    A6, D7                  ; Save address of buffer & count.
10$:    ADDB    (A6)+, D6               ; Add ascii value byte to number.
       DBF     D7, 10$                 ; For all chars.

; The following code represents what appears to be adding in
; the ESP field's Read and Write security level.
;
;  Which for most of the time is a constant unless it is changed in
;  an ESP screen. While changing this value would create a different
;  hash total than a previous one with different field security levels, it
;  would create the same hash total on the next pass if the values for Read
;  and Write security remain the same. Soooo for this example we assume
;  that the Read and Write security is 0. Thus we comment it out because
;  any number + 0 is still that number.

;;      ADDB    22(A3), D6              ; Add read security value.
;;      ADDB    23(A3), D6              ; Add Write security value.

       REST    A6, D7                  ; Restore buffer address & count.
       SWAP    D6                      ; Swap Words.

20$:    CLR     D1                      ; Preclear hasher.
       MOVB    (A6)+, D1               ; Get next char.
       XORW    D1, D6                  ; Shake it.
       ROLW    D6, #1                  ; Roll it.
       DBF     D7, 20$                 ; And try again.
99$:    RTN                             ; Return to caller.

       END