hashsize equ $100 stacksize equ $100 stackofs equ $1000 reset equ $e400 ; reset routine of sbc09 monitor org $400 nop ; for debugging nop main lds #stacktop ldd #list std ,--s lda #listsize sta ,-s jsr stat jmp reset ; end bra * ; loop here ; -- ROUTINE stat ------------------ ; ; parameters: adr(list of bytes) 16bit ; length of list 8bit (signed, usable: 0-$7F) stat pshs x,y,a,b,u ; => stackoffset 2+2+1+1+2 = 8 leau 8+2,s ; original stack-pointer ohne letztes pshs und return pointer paramLen equ 0 ; 2nd pushed: 8bit paramAdr equ 1 ; 1st pushed: 16bit (+1 to jump over previous 8bit) ; einfache variante mit 16bit signed index (pos.zahlenbereich reicht aus) ; bei adressierung op r1,r2 wird das r2 register als ; zähler verwendet, r1 bleibt gleich init ldb #$ba ; s.u. zum test ldx #hashsize clear leax -1,x ; dec x stb hash,x clr hash,x cmpx #0 bne clear cnt ldx #listsize cntloop leax -1,x ; dec x lda list,x ; vom listenende an durchlaufen: 8bit laden... tfr a,y ; ... in 16bit reg schieben (hibyte wird gelöscht) inc hash,y cmpx #0 bne cntloop bra statend ; nächste variante überspringen ; "akademische" variante mit 8bit signed index ; bei adressierung op r1,r2 wird das r1 register als ; zähler verwendet, r2 bleibt gleich init2 ldx #hash leax hashsize/2,x ; siehe anmerkungen am dateiende lda hashsize ldb #1 ; zum test erst mal "1" schreiben, dann "0" clear2 deca ; ... damit man was im simulator sieht :) stb a,x clr a,x tsta bne clear2 cnt2 lda paramLen,u ; A=länge ldy paramAdr,u ; Y=adresse der liste cntloop2 deca ldb ,y ; wert aus liste subb #hashsize/2 ; siehe anmerkungen am dateiende inc b,x leay 1,y ; inc y tsta bne cntloop2 statend puls x,y,a,b,u rts ; -- DATA -------------------------- org (*+$100-*%$100) ; für einfaches debugging an modulo $100 adresse ausrichten hash rmb hashsize list fcb $0, $1, $2, $0, $3, $10, $10, $10, $A0, $A1 listend listsize equ listend-list ; -- STACK ------------------------- org stackofs stackend rmb stacksize stacktop end ; -- ANMERKUNGEN (nach 'end') ------ korrektur: für die indizierte adressierung über x wird das register b verwendet. die indizierung erfolgt 'signed', d.h. der index würde von $7F auf $80 ins negative umschlagen und einen bereich vor der startadresse in x adressieren. deshalb wird die startadresse in die mitte des datenbereichs gelegt, damit der ggf. negative index einmal in die obere (pos) oder die untere (neg) hälfte verweist: leax hashsize/2,x entsprechend muss beim hashing der schlüssel (listenwert) um diese verschiebung korrigiert werden, d.h. ein schlüssel $0 soll nicht in die hash-mitte (x+$0), sondern auf den anfang (das 0-. element) verweisen (x-$80+$0): subb #hashsize/2