Jump to content

Printing Hex values, with thanks to Woz


rje
 Share

Recommended Posts

Last month I was writing a little routine to print numbers in hex, and I got stuck.  Today I picked it up and realized that I was very close to a solution, but surely someone has already solved this problem.  And indeed, Steve Wozniak gave me valuable pointers in his wozmon.txt file... in particular:

  • PUSH the value onto the stack to save the cycles of having to LDA later.
  • Use ORA instead of ADC for the initial add, and use a BCC when testing for a digit.

That second point proved to be the key to solving my code problem.  At any rate, here's my working code:

;
; Prints an 8 bit value in hex.
;
; Author:               Robert Eaglestone with valuable advice from Steve Wozniak
; More Info:            wozmon.txt
;
; System:               Commander X16
; Version:              Emulator R.37
; Compiler:             CC65
; Build using:  cl65 -t cx16 hex.s -C cx16-asm.cfg -o HEX.PRG
;
chrout          = $ffd2         ; Commodore Kernal RULES!
.org    $8000
.export LOADADDR = *

; $8000
value:          .byte 0         ; 0-255

; $8001
Main:           lda value
                pha             ; save A for LSD
print_hi:       ;
                ; print the high nybble
                ;
                lsr             ; shift right four bits
                lsr
                lsr
                lsr
                jsr hex
print_lo:       ;
                ; print the low nybble
                ;
                pla             ; fetch for LSD
hex:
                and #$0f
                ora #$30        ; i.e. "0"
                cmp #$3a        ; digit?
                bcc echo        ; yes
                adc #6          ; add offset for A
echo:
                jsr chrout      ; print it
                rts
	

 

Edited by rje
Link to comment
Share on other sites

21 hours ago, desertfish said:

I'm using this, with a lookup table to save some cycles.   Input in A, returns the two digits in A and Y.


      pha
      and  #$0f
      tax
      ldy  _hex_digits,x
      pla
      lsr  a
      lsr  a
      lsr  a
      lsr  a
      tax
      lda  _hex_digits,x
      rts

_hex_digits    .text "0123456789abcdef"

Yep, that is the easiest to use and understand, however Steves version is shorter. It is using the trick that the letters follow the numbers .. great idea. 

Link to comment
Share on other sites

  • Super Administrators
On 8/29/2020 at 2:54 PM, SerErris said:

Yep, that is the easiest to use and understand, however Steves version is shorter. It is using the trick that the letters follow the numbers .. great idea. 

I think desertfish's version is likely to be faster, and it's certainly more legible... but there's definitely an elegance to Butterfield's method. 

As to space... it's only about 8 bytes difference, and as it's the textbook method (literally... this is how we were taught to do it back in 1984), I still prefer the lookup method. 

However... I can't help but be impressed when I see Wozniak break at least three rules of software engineering... and yet the program is perfectly suited for its use. 

Edited by TomXP411
name correction
  • Like 1
Link to comment
Share on other sites

6 minutes ago, TomXP411 said:

I think SerErris's version is likely to be faster, and it's certainly more legible... but there's definitely an elegance to Butterfield's method. 

As to space... it's only about 8 bytes difference, and as it's the textbook method (literally... this is how we were taught to do it back in 1984), I still prefer the lookup method. 

However... I can't help but be impressed when I see Butterfield break at least three rules of software engineering... and yet the program is perfectly suited for its use. 

Thanks for the flowers, but non of the examples was from me 🙂 Credits go to rje (I assume you mean his approach).

Link to comment
Share on other sites

8 bytes no longer matters, I think it's safe to say, although I more often feel the pull towards smaller trumps faster... even though context is king.  Was it Knuth who said you should have both (a) a fast routine and (b) an efficient routine handy?   (I don't think it was Knuth.  It was someone like that tho.)

Will acquire a copy of Butterfield's book.  Thank you.

 

Edited by rje
Link to comment
Share on other sites

  • Super Administrators
2 hours ago, SerErris said:

Thanks for the flowers, but non of the examples was from me 🙂 Credits go to rje (I assume you mean his approach)

Actually, I was referring to the lookup table method, which desertfish posted first in this thread. My code is a little different, but does essentially the same thing. 

51 minutes ago, rje said:

8 bytes no longer matters, I think it's safe to say, although I more often feel the pull towards smaller trumps faster... even though context is king.

That's the important thing to remember. Sometimes you need 8 more  bytes of RAM. Sometimes you need 30 clock cycles. I'd probably make a different choice on a VIC-20 than I'd make on a Commodore 128 - one has only 4K of RAM, but the other one has a slower execution speed. 

 

  • Like 1
Link to comment
Share on other sites

  • Super Administrators
2 hours ago, BruceMcF said:

If you are worried about execution speed and have the C138 down as slower than the Vic-20, you are using the wrong video mode, time to crank the C128 up to 2MH.

🙄 tooootally missing the point.  Sometimes you need it to go fast, and sometimes you need it to use less memory... you can't always have both.

 

 

Edited by TomXP411
Link to comment
Share on other sites

2 hours ago, TomXP411 said:

🙄 tooootally missing the point.  Sometimes you need it to go fast, and sometimes you need it to use less memory... you can't always have both.

Yes, but I was not responding to the point you were trying to make, but to the claim you made enroute to your point ... with the VIC-20 being the only one that ever has only 4K of RAM (out of the box), that leaves the C128 being "but the other one has slower execution speed", which is only marginally true and only if electing to run it in slow mode with the VIC IIE slowing it down.

Edited by BruceMcF
Link to comment
Share on other sites

19 hours ago, SerErris said:

That solution was btw already in Jim Butterfields excellent Book 

Ah yes, my first ever ML Monitor, SuperMon, a type-in program right out of Jim Butterfield's book.  I eventually got a more full-featured ML Monitor cartridge for the the C64 (HES Mon), but messing around with ML in SuperMon is how I 'made the leap' from being confused by computers to feeling like I might be able to understand them someday.  Big thanks all these decades later to Jim Butterfield.

Sorry for the digression; I have no comment on which method of displaying Hex is preferable.

Edited by John Chow Seymour
  • Haha 1
Link to comment
Share on other sites

  • Super Administrators
12 hours ago, BruceMcF said:

Yes, but I was not responding to the point you were trying to make, but to the claim you made enroute to your point ... with the VIC-20 being the only one that ever has only 4K of RAM (out of the box), that leaves the C128 being "but the other one has slower execution speed", which is only marginally true and only if electing to run it in slow mode with the VIC IIE slowing it down.

And yet nobody else felt the need to nitpick that tiny detail, which again totally missed the point of "smaller vs faster."

Edited by TomXP411
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use