;-----------------------------------------------------------------
; catu255.mu -- Microcode source for Alto running
;
64 Kilobit u-255 law coded speech.
; This code executes as part of the audio task.
; Last modified by L. Stewart September 22, 1979 5:20 PM
; October 15, 1979 2:30 PM silence detection
; March 17, 1980 12:15 PM CAT copy, CatU255.mu
;-----------------------------------------------------------------

;-----------------------------------------------------------------
; u-255 law encoding
; Assumes left justified 12 bit two’s complement value in L
; u255 value returned r.j. in L and l.j. in utVal=Temp
;-----------------------------------------------------------------
!1,2,utEPlus,utEMinus;
!1,2,utEShift,utEOV;
!1,2,utEDone,utEMore;
!1,2,utEMinus1,utEPlus1;

; First convert to sign magnitude

utEncode:
utVal←L;
L←100000,SH<0;
utExp←L,:utEPlus;!1,2,utEPlus,utEMinus;

utEPlus:
L←0,TASK,:utECom1;

utEMinus:
L←0-T;
utVal←L,T←0-1,TASK,:utECom1;

utECom1:
utSign←L,:utAddConst;

; Now add 41B returning max on overflow
utAddConst:
T←203+1;Lucky constant value
L←utVal+T;
NOP,SH<0;
utVal ← L RSH 1,:utEShift;!1,2,utEShift,utEOV;

utEOV:
L←177,TASK;
utVal←L,:utEAddSign;

; Now shift right by 2, to align the value so that it is right for the highest
; exponent.

utEShift:
L←utVal,TASK;
utVal ← L RSH 1;

; Now enter the main loop of the conversion.

utELoop:
T←STRCWFS;STRCWFS=10000
L←utVal AND T;
L←utExp-T,SH=0;
utExp←L,:utEDone;!1,2,utEDone,utEMore;
utEMore:
L←utVal,TASK;
utVal←L LSH 1,:utELoop;

; Now package everything up

utEDone:
T←7400;4 bit mask
T←utVal.T;
L←utExp OR T,TASK;
utVal←L LCY 8;

; Add in sign;
utEAddSign:
SINK←utSign,BUS=0;
L←T←utVal,:utEMinus1;!1,2,utEMinus1,utEPlus1;
utEMinus1:
L←200 OR T,:utEPlus1;
utEPlus1:
utVal←L LCY 8,:utStore;

;-----------------------------------------------------------------
; u-255 law decoding
; Assumes right justified 8 bit u-255 value in L
; Returns linear value in L and utVal=Temp
;-----------------------------------------------------------------
!1,2,utDLoop,utDDone;
!1,2,utDMinus,utDPlus;

utDecode:

; First step, separate components.

utVal←L;
T←100;
T←60 OR T;Construct constant
L←utVal AND T,TASK;
utExp←L;

T←utVal;
L←200 AND T;
utSign←L;Minus if Sign non-zero
L←17 AND T,TASK;
utVal←L LSH 1;

; Build frame for decoding;
T←utVal+1;
L←40+T,TASK;
utVal←L LSH 1;

; The value is now 0 000 000 001 xxx x10 in binary.
; We now must shift left (Exp/20B)+1 places.

utDLoop:
L←utVal,TASK;
utVal←L LSH 1;
T←20;
L←utExp-T,BUS=0,TASK;
utExp←L,:utDLoop;!1,2,utDLoop,utDDone;

; Now subtract 204B (see encode), this will never underflow.

utDDone:
T←203+1;
L←utVal-T;
T←17;
L←LASTL AND NOT T,TASK;Truncate towards 0.
utVal←L;

; Handle sign.

SINK←utSign,BUS=0;
L←T←utVal,:utDMinus;!1,2,utDMinus,utDPlus;
utDMinus:
L←0-T;
utDPlus:
utVal←L,:utShipit;

;-----------------------------------------------------------------
; u-255 law decoding
; Assumes right justified 8 bit u-255 value in L
; Returns linear value in L and utVal=Temp
;-----------------------------------------------------------------
!1,2,uttDLoop,uttDDone;
!1,2,uttDMinus,uttDPlus;

uttDecode:

; First step, separate components.

utVal←L;
T←100;
T←60 OR T;Construct constant
L←utVal AND T,TASK;
utExp←L;

T←utVal;
L←200 AND T;
utSign←L;Minus if Sign non-zero
L←17 AND T,TASK;
utVal←L LSH 1;

; Build frame for decoding;
T←utVal+1;
L←40+T,TASK;
utVal←L LSH 1;

; The value is now 0 000 000 001 xxx x10 in binary.
; We now must shift left (Exp/20B)+1 places.

uttDLoop:
L←utVal,TASK;
utVal←L LSH 1;
T←20;
L←utExp-T,BUS=0,TASK;
utExp←L,:uttDLoop;!1,2,uttDLoop,uttDDone;

; Now subtract 204B (see encode), this will never underflow.

uttDDone:
T←203+1;
L←utVal-T;
T←17;
L←LASTL AND NOT T,TASK;Truncate towards 0.
utVal←L;

; Handle sign.

SINK←utSign,BUS=0;
L←T←utVal,:uttDMinus;!1,2,uttDMinus,uttDPlus;
uttDMinus:
L←0-T;
uttDPlus:
utVal←L,:uttShipit;