.. index:: !Jacobs-DeArras;instructions
.. index:: !instructions;Jacobs-DeArras

==============================
Jacobs-DeArras instruction set
==============================

This chapter summarizes the Jacobs-DeArras instruction set without
going into deep details.

.. index:: jumps;non-local, non-local jumps, mainframe;calling

Non-local jump instructions
---------------------------

These instructions will jump to an absolute address within the 64K
memory space. They are used for calling entries in the mainframe ROM
and some fixed page located ROMs, typically in the address range
``0000``--``7FFF``.

.. table:: Non-local jumps
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+----------------+
 |Mnemonic        |Operand         |Description     |
 +================+================+================+
 |``?ncxq``       |*expr*          |Absolute jump to|
 |                |                |subroutine      |
 +----------------+----------------+----------------+
 |``?cxq``        |*expr*          |Absolute jump to|
 |                |                |subroutine on   |
 |                |                |carry set       |
 +----------------+----------------+----------------+
 |``?ncgo``       |*expr*          |Absolute jump   |
 +----------------+----------------+----------------+
 |``?cgo``        |*expr*          |Absolute jump on|
 |                |                |carry set       |
 +----------------+----------------+----------------+


.. index:: jumps;local, local jumps, local branch instructions

Local branches
--------------

Local branch instructions are position independent branches.
They are rather short distance, -63 to 64 words.

.. table:: Local jumps
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+----------------+
 |Mnemonic        |Operand         |Description     |
 +================+================+================+
 |``jnc``         |*expr*          |Synonym for     |
 |                |                |``goto``        |
 +----------------+----------------+----------------+
 |``jc``          |*expr*          |Short branch on |
 |                |                |carry set       |
 +----------------+----------------+----------------+


.. index:: page relocatable jumps, jumps;page relocatable

Page relocatable jumps
----------------------

These instructions take 3 words and are made up by a 2-word non-local
``?ncxq`` to a mainframe routine that reads the third word and uses
that as part of the destination. They work inside a 4K ROM page.

As they are implemented with the ``?ncxq`` instruction, you need to
ensure that the carry flag is not set when executing the instruction,
otherwise the ``?ncxq`` will be skipped and you end up executing the
third (page offset) word as an instruction, which is probably not what
you intended.

The linker will pick the appropriate mainframe routine to use
depending on the jump location and its destination.


.. table:: Page relative jumps
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+----------------+
 |Mnemonic        |Operand         |Description     |
 +================+================+================+
 |``rxq``         |*expr*          |4K page         |
 |                |                |relocatable jump|
 |                |                |to subroutine   |
 +----------------+----------------+----------------+
 |``rgo``         |*expr*          |4K page         |
 |                |                |relocatable jump|
 +----------------+----------------+----------------+



.. index:: return instructions, instructions;return, instructions;indirect jumps

Other jump and subroutine instructions
--------------------------------------

.. table::
 :widths: 1 4
 :column-dividers: none single none

 +----------------+----------------+
 |Mnemonic        |Description     |
 +================+================+
 |``gotoadr``     |Jump to address |
 |                |in ``C[6:3]``   |
 |                |                |
 +----------------+----------------+
 |``pushadr``     |Push ``C[6:3]`` |
 |                |on stack        |
 |                |                |
 +----------------+----------------+
 |``popadr``      |Pop stack to    |
 |                |``C[6:3]``      |
 +----------------+----------------+
 |``xq>go``       |Pop stack and   |
 |                |discard value   |
 +----------------+----------------+
 |``rtn``         |Return from     |
 |                |subroutine      |
 +----------------+----------------+
 |``?ncrtn``      |Return from     |
 |                |subroutine if   |
 |                |carry clear     |
 +----------------+----------------+
 |``?crtn``       |Return from     |
 |                |subroutine if   |
 |                |carry set       |
 +----------------+----------------+


.. index:: pointer instructions, instructions;pointer

Pointer instructions
--------------------

There are two pointers, P and Q. They are used to describe which part
of a 56-bit register to operate on, but they can also be used as
counters. One pointer register is active at any given time.

.. table:: Pointer instructions
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+----------------+
 |Mnemonic        |Operand         |Description     |
 +================+================+================+
 |``slctp``       |                |Select pointer P|
 +----------------+----------------+----------------+
 |``slctq``       |                |Select pointer Q|
 +----------------+----------------+----------------+
 |``?p=q``        |                |Test if P and Q |
 |                |                |pointers are    |
 |                |                |equal           |
 +----------------+----------------+----------------+
 |``r=r-1``       |                |Decrement       |
 |                |                |current pointer |
 +----------------+----------------+----------------+
 |``r=r+1``       |                |Increment       |
 |                |                |current pointer |
 +----------------+----------------+----------------+
 |``r=``          |*expr*          |Set current     |
 |                |                |pointer         |
 +----------------+----------------+----------------+
 |``?r=``         |*expr*          |Test if current |
 |                |                |pointer equals  |
 |                |                |value           |
 +----------------+----------------+----------------+



.. index:: arithmetic instructions, class two instructions, instructions;class two

Arithmetic instructions
-----------------------

Arithmetic instructions take a *field* argument describing which part of
the register to operate on.

.. table:: Fields
 :widths: 1 4
 :column-dividers: none single none

 +----------------+---------------------+
 |Field           |Description          |
 +================+=====================+
 |``@r``          |At pointer           |
 +----------------+---------------------+
 |``s&x``         |Exponent             |
 +----------------+---------------------+
 |``r<-``         |Word up to pointer   |
 +----------------+---------------------+
 |``all``         |Word                 |
 +----------------+---------------------+
 |``p-q``         |Between pointers     |
 +----------------+---------------------+
 |``xs``          |Exponent sign        |
 +----------------+---------------------+
 |``m``           |Mantissa             |
 +----------------+---------------------+
 |``ms``          |Sign of mantissa     |
 +----------------+---------------------+


.. table:: Arithmetic instructions
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+---------------------------------------+
 |Mnemonic        |Operand         |Description                            |
 +================+================+=======================================+
 |``a=0``         |*field*         |Clear (part of) ``A`` register         |
 +----------------+----------------+---------------------------------------+
 |``b=0``         |*field*         |Clear (part of) ``B`` register         |
 +----------------+----------------+---------------------------------------+
 |``c=0``         |*field*         |Clear (part of) ``C`` register         |
 +----------------+----------------+---------------------------------------+
 |``a<>b``        |*field*         |Exchange (part of) ``A`` and ``B``     |
 |                |                |registers                              |
 +----------------+----------------+---------------------------------------+
 |``b=a``         |*field*         |Move (part of) ``A`` to ``B`` register |
 +----------------+----------------+---------------------------------------+
 |``a<>c``        |*field*         |Exchange (part of) ``A`` and ``C``     |
 |                |                |registers                              |
 +----------------+----------------+---------------------------------------+
 |``c=b``         |*field*         |Move (part of) ``B`` to ``C`` register |
 +----------------+----------------+---------------------------------------+
 |``c<>b``        |*field*         |Exchange (part of) ``B`` and ``C``     |
 |                |                |registers                              |
 +----------------+----------------+---------------------------------------+
 |``a=c``         |*field*         |Move (part of) ``C`` to ``A`` register |
 +----------------+----------------+---------------------------------------+
 |``a=a+b``       |*field*         |Add (part of) register                 |
 +----------------+----------------+---------------------------------------+
 |``a=a+c``       |*field*         |Add (part of) register                 |
 +----------------+----------------+---------------------------------------+
 |``a=a+1``       |*field*         |Increment (part of) register           |
 +----------------+----------------+---------------------------------------+
 |``a=a-b``       |*field*         |Subtract (part of) register            |
 +----------------+----------------+---------------------------------------+
 |``a=a-1``       |*field*         |Decrement (part of) register           |
 +----------------+----------------+---------------------------------------+
 |``a=a-c``       |*field*         |Subtract (part of) register            |
 +----------------+----------------+---------------------------------------+
 |``c=c+c``       |*field*         |Bit shift left (part of) ``C``         |
 |                |                |register                               |
 +----------------+----------------+---------------------------------------+
 |``c=a+c``       |*field*         |Add (part of) register                 |
 +----------------+----------------+---------------------------------------+
 |``c=c+a``       |*field*         |Synonym for previous instruction       |
 +----------------+----------------+---------------------------------------+
 |``c=c+1``       |*field*         |Increment (part of) register           |
 +----------------+----------------+---------------------------------------+
 |``c=a-c``       |*field*         |Subtract (part of) register            |
 +----------------+----------------+---------------------------------------+
 |``c=c-1``       |*field*         |Decrement (part of) register           |
 +----------------+----------------+---------------------------------------+
 |``c=0-c``       |*field*         |One complement (part of )              |
 |                |                |register                               |
 +----------------+----------------+---------------------------------------+
 |``c=-c-1``      |*field*         |Two complement (part of)               |
 |                |                |register                               |
 +----------------+----------------+---------------------------------------+
 |``?a#0``        |*field*         |Test if (part of) ``A`` is non-zero    |
 +----------------+----------------+---------------------------------------+
 |``?b#0``        |*field*         |Test if (part of) ``B`` is non-zero    |
 +----------------+----------------+---------------------------------------+
 |``?c#0``        |*field*         |Test if (part of) ``C`` is non-zero    |
 +----------------+----------------+---------------------------------------+
 |``?a<c``        |*field*         |Test if (part of) ``A`` is less than   |
 |                |                |``C``                                  |
 +----------------+----------------+---------------------------------------+
 |``?a<b``        |*field*         |Test if (part of) ``A`` is less than   |
 |                |                |``B``                                  |
 +----------------+----------------+---------------------------------------+
 |``?a#c``        |*field**        |Test if (part of) ``A`` is not equal   |
 |                |                |to ``C``                               |
 +----------------+----------------+---------------------------------------+
 |``rshfa``       |*field**        |Nibble shift (part of) ``A`` right     |
 +----------------+----------------+---------------------------------------+
 |``rshfb``       |*field**        |Nibble shift (part of) ``B`` right     |
 +----------------+----------------+---------------------------------------+
 |``rshfc``       |*field**        |Nibble shift (part of) ``C`` right     |
 +----------------+----------------+---------------------------------------+
 |``lshfa``       |*field*         |Nibble shift (part of) ``A`` left      |
 +----------------+----------------+---------------------------------------+


.. index:: flag instructions, instructions;flags

Flag instructions
-----------------

.. table::
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+----------------+
 |Mnemonic        |Operand         |Description     |
 +================+================+================+
 |``clrf``        |*expr*          |Clear flag      |
 +----------------+----------------+----------------+
 |``setf``        |*expr*          |Set flag        |
 +----------------+----------------+----------------+
 |``?fset``       |*expr*          |Test flag       |
 +----------------+----------------+----------------+
 |``st=0``        |                |Clear flags     |
 |                |                |``0``--``7``    |
 +----------------+----------------+----------------+
 |``st=c``        |                |Copy ``C[0:1]`` |
 |                |                |to flags        |
 |                |                |``0``--``7``    |
 +----------------+----------------+----------------+
 |``c=st``        |                |Copy flags      |
 |                |                |``0``--``7`` to |
 |                |                |``C[0:1]``      |
 +----------------+----------------+----------------+
 |``c<>st``       |                |Exchange        |
 |                |                |``C[0:1]`` with |
 |                |                |flags           |
 |                |                |``0``--``7``    |
 +----------------+----------------+----------------+


.. index:: RAM memory instructions, instructions;RAM memory

RAM memory instructions
-----------------------

