BIN HEX to BCD (to Decimal) - simondotm/stardot-wiki GitHub Wiki

BIN/HEX to BCD (to Decimal)

Fast conversion of 16 bit numbers to BCD Binary Coded Decimal, that is 42 = &2A or 42 = &42 in BCD

Having written this code this morning and had a closer look at what is available, this is similar to an unwinding of Print decimal by J.G.Harston.

This code does as far as I can see (having just written it ;-) a very fast conversion from HEX/Binary to BCD - now I am wondering why you would want it!

You could just use BCD mode to keep scores and Print decimal for debugging, but maybe someone will find it interesting and it was a nice little project while I was waiting for the plumber!

The code works by having three tables for what the bits 15..12, 11..8 and 7..3 are as BCD, leaving bits 2..0 which are the same in hex as decimal (0..7)

The code copies the most significant values and then adds the other three (two from tables and the LSB & 7) - Job Done.

The code is wrapped in a SEI/CLI as this means that interrupts don't need to worry about the DECimal flag - something that all interrupts should do, but some code doesn't since it isn't part of the guarantees made on the Beeb (from what I can remember).

When I originally thought of this this morning, I did think of looping like Print decimal, but as this is supposed to be game ready, I didn't like the idea of worst case 64999 being converted and having to loop through subtractions nearly 40 times; so paid the old price of time vs memory and added the small (?) tables.

Here is the BeebAsm code, I will port it over to the Beeb, add some test code and post the code and an .ssd to the forums 1.

    \\ unless documented, AXY and CNVZ are undefined on exit, BID are unchanged (B=B I=I D=D)



    GUARD &5800

    ORG   &1400



.BEGIN



.MAIN

{

}



bin_as_bcd = &70



.bin_to_bcd \\ &yyxx to bin_to_bcd X=X \\ 99 bytes (+21 if bin_as_bcd not ZP)

{

    sei \\ disable interrupts to avoid issues when using bcd

    sed

    tya

    pha

    lsr a : lsr a : lsr a : lsr a

    tay

    lda bits1512_b0,y

    sta bin_as_bcd+0

    lda bits1512_b1,y

    sta bin_as_bcd+1

    lda bits1512_b2,y

    sta bin_as_bcd+2

    pla

    and #&f

    tay

    clc

    lda bits118_b0,y

    adc bin_as_bcd+0

    sta bin_as_bcd+0

    lda bits118_b1,y

    adc bin_as_bcd+1

    sta bin_as_bcd+1

    lda #0

    adc bin_as_bcd+2

    sta bin_as_bcd+2

    txa

    lsr a : lsr a : lsr a

    tay

    clc

    lda bits73_b0,y

    adc bin_as_bcd+0

    sta bin_as_bcd+0

    lda bits73_b1,y

    adc bin_as_bcd+1

    sta bin_as_bcd+1

    lda #0

    adc bin_as_bcd+2

    sta bin_as_bcd+2

    txa

    and #7

    adc bin_as_bcd+0

    sta bin_as_bcd+0

    lda #0

    adc bin_as_bcd+1

    sta bin_as_bcd+1

    lda #0

    adc bin_as_bcd+2

    sta bin_as_bcd+2

    cld

    cli

    rts



.bits1512_b2

    FOR n,0,&f000,&1000

    EQUB n DIV 10000

    NEXT

.bits1512_b1

    FOR n,0,&f000,&1000

    EQUB (((n DIV 1000) MOD10) * 16) + ((n DIV 100) MOD 10)

    NEXT

.bits1512_b0

    FOR n,0,&f000,&1000

    EQUB (((n DIV 10) MOD 10) * 16) + (n MOD 10)

    NEXT

.bits118_b1

    FOR n,0,&f00,&100

    EQUB (((n DIV 1000) MOD10) * 16) + ((n DIV 100) MOD 10)

    NEXT

.bits118_b0

    FOR n,0,&f00,&100

    EQUB (((n DIV 10) MOD 10) * 16) + (n MOD 10)

    NEXT

.bits73_b1

    FOR n,0,&f8,&08

    EQUB ((n DIV 100) MOD 10)

    NEXT

.bits73_b0

    FOR n,0,&f8,&08

    EQUB (((n DIV 10) MOD 10) * 16) + (n MOD 10)

    NEXT

}



.END



    PRINT "GAME",~BEGIN, ~END, ~MAIN

    SAVE "GAME", BEGIN, END, MAIN
⚠️ **GitHub.com Fallback** ⚠️