Page 1 of 2

Converting byte to hex string

Posted: Fri Jan 23, 2015 5:47 pm
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

Re: Converting byte to hex string

Posted: Fri Jan 23, 2015 6:32 pm
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.

Re: Converting byte to hex string

Posted: Fri Jan 23, 2015 7:32 pm
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.

Re: Converting byte to hex string

Posted: Fri Jan 23, 2015 9:28 pm
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.

Re: Converting byte to hex string

Posted: Sat Jan 24, 2015 1:09 am
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
;


Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 9:09 am
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.

Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 9:37 am
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.

Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 9:42 am
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.

Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 9:53 am
by MichaelM
Missed the significance of the SED at the beginning. Very cool and sneaky.

Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 11:14 am
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.

Re: Converting byte to hex string

Posted: Sun Jan 25, 2015 10:25 pm
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.

Re: Converting byte to hex string

Posted: Mon Dec 25, 2017 6:08 pm
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?

Re: Converting byte to hex string

Posted: Tue Dec 26, 2017 8:54 am
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

Re: Converting byte to hex string

Posted: Wed Dec 27, 2017 9:17 am
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

Re: Converting byte to hex string

Posted: Wed Dec 27, 2017 10:19 am
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.