!pr1
Short Single-Byte Hex-to-decimal Printer...Bob Sander-Cederlof

Inside DOS there exists a subroutine whose purpose is to convert a single byte into a three digit decimal number, and print it out.  It is called twice from within the CATALOG processor: to print the volume number, and to print the number of sectors in a file.  It isn't very space or speed efficient, and has been picked apart in various articles in Nibble and elsewhere.  The DOS routine is located at $AE42.

In any case, here is a shorter routine that does the same job.  I also added a little test routine which exercises the subroutine by calling it for every possible value of a byte.

Lines 1200-1290 are the test routine.  It is essentially equivalent to:  FOR A = 0 TO 255 : PRINT X" "; : NEXT X.

Lines 1020-1160 are the conversion and print subroutine.  It is written as a loop that runs the Y-register from 2 down to 0.  Line 1030 starts Y=2, and lines 1140-1150 decrement and test Y, like BASIC's NEXT Y.

Another loop keeps subtracting a table entry from the value being converted until the remainder is smaller than the table entry.  The table contains powers of ten.  The first time through, 100 is subtracted as many times as possible.  Each time, the X-register is incremented.  Since line 1040 started X out as the ASCII code for zero, when the inner loop finishes X will have the ASCII code for the next decimal digit of the original value.  Line 1120 calls the monitor COUT routine to print the digit.

The next time through the table value that gets subtracted is 10, and the third and last time through 1 gets subtracted.  So you see that we first print the hundreds digit, then the tens digit, and finally the units digit.

The DOS version takes 40 bytes plus a three byte table, and mine takes 25 bytes plus a three byte table.  It's probably not fair to compare 40 to 25 too unfavorably, because mine does use the X-register while the DOS version does not.  The part of the CATALOG code that prints the number of sectors in a file requires that the X-register not be changed, so mine is not quite compatible as is.  On the other hand, DOS goes to the trouble of saving the value to be printed in location $44, which is unnecessary, and also saves a value in $45 which is otherwise totally ignored.  This foolishness takes place at $ADB9-$ADBF and $AE04-$AE0A.

Anyway, here is my code:
