; MPattern.asm -- Data pattern generator initialized by MDEBUG.BCPL and ; used in the "Test" overlay and elsewhere. MUST BE RESIDENT because ; RanTab has to be resident. ; Last editted 5 June 1979 .get "MAsmCommon.d" ; MASM .bextz MSave2,MCount ; MDATA .bextz ShouldBe,DataWas,BitsChecked .bextz LoopCount,CurrentAddress,NDWords .bext BitsPicked,BitsDropped,AddrUnion,AddrIntersect,TestFailures ; Defined here .bext NextData,CheckData,RanTab,RanLen,IncV .bextz RANDIX,PATTERN .zrel RANDIX: 33. PATTERN: 0 .srel NextData: .NextData ; Procedure to generate next data pattern CheckData: .CheckData ; Procedure to check results IncV: .IncV ; Vector loaded with a 1 in the right-most RanTab: .RanTab ; Random number data vector RanLen: 33. ; Length of random no. data vector .nrel ;and CheckData() = valof ;[ DoubleAdd(LoopCount,LongOne) ; for I = 0 to NDWords-1 do ; [ if ((ShouldBe!I xor DataWas!I) & BitsChecked!I) ne 0 then ; [ DoubleAdd(TestFailures,LongOne) ; for J = 0 to 1 do ; [ AddrUnion!J = AddrUnion!J % CurrentAddress!J ; AddrIntersect!J = AddrIntersect!J & CurrentAddress!J ; ] ; for J = 0 to NDWords-1 do ; [ BitsPicked!J = BitsPicked!J % (DataWas!J & not ShouldBe!J) ; BitsDropped!J = BitsDropped!J % (ShouldBe!J & not DataWas!J) ; ] ; resultis true ; ] ; ] ; resultis false ;] .CheckData: sta 3 1 2 lda 3 LoopCount isz 1 3 ; Increment LoopCount (double-precision) jmp .+3 isz 0 3 jmp .+1 lda 0 NDWords sta 0 2 2 CDlp1: lda 3 DataWas lda 0 2 2 ; Word count add 0 3 lda 1 -1 3 ; 1/ DataWas!I lda 3 ShouldBe add 0 3 lda 0 -1 3 ; 0/ ShouldBe!I mov 0 3 ; Xor = A+B-2*(A & B) andzl 1 3 add 1 0 sub 3 0 ; 0/ ShouldBe!I xor DataWas!I lda 3 BitsChecked lda 1 2 2 add 1 3 lda 1 -1 3 ; 1/ BitsChecked!I and# 1 0 szr ; (DataWas!I xor ShouldBe!I) & (BitsChecked!I eq 0) jmp CDfail dsz 2 2 jmp CDlp1 jmp CDret CDfail: sta 2 MSave2 lda 3 CurrentAddress lda 2 @lvAddrIntersect lda 0 0 2 ; AddrIntersect = AddrIntersect & CurrentAddess lda 1 0 3 and 1 0 sta 0 0 2 lda 0 1 2 lda 1 1 3 and 1 0 sta 0 1 2 lda 2 @lvAddrUnion lda 0 0 2 ; AddrUnion = AddrUnion % CurrentAddress lda 1 0 3 com 0 0 and 0 1 adc 0 1 sta 1 0 2 lda 0 1 2 lda 1 1 3 com 0 0 and 0 1 adc 0 1 sta 1 1 2 lda 0 NDWords sta 0 MCount CDlp2: lda 0 MCount lda 2 ShouldBe add 0 2 lda 1 -1 2 ; ShouldBe!J lda 3 DataWas add 0 3 lda 0 -1 3 ; DataWas!J com 0 2 and 1 2 ; 2/ Dropped = ShouldBe!J & not DataWas!J com 1 1 and 1 0 ; 0/ Picked = DataWas!J & not ShouldBe!J lda 3 @lvBitsPicked lda 1 MCount add 1 3 lda 1 -1 3 ; BitsPicked!J com 0 0 and 0 1 adc 0 1 sta 1 -1 3 ; BitsPicked!J = BitsPicked!J % Picked!J lda 3 @lvBitsDropped lda 1 MCount add 1 3 lda 1 -1 3 ; BitsDropped!J com 2 0 and 0 1 adc 0 1 sta 1 -1 3 ; BitsDropped!J = BitsDropped!J % Dropped!J dsz MCount jmp CDlp2 lda 3 @lvFailures isz 1 3 jmp CDFx isz 0 3 jmp CDFx CDFx: lda 2 MSave2 mkminusone 0 0 skp ; return -1 on failure CDret: mkzero 0 0 ; return 0 on ok lda 3 1 2 jmp 1 3 lvAddrUnion: AddrUnion lvAddrIntersect: AddrIntersect lvBitsPicked: BitsPicked lvBitsDropped: BitsDropped lvFailures: TestFailures .NextData: sta 3 1 2 sta 2 MSave2 lda 2 ShouldBe lda 1 NDWords sta 1 MCount ; Dispatch to routine for selected pattern jsr NData1 jmp NDret ; Zeroes jmp NDret ; Ones jmp NDcyc1 ; Cyc1 jmp NDcyc0 ; Cyc0 jmp NDran ; Random jmp NDseq ; Sequential jmp NDret ; ShouldBe jmp NDalt ; AltZO jmp NDalt ; AltShouldBe NData1: lda 0 PATTERN add 0 3 jmp 0 3 NDalt: lda 0 0 2 com 0 0 sta 0 0 2 inc 2 2 dsz MCount jmp NDalt jmp NDret NDcyc0: mkminusone 3 3 lda 0 0 2 movl# 0 0 snc ; Skip if bit cycled into low word will be 1 jmp CopyNI ; Otherwise, reinitialize the pattern add 1 2 ; 2/ ShouldBe+NDWords Cyc1B: add 3 2 lda 0 0 2 movol 0 0 snc jmp Cyc0 Cyc1: sta 0 0 2 dsz MCount jmp Cyc1B jmp NDret Cyc0S: mkminusone 3 3 add 1 2 Cyc0B: add 3 2 lda 0 0 2 movzl 0 0 szr jmp Cyc1 Cyc0: sta 0 0 2 dsz MCount jmp Cyc0B jmp NDret lvIncV: IncV NDcyc1: lda 0 0 2 movl# 0 0 snc ; Skip if the 1 is being cycled off the left end jmp Cyc0S ; No, normal cycling CopyNI: lda 3 @lvIncV CopyI: lda 0 0 3 sta 0 0 2 inc 2 2 inc 3 3 dsz MCount jmp CopyI jmp NDret NDseq: jsr NDseq1 .IncV: 0 ; This vec is filled in with 1 in the least sig. 0 ; bit of the DVec 0 0 0 0 0 ; Do next sum with incoming carry = 0 sc00: mkminusone 1 1 NDseq1: add 1 2 ; ShouldBe+NDWords add 1 3 ; IncV+NDWords lda 0 -1 2 ; Low-order ShouldBe word lda 1 -1 3 ; Low-order IncV word addz 1 0 szc ; Low-order sum jmp seqc1 seqc0: sta 0 -1 2 dsz MCount jmp sc00 NDret: lda 2 MSave2 lda 3 1 2 jmp 1 3 ; Do next sum with incoming carry = 1 sc11: mkminusone 1 1 add 1 2 add 1 3 lda 0 -1 2 incz 0 0 lda 1 -1 3 add 1 0 snc jmp seqc0 seqc1: sta 0 -1 2 dsz MCount jmp sc11 jmp NDret R7: 7 ; Random no. generator does x[n] = (x[n-33] + x[n-13]) mod 2↑16 ; which should have a period .g. 2↑33 and passes usual tests for ; randomness NDran: jsr ran1 .RanTab: 160315 34255 43770 104071 21360 135442 45545 106565 6714 133667 176741 12402 114375 36624 34427 105045 146515 63276 36434 67771 127054 77772 26244 171113 164223 114267 132355 146005 44600 41705 144466 131235 31377 ran1: lda 0 RANDIX ; Get index (counts toward 0) add 0 3 ; Point to table entry +1 lda 1 d20 ; Is x[n-13] ahead or behind us in table? sgt 0 1 jmp ran2 lda 1 -21. 3 ; x[n-13] from ahead of us (lower address) jmp ran3 ran2: lda 1 12. 3 ; x[n-13] from behind us (higher address) ran3: lda 0 -1 3 ; Add x[n-33] add 1 0 sta 0 -1 3 ; Result sta 0 0 2 dsz RANDIX jmp .+3 lda 1 d33 sta 1 RANDIX inc 2 2 dsz MCount ; Loop over TValSize words jmp NDran jmp NDret d20: 20. d33: 33. .end