6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 21, 2024 7:46 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Thu Dec 28, 2017 4:41 pm 
Offline

Joined: Mon Dec 25, 2017 6:03 pm
Posts: 3
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:
                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:
        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


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 28, 2017 11:08 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 29, 2017 2:52 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
Here is an untested sample of what I'm describing:
Code:
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 29, 2017 4:32 am 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 674
And here's a stupidly small tested version from codebase. .A = number in. .Y/.X/.A = 100s/10s/1s ASCII digit out.

Code:
  ldy #$2f
  ldx #$3a
  sec
- iny
  sbc #100
  bcs -
- dex
  adc #10
  bmi -
  adc #$2f
  rts

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 29, 2017 5:17 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
Nice! Even if we replace your RTS with
Code:
   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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 31, 2017 3:57 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: