; Assembly language code for non-microcoded FindPkg ; last edited October 31, 1980 6:12 PM ; Copyright Xerox Corporation 1980 ; The phase argument / result below is actually ; 4000b*swap+phase, where swap=1 means even phases access odd byte. ; This peculiar convention is for microcode compatibility. .ent fJumpRam ; (arg, entry) ; Entry #s are: ; 0 Reset(phase) ; 2 NextEven(addr) -> (addr, -1-or-ctr-index, phase) ; 3 NextOdd(addr) -> same .ent fWriteReg ; (reg, value) ; Register #s are: ; 15b phase ; 16b -nMatch+1 .ent fSkip, fExit, fClear, fCount .ent flvlvlvCtrs, fnNctrs, flvDisp .srel fJumpRam: .fJumpRam fWriteReg: .fWriteReg fSkip: .fSkip fExit: .fExit fClear: .fClear .zrel fCount: .fCount ; lvlvlvCtrs is the base of a table indexed by phase; ; lvlvCtrs points to the base of a table indexed by counter #: ; each entry in this table points to a counter ; the -1 entry is the same as the 0 entry flvlvlvCtrs: 0 lvlvCtrs: 0 lvCtrs: 0 ; base of counters fnNctrs: 0 ; - # of counters nNmatch: 0 ; - # of matches required +1 flvDisp: 0 ; base of dispatch daddr: 0 ; pointer to data oddByte: 0 ; even if even (left) byte, odd if odd byte fac2: 0 ; save AC2 in search loop .nrel link=1 temp=2 arg3=3 ; Simulate WriteReg .fWriteReg: sta 3 link,2 movr# 0 0 szc jmp .fSetPhase jmp .fInit ; Initialize with number of matches .fInit: adc 0 0 add 0 1 ; ac1 ← ac1-1 sta 1 nNmatch lda 3 @flvlvlvCtrs lda 3 0,3 sta 3 lvCtrs lda 3 link,2 jmp 1,3 ; Set phase .fSetPhase: lda 0 m4001 andzr 1 0 szr ; carry ← odd phase, skip if swap not set movcl 0 0 skp ; odd byte flag ← not odd phase (swap set) movl 0 0 ; odd byte flag ← odd phase (swap not set) sta 0 oddByte inc 1 1 lda 0 m1777 and 0 1 adc 0 0 add 0 1 ; mask phase lda 0 flvlvlvCtrs add 1 0 sta 0 lvlvCtrs lda 3 link,2 jmp 1,3 m4001: 4001 m1777: 1777 ; Simulate JumpRam .fJumpRam: sta 3 link,2 mov# 1 1 snr jmp .fReset sta 0 daddr sta 2 fac2 lda 2 lvlvCtrs movr# 1 1 snc jmp .fEven lda 1 @daddr jmp .fOdd ; Reset counters and phase .fReset: sta 3 link,2 lda 3 lvCtrs lda 1 fnNctrs sta 1 temp,2 lda 1 nNmatch .fr1: sta 1 0,3 inc 3 3 isz temp,2 jmp .fr1 mov 0 1 jmp .fSetPhase ; Find next match. Carry=oddByte, AC2=lvlvCtrs, AC1=@daddr for .fOdd ; Dispatch here for skip character .fSkip: mov# 0 0 szc ; carry=oddByte jmp .fOdd ; Falls through to .fEven .fEven: isz daddr lda 1 @daddr lda 3 lcmask ands 1 3 lda 0 flvDisp addo 0 3 ; carry ← 1, odd byte next jmp @0,3 lcmask: 77400 ; Dispatch here for a character not appearing in the pattern. ; This is exactly like an ordinary character with a null table. .fcl0: lda 2 flvlvlvCtrs lda 3 0,2 jmp .fcl1 .fClear: inc 2 2 lda 3 0,2 mov# 3 3 snr jmp .fcl0 .fcl1: lda 0 nNmatch sta 0 @-1,3 mov# 0 0 snc ; carry=oddByte jmp .fEven ; Falls through to .fOdd .fOdd: lda 3 rcmask and 1 3 lda 0 flvDisp addz 0 3 ; carry ← 0, even byte next jmp @0,3 rcmask: 177 ; Dispatch here for exit character .fExit: subcl 1 1 ; ac1 ← carry sta 1 oddByte inc 2 2 adc 1 1 ; Not a real match ; Here for exit or match. ac1=-1 or counter # .fOut: lda 0 0,2 mov# 0 0 snr ; Check for wraparound jmp .fx3 sta 2 lvlvCtrs lda 0 flvlvlvCtrs sub 0 2 ; Compute phase lda 3 m1777 and 2 3 ; Might be -1 .fx2: lda 2 fac2 ; Restore Bcpl AC2 isz link,2 ; Don't smash ac3 lda 0 oddByte addr# 3 0 snc ; carry ← odd phase xor odd byte jmp .fx4 lda 0 daddr jmp @link,2 .fx3: lda 3 flvlvlvCtrs sta 3 lvlvCtrs sub 3 3 jmp .fx2 .fx4: lda 0 swapbit add 0 3 ; Set swap bit if phase parity # byte parity lda 0 daddr jmp @link,2 swapbit: 4000 ; Dispatch here for ordinary character. Code is ; jsr @fCount ; table of counter indices ; -1 .fCount: subcl 1 1 ; ac1 ← carry inc 2 2 lda 0 0,2 mov# 0 0 snr jmp .fc3 ; Wrap around to phase 0 .fc0: sta 2 lvlvCtrs .fc1: lda 2 0,3 addz 0 2 szc jmp .fc2 ; Ran off end of table, no match inc 3 3 isz @0,2 jmp .fc1 sta 1 oddByte lda 1 0,2 ; Match, return counter # lda 0 lvCtrs sub 0 1 lda 2 lvlvCtrs jmp .fOut .fc2: lda 0 nNmatch sta 0 @0,2 ; Reset first counter of next cycle lda 2 lvlvCtrs movr# 1 1 snc ; ac1=oddByte jmp .fEven lda 1 @daddr jmp .fOdd .fc3: lda 2 flvlvlvCtrs lda 0 0,2 jmp .fc0 .end