6502 BCD based on HEX converter

Building your first 6502-based project? We'll help you get started here.
Post Reply
jgjg
Posts: 3
Joined: 25 Dec 2017

6502 BCD based on HEX converter

Post by jgjg »

Hi, I have to code two programs in 6502, the first one - showing on the screen hexa number - is done, and it works correctly, but the second one - showing decimal number on the screen - isn't working. I'm trying to connect the program, which is working with the functions which let count decimal number to get a working program. What I can't achieve, is output on the screen. The loop seems to be working, so the convertion might be done correctly, but there is no output on the screen. I tried using something similar to pr in hexa, jumping there and storing accumulator in $80, but without any effects. I removed my efforts to readability of my code. Could you tell me what should be changed in BCD code?

HEX:

Code: Select all

                opt f-g-h+l+o+
                org $1000

start           equ *

                lda <text
                sta $80
                lda >text
                sta $81
                ldy #1
                lda #$ba    ; input
                jsr phex
                lda <text
                ldx >text
                jsr $ff80
                brk

phex            pha
                jsr prhex
                pla
                lsr @
                lsr @
                lsr @
                lsr @
                

prhex           and #%00001111 
                ora #'0'
                cmp #'9'+1
                bcc pr
                adc #6

pr              sta ($80),y
                dey
                rts

byte            dta b(0)

                org $2000

text            equ *
                dta b(0),b(0)
                dta b(10) ; '\n'

                org $2E0
                dta a(start)

                end of file
BCD:

Code: Select all

        opt f-g-h+l+o+
        org $1000

start   equ *
        lda <text
        sta $80
        lda >text
        sta $81
        jsr BINBCD8
        lda <text
        ldx >text
        jsr $ff80
        brk

BINBCD8	SED		; Switch to decimal mode
		LDA #0		; Ensure the result is clear
		STA BCD+0
		STA BCD+1
		LDX #8		; The number of source bits

CNVBIT	ASL BIN		; Shift out one bit
		LDA BCD+0	; And add into result
		ADC BCD+0
		STA BCD+0
		LDA BCD+1	; propagating any carry
		ADC BCD+1
		STA BCD+1
        DEY
		DEX		; And repeat for next bit
		BNE CNVBIT
		CLD		; Back to binary
		BRK		; All Done.

BCD     equ 0
BIN     equ 96


        org $2000

text    equ *
        dta b(0),b(0),b(0),b(0),b(0),b(0),b(0),b(0)
        dta b(10) ; '\n'

        org $2E0
        dta a(start)

        end of file
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 6502 BCD based on HEX converter

Post by barrym95838 »

It's not clear to me what your strategy is. First of all, are you attempting to convert binary to ASCII, because if you're converting BCD to ASCII then your first code sample should be fine.

My strategy to convert 8-bit binary to ASCII might be to initialize a counter to -1, then construct a small loop that increments the counter and subtracts 100 decimal from the accumulator until the carry is clear, indicating that we went "one iteration too far". The accumulator would then get the last 100 added back in and the counter would be stored in the text buffer as the "100s" digit (after an ASCII offset adjustment). The counter is reset to -1 and another small loop does the same thing but with 10 decimal instead of 100 decimal. The counter is stored as the "10s" digit (after offset adjustment), and the accumulator gets 10 added back in before being stored as the "1s" digit (again with offset adjustment). No BCD would be necessary in my example.

Mike B.

P.S. You can find an example of what I mean here, starting at the instruction LDY #"0"-1 ... but it is only designed to handle binary numbers less than 100 decimal, and has been "streamlined" in ways that may not be clear to a beginner.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 6502 BCD based on HEX converter

Post by barrym95838 »

Here is an untested sample of what I'm describing:

Code: Select all

bin2asc8:
   lda  number
   ldy  #"0"-1
   sec
div100:
   iny
   sbc  #100
   bcs  div100
   adc  #100
   pha
   tya
   jsr  cout    ; print 100s digit
   pla
   ldy  #"0"-1
   sec
div10:
   iny
   sbc  #10
   bcs  div10
   adc  #"0"+10
   pha
   tya
   jsr  cout    ; print 10s digit
   pla
   jmp  cout    ; print 1s digit and return
Mike B.
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: 6502 BCD based on HEX converter

Post by White Flame »

And here's a stupidly small tested version from codebase. .A = number in. .Y/.X/.A = 100s/10s/1s ASCII digit out.

Code: Select all

  ldy #$2f
  ldx #$3a
  sec
- iny
  sbc #100
  bcs -
- dex
  adc #10
  bmi -
  adc #$2f
  rts
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 6502 BCD based on HEX converter

Post by barrym95838 »

Nice! Even if we replace your RTS with

Code: Select all

   pha
   tya
   jsr  cout
   txa
   jsr  cout
   pla
   jmp  cout
... it still ends up at only 30 bytes.
Here's a (tested!!) 34-byte version that removes leading zeros but still prints "0" for zero. It uses some advanced stack and V-flag trickery that I learned from John Brooks, and can be very economically expanded to any input with a width that's a multiple of eight bits:

Code: Select all

bin2asc8:
   lda  #0      ; zero out remainder
   clv          ; V = 0 means quotient = 0
   ldy  #8      ; 8-bit divide
divmod:
   cmp  #10/2
   bcc  divmod2
   sbc  #10/2+$80 ; set V to show quotient > 0
   sec          ; shift 1 into div result
divmod2:
   rol  number
   rol
   dey
   bne  divmod
   pha          ; push remainder to print
   lda  #>(print-1)
   pha
   lda  #<(print-1)
   pha
   bvs  bin2asc8
   rts          ; print digits in reverse order
print:
   pla
   ora  #"0"
   jmp  cout
Mike B.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 6502 BCD based on HEX converter

Post by barrym95838 »

jgjg wrote:
... What I can't achieve, is output on the screen. The loop seems to be working, so the convertion might be done correctly, but there is no output on the screen ...
I don't know about the algorithm, but you need to conclude your BINBCD8 subroutine with RTS instead of BRK or it will never return to its caller, and none of the subsequent caller code will be executed.

Mike B.
Post Reply