{
File : VECTOROPS.mc
Author : Gwan Santosa
Date : 2-Aug-85 14:11:37
This program does the following vector operations :
1. Get a pointer to a maximum value of a vector.
2. Get a pointer to a minimum value of a vector.
3. Get a pointer to an absolute minimum value of a vector.
4. Get a pointer to an absolute maximum value of a vector.
5. Get sum of vector's elements (not coded yet).
Algorithm (for 1 to 4) :
Fetch stack parameters. (TOS = count down counter)
Check counter, if 0, exit.
If 1, exit.
Otherwise :
Initialize current position to 1.
Initialize index to 0.
Fetch 2 floating point numbers from array.
Store the first element into reference register.
Inner loop :
Call comparison subroutine.
If TOS is 0, done.
Else :
Update current position
Fetch next element.
Back to Inner loop
Comparison subroutine :
Check if to find absolute extreme.
If yes, convert sign bit to +.
Else :
Compare 2 numbers.
If new extreme is found, update index and reference register.
Return
}
{Set[L1.FS.NR.0C, 0C];}
Set[L0.VO.RO.04, 04];
Set[L0.VO.RO.05, 05];
Set[L0.VO.RO.09, 09];
Set[L0.VO.RO.0A, 0A];
Set[L0.VO.RO.0B, 0B];
RegDef[rCOUNT, R, 04]; {=S}
RegDef[rRESMN, R, 05]; {=PC}
RegDef[uINDEX, U, 42];
RegDef[uNEWH, U, 44];
RegDef[uMAXH, U, 05];
RegDef[uMAXL, U, 56];
Ybus ← TOSH xor smallpl, ZeroBr, GOTO[VOBK1], c3, at[0C, 10, ub2op]; {Check if size = NIL}
Ybus ← TOSH xor smallpl, ZeroBr, GOTO[VOBK1], c3, at[0D, 10, ub2op]; {Check if size = NIL}
Ybus ← TOSH xor smallpl, ZeroBr, GOTO[VOBK1], c3, at[0E, 10, ub2op]; {Check if size = NIL}
Ybus ← TOSH xor smallpl, ZeroBr, GOTO[VOBK1], c3, at[0F, 10, ub2op]; {Check if size = NIL}
VOBK1: TT ← 0FF + 1, BRANCH[VOER1, $], c1; {set PPort to read}
Q ← uPPsave, L1 ← L1.FS.NR.0C, c2;
PPort ← Q and ~TT, CALL[SaveAllRegsB2], c3; {Save all registers}
MAR ← [rhS, S - 1], c1, at[L1.FS.NR.0C, 10, SaveRegsB2Ret];
Ybus ← TOS, ZeroBr, CANCELBR[$, 2], c2; {Check if size = 0}
Q ← MD, BRANCH[$, VOER0], c3;
MAR ← [rhS, S + 0], c1;
TOS ← TOS - 1, ZeroBr, c2; {check if only 1 entry}
TT ← MD, BRANCH[$, VOEX0], c3;
rhTT ← Q LRot0, c1;
FloatNop, c2;
FloatNop, c3;
TS101: Map ← [rhTT, TT + 0], L1 ← L1.FS.NR.0C, c1;
uTT ← TT, L0 ← L0.VO.RO.04, c2;
rhRx ← Rx ← MD, XRefBr, c3;
TS202: MAR ← Q ← [rhRx, TT + 0], BRANCH[VOCH0, $], c1, at[L0.VO.RO.04, 10, NRMapFixCallerB2];
Rx ← Q, c2;
TOSH ← MD, c3;
TS303: MAR ← Rx ← [rhRx, Rx + 1], L2 ← 00, c1; {Get first element and initialize as MAX}
uMAXH ← TOSH, BRANCH[$, FXVO0, 1], c2;
TOSH ← MD, c3;
TS404: MAR ← Rx ← [rhRx, Rx + 1], L2 ← 01, c1, at[00, 10, FETCHRET];
uMAXL ← TOSH, BRANCH[$, FXVO1, 1], c2;
TOSH ← MD, c3;
TS505: MAR ← Rx ← [rhRx, Rx + 1], L2 ← 02, c1, at[01, 10, FETCHRET];
uNEWH ← TOSH, BRANCH[$, FXVO2, 1], c2;
TOSH ← MD, c3; {Get second element and initialize as NEW}
TS606: rCOUNT ← 1, c1, at[02, 10, FETCHRET];
uINDEX ← 0, c2; {Index keeps track of the latest extreme}
FloatMode.RN.AI.IEEE, FloatFLOW, CALL[VOCP], c3; {Count keeps track of the current position}
{
========================================================================================================
Inner loop
========================================================================================================
}
TOS ← TOS - 1, ZeroBr, c1, at[0, 10, COMPRET]; {TOS is the count down counter}
rCOUNT ← rCOUNT + 1, BRANCH[$, VOEX1], c2; {If TOS = 0, done}
L2 ← 03, c3; {Current position (rCOUNT) is updated}
MAR ← Rx ← [rhRx, Rx + 1], c1; {Fetch next element}
BRANCH[$, FXVO3, 1], c2;
TOSH ← MD, c3;
MAR ← Rx ← [rhRx, Rx + 1], c1, at[03, 10, FETCHRET];
uNEWH ← TOSH, BRANCH[$, FXVO4, 1], c2;
CHRT5: TOSH ← MD, CALL[VOCP], c3; {Call comparison subroutine}
{
==========================================================================================
Compare subroutine
==========================================================================================
This subroutine handles 4 comparisons.
The low 2 bits of ib determines which operation.
00 : Find index of max. value.
01 : Find index of min. value.
10 : Find index of absolute max. value.
11 : Find index of absolute min. value.
If a new extreme value is found, it will update the index and the new extreme value is
loaded into a reference register uMAX
}
VOCP: Xbus ← ibNA, XDisp, c1;
Q ← uMAXH, DISP4[MAXMIN, 0D], c2;
GOTO[VCOM], c3, at[0D, 10, MAXMIN];
TT ← ~TT xor TT, c3, at[0F, 10, MAXMIN];
TT ← RShift1 TT, SE ← 0, c1; {This section convert the sign bit to +}
Q ← TT and Q, c2;
uMAXH ← Q, c3;
Q ← uNEWH, c1;
Q ← TT and Q, c2;
uNEWH ← Q, GOTO[VCOM], c3;
VCOM: FloatAB ← uNEWH, c1;
FloatAB ← TOSH LRot0, c2;
FloatA ← uMAXH, FLAMinusB, c3;
FloatA ← uMAXL, c1;
FloatNop, c2;
Noop, c3;
L3 ← 0, c1;
Noop, c2;
FloatUnloadS, Float.M, c3;
FloatUnloadS, Float.L, c1;
rSTATUS ← PPort, c2;
rRESMN ← FloatResult, c3;
Q ← FloatResult, c1;
rRESMN ← rRESMN LRot8, c2;
rRESMN ← rRESMN and 80, c3;
Xbus ← ibNA, XDisp, c1;
DISP4[VOMAXMIN, 0E], c2;
Ybus ← rRESMN, ZeroBr, c3, at[0E, 10, VOMAXMIN]; {Determine max. value}
BRANCH[FNMAX1, SMMAX], c1;
FNMAX1: Q ← uNEWH, c2; {B>A, New max. is found}
uMAXH ← Q, c3; {Update uMAXH and uMAXL}
uMAXL ← TOSH, c1; {They now contain the new extreme value}
uINDEX ← rCOUNT, L3Disp, c2;
RET[COMPRET], c3;
SMMAX: L3Disp, c2;
RET[COMPRET], c3;
Ybus ← rRESMN, ZeroBr, c3, at[0F, 10, VOMAXMIN]; {Determine min. value}
BRANCH[SMMIN, FNMIN1], c1;
FNMIN1: Q ← uNEWH, c2; {New min. is found}
uMAXH ← Q, c3; {Update uMAXH and uMAXL}
uMAXL ← TOSH, c1; {They now contain the new extreme value}
uINDEX ← rCOUNT, L3Disp, c2;
RET[COMPRET], c3;
SMMIN: L3Disp, c2;
RET[COMPRET], c3;
{
==========================================================================================
Remap
==========================================================================================
}
VOCH0: CALL[NRLMapFixB2], c2;
VOCH1: CALL[NRLMapFixB2], c2;
VOCH5: CALL[NRLMapFixB2], c2;
FXVO0: GOTO[VOFX], c3;
FXVO1: GOTO[VOFX], c3;
FXVO2: GOTO[VOFX], c3;
FXVO3: TT ← uTT, GOTO[VOFX], c3;
VOFX: Q ← 0FF + 1, c1;
TT ← TT + Q, CarryBr, c2;
Q ← rhTT, BRANCH[VONC0, VOC0], c3;
VONC0: GOTO[VOMG0], c1;
VOC0: Q ← Q + 1, c1;
VOMG0: rhTT ← Q LRot0, c2;
uTT ← TT, c3;
Map ← [rhTT, TT + 0], L0 ← L0.VO.RO.05, c1;
TOSH ← Rx, L1 ← L1.FS.NR.0C, c2;
rhRx ← Rx ← MD, XRefBr, c3;
MAR ← Q ← [rhRx, TOSH + 0], BRANCH[VOCH1, $], c1, at[L0.VO.RO.05, 10, NRMapFixCallerB2];
Rx ← Q, L2Disp, c2;
TOSH ← MD, DISP4[FETCHRET], c3;
FXVO4: TT ← uTT, c3;
Q ← 0FF + 1, c1;
TT ← TT + Q, CarryBr, c2;
Q ← rhTT, BRANCH[VONC4, VOC4], c3;
VONC4: GOTO[MGVO1], c1;
VOC4: Q ← Q + 1, c1;
MGVO1: rhTT ← Q LRot0, c2;
TOSH ← Rx, c3;
Map ← [rhTT, TT + 0], L1 ← L1.FS.NR.0C, c1;
uTT ← TT, L0 ← L0.VO.RO.09, c2;
rhRx ← Rx ← MD, XRefBr, c3;
MAR ← Q ← [rhRx, TOSH + 0], BRANCH[VOCH5, $], c1, at[L0.VO.RO.09, 10, NRMapFixCallerB2];
Rx ← Q, GOTO[CHRT5], c2;
{
==========================================================================================
Exit points
==========================================================================================
}
VOEX0: S ← S - 2, L1 ← L1.RestoreAndExit, c1;
Xbus ← ib, L1Disp, c2;
DISP4[RestoreRegsB2Ret], c3;
VOEX1: TOS ← uINDEX, c3;
TOSH ← uTOSH, c1;
S ← uS, c2;
PC ← uPC, c3;
S ← S - 2, L1 ← L1.RestoreAndExit, c1;
Xbus ← ib, L1Disp, c2;
PV ← uPVx, DISP4[RestoreRegsB2Ret], c3;
{
==========================================================================================
Error cases
==========================================================================================
}
VOER0: Noop, c1;
VOER1: GOTO[ufnX3], c2;
{END}