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
テストスイートのオンラインデモ。