; Full test of the EBFs. ; The number of the errors counted by cpu(n) is stored in the location 0xF00(n) of the D-bank. #ifdef short #def eblength= 4; #else #def eblength=64; #endif #def margaddr=prf[0] ; marginal address (first addr. at the begining, last one +1 at the end) #def work=PRF[1] ; register for current operations (CO) #def rdata=PRF[2] ; data red by test_programs and CO #def tdata=PRF[3] ; test_vector to be writen #def errnum=PRF[4] ; contains the number of err_ors #def return1=PRF[5] ; return address (at first level) #def return2=PRF[6] ; return address (at second level) #def return3=PRF[7] ; return address (at third level) #def tdgen=PRF[8] ; test data generator code label #def itdgen=PRF[9] ; init tdgen code label #def psrmask=PRF[10] ; mask for test_vector #def chanum=PRF[12] ; number of certain chanal ; prf11 and prf13 are used inside the testing routine ; DEFINITIONS, USED IN THE PROGRAM CODE: #def ioaddr=PRF[14] ; contains the autoincrementing address of I/O operations through GIO #def errstore=PRF[15] ; autoincrement address for RAM-access #def bitnum=grf[0] ; 32 minus the number of bits tested (here 32-10=22) #def BITMASK10=0x3FF ; 10-bit mask nop #ifdef cpu0 iext 0x300F mov 0x300F r1 mov c0 r0 sgio r0 r1 #else nop nop nop nop #endif start: jmp cc_uncond mprg ; BEGIN THE TESTING ROUTINE (uses testing subroutine) cltst: mov 1, prf[11] mov 1, prf[13] nt: nop ;#ifdef walk1 mov wlk1, tdgen ; call walking 1 test_routine mov iwlk1, itdgen ; mvpcr +2, return2 jmp cc_uncond, tstglio ;#endif ;#ifdef walk0 mov wlk0, tdgen ; call walking 0 test_routine mov iwlk0, itdgen mvpcr +2, return2 jmp cc_uncond, tstglio ;#endif ;#ifdef psrgt mov psr, tdgen ; call pseudo random vector test_routine mov ipsr, itdgen mvpcr +2, return2 jmp cc_uncond, tstglio ;#endif add prf[13], c3, prf[13] ; next initial vectors for all shl 1, prf[11], prf[11] ; testing routines jmp cc_carry, return1 mov bitnum work mov 15 rdata mov prf[11] tdata cmp rdata bitnum jmpr cc_ncarry 3 shl 15 tdata tdata sub work rdata work shlt work, tdata ; if MSB of the current register tested is set - stop! jmp cc_ncarry, nt jmp cc_uncond return1 ; left side of the MSB of the mask - stop! ; END OF THE TESTING ROUTINE ; BEGIN OF THE SUBROUTINE tstglio: mvpcr +2, return3 jmp cc_uncond, itdgen ; go to init the test data gen shl 2 c5 margaddr ; preparing the initial address add margaddr c5 margaddr ; in GIO: add margaddr chanum margaddr ; ioaddr=0x2000+0x80*(5*CPU_ID+chanum) mov 0x80 work ; the value for ioaddr is first prepared in mul32 margaddr work margaddr ; margaddr (marginal address) nop iext 0x2000 mov 0x2000 work add margaddr work margaddr mov margaddr, ioaddr ; then the last address is calculated by mov eblength work ; addition of 64 to margaddr add work margaddr margaddr wd: jmpr cc_busy, 0 sgio+ tdata ; ioaddr is autoincrementing register mov 20 work ; certain delay befor the next write operation wt: sub work c1 work jmp cc_nzero wt mvpcr +2, return3 ; preparing the next test_vector by tdgen-procedure jmp cc_uncond, tdgen ; comparing if the last address is reached cmp ioaddr, margaddr jmp cc_carry, wd ; BEGIN COMPARING PART OF CODE mov 0x40 margaddr ; preparing the first addres in LIO: mul32 margaddr chanum margaddr ; ioaddr=0x800+0x40*chanum ; nop mov 0x800 work add work margaddr margaddr mov margaddr, ioaddr mov eblength work add work margaddr margaddr ; preparing the last address, stored in margaddr mvpcr +2, return3 jmp cc_uncond, itdgen ; and go to init for testing wc: jmpr cc_busy, 0 lpio ioaddr rdata ; here is the cycle of reading and comparing lpio+ rdata ; with stored before pattern ; nop ; wait and rdata psrmask rdata ; the data red is masked again to avoid the cmp rdata, tdata ; err_or that should occur because of the parity jmp cc_zero, noerr ; bit add errnum, c1, errnum noerr: mvpcr +2, return3 jmp cc_uncond, tdgen ; get next test_data to compare with cmp ioaddr, margaddr ; is tne last address tested? jmp cc_carry, wc ; if not go to wc jmp cc_uncond, return2 ; otherwise return back ; prepares the next data - walking 1 wlk1: shl 1, tdata, tdata and tdata, psrmask, tdata jmp cc_nzero, return3 mov 1, tdata jmp cc_uncond, return3 ; end of walking 1 ; prepares the next data - walking 0 wlk0: com tdata, tdata shl 1, tdata, tdata and tdata, psrmask, tdata jmpr cc_nzero, +2 mov 1, tdata com tdata, tdata and tdata, psrmask, tdata jmp cc_uncond, return3 ; end of walking 0 ; prepares the next data by pseudo random generator psr: lpio 0x202, tdata and tdata, psrmask, tdata jmp cc_uncond, return3 ; end random generator ; init walking 1 iwlk1: and prf[11], psrmask, tdata jmp cc_uncond, return3 ; init walking 0 iwlk0: com prf[11], tdata and tdata, psrmask, tdata jmp cc_uncond, return3 ; init psr ;#ifdef trap3 ipsr: mov b1_0_0_00_01_00000, tdata ;#else ;ipsr: mov b1_0_0_00_01_0000, tdata ;#endif mov 31 work sub work bitnum work ;#ifdef trap3 ;#else ; cmp work 16 ; jmpr cc_carry 2 ; mov 15 work ;#endif or tdata work tdata spio tdata, 0x201 mov prf[13], tdata spio tdata, 0x200 nop nop lpio 0x202, tdata jmp cc_uncond, return3 ; END OF THE SUBROUTINES ; MAIN PROGRAM CODE BELOW mprg: nop mov BITMASK10 psrmask mov 22 bitnum mov 0, errnum mov c0 chanum ; call test for channel 0 mvpcr +2 return1 jmp cc_uncond cltst mov c1 chanum ; call test for channel 1 mvpcr +2 return1 jmp cc_uncond cltst mov c2 chanum ; call test for channel 2 mvpcr +2 return1 jmp cc_uncond cltst mov c3 chanum ; call test for channel 3 mvpcr +2 return1 jmp cc_uncond cltst mov c4 chanum ; call test for channel 4 mvpcr +2 return1 jmp cc_uncond cltst #ifdef cpu3 mov 5 chanum ; call test for channel 20 mvpcr +2 return1 jmp cc_uncond cltst #else nop nop nop #endif cpu3 jmpr cc_busy 0 ; here reading the Event Buffer Parity Violation iext 0x3010 mov 0x3010 ioaddr ; Counter, wich is additional err_or indicator add ioaddr c5 ioaddr lgio 1 ioaddr ; the value of EBPVC is added to errnum jmpr cc_busy 0 lpio 0x301 work add errnum work errnum ; add errnum c5 errnum iext 0xF000 ; the total errnum is stored in DBANK mov 0xF000 errstore add errstore c5 errstore jmpr cc_busy 0 sgio errnum errstore jmpr cc_busy 0 #ifdef cpu3 jmpr cc_busy, 0 iext 0x0A26 ; CPU3 turns the power off when finished mov 0x0A26, work mov b0_0111, rdata sgio rdata, work jmpr cc_busy, 0 sgio rdata 0xA20 ; send end to the scsn master in simulation mov 1, work iext 0x3178 mov 0x3178, ioaddr sgio+ work mov 0, tdata ; single ended bidir outputs jmpr cc_busy, 0 sgio tdata, ioaddr jmpr cc_busy, 0 sgio work, ioaddr jmpr cc_busy, 0 mov 0x012, work sgio work, 0xA04 jmpr cc_uncond 0 #else ; turns on cpu N+1 ... mov c1 rdata jmpr cc_busy 0 mov c1 ioaddr add ioaddr c5 ioaddr shl 1 ioaddr ioaddr mov 0xA20 work add ioaddr work ioaddr sgio rdata ioaddr jmpr cc_busy 0 sub ioaddr c2 ioaddr mov c0 rdata sgio rdata ioaddr jmpr cc_uncond 0 ; ... and stops itself #endif cpu3