MC 68000 MACHINE LANGUAGE COURSE PART IV by Mark van den Boer

What a pity!!  You missed the mega-surprise of part 3.  Next time
better luck! I am gonna take that holiday to Hawaii myself!

This time I will discuss the Integer Arithmetic Instructions. The
syntax used is of course the same as in part 3,  so when in doubt
refer  to  part  3.  This class of instructions  is  used  to  do
mathematical  calculations.  This  group is very  often  used  by
assembly  language programmers,  especially the instructions  for

Integer Arithmetic Instructions

Data sizes:    byte, word, long

Condition codes affected:
X, C set by carry out of the most significant bit
N    set if the result was negative, cleared otherwise
Z    set if the result was zero, cleared otherwise
V    set if the result overflowed, cleared otherwise
Source: (destination is Dn)
Dn
An
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
w(PC)
b(PC,Rn)

Destination:
Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
Function: Add  source  to  destination  and  put  the  result  in
destination.
Examples:
Instruction              Before         After
d1=0000FFFA    d1=0000000B
XNZVC=00000    XNZVC=11001
a0=12345678    a0=12345678
12345678 contains 5
XNZVC=00000    XNZVC=00000

Data sizes:    word, long
Condition codes affected: None
Source:
Dn
An
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
w(PC)
b(PC,Rn)
#
Destination:
An

not change any of the condition code values.  Note that
most  operations  that have an address  register  as  a
destination does not change the condition codes.
Example:
Instruction              Before         After
Notice  that this instruction has the same effect as  multiplying
the address register with two (if this was possible).

This instruction has exactly the same characteristics as the  ADD
instruction, except that the source can only be a constant.

Same story as for ADDI,  except that the immediate values in  the
source  field  can only range from 1 to 8.  Q stands  for  Quick,
since this instruction is the fastest way to add a number from  1
to 8 to a destination operand.
Most assemblers accept the following instruction: ADD #1,Dn
and will translate it automatically to ADDQ #1,Dn    thus  saving
a few bytes of object code and some clock cycles execution time.

Data sizes:    byte, word, long
Function: Add  X-bit  and  source to destination  and  store  the
result  in destination.  This instruction is  used  for
multiple  precision  operations and is  therefore  only
available with the two addressing modes mentioned.
Example:
Instruction              Before         After
a1=10002001    a1=10002000
10001000 contains AA   the same
10002000 contains 5A   10002000 contains 4
X=0            X=1
a1=10002000    a1-10001fff
10000fff contains 0    the same
10001fff contains 0    10001fff contains 1
X=1            X=0
In this example the word that begins at 10000fff is added to  the
word that begins at 10001fff.  If one should try to do this  with
always must be aligned to even addresses. This instruction can be
compared to the ADC instruction of the 6502 and 6809.

Instruction:   CLR
Syntax:        CLR <ea>
Data sizes:    byte, word, long
Condition codes affected:
N    always cleared
Z    always set
V    always cleared
C    always cleared

Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
Function: Set an effective address to zero. You will have noticed
that you can't CLR an address register.  However,  most
assemblers  allow  the  programmer to  CLR  an  address
register  by  substituting CLR a0 with SUB.L  a0,a0   .
This instruction has exactly the same result.
Example:
Instruction              Before         After
CLR.W d0                 d0=ffffffff    d0=00000000
NZVC=1011      NZVC=0100

Instruction:   CMP
Syntax:        CMP <ea>,Dn
Data sizes:    byte, word, long
Condition codes affected: NZVC (X is not affected)
Dn
An
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
w(PC)
b(PC,Rn)
Function: compare an effective address with a data  register.  In
fact  all  condition codes are set as  if  Dn-<ea>  was
performed.  So CMP is kind of a subtraction which  only
affects the conditon codes.

Example:
Instruction              Before         After
CMP.L d0,d1              d0=00000001    d0=00000001
d1=00000002    d1=00000002
NZVC=1111      NZVC=0000

Instruction:   CMPA
Syntax:        CMPA <ea>,An
Data sizes:    word, long
Function: This  instruction  differs only from CMP  in  that  the
second  operand  is an address register and  that  byte
isn't allowed as a data size.

Instruction:   CMPI
Syntax:        CMPI #,Dn
Function: Yes,  it is nearly exactly the same as compare but  now
the first operand must be a constant.

Instruction:   CMPM
Syntax:        CMPM (An)+,(An)+
Function: Again, nearly exactly the same as CMP, but now both the
source  and  destination operand must  be  (An)+.  This
instruction  is used to compare areas  of  memory.  For
those of you who have a working knowledge of C:  strcmp
can be programmed easy with this instruction.

Note on all CMPx instructions.
Most assemblers accept instructions like:
CMP.W (a0)+,(a1)+
CMP.L #3,d0
Substitution of CMPM,  CMPI and CMPA are automatically  performed
by the assembler.

Instruction:   DIVS
Syntax:        DIVS <ea>,Dn
Data sizes:    word

Condition codes affected:
N    behaves normal; undefined on overflow
Z    behaves normal; undefined on overflow
V    behaves normal
C    always cleared
Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
w(PC)
b(PC,Rn)
#

Function: Guess  what?   This  instruction  performs  a  division
between two signed numbers. The
destination  register  is  always a  longword  and  the
source operand is always a word. After the division the
destination operand contains the result.  The  quotient
is always in the lower word and the remainder is always
in the high order word of the data register! This way a
modulo operation is also performed,  you just SWAP  the
data  register  and you have your result in  the  lower
word  of the data register.  Overflow occurs  when  you
attempt to divide a large number by a small number e.g.
ffffff divided by 1,  the result doesn't fit in a word.
Another error occurs when attempting to divide by zero.
In this case the 68000 generates an exception and  will
trap  to  a special routine which handles  division  by
zero erros.  On the Atari you must set up this  routine
yourself.  E.g.  FLOYD  (a  machine  language  monitor)
responds  to  a  division by zero  with  the  following
sentence "The answer is 42". Remember, don't panic when

Example:
Instruction              Before         After
DIVS #3,d0               d0=0000000B    d0=00020003
NZVC=1111      NZVC=0000

Instruction: DIVU
Function: Nearly  exactly the same as DIVS,  only this time  both
operands are assumed to be unsigned.

Instruction:   EXT
Syntax:        EXT Dn
Data sizes:    word, long
Condition codes affected:
N    behaves normal
Z    behaves normal
V    always cleared
C    always cleared

Function: turn  a byte into a word,  or turn a word into a  long.
This  instruction provides a convenient way to  turn  a
word into a long and still have the same value for that
register. If the high order bit of the data register is
0,  so the data register is positive, zeroes are padded
in, otherwise ones are padded in.
Example:
Instruction              Before         After
EXT.W d0                 d0=000000ff    d0=0000ffff
EXT.L d0                 d0=ffff0000    d0=00000000

Instruction:   MULS
Syntax:        MULS <ea>,Dn
Data sizes:    word
Condition codes affected:
N    behaves normal
Z    behaves normal
V    always cleared
C    always cleared

Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
w(PC)
b(PC,Rn)
#
Function: Ah!  another very handy instruction.  This  instruction
performs a multiplication of the source and destination
operand, putting the result in the destination operand.
Example:
Instruction              Before         After
MULS #3,d0               d0=0000000B    d0=00000021
NZVC=1111      NZVC=0000

Instruction: MULU
Function: Nearly  exactly the same as MULUS,  only this time  both
operands are assumed to be unsigned.

Instruction:   NEG
Syntax:        NEG <ea>
Data sizes:    byte, word, long
Condition codes affected: XNZVC (all behave normal)
Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
Function: negate  an effective address operand.  In a high  level
language it would look like this: a = -a

Example:
Instruction              Before         After
NEG.L d0                 d0=00000001    d0=ffffffff

Instruction:   NEGX
Syntax:        NEGX <ea>
Data sizes:    byte, word, long
Condition codes affected: XNZVC (all behave normal)
Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
to  the  result.  This  is  another  instruction  which
provides a way to handle multi-precision  (e.g.  8-byte
integers).
Example:
Instruction              Before         After
NEGX.L d0                d0=00000001    d0=00000000
X=1            X=1

Instructions: SUB, SUBA, SUBI, SUBQ, SUBX
All these instruction perform subtractions.  They only differ  in
that   way   from   from  the   ADD   instructions,   all   other
characteristics are the same.

Instruction:   TAS
Syntax:        TAS <ea>
Data sizes:    byte
Condition codes affected:
N    evaluated before setting the byte
Z    evaluated before setting the byte
V    always cleared
C    always cleared

Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
Function: First  test  the operand and set the  condition  codes,
then set the high-order bit to 1.  People who know what
semaphores (in programming of course...) are, immedia
tely  will love this instruction.  For those who  don't
know what semaphores are: M. Ben Ari has written a good
book  on the subject called "Principles  of  Concurrent
Programming".  Never,  I repeat never,  read a book  on
this subject written by a certain Ir.  E.H.H.  Dijkstra
(not the famous Dijkstra,  this Dijkstra will never  be
famous).

Example:
Instruction              Before         After
TAS \$436                 \$436=00        \$436=80
NZVC=1111      NZVC=0100
TAS \$436                 \$436=FF        \$436=FF
NZVC=1111      NZVC=1000

Instruction:   TST
Syntax:        TST <ea>
Data sizes:    byte, word, long
Condition codes affected:
N    behaves normal
Z    behaves normal
V    always cleared
C    always cleared

Dn
(An)
(An)+
-(An)
w(An)
b(An,Rn)
w
l
Function: test an effective address operand. This instruction can
be  seen as CMP <ea>,d0 where d0 is 0.  TST  is  nearly
always followed by a branch instruction (more on  these
later)

To  the people who also read the last lines (I hope  you've  also
read most of the preceeding ones):  Phone me and tell me how  you
like this course.

My phonenumber (in Holland) is:
Weekends: 013-422397
Midweek:  070-933487 (only at evenings)

Disclaimer
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.