; IfsPupChecksum.mu ; Copyright Xerox Corporation 1979, 1980 ; Last modified by Taft, February 26, 1980 5:44 PM ; Pup Checksum instruction ; AC0/ 0 initially ; AC1/ address of block ; AC3/ length of block (words) ; Computes the ones-complement add-and-cycle checksum over the block. ; When the instruction finishes, ; AC0/ result ; AC1/ address+length-1 ; AC3/ 0 ; This instruction is interruptible. If an interrupt occurs, intermediate ; state is stored in the ACs and the PC is backed up so the instruction will ; start over when the interrupt is dismissed. ; Timing: 9 cycles/word ; 2484 cycles (= 422 microseconds) per maximum-length Pup $AC3 $R0; $AC1 $R2; $AC0 $R3; $NWW $R4; $PC $R6; $LREG $R40; !1,2,PCMayI,PCNoI; !1,2,PCDoI,PCDisI; !1,2,PCNoCy,PCCy; !1,2,PCLoop,PCDone; !1,2,PCNoMZ,PCMinZ; PupChecksum: MAR_ L_ AC1, :PCLp1; Start fetch of first word ; Top of main loop PCLoop: MAR_ L_ AC1+1; Start fetch of next word PCLp1: AC1_ L; Update pointer L_ NWW, BUS=0; Test for interrupts T_ AC0, SH<0, :PCMayI; [PCMayI, PCNoI] Get accumulated checksum PCMayI: L_ MD+T, :PCDoI; [PCDoI, PCDisI] Add new word PCNoI: L_ MD+T, :PCDisI; PCDisI: T_ M, ALUCY; Test for carry out L_ AC3-1, :PCNoCy; [PCNoCy, PCCy] Decrement and test count PCNoCy: AC3_ L, L_ T, SH=0, TASK, :PCLast; No carry PCCy: AC3_ L, L_ T_ 0+T+1, SH=0, TASK; Do end-around carry PCLast: AC0_ L MLSH 1, :PCLoop; [PCLoop, PCDone] Left cycle 1 ; Here when done PCDone: L_ AC0+1; Test for minus zero (ones-complement) SH=0; PCDn1: SWMODE, :PCNoMZ; [PCNoMZ, PCMinZ] PCNoMZ: :START; PCMinZ: AC0_ L, :START; Minus zero, change to plus zero ; Here when interrupted PCDoI: L_ PC-1, TASK; Back up PC PC_ L, :PCDn1;