00 C0 20 9E AD 20 A3 B6 A8 88 A9 05 4A 90 02 49 B1 71 22 88 10 F6 29 1F C9 07
B0 02 69 0D A8 BE 32 C0 B9 1E C0 4C CD BD 00 00 00 00 03 00 0A 00 06 10 01 00
FF 00 02 00 00 00 00 00 08 00 15 0D DB 02 18 90 3D 55 79 05 FF E9 62 22 01 59
01 37 FF 03
Questo utilizza l'hashing (ovviamente), ma ottimizzato per una breve implementazione sul 6502, sfruttando il flag di carry impostato spostando e usato in aggiunta. I numeri magici per l'hashing sono stati trovati forzando brutalmente con un piccolo programma C; ilFF
byte sono sfortunati buchi nella tabella hash;)
Conteggio byte: indirizzo di caricamento 2 byte, codice 38 byte, hashtable 42 byte per i valori.
Utilizzo: SYS49152"[ordinal]"
ad esempio SYS49152"DUODECIMUS"
. (notare che le lettere appaiono in maiuscolo nella configurazione C64 predefinita).
Importante : prima del primo avvio, emettere un NEW
comando. Ciò è necessario perché il LOAD
comando BASIC C64 alterna alcuni vettori BASIC, anche quando si carica un programma macchina su un indirizzo assoluto (come qui $C000
/ 49152
).
Smontaggio commentato :
00 C0 ; load address
.C:c000 20 9E AD JSR $AD9E ; evaluate expression
.C:c003 20 A3 B6 JSR $B6A3 ; evaluate as string
.C:c006 A8 TAY ; length to y register
.C:c007 88 DEY ; decrement (start at last char)
.C:c008 A9 05 LDA #$05 ; start value for hash
.C:c00a .hashloop:
.C:c00a 4A LSR A ; shift right
.C:c00b 90 02 BCC .skip ; shifted bit zero? -> skip xor
.C:c00d 49 B1 EOR #$B1 ; xor "magic" value
.C:c00f .skip:
.C:c00f 71 22 ADC ($22),Y ; add current character (plus carry)
.C:c011 88 DEY ; previous character
.C:c012 10 F6 BPL .hashloop ; pos >= 0? -> repeat
.C:c014 29 1F AND #$1F ; mask lowest 5 bits
.C:c016 C9 07 CMP #$07 ; larger than 7 ?
.C:c018 B0 02 BCS .output ; -> to output
.C:c01a 69 0D ADC #$0D ; add 13
.C:c01c .output:
.C:c01c A8 TAY ; hash to y register
.C:c01d BE 32 C0 LDX .lb-8,Y ; load low byte from hashtable
.C:c020 B9 1E C0 LDA .hb-8,Y ; load high byte from hashtable
.C:c023 4C CD BD JMP $BDCD ; to output of 16bit number
.C:c026 .hb:
.C:c026 00 00 00 00 .BYTE $00,$00,$00,$00
.C:c02a 03 00 0A 00 .BYTE $03,$00,$0A,$00
.C:c02e 06 10 01 00 .BYTE $06,$10,$01,$00
.C:c032 FF 00 02 00 .BYTE $FF,$00,$02,$00
.C:c036 00 00 00 00 .BYTE $00,$00,$00,$00
.C:c03a .lb:
.C:c03a 08 00 15 0D .BYTE $08,$00,$15,$0D ; second byte used in .hb as well
.C:c03e DB 02 18 90 .BYTE $DB,$02,$18,$90
.C:c042 3D 55 79 05 .BYTE $3D,$55,$79,$05
.C:c046 FF E9 62 22 .BYTE $FF,$E9,$62,$22
.C:c04a 01 59 01 37 .BYTE $01,$59,$01,$37
.C:c04e FF 03 .BYTE $FF,$03
Suite di test C64 BASIC V2
(contenente il programma della macchina in DATA
righe)
0fOa=49152to49231:rEb:pOa,b:nE
1?"primus",:sY49152"primus":?
2?"secundus",:sY49152"secundus":?
3?"tertius",:sY49152"tertius":?
4?"quartus",:sY49152"quartus":?
5?"quintus",:sY49152"quintus":?
6?"sextus",:sY49152"sextus":?
7?"septimus",:sY49152"septimus":?
8?"octavus",:sY49152"octavus":?
9?"nonus",:sY49152"nonus":?
10?"decimus",:sY49152"decimus":?
11?"undecimus",:sY49152"undecimus":?
12?"duodecimus",:sY49152"duodecimus":?
13?"tertius decimus",:sY49152"tertius decimus":?
14?"quartus decimus",:sY49152"quartus decimus":?
15?"quintus decimus",:sY49152"quintus decimus":?
16?"sextus decimus",:sY49152"sextus decimus":?
17?"septimus decimus",:sY49152"septimus decimus":?
18?"duodevicesimus",:sY49152"duodevicesimus":?
19?"undevicesimus",:sY49152"undevicesimus":?
20?"vicesimus",:sY49152"vicesimus":?
21dA32,158,173,32,163,182,168,136,169,5,74,144,2,73,177,113,34,136,16,246,41,31
22dA201,7,176,2,105,13,168,190,50,192,185,30,192,76,205,189,0,0,0,0,3,0,10,0,6
23dA16,1,0,255,0,2,0,0,0,0,0,8,0,21,13,219,2,24,144,61,85,121,5,255,233,98,34,1
24dA89,1,55,255,3