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
测试套件的在线演示。