.proc convert_to_base100 ; (addressIN: word, addressOUT: word) ; regx, regy: low, hi, address input (24 bit value up to 999,999) ; reg a, pla: low high address out ; convert 24 bits to 3 bytes: 10,000s, 1000s, 100s ; double dabble: to correct a single digit, before ; it is shifted look if it will become a 10. If it was to become ; a 10 you add 6 to correct before a shift you add 3 for the ; same result. Adding 3 is done right before the shift would have ; moved the digit into the correct spot ; ; so for a value of 100 you add 9C or 4E before the shift ; ; 100 in hex: 64 32 ; + 9C + 4E ; ----- ----- ; 100 80 --> shl 1 = 100 ; ; add 4E if the value to be shifted once more is >=32hex ; ; 0 - 9 is ten digits, 0 -99 one hundred digits , need to check the ; hundreds for greater than or equal 32 ; ; 999999 = 00001111 01000010 00111111 4 shifts to discard zeros ; to be shifted into 00000000 00000000 00000000 ; 32 in binary = 00110010 = 6 more shifts before check needed ; 10 shifts total needed before testing ; ; 14 more shifts after ; .struct addressIN .byte 2 addressOUT .byte 2 tempIN .byte 3 tempOUT .byte 3 .endstruct stx addressIN sty addressIN+1 sta addressOUT pla sta addressOUT+1 ldy #2 repeat lda (addressIN),y sta tempIN,y dey until negative lda #0 sta tempOUT sta tempOUT+1 sta tempOUT+2 clc ; 4 shifts to remove zeros lda tempIN rol a rol tempIN + 1 rol tempIN + 2 rol a rol tempIN + 1 rol tempIN + 2 rol a rol tempIN + 1 rol tempIN + 2 rol a rol tempIN + 1 rol tempIN + 2 ldy #4 ; 4 shifts that have to go into OUT repeat rol a rol tempIN + 1 rol tempIN + 2 rol tempOUT dey until zero ; TWO MORE lda tempIN + 1 rol a rol tempIN + 2 rol tempOUT rol a rol tempIN + 2 rol tempOUT sta tempIN + 1 ; 10 shifts done ldx #0 ldy #6 repeat jsr check32 rol tempIN + 1 rol tempIN + 2 rol tempOUT rol tempOUT + 1 dey until zero ; after this next check, byte 1 could hold $80 ; 6 more shifts to check byte 2 ..don't need to though ldy #8 repeat ldx #1 jsr check32 dex jsr check32 ; clc ; rol tempIN ; rol tempIN + 1 rol tempIN + 2 rol tempOUT rol tempOUT + 1 rol tempOUT + 2 dey until zero ldy #2 repeat lda tempOUT,y sta (addressOUT),y dey until negative rts check32: lda tempOUT,x cmp #$32 if greaterORequal ; carry is set adc #$4D ; add #$4E sta tempOUT,x endif rts .endproc
Thursday, September 20, 2012
Wierd "Double Dabble" code.
This code, as the comments suggest, takes 24 bits up to a decimal value of 999,999 and converts it to a base100 code into three bytes. Code assumes it can use local vars starting at address $0000. Assumes it can use .macros from here.
Labels:
ca65
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment