John Brooks

2017-07-08 02:09:21 UTC

In 2015 I made very compact assembly routines to convert binary words to decimal.

The 65816 binary-to-BCD conversion routine is $11 bytes and is posted here:

https://groups.google.com/forum/#!searchin/comp.sys.apple2.programmer/woz$20hextodec%7Csort:relevance/comp.sys.apple2.programmer/NpfRXsf2T0s/9swgn8FMCwAJ

I found that the 6502 version was much larger and more complex than the 65816 version due to the inefficiency of handling BCD-packed digits.

I ended up avoiding BCD and created a compact 6502 routine which could be configured to:

1) display all digits

2) left justify (by skipping leading zeroes)

3) right justify (by replacing leading zeroes with spaces)

4) print 2 to 5 digit numbers

The configurations range between 53 & 61 bytes. I've also added a 4 byte 'Demo' to each config which prints #$1234 as decimal 4660.

len=$34 Print leading zeroes

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 30 08 48 A5 3F FD 34 08 B0 EE 68 98

0820:D0 00 49 B0 20 ED FD A0 00 A5 3E CA F0 F4 10 E2

0830:60 0A 64 E8 10 00 00 03 27

len=$3B Left justify (skip leading zeroes)

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 36 08 48 A5 3F FD 3A 08 B0 EE 68 98

0820:D0 04 E6 3D 10 07 49 B0 20 ED FD A0 00 C6 3D A5

0830:3E CA F0 F2 10 DC 60 0A 64 E8 10 00 00 03 27

len=$3D Right justify (spaces instead of leading zeroes)

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 38 08 48 A5 3F FD 3C 08 B0 EE 68 98

0820:D0 06 E6 3D 30 02 A9 10 49 B0 20 ED FD A0 00 C6

0830:3D A5 3E CA F0 F2 10 DA 60 0A 64 E8 10 00 00 03 27

I'm interested in making the code smaller if anyone has ideas. Code golf anyone? qkumba?

Below is the source, compatible with Merlin 8, Merlin 16, and Merlin32:

-JB

@JBrooksBSI

1 *-------------------------------

2 * DecPrint - 6502 print 16 bits

3 *

4 * 11/8/2015 by John Brooks

5 *-------------------------------

6 org $800

7

8 Demo ldx #$12 ;X=H

9 lda #$34 ;A=L

10 * Fall into DecPrintU16

11

12 *-------------------------------

13

14 DEC_SKIP0 = 1 ;Set to 1 to skip leading zeroes (left justify)

15 DEC_SPACE0 = 0 ;Set to 1 to print leading spaces (right justify)

16 DEC_DIGITS = 5 ;# of digits to print (2-5)

17 DEC_VARS = $3D

18

19 dum DEC_VARS ;Uses 3 temp bytes (ZP or ABS)

20 DecCtr ds 1 ;Leading zero ctr

21 DecWord ds 2 ;U16 being printed

22 dend

23

24 RomCOut = $FDED

25

26 *-------------------------------

27 * Print U16 as decimal via COUT

28 * IN: X=hi, A=Lo

29 * OUT: X=$FF, Y=$00

30 *-------------------------------

31 DecPrintU16

32 pha

33 txa

34 DecModLen = *+1

35 :MOD ldx #DEC_DIGITS-1

36 ldy #-1

37 sty DecCtr

38

39 :Loop iny

40 sta DecWord+1

41 pla

42 sta DecWord

43

44 :DoDigit sec

45 sbc Power10L-1,x

46 pha

47 lda DecWord+1

48 sbc Power10H-1,x

49 bcs :Loop

50

51 :GotDigit

52 pla

53 tya

54 bne :PrDigit ;Print all non-zero digits

55

56 do DEC_SKIP0

57 inc DecCtr

58 bpl :NoDigit ;Skip leading zeroes

59 else

60 do DEC_SPACE0

61 inc DecCtr

62 bmi :PrDigit ;Print digit if we've seen a non-zero

63 lda #$10 ;Else print a space

64 fin

65 fin

66

67 :PrDigit eor #"0"

68 jsr RomCOut

69 ldy #0

70 :NoDigit

71 do DEC_SKIP0+DEC_SPACE0

72 dec DecCtr

73 fin

74 lda DecWord

75 dex

76 beq :PrDigit

77 bpl :DoDigit

78 rts

79

80 Power10L db <10,<100,<1000,<10000

81 Power10H db >10,>100,>1000,>10000

82

83 lst off

The 65816 binary-to-BCD conversion routine is $11 bytes and is posted here:

https://groups.google.com/forum/#!searchin/comp.sys.apple2.programmer/woz$20hextodec%7Csort:relevance/comp.sys.apple2.programmer/NpfRXsf2T0s/9swgn8FMCwAJ

I found that the 6502 version was much larger and more complex than the 65816 version due to the inefficiency of handling BCD-packed digits.

I ended up avoiding BCD and created a compact 6502 routine which could be configured to:

1) display all digits

2) left justify (by skipping leading zeroes)

3) right justify (by replacing leading zeroes with spaces)

4) print 2 to 5 digit numbers

The configurations range between 53 & 61 bytes. I've also added a 4 byte 'Demo' to each config which prints #$1234 as decimal 4660.

len=$34 Print leading zeroes

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 30 08 48 A5 3F FD 34 08 B0 EE 68 98

0820:D0 00 49 B0 20 ED FD A0 00 A5 3E CA F0 F4 10 E2

0830:60 0A 64 E8 10 00 00 03 27

len=$3B Left justify (skip leading zeroes)

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 36 08 48 A5 3F FD 3A 08 B0 EE 68 98

0820:D0 04 E6 3D 10 07 49 B0 20 ED FD A0 00 C6 3D A5

0830:3E CA F0 F2 10 DC 60 0A 64 E8 10 00 00 03 27

len=$3D Right justify (spaces instead of leading zeroes)

0800:A2 12 A9 34 48 8A A2 04 A0 FF 84 3D C8 85 3F 68

0810:85 3E 38 FD 38 08 48 A5 3F FD 3C 08 B0 EE 68 98

0820:D0 06 E6 3D 30 02 A9 10 49 B0 20 ED FD A0 00 C6

0830:3D A5 3E CA F0 F2 10 DA 60 0A 64 E8 10 00 00 03 27

I'm interested in making the code smaller if anyone has ideas. Code golf anyone? qkumba?

Below is the source, compatible with Merlin 8, Merlin 16, and Merlin32:

-JB

@JBrooksBSI

1 *-------------------------------

2 * DecPrint - 6502 print 16 bits

3 *

4 * 11/8/2015 by John Brooks

5 *-------------------------------

6 org $800

7

8 Demo ldx #$12 ;X=H

9 lda #$34 ;A=L

10 * Fall into DecPrintU16

11

12 *-------------------------------

13

14 DEC_SKIP0 = 1 ;Set to 1 to skip leading zeroes (left justify)

15 DEC_SPACE0 = 0 ;Set to 1 to print leading spaces (right justify)

16 DEC_DIGITS = 5 ;# of digits to print (2-5)

17 DEC_VARS = $3D

18

19 dum DEC_VARS ;Uses 3 temp bytes (ZP or ABS)

20 DecCtr ds 1 ;Leading zero ctr

21 DecWord ds 2 ;U16 being printed

22 dend

23

24 RomCOut = $FDED

25

26 *-------------------------------

27 * Print U16 as decimal via COUT

28 * IN: X=hi, A=Lo

29 * OUT: X=$FF, Y=$00

30 *-------------------------------

31 DecPrintU16

32 pha

33 txa

34 DecModLen = *+1

35 :MOD ldx #DEC_DIGITS-1

36 ldy #-1

37 sty DecCtr

38

39 :Loop iny

40 sta DecWord+1

41 pla

42 sta DecWord

43

44 :DoDigit sec

45 sbc Power10L-1,x

46 pha

47 lda DecWord+1

48 sbc Power10H-1,x

49 bcs :Loop

50

51 :GotDigit

52 pla

53 tya

54 bne :PrDigit ;Print all non-zero digits

55

56 do DEC_SKIP0

57 inc DecCtr

58 bpl :NoDigit ;Skip leading zeroes

59 else

60 do DEC_SPACE0

61 inc DecCtr

62 bmi :PrDigit ;Print digit if we've seen a non-zero

63 lda #$10 ;Else print a space

64 fin

65 fin

66

67 :PrDigit eor #"0"

68 jsr RomCOut

69 ldy #0

70 :NoDigit

71 do DEC_SKIP0+DEC_SPACE0

72 dec DecCtr

73 fin

74 lda DecWord

75 dex

76 beq :PrDigit

77 bpl :DoDigit

78 rts

79

80 Power10L db <10,<100,<1000,<10000

81 Power10H db >10,>100,>1000,>10000

82

83 lst off