Close

Indirect memory accesses

A project log for Instruction Set for ECM-16/TTL homebrew cpu

All the instructions laid out in systematic manner

pavelPavel 10/23/2022 at 10:140 Comments

Loading and Storing of data at addresses calculated at runtime from values stored in registers and/or immediate values in instructions.

There are 8 ways to calculate these addresses, for each there is a Load and Store instruction, in all there are 16 instructions in this group.

There is always a Memory  Pointer register pair used for providing base address, this can be one of: Program Counter (PC), Stack Pointer (SP), Frame Pointer (FP) and Base Pointer (BP).

Load or Store can be performed to and from any of the General Purpose Registers(GPR) and any of Memory Pointer Registers(MP).

For calculating addresses, signed 16-bit offset can be used, it is provided either from one of GPR, or from immediate value.

When multi-word flag is set, several consecutive registers can have their contents stored to memory or several words from memory can be loaded into corresponding number of consecutive registers with one instruction. In this case, there are additional clock cycles spent for each additional word. As Load/Store operations themselves take up several clock cycles, loading/storing 2 and more registers using one instruction will save clock cycles compared to loading/storing each word individually.

Other instructions can be investigated here: General layout of instruction types.


Instruction bits meaning:

bits F, E, D: opcode for indirect memory access

bit C: 0 = load, 1 = store

bit B: 0 = GPR, 1 = MP

bits A, 9, 8: register address for load/store

bits 7, 6, 5: address of register containing offset value

bit 4: 0 = do NOT update MP at memory access, 

         1 = update MP at memory access (either post- or pre- increment, depending on bit 3)

bit 3: 0 = do NOT add offset before accessing the memory (post-increment if bit 4 = 1),

          1 = add offset before accessing the memory (pre-increment if bit 4 = 1),

bit 2: 0 = use offset from GPR, 1 = use immediate value for offset

bits 1, 0: Memory Pointer pair index


Instruction layouts:

1) LD and ST: loading / storing at address in MP, without offset:

               Instruction words:
               bits of word #1      bits of word #2
Mnemonic:      FEDC BA98 7654 3210  FEDC BA98 7654 3210
LD rX MP       0110 dddd xxx0 00aa
ST rX MP       0111 ssss xxx0 00aa
LD rX MP*      0110 dddd xxx0 01aa  xxxx xxxx xxxx xxxx
ST rX MP*      0111 ssss xxx0 01aa  xxxx xxxx xxxx xxxx

d, s - bits of register address (X or MP) which is destination or source
a - bits of Memory Pointer pair index, PC = 00, SP = 01, FP = 10, BP = 11
x - "don't care" bits - have no effect on result
rX - General Purpose Register #X
MP - Memory Pointer pair (either of PC, SP, FP and BP)

* - this pair of instructions is possible, because hardware is capable of executing them.
They have the same effect as the first pair, only take up more space in memory
 and 1 more clock cycle to execute.
These instructions, however, will not be output from assembler - they are superfluous. 

2) LDr/LDo and STr/STo: loading / storing at address in MP + offset, MP value stays the same
                   Instruction words:
                   bits of word #1      bits of word #2
Mnemonic:          FEDC BA98 7654 3210  FEDC BA98 7654 3210
LDr rY MP rX       0110 dddd rrr0 10aa
STr rY MP rX       0111 ssss rrr0 10aa
LDo rY MP 0xFFFF   0110 dddd xxx0 11aa  oooo oooo oooo oooo
STo rY MP 0xFFFF   0111 ssss xxx0 11aa  oooo oooo oooo oooo

d, s - bits of register address (Y or MP) which is destination or source
a - bits of Memory Pointer pair index, PC = 00, SP = 01, FP = 10, BP = 11
r - bits of register address (X) that holds offset value
o - bits of immediate offset value
x - "don't care" bits - have no effect on result
rX, rY - General Purpose Registers #X and #Y
MP - Memory Pointer pair (either of PC, SP, FP and BP)
OxFFFF -signed 16-bit offset value (in range -32768..+32767)

3) LDra/LDoa and STra/SToa: loading / storing at address in MP, and after this, update MP value with its current value + offset (loads/stores with POST-increment of MP)
                    Instruction words:
                    bits of word #1      bits of word #2
Mnemonic:           FEDC BA98 7654 3210  FEDC BA98 7654 3210
LDra rY MP rX       0110 dddd rrr1 00aa
STra rY MP rX       0111 ssss rrr1 00aa
LDoa rY MP 0xFFFF   0110 dddd xxx1 01aa  oooo oooo oooo oooo
SToa rY MP 0xFFFF   0111 ssss xxx1 01aa  oooo oooo oooo oooo

d, s - bits of register address (Y or MP) which is destination or source
a - bits of Memory Pointer pair index, PC = 00, SP = 01, FP = 10, BP = 11
r - bits of register address (X) that holds offset value
o - bits of immediate offset value
x - "don't care" bits - have no effect on result
rX, rY - General Purpose Registers #X and #Y
MP - Memory Pointer pair (either of PC, SP, FP and BP)
OxFFFF -signed 16-bit offset value (in range -32768..+32767)

4) LDrb/LDob and STrb/STob:  update MP value with its current value + offset  before loading / storing at updated address  (loads/stores with PRE-increment of MP)
                    Instruction words:
                    bits of word #1      bits of word #2
Mnemonic:           FEDC BA98 7654 3210  FEDC BA98 7654 3210
LDrb rY MP rX       0110 dddd rrr1 10aa
STrb rY MP rX       0111 ssss rrr1 10aa
LDob rY MP 0xFFFF   0110 dddd xxx1 11aa  oooo oooo oooo oooo
STob rY MP 0xFFFF   0111 ssss xxx1 11aa  oooo oooo oooo oooo

d, s - bits of register address (Y or MP) which is destination or source
a - bits of Memory Pointer pair index, PC = 00, SP = 01, FP = 10, BP = 11
r - bits of register address (X) that holds offset value
o - bits of immediate offset value
x - "don't care" bits - have no effect on result
rX, rY - General Purpose Registers #X and #Y
MP - Memory Pointer pair (either of PC, SP, FP and BP)
OxFFFF -signed 16-bit offset value (in range -32768..+32767)

Discussions