RAM comes in units of 16 registers. You select a register to operate
on and then read or write that particular register. It is also
possible to access registers within the same 16 register unit, [#RegZero]_
but in practise, this is only useful for the very first 16 registers.

.. rubric:: Footnotes
.. [#RegZero] Reading register ``0`` is special because it does not
              exist. Instead that opcode is used for ``c=data``, read
              the current selected register.

.. table:: RAM memory instructions
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+-------------------+
 |Mnemonic        |Operand         |Description        |
 +================+================+===================+
 |``ramslct``     |                |Select RAM         |
 |                |                |memory register    |
 |                |                |location           |
 +----------------+----------------+-------------------+
 |``writedata``   |                |Write ``C``        |
 |                |                |register to        |
 |                |                |selected RAM       |
 |                |                |location           |
 +----------------+----------------+-------------------+
 |``readdata``    |                |Read from selected |
 |                |                |RAM location to    |
 |                |                |``C`` register     |
 +----------------+----------------+-------------------+
 |``writ``        |*register*      |Write ``C``        |
 |                |                |register to        |
 |                |                |given RAM          |
 |                |                |register           |
 +----------------+----------------+-------------------+
 |``read``        |*register*      |Read given RAM     |
 |                |                |register to        |
 |                |                |``C`` register     |
 |                |                |                   |
 +----------------+----------------+-------------------+


.. index:: RAM registers

.. table:: RAM registers
 :widths: 1 1
 :column-dividers: none single single none

 +--------+-----------+
 |Register|Alternative|
 |number  |           |
 +========+===========+
 |0       |``T``      |
 +--------+-----------+
 |1       |``Z``      |
 +--------+-----------+
 |2       |``Y``      |
 +--------+-----------+
 |3       |``X``      |
 +--------+-----------+
 |4       |``L``      |
 +--------+-----------+
 |5       |``M``      |
 +--------+-----------+
 |6       |``N``      |
 +--------+-----------+
 |7       |``O``      |
 +--------+-----------+
 |8       |``P``      |
 +--------+-----------+
 |9       |``Q``      |
 +--------+-----------+
 |10      |``+``      |
 +--------+-----------+
 |10      |``|-``     |
 +--------+-----------+
 |11      |``a``      |
 +--------+-----------+
 |12      |``b``      |
 +--------+-----------+
 |13      |``c``      |
 +--------+-----------+
 |14      |``d``      |
 +--------+-----------+
 |15      |``e``      |
 +--------+-----------+



.. index:: ROM memory instructions, instructions;ROM memory

ROM memory instructions
-----------------------

.. table::
 :widths: 1 3
 :column-dividers: none single none

 +----------------+------------------------+
 |Mnemonic        |Description             |
 +================+========================+
 |``fetch``       |Read word from          |
 |                |ROM memory              |
 +----------------+------------------------+
 |``wmldl``       |Write to simulated MLDL |
 |                |ROM                     |
 +----------------+------------------------+
 |``enrom1``      |Enable ROM bank         |
 |                |1                       |
 +----------------+------------------------+
 |``enrom2``      |Enable ROM bank         |
 |                |2                       |
 +----------------+------------------------+
 |``enrom3``      |Enable ROM bank         |
 |                |3                       |
 +----------------+------------------------+
 |``enrom4``      |Enable ROM bank         |
 |                |4                       |
 +----------------+------------------------+

.. index:: keyboard instructions, instructions;keyboard

Keyboard instructions
---------------------

.. table::
 :widths: 1 3
 :column-dividers: none single none

 +----------------+----------------+
 |Mnemonic        |Description     |
 +================+================+
 |``c=key``       |Read keycode to |
 |                |``C[4:3]``      |
 +----------------+----------------+
 |``gtokey``      |Put keycode into|
 |                |low part of     |
 |                |``PC``          |
 +----------------+----------------+
 |``clrkey``      |Reset keyboard  |
 +----------------+----------------+
 |``?key``        |Test if key is  |
 |                |down            |
 +----------------+----------------+


Miscellaneous instructions
--------------------------

.. table::
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+---------------------------+
 |Mnemonic        |Operand         |Description                |
 +================+================+===========================+
 |``nop``         |                |No operation               |
 +----------------+----------------+---------------------------+
 |``powoff``      |                |Stop CPU                   |
 +----------------+----------------+---------------------------+
 |``ld@r``        |*expr*          |Load 4-bit value to ``C``  |
 |                |                |register at pointer        |
 |                |                |selected nibble            |
 +----------------+----------------+---------------------------+
 |``ldi``         |*expr*          |Load 10-bits immediate to  |
 |                |                |``C.X``                    |
 +----------------+----------------+---------------------------+
 |``selp``        |*expr*          |Select smart peripheral    |
 +----------------+----------------+---------------------------+
 |``?fi``         |*expr*          |Test if I/O flag is pulled |
 +----------------+----------------+---------------------------+
 |``rcr``         |*expr*          |Rotate ``C`` register      |
 |                |                |right, both positive and   |
 |                |                |negative values are        |
 |                |                |accepted                   |
 +----------------+----------------+---------------------------+
 |``sethex``      |                |Set binary arithmetic mode |
 +----------------+----------------+---------------------------+
 |``setdec``      |                |Set BCD arithmetic mode    |
 +----------------+----------------+---------------------------+
 |``c=n``         |                |Move ``N`` to ``C``        |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``n=c``         |                |Move ``C`` to ``N``        |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``c<>n``        |                |Exchange ``C`` and ``N``   |
 |                |                |registers                  |
 +----------------+----------------+---------------------------+
 |``c=m``         |                |Move ``M`` to ``C``        |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``m=c``         |                |Move ``C`` to ``M``        |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``c<>m``        |                |Exchange ``C`` and ``M``   |
 |                |                |registers                  |
 +----------------+----------------+---------------------------+
 |``c=g``         |                |Move ``G`` to ``C``        |
 |                |                |register at pointer        |
 |                |                |position                   |
 +----------------+----------------+---------------------------+
 |``g=c``         |                |Move ``C`` to ``G``        |
 |                |                |register at pointer        |
 |                |                |position                   |
 +----------------+----------------+---------------------------+
 |``c<>g``        |                |Exchange ``C`` and ``G``   |
 |                |                |registers at pointer       |
 |                |                |position                   |
 +----------------+----------------+---------------------------+
 |``t=st``        |                |Move status byte to tone   |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``st=t``        |                |Move tone register to      |
 |                |                |status byte                |
 +----------------+----------------+---------------------------+
 |``st<>t``       |                |Exchange tone register and |
 |                |                |status byte                |
 +----------------+----------------+---------------------------+
 |``?lowbat``     |                |Low level detect, check for|
 |                |                |low battery                |
 +----------------+----------------+---------------------------+
 |``c=cora``      |                |Bitwise or ``A`` to ``C``  |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``c=c&a``       |                |Bitwise and ``A`` to ``C`` |
 |                |                |register                   |
 +----------------+----------------+---------------------------+
 |``clrabc``      |                |Clear ``A``, ``B`` and     |
 |                |                |``C`` registers            |
 +----------------+----------------+---------------------------+
 |``prphslct``    |                |Select peripheral          |
 +----------------+----------------+---------------------------+


.. index:: instructions;Hepax, Hepax

Hepax instructions
------------------

.. table::
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+-----------------------------------------+
 |Mnemonic        |Operand         |Description                              |
 +================+================+=========================================+
 |``romblk``      |                |Move ROM block                           |
 +----------------+----------------+-----------------------------------------+
 |``wptog``       |                |Toggle write protection                  |
 +----------------+----------------+-----------------------------------------+


.. index:: instructions;NEWT, NEWT;instructions

NEWT specific instructions
--------------------------

NEWT specific instructions are recognized if you specify the command
line option ``--core newt``.

.. table::
 :widths: 1 1 4
 :column-dividers: none single single none

 +----------------+----------------+-----------------------------------------+
 |Mnemonic        |Operand         |Description                              |
 +================+================+=========================================+
 |``wcmd``        |                |Write command                            |
 +----------------+----------------+-----------------------------------------+



Peripheral instructions
-----------------------

Refer to the sections describing :ref:`Peripheral instructions
<peripheralInstructions>` in the HP instructions chapter for the
peripheral specific instructions recognized, as they are the same in
both instructions sets (they were never defined for the Jacobs-DeArras
instruction set).
