6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 8:15 pm

All times are UTC




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Jan 23, 2015 5:47 pm 
Offline
User avatar

Joined: Sun Sep 08, 2013 10:24 am
Posts: 740
Location: A missile silo somewhere under southern England
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:
' 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


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 23, 2015 6:32 pm 
Offline

Joined: Thu Mar 03, 2011 5:56 pm
Posts: 284
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.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 23, 2015 7:32 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
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:
;================================================================================
;
;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!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 23, 2015 9:28 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 679
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.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 24, 2015 1:09 am 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 411
Location: Minnesota
Ugh. Longer than it needs to be and somewhat obscure.

Code:
;================================================================================
;
;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
;



Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 9:09 am 
Offline

Joined: Sun Jan 25, 2015 8:13 am
Posts: 7
How about this?

Code:
;  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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 9:37 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Last edited by MichaelM on Sun Jan 25, 2015 9:49 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 9:42 am 
Offline
User avatar

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


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 9:53 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Missed the significance of the SED at the beginning. Very cool and sneaky.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 11:14 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
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


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 25, 2015 10:25 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
Omegamatrix wrote:
How about this?

Code:
;  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!


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 25, 2017 6:08 pm 
Offline

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 26, 2017 8:54 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Code:
; 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


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 27, 2017 9:17 am 
Offline

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


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 27, 2017 10:19 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
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:
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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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: