Flag tricks


Now for a better description of some side effects,
when playing with Bit 4..6.

Testing a Word in memory for zero or negative would
(for instance) encode as:
always, absoute_addressing, don't write result, modify_Flags, move_memory

tst&    MACRO   addr
        dc.w    %0001100001000101 ; $1845
        dc.w    addr
        ENDM

In 68000 assembly language, dc.w defines a 16 Bit constant.

MACRO means, that the assembler will replace every tst&
found in the source code with those two 16 Bit constants.
End of the macro is marked with ENDM.


For comparing ACC with an immediate value:
always, immediate, don't write result, modify_Flags, c_in=1, SUB
Basically a subtraction, but we throw away the result and only modify Flags.

cmp#    MACRO   val
        dc.w    %0000000001111010 ; $007a
        dc.w    val
        ENDM

Result:
ACC< val: C_Flag=0
ACC>=val: C_Flag=1

Note: for ADD, force c_in to 0. For SUB, force c_in to 1.
That's because ADD uses a high_active carry, while SUB uses a low_active borrow...
as with the 6502.
For ADD/SUB/cmp with more than 16 Bit, connect ALU c_in to the C_Flag.

When incrementing/decrementing ACC, add# 1 or sub# 1 can be used.

There isn't a dedicated "increment" OpCode, but incrementing a word
in memory can be done by using MVM, with c_in=1:
always, absolute_addressing, write to memory, modify_Flags, c_in=1, MVM.

inc&    MACRO   addr
        dc.w  %0001100111110101 ; $19f5
        dc.w  addr
        ENDM

Now some words for shifting and rotating:

c_in=0     : shifts the word, filling empty locations with 0
c_in=C_Flag: rotates the word through the C_Flag.

There is a trick for shifting words to the right (means, divide by 2),
containing 16 Bit signed integer:
First, we read the word from memory, shift it left, and throw away
the result, so the C_Flag contains the sign Bit.
Second, we shift the word in memory right with c_in=C_Flag,
filling empty locations with said sign Bit.

Now another trick: MT15 can't directly read/write the status register.
Nevertheless, it is possible to read/restore Flag status.

SaveFlg MACRO
        ;
        dc.w  %0000000010001000 ; set ACC to $0000, don't modify Flags
        dc.w  0
        ;
        dc.w  %1100000010000010 ; $e082 if_c,  ora# $8000, don't mod. Flg.
        dc.w  $8000
        ;
        dc.w  %0110000010000010 ; $6082 if_n,  ora# $4000, don't mod. Flg.
        dc.w  $4000
        ;
        dc.w  %1000000010000010 ; $a082 if_nz, ora# $2000, don't mod. Flg.
        dc.w  $2000
        ;
        ENDM

Note, that all those commands don't modify the Flags.
Basically, we now transferred the Flags C,N,Z into ACC Bit 15,14,13.

Restoring the Flags is easy:
all we have to do is shifting the value in ACC left, with c_in=0.

RestoreFlg MACRO        ;restore_Flags
           ;
           dc.w  %0000000001001110 ; $004E cin=0, SLR, modify Flags
           dc.w  0
           ;
           ENDM

Saving/Restoring ACC without modifying the Flags is basically a "move" with OpCode Bit 6 = 0.


[HOME] [UP]/ [BACK] [1] [2] [3] [4] [5] [6] [7] [8] [NEXT]

(c) Dieter Mueller 2005