Convert a byte as hex string (to display on screen)

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
Post Reply
User avatar
Symoon
Archivist
Posts: 1101
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Convert a byte as hex string (to display on screen)

Post by Symoon » Fri Aug 04, 2017 7:41 pm

One thing I always thought would be boring to do in assembler, is having to convert a byte value to display it on screen.
For instance, A contains the value #60. If you directly put it on screen, on the Oric you'll get the ASCII char for "(c)".
But how to display "60" instead, which will require two bytes ? ("6" and "0").

I got the answer very quickly thanks to the forum at 6502.org, which had this topic and an incredible solution I'm copying/pasting here with a little extra (and sad) information about its author...

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
28 cycles, 19 bytes. The code comes from Lee Davison code shorts website. This site disappeared but can still be found on Wayback Machine, along with some other sites trying to put back its content online.
Lee passed away peacefully in his sleep on September 21, 2013. Being a Sunday coder in 6502, I had never heared of him, but he seems to have a well deserved good reputation, which the efficiency of the above code can confirm.

Thanks to this code I can display values while an Oric program is loading. Priceless.

User avatar
Chema
Game master
Posts: 1971
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Chema » Sun Aug 06, 2017 1:50 pm

Indeed it is a nice piece of code!

I never manage to make the correct comparisons or use of the decimal mode for these things. :)

By the way you can also use a 16-byte table (4 bit value - ascii code) and even save a few more cycles. No need for comparisons nor additions. Not sure about total cycles (need to move things to x or y and do a table access for each code) ... can't check now, but maybe worth to try :)

User avatar
Silicebit.
Flying Officer
Posts: 220
Joined: Thu Jan 12, 2006 10:18 pm
Location: Madrid, Spain
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Silicebit. » Sun Aug 06, 2017 9:54 pm

Chema wrote:
Sun Aug 06, 2017 1:50 pm
Indeed it is a nice piece of code!

I never manage to make the correct comparisons or use of the decimal mode for these things. :)

By the way you can also use a 16-byte table (4 bit value - ascii code) and even save a few more cycles. No need for comparisons nor additions. Not sure about total cycles (need to move things to x or y and do a table access for each code) ... can't check now, but maybe worth to try :)

An example. :-)

Code: Select all

; A = entry value
;
PHA
LSR
LSR
LSR
LSR
TAY
LDX table,Y
JSR $CCFB ;Routine ROM print Atmos
PLA
AND #$0F
TAY
LDX table,Y
JSR $CCFB ;Routine ROM print Atmos
RTS
;
table .byte 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 ; 0 1 2 3 4 5 6 7 8 9 A B C D E F
Oric user since 1984. YouTube

User avatar
Silicebit.
Flying Officer
Posts: 220
Joined: Thu Jan 12, 2006 10:18 pm
Location: Madrid, Spain
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Silicebit. » Sun Aug 06, 2017 11:45 pm

Other more simple routine. :-)

Code: Select all

; A = entry value
;
TAX
LSR
LSR
LSR
LSR
TAY
TXA
LDX table,Y
AND #$0F
TAY
LDA table,Y
RTS
;
table .byte 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 ; 0 1 2 3 4 5 6 7 8 9 A B C D E F
;
; X = MSN ASCII char
; A = LSN ASCII char
Oric user since 1984. YouTube

User avatar
Symoon
Archivist
Posts: 1101
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Symoon » Mon Aug 07, 2017 6:00 am

Nice!
If I'm counting right, the table solution (the latest one, being closer to the 1st routine posted) is two cycles faster ;)
For 32 bytes (I'm not counting the RTS) against 19 though. But it all depends on what has to be optimised, the speed gain has a cost :)

User avatar
Dbug
Site Admin
Posts: 2322
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Dbug » Mon Aug 07, 2017 7:03 am

Be careful when playing with the decimal mode: That can have surprising effect on an interrupt routine that can trigger between the calls to SED and CLD.

User avatar
Symoon
Archivist
Posts: 1101
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Symoon » Mon Aug 07, 2017 9:04 am

Dbug wrote:
Mon Aug 07, 2017 7:03 am
Be careful when playing with the decimal mode: That can have surprising effect on an interrupt routine that can trigger between the calls to SED and CLD.
Do you mean ideally the author should have disabled the interrupts first? (In my case, as I'm operating while a program is loading, there are no interrupts... So it should be fine, but I didn't think about that risk).

User avatar
Chema
Game master
Posts: 1971
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Chema » Mon Aug 07, 2017 12:15 pm

And change
JSR $CCFB ;Routine ROM print Atmos
RTS

With
jmp $ccfb

to scratch a few more cycles :)

User avatar
Symoon
Archivist
Posts: 1101
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Symoon » Mon Aug 07, 2017 12:36 pm

Chema wrote:
Mon Aug 07, 2017 12:15 pm
And change
JSR $CCFB ;Routine ROM print Atmos
RTS

With
jmp $ccfb

to scratch a few more cycles :)
In my little program, I am actually directly printing myself the bytes at the desired screen address. Managing it myself saved lots of cycles - especially when, trying to count the ROM routine cost, I had the feeling it was calling itself! Guess I was wrong somewhere ;)
Of course this leads to other problems (like, when the program ends, "Ready" being printed over some of what the program may have displayed ;) )

User avatar
Dbug
Site Admin
Posts: 2322
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Convert a byte as hex string (to display on screen)

Post by Dbug » Mon Aug 07, 2017 4:50 pm

Symoon wrote:
Mon Aug 07, 2017 9:04 am
Dbug wrote:
Mon Aug 07, 2017 7:03 am
Be careful when playing with the decimal mode: That can have surprising effect on an interrupt routine that can trigger between the calls to SED and CLD.
Do you mean ideally the author should have disabled the interrupts first? (In my case, as I'm operating while a program is loading, there are no interrupts... So it should be fine, but I didn't think about that risk).
Not necessarily, but basically you have to remember that most of the code on the machine assumes that some flags are set-up in a certain way, and only perform the minimum necessary for the operations to be completed correctly. If any of this code is called with a totally different set of parameters, it can misbehave.
That could be any ROM routine you call in between, or an IRQ triggering.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests