Tables
Tables = array pf byte-long data items
length of table is not fixed
need to recognize end of table
reserve one bit pattern as sentinel: $FF ($0 for strings in C)
sentinel byte not part of data items
Data value range must not include sentinel value
TABLE FCB 1, 5, $F0, #10, $FF
Program: Add items up in table and store in one-byte result variable
TABLE = array of data bytes; array elements can be accessed two ways:
Through array index;
Through pointer into array
Which to use? Pointers
Addressing mode determines where the elements are coming from. Index X and Y
Use a while or do-until structure?
Have to use a while loop
************************************************************
Psuedo code:
int table[]; //signed
int result;
#define SENTI FF
int *pointer
result = 0;
pointer = &table[0];
while(*pointer ≠ SENTI){
*pointer + result => result;
pointer++;
}
************************************************************
ASSEMBLY:
ORG B000
table FCB $F0, $10, 4, FF
ORG $C000
CLR result
LDX #table With # we are loading $B000, without we are loading F010
WHILE LDAA 0,X Dereference X pointer
CMPA #SENTI
BEQ DONE
ADDA result
STAA result
INX
BRA WHILE
DONE STOP
************************************************************
How to add 2 N-byte numbers (N>=1)
NUMB1 + NUMB2 → NUMB1
MSB B1 LSB NUMB1
+ MSB B1 LSB NUMB2
= MSB B1 LSB SUM (NUM1)
add byte by byte, starting with LSB; store result bytes in place of NUMB1.
For all bytes: add carry flag as well (initialize CF to zero before LSB addition)
*******************************************************
Pseudo Code
int NUMB1[], NUMB2[];
#define N=4
int Counter;
int Counter, *Pointer1, *Pointer2;
Counter = N;
Pointer1 = &NUMB1[0];
Pointer2 = &NUMB2[0];
CF = 0.
DO{
*Pointer1 + *Pointer2 + CF => *Pointer1
*Pointer1++
*Pointer2++
Counter—;
}UNTIL(Counter==0)
*******************************************************
Decide where to put which variable
Assume numbers are stored in LITTLE endian
Addition: Register A
Counter: Register B
Pointer1: X Register
Pointer2: Y Register
*******************************************************
Assembly
ORG B000
NUMB1 FCB $F0, $10, 4, 5 (LSB, … MSB)
NUMB2 FCB 4, C000
LDAB #N
LDX #NUMB1
LDY #NUMB2
CLC (clear carry flag)
DO LDAA 0,X
ADCA 0,Y (add + carry flag)
STAA 0,X
INX
INY
DECB This will set the Z flag if B hits 0
UNTIL BNE DO
DONE STOP
*******************************************************
It’s better to count down to 0 than up to N. It’s better to use == or ≠ in comparisons
IF THIS WAS BIG-ENDIAN
ORG $C000
LDAB #N
LDX #NUMB1 → LDX #NUMB1+N-1
LDY #NUMB2 → LDY #NUMB2+N-1
CLC (clear carry flag)
DO LDAA 0,X
ADCA 0,Y (add + carry flag)
STAA 0,X
INX → DEX
INY → DEY
DECB This will set the Z flag if B hits 0
UNTIL BNE DO
DONE STOP
Shift and Rotate Instructions
Only one byte at a time
Logical Shift (Left/right)
Shift in a 0 from the right or left; shift out into CF
Logical shift left: multiply by 2 for unsigned numbers, 01000010 → 10000100
Logical shift right: divide by 2 for unsigned numbers, 10010000→ 11001000
Keep the same first bit for the sign
Used to test bits individually (through CF)
arithmetic shift (left/right)'
Rotation
Always through CF. CF←10101010←CF
Vice Verse