20 FD AE 20 9E AD 85 FC 20 A3 B6 A9 79 85 FB A0 00 84 FD B1 22 10 03 69 A0 18
45 FD 65 FB 85 FD E6 FB C8 C4 FC D0 EC E9 29 B0 FC 69 29 C9 1A 90 1C 29 0F C9
0D 90 04 69 09 90 12 C9 02 F0 0F C9 08 D0 04 A9 06 D0 06 C9 0C D0 02 A9 11 18
69 41 4C D2 FF
이것은 위치 독립적 인 코드이므로 RAM에 어딘가에 놓고 sys
명령을 사용하여 점프하십시오 .
온라인 데모 ($C000
/에로드49152
).
사용법 : sys49152,"[name]"
예 sys49152,"Aretha Franklin"
.
중요 : 프로그램이 온라인 데모와 같이 디스크에서로드 된 경우 new
먼저 명령을 실행하십시오! 머신 프로그램을로드하면 일부 C64 BASIC 포인터가 손상되기 때문에이 작업이 필요합니다.
참고 : C64는 기본적으로 소문자가없는 모드입니다. 읽을 수있는 이름 을 입력 하려면 먼저 SHIFT
+ 를 눌러 소문자 모드로 전환 하십시오 CBM
.
설명
실제로 이러한 이름에 대한 최소한의 완벽한 해시 함수를 찾는 것이 과제입니다. C64의 경우 간단한 8 비트 연산에서 쉽게 계산할 수있는 것을 찾아야했습니다. 주석 처리 된 해체 목록은 다음과 같습니다.
.C:c000 20 FD AE JSR $AEFD ; consume comma
.C:c003 20 9E AD JSR $AD9E ; evaluate expression
.C:c006 85 FC STA $FC ; save string length
.C:c008 20 A3 B6 JSR $B6A3 ; free string
.C:c00b A9 79 LDA #$79 ; value for adding during hashing
.C:c00d 85 FB STA $FB
.C:c00f A0 00 LDY #$00 ; offset for reading string
.C:c011 84 FD STY $FD ; and initial hash value
.C:c013 .hashloop:
.C:c013 B1 22 LDA ($22),Y ; read next character from string
.C:c015 10 03 BPL .xor ; if bit 8 set (shifted)
.C:c017 69 A0 ADC #$A0 ; translate to same unshifted character
.C:c019 18 CLC
.C:c01a .xor:
.C:c01a 45 FD EOR $FD ; xor with previous hash
.C:c01c 65 FB ADC $FB ; add offset
.C:c01e 85 FD STA $FD ; store new hash
.C:c020 E6 FB INC $FB ; increment offset
.C:c022 C8 INY
.C:c023 C4 FC CPY $FC
.C:c025 D0 EC BNE .hashloop ; repeat until last character
.C:c027 .modloop:
.C:c027 E9 29 SBC #$29 ; subtract $29 until
.C:c029 B0 FC BCS .modloop ; underflow, then
.C:c02b 69 29 ADC #$29 ; add once again ( => mod $29)
.C:c02d C9 1A CMP #$1A ; value in hash range?
.C:c02f 90 1C BCC .tochar ; -> output
.C:c031 29 0F AND #$0F ; mask lowest 4 bits only
.C:c033 C9 0D CMP #$0D ; greater 12 ?
.C:c035 90 04 BCC .fixedvals
.C:c037 69 09 ADC #$09 ; then just add 10 (9 plus carry)
.C:c039 90 12 BCC .tochar ; and done -> output
.C:c03b .fixedvals:
.C:c03b C9 02 CMP #$02 ; 2 becomes 3 by adding
.C:c03d F0 0F BEQ .tochar2 ; with carry (jump after the CLC)
.C:c03f C9 08 CMP #$08 ; if value was 8
.C:c041 D0 04 BNE .check2
.C:c043 A9 06 LDA #$06 ; new value is 6
.C:c045 D0 06 BNE .tochar ; and output
.C:c046 .check2:
.C:c047 C9 0C CMP #$0C ; else if value was 12
.C:c049 D0 02 BNE .tochar
.C:c04b A9 11 LDA #$11 ; new value is 17
.C:c04d .tochar:
.C:c04d 18 CLC
.C:c04d .tochar2:
.C:c04e 69 41 ADC #$41 ; add character code for 'a'
.C:c050 4C D2 FF JMP $FFD2 ; jump to kernal CHROUT routine
테스트 스위트 (C64 BASIC, 기계 코드 루틴을 data
라인으로 포함)
0fOa=49152to49234:rEb:pOa,b:nE:pO53272,23
1sY49152,"Aretha Franklin":?":Aretha Franklin"
2sY49152,"Ray Charles":?":Ray Charles"
3sY49152,"Elvis Presley":?":Elvis Presley"
4sY49152,"Sam Cooke":?":Sam Cooke"
5sY49152,"John Lennon":?":John Lennon"
6sY49152,"Marvin Gaye":?":Marvin Gaye"
7sY49152,"Bob Dylan":?":Bob Dylan"
8sY49152,"Otis Redding":?":Otis Redding"
9sY49152,"Stevie Wonder":?":Stevie Wonder"
10sY49152,"James Brown":?":James Brown"
11sY49152,"Paul McCartney":?":Paul McCartney"
12sY49152,"Little Richard":?":Little Richard"
13sY49152,"Roy Orbison":?":Roy Orbison"
14sY49152,"Al Green":?":Al Green"
15sY49152,"Robert Plant":?":Robert Plant"
16sY49152,"Mick Jagger":?":Mick Jagger"
17sY49152,"Tina Turner":?":Tina Turner"
18sY49152,"Freddie Mercury":?":Freddie Mercury"
19sY49152,"Bob Marley":?":Bob Marley"
20sY49152,"Smokey Robinson":?":Smokey Robinson"
21sY49152,"Johnny Cash":?":Johnny Cash"
22sY49152,"Etta James":?":Etta James"
23sY49152,"David Bowie":?":David Bowie"
24sY49152,"Van Morrison":?":Van Morrison"
25sY49152,"Michael Jackson":?":Michael Jackson"
26sY49152,"Jackie Wilson":?":Jackie Wilson"
27dA32,253,174,32,158,173,133,252,32,163,182,169,121,133,251,160,0,132,253,177
28dA34,16,3,105,160,24,69,253,101,251,133,253,230,251,200,196,252,208,236,233
29dA41,176,252,105,41,201,26,144,28,41,15,201,13,144,4,105,9,144,18,201,2,240
30dA15,201,8,208,4,169,6,208,6,201,12,208,2,169,17,24,105,65,76,210,255
테스트 스위트의 온라인 데모 .