Addressing modes


MT15 addressing modes:

Addressing modes are valid for ALL instructions.

d16 means the parameter field, second word of a MT15 instruction.
Example: lda: load ACC with word in memory...

 #d16      lda#    ; immediate with d16
  d16      lda&    ; mem[d16]
 [d16]     lda@    ; mem[mem[d16]]      //nice for implementing a stack
  d16+ACC  ldaa&   ; mem[d16+ACC ]      
  d16+PC   ldapc&  ; mem[d16+PC  ]      //PC relative data
 [d16+ACC] ldaa@   ; mem[mem[d16+ACC]
 [d16+PC ] ldapc@  ; mem[mem[d16+PC ]   //PC relative pointer

Another example:
 jmp#  writes d16 immediate into PC, like the "JMP" known frome other CPUs.
 jmpa& takes one word from a table in memory, starting at d16, with ACC as offset.
 jmp@  reads from a word selected by a pointer in memory, as when returning from a subroutine.

...although jmp# looks a bit odd.

Now a nice example for jmpa&:

You did read an ASCII character, maybe from a keyboard, and want
to execute a part in a program depending on a number:

        ;ACC='0'..'3'=$0030..$0033
        ;
        and#   $0003       ;limit ACC to $0001..$0003
        jmpa&  ladr(TABLE) ;load PC with contents of address "TABLE+ACC".
TABLE
        dc.w   ladr(addr0) ;<-ACC = $0000, was '0'
        dc.w   ladr(addr1) ;<-ACC = $0001, was '1'
        dc.w   ladr(addr2) ;<-ACC = $0002, was '2'
        dc.w   ladr(addr3) ;<-ACC = $0003, was '3'

...don't get confused by ladr(),
it just indicates, that TABLE is an address.

ladr() is defined as a function:
ladr function addr, (addr>>1) Didn't like TMS32010 notation, or PIC endianess...
so I decided to stay with the AS macroassembler in 68000 mode.

Had to improvise a bit, because 68000 assembler is counting Bytes
of program memory, while MT15 is counting words.
So ladr() divides by two for a correction by shifting the address one Bit
to the right.
You sure know, how to do better than that.


Building (conditional) jumps is easy.

        jnz#  ladr(TARGET)      ;jump, if Z_Flag = 0
could be encoded with:
if_nz, immediate_addressing, keep flags, write PC, MVM
Here the macro:
jnz#    macro addr          
        dc.w  %1000000100000101 ; $8105
        dc.w  addr          
        endm

Now for the "branch" instruction.

Branch means, a relative jump from the actual PC address.
In other words: nothing more than adding a value to PC.

Example:

        brz#  lrel(ADDR)
would look like:
if_z, immediate_addressing, keep flags, read PC, write PC, increment, ADD
brz#    macro rel 
        dc.w  %1010001100111001 ; $a339
        dc.w  rel 
        endm

lrel() is defined as a function:
lrel function rel, (addr-(*+2))/2

PC (ProgramCounter) would point to the address of the
second word of the instruction during data calculation.
So we add 2 to increment the address to the next word
(what would be the first word of the next instruction).

Then we have to subtract the target address from that,
and divide the result by two
(you already know, why).
Since the subtraction will result in a signed integer,
we have to perform a signed division.


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

(c) Dieter Mueller 2005