.. _command-line:

********************
Console command line
********************

The console interpreter is intended for interactive command line
use. In this mode you have access to a powerful command line
interpreter with command completion, command history and command
line editing.

Your command line history is also saved between sessions in
``~/.dbnut/dbnut.history``. You will also find a file that preserves
the state of your HP-41 calculator in the same directory.


.. index:: command; structure

Command structure
=================

Commands are made up from one or more space separated words.
If a given word is long enough to be a unique match, it does not need
to spelled out in full.

After the command there may be an argument that is specific to the
command, i.e. a string, file path or boolean value.


.. index:: command; completion

Command completion
^^^^^^^^^^^^^^^^^^

Command completion is available using the ``TAB`` key. Pressing
``TAB`` directly at the prompt provides a list of all words that can
be used to start a command:

.. code-block:: none

  (dbnut) <TAB>
  b                 enable            n                 s
  break             exec-file         next              set
  c                 file              nexti             show
  cd                frame             ni                si
  clear             ignore            p                 source
  complete          info              platform          step
  condition         interpreter-exec  plug-in           stepi
  continue          interrupt         print             thread
  delete            kill              pwd               tty
  directory         lua               quit
  disable           maintenance       r
  disassemble       module            run
  (dbnut)

Pressing ``TAB`` will complete the command to the left of the cursor
as far as possible. If the word can be partially completed the
first ``TAB`` will fill in as far as possible:

.. code-block:: sh

  (dbnut) int<TAB>

Results in:

.. code-block:: sh

  (dbnut) inter

Pressing ``TAB`` a second time results in:

.. code-block:: sh

  (dbnut) inter<TAB>
  interpreter-exec  interrupt
  (dbnut) inter


A simple session
================

To get a feeling for how to run a very simple debugging session here
is how it can look.

.. code-block:: none

  $ dbnut --load-module 41cx.mod myimage
  Calypsi debugger for Nut
  listening for user interface connections on port 8080
  (dbnut) b APX
  breakpoint 1
  (dbnut) info breakpoints
  Num      Type            Disp  Enb  Lua/plug-in   Address     What
  1        breakpoint      keep  y    no            0x82af      APX
  (dbnut) r
  running


.. note ::
   A command only need entered with enough characters to make it
   unique. For the command ``info breakpoints`` it is enough to type
   ``i b`` followed by return. This works because the command
   interpreter takes all words in account. The command line completer
   looks at what is to the left of the cursor, so if
   you type ``i<TAB>`` you will get all command alternatives that
   start ``i``. To make it complete to ``info`` you need to type
   ``inf<TAB>`` followed by ``b<TAB>``. However, if you type
   ``i b<TAB>`` it will expanded to ``i breakpoints``.

Now switch to the user interface and turn the calculator on. If this
is the first time you start it, you will be greeted with the well
known ``MEMORY LOST`` message indicating that the calculator firmware
has initialized the calculator properly for the first time.

Enter the number ``48`` in the HP-41 user interface. Now execute the
``APX`` command, which happens to be the name of
the command as well as entry point label in the MCODE program.

Once you do ``XEQ ALPHA APX ALPHA`` the user interface freezes as the
debugger takes control when the breakpoint is hit.

.. index:: program context, context; program

.. code-block:: none

  (dbnut) r
  running
  program hit breakpoint 1
     1 #include "mainframe.h"
     2
     3               .pubweak APX
     4               .name   "APX"
  -> 5 APX:          c=0                   ; initialize REG.9 for DIGENT
     6               c=c-1
     7               c=0     xs
     8               pt=     13
     9               lc      10            ; initial D.P. position
  0x82af at stack/apx.s:5
  (dbnut)

The breakpoint is hit at address ``0x82af`` in the source file
``stack/apx.s:5``. Some source lines are shown as context with the
current line indicated.

We can now perform a couple of single steps:

.. code-block:: none

  (dbnut) s
      2
      3               .pubweak APX
      4               .name   "APX"
      5 APX:          c=0                   ; initialize REG.9 for DIGENT
  ->  6               c=c-1
      7               c=0     xs
      8               pt=     13
      9               lc      10            ; initial D.P. position
     10               regn=c  9
  0x82b0 at stack/apx.s:6
  (dbnut)
      3               .pubweak APX
      4               .name   "APX"
      5 APX:          c=0                   ; initialize REG.9 for DIGENT
      6               c=c-1
  ->  7               c=0     xs
      8               pt=     13
      9               lc      10            ; initial D.P. position
     10               regn=c  9
     11               gosub   STBT10        ; copy status bits for DIGENT
  0x82b1 at stack/apx.s:7
  (dbnut)

We use the step command that can be entered as ``s``. This steps one
source line. The second step we simply press ``RETURN`` which repeats
the previous command (``s`` in this case).

Each step moves us one line further ahead and the source context shown
moves along with it.

We can inspect registers with ``info registers``.

.. code-block:: none

  (dbnut) info registers
  pc                  82b1
  cy                     1 yes
  a         00000008000000 0.0000008000.000
  b         0000000000e005 0.000000000e.005
  c         ffffffffffffff f.ffffffffff.fff
  m         900a38582afa80 9.00a38582af.a80
  n         00000008000000 0.0000008000.000
  g                     a3
  f                     00
  st                    00
  sth                   02
  p                      1
  q                      d
  pactive                1 yes
  cycles  000000000000487c
  (dbnut)

The first column shows the register name, the second is the hex value
of it and the third column shows the same value in a more decorative
way (for some registers).

.. hint::

   The ``cycles`` register is the cycle counter as a 64-bit hex
   number. This is very useful for evaluating performance of sections
   of code. Simply stop at strategic places and read the ``cycles``
   register, then compute the difference.

.. hint::

   A good calculator which can work in different number bases and word
   sizes is very useful when debugging MCODE. The HP-16C calculator or
   the Ladybug module for the HP-41 are very powerful tools for this.

Looking at the source code, we realize that we want to stop next at a
certain line a bit further down, this can be done as follows:

.. code-block:: none

  (dbnut) b apx.s:49
  breakpoint 2
  (dbnut) c
  running
  program hit breakpoint 2
     45               acex    s
     46               rcr     -1
     47               pt=     0
     48               g=c
  -> 49               gosub   DIGENT
     50               gosub   NOREG9        ; normalize and move to X
     51               bcex    x             ; decrement exponent
     52               c=c-1   x
     53               ?c#0    xs            ; negative (hit fractional part?)
  0x82dd at stack/apx.s:49
  (dbnut)

The ``continue`` command (short form ``c``) is used to resume
execution (not ``run`` which runs the program from start).

Here we want to see what we are passing in to ``DIGENT``. We could
display the registers again, but we can also show that value by just
displaying the ``G`` register. We can do this by printing an
expression (using the ``print`` or ``p`` command). A register name
need to be preceded by a dollar sign:

.. code-block:: none

  (dbnut) p $g
  $1 = 16
  (dbnut) p/x $g
  $2 = 0x10
  (dbnut)

We got ``16`` and realized it was in decimal. Passing the ``/x``
modifier to the print command gives the value in hexadecimal.

We can also display a part of a register using a field. In this case
we have a counter in the ``X`` (exponent) field of the ``B`` register:

.. code-block:: none

  (dbnut) p/x $b.x
  $3 = 0x1
  (dbnut)


It is apparently ``1`` at this point.
Now step over the ``gosub`` we are standing at. This can be done using
the ``next`` command (or ``n`` for short).

.. code-block:: none

  (dbnut) n
     46               rcr     -1
     47               pt=     0
     48               g=c
     49               gosub   DIGENT
  -> 50               gosub   NOREG9        ; normalize and move to X
     51               bcex    x             ; decrement exponent
     52               c=c-1   x
     53               ?c#0    xs            ; negative (hit fractional part?)
     54               goc     25$           ; yes
  0x82df at stack/apx.s:50
  (dbnut)

We realize that we do not need to use the first breakpoint anymore.
It can be removed using ``delete``, but we decide to to disable it
using the ``disable`` command instead:

.. code-block:: none

  (dbnut) disable 1
  (dbnut) info breakpoints
  Num      Type            Disp  Enb  Lua/plug-in   Address     What
  1        breakpoint      keep  n    no            0x82af      APX
           breakpoint already hit 1 time
  2        breakpoint      keep  y    no            0x82dd      apx.s:49
           breakpoint already hit 1 time
  (dbnut)

Here we can see that the first breakpoint still exists, but it is not
enabled (``n`` in the ``Enb`` column). We can also see that the
debugger also keeps track of statistics about the breakpoints.
