Well, I'm still not convinced that there's an advantage in this case, although it does sound more suited to machine language. The only padding I had to do (the way you describe) was to bring the HEX range user input values to a fixed 4 digits, but I think as in B 9's example it probably makes more sense to input in decimal.
I think I'll leave the Forth version for another day ;-) m ----- Original Message ----- From: John R. Hogerhuis To: [email protected] Sent: Friday, October 28, 2022 5:52 PM Subject: Re: [M100] Notoriously S.L.O.W BASIC posted - help speeding it up appreciated On Thu, Oct 27, 2022 at 6:04 PM Mike Stein <[email protected]> wrote: I don't see where it makes much difference In general in BASIC but in this case there is a justification for MSB first ;-) It goes from MSB to LSB because the same routine does 4 or 2 digits depending on where you enter; line 5 gives the 4 digit address and it falls through to line 7 which also gives the 2 digit bytes peeked and creates the ASCII value for the text on the right hand side. The general idea is to do-while convert until you get to zero on the value being converted to string. So in reverse, you wouldn't need multiple entry points, it works for either 1-4 nibbles length. That leaves a question of zero-padding, but RIGHT$("000"+D$, 2 or 4) always works. FWIW, Forth's "pictured numeric output" is organized around this principle of LSB to MSB. It goes beyond radix conversions to support advanced number formatting like BASIC supports through PRINT USING. It probably helps that Forthers are used to doing everything backwards ;-) https://www.jimbrooks.org/archive/programming/forth/forthPicturedNumericOutput.php Also of note for M100 specifically, MFORTH has a built-in DUMP word that can be compared for speed, though I actually don't know if that word is implemented in ML or threaded code. There's also an 8085 assembler for it, so it should make a nice environment for directly experimenting with machine code. -- John. I suppose going the other way I'd always have to start at the beginning and return after two digits 'if' doing peeks instead of addresses; more complicated IMO. m On Thu, Oct 27, 2022 at 6:04 PM John R. Hogerhuis <[email protected]> wrote: On Thu, Oct 27, 2022 at 1:10 PM MikeS <[email protected]> wrote: More good tips, thanks. Yes, I have to look at defining the various types, especially the ones that can go above 32768. Concatenation with '+' is a habit from other languages I've worked with; as a matter of fact in most cases the M100 lets you print without any separators at all, e.g. print A$" to "B$ or a"plus"b Interesting discussion (at least for some of us ;-) ) One overall thing in outputting numbers in any radix, is that it is *usually* most tractable in reverse of how you output since we generally write/read numbers with the most significant digit first. So for generating a number to output, It is most efficient to extract the least significant digit, shift or otherwise divide by the radix, prepend the extracted number onto a string/buffer, and when the value gets to zero, you're done, output the string. So for the number 1235 in decimal, 1235 MOD 10 = 5. Prepend ASC('0') + 5 on buffer. Divide remaining value by 10 123 MOD 10 = 3. Prepend ASC('0') + 3 on buffer. Divide remaining value by 10 12 MOD 10 = 2. Prepend ASC('0') + 2 on buffer. Divide remaining value by 10 1 MOD 10 = 1. Prepend ASC('0') + 1 on buffer. Divide remaining value by 10 Remaining value is 0, so we're done. Buffer contains the number In your subroutine at 5 it is doing it MSB to LSB, I think. Overall your way may still be faster in BASIC even with the larger divisors. With hex it's a question though since MOD 16 can be done with AND 15 which is probably faster than a general integer 16 modulus. There's no bitshift operator so you still need a integer divide by 16%. Who knows how efficient an integer divide by 16 is in the interpreter versus 4096 (integer) divides. -- John.
