;*; Updated on 17-Sep-92 at 5:55 AM by James A. Jarboe I V; edit time: 0:00:30
;*; Created on 17-Sep-92 at 5:01 AM by James A. Jarboe I V; edit time: 0:08:19
;
; TBXHS2 - Demonstrates possible fix 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 IRV 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.



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.

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

       PRTTAB  -1,0                    ; Clear screen
       TYPECR  <Testing NEW Hashing routine.>
       TYPECR  <Using IRV style hashing.>
       CRLF                            ; Bump line

       TYPECR  <String   Hash            Hash >
       CRLF

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

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.ME                   ; Do hashing and display.

       MOV     #S..BOT, D4             ; Set starting number.
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    IRVHSH                  ; 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.ME                   ; Display hash match.
       MOV     #7, D1                  ; Ring bell.
       TTY
       ADD     #1, TT.OCR(A5)
       BR      10$                     ; Try again.

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


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


; Do hashing and display. Using another hashing method.
;
; 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.ME:
       PUSH    A6                      ; Save buffer address.
       CALL    IRVHSH                  ; 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.



;IRVHSH:
;
; Part of this hashing routine was taken from JOBSTS.LIT by Irv Bromberg
; off the AMUS Newtork. It always appeared to work without any problems.
; I am sure some mathmematicion could verify it's redundency occurance of
; likely hash matches for different string values.
;
; Incoming:
;               D6 =: Number of characters to hash.
;
;               A6 -> Indexes buffer to hash.
;
; Outgoing:
;               D6 =: Hash total of field.
;               A6 -> Indexes end of buffer.


IRVHSH:
       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.

;;      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.

       CLR     D1                      ; Preclear hasher.

; Here's a modified adaptation of Irv's hashing routine. Actually he only
; stored and checked the resulting word value. Assuming that ESP stores this
; as a long word, we just tack it on to what is done above since it appears
; that the TOOLBX version does about the same thing.
;
20$:    MOVB    (A6)+, D1               ; Get next char.
       LSLW    D1, #8.                 ; Shift to high byte.
       XORW    D1, D6                  ; Rattle.
       PUSH    D7                      ; Save current char count.
       MOVW    #<8.-1>, D7             ; Set number of bits (dbf adj).

30$:    TSTW    D6                      ; Is hash word negative?
       BMI     40$                     ;  Yes..
       LSLW    D6, #1                  ; No..shift.
       BR      50$                     ; Try next bits.

40$:    LSLW    D6, #1                  ; Shift.
       XORW    #^O10041, D6            ; Rattle.

50$:    DBF     D7, 30$                 ; Do all bits.
       POP     D7                      ; Restore current count.
       DBF     D7, 20$                 ; Do all chars.

99$:    RTN                             ; Return to caller.

       END