Converting byte to hex string

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
banedon
Posts: 742
Joined: 08 Sep 2013
Location: A missile silo somewhere under southern England

Converting byte to hex string

Post by banedon »

Hi guys

I couldn't readily find some 6502 code to convert a byte to hex string (basically, to show the contents of particular memory locations on an LCD screen, etc.) so have written my own. It does work. What does everyone think?

Code: Select all

' Parameters:
' A - value to convert from byte to hex string
' Outputs:
' X - LSB character
' Y - MSB character
.byteTOhexstr
PHA
' grab the MSB and move to LSB
LSR A
LSR A
LSR A
LSR A
' if A is greater than &A then go to A-F
CMP #&A
BCS numstrMSB_AtoF
.numstrMSB_0to9
ADC #48
TAX
JMP numstrLSB
.numstrMSB_AtoF
CLC
ADC #55
TAX

' LSB
.numstrLSB
PLA
' grab the LSB by masking out the MSB
AND #&0F
' if A is greater than &A then go to A-F
CMP #&A
BCS numstrLSB_AtoF
.numstrLSB_0to9
ADC #48
TAX
JMP numstrLSB
.numstrLSB_AtoF
CLC
ADC #55
TAY

RTS
rwiker
Posts: 294
Joined: 03 Mar 2011

Re: Converting byte to hex string

Post by rwiker »

You'll find code for printing a hex byte at http://www.sbprojects.com/projects/apple1/wozmon.txt; search for "PRBYTE" on that page. That's code written by Woz, so should be worth looking at.
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Converting byte to hex string

Post by BigDumbDinosaur »

banedon wrote:
Hi guys

I couldn't readily find some 6502 code to convert a byte to hex string (basically, to show the contents of particular memory locations on an LCD screen, etc.) so have written my own. It does work. What does everyone think?
Have you looked at this code? It can convert a binary value to any of four radices, hex being one of them. The largest binary value that it can convert is $FFFFFFFF or (2^32)-1.

To convert a single byte to printable hexadecimal characters, you could use the following code:

Code: Select all

;================================================================================
;
;binhex: CONVERT BINARY BYTE TO HEX ASCII CHARS
;
;	————————————————————————————————————
;	Preparatory Ops: .A: byte to convert
;
;	Returned Values: .A: MSN ASCII char
;	                 .X: LSN ASCII char
;	                 .Y: entry value
;	————————————————————————————————————
;
binhex   pha                   ;save byte
         and #%00001111        ;extract LSN
         tax                   ;save it
         pla                   ;recover byte
         lsr                   ;extract...
         lsr                   ;MSN
         lsr
         lsr
         pha                   ;save MSN
         txa                   ;LSN
         jsr .0000010          ;generate ASCII LSN
         tax                   ;save
         pla                   ;get MSN & fall thru
;
;
;	convert nybble to hex ASCII equivalent...
;
.0000010 cmp #$0a
         bcc .0000020          ;in decimal range
;
         adc #$66              ;hex compensate
;         
.0000020 eor #%00110000        ;finalize nybble
         rts                   ;done
;
Labels such as .0000010 and .0000020 are local labels.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: Converting byte to hex string

Post by White Flame »

It's a few bytes longer, but a few cycles faster (especially if you avoid the JSR), to look the nybble up in a table of "0123456789ABCDEF". I tend to go that route, since that's often an integral part of IO where I need to maximize speed.
teamtempest
Posts: 443
Joined: 08 Nov 2009
Location: Minnesota
Contact:

Re: Converting byte to hex string

Post by teamtempest »

Ugh. Longer than it needs to be and somewhat obscure.

Code: Select all

;================================================================================
;
;binhex: CONVERT BINARY BYTE TO HEX ASCII CHARS
;
;   ————————————————————————————————————
;   Preparatory Ops: .A: byte to convert
;
;   Returned Values: .A: MSN ASCII char
;                    .X: LSN ASCII char
;                    .Y: entry value
;   ————————————————————————————————————
;
binhex   pha                   ;save byte
         and #%00001111        ;extract LSN
         jsr .0000010
         tax                   ;save ASCII
         pla                   ;recover byte
         lsr                   ;extract...
         lsr                   ;MSN
         lsr
         lsr			
;
;
;   convert nybble to hex ASCII equivalent...
;
; 0 to 9 -> $30 to $39
; 10 to 15 -> $41 to $46
;
.0000010 cmp #10		         ; 0 to 9 ?
         bcc .0000020          ; b: yes - must set bits 4 and 5
;
         adc #103-1            ; 10 to 15 -> 113 to 118
;
; $71 to $76
; %01110001 to %01110110
; - must clear bits 4 and 5
;         
.0000020 eor #%00110000        ;set or clear bits 4 and 5
         rts                   ;done
;

; or perhaps the One True Way as Preached by Leventhal:

.0000010 cmp #10		         ; 0 to 9 ?
         bcc .0000020          ; b: yes ($00 to $09)
;
         adc #'A'-'0'-10-1     ; 10 to 15 -> $11 to $16
;         
.0000020 adc #$30              ; $30 to $39 or $41 to $46
         rts                   ;done
;

Omegamatrix
Posts: 7
Joined: 25 Jan 2015

Re: Converting byte to hex string

Post by Omegamatrix »

How about this?

Code: Select all

;  A = entry value

  sed        ;2  @2
  tax        ;2  @4
  and #$0F   ;2  @6
  cmp #9+1   ;2  @8
  adc #$30   ;2  @10
  tay        ;2  @12
  txa        ;2  @14
  lsr        ;2  @16
  lsr        ;2  @18
  lsr        ;2  @20
  lsr        ;2  @22
  cmp #9+1   ;2  @24
  adc #$30   ;2  @26
  cld        ;2  @28

;  A = MSN ASCII char
;  Y = LSN ASCII char

I ran a short test program and it works. It's very quick at 28 cycles, and just takes 19 bytes. The basic code comes from Lee Davison code shorts.
User avatar
MichaelM
Posts: 761
Joined: 23 Apr 2012
Location: Huntsville, AL

Re: Converting byte to hex string

Post by MichaelM »

There aren't any branches associated with the CMP instructiions. To convert to ASCII hex, a test for 0...9 should be followed by an ORA #$30 (or ADC #$30). But if the nibble is greater than 9, the adjustment for A...F needs to be applied instead.
Last edited by MichaelM on Sun Jan 25, 2015 9:49 am, edited 1 time in total.
Michael A.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Converting byte to hex string

Post by barrym95838 »

He's using the cmp instructions for their carry side-effects, Michael. Combined with the BCD +6 adjustment, the carry flag provides just the right +7 to jump from '9' to 'A' in ASCII.

Mike B.
User avatar
MichaelM
Posts: 761
Joined: 23 Apr 2012
Location: Huntsville, AL

Re: Converting byte to hex string

Post by MichaelM »

Missed the significance of the SED at the beginning. Very cool and sneaky.
Michael A.
Klaus2m5
Posts: 442
Joined: 28 Jul 2012
Location: Wiesbaden, Germany

Re: Converting byte to hex string

Post by Klaus2m5 »

Though there is one problem: It works with invalid BCD digits and might not work on emulators.

I looked at the source code of Lee's EhBASIC. He used that trick in HEX$(). I had to patch it to use binary mode ADC only.
6502 sources on GitHub: https://github.com/Klaus2m5
User avatar
BigDumbDinosaur
Posts: 9427
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Converting byte to hex string

Post by BigDumbDinosaur »

Omegamatrix wrote:
How about this?

Code: Select all

;  A = entry value

  sed        ;2  @2
  tax        ;2  @4
  and #$0F   ;2  @6
  cmp #9+1   ;2  @8
  adc #$30   ;2  @10
  tay        ;2  @12
  txa        ;2  @14
  lsr        ;2  @16
  lsr        ;2  @18
  lsr        ;2  @20
  lsr        ;2  @22
  cmp #9+1   ;2  @24
  adc #$30   ;2  @26
  cld        ;2  @28

;  A = MSN ASCII char
;  Y = LSN ASCII char

I ran a short test program and it works. It's very quick at 28 cycles, and just takes 19 bytes. The basic code comes from Lee Davison code shorts.
I seem to recall trying that one on POC and not having it work right. It may be an issue with 65C816 native mode operation.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
jgjg
Posts: 3
Joined: 25 Dec 2017

Re: Converting byte to hex string

Post by jgjg »

rwiker wrote:
You'll find code for printing a hex byte at http://www.sbprojects.com/projects/apple1/wozmon.txt; search for "PRBYTE" on that page. That's code written by Woz, so should be worth looking at.
Hi, I want to change this code to be able to write on a screen 2 bytes number. It shows only first byte now, I should make a jump to PRHEX before making 4 LSR for sure, but despite trying it doesn't work, so I think there is something I forgot. Can you tell me what is wrong in my thinking?
Klaus2m5
Posts: 442
Joined: 28 Jul 2012
Location: Wiesbaden, Germany

Re: Converting byte to hex string

Post by Klaus2m5 »

Code: Select all

; put this just before PRBYTE
                BMI     PRBYTE

;-------------------------------------------------------------------------
;  Subroutine to print a word in X (low byte) and A (high byte)
;-------------------------------------------------------------------------
PRWORD          JSR     PRBYTE          ;print high byte
                TXA                     ;continue to print low byte

; continue with PRBYTE
6502 sources on GitHub: https://github.com/Klaus2m5
jgjg
Posts: 3
Joined: 25 Dec 2017

Re: Converting byte to hex string

Post by jgjg »

Thank you for your answer. I edited my code as you'd wrote, but it didn't work, it printed high byte all the time. I tried putting

Code: Select all

lda <text
ldx >text
in different positions, because I wonder if it should be executed 2 times, but I haven't had good result yet.

Code: Select all

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

start           equ *

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

                bmi phex
print           jsr phex
                txa

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

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'
                dta b(0)

                org $2E0
                dta a(start)

                end of file
Klaus2m5
Posts: 442
Joined: 28 Jul 2012
Location: Wiesbaden, Germany

Re: Converting byte to hex string

Post by Klaus2m5 »

Prior to "jsr print" I do not see any ldx and A is always loaded with $ba! The "bmi phex" is only necessary in the original context. I suppose $ff80 points to your print string utility.

The original problem seems to be here:

Code: Select all

pr              sta ($80),y
                dey
                rts
You initialize Y with 0 and then attempt to write the characters of a hex word backwards to ($80)+0, ($80)+$ff, ($80)+$fe, ($80)+$fd.

Please note that you should ask this kind of questions in a separate thread in the newbies section with a link to where you found the original code. And remember to post your modifications from the beginning as what you say might not be what you actually have programmed.
6502 sources on GitHub: https://github.com/Klaus2m5
Post Reply