8. Example 18

# EXAMPLE 18: using the print iterator

# An expanded version of example17.ini, with local functions called as macros.

__ FD ( addr -- nxtaddr ) Print 256 bytes of memory in hex, as 16 rows of 4
__                        32-bit values with ASCII equivalents. The value 
__                        left on the stack, nxtaddr, is the address of the 
__                        next location following the last dumped location.
__                        This helps with repeated FD commands.
__    usage example: 8K FD FD .
#BUFFER
{D

   __  ff ( addr -- ) print ASCII equiv. of the word, in left-to-right order
   `f               __ assume little-endian machine
     3+             __ start at the end of the word
     "!A!d@C@C@C@C" __ print 4 characters (decrementing)
   `

   __  fe ( addr -- ) print the ASCII equivalent of the 4 words
   `e
     "  "              __ output two blanks
     15 over + swap    __ convert addr to end-addr start-addr
     loop 2dup swap <= while   __ while start-addr <= end-addr
       dup mff         __ display the ASCII equivalent of a word
       4+              __ advance to next word
     endloop 2drop     __ remove start-addr end-addr from stack
   `

   __   fd ( addr -- ) dump the 4 words in hex followed by the ASCII
   `d
     dup                __ preserve a copy of addr for fe to use later on
     "!A @a:"           __ print the row address
     " @W @W @W @W"     __ display 4 words
     mfe                __ display ASCII equiv.
     "\n"               __ print newline
   `

  3~&                    __ force addr to be word aligned
  255 over + swap        __ convert addr to end-addr start-addr
  loop 2dup swap <= while   __ while start-addr <= end-addr
    dup mfd 16+          __ display a row and advance start-addr to next row
  endloop
  drop 1+                __ remove start-addr, adjust end-addr to next byte
}
#EXECUTE