Add real ADSP-2191 assembly examples + open21xx assembler test

This commit is contained in:
Siggi
2026-04-12 18:10:08 +00:00
parent d325e04765
commit d7f0569a47
34 changed files with 6283 additions and 0 deletions

View File

@@ -0,0 +1,189 @@
/**************************************************************
File Name: Viterbi.asm
Date Modified: 6/23/01 BJM
Description:
ADSP-2192 single core subroutine that implements the
1/2 rate GSM soft decision Viterbi decoder.
Assumptions:
The class 1 bits are encoded with the 1/2 rate convolutional code defined by
the polynomials:
G0 = 1 + D3+ D4
G1 = 1 + D + D3+ D4
Encoded outputs are transmitted as signed antipodal analog signals. They are recieved at
the decoder and quantized. The quantized number is represented in a 2's
compliment giving the range of -8 to 7. The process of quantizing a binary analog signal
with a multi-bit qunatizer is called soft decision. This soft decision is represented by
the array 'SOFT_DEC_INPUT'
Registers Affected:
I0,I1,I2,I3,I4
M0,M1,M2,M3,M4,M5,M6,M7
L0,L1,L2,L3,L4
B1,B3,B4
AX0,AX1,AY0,AY1
AR,AF,SR,SI,SE
MX0
Cycle Count:
30751 Cycles
Memory Usage:
Instructions Words (24-bits):
107 instruction words
Data Words (16 or 24-bits):
2*N_out = Number of soft decisions (16-bit)
N_out = Number of state transitions (16-bit)
16 = Number of New and Old metrics (16-bit)
N_Words = Decoded output of GSM frame (16-bit)
8 = Metric Table (16-bit)
Notes:
**************************************************************/
#define N_out 189
#define N_words 12
#define N_mod_16 13
/* DM data */
.section/data data1;
.VAR soft_dec_input[2*N_out] = "gsm_rec.dat";
.VAR state_trans[N_out];
.VAR old_acc_metric[16];
.VAR new_acc_metric[16];
.VAR decoded_output[N_words+4];
.VAR met_table[8];
/* PM interrupt vector code */
.section/pm IVreset;
JUMP start; NOP; NOP; NOP; /* Interupt vector table */
/* Program memory code */
.section/pm program;
start:
I0 = soft_dec_input; /* Initialize soft_dec_input pointer */
L0 = 0; /* Initialize for modulo addressing */
I1 = old_acc_metric; /* Initialize old_acc_metric pointer */
L1 = length(old_acc_metric); /* Initialize old_acc_metric circular buffer */
AX0 = I1;
reg(B1) = AX0; /* Initialize pointer to old_acc_metric */
I2 = state_trans; /* Initialize state_trans pointer */
L2 = 0; /* Initialize for modulo addressing */
I3 = met_table; /* Initialize met_table pointer */
L3 = length(met_table); /* Initialize met_table circular buffer */
AX0 = I3;
reg(B3) = AX0; /* Initialize pointer to met_table */
I4 = new_acc_metric; /* Initialize new_acc_metric pointer */
L4 = length(new_acc_metric); /* Initialize new_acc_metric circular buffer */
AX0 = I4;
reg(B4) = AX0; /* Initialize pointer to new_acc_metric */
M0 = -8;
M1 = 1;
M2 = -16;
M3 = 0;
M4 = 8;
M5 = -7;
M6 = -8;
M7 = -1;
SE = 1; /* Setup bit shift */
SI = 0X8000;
SR0 = 0;
SR1 = 0;
CNTR = 16;
DO zero_metric UNTIL CE;
zero_metric: dm(I1,M1) = M3; /* Initialize accumulated metric array */
CNTR = N_out; /* FOR (k=0; k<N_out; k++) */
DO add_compare UNTIL CE;
AX0 = dm(I0,M1);
AY0 = dm(I0,M1);
AR = AX0 + AY0;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = AX0 - AY0;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR;
CNTR = 8; /* FOR (i=0; i<8; i++) */
DO calc_metric UNTIL CE;
AY0 = dm(I3,M1);
AX1 = dm(I1,M1);
AF = AX1 + AY0, AX0 = dm(I1,M1); /* AF = old_acc_metric[2*i] + Met_table */
AR = AX0 - AY0; /* AR = old_acc_metric[2*i+1] - Met_table */
SR = LSHIFT SR1 (HI); /* State_trans[k] = state_trans[k] << by 1 */
NONE = AR - AF;
IF GT SR = SR OR LSHIFT SI (LO); /* Then state_trans[k] = state_trans[k]<<1 | 1 */
IF LT AR = PASS AF;
dm(I4,M4) = AR, AF = AX1 - AY0; /* AF = old_acc_metric[2*i] - Met_table */
AR = AX0 + AY0; /* AR = old_acc_metric[2*i+1] + (-Met_table) */
SR = LSHIFT SR1 (HI); /* State_trans[k] = state_trans[k] << by 1 */
NONE = AR - AF;
IF GT SR = SR OR LSHIFT SI (LO); /* Then state_trans[k] = state_trans[k]<<1 | 1 */
IF LT AR = PASS AF;
calc_metric: dm(I4,M5) = AR; /* New_acc_metric[i+2] = AR */
modify(I4,M6); /* Reset I4 to new_acc_metirc */
AX1 = I1; /* AX1 = old_acc_metric */
I1 = I4; /* Old_acc_metric = new_acc_metric */
AX0 = I1;
reg(B1) = AX0; /* Initialize pointer to old_acc_metric */
I4 = AX1; /* New_acc_metric = AX1 */
reg(B4) = AX1; /* Initialize pointer to new_acc_metric */
add_compare: dm(I2,M1) = SR1; /* Store state_trans[k] */
M1 = -1;
I3 = decoded_output + N_words; /* Initialize decoded_output + N_words pointer */
L3 = 0; /* Initialize for modulo addressing */
AY0 = -15;
AY1 = 15;
MR0 = N_out - 1;
MR1 = 0;
SI = dm(I2,M1); /* Save previous state_trans */
AX0 = 0;
MX0 = N_mod_16; /* First word only has 13 valid bits */
CNTR = N_words;
DO trace_back UNTIL CE;
CNTR = MX0;
DO state_bits UNTIL CE;
SR = LSHIFT MR1 by 1(LO); /* SR0 = State << 1 */
AR = CLRBIT 4 OF SR0;
AX1 = AR;
AF = TSTBIT 4 OF SR0;
IF NE AR = SETBIT 0 OF AR;
AR = AR + AY0, SI = dm(I2,M1); /* Bit_Pos = 15 - rotate(State) */
SE = AR;
SR = LSHIFT SI (LO);
AR = TSTBIT 0 OF SR0;
AR = AR OR AX1; /* AR = state_trans[k] >> Bit_Pos */
MR2 = AR, AR = MR0 AND AY1;
SR = LSHIFT MR1 by - 3(LO);
SE = AR;
AR = TSTBIT 0 OF SR0;
SI = AR;
SR = LSHIFT SI (LO);
AR = AX0 OR SR0;
AX0 = AR;
AR = MR0 -1; /* Decoded_output |= ((State & 8) >> 3) << (k & 15) */
MR0 = AR;
state_bits:
MR1 = MR2; /* State = new_acc_metric */
MX0 = 16;
dm(I3,M1) = AX0;
trace_back:
AX0 = 0;
looping: JUMP looping; /* Loop upon itself */