; BCPL Microcode for running Diablo Port Audio Terminal ; Last modified by L. Stewart: March 15, 1980 3:25 PM ; Microcode command file for Audio Terminal ; MU/l ATmc.mu ; PackMu ATmc.mb ATmc.br 160376 // Alto II ; PackMu ATmc.mb ATmc.br 177376 // Alto I ; Task assignments and BCPL emulator-routine entry points. ; Alto II version %17,1777,0, Novem, L1, L2, L3, L4, L5, L6, L7, MRT, DWT, CURT, DHT, DVT, L15; ; Alto I version ; %17,1777,0, Novem, L1, L2, L3, L4, L5, L6, L7, MRT, L11, L12, L13, L14, L15; %1,1777,20,Start; %1,1777,21,AudioInit; %1,1777,22,AudioStart; %1,1777,23,AudioEnqueue; #AltoConsts23.mu; L1: TASK, :L1; L2: TASK, :L2; L3: TASK, :L3; L4: TASK, :L4; L5: TASK, :L5; L6: TASK, :L6; L7: TASK, :L7; ; L10: TASK, :L10; Memory refresh task ; For Alto II, comment out L11, L12, L13, and L 14 ; L11: TASK, :L11; Display Word Task ; L12: TASK, :L12; Cursor Task ; L13: TASK, :L13; Display horizontal task ; L14: TASK, :L14; Display Vertical Task L15: TASK, :L15; ; For Alto I ; #CATMRT.mu; contains MRT ; For Alto II #CATIIMRT.mu; contains MRT #GateDisplay.mu; contains DHT, DVT, CURT, DWT ;BCPL Emulator routines (via JMPRAM) ; Arg1 in AC0 ; Ram Location Routine ; 20 SetBLV -- Silent boot code (doesn't do the StartIO) for BCPL ; 21 AudioInit ; 22 AudioStart ; 23 AudioEnqueue ; Register definitions $AC0 $R3; $AC3 $R0; $LastL $R40; $IACB $R71; input Audio Control Block $IPtr $R72; data block pointer $ICount $R73; word count $RData $R14; input assembly register $OACB $R74; output Audio Control Block $OPtr $R75; $OCount $R76; $WData $R15; output word register $NCount $R60; ; Temporaries $Temp2 $R63; $Temp $R16; In Data ; Constants $OREMask $4000; $DataMask $170000; $Strobe $1; command word strobe ; Silent boot interface TStart: TASK; NStart: NOP; Novem: SWMODE; 1Start: :Start; Start: RMR _ AC0, :Novem; Set RMR -- classical location for it ; This must run with MRT disabled (i.e. running in ROM) AudioInit: L _ 0; NCount _ L; IACB _ L; OACB _ L; OCount _ L; ICount _ L,TASK; WData _ L; T _ 177000; Clear ready bit in hardware MAR _ 16 + T; L _ Strobe; MD _ LastL; MAR _ 16 + T; L _ 0, TASK; MD _ LastL,:NStart; ; On entry to AudioEnqueue, AC0 points to the new ACB, AC3 to the old !1,2,Fail, Link; AudioEnqueue: MAR _ AC3; L _ 0; SINK _ MD,BUS=0; MAR _ AC3+1,:Fail; !1,2,Fail, Link; Link: NOP; MD _ AC0,TASK,:NStart; Fail: AC0 _ L,TASK,:NStart; ; AudioStart expects AC0 to be IACB and AC3 to be OACB. ; n. b. A 0 starting value means none... ; ; Format of an ACB (Even word aligned) ; word 0: Flags Goes non-zero on completion ; word 1: Next ACB pointer to next ACB ; word 2: Pointer pointer to data block ; word 3: Count size of block (in words) AudioStart: L _ AC0; IACB _ L; L _ AC3; OACB _ L; L _ 0; ICount _ L,TASK; OCount _ L,:Novem; ; This code runs as part of MRT !1,2,Ready,NotYet; AudioTest: T _ 177000; MAR _ 30 + T; T _ OREMask; two cycles here! (compute portout?) L _ T _ MD AND T; L _ DataMask AND T, SH=0; Temp2 _ L,:Ready; !1,2,Ready,NotYet; NotYet: TASK; NOP,:ATDone; back to MRT !1,2,RightB,LeftB; !1,2,IBMore,IBDone; !1,2,ICMore,ICDone; !1,2,OBMore,OBDone; !1,2,OCMore,OCDone; Ready: ; write data T _ 177000; MAR _ 16 + T; T _ 177400; L _ WData AND T; MD _ LastL, TASK; Temp _ L; ; Strobe it in T _ 177000; MAR _ 16 + T; L _ Temp + 1; we know 1 is Strobe MD _ LastL; ; Now read next nibble MAR _ 30 + T; #177030 T _ DataMask; L _ MD AND T,TASK; Temp _ L; ; Turn off strobe T _ 177000; MAR _ 16 + T; T _ 177400; L _ WData AND T, TASK; MD _ LastL; L _ Temp, TASK; Temp _ L RSH 1; L _ Temp, TASK; Temp _ L RSH 1; L _ Temp, TASK; Temp _ L RSH 1; L _ Temp, TASK; Temp _ L RSH 1; T _ Temp; L _ Temp2 OR T, TASK; Temp _ L; ; Now input byte is left justified in Temp SINK _ NCount, BUS=0; L _ 0,:RightB; !1,2,RightB,LeftB; ;Assume Temp holds left justified nibble. ; Left Byte LeftB: L _ ALLONES; NCount _ L; L _ Temp, TASK; RData _ L LCY 8; L _ WData,TASK; swab WData WData _ L LCY 8,:ATDone; ; Right byte RightB: NCount _ L; T _ RData; L _ Temp OR T, TASK; RData _ L LCY 8,:WTIn; ; Once per word code (250 microseconds) WTIn: L _ ICount-1, BUS=0, TASK; decrement input count ICount _ L,:IBMore; !1,2,IBMore,IBDone; (input block) ; Block completion, input IBDone: MAR _ L _ IACB,BUS=0; T _ 2,:ICMore; !1,2,ICMore,ICDone; (input chain) ICMore: MD _ LastL; L _ MD; MAR _ LastL+T; IACB _ L; ; predecrement ptr because we increment it before use L _ MD - 1; ; we test count for zero before decrementing it ; since we are starting a new block, ICount must be decremented ; to account for the store in IBMore below. T _ MD - 1; IPtr _ L, L _ T, TASK; ICount _ L,: IBMore; ICDone: L _ 0, TASK; leave count at 0 ICount _ L,:WTOut; IBMore: MAR _ L _ IPtr+1; we increment ptr before use IPtr _ L; L _ RData, TASK; MD _ LastL,:WTOut; WTOut: L _ OCount-1, BUS=0, TASK; decrement output count OCount _ L,:OBMore; !1,2,OBMore,OBDone; ; Block completion, output OBDone: MAR _ L _ OACB,BUS=0; T _ 2,:OCMore; !1,2,OCMore,OCDone; OCMore: MD _ LastL; L _ MD; MAR _ LastL+T; OACB _ L; ; predecrement ptr because we increment it before use L _ MD - 1; ; we test count for zero before decrementing it ; OCount must be decremented to account for the fetch in ; OBMore below. T _ MD - 1; OPtr _ L, L _ T, TASK; OCount _ L,: OBMore; OCDone: L _ 0; WData _ 0, TASK; OCount _ L,:ATDone; leave count at 0 OBMore: MAR _ L _ OPtr+1; OPtr _ L; L _ MD, TASK; WData _ L,:ATDone; ;; December 24, 1979 5:59 PM L. Stewart. created file ;; December 25, 1979 8:18 PM L. Stewart. task code ;; December 28, 1979 10:43 PM L. Stewart. new design (0,5376)(1,11264)\f1