Page 1 of 1

6502 BCD based on HEX converter

Posted: Thu Dec 28, 2017 4:41 pm
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

Re: 6502 BCD based on HEX converter

Posted: Thu Dec 28, 2017 11:08 pm
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.

Re: 6502 BCD based on HEX converter

Posted: Fri Dec 29, 2017 2:52 am
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.

Re: 6502 BCD based on HEX converter

Posted: Fri Dec 29, 2017 4:32 am
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

Re: 6502 BCD based on HEX converter

Posted: Fri Dec 29, 2017 5:17 am
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.

Re: 6502 BCD based on HEX converter

Posted: Sun Dec 31, 2017 3:57 am
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.