{ 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}