; Originally was compiled by MACY-11, an assembler running on the PDP-10. ; The source is adapted to be translated by regular MACRO-11. ; ; IDENTIFICATION ; -------------- ; Product code: AC-8054B-MC ; Product name: CFKTHB0 PDP 11/34 MEM MGMT ; Date: June 22, 1978 ; Maintainer: Diagnostic Engineering ; Author: Diagnostic Engineering ; ; The information in this document is subject to change without notice ; and should not be construed as a commitment by Digital Equipment ; Corporation. Digital Equipment Corporation assumes no responsibility ; for any errors that may appear in this document. ; ; The software described in this document is furnished to the purchaser ; under a license for use on a single computer system and can be copied ; (with inclusion of digital's copyright notice) only for use in such ; system, except as may otherwise be provided in writing by Digital. ; ; Digital Equipment Corporation assumes no responsibility for the use ; or reliability of its software on equipment that is not supplied ; by Digital. ; ; Copyright (c) 1977, 1978 by Digital Equipment Corporation ; ; PROGRAM HISTORY ; ; Date Revision Reason for revision ; ; 31-Jan-77 A First release ; 28-Jun-78 B Hardware fault not detected ; ; ; TABLE OF CONTENTS ; ; 1.0 Program information ; 1.1 Abstract ; 1.2 Requirements ; 1.3 Related documents and standards ; 1.4 Preliminary programs ; ; 2.0 Operating instructions ; 2.1 Loading procedures ; 2.2 Starting procedures ; 2.3 Operational switch settings ; 2.4 Loading the switch register ; 2.5 Execution times ; ; 3.0 Error information ; 3.1 Error reporting procedures ; 3.2 Interpreting error reports ; 3.3 Sample error report ; ; 4.0 Miscellaneous information ; 4.1 ACT/APT/XXDP compatability ; 4.2 End-of-pass message ; 4.3 T-bit trapping ; 4.4 Power failure handling ; 4.5 Physical bus address construction ; ; 5.0 Program description ; 5.1 Subroutines used by this program ; 5.2 Program listing ; 5.3 Using the program to diagnose a fault ; ; 1.0 Program information ; 1.1 Abstract ; ; This program was designed using a "bottom up" approach ; starting with the smallest segment of memory management ; logic possible and building to cover all of the logic. ; The diagnostic will provide enough information such that ; by deduction, the failure can be isolated to a small ; segment of the memory management logic. ; ; The program begins by testing some of the internal CPU ; data and address paths and address detection logic, then ; works outward through the memory management registers. ; After the registers are found to be useable, relocation ; (construction of physical addresses from a virtual address ; and the associated PAR/PDR information) is tested followed ; by testing of the abort and status segments of logic. ; Finally, checks of special abort sequences and testing of ; the mfpi/mtpi instructions are done. ; ; 1.2 Requirements ; ; A PDP 11/34 processor with a minimum of 16kW of memory ; and a console terminal are required to run the program ; unless the program is running under APT or ACT in which ; case the console terminal is not necessary. ; ; 1.3 Related documents and standards ; ; 1. ACT11/XXDP programming specification ; 2. Standard apt system to a pdp11 diagnostic interface ; 3. Diagnostic engineering standards and conventions ; 4. PDP-11 maindec sysmac package ; 5. XXDP user's manual ; ; 1.4 Preliminary programs ; ; Before this memory management diagnostic is run, the ; following CPU diagnostics should be run: ; ; md-11-dfkaa PDP-11/34 basic cpu tests ; md-11-dfkab PDP-11/34 traps tests ; ; Also, one of the main memory diagnostics should be run ; to scan at least the first 16k to see that a program ; can be executed. ; ; 2.0 Operating instructions ; 2.1 Loading procedures ; ; The program is supplied on the diagnostic load media. ; refer to the XXDP user's manual for further information. ; For use with ACT or APT, refer to their respective ; documents. The program can also be directly loaded ; using the absolute loader and the binary paper tape. ; ; 2.2 Starting procedures ; ; The program is started by loading address 200 and ; starting. If the processor has the optional programmer's ; console, the switch register should be set according to ; section 2.3 before the program is started. If there ; is no hardware switch register, the program will use the ; software switch register at location 176 (location 174 ; will be used as the software display register). In that case ; the program will ask for the initial switch register ; value by typing "swr = xxxxxx" "new= " after typing ; the name of the program (xxxxxx = the octal contents of ; location 176). (see section 2.4) ; ; Also the program can be made to use the software switch ; reg. even if the hardware switch reg. is present by loading ; "177777" into the hardware switch reg. before starting ; the program. ; ; 2.3 Control switch settings ; ; Switch Octal Use ; ; sw15 100000 Halt on error ; This switch when set will halt ; the processor when an error is ; detected after the error message ; has been typed. pressing continue ; will resume testing (see section ; 3.1 about loading the switch reg ; before continuing). ; ; sw14 040000 Loop on test ; This switch when set will ; cause the program to loop on ; the current subtest. ; ; sw13 020000 Inhibit error typeouts ; This switch when set will ; inhibit the typing of error ; messages. ; ; sw12 010000 Inhibit trace trap ; This switch when set will ; Inhibit T-bit trapping which ; normally takes place during ; every other pass starting ; with the third pass. ; ; sw11 004000 Inhibit subtest iterations ; This switch when set inhibits ; iterations of each subtest after ; the first pass. If this switch ; is not set, each subtest is run ; 200. times. ; ; sw10 002000 Bell on error ; This switch when set will ring ; the console terminal bell when ; an error has been detected. ; ; sw9 001000 Loop on error ; This switch when set will ; cause the program to loop on the ; first failure which is encountered ; even if the failure is intermittant ; ; sw8 000400 Loop on test in swr <7:0> ; This switch when set will ; cause the program to loop on the ; test whose test number is set ; in bits 7-0 of the switch reg. ; ; 2.4 Loading the switch register ; ; The hardware switch register provided when the optional ; programmer's console is present is loaded directly from ; the console keypad by depressing the "lsr" key. The ; value of the hardware switch reg. can be changed any ; time whether the program is running or not. ; ; To load the software switch reg. while the program is ; running, a control g (^g) should be typed on the console ; terminal. (the "scope" and "error" routines check to see ; if a ^g has been typed.) The original value of the software ; switch reg. will be requested as mentioned in section 2.2. ; ; In response to a ^g or at the beginning of the program, the ; program will type: ; ; swr = xxxxxx new = ; ; where "xxxxxx" is the current octal contents of loc. 176. ; The operator may then type any one of the following: ; ; - xxxxxx one to six octal digits followed by a ; carriage return which will be loaded as the new ; value for the switch reg. ; - just a , leaves the switch reg. as it is. ; ; - xxx^u, a control-u (^u) will cause all of the ; digits typed so far to be ignored. ; ; - ^c will cause the program to type the present ; test and pass numbers, request a new value ; for the switch reg., and jump to the end- ; of-pass routine so the program will go directly ; to the next pass with a new sw. reg. value ; ; - any character typed which is not any of the ; above or an octal digit will cause the program ; to type a "?" and react as though a ; ^u had been typed. ; ; NOTE: recognition of a ^g may be hampered by ; ----- execution of a couple "reset" instructions ; within the program. ; ; 2.5 Execution times ; ; The run time for a single pass with no iterations ; or trace trapping is approximately 5 seconds. ; ; The run time for a single pass with iterations ; and trace trapping enabled is approximately 3 1/4 minutes. ; ; 3.0 Error information ; ; 3.1 Error reporting procedures ; ; If an error is detected, the program will trap to the ; error handling routine ($error). The value of bits ; 15, 13, 10, and 9 in the switch register are considered ; in reporting an error (see section 2.3). the ; error information will be typed unless sw13 = 1. ; ; If sw15 = 1, the processor will halt after the error is ; reported. If the contents of the software switch register ; are to be changed, a ^g should be typed before pressing ; "continue" to resume testing. ; ; If sw9 = 1 (loop on error), the program will go to the ; address contained in location "$lperr". After reporting ; the error. "$lperr" is set by each "scope" call and is ; set directly during some subtests to provide the smallest ; loop for looping on error. If sw9 = 0, the program will ; return to the instruction following the error call. ; (see section 5.3 for more on "loop on error"). ; ; 3.2 Interpreting error reports ; ; Every error report types the number of the test in which ; the error took place (testno) and the location of the ; error call (errorpc). These two values pinpoint the ; place in the code that the error occurred. by referring ; to the program listing, The operator can then read the ; comments associated with that particular error and subtest. ; A description of the test found in the program listing ; will also provide the operator with information on the logic ; and functions being tested. ; ; Every error report also types an error message ; giving a verbal description of the error that has ; been detected. ; ; By using the comments and test description found in ; the program listing to determine what function or ; logic was being tested, the operator can then refer ; to the engineering drawings to isolate the probable ; cause for the failure. ; ; 3.3 Sample error report ; ; Below is an example of an error which could have ; occurred during execution of the program: ; ; mem. mgmt. reg. bits not set correctly ; registr wrote read read-(binary) ; address (octal) (octal) 5432109876543210 testno errorpc ; 177572 040000 060000 0110000000000000 000012 022060 ; ; We see that the error occurred in test 12 at location ; 022060. The "registr address" tells us that we were ; testing memory management's status register 0 (SR0). ; in the listing, The test description says that the ; error bits (bits <15:13>) of SR0 were being set and ; cleared individually. The error report says we tried ; to set bit 14 by writing "040000" to SR0 but when we ; read it back we read "060000". It appears that bit 13 is ; stuck at "1" or it is getting set when bit 14 is set ; to "1". Error reports before and after this one could ; tell us which is the case. ; ; 4.0 Miscellaneous information ; 4.1 ACT/APT/XXDP compatability ; ; The program is fully ACT and APT compatable ; and is supported under the xxdp package. ; ; 4.2 End-of-pass message ; ; At the end of each pass of the program the pass number ; and total number of errors since the last end-of-pass are ; reported in the end-of-pass message. for example: ; ; END OF PASS #2 TOTAL ERRORS SINCE LAST REPORT 0 ; ; That would indicate that pass two was just completed ; and no errors were detected during that pass. both ; the pass number and number of errors are decimal numbers. ; ; 4.3 T-bit trapping ; ; The "T-bit" (bit 4) in the processor status word is set ; by an "rti" in the end-of-pass routine for every other pass ; beginning with the third pass (passes 3, 5, 7, 9...). T-bit ; trapping can be inhibited by setting bit 12 = 1 in the switch ; register (see section 2.4). ; ; 4.4 Power failure handling ; ; If a power fail occurs (followed by a power up). the ; message "power failure-restarting" is typed out and ; the program will restart execution at "start:" (the ; very beginning of the program). If the software ; switch register is being used. its contents will be ; restored. if there is a hardware switch register, ; there is no way to restore the value of the switch ; register so the operator must reload it from the console. ; ; 4.5 Physical bus address construction ; ; Below is a simplified diagram of how the memory ; management logic constructs a physical bus address ; using the virtual address and the page address register. ; the page descriptor register selected will contain the ; page expansion, length, and access information. ; ; 12 11 10 09 08 07 06 05 04 03 02 01 00 ; -------------------------------------- ; / 0 1 1 1 1 1 1 1 1 1 1 1 0/ vba* ; --------------------------------------- ; I ; (added to) I ; I ; 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 I ; ------------------------------------------------ I ; / 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1/ I par** ; ------------------------------------------------- I ; I I ; I I ; V V ; 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 ; ------------------------------------------------------------------- ; / 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0/ pba ; ------------------------------------------------------------------- ; ; *= vba bits <15:13> select the appropriate PAR and PDR ; **= PSW mode bit 15 selects the user (=1) or ; kernel (=0) set of par's/pdr's ; ; 5.0 Program description ; ; 5.1 Subroutines used by this program ; ; Following is a list of the subroutines and handlers used ; by this program that are not provided by the "sysmac ; package". Details of the subroutines unique to this ; program may be found in the program listing. Refer to ; the "sysmac" document and program listing for the other ; routines. ; ; 1. Turn off T-bit and save current PSW ; 2. Turn on T-bit and restore previous PSW ; 3. Set all writeable bits in all PAR/PDR's ; 4. Read and compare kernel and user PAR/PDR's ; 5. Convert virtual address to physical address ; ; 5.2 Program listing ; ; A table of contents appears at the beginning of the listing ; which contains the names of each section, subtest, and ; routine and the line numbers corresponding to the start of ; each. ; ; Following this section of documentation is the actual ; program listing complete with subtest descriptions and ; "coding comments". ; ; 5.3 Using the program to diagnose a fault ; ; When an error occurs, one of the things that's important ; to note is what pass the error occurred on. If the pass ; number is odd and is three or greater, the error might be ; T-bit sensitive. Try running the program again with bit ; 12 of the switch reg. equal to "1" to inhibit T-bit ; trapping. If the pass number is greater than one, the ; error may be iteration sensitive. Try running the program ; again with bit 11 of the switch reg. equal to "1" to inhibit ; iterations. These hints should help you determine what makes ; the machine fail and when. ; ; If you have been running with bit 15 of the switch ; reg. equal to "0", then you are able to look at all ; the errors that may be related to the fault you are ; diagnosing. A fault in an earlier test may result in ; errors during later tests which may give you more ; clues about the nature of the fault. Now use the method ; outlined in section 3.2 for each error to gather as ; much information as possible. ; ; Now to test your ideas on the cause of the failure, ; you may want to scope this error condition. Set bit 9 ; of the switch reg. equal to "1" to loop on the error. ; For an even tighter scope loop the error call can be ; replaced with a branch (refer to comments by error calls ; in the program listing). ; ; Or you could loop on the test by either setting bit 14 ; of the switch reg. equal to "1" of by setting bit 08 of the ; switch reg. equal to "1" and then setting the test number ; in bits 07-00 of the switch reg. You will probably want to ; inhibit error typeouts by setting bit 13 of the switch reg. ; equal to "1". ;_____________________________________________________________________________ ; HOEP = 0 ; halt on end-of-pass NOSCO = 0 ; no scope trap INSWR = 000000 ; 100000 for halt on error, no gtswr MSIM = 0 ; make test shorter for simulation SKIP = 0 ; skip/minimize final prints ;_____________________________________________________________________________ ; .asect ; . = 0 ; loop on test .title CFKTHB0 PDP 11/34 MEM MGNT DIAG .nlist cnd, mc, md .list me ; ;_____________________________________________________________________________ ; ; This program was assembled using the pdp-11 maindec sysmac ; package (maindec-11-dzqac-c3), Jan 19, 1977. ; .sbttl "OPERATIONAL SWITCH SETTINGS" ; ; switch use ; ------ ----------------------------------- ; 15 Halt on error ; 14 Loop on test ; 13 Inhibit error typeouts ; 12 Inhibit trace trap ; 11 Inhibit iterations ; 10 Bell on error ; 9 Loop on error ; 8 Loop on test in swr <7:0> ; .sbttl "BASIC DEFINITIONS" .macro error, code emt code .endm ;_____________________________________________________________________________ ; .if ne NOSCO ; scope = 240 ; nop .iff ; scope = iot ; .equiv iot, scope - basic definition of scope call .endc ; stack = 1100 ; initial address of the stack pointer ht = 11 ; code for horizontal tab lf = 12 ; code for line feed cr = 15 ; code for carriage return crlf = 200 ; code for carriage return-line feed ps = 177776 ; processor status word psw = ps ; stklmt = 177774 ; stack limit register pirq = 177772 ; program interrupt request register dswr = 177570 ; hardware switch register ddisp = 177570 ; hardware display register aptspool = 100 ; ; "switch register" switch definitions sw15 = 100000 ; sw14 = 40000 ; sw13 = 20000 ; sw12 = 10000 ; sw11 = 4000 ; sw10 = 2000 ; sw09 = 1000 ; sw08 = 400 ; sw07 = 200 ; sw06 = 100 ; sw05 = 40 ; sw04 = 20 ; sw03 = 10 ; sw02 = 4 ; sw01 = 2 ; sw00 = 1 ; sw9 = sw09 ; sw8 = sw08 ; sw7 = sw07 ; sw6 = sw06 ; sw5 = sw05 ; sw4 = sw04 ; sw3 = sw03 ; sw2 = sw02 ; sw1 = sw01 ; sw0 = sw00 ; ; data bit definitions (bit00 to bit15) bit15 = 100000 ; bit14 = 40000 ; bit13 = 20000 ; bit12 = 10000 ; bit11 = 4000 ; bit10 = 2000 ; bit09 = 1000 ; bit08 = 400 ; bit07 = 200 ; bit06 = 100 ; bit05 = 40 ; bit04 = 20 ; bit03 = 10 ; bit02 = 4 ; bit01 = 2 ; bit00 = 1 ; ; bit9 = bit09 ; bit8 = bit08 ; bit7 = bit07 ; bit6 = bit06 ; bit5 = bit05 ; bit4 = bit04 ; bit3 = bit03 ; bit2 = bit02 ; bit1 = bit01 ; bit0 = bit00 ; ; ; basic "CPU" trap vector addresses errvec = 4 ; time out and other errors resvec = 10 ; reserved and illegal instructions tbitvec = 14 ; "T"-bit trtvec = 14 ; trace trap bptvec = 14 ; breakpoint trap (bpt) iotvec = 20 ; input/output trap (iot) **scope** pwrvec = 24 ; power fail emtvec = 30 ; emulator trap (emt) **error** trapvec = 34 ; "trap" trap tkvec = 60 ; tty keyboard vector tpvec = 64 ; tty printer vector pirqvec = 240 ; program interrupt request vector ; ;_____________________________________________________________________________ ; .sbttl "MEMORY MANAGEMENT DEFINITIONS" mmvec = 250 ; kt11 vector address ; kt11 status register addresses sr0 = 177572 ; sr1 = 177574 ; sr2 = 177576 ; sr3 = 172516 ; ; user "I" page descriptor registers uipdr0 = 177600 ; uipdr1 = 177602 ; uipdr2 = 177604 ; uipdr3 = 177606 ; uipdr4 = 177610 ; uipdr5 = 177612 ; uipdSP = 177614 ; uipdr7 = 177616 ; ; user "I" page address registers uipar0 = 177640 ; uipar1 = 177642 ; uipar2 = 177644 ; uipar3 = 177646 ; uipar4 = 177650 ; uipar5 = 177652 ; uipaSP = 177654 ; uipar7 = 177656 ; ; kernel "I" page descriptor registers kipdr0 = 172300 ; kipdr1 = 172302 ; kipdr2 = 172304 ; kipdr3 = 172306 ; kipdr4 = 172310 ; kipdr5 = 172312 ; kipdSP = 172314 ; kipdr7 = 172316 ; ; kernel "I" page address registers kipar0 = 172340 ; kipar1 = 172342 ; kipar2 = 172344 ; kipar3 = 172346 ; kipar4 = 172350 ; kipar5 = 172352 ; kipaSP = 172354 ; kipar7 = 172356 ; ; ksp = SP ; usp = SP ; tbit = bit4 ; wbit = bit6 ; kerstk = stack ; usestk = stack-200 ; ;_____________________________________________________________________________ ; .macro vect, offset, adr, val ; . = offset ; .if nb, ; .word adr ; .iff ; .word .+2 ; .endc ; .if nb, ; .word val ; .iff ; .word 0 ; .endc ; .endm ; ;_____________________________________________________________________________ ; ; all unused locations from 4-776 contain a ".+2, halt" ; sequence to catch illegal traps and interrupts ; location 0 contains 0 to catch improperly loaded vectors ; .sbttl "TRAP CATCHER" .nlist ; vect 0, 0 ; vect 4, 6 ; vect 10, 12 ; vect 14, 16 ; vect 20, 22 ; vect 24, 200 ; for apt start up vect 30, 32 ; vect 34, 36 ; vect 40, 42 ; hooks required by act-11 vect 44, $apthd, $endad ; set loc.46 to address of $endad in .seop .list ; ;_____________________________________________________________________________ ; .sbttl "act11 hooks" .nlist ; vect 50, 52 ; set loc.52 to zero vect 54, 56 ; vect 60, 62 ; vect 64, 66 ; vect 70, 72 ; vect 74, 76 ; vect 100, 102 ; vect 104, 106 ; vect 110, 112 ; vect 114, 116 ; vect 120, 122 ; vect 124, 126 ; vect 130, 132 ; vect 134, 136 ; vect 140, 142 ; vect 144, 146 ; vect 150, 152 ; vect 154, 156 ; vect 160, 162 ; vect 164, 166 ; vect 170, 172 ; .list ; ; . = 174 ; dispreg: .word 0 ; software display register swreg: .word INSWR ; software switch register .sbttl "STARTING ADDRESS(ES)" jmp @#start ; jump to starting address of program ;_____________________________________________________________________________ ; .sbttl "APT PARAMETER BLOCK" ; ; Setup APT parameter block as defined in the apt-pdp11 diagnostic interface spec. ; $apthd: $hibts: .word 0 ; two high bits of 18 bit mailbox addr. $mbadr: .word $mail ; address of apt mailbox (bits 0-15) $tstm: .word 10 ; run tim of longest test $pastm: .word 20 ; run time in secs. of 1st pass on 1 unit (quick verify) $unitm: .word 5 ; additional run time (secs) of a pass for each additional unit .word $etend-$mail/2 ; length mailbox-etable(words) ;_____________________________________________________________________________ ; .nlist ; vect 220, 222 ; vect 224, 226 ; vect 230, 232 ; vect 234, 236 ; vect 240, 242 ; vect 244, 246 ; vect 250, 252 ; vect 254, 256 ; vect 260, 262 ; vect 264, 266 ; vect 270, 272 ; vect 274, 276 ; vect 300, 302 ; vect 304, 306 ; vect 310, 312 ; vect 314, 316 ; vect 320, 322 ; vect 324, 326 ; vect 330, 332 ; vect 334, 336 ; vect 340, 342 ; vect 344, 346 ; vect 350, 352 ; vect 354, 356 ; vect 360, 362 ; vect 364, 366 ; vect 370, 372 ; vect 374, 376 ; ; vect 400, 402 ; vect 404, 406 ; vect 410, 412 ; vect 414, 416 ; vect 420, 422 ; vect 424, 426 ; vect 430, 432 ; vect 434, 436 ; vect 440, 442 ; vect 444, 446 ; vect 450, 452 ; vect 454, 456 ; vect 460, 462 ; vect 464, 466 ; vect 470, 472 ; vect 474, 476 ; vect 500, 502 ; vect 504, 506 ; vect 510, 512 ; vect 514, 516 ; vect 520, 522 ; vect 524, 526 ; vect 530, 532 ; vect 534, 536 ; vect 540, 542 ; vect 544, 546 ; vect 550, 552 ; vect 554, 556 ; vect 560, 562 ; vect 564, 566 ; vect 570, 572 ; vect 574, 576 ; ; vect 600, 602 ; vect 604, 606 ; vect 610, 612 ; vect 614, 616 ; vect 620, 622 ; vect 624, 626 ; vect 630, 632 ; vect 634, 636 ; vect 640, 642 ; vect 644, 646 ; vect 650, 652 ; vect 654, 656 ; vect 660, 662 ; vect 664, 666 ; vect 670, 672 ; vect 674, 676 ; vect 700, 702 ; vect 704, 706 ; vect 710, 712 ; vect 714, 716 ; vect 720, 722 ; vect 724, 726 ; vect 730, 732 ; vect 734, 736 ; vect 740, 742 ; vect 744, 746 ; vect 750, 752 ; vect 754, 756 ; vect 760, 762 ; vect 764, 766 ; vect 770, 772 ; vect 774, 776 ; .list ; ;_____________________________________________________________________________ ; ; This table contains various common storage locations used in the program ; . = 1100 ; $cmtag: .word 0 ; start of common tags $tstnm: .byte 0 ; contains the test number $erflg: .byte 0 ; contains error flag $icnt: .word 0 ; contains subtest iteration count $lpadr: .word 0 ; contains scope loop address $lperr: .word 0 ; contains scope return for errors $erttl: .word 0 ; contains total errors detected $itemb: .byte 0 ; contains item control byte $ermax: .byte 1 ; contains max. errors per test $errpc: .word 0 ; contains PC of last error instruction $gdadr: .word 0 ; contains address of 'good' data $bdadr: .word 0 ; contains address of 'bad' data $gddat: .word 0 ; contains 'good' data $bddat: .word 0 ; contains 'bad' data .word 0 ; reserved—not to be used .word 0 ; $autob: .byte 0 ; automatic mode indicator $intag: .byte 0 ; interrupt mode indicator .word 0 ; swr: .word dswr ; address of switch register display: .word ddisp ; address of display register $tks: .word 177560 ; tty kbd status $tkb: .word 177562 ; tty kbd buffer $tps: .word 177564 ; tty printer status reg. address $tpb: .word 177566 ; tty printer buffer reg. address $null: .byte 0 ; contains null character for fills $fills: .byte 2 ; contains # of filler characters required $fillc: .byte 12 ; insert fill chars. after a "line feed" $tpflg: .byte 0 ; insert fill chars. after a "line feed" $regad: .word 0 ; contains the address from ; which (sreg0) was obtained $reg0: .word 0 ; contains ((sregad)+0) $reg1: .word 0 ; contains ((sregad)+2) $reg2: .word 0 ; contains ((sregad)+4) $reg3: .word 0 ; contains (($regad)+6) $reg4: .word 0 ; contains (($regad)+10) $reg5: .word 0 ; contains (($regad)+12) $tmp0: .word 0 ; user defined $tmp1: .word 0 ; user defined $tmp2: .word 0 ; user defined $tmp3: .word 0 ; user defined $tmp4: .word 0 ; user defined $tmp5: .word 0 ; user defined $times: .word 0 ; max. number of iterations $escape: .word 0 ; escape on error address $bell: .asciz <207><377><377> ; code for bell $ques: .ascii /?/ ; question mark $crlf: .ascii <15> ; carriage return $lf: .asciz <12> ; line feed .sbttl "APT MAILBOX-ETABLE" ;_____________________________________________________________________________ ; .even ; $mail: ; apt mailbox $msgty: .word 0 ; message type code $fatal: .word 0 ; fatal error number $testn: .word 0 ; test number $pass: .word 0 ; pass count $devct: .word 0 ; device count $unit: .word 0 ; i/o unit number $msgad: .word 0 ; message address $msglg: .word 0 ; message length $etable: ; apt environment table $env: .byte 0 ; environment byte $envm: .byte 0 ; environment mode bits $swreg: .word 0 ; apt switch register $uswr: .word 0 ; user switches $cpuop: .word 0 ; cpu type, options ; bits 15-11=cpu type ; 11/04=01, 11/05=02, ; 11/20=03, 11/40=04, ; 11/45=05, 11/70=06, ; pdq=07, q=10 ; bit 10 = real time clock ; bit 9 = floating point processor ; bit 8 = memory management ;_____________________________________________________________________________ ; $mams1: .byte 0 ; high address, m.s. byte $mtyp1: .byte 0 ; mem. type, blk#1 ; mem. type byte -- (high byte) ; 900 nsec core=001 ; 300 nsec bipolar=002 ; 500 nsec mos=003 $madr1: .word 0 ; high address, blk#1 ; mem. last addr.=3 bytes, ; this word and low of "type" above $mams2: .byte 0 ; high address, m.s. byte $mtyp2: .byte 0 ; mem. type, blk#2 $madr2: .word 0 ; mem. last address, blk#2 $mams3: .byte 0 ; high address, m.s. byte $mtyp3: .byte 0 ; mem. type, blk#3 $madr3: .word 0 ; mem. last address, blk#3 $mams4: .byte 0 ; high address, m.s. byte $mtyp4: .byte 0 ; mem. type, blk#4 $madr4: .word 0 ; mem. last address, blk#4 $vect1: .word 0 ; interrupt vector#1, bus priority#1 $vect2: .word 0 ; interrupt vector#2, bus priority#2 $base: .word 0 ; base address of equipment under test $devm: .word 0 ; device map $cdw1: .word 0 ; controller description word#1 $cdw2: .word 0 ; controller description word#2 $ddw0: .word 0 ; device descriptor word#0 $ddw1: .word 0 ; device descriptor word#1 $ddw2: .word 0 ; device descriptor word#2 $ddw3: .word 0 ; device descriptor word#3 $ddw4: .word 0 ; device descriptor word#4 $ddw5: .word 0 ; device descriptor word#5 $ddw6: .word 0 ; device descriptor word#6 $ddw7: .word 0 ; device descriptor word#7 $ddw8: .word 0 ; device descriptor word#8 $ddw9: .word 0 ; device descriptor word#9 $ddw10: .word 0 ; device descriptor word#10 $ddw11: .word 0 ; device descriptor word#11 $ddw12: .word 0 ; device descriptor word#12 $ddw13: .word 0 ; device descriptor word#13 $ddw14: .word 0 ; device descriptor word#14 $ddw15: .word 0 ; device descriptor word#15 ; $etend: ; ; testno: .word 0 ; holds test number for typeouts wasSP: .word 0 ; used to store the stack pointer after a trap trappc: .word 0 ; used to store the PC of a trap or abort trapps: .word 0 ; used to store the ps of a trap or abort corsr0: .word 0 ;+ used to store the correct sr0 corsr2: .word 0 ;+ used to store the correct sr2 wassr0: .word 0 ; used to store contents of sr0 wassr2: .word 0 ; used to store contents or sr2 tbitps: .word 0 ; saves the PSW that may have its T-bit on andadr: .word 0 ; holds result of addresses being and-ed oradr: .word 0 ; holds result of addresses being or-ed tonum: .word 0 ; holds number of time-outs virt1: .word 0 ; holds virtual address to be converted virt2: .word 0 ; holds virtual address to be converted pbalo: .word 0 ; holds bits <15:00> of physical address pbahi: .word 0 ; holds bits <17:16> of physical address .sbttl "ERROR POINTER TABLE" ;_____________________________________________________________________________ ; ; This table contains the information for each error that can occur. ; The information is obtained by using the index number found in ; location $itemb. This number indicates which item in the table is pertinent. ; Note1: If $itemb is 0 the only pertinent data is ($errpc). ; Note2: Each item in the table contains 4 pointers explained as follows: ; ; em ; points to the error message ; dh ; points to the data header ; dt ; points to the data ; df ; points to the data format ; $errtb: ; item 1 em1 ; unexpected cpu trap to loc. 004 dh1 ; old PC old PSW SP was testno errorpc dt1 ; trappc, trapps, wasSP, testno, $erppc, 0 df1 ; 0, 0, 0, 0, 0 ; item 2 em2 ; unexpected mem. mgmt. trap to loc. 250 dh2 ; old PC old PSW SP was sr0 sr2 testno errorpc dt2 ; trappc, trapps, wasSP, wassr0, wassr2, testno, $errpc, df2 ; 0, 0, 0, 0, 0, 0, 0 ; item 3 em3 ; priority bits set wrong in PSW dh3 ; wrote read testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 4 em4 ; mode bits set wrong in PSW dh3 ; wrote read testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 5 em5 ; dual addressing between hi&lo bytes of PSW dh3 ; wrote read testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 6 em6 ; kernel SP changed by writing user SP dh3 ; wrote read testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 7 em7 ; a memory mgmt. reg. timed out dh7 ; address testno errorpc dt7 ; $reg0, testno, $errpc, 0 df7 ; 0, 0, 0 ; item 10 em10 ; summary of mem. mgmt. reg. timeouts dh10 ; register-addrs num. of ; and-ed or-ed timouts testno errorpc dt10 ; andadr, oradr, tonum, testno, $errpc, 0 df10 ; 0, 0, 1, 0, 0 ; item 11 em11 ; mem. mgmt. reg. would not clear dh11 ; registr read read-(binary) ; address (octal) 5432109876543210 testno errorpc dt11 ; $reg0, $reg1, $reg1, testno, $errpc, 0 df11 ; 0, 0, 2, 0, 0 ; item 12 em12 ; mem. mgmt. reg. bits not set correctly dh12 ; registr wrote read read ; address (octal) (octal) (binary) testno errorpc dt12 ; $reg0, $reg1, $reg2, $reg2, testno, $errpc, 0 df12 ; 0, 0, 0, 2, 0, 0 ; item 13 em13 ; sr0 effected by write to PSW dh13 ; read testno errorpc dt13 ; $reg0, testno, $errpc, 0 df13 ; 0, 0, 0 ; item 14 em14 ; sr1 did not read all zeros dh13 ; read testno errorpc dt13 ; $reg0, testno, $errpc, 0 df13 ; 0, 0, 0 ; item 15 em15 ; dual addressing between bytes of par or pdr dh12 ; register wrote read read ; address (octal) (octal) (binary) testno errorpc dt12 ; $reg0, $reg1, $reg2, $reg2, testno, $errpc, 0 df12 ; 0, 0, 0, 2, 0, 0 ; item 16 em16 ; dual addressing between par-pdr's dh16 ; par-pdr par-pdr ; cleared effectd expectd receivd testno errorpc dt16 ; $reg0, $reg1, $reg5, $reg2, testno, $errpc, 0 df16 ; 0, 0, 0, 0, 0, 0 ; item 17 em17 ; phys. addr. formed read wrong in maint. mode dh17 ; physical virtual ; address address kipar4 testno errorpc dt17 ; pbalo, virt1, $reg4, testno, $errpc, 0 df17 ; 3, 0, 0, 0, 0 ; item 20 em20 ; phys. addr. formed read wrong in relocate mode dh20 ; physicl par 4 par 5 ; address vba vba par 4 par 5 PSW testno dt20 ; pbalo, virt1, virt2, $reg4, $reg5, $tmp0, testno, $errpc, 0 df20 ; 3, 0, 0, 0, 0, 0, 0, 0 ; item 21 em21 ; W-bit did not get set in pdr dh21 ; pdr virtual ; tested address testno errorpc dt21 ; $reg5, $reg3, testno, $errpc, 0 df21 ; 0, 0, 0, 0 ; item 22 em22 ; W-bit set in more than one pdr dh22 ; pdr in pdr virtual ; error tested address testno errorpc dt22 ; $reg0, $reg5, $reg3, testno, $errpc, 0 df22 ; 0, 0, 0, 0, 0 ; item 23 em23 ; W-bit not cleared by writing to pdr dh23 ; pdr testno errorpc dt23 ; $reg5, testno, $errpc, 0 df23 ; 0, 0, 0 ; item 24 em24 ; writing sr0 set W-bit in kipdr7 dh24 ; pdr was expectd testno errorpc dt24 ; $reg2, $reg1, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 25 em25 ; W-bit got set during odd addr. abort dh24 ; pdr was expectd testno errorpc dt24 ; $reg2, $reg1, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 26 em26 ; memory mgmt. access abort did not occur dh26 ; pdr 4 PSW testno errorpc dt26 ; $reg2, $tmp0, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 27 em27 ; access error did not abort instruction dh26 ; pdr 4 PSW testno errorpc dt26 ; $reg2, $tmp0, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 30 em30 ; sr0 did not report access error correctly dh30 ; sr0 was expectd pdr 4 PSW testno errorpc dt30 ; wassr0, $reg3, $reg2, $tmp0, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 31 em31 ; sr2 did not lockup correct virtual addr. dh31 ; sr2 was expectd pdr 4 PSW testno errorpc dt31 ; wassr2, $reg4, $reg2, $tmp0, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 32 em32 ; page lgth. abort occurred when it shouldn't have dh32 ; v.b.a. kipdr4 sr0 was sr2 was testno errorpc dt32 ; $reg0, $reg4, wassr0, wassr2, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 33 em33 ; page lgth. abort did not occur when it should have dh33 ; v.b.a. kipdr4 testno errorpc dt33 ; $reg0, $reg4, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 34 em34 ; sr0 did not report page lgth. abort correctly dh34 ; v.b.a. kipdr4 sr0 was expectd testno errorpc dt34 ; $reg0, $reg4, wassr0, $reg2, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 35 em31 ; sr2 did not lockup correct virtual addr. dh35 ; v.b.a. kipdr4 sr2 was expectd testno errorpc dt35 ; $reg0, $reg4, wassr2, $reg3, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 36 em31 ; sr2 did not lockup correct virtual addr. dh36 ; sr2 was expectd testno errorpc dt36 ; wassr2, $reg1, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 37 em37 ; sr0 or sr2 changed by a second abort dh37 ; first abort second abort ; sr0 was sr2 was sr0 was sr2 was testno errorpc dt37 ; $tmp0, $tmp2, wassr0, wassr2, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 40 em40 ; sr0 or sr2 was not "reset" by a reset dh40 ; sr0 was sr2 was testno errorpc dt40 ; wassr0, wassr2, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 41 em41 ; sr2 not tracking correctly dh36 ; sr2 was expectd testno erropc dt36 ; wassr2, $reg1, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 42 em42 ; did not trap thru kernel space dh42 ; PSW was SP was testno errorpc dt42 ; $reg1, $reg2, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 43 em43 ; kt error serviced on odd addr. error dh23 ; pdr testno errorpc dt23 ; $reg5, testno, $errpc, 0 df23 ; 0, 0, 0 ; item 44 em44 ; sr0 or sr2 changed by odd addr. error dh44 ; expected received ; sr0 sr2 sr0 was sr2 was testno errorpc dt44 ; $reg0, $reg1, wassr0, wassr2, testno, $errpc, 0 df30 ; 0, 0, 0, 0, 0, 0 ; item 45 em45 ; error during "double error" (kt & odd addr.) dh45 ; expected: ; PSW PC sr0 sr2 ; 170017 (3$+4) 020147 (3$) ; received ; PSW PC sr0 sr2 testno errorpc dt45 ; $reg1, $reg3, wassr0, wassr2, testno, $errpc df30 ; 0, 0, 0, 0, 0, 0 ; item 46 em46 ; mfpi instruction pushed wrong data dh46 ; data data ; expectd receivd testno errorpc dt46 ; $reg0, $reg1, testno, $errpc, 0 df46 ; 0, 0, 0, 0 ; item 47 em47 ; mtpi instruction loaded wrong data dh46 ; data data ; expectd receivd testno errorpc dt46 ; $reg0, $reg1, testno, $errpc, 0 df46 ; 0, 0, 0, 0 ; item 50 em50 ; stack not pushed by mfpi-mtpi dh50 ; testno errorpc dt50 ; testno, $errpc, 0 df50 ; 0, 0 ; item 51 em51 ; kernel page accessed instead of user: mfpi-mtpi dh51 ; sr0 was sr2 was testno errorpc dt51 ; wassr0, wassr2, testno, $errpc, 0 df51 ; 0, 0, 0, 0 ; item 52 em52 ; wrong pdr's referenced while in relocate mode dh52 ; physicl par 4 ; address v.b.a. par 4 sr0 was sr2 was PSW testno dt52 ; pbalo, virt1, $reg4, wassr0, wassr2, $tmp0, testno, $errpc, 0 df52 ; 3, 0, 0, 0, 0, 0, 0, 0 ; item 53 em53 ; mfpd instruction pushed wrong data dh46 ; data data ; expectd receivd testno errorpc dt46 ; $reg0, $reg1, testno, $errpc, 0 df46 ; 0, 0, 0, 0 ; item 54 em54 ; stack not pushed by mfpd-mtpd dh50 ; testno errorpc dt50 ; testno, $errpc, 0 df50 ; 0, 0 ; item 55 em55 ; par or pdr was changed by a reset dh11 ; registr read read-(binary) ; address (octal) 5432109b76543210 testno errorpc dt11 ; $reg0, $reg1, $reg1, testno, $errpc, 0 df11 ; 0, 0, 2, 0, 0 ; item 56 em56 ; illegal mode 01 not aborted dh50 ; testno errorpc dt50 ; testno, $errpc, 0 df50 ; 0, 0 ; item 57 em57 ; sr0 did not report illegal mode 01 correctly dh57 ; sr0 was expectd testno errorpc dt57 ; wassr0, $reg1, testno, $errpc, 0 df57 ; 0, 0, 0, 0 ; item 60 em60 ; PSW changed by an rti in user mode dh60 ; PSW was expectd testno errorpc dt60 ; $reg1, $reg2, testno, $errpc, 0 df60 ; 0, 0, 0, 0 ; item 61 em61 ; maint mode (sr0 <8>) not disabled by a reset dh50 ; testno errorpc dt50 ; testno, uerrpc, 0 df50 ; 0, 0 ; item 62 em62 ; data incorrect after a maint. mode write dh3 ; wrote read testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 63 em63 ; source relocated in maint. mode dh2 ; old PC old PSW SP was sr0 sr2 testno errorpc dt2 ; trappc, trapps, wasSP, wassr0, wassr2, testno, $errpc, 0 df2 ; 0, 0, 0, 0, 0, 0, 0 ; item 64 em31 ; sr2 didnot lockup correct virtual addr. dh36 ; sr2 was expectd testno errorpc dt64 ; wassr2, $reg4, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 65 em64 ; +non resident abort did not occur dh61 ; +sr0 sr2 testno errorpc dt65 ; +wassr0, wassr2, testno, $errorpc df61 ; +0, 0, 0, 0 ; item 66 em65 ; +error flag for kr abort did not set dh61 ; +sr0 sr2 testno errorpc dt65 ; +wassr0, wassr2, testno, $errpc df61 ; +0, 0, 0, 0 ; item 67 em66 ; +sr2 did not freeze the virtual adrs of abort dh61 ; +sr0 sr2 testno errorpc dt65 ; +wassr0, wassr2, testno, $errpc df61 ; +0, 0, 0, 0 ; item 70 em67 ; +2nd non resident abort did not occur dh61 ; +sr0 sr2 testno errorpc dt65 ; +wassr0, wassr2, testno, $errpc df61 ; +0, 0, 0, 0 ; item 71 em70 ; +2nd nr abort changed sr2 dh62 ; +sr2 expt sr2 recd testno errorpc dt66 ; +corsr0, wassr2, testno, $errpc df61 ; +0, 0, 0, 0 ; item 72 em71 ; +sr0 was not cleared by init dh63 ; +sr0 expt sr0 recd testno errorpc dt67 ; +corsr0, wassr0, testno, errorpc df61 ; +0, 0, 0, 0 .enabl ama ; .sbttl "***** TRAP HANDLING ROUTINES *****" .sbttl "CPU TRAP HANDLER ROUTINE" ;_____________________________________________________________________________ ; ; This subroutine will handle all cpu traps and aborts thru ; "errvec" (loc. 004). if this subroutine is entered by a ; second trap before the first has been serviced, a halt is ; executed. ; timerr: inc (PC)+ ; make flag zero if first time thru timflg: .word -1 ; negative one for "have entered" flag beq 1$ ; branch if first time in halt ; stop! - i've entered this routine ; a second time before i finished ; reporting the first error. the ; second entry address should be on ; the kernel stack. 1$: mov (KSP)+, trappc ; save PC+2 at time of abort mov (KSP)+, trapps ; save PSW at time of abort mov KSP, wasSP ; save stack pointer value error 1 ; unexpected trap or abort to loc. 4 mov #-1, timflg ; make flag negative one for next time mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rtt ; return from interrupt or abort .sbttl "MEMORY MANAGEMENT TRAP HANDLER ROUTINE" ;_____________________________________________________________________________ ; ; This subroutine will handle all unexpected memory management ; traps and aborts thru "mmvec" (loc. 250). If this subroutine is ; entered by a second trap before the first has been serviced, a ; halt is executed. ; mgmerr: inc (PC)+ ; make flag zero if first time thru mgmflg: .word -1 ; negative one for "have entered" flag beq 1$ ; branch if first time in halt ; stop! - i've entered this routine ; a second time before i finished ; reporting the first error. the ; second entry address should be on ; the kernel stack. 1$: mov (KSP)+, trappc ; save PC+2 at time of abort mov (KSP)+, trapps ; save ps at time of abort mov KSP, wasSP ; save stack pointer value mov sr0, wassr0 ; save contents of kt status reg. 0 mov sr2, wassr2 ; save contents of kt status reg. 2 bic #160000, sr0 ; clear error bits in status reg 0 error 2 ; unexpected trap or abort to loc. 250 mov #-1, mgmflg ; make flag negative one for next time mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rtt ; return from interrupt or abort. .sbttl "***** STARTING POINT OF TEST *****" .sbttl "***** STARTING ADDRESS OF 200 *****" . = 20000 ;_____________________________________________________________________________ ; .sbttl "INITIALIZE THE COMMON TAGS" start: ; clear the common tags ($cmtag) area mov #$cmtag, SP ; first location to be cleared clr (SP)+ ; clear memory location cmp #swr, SP ; done? bne .-6 ; loop back if no mov #stack, SP ; setup the stack pointer ; unitialize a few vectors mov #$scope, iotvec ; iot vector for scope routine mov #340, iotvec+2 ; level 7 mov #$error, emtvec ; emt vector for error routine mov #340, emtvec+2 ; level 7 mov #$trap, trapvec ; trap vector for trap calls mov #340, trapvec+2 ; level 7 mov #$pwrdn, pwrvec ; power failure vector mov #340, pwrvec+2 ; level 7 mov $endct, $eopct ; setup end-of-program counter clr $times ; initialize number of iterations clr $escape ; clear the escape on error address movb #1, $ermax ; allow one error per test ; ; Tnitialize the "T-bit" trap vector. Then load location "$rtrn", in ; the "END-OF-PASS" ($eop) routine, with a "rti" or "rtt". ; mov #$rtrn, tbitvec ; set "T"-bit vector to $rtrn mov #340, tbitvec+2 ; level 7 mov #rti, $rtrn ; set $rtrn to a rti mov #65$, resvec ; try to do a rtt clr -(SP) ; dummy PSW mov #64$, -(SP) ; and PC rtt ; try the rtt ; 64$: mov #rtt, $rtrn ; rtt is legal-set $rtrn to a rtt br 66$ ; 65$: add #10, SP ; rtt illegal-clean off the stack 66$: mov #resvec+2, resvec ; restore trap catcher clr $tbit ; clear "T"-bit switch mov #., $lpadr ; initialize the loop address for scope mov #., $lperr ; setup the error loop address ; ; Size for a hardware switch register. If not found or it is ; equal to a "-1", setup for a software switch register. ; mov @#errvec, -(SP) ; save error vector mov #67$, errvec ; set up error vector mov #dswr, swr ; setup for a hardware swich register mov #ddisp, display ; and a hardware display register cmp #-1, @swr ; try to reference hardware swr bne 69$ ; branch if no timeout trap occurred ; and the hardware swr is not = -1 br 68$ ; branch if no timeout ; 67$: mov #68$, (SP) ; set up for trap return rti ; ; 68$: mov #swreg, swr ; point to software swr mov #dispreg, display ; 69$: mov (SP)+, errvec ; restore error vector clr @#$pass ; clear pass count bitb #aptsize, $envm ; test user size under apt beq 70$ ; yes, use non-apt switch mov #$swreg, swr ; no, use apt switch register 70$: ; .sbttl "TYPE PROGRAM NAME" ;_____________________________________________________________________________ ; ; Type the name of the program if first pass ; inc #-1 ; first time? bne 71$ ; branch if no cmp #$endad, @#42 ; ACT-11? beq 71$ ; branch if yes type , 72$ ; type asciz string .sbttl "GET VALUE FOR SOFTWARE SWITCH REGISTER" tst @#42 ; are we running under XXDP/ACT? bne 73$ ; branch if yes cmpb @#$env, #1 ; are we running under APT? beq 73$ ; branch if yes cmp @#swr, #swreg ; software switch reg selected? bne 74$ ; branch if no gtswr ; get soft-swr settings br 74$ ; 73$: movb #1, @#$autob ; set auto-mode indicator 74$: br 71$ ; get over the asciz ; .if ne SKIP 72$: .asciz <15><0>#CFKTHB0 11/34 MEMORY MGMT. DIAG.# .iff 72$: .asciz #CFKTHB0 11/34 MEMORY MGMT. DIAG.# .endc .even ; 71$: ; ; loop: mov #stack, KSP ; initialize the stack pointer mov #timerr, errvec ; load cpu service routine into trap vector mov #340, errvec+2 ; set new ps to priority level 7-kernel mov #mgmerr, mmvec ; load memory managent routine into vector mov #340, mmvec+2 ; set new ps to priority level 7-kernel mov #-1, R0 ; put -1 into R0 to initialize flags mov R0, timflg ; initialize cpu error flag mov R0, mgmflg ; initialize memory management error flag mov #340, tbitps ; initialize log that holds T-bit PSW clr sr0 ; be sure mem. mgmt is off to start with ;_____________________________________________________________________________ ; ; Test 1 - PSW priority bit test ; ; This test reads and writes the processor status word <7:5> "priority bits" ; to see that some of the basic "data path" logic is working. ; tst1: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ clr R0 ; initialize R0 with priority=0 data 2$: clr R1 ; prepare R1 to accept data read mtps R0 ; write priority bits in the PSW mfps R1 ; read back the low byte of PSW bic #177437, R1 ; mask off everything except priority bits cmp R0, R1 ; was correct priority set in the PSW? beq 3$ ; branch if yes error 3 ; priority bits set wrong in PSW ; 3$: add #40, R0 ; change data to next priority cmp #400, R0 ; have priorities 0-7 all been checked? bne 2$ ; branch if no mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 2 - PSW mode bit test ; ; This test reads and writes the processor status word <15:12> "mode bits" ; to further check the basic CPU data paths. ; tst2: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ clr R0 ; initialize R0 with mode bits = 0000 2$: clr @#psw ; initialize PSW bis R0, PSW ; bit set the PSW mode bits with R0 mov PSW, R1 ; read back the contents of the PSW bic #007777, R1 ; mask off everything except the mode bits cmp R0, R1 ; were the mode bits set correctly? beq 3$ ; branch if yes clr PSW ; clear PSW for error report error 4 ; mode bits set wrong in PSW ; 3$: add #10000, R0 ; change mode bit data bne 2$ ; branch if still more combinations mov #1$, $lperr ; reset loop on error pointer to 1$ clr PSW ; reset PSW before leaving ;_____________________________________________________________________________ ; ; Test 3 - byte addressing test for PSW ; ; This test writes the high and low bytes of the processor status word ; and reads them back to be sure they can be written independently. ; This checks the PSW portion of the address detection logic. ; tst3: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ 2$: clr PSW ; clear the PSW mov #360, R0 ; put the high byte data into R0 movb R0, PSW+1 ; write the high byte of the PSW mov PSW, R1 ; read back the entire PSW bic #007437, R1 ; mask off the t & cc bits swab R0 ; get data written in high byte of R0 cmp R0, R1 ; was the PSW written to correctly beq 3$ ; branch if yes clr PSW ; clear PSW for error report error 5 ; low byte effected by write to high byte of PSW ; 3$: mov #4$, $lperr ; set loop on error pointer to 4$ 4$: clr PSW ; clear the PSW mov #340, R0 ; put the low byte data into R0 movb R0, PSW ; write the low byte of the PSW mov PSW, R1 ; read back the entire PSW bic #007437, R1 ; mask off the t & cc bits cmp R0, R1 ; was PSW written to correctly beq 5$ ; branch if yes clr PSW ; clear PSW for error report error 5 ; high byte effected by write to low byte of PSW ; 5$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 4 - test and setup of stack pointers ; ; This test sets the user and kernel stack pointers for the ; rest of the program and makes sure they are independent of ; each other. Kernel SP is set to 1100, user SP is set to 700, then ; kernel SP is read to be sure its still 1100. ; tst4: scope ; clr PSW ; go to kernel mode mov #kerstk, KSP ; set kernel stack pointer to 1100 mov #140000, PSW ; go to user mode mov #usestk, USP ; set user stack pointer to 700 clr PSW ; back to kernel mode cmp #kerstk, KSP ; is kernel SP still 1100? beq tst5 ; branch if kernel SP is okay mov #kerstk, R0 ; save data written for error report mov KSP, R1 ; save data read after user SP was written error 6 ; kernel SP changed by writing user SP ;_____________________________________________________________________________ ; ; The next five (5) tests will try to address all of the ; memory management registers (sr0, sr1, sr2, kernel & user par/pdr's). ; Every time a register times out its address will be reported. ; at the end of each test a summary of the addresses that timed ; out during that test is given. The results of "and-ing" and "or-ing" ; their addresses is given to show which address lines may be ; stuck at 0 or 1. The PAR/PDR address and KT mux's are the ; things being checked. ;_____________________________________________________________________________ ; ; Test 5 - sr0, sr1, sr2 timeout test ; ; This test addresses the memory management status registers: 0, 1, and 2. ; Status reg. 1 is not used but should still respond to its unibus address. ; Data will be written or read from these registers in later tests, this ; test just check for a response. ; tst5: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #5$, @#4 ; set timeout vector to 5$ mov #sr0, R0 ; load R0 with address of first reg. mov #3, R1 ; load R1 with the loop count mov #-1, andadr ; initialize "and" of addrs. loc. clr oradr ; initialize "or" of addrs. loc. clr tonum ; initialize "timeouts" counter 2$: tst (R0) ; try addressing a status register ; if it times out go to 5$ 3$: add #2, R0 ; put next address in R0 sob R1, 2$ ; loop back to 2$ until all tested mov #1$, $lperr ; reset loop on error pointer to 1$ tst tonum ; did any of the status reg.s timeout? beq 4$ ; branch if no error 10 ; summary of status reg. timeouts 4$: mov #timerr, @#4 ; restore normal cpu trap routine address br tst6 ; go to next test 5$: add #4, KSP ; clean up the stack error 7 ; one of the status regs. timed out ; mov R0, R2 ; load the address that timed out into R2 bis R2, oradr ; "or" it with other addrs. that timed out com R2 ; "and" it with other addrs. that timed out bic R2, andadr ; inc tonum ; increment the timeout counter br 3$ ; branch back to test the next addr. ;_____________________________________________________________________________ ; ; Test 6 - kernel PAR's timeout test ; ; This test addresses the eight (8) kernel page address ; registers (kipar0-kipar7) and checks that something ; responds to their addresses. ; tst6: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #5$, @#4 ; set timeout vector to 5$ mov #kipar0, R0 ; load R0 with address of first reg. mov #10, R1 ; load R1 with loop count (8) mov #-1, andadr ; initialize "and" of addr. loc clr oradr ; initialize "or" of addr. loc. clr tonum ; initialize "timeouts" counter 2$: tst (R0) ; try addressing a kipar ; if it times out, will go to 5$ 3$: add #2, R0 ; put next kipar address in R0 sob R1, 2$ ; loop back to 2$ until all tested mov #1$, $lperr ; reset loop on error pointer to 1$ tst tonum ; did any of the kipars time out? beq 4$ ; branch if no error 10 ; summary of kipar timeouts 4$: mov #timerr, @#4 ; restore normal cpu trap routine address br tst7 ; go to next test 5$: add #4, KSP ; clean up the stack error 7 ; one of the kipars timed out ; mov R0, R2 ; load the address that timed out into R2 bis R2, oradr ; "or" it with other addrs. that timed out com R2 ; "and" it with other addrs. that timed out bic R2, andadr ; inc tonum ; increment the timeout counter br 3$ ; branch back to test the next kipar ;_____________________________________________________________________________ ; ; Test 7 - kernel pdr's timeout test ; ; This test addresses the eight (8) kernel page descriptor ; registers (kipdr0-kipdr7) and checks that something ; responds to their addresses. ; tst7: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #5$, @#4 ; set timeout vector to 5$ mov #kipdr0, R0 ; load R0 with address of first reg. mov #10, R1 ; load R1 with loop count (8) mov #-1, andadr ; initialize "and" of addr. loc clr oradr ; initialize "or" of addr. loc. clr tonum ; initialize "timeouts" counter 2$: tst (R0) ; try addressing a kipdr ; if it times out, will go to 5$ 3$: add #2, R0 ; put next kipdr address in R0 sob R1, 2$ ; loop back to 2$ until all tested mov #1$, $lperr ; reset loop on error pointer to 1$ tst tonum ; did any of the kipdrs time out? beq 4$ ; branch if no error 10 ; summary of kipdr timeouts 4$: mov #timerr, @#4 ; restore normal cpu trap routine address br tst10 ; go to next test 5$: add #4, KSP ; clean up the stack error 7 ; one of the kipdrs timed out ; mov R0, R2 ; load the address that timed out into R2 bis R2, oradr ; "or" it with other addrs. that timed out com R2 ; "and" it with other addrs. that timed out bic R2, andadr ; inc tonum ; increment the timeout counter br 3$ ; branch back to test the next kipdr ;_____________________________________________________________________________ ; ; Test 10 - user par's timeout test ; ; This test addresses the eight (8) user page address ; registers (uipar0-uipar7) and checks that something ; responds to their addresses. ; tst10: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #5$, @#4 ; set timeout vector to 5$ mov #uipar0, R0 ; load R0 with address of first reg. mov #10, R1 ; load R1 with loop count (8) mov #-1, andadr ; initialize "and" of addr. loc clr oradr ; initialize "or" of addr. loc. clr tonum ; initialize "timeouts" counter 2$: tst (R0) ; try addressing a uipar ; if it times out, will go to 5$ 3$: add #2, R0 ; put next uipar address in R0 sob R1, 2$ ; loop back to 2$ until all tested mov #1$, $lperr ; reset loop on error pointer to 1$ tst tonum ; did any of the uipars time out? beq 4$ ; branch if no error 10 ; summary of uipar timeouts 4$: mov #timerr, @#4 ; restore normal cpu trap routine address br tst11 ; go to next test 5$: add #4, KSP ; clean up the stack error 7 ; one of the uipars timed out ; mov R0, R2 ; load the address that timed out into R2 bis R2, oradr ; "or" it with other addrs. that timed out com R2 ; "and" it with other addrs. that timed out bic R2, andadr ; inc tonum ; increment the timeout counter br 3$ ; branch back to test the next uipar ;_____________________________________________________________________________ ; ; Test 11 - user pdr's timeout test ; ; This test addresses the eight (8) user page descriptor ; registers (uipdr0-uipdr7) and checks that something ; responds to their addresses. ; tst11: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #5$, @#4 ; set timeout vector to 5$ mov #uipdr0, R0 ; load R0 with address of first reg. mov #10, R1 ; load R1 with loop count (8) mov #-1, andadr ; initialize "and" of addr. loc clr oradr ; initialize "or" of addr. loc. clr tonum ; initialize "timeouts" counter 2$: tst (R0) ; try addressing a uipdr ; if it times out, will go to 5$ 3$: add #2, R0 ; put next uipdr address in R0 sob R1, 2$ ; loop back to 2$ until all tested mov #1$, $lperr ; reset loop on error pointer to 1$ tst tonum ; did any of the uipdrs time out? beq 4$ ; branch if no error 10 ; summary of uipdr timeouts 4$: mov #timerr, @#4 ; restore normal cpu trap routine address br tst12 ; go to next test 5$: add #4, KSP ; clean up the stack error 7 ; one of the uipdrs timed out mov R0, R2 ; load the address that timed out into R2 bis R2, oradr ; "or" it with other addrs. that timed out com R2 ; "and" it with other addrs. that timed out bic R2, andadr ; inc tonum ; increment the timeout counter br 3$ ; branch back to test the next uipdr ;_____________________________________________________________________________ ; ; Test 12 - sr0(15:13) bit test & sr2 test ; ; This test checks bits <15:13> of status register 0 to see ; that each can be set and cleared and that a "reset" will ; clear all of them. A test of these three error bits checks ; part of sr0, the sr0 mux and the ktmux. The rest of the ; bits in sr0 will be checked later. ; ; Also check that sr2 is tracking with mem. mgmt. ; off but locks up when any of sr0 error bits set. ; tst12: scope ; 1$: mov #sr0, R0 ; load address of sr0 into R0 mov #160000, (R0) ; set bits <15:13> in sr0 (error bits) reset ; issue and "init" signal mov (R0), R1 ; read sr0 into R1 to see if clear beq 2$ ; branch if sr0 <15:13> cleared by "init" error 11 ; sr0 <15:13> not cleared by a "reset" ; mov #2$, $lperr ; set loop on error pointer to 2$ 2$: mov sr2, wassr2 ; read contents of sr2 mov #2$, R1 ; load expected contents into R1 cmp R1, wassr2 ; is sr2 tracking? beq 3$ ; branch if yes error 41 ; sr2 not "tracking" virtual addresses ; 3$: mov #4$, $lperr ; set loop on error pointer to 4$ mov #bit15, R1 ; put data to be written in R1 mov #3, R3 ; setup R3 as a loop counter 4$: clr (R0) ; clear sr0 5$: bis R1, (R0) ; set one of the error bits in sr0 mov (R0), R2 ; read sr0 into R2 cmp R1, R2 ; did right error bit get set? beq 6$ ; branch if yes error 12 ; bits were set wrong in sr0 ; 6$: mov #5$, R4 ; load expected contents of sr2 in R4 mov sr2, wassr2 ; read sr2 cmp R4, wassr2 ; did sr2 luck up when error ; bit set in sr1? beq 7$ ; branch if yes error 64 ; sr2 did not lock up ; 7$: ror R1 ; change data to check next error bit sob R3, 4$ ; loop back until <15:13> all tested clr (R0) ; clear sr0 before leaving mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 13 - sr0 & PSW dual addressing test ; ; This test checks more of the address detection logic by ; verifying that status register 0 is not effected by writing ; to the PSW and that the low byte of status register 0 ; is not effected by writing to its high byte. This is to ; see if adjacent outputs are shorted on the address det. logic. ; tst13: scope ; 1$: clr PSW ; clear the PSW clr sr0 ; clear status register 0 mtps #340 ; set priority 7 in low byte of PSW mov sr0, R0 ; read status register 0 beq 2$ ; branch if it was still 0 error 13 ; sr0 effected by a write to the PSW ; 2$: clr sr0 ; be sure sr0 is 0 before leaving clr PSW ; be sure PSW is 0 before leaving ;_____________________________________________________________________________ ; ; Test 14 - test that sr1 reads all zeros ; ; This test checks that even though status register 1 ; is non-existent, its address should respond with all zeros, ; Thereby check another portion of the address detection logic. ; tst14: scope ; mov #-1, R0 ; fill R0 with all ones mov sr1, R0 ; read sr1 into R0 beq tst15 ; branch if sr1 reads all zeros error 14 ; sr1 did not read all zeros ;_____________________________________________________________________________ ; ; Test 15 - bit test of kernel <8 user PAR's> ; ; The following test checks the bits <11:00> of both the kernel ; and user page address registers. A "0" is rotated thru ; the registers from left to right. This checks the operation ; of the par/pdr address mux, the kt mux, and the par output data lines. ; tst15: scope ; 1$: mov #kipar0, R0 ; load address of first par in R0 2$: mov #10, R3 ; setup R3 to count 8 par's mov #3$, $lperr ; set loop on error pointer to 3$ 3$: clr (R0) ; clear the par mov (R0), R1 ; read the par into R1 beq 4$ ; branch if par cleared ok error 11 ; par would not clear ; 4$: mov #167777, R4 ; load "walking 0" test pattern in R4 mov #5$, $lperr ; set loop on error pointer to 5$ 5$: clr (R0) ; clear the par before loading data mov R4, R1 ; load data into R1 bic #170000, R1 ; mask unused bits out of the data bis R1, (R0) ; bit set the test pattern into the par mov (R0), R2 ; read the par into R2 cmp R1, R2 ; does data written=data read? beq 6$ ; branch if yes error 12 ; par bits did not set correctly ; 6$: sec ; set the c-bit for the rotate inst. ror R4 ; rotate the test pattern in R4 bcs 5$ ; branch back if more bits to test add #2, R0 ; get next par address in R0 sob R3, 3$ ; branch back until all par's tested cmp #uipar7+2, R0 ; have user par's been tested bhis 7$ ; branch if yes mov #uipar0, R0 ; load first user par addr. in R0 br 2$ ; branch back to test user par's 7$: mov #1$, $lperr ; reset loop or error pointer to 1$ ; leave test with bits <11:1>=1 in all par's ;_____________________________________________________________________________ ; ; Test 16 - bit test of kernel & user PDR's ; ; The following test checks the bits <14:8> and <3:1> of both the ; kernel and user page descriptor registers. A "0" is rotated ; thru the registers from left to right. Some test patterns will ; be loaded more than once due to the unused bits in the PDR's. ; The PAR/PDRr address mux, ktmux, and PDR output data lines ; are being checked. ; tst16: scope ; 1$: mov #kipdr0, R0 ; load address of first pdr in R0 2$: mov #10, R3 ; setup R3 to count 8 pdr's mov #3$, $lperr ; set loop on error pointer to 3$ 3$: clr (R0) ; clear the pdr mov (R0), R1 ; read the pdr into R1 beq 4$ ; branch if pdr cleared ok error 11 ; pdr would not clear ; 4$: mov #077777, R4 ; load "walking "0" test pattern in R4 mov #5$, $lperr ; set loop on error pointer to 5$ 5$: clr (R0) ; clear the pdr before loading data mov R4, R1 ; load data into R1 bic #100361, R1 ; mask unused bits out of the data bis R1, (R0) ; bit set the test pattern into the pdr mov (R0), R2 ; read the pdr into R2 cmp R1, R2 ; does data written=data read? beq 6$ ; branch if yes error 12 ; pdr bits did not set correctly ; 6$: sec ; set the c-bit for the rotate inst. ror R4 ; rotate the test pattern in R4 bcs 5$ ; branch back if more bits to test add #2, R0 ; get next pdr address in R0 sob R3, 3$ ; branch back until all pdr's tested cmp #uipdr7+2, R0 ; have user pdr's been tested? bhis 7$ ; branch if yes mov #uipdr0, R0 ; load first user pdr addr. in R0 br 2$ ; branch back to test user pdr's 7$: mov #1$, $lperr ; reset loop on error pointer to 1$ ; leave test with all writeable bits in ; all pdr's = 1 ;_____________________________________________________________________________ ; ; Test 17 - test for dual byte addressing of kernel a user par's ; ; The following test writes to both bytes of the kernel & user ; par's separately to see that writing to one does not effect ; the other. This further verifies the operation of the par/pdr ; addr. mux and the addr. detection logic. ; tst17: scope ; 1$: mov #kipar0, R0 ; load address of first par into R0 2$: mov #3$, $lperr ; set loop on error pointer to 3$ mov #10, R3 ; load loop counter to do 8 par's 3$: mov #-1, R1 ; load test pattern into R1 clr (R0) ; clear the par movb R1, (R0) ; write 1's to the low byte of the par mov (R0), R2 ; read the entire par into R2 bic #177400, R1 ; mask high byte & unused bits out of the data cmp R1, R2 ; was only the low byte written to beq 4$ ; branch if yes error 15 ; high byte effected by writing low byte in par ; 4$: mov #5$, $lperr ; set loop on error pointer to 5$ 5$: clr (R0) ; clear the par mov #-1, R1 ; load test, pattern into R1 movb R1, 1(R0) ; write 1's to the high byte of the par mov (R0), R2 ; read the entire par into R2 bic #170377, R1 ; mask low byte & unused bits out of data cmp R1, R2 ; was only the high byte written to? beq 6$ ; branch if yes error 15 ; low byte effected by writing high byte in par ; 6$: add #2, R0 ; put address of next par in R0 sob R3, 3$ ; branch back until 8 par's tested cmp #uipar7+2, R0 ; have user par's been tested bhis 7$ ; branch if yes mov #uipar0, R0 ; load address of first user par in R0 br 2$ ; branch back to test user par's 7$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 20 - test for dual byte addressing of kernel & user pdr's ; ; The following test writes to both bytes of the kernel & user ; pdr's separately to see that writing to one does not effect ; the other. This further verifies the operation of the par/pdr ; addr. mux and the addr. detection logic. ; tst20: scope ; 1$: mov #kipdr0, R0 ; load address of first pdr into R0 2$: mov #3$, $lperr ; set loop on error pointer to 3$ mov #10, R3 ; load loop counter to do 8 pdr's 3$: mov #-1, R1 ; load test pattern into R1 clr (R0) ; clear the pdr movb R1, (R0) ; write 1's to the low byte of the pdr mov (R0), R2 ; read the entire pdr into R2 bic #177761, R1 ; mask high byte & unused bits out of data cmp R1, R2 ; was only the low byte written to? beq 4$ ; branch if yes error 15 ; high byte effected by writing low byte in pdr ; 4$: mov #5$, $lperr ; set loop on error pointer to 5$ 5$: clr (R0) ; clear the pdr mov #-1, R1 ; load test pattern into R1 movb R1, 1(R0) ; write 1's to the high byte of the pdr mov (R0), R2 ; read the entire pdr into R2 bic #100377, R1 ; mask low byte & unused bits out of data cmp R1, R2 ; was only the high byte written to? beq 6$ ; branch if yes error 15 ; low byte effected by writing high byte in pdr ; 6$: add #2, R0 ; put address of next pdr in R0 sob R3, 3$ ; branch back until 8 pdr's tested cmp #uipdr7+2, R0 ; have user pdr's been tested? bhis 7$ ; branch if yes mov #uipdr0, R0 ; load address of first user pdr in R0 br 2$ ; branch back to test user pdr's 7$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 21 - par-pdr dual addressing test ; ; The following test sets all of the writeable bits to 1 ; in the sixteen (16) par's and pdr's using the "setreg" ; subroutine and then clears just, one of them. The "cmpreg" ; subroutine is used to read all of the par's and pdr's to see ; that only one register was cleared in response to that one ; par or pdr address. The "cmpreg" subroutine reports the ; address of any register whose bits did not remain set when ; another register was cleared. ; The par and pdr chips, par/pdr addr. mux, and addr. detection ; logic are checked. ; tst21: scope ; 1$: mov #2$, $lperr ; set loop on error pointer 2$ mov #10, R3 ; load loop counter with an 8 mov #kipdr0, R0 ; load address of first kernel pdr and R0 2$: mov #kerstk, KSP ; setup stack pointer jsr PC, setreg ; set all bits in all par's in pdr's clr (R0) ; clear one of the kernel pdr's jsr PC, cmpreg ; see if other par/pdr's were effected add #2, R0 ; form address of next kernel pdr to clear sob R3, 2$ ; loop to 2$ until all kernel pdr's checked mov #3$, $lperr ; set loop on error pointer to 3$ mov #10, R3 ; load loop counter with an 8 mov #kipar0, R0 ; load address of first kernel par in R0 3$: mov #kerstk, KSP ; setup stack pointer jsr PC, setreg ; set all bits in all par's and pdr's clr (R0) ; clear one of the kernel par's jsr PC, cmpreg ; see if other par/pdr's were effected add #2, R0 ; form address of next kernel par to clear sob R3, 3$ ; loop to 3$ until all kernel par's checked mov #4$, $lperr ; set loop on error pointer to 4$ mov #10, R3 ; load loop counter with an 8 mov #uipdr0, R0 ; load address of first user pdr in R0 4$: mov #kerstk, KSP ; setup stack pointer jsr PC, setreg ; set all bits in all par's and pdr's clr (R0) ; clear one of the user pdr's jsr PC, cmpreg ; see if other par/pdr's were effected add #2, R0 ; form address of next user pdr to clear sob R3, 4$ ; loop to 4$ until all user pdr's checked mov #5$, $lperr ; set loop on error pointer to 5$ mov #10, R3 ; load loop counter with an b mov #uipar0, R0 ; load address of first user par in R0 5$: mov #kerstk, KSP ; setup stack pointer jsr PC, setreg ; set all bits in all par's and pdr's clr (R0) ; clear one of the user par's jsr PC, cmpreg ; see if other par/pdr's were effected add #2, R0 ; form address of next user par to clear sob R3, 5$ ; loop to 5$ until all user par's checked mov #1$, $lperr ; set loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 22 - test that par-pdr's not affected by reset ; ; This test checks to see that the kernel or user par/pdr's are ; not affected by the execution of a "reset" instruction. The ; "setreg" subroutine is used to set all writeable bits to a "1" in ; the par/pdr's. Then they are read to see that they remained ; unchanged ; tst22: scope ; 1$: jsr PC, setreg ; set all bits in all par's and pdr's reset ; issue an "init" by executing a reset mov #kipdr0, R0 ; load address of first kernel pdr in R0 mov #10, R4 ; load loop counter with an 8 2$: mov (R0), R1 ; read a kernel pdr into R1 cmp #77416, R1 ; are all the bits still set? beq 3$ ; branch if yes error 55 ; kernel pdr affected by a reset ; 3$: add #2, R0 ; form address of next kernel pdr sob R4, 2$ ; loop to 2$ until all kernel pdr's checked mov #kipar0, R0 ; load address of first kernel par in R0 mov #10, R4 ; load loop counter with an b 4$: mov (R0), R1 ; read a kernel par into R1 cmp #7777, R1 ; are all the bits still set? beq 5$ ; branch if yes error 55 ; kernel par affected by a reset ; 5$: add #2, R0 ; form address of next kernel par sob R4, 4$ ; loop to 4$ until all kernel par's checked mov #uipdr0, R0 ; load address of first user pdr in R0 mov #10, R4 ; load loop counter with an 8 6$: mov (R0), R1 ; read a user pdr into R1 cmp #77416, R1 ; are all the bits still set? beq 7$ ; branch f yes error 55 ; user pdr affected by a reset ; 7$: add #2, R0 ; form address of next user pdr sob R4, 6$ ; loop to 6$ until all user pdr's checked mov #uipar0, R0 ; load address of first user par in R0 mov #10, R4 ; load loop counter with an 8 8$: mov (R0), R1 ; read a user par into R1 cmp #7777, R1 ; are all the bits still set? beq 9$ ; branch if yes error 55 ; user par affected by a reset ; 9$: add #2, R0 ; form address of next user par sob R4, 8$ ; loop to 8$ until all user par's checked ;_____________________________________________________________________________ ; ; Test 23 - instruction fetch not relocated in maint. mode ; ; This test checks to see that when memory management is in ; maintenance mode (destination-only-relocation), an instruction ; fetch is not relocated and a reset clears the maintenance bit ; (bit 08) in sr0. If the "fetch" is relocated, a pg. length abort ; should occur, causing a halt since trap catcher is placed in vector 250 ; Note: a halt may occur if maint. mode not disabled by reset ; tst23: scope ; 1$: jsr PC, toff ; turn T-bit trapping off for this test mov #kipdr0, R0 ; load address of first kernel pdr into R0 mov #10, R4 ; load loop counter with an 8 2$: clr (R0)+ ; clear pdr - mapping page non-res, 0 blks. sob R4, 2$ ; loop to 2$ until all kernel pdr's cleared mov #mmvec+2, mmvec ; load trap catcher into mem mgm. vector clr mmvec+2 ; ; a halt will occur if reset fails ; to disable dest.-only relocation mov #1006, kipdr0 ; map kernel pg 0 r/w, 3 blocks long. mov #3$, $lperr ; set loop on error pointer to 3$ 3$: mov #bit8, sr0 ; turn on dest-only-relocation reset ; should clear maint. bit - will abort if relocated bit #bit8, sr0 ; was maint. bit (bit 8) of sr0 cleared? beq 4$ ; branch if yes clr sr0 ; clear sr0 so error can be reported error 61 ; maint. mode not disabled by a reset ; 4$: mov #kerstk, KSP ; restore stack pointer clr sr0 ; be sure sr0 is clear mov #mgmerr, mmvec ; restore mem. mgmt. trap vector mov #340, mmvec+2 ; restore mem. mgmt vector+2 mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit trapping back on ;_____________________________________________________________________________ ; ; Test 24 - test that source not relocated in maintenance mode ; ; This test checks to see that when memory management is in ; maintenance mode, the source is not relocated. Only the ; destination is relocated. Kernel par's 3 & 4 are mapped to ; physical address 60000-77776. pdr4 is set to allow full read/write ; but pdr3 is clear allowing to access. Virtual addresses referencing ; par/pdr's 4 & 3 are used in as destination and source respectively. ; If the source is relocated in maintenance a mem. mgmt. trap will ; occur and the error will be reported. Kernel pg. 7 is mapped r/w. ; tst24: scope ; 1$: jsr PC, toff ; turn off T-bit trapping for this test mov #2$, $lperr ; set loop on error pointer to 2$ mov #600, kipar3 ; map kernel page 3 to 12-16k mov #600, kipar4 ; map kernel page 4 to 12-16k mov #7600, kipar7 ; map kernel page 7 to the i/o page clr kipdr3 ; map kernel page 3 "no access" mov #77406, kipdr4 ; map kernel page 4 r/w, 128 blks mov #77406, kipdr7 ; map kernel page 7 r/w, 128 blks mov #4$, mmvec ; set m.m. vector to 4$ in case of abort mov #377, @#60000 ; load all 1's in low byte of test loc. mov #-1, R0 ; load expected contents of test loc. in R0 2$: bis #bit8, sr0 ; turn on dest.-only-relocation movb @#60000, @#100001 ; load hi byte of test loc.-abort if source relocated reset ; turn off dest.-only-relocation mov @#60000, R1 ; read contents of test loc. cmp R0, R1 ; was test location loaded properly? beq 3$ ; branch if yes error 62 ; test loc. not loaded - inst. was aborted ; 3$: mov #mgmerr, mmvec ; restore mem. mgmt. vector mov #77406, kipdr3 ; map kernel page 3 r/w, 128 blks mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit trapping back on br tst25 ; skip to next test ; if the program tries to relocate the source, it should trap to 4$ 4$: bic #bit8, sr0 ; turn off dest.-only-relocation thru par/pdr 7 mov sr0, wassr0 ; save rest of sr0 contents mov sr2, wassr2 ; save contents of sr2 mov SP, wasSP ; save value of the stack pointer mov (SP)+, trappc ; save PC of trap mov (SP)+, trapps ; save PSW of trap bic #160000, sr0 ; clear error bits in sr1 error 63 ; source apparently relocated in maint. mode ; mov trapps, -(SP) ; put PSW of trap back on the stack mov trappc, -(SP) ; put PC of trap back on the stack rti ; return to test ;_____________________________________________________________________________ ; ; Test 25 - relocation & adder test (no carries) ; ; The following test sets up the kernel par's and pdr's ; for the rest of the program. It then uses different ; virtual addresses and different values for kernel par 4 ; to put different patterns at the inputs of the three ; memory management adder chips. The values are such ; that no carries are generated out of any of the adder chips. ; The method used to see that the right physical bus address ; is formed by the adders is to write a pattern to virtual ; location with memory mgmt. In the maintenance mode, and ; then read that location using the physical address that should ; have been formed to see if the test pattern got their. ; tst25: scope ; 1$: mov #kipar0, R0 ; load address of first kernel par in R0 clr R1 ; clear R1 mov #7, R2 ; load loop counter with a 7 2$: mov R1, (R0)+ ; map kernel par's to pages 0-6 (4k each) add #200, R1 ; sob R2, 2$ ; loop until kipar0 - kipaSP are loaded mov #7600, (R0) ; map kipar7 to the i/o page mov #kipdr0, R0 ; load address of first kernel pdr in R0 mov #77406, R1 ; load pdr data into R1 mov #10, R2 ; load loop counter with an b 3$: mov R1, (R0)+ ; map all b pages 12b blocks, upward sob R2, 3$ ; expandable, read/write 4$: mov #4$, $lperr ; set loop on error pointer to 4$ mov #67776, R0 ; load physical addr. pba into R0 mov #107776, R1 ; load virtual addr. vba into R1 mov #125250, R2 ; load test pattern into R2 mov #600, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125250 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125250 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 5$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 5$: ; 6$: mov #6$, $lperr ; set loop on error pointer to 6$ mov #67776, R0 ; load physical addr. pba into R0 mov #102576, R1 ; load virtual addr. vba into R1 mov #125251, R2 ; load test pattern into R2 mov #652, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125251 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125251 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 7$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 7$: ; 8$: mov #8$, $lperr ; set loop on error pointer to 8$ mov #67776, R0 ; load physical addr. pba into R0 mov #105276, R1 ; load virtual addr. vba into R1 mov #125252, R2 ; load test pattern into R2 mov #625, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125252 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125252 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 9$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 9$: ; 10$: mov #10$, $lperr ; set loop on error pointer to 10$ mov #psw, R0 ; load phys. addr. of PSW into R0 mov #100076, R1 ; load virtual addr. for PSW into R1 mov #030340, R2 ; load data for PSW in R2 mov #7777, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> clr (R0) ; clear the PSW bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load PSW using adder chips (par4 + virt addr.) mov (R0), R3 ; read PSW back without using mem. mgmt. reset ; turn off mem. mgmt maint. mode clr (R0) ; clear the PSW bic #37, R3 ; mask T-bit & cc bits out of data read cmp R2, R3 ; was PSW written while in maint. mode? beq 11$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical addr. for typing error 17 ; PSW did not have data that it should have, ; apparently phys. addr. of PSW was ; not formed by adders using the ; virtual addr. and kipar4 11$: mov #11$, $lperr ; set loop on error pointer to 11$ mov #psw, R0 ; load phys. addr. of PSW into R0 mov #117776, R1 ; load virtual addr. for PSW into R1 mov #030240, R2 ; load data for PSW in R2 mov #7600, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load PSW using adder chips (par4 + virt. addr.) mov (R0), R3 ; read PSW back without using mem. mgmt. reset ; turn off mem. mgmt. maint. mode clr (R0) ; clear the PSW bic #37, R3 ; mask T-bit & cc bits out of data read cmp R2, R3 ; was PSW written while in maint. mode? beq 12$ ; branch if yes mov R1, virt1 ; save virtual addr. to form physical addr. jsr PC, formpa ; go form physical addr. for typing error 17 ; PSW did not have data that it should ; have, apparently phys. addr. of PSW was ; not formed by adders using the ; virtual addr. and kipar4 ; for tighter scope loop ; replace error call with ; "br 11$" = 000743 12$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 26 - relocation & adder test (with carries) ; ; The following test uses the same method as the previous ; test to verify memory managements ability to construct ; physical bus addresses using a virtual bus address and the ; contents of a page address register. However, the values ; and patterns used in this test will generate carries from ; chip to chip and check "wraparound" to address 000000 by ; using virtual addr. 100100 and kipar4 = 7777. ; tst26: scope ; 1$: ; kernel par's and pdr's have been ; setup by the previous test 2$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #64276, R0 ; load physical addr. pba into R0 mov #102176, R1 ; load virtual addr. vba into R1 mov #125253, R2 ; load test pattern into R2 mov #621, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125253 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125253 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 3$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 3$: ; 4$: mov #4$, $lperr ; set loop on error pointer to 4$ mov #64476, R0 ; load physical addr. pba into R0 mov #112376, R1 ; load virtual addr. vba into R1 mov #125254, R2 ; load test pattern into R2 mov #521, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125254 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125254 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 5$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 5$: ; 6$: mov #6$, $lperr ; set loop on error pointer to 6$ mov #61076, R0 ; load physical addr. pba into R0 mov #106776, R1 ; load virtual addr. vba into R1 mov #125255, R2 ; load test pattern into R2 mov #521, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125255 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125255 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 7$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 7$: ; 8$: mov #8$, $lperr ; set loop on error pointer to 8$ mov #60076, R0 ; load physical addr. pba into R0 mov #107776, R1 ; load virtual addr. vba into R1 mov #125256, R2 ; load test pattern into R2 mov #501, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125256 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125256 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 9$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 9$: ; 10$: mov #10$, $lperr ; set loop on error pointer to 10$ mov #000000, R0 ; load physical addr. pba into R0 mov #100100, R1 ; load virtual addr. vba into R1 mov #125257, R2 ; load test pattern into R2 mov #7777, R4 ; load R4 with par value mov R4, kipar4 ; load kernel par 4 bits <11:00> mov (R0), $tmp0 ; save contents at test location bis #bit8, sr0 ; turn on "destination-only-relocation" mov R2, (R1) ; load 125257 using adder chips (par4 + virt addr.) mov (R0), R3 ; read 125257 back without using mem. mgmt. reset ; turn off memory mgmt. maint. mode mov $tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using "dest-only-reloc."? beq 11$ ; branch if yes mov R1, virt1 ; save virtual addr. to form phys. addr jsr PC, formpa ; go form physical address for typing error 17 ; test location did not have pattern ; that should have been written to it. ; apparently physical addr. was ; formed wrong by adders using ; the virtual addr. and kipar4 11$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 27 - read and write while in relocate mode ; ; The following test turns on memory management and then ; reads and writes locations between physical addresses ; 060000-067600. One location in every block (32. words) ; is written using par4 and read using par5. This is ; done in both user and kernel modes. The user par/pdr's ; are setup at the beginning of the test and once memory ; management is turned on it is left on for the rest of the ; of the program. The "mode" input to the par/pdr address mux ; is checked by reading and writing in user mode. Remember ; also, that since memory management is on (in relocate ; mode) the program itself is using its virtual addresses and ; the par/pdr's to execute. ; ; While testing in kernel mode, user pages 4 & 5 are mapped ; non-resident with different par values than the kernel ; par's to be sure that the kernel par's and pdr's are being ; used when in kernel mode (and vice versa while testing in ; user mode). If a mem. mgmt. trap occurs, the program goes ; to 8$ where the trap is reported. ; tst27: scope ; 1$: clr PSW ; start in kernel mode mov #577, R4 ; load R4 with value for par4 mov #600, R5 ; load R5 with value for par5 mov R4, kipar4 ; load kernel par4 mov R5, kipar5 ; load kernel par5 mov #uipar0, R0 ; load address of first user par in R0 clr R1 ; clear R1 mov #7, R2 ; load loop counter with a 7 2$: mov R1, (R0)+ ; map user par's to pages 0-6 (4k each) add #200, R1 ; sob R2, 2$ ; loop until uipar0-uipaSP are loaded mov #7600, (R0) ; map uslr par7 to the i/o page mov #uipdr0, R0 ; load address of first user pdr in R0 mov #77406, R1 ; load pdr data into R1 mov #10, R2 ; load loop counter with an 8 3$: mov R1, (R0)+ ; map all 8 pages 128 blocks, upward sob R2, 3$ ; expandable, read/write clrb uipdr4 ; map user space non-resident while clrb uipdr5 ; testing kernel space mov R5, uipar4 ; map user par's opposite of kipar's mov R4, uipar5 ; mov #1, sr0 ; turn on memory management (relocate mode) mov #5$, $lperr ; set loop on error pointer to 5$ mov #8$, mmvec ; set m. m. trap vector to 8$ 4$: mov PSW, $tmp0 ; save PSW in case of error mov #100100, R0 ; put virtual addr. that user par4 in R0 mov #120000, R1 ; put virtual addr. that uses par5 in R1 5$: mov R0, (R0) ; write to test loc. using par4 mov (R1), R2 ; read the same loc., but using par5 cmp R0, R2 ; did we read what we wrote? beq 6$ ; branch if yes mov R1, virt2 ; save virtual addr. that selected par5 mov R0, virt1 ; save virtual addr. that selected par4 jsr PC, formpa ; go form physical address being used error 20 ; reading loc. using par5 and a virt. ; addr. did not find data written when using ; par4 and virt. address. mov virt1, R0 ; restore vba in R0 6$: add #100, R0 ; change virtual addrs. to point to next block add #100, R1 ; cmp R1, #127700 ; were blocks from 60000-676000 all tried? bne 5$ ; branch if no bit #140000, PSW ; have we done test in user mode yet? bne 7$ ; branch if yes mov R4, uipar4 ; load user par4 mov R5, uipar5 ; load user par5 movb #6, uipdr4 ; map user space r/w to test it movb #6, uipdr5 ; clrb kipdr4 ; map kernel space non-resident while clrb kipdr5 ; testing user space mov R5, kipar4 ; map kernel par's opposite uipar's mov R4, kipar5 ; mov #140000, PSW ; go to user mode br 4$ ; go back and read/write in user mode 7$: clr PSW ; go back to kernel mode before leaving mov #77406, kipdr4 ; remap kernel pages read/write mov #77406, kipdr5 ; mov R5, kipar4 ; map kernel and user par's 4 & 5 mov R5, kipar5 ; back to 12-16k mov R5, uipar4 ; mov R5, uipar5 ; mov #mgmerr, mmvec ; restore addr. of normal m.m. trap routine mov #1$, $lperr ; reset loop on error pointer to 1$ br tst30 ; go to next test 8$: mov (KSP)+, trappc ; save PC a ps of trap mov (KSP)+, trapps ; ; program will trap to here if try ; to use user pdr's when in kernel mode ; or kernel pdr's when in user mode mov R0, virt1 ; save virtual address for error report jsr PC, formpa ; go form the physical address being used mov sr0, wassr0 ; save sr0 & sr2 for error report mov sr2, wassr2 ; bic #160000, sr0 ; clear error bits in sr0 error 52 ; m.m. trap while in relocate mode - ; referenced wrong set of pdr's mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rti ; return to test ;_____________________________________________________________________________ ; ; Test 30 - W-bit logic test, kernel pdr's ; ; This test writes to eight (8) different virtual addresses ; (vba's = 17776, 37776, 57776, 77776, 117776, 137776, 157776, & 177776 ; & pba's constructed = 17776, 37776, 57776, 77776, 77776, ; 77776, 77776, & 777776 respectively). ; ; Which should cause the "W-bit" to set in each of the ; eight (8) kernel page descriptor registers. The pdr's ; are checked to see that it's W-bit does set when the ; page it is mapped to is written to and that the W-bit ; does not set in any of the other pdr's. Kernel pdr's 3, 4, 5, 6 ; are mapped to 12-16k for this test. Also the W-bit ; should be cleared when the pdr is written to. The ; W-bit portion of the pdr's and the par/pdr adrs mux ; are being checked. ; tst30: scope ; 1$: jsr PC, toff ; turn T-bit trapping off for this test mov #4, R2 ; set loop counter to 4 mov #kipar3, R0 ; load address of par3 into R0 mov #600, R1 ; load "12-16k" par value into R1 2$: mov R1, (R0)+ ; map pars 3-6 to 12-16k sob R2, 2$ ; loop til all 4 of them loaded mov #kipdr0, R5 ; load address of first pdr to be tested in R5 mov #10, R4 ; set loop counter to 8 mov #17776, R3 ; initialize virtual address to be in R3 mov #3$, $lperr ; set loop on error pointer to 3$ 3$: mov #kipdr0, R0 ; load addr. of first pdr to be setup in R0 mov #10, R2 ; set loop counter to 8 mov #77406, R1 ; put "W-bit off data" into R1 4$: mov R1, (R0)+ ; clear all W-bits by writing to all pdrs sob R2, 4$ ; loop until all of them setup mov (R3), (R3) ; do "dato" to virtual addr.-setting a W-bit bit (R5), #wbit ; did that cause W-bit to be set? bne 5$ ; branch if yes error 21 ; W-bit did not get set in pdr ; br 8$ ; skip checking other pdr's-error will set W-bits 5$: mov #10, R2 ; set loop counter to 8 mov #kipdr0, R0 ; load addr. of first pdr to be checked in R0 6$: bit (R0), #wbit ; did W-bit in other pdrs remain clear? beq 7$ ; branch if yes cmp R5, R0 ; if W-bit set, then was it pdr under test? beq 7$ ; branch if yes error 22 ; W-bit got set in more than one pdr ; 7$: add #2, R0 ; point R0 to next pdr to be checked sob R2, 6$ ; loop until all 8 checked for clear W-bit mov R1, (R5) ; write to the pdr tested to clear W-bit bit (R5), #wbit ; did writing pdr clear the W-bit? beq 8$ ; branch if yes error 23 ; W-bit did not clear by writing the pdr ; 8$: add #2, R5 ; point R5 to the next pdr to be tested add #20000, R3 ; change virt. addr to ref. next pdr sob R4, 3$ ; loop back to 3$ until all 8 pdr's tested mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit back on for next test ;_____________________________________________________________________________ ; ; Test 31 - W-bit logic test, user pdr's ; ; This test writes to eight (8) different virtual addresses ; (vba's = 17776, 37776, 57776, 77776, 117776, 137776, 157776, & 177776 ; & pba's constructed = 17776, 37776, 57776, 77776, 77776, ; 77776, 77776, & 777776 respectively). ; ; Which should cause the "W-bit" to set in each of the ; eight (8) user page descriptor registers. The pdr's ; are checked to see that it's W-bit does set when the ; page it is mapped to is written to and that the W-bit ; does not set in any of the other pdr's. User pdr's 3, 4, 5, 6 ; are mapped to 12-16k for this test. Also the W-bit ; should be cleared when the pdr is written to. The ; W-bit portion of the pdr's and the par/pdr adrs mux ; are being checked. ; tst31: scope ; 1$: mov #140000, PSW ; go to user mode for this test jsr PC, toff ; turn T-bit trapping off for this test mov #4, R2 ; set loop counter to 4 mov #uipar3, R0 ; load address of par3 into R0 mov #600, R1 ; load "12-16k" par value into R1 2$: mov R1, (R0)+ ; map pars 3-6 to 12-16k sob R2, 2$ ; loop til all 4 of them loaded mov #uipdr0, R5 ; load address of first pdr to be tested in R5 mov #10, R4 ; set loop counter to 8 mov #17776, R3 ; initialize virtual address to be in R3 mov #3$, $lperr ; set loop on error pointer to 3$ 3$: mov #uipdr0, R0 ; load addr. of first pdr to be setup in R0 mov #10, R2 ; set loop counter to 8 mov #77406, R1 ; put "W-bit off data" into R1 4$: mov R1, (R0)+ ; clear all W-bits by writing to all pdrs sob R2, 4$ ; loop until all of them setup mov (R3), (R3) ; do "dato" to virtual addr.-setting a W-bit bit (R5), #wbit ; did that cause W-bit to be set? bne 5$ ; branch if yes error 21 ; W-bit did not get set in pdr ; for tighter scope loop ; replace error call with ; "br 3$" = 000763 br 8$ ; skip checking other pdr's-error will set W-bits 5$: mov #10, R2 ; set loop counter to 8 mov #uipdr0, R0 ; load addr. of first pdr to be checked in R0 6$: bit (R0), #wbit ; did W-bit in other pdrs remain clear? beq 7$ ; branch if yes cmp R5, R0 ; if W-bit set, then was it pdr under test? beq 7$ ; branch if yes error 22 ; W-bit got set in more than one pdr ; for tighter scope loop ; replace error call with ; "br 3$" = 000750 7$: add #2, R0 ; point R0 to next pdr to be checked sob R2, 6$ ; loop until all 8 checked for clear W-bit mov R1, (R5) ; write to the pdr tested to clear W-bit bit (R5), #wbit ; did writing pdr clear the W-bit? beq 8$ ; branch 1f yes error 23 ; W-bit did not clear by writing the pdr ; for tighter scope loop ; replace error call with ; "br 3$" = 000740 8$: add #2, R5 ; point R5 to the next pdr to be tested add #20000, R3 ; change virt. addr to ref. next pdr sob R4, 3$ ; loop back to 3$ until all 8 pdr's tested mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit back on for next test clr PSW ; back to kernel mode before leaving ;_____________________________________________________________________________ ; ; Test 32 - test "W-bit not set" cases ; ; This test checks two special cases where the W-bit does ; not get set on a write. First case is that the W-bit ; should not set in page descriptor reg. 7 when writing to ; status reg sr0 (kernel pdr 7 is used). Second case is that ; the W-bit is not set if the "dato" is aborted due to an ; odd address error (kernel pdr3 & virtual addr 60001 are used). ; tst32: scope ; 1$: jsr PC, toff ; turn off T-bit trapping for this test mov #77406, R1 ; put "W-bit off" value for pdr in R1 mov #2$, $lperr ; set loop on error pointer to 2$ 2$: mov R1, kipdr7 ; load kernel pdr 7 to clear W-bit mov sr0, R0 ; read present contents of status reg. 0 mov R0, sr0 ; write present contents of sr0 back to itself mov kipdr7, R2 ; read contents of kipdr7 into R2 cmp R1, R2 ; was W-bit left cleared? beq 3$ ; branch if yes error 24 ; W-bit in kipdr7 set when sr0 was written to ; for tighter scope loop ; replace error call with ; "br 2$" = 000765 3$: mov #3$, $lperr ; set loop on error pointer to 3$ mov R1, kipdr3 ; load kernel pdr3 with 77406 to clear W-bit mov #4$, errvec ; set up loc. 4 to 4$ for odd addr. abort inc 60001 ; cause odd address abort thru loc. 4 4$: mov #kerstk, KSP ; restore the stack pointer mov kipdr3, R2 ; read kipdr3 into R2 cmp R1, R2 ; was W-bit left cleared? beq 5$ ; branch if yes error 25 ; W-bit got set during an odd addr. abort ; for tighter scope loop ; replace error call with ; "br 3$" = 000757 5$: mov #timerr, errvec ; restore normal cpu trap routine to loc. 4 mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit trapping back on ;_____________________________________________________________________________ ; ; The next three (3) tests cause memory management errors ; to check the ability of status register 0 to record kt ; errors and the ability of status register 2 to lock up the ; virtual addr. of the instruction that caused the error. ; The bits of sr2 are checked and bits <15:13>, <6=5>, and <3:0> ; are checked in sr0. So the sr0 and sr2 logic and the ; kt error logic are checked. ;_____________________________________________________________________________ ; ; Test 33 - non-resident abort test (acf=0&4) ; ; This test checks the access control field (acf) comparator ; logic by causing non-resident aborts in both kernel and ; user modes. pdr 4 is loaded with acf's = 0&4 and ; then physical addr. 60000 is accessed to cause the abort. ; tst33: scope ; 1$: mov #600, R0 ; load data for par's into R0 mov R0, kipar3 ; map kernel par's 3&4 to 12-16k mov R0, kipar4 ; mov R0, uipar3 ; map user par's 3&4 to 12-16k mov R0, uipar4 ; mov #77406, kipdr3 ; map kernel pdr 3 128 blks, read-write mov #77406, uipdr3 ; map user pdr 3 128 blks, read-write mov #60000, R0 ; load virtual addr. to reference pdr3 into R0 mov #100000, R1 ; load virtual addr. to reference pdr4 into R1 mov #100011, R3 ; load R3 with what sr0 should read - n.r., kernel, pg.4 mov #77400, R2 ; load acf=0 (non-resident) pdr value in R2 2$: mov #5$, mmvec ; point mem. mgmt. trap vector to 5$ below mov R2, kipdr4 ; load acf test value into kipdr4 mov R2, uipdr4 ; load acf test value into uipdr4 mov #3$, $lperr ; set loop on error pointer to 3$ 3$: clr (R0) ; clear phys. loc. 60000 using pdr3 mov PSW, $tmp0 ; save PSW in case of error 4$: inc (R1) ; try to ref. it using pdr4 - should trap to 5$ error 26 ; mem. mgmt. abort did not occur ; for tighter scope loop ; replace error call with ; "br 3$" = 000772 br 8$ ; branch around status reg. checks if no abort 5$: add #4, SP ; restore stack pointer tst (R0) ; did instruction get aborted & not execute beq 6$ ; branch if yes error 27 ; instruction was not aborted, loc. got changed ; for tighter scope loop ; replace error call with ; "br 3$" = 000764 6$: mov sr0, wassr0 ; read status register 0 mov sr2, wassr2 ; read status register 2 cmp R3, wassr0 ; did sr0 report non-resident error correctly? beq 7$ ; branch if yes error 30 ; sr0 did not report non-res. error correctly ; for tighter scope loop ; replace error call with ; "br 3$" = 000752 7$: mov #4$, R4 ; load p4 with what sr2 should read cmp R4, wassr2 ; did sr2 lockup right virtual addr. (=4$)? beq 8$ ; branch if yes error 31 ; sr2 did not lock virtual addr. of non-res. error ; for tighter scope loop ; replace error call with ; "br 3$" = 000744 8$: bic #160000, sr0 ; clear the error bits in sr0 bit #140000, $tmp0 ; has acf=0&4 been tested in user yet bne 9$ ; branch if yes mov #100151, R3 ; load R3 with what sr0 should read - n.r., user, pg.4 mov #140000, PSW ; go to user mode br 2$ ; repeat test in user mode 9$: cmp #77404, R2 ; has acf=4 been tested yet? beq 10$ ; branch if yes mov #77404, R2 ; then load acf=4 (non-res) pdr value in R2 mov #100011, R3 ; load R3 with what sr0 should read-n.r., kernel, pg. 4 clr PSW ; go back to kernel mode br 2$ ; go back & test acf=4 in same mode 10$: clr PSW ; go back to kernel mode before leaving mov #1$, $lperr ; reset loop on error pointer to 1$ mov #mgmerr, mmvec ; restore address of normal memory ; management error routine to mmvec ;_____________________________________________________________________________ ; ; Test 34 - read-only abort test (acf=2) ; ; This test checks the access control field (acf) comparator ; logic by causing read-only aborts in both kernel and ; user modes. pdr 4 is load with acf=2 and then ; physical addr. 60000 is written to cause the abort. ; tst34: scope ; 1$: ; kernel & user par's 3 & 4 and pdr 3 ; are setup from last test mov #60000, R0 ; load virtual addr. to reference pdr3 into R0 mov #100000, R1 ; load virtual addr. to reference pdr4 into R1 mov #20011, R3 ; load R3 with what sr0 should read - r/o, kernel, pg.4 mov #77402, R2 ; load acf=2 (read-only) pdr value in R2 2$: mov #5$, mmvec ; point mem. mgmt. trap vector to 5$ below mov R2, kipdr4 ; load acf=2 into kipdr4 mov R2, uipdr4 ; load acf=2 into uipdr4 mov #3$, $lperr ; set loop on error pointer to 3$ 3$: clr (R0) ; clear phys. loc. 60000 using pdr3 mov PSW, $tmp0 ; save PSW in case of error 4$: inc (R1) ; try to write using pdr4 - should trap to 5$ error 26 ; mem. mgmt. abort did not occur ; for tighter scope loop ; replace error call with ; "br 3$" = 000772 br 8$ ; branch around status reg. checks if no abort 5$: add #4, SP ; restore stack pointer tst (R0) ; did instruction get aborted & not execute beq 6$ ; branch if yes error 27 ; instruction was not aborted, loc. got changed ; for tighter scope loop ; replace error call with ; "br 3$" = 000764 6$: mov sr0, wassr0 ; read status reg. 0 mov sr2, wassr2 ; read status reg. 2 cmp R3, wassr0 ; did sr0 report read-only error correctly? beq 7$ ; branch if yes error 30 ; sr0 did not report r/o error correctly ; for tighter scope loop ; replace error call with ; "br 3$" = 000752 7$: mov #4$, R4 ; load R4 with what sr2 should read cmp R4, wassr2 ; did sr2 lockup right virtual addr. (=4$)? beq 8$ ; branch if yes error 31 ; sr2 did not lockup virtual addr. of r/o error ; for tighter scope loop ; replace error call with ; "br 3$" = 000744 8$: bic #160000, sr0 ; clear the error bits in sr0 bit #140000, $tmp0 ; has acf=2 been tested in user mode? bne 9$ ; branch if yes mov #20151, R3 ; load R3 with what sr0 should read-r/o, user, pg.4 mov #140000, PSW ; go to user mode br 2$ ; repeat test in user mode 9$: clr PSW ; go back to kernel mode before leaving mov #1$, $lperr ; reset loop on error pointer to 1$ mov #mgmerr, mmvec ; restore address of normal memory ; management error routine to mmvec. ;_____________________________________________________________________________ ; ; Test 35 - test illegal mode "01" ; ; This test checks to see that a 01 in the current mode bits of the ; PSW while memory management is on is illegal. A ; memory management abort should occur and status register 0 ; should report non-resident abort, mode = 01, page = 1 (100043). Status ; register 2 should lockup the address of the instruction ; that loaded the PSW. ; tst35: scope ; 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #3$, mmvec ; load mem. mgmt. trap vector with 3$ 2$: mov #40000, PSW ; set 01 in PSW current mode bits nop ; fetch of this instruction should cause abort error 56 ; illegal mode 01 not aborted ; br 5$ ; branch around sr0 & sr2 checks 3$: mov #kerstk, SP ; restore stack pointer mov #100043, R1 ; load expected contents or sr0 into R1 mov sr0, wassr0 ; read contents of sr0 cmp R1, wassr0 ; did sr0 report illegal mode correctly? beq 4$ ; branch if yes error 57 ; sr0 did not report nr abort, pg=1, mode=01 ; for tighter scope loop ; replace error call with ; "br 2$" = 000757 4$: mov #2$, R1 ; load expected contents of sr2 into R1 mov sr2, wassr2 ; read contents of sr2 cmp R1, wassr2 ; did sr2 lockup virt. addr of aborted inst. beq 5$ ; branch if yes error 36 ; sr2 did not lockup virt. addr. of ill. mode inst. ; for tighter scope loop ; replace error call with ; "br 2$" = 000746 5$: bic #160000, sr0 ; clear possible error bits in sr0 mov #mgmerr, mmvec ; restore mem. mgmt. abort vector mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; The next two (2) tests will be checking the page length ; comparators and some more of the kt error detection ; and status logic. The page length field (plf) in kernel ; pdr 4 is varied and for every plf, three (3) virtual ; addresses are read. While using both upward & downward page ; expansion, one of those three virtual addresses will cause a ; "page length abort" while the other two won't. ; Status register 0 & 2 are checked when the page length ; abort does occur to see that the abort is reported and that ; the virtual address of the instruction that caused the abort ; is locked up. ;_____________________________________________________________________________ ; ; Test 36 - page length faults-upward expansion ; ; This test varies the page length field (plf) in kernel pdr 4 ; from 1 to 177 and for each plf, three virtual addresses (vba's) ; are accessed. When vba <12:6> is less than or equal to pdr <14:8> ; no abort should occur. When vba <12:6> is greater than pdr <14:8>, ; a page length abort should occur and be reported by sr0 & sr2. ; The page expansion direction in this test is upward, (the ed bit ; (bit 3) of pdr 4 = 0). ; tst36: scope ; 1$: mov #77406, kipdr3 ; make sure pdr3 is described as r/w mov #77406, kipdr5 ; make sure pdr5 is described as r/w mov #100000, R0 ; load virtual addr. to select pdr4 into R0 mov #406, R4 ; load first pdr value in R4 (plf=1, acf=6) 2$: mov #9$, mmvec ; setup m.m. trap vector for unexpected aborts mov R4, kipdr4 ; load kipdr4 with page length value mov #3$, $lperr ; set loop on error pointer to 3$ 3$: mov #kerstk, KSP ; make sure stack pointer is all set up mov (R0), R1 ; access virtual addr. (vba < plf - no abort) add #100, R0 ; form next virtual address in R0 mov #4$, $lperr ; set loop on error pointer to 4$ 4$: mov #kerstk, KSP ; make sure stack pointer is all set up mov (R0), R1 ; access virtual addr. (vba = plf - mo abort) add #100, R0 ; form next virtual addr in R0 cmp R0, #117700 ; have all plf's been tested yet? beq 10$ ; branch if all vba's & plf's have been used mov #5$, $lperr ; set loop on error pointer to 5$ mov #6$, mmvec ; setup m.m. trap vector for expected abort 5$: mov (R0), R1 ; access virtual addr. (vba > plf - abort to 6$) error 33 ; expected page length abort did not occur ; for tighter scope loop ; replace error call with ; "br 5$" = 000776 br 8$ ; branch around abort checks 6$: mov #kerstk, KSP ; restore stack pointer following abort mov sr0, wassr0 ; read m.m. status reg. 0 mov sr2, wassr2 ; read m.m. status reg. 2 mov #40011, R2 ; put expected sr0 contents in R2 cmp R2, wassr0 ; did sr0 report pg. length abort, page 4, kernel? beq 7$ ; branch if yes error 34 ; sr0 did not report pg. length abort correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000757 7$: mov #5$, R3 ; put expected sr2 contents in R3 cmp R3, wassr2 ; did sr2 lockup virt. addr. of aborted instruction? beq 8$ ; branch if yes error 35 ; sr2 did not lockup virt. addr. of abort correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000751 8$: bic #160000, sr0 ; clear error bits in sr0 add #400, R4 ; form next plf value for kipdr4 sub #100, R0 ; form first virt. addr for that plf value br 2$ ; branch back and access 3 vba's for ; the plf value just formed 9$: mov (KSP)+, trappc ; save PC & ps of trap mov (KSP)+, trapps ; mov sr0, wassr0 ; save contents of sr0 for error mov sr2, wassr2 ; save contents of sr2 for error bic #160000, sr0 ; clear error bits in sr0 error 32 ; got pg. length abort before it was expected ; for tighter scope loop ; replace error call with ; a "nop" = 000240 mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rti ; return from unexpected abort 10$: mov #1$, $lperr ; reset loop on error pointer to 1$ mov #mgmerr, mmvec ; restore normal m.m. trap handler ; address to m.m. trap vector ;_____________________________________________________________________________ ; ; Test 37 - page length faults-downward expansion ; ; This test varies the page length field (plf) in kernel pdr4 ; from 176 to 0 and for each plf, three virtual addresses (vba's) ; are accessed. When vba <12:6> is greater than or equal to pdr <14:8> ; no page abort should occur. When vba <12:6> is less than pdr <14:8> ; a page length abort should occur and be reported by sr0 & sr2. ; The page expansion direction in this test is downward, (the ed bit ; (bit 3) of pdr4=1). ; tst37: scope ; 1$: mov #117700, R0 ; load virtual addr. to select pdr4 into R0 mov #77016, R4 ; load first pdr value in R4 (plf=176, acf=6) 2$: mov #9$, mmvec ; setup m.m. trap vector for unexpected aborts mov R4, kipdr4 ; load kipdr4 with page length value mov #3$, $lperr ; set loop on error pointer to 3$ 3$: mov #kerstk, KSP ; make sure stack pointer is all set up mov (R0), R1 ; access virtual addr. (vba > plf - no abort) sub #100, R0 ; form next virtual address in R0 mov #4$, $lperr ; set loop on error pointer to 4$ 4$: mov #kerstk, KSP ; make sure stack pointer is all set up mov (R0), R1 ; access virtual addr. (vba = plf - no abort) sub #100, R0 ; form next virtual addr. in R0 cmp R0, #100000 ; have all plf's been tested yet? beq 10$ ; branch if all vba's & plf's have been used mov #5$, $lperr ; set loop on error pointer to 5$ mov #6$, mmvec ; setup m.m. trap vector for expected abort 5$: mov (R0), R1 ; access virtual addr. (vba < plf - abort to 6$) error 33 ; expected page length abort did not occur ; for tighter scope loop ; replace error call with ; "br 5$" = 000776 br 8$ ; branch around abort checks 6$: mov #kerstk, KSP ; restore stack pointer following abort mov sr0, wassr0 ; read m.m. status reg. 0 mov sr2, wassr2 ; read m.m. status reg. 2 mov #40011, R2 ; put expected sr0 contents in R2 cmp R2, wassr0 ; did sr0 report pg. length abort, pg. 4. kernel? beq 7$ ; branch if yes error 34 ; sr0 did not report pg. length abort correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000757 7$: mov #5$, R3 ; put expected sr2 contents in R3 cmp R3, wassr2 ; did sr2 lockup virt. addr. of aborted instruction? beq 8$ ; branch if yes error 35 ; sr2 did not lockup virt. addr. of abort correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000751 8$: bic #160000, sr0 ; clear error bits in sr0 sub #400, R4 ; form next plf value for kipdr4 add #100, R0 ; form first virt. addr. for that plf value br 2$ ; branch back and access 3 vba's for ; the plf value just formed 9$: mov (KSP)+, trappc ; save PC & ps of trap mov (KSP)+, trapps mov sr0, wassr0 ; save contents of sr0 for error mov sr2, wassr2 ; save contents of sr2 for error bic #160000, sr0 ; clear error bits in sr0 error 32 ; got pg. length abort before it was expected ; for tighter scope loop ; replace error call with ; a "nop" = 000240 mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rti ; return from unexpected abort 10$: mov #1$, $lperr ; reset loop on error pointer to 1$ mov #mgmerr, mmvec ; restore normal m.m. trap handler ; address to m.m. trap vector ;_____________________________________________________________________________ ; ; Test 40 - sr2 bit test ; ; This test checks the bits in memory management register 2 by ; causing "read-only aborts" at virtual addresses between 100000 ; to 111000 (physical addresses 060000-071000). kipdr4 is used to execute ; the following four words of code which are moved thru memory: ; 010727 mov PC, (PC)+ ; this instruction should cause a r/o abort ; 000000 ; its virtual addr. should be locked up in sr2 ; 000137 jmp @#3$ ; this instruction is also moved thru memory ; (addr. of 3$) ; in case a r/o abort does not occur, ; ; in which case sr2 will not contain correct addr. tst40: scope ; 1$: mov #600, kipar3 ; be sure par3 is mapped to 12-16k mov #600, kipar4 ; be sure par4 is mapped to 12-16k mov #77406, kipdr3 ; map page 3 128 blocks, r/w mov #77402, kipdr4 ; map page 4 128 blocks, read-only mov #60000, R0 ; load R0 with virtual addr. which uses pdr3 mov #100000, R1 ; load R1 with virtual addr. which uses pdr4 mov #3$, mmvec ; set m.m. trap vector to 3$ mov #2$, $lperr ; set loop on error pointer to 2$ 2$: mov #010727, (R0)+ ; load "mov PC, (PC)+" instruction at addr. clr (R0)+ ; reached thru pdr/par 4. mov #000137, (R0)+ ; load "jmp @#3$" instruction at virt. addr. mov #3$, (R0) ; in case r/o viol. does not abort mov R1, PC ; transfer program execution to "page 4 instructions" 3$: mov #kerstk, KSP ; restore stack pointer mov sr2, wassr2 ; read contents of status reg 2 cmp R1, wassr2 ; was addr. of "relocated - r/o abort" locked up? beq 4$ ; branch if yes error 36 ; sr2 did not lock up virtual addr. of r/o viol. ; for tighter scope loop ; replace error call with ; "br 2$" = 000757 4$: bic #160000, sr0 ; clear the error bits in sr0 .if ne MSIM ; add #100-6, R0 ; add #100, R1 ; form virtual addr. that should be locked up next .iff ; sub #4, R0 ; reset R0 to point to next virt. addr. to load add #2, R1 ; form virtual addr. that should be locked up next .endc ; cmp R1, #111002 ; have all vba's 100000-111000 been tested? blo 2$ ; branch if no 5$: mov #1$, $lperr ; reset loop on error pointer to 1$ mov #77406, kipdr4 ; restore pdr4 to r/w access mov #mgmerr, mmvec ; restore address of normal m.m. ; trap handler to m.m. vector ;_____________________________________________________________________________ ; ; Test 41 - more checks of sr0 & sr2 ; ; This test performs some additional checks of the sr0 & sr2 logic. ; First it checks that sr2 "tracks" along acting as a virtual address ; program counter. Also sr0 & sr2 are locked up by a page length ; abort, then without clearing sr0's error bits, a r/o abort is caused. ; sr0 & sr2 should not be changed by the second abort and the ; information about the page length abort sould still be locked up. ; In addition a "reset" is executed to verify that sr0 is cleared ; and sr2 is unlocked by a reset. After memory management is turned back on, ; sr2 is checked to see that it is tracking again. ; tst41: scope ; 1$: mov #600, kipar5 ; map kernel page 5 to 12-16k mov #406, kipdr4 ; setup pdr4 for page length abort mov #77402, kipdr5 ; setup pdr5 for r/o abort mov #2$, $lperr ; set loop on error pointer to 2$ 2$: mov sr2, wassr2 ; read sr2 to see if its tracking mov #2$, R1 ; put expected virtual PC in R1 cmp R1, wassr2 ; did sr2 contain virtual PC at 2$? beq 3$ ; branch if yes error 41 ; sr2 not tracking correctly ; for tighter scope loop ; replace error call with ; "br 2$" = 000767 3$: mov #4$, $lperr ; set loop on error pointer to 4$ 4$: mov sr2, wassr2 ; read sr2 to see if its fracking mov #4$, R1 ; put expected virtual PC in R1 cmp R1, wassr2 ; did sr2 contain virtual PC at 4$ beq 5$ ; branch if yes error 41 ; sr2 not tracking correctly ; for tighter scope loop ; replace error call with ; "br 4$" = 000767 5$: mov #6$, $lperr ; set loop on error pointer to 6$ 6$: mov #7$, mmvec ; put address of 7$ in m.m. trap vector clr $tmp1 ; clear error indicator inc @#100500 ; cause page length abort - trap to 7$ 7$: mov #kerstk, KSP ; restore stack pointer after abort mov sr0, $tmp0 ; save sr0's information on pg. lgth. abort mov sr2, $tmp2 ; save sr2's information on pg. lgth. abort mov #8$, mmvec ; put address of 8$ in m.m. trap vector inc @#120000 ; cause r/o abort - trap to 8$ 8$: mov #kerstk, KSP ; restore stack pointer after abort mov sr0, wassr0 ; read sr0 follwoing second kt abort mov sr2, wassr2 ; read sr2 following second kt abort cmp $tmp0, wassr0 ; is sr0 still holding info on first abort? beq 9$ ; branch if yes inc $tmp1 ; set error indicator 9$: cmp $tmp2, wassr2 ; does sr2 still hold PC of first abort? beq 10$ ; branch if yes inc $tmp1 ; set error indicator 10$: tst $tmp1 ; were sr0 or sr2 changed by a second abort? beq 11$ ; branch if no error 37 ; one of status regs. changed by second abort ; for tighter scope loop ; replace error call with ; "br 6$" = 000726 11$: clr $tmp1 ; clear error indicator reset ; execute a reset, applying an "init" mov sr0, wassr0 ; read sr0 tst wassr0 ; was sr0 cleared by the reset? beq 12$ ; branch if yes inc $tmp1 ; sr0 not cleared by a reset 12$: mov sr2, wassr2 ; read sr2 cmp #12$, wassr2 ; was sr2 unlocked by a reset? beq 13$ ; branch if yes inc $tmp1 ; sr2 not unlocked by a reset 13$: tst $tmp1 ; were sr0 & sr2 both "reset" by a reset? beq 14$ ; branch if yes error 40 ; sr0 or sr2 not "reset" by a reset ; for tighter scope loop ; replace error call with ; "br 6$" = 000676 14$: inc sr0 ; turn memory management back on 15$: mov sr2, wassr2 ; read sr2 to see if its tracking again mov #15$, R1 ; put expected virtual PC in R1 cmp R1, wassr2 ; did sr2 contain virtual PC at 15$ beq 16$ ; branch if yes error 41 ; sr2 not tracking correctly ; for tighter scope loop ; replace error call with ; "br 6$" = 000663 ;_____________________________________________________________________________ ; ; All code with a '; +' designation in the comment indicates that it has been ; added to the original rev of this diagnostic. These enhancements or corrections ; are made by the product enhancement group (diagnostics). ;_____________________________________________________________________________ ; 16$: mov #21$, mmvec ; +set up ktvec for non-resident abort mov #77400, kipdr5 ; +set up kipdr5 for nr abort mov #17$, $lperr ; +set loop on error pointer 17$: clr $tmp1 ; +clear error indicator 20$: inc @#130000 ; +cause a non-resident abort inc $tmp1 ; +set error indicator mov sr0, wassr0 ; +read sr0 mov sr2, wassr2 ; +read sr2 error 65 ; +non-resident abort did not occur clr $tmp1 ; +clear error indicator 21$: mov #kerstk, KSP ; +restore kernel stack pointer 22$: tst sr0 ; +test for the nr abort in sr0 (bit 15) bmi 23$ ; +if set branch inc $tmp1 ; +set error indicator mov sr0, wassr0 ; +read sr0 mov sr2, wassr2 ; +read sr2 error 66 ; +nr abort error did not set in sr0 (bit 15) clr $tmp1 ; +clear error indicator 23$: cmp sr2, #20$ ; +test that sr2 froze to the virtual ; +address of the nr abort instr. beq 24$ ; +if equal branch inc $tmp1 ; +else error mov sr0, wassr0 ; +read sr0 mov sr2, wassr2 ; +read sr2 error 67 ; +sr2 did not contain the correct address clr $tmp1 ; +clear error indicator 24$: mov #25$, mmvec ; +set ktvec for 2nd nr abort inc @#130000 ; +cause abort inc $tmp1 ; +set error indicator mov sr0, wassr0 ; +read sr0 mov sr2, wassr2 ; +read sr2 error 70 ; +2nd nr abort did not occur clr $tmp1 ; +clear error indicator 25$: mov #kerstk, KSP ; +restore kernel stack mov sr2, wassr2 ; +read sr2 cmp wassr2, #20$ ; +test sr2 for virtual address of ; +of the first non-resident abort beq 26$ ; +if equal branch ; +else error inc $tmp1 ; +set error indicator mov sr0, wassr0 ; +read sr0 mov #20$, corsr2 ; +read correct sr2 value error 71 ; +sr2 did not contain the value of ; +the first nr abort clr $tmp1 ; +clear error indicator 26$: reset ; +issue init. conditions tst sr0 ; +sr0 should be clear beq 27$ ; +if true branch ; +else error inc $tmp1 ; +set error indicator mov sr0, wassr0 ; +read sr0 clr corsr0 ; +set correct sr0 value for error msg error 72 ; +sr0 did not clear after init. clr $tmp1 ; +clear error indicator 27$: inc sr0 ; +turn mem mang on 30$: mov sr2, wassr2 ; +read sr2 cmp wassr2, #30$ ; +is sr2 tracking again beq 31$ ; +yes, branch ; +else error inc $tmp1 ; +set error indicator mov #30$, R1 ; +set correct sr2 value foe error msg error 41 ; +error, sr2 is not tracking correctly 31$: mov #1$, $lperr ; reset loop on error pointer to 1$ mov #77406, kipdr4 ; reset pdr4 to 128 blks. r/w mov #77406, kipdr5 ; reset pdr5 to 128 blks, r/w mov #mgmerr, mmvec ; restore address of normal memory ; management trap routine to m.m. vector ;_____________________________________________________________________________ ; ; Test 42 - user abort picks up kernel space vector ; ; This test checks to be sure that when an abort occurs while in ; user mode, the trap vector information fetched is taken from ; kernel space. User page 0 is mapped to 12k (60000-77776) so ; that if user space is used instead of kernel. The new PC that ; was loaded at loc. 060004 is used instead of the new PC that ; should be picked up from loc. 000004. An odd address error is used ; to cause a trap to "4". ; tst42: scope ; 1$: jsr PC, toff ; turn off, T-bit trapping for this test mov #2$, $lperr ; set loop on error pointer to 2$ 2$: clr PSW ; go to kernel mode mov #kerstk, KSP ; setup kernel stack ptr. mov #600, uipar0 ; map user page 0 to 12k mov #4$, @#4 ; load kernel vector 4 (loc.4) with 4$ mov #340, @#6 ; load vector+2 with new PSW mov #140000, PSW ; go to user mode mov #usestk, USP ; setup user stack ptr. mov #3$, @#4 ; load user vector 4 (loc. 60004) with 3$ mov #340, @#6 ; load vector+2 with new PSW tst 3$+1 ; cause odd addr. error trap to "4" ; should pick up new PC=4$ from kernel ; loc. 4, not PC=3$ from user loc. 4 (=60004) 3$: mov PSW, R1 ; save PSW for error mov SP, R2 ; save value of stack pointer for error clr PSW ; be sure back in kernel mode error 42 ; did not trap thru kernel space ; 4$: clr PSW ; be sure back in kernel mode mov #kerstk, KSP ; restore kernel s.p. in case it changed clr uipar0 ; remap user page 0 to 0-4k mov #140000, PSW ; go to user mode mov #usestk, USP ; restore user stack pointer clr PSW ; go back to kernel mode mov #timerr, @#4 ; restore addr. of normal cpu trap handler to 4 mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit trapping back on ;_____________________________________________________________________________ ; ; Test 43 - rti in user mode does not change PSW ; ; This test checks to see that when an rti is executed in user ; mode, the mode or priority bits of the PSW are not changed. ; tst43: scope 1$: mov #2$, $lperr ; set loop on error pointer to 2$ mov #170000, R2 ; load "present & expected" PSW value into R2 2$: mov R2, PSW ; go to user mode-priority 0 mov #340, -(SP) ; put a new PSW (priority=7) on stack mov #3$, -(SP) ; put new PC on the stack rti ; do an rti from user mode 3$: mov PSW, R1 ; read new PSW into R1 bic #7437, R1 ; mask off cond. code, T-bit and unused bits clr PSW ; go back to kernel mode cmp R2, R1 ; did PSW stay in user, priority=0? beq 4$ ; branch if yes error 60 ; PSW changed by an rti from user ; 4$: mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 44 - kt error not serviced if odd addr. error ; ; This test checks to see that if a certain virtual address that ; would cause a memory management error causes an odd address ; error first, the odd address error is serviced but the memory ; management error isn't. This means that sr0 and sr2 ; should not report the error or lock up its virtual address. ; A read-only violation is used as the potential memory management ; error ; tst44: scope ; 1$: mov #600, kipar4 ; map kernel page 4 to 12-16k mov #77402, R5 ; load pdr4 data into R5 mov R5, kipdr4 ; map page 4 read-only mov #4$, @#4 ; set cpu trap vector to address of 4$ mov #3$, @#250 ; set m.m. trap vector to address of 3$ mov #2$, $lperr ; set loop on error pointer to 2$ 2$: inc 60001 ; cause odd addr. error & potential r/o abort 3$: error 43 ; trapped thru m, m. vector but shouldn't have ; 4$: mov #kerstk, KSP ; restore stack pointer after trapping clr $tmp1 ; clear error indicator mov sr0, wassr0 ; read status reg. 0 5$: mov sr2, wassr2 ; read status reg. 2 mov #17, R0 ; load expected sr0 contents into R0 cmp R0, wassr0 ; sr0 error bits left clear by trapping? beq 6$ ; branch if yes inc $tmp1 ; sr0 error bits set when odd addr. serviced 6$: mov #5$, R1 ; load expected sr2 contents into R1 cmp R1, wassr2 ; was sr2 left unlocked by trapping? beq 7$ ; branch if yes inc $tmp1 ; sr2 locked up by odd addr. error 7$: tst $tmp1 ; where sr0 or sr2 effected? beq 8$ ; branch if no error 44 ; sr0 or sr2 changed by odd addr. error ; bic #160000, sr0 ; clear error bits that may be set in sr0 8$: mov #timerr, @#4 ; restore address of normal cpu trap handler mov #mgmerr, @#250 ; restore address of normal m.m. trap handler mov #77406, kipdr4 ; remap page 4 to read/write mov #1$, $lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; Test 45 - PC & PSW saved for kt error during service of odd addr. error ; ; This test checks the PC and processor status word saved when ; a kt error occurs during the second push on the stack during ; servicing of an odd addr. error. During a "double error" ; sequence such as this, the PSW saved will be the one picked up ; from vector+2 (loc. 6 in this case) after the first trap, ; not the PSW present before the first trap. sr0 and sr2 ; should record the kt error (a r/o violation by the user stack ptr.) ; Note that the previous mode bits <13:12> of the PSW ; will be set in the PSW that is saved. ; tst45: scope ; 1$: jsr PC, toff ; turn T-bit trapping off for this test mov #600, uipar3 ; map user page 3 to 12-16k mov #600, uipar4 ; map user page 4 to 12-16k mov #77402, uipdr3 ; map user page 3 read-only mov #77406, uipdr4 ; map user page 4 read/write mov #4$, @#4 ; load address of 4$ in cpu (odd addr.) vector mov #140017, @#6 ; load PSW that should be put on stack in vector+2 mov #4$, @#250 ; load address of 4$ in m.m. trap vector mov #340, @#252 ; load a kernel PSW in mmvec+2 mov #2$, $lperr ; set loop on error pointer to 2$ 2$: mov #140000, PSW ; go to user mode mov #100002, USP ; set user stack ptr. so second push is in pg. 3 3$: inc 100005 ; cause odd address error that will cause ; r/o error when try to save old PC 4$: mov 2(KSP), R1 ; put PSW saved on kernel stack into R1 mov (KSP), R3 ; put PC saved on kernel stack into R3 mov sr0, wassr0 ; read the contents of m.m. status reg. 0 mov sr2, wassr2 ; read the contents of m.m. status reg. 2 bic #160000, sr0 ; clear the error bits in sr0 clr PSW ; be sure in kernel mode mov #kerstk, KSP ; restore kernel stack pointer mov #140000, PSW ; go to user mode mov #usestk, USP ; restore user stack pointer clr PSW ; go back to kernel mode clr $tmp0 ; clear error indicator cmp R1, #170017 ; was the PSW saved the one picked up by the ; odd addr. trap from errvec+2? ; value 170017 = PSW from loc. 6 with ; previous mode bits = user beq 5$ ; branch if yes inc $tmp0 ; wrong PSW saved during "double error" sequence 5$: cmp R3, #3$+4 ; was the PC at the time of the odd addr. error ; saved on the stack? beq 6$ ; branch if yes inc $tmp0 ; wrong PC saved during trap sequence 6$: cmp wassr0, #20147 ; did sr0 report - user, page 3, r/o abort? beq 7$ ; branch if yes inc $tmp0 ; sr0 did not report r/o abort 7$: cmp wassr2, #3$ ; did sr2 lock up virtual addr. of last ; instruction successfully fetched? beq 8$ ; branch if yes inc $tmp0 ; sr2 did not lock up addr. of odd addr. inst. 8$: tst $tmp0 ; any "errors" during trap sequence? beq 9$ ; branch if no error 45 ; the wrong PC or PSW were saved ; or sr0 or sr2 did not report r/o ; error during odd addr. - kt trap ; sequence 9$: mov #timerr, @#4 ; restore address of normal cpu trap handler mov #340, @#6 ; reload errvec+2 with kernel PSW mov #mgmerr, @#250 ; restore address of normal m.m. trap handler mov #77406, uipdr3 ; remap user page 3 read/write mov #1$, $lperr ; reset loop on error pointer to 1$ jsr PC, ton ; turn T-bit trapping back on ;_____________________________________________________________________________ ; ; This group of tests will test all the logic associated with ; the "move from previous" and "move to previous" instructions. ;_____________________________________________________________________________ ; ; Test 46 - move from previous (user) i-space ; ; This test uses the 'mfpi' instruction to ensure that the ; previous mode is clocked correctly ; there is a description before each destination mode tested, ; if the correct mode (user) is not enabled a non-resident abort ; will occur and trap to 23$, where the errors are reported. ; tst46: scope ; 1$: clr kipar0 ; map kernel page 0 to 0-4k mov #200, kipar1 ; map kernel page 1 to 4-8k mov #400, kipar2 ; map kernel page 2 to 8-12k mov #600, kipar3 ; map kernel page 3 to 12-16k mov #600, kipar4 ; map kernel page 4 to 12-16k mov #7600, kipar7 ; map kernel page 7 to the i/o page mov #77406, R0 ; make all kernel i-space pages resident ; read/write. length 200 blocks mov #10, R2 ; set loop counter to 8 mov #kipdr0, R1 ; put address of first pdr in R1 2$: mov R0, (R1)+ ; load pdr with 77406 sob R2, 2$ ; loop to 2$ until all pdrs loaded mov #10, R2 ; set loop counter to 8 mov #uipdr0, R1 ; put address of first pdr in R1 3$: mov R0, (R1)+ ; load pdr with 77406 sob R2, 3$ ; loop to 3$ until all pdrs loaded mov #000, uipar0 ; map user i page 0 to 0-4k mov #200, uipar1 ; map user i page 1 to 4-8k mov #400, uipar2 ; map user i page 2 to 8-12k mov #600, uipar3 ; map user i page 3 to 12-16k mov #7600, uipar7 ; map user i page 7 to the i/o page mov #4$, $lperr ; set loop on error to 4$ 4$: mov #77406, kipdr4 ; kernel i-space page 4 read/write mov #600, kipar4 ; map kernel i page 4 to 12k mov #600, uipar4 ; map user i page 4 to 12k mov #36514, R0 ; load data pattern into R0 mov R0, @#100000 ; load data pattern into phy 60000 mov #23$, mmvec ; set m.m. vector to 23$ clrb kipdr4 ; make kernel i-space page 4 non-resident ; the following will test dstm=0 mfpi mov #5$, $lperr ; set loop on error pointer to 5$ 5$: mov #030340, PSW ; make previous mode user 6$: mfpi USP ; put user stack pointer on kernel ; stack cmp #kerstk, KSP ; was something pushed on stack at 6$ beq 7$ ; branch if nothing was pushed mov (KSP)+, R0 ; pop kernel stack into R0 mov #usestk, R1 ; expecting to get 700 as USP cmp R0, R1 ; did you get the right pointer? beq 8$ ; branch if you dio error 46 ; wrong thing was pushed on stack ; br 8$ ; branch to next try 7$: error 50 ; nothing pushed on stack ; 8$: ; the following will test dstm=1 mfpi. mov #9$, $lperr ; set loop on error pointer to 9$ mov #36514, R0 ; reload data pattern in R0 9$: mov #030340, PSW ; make previous mode user mov #100000, R2 ; load virtual address into R2 mfpi (R2) ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 10$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 10$: ; the following will test dstm=2 mfpi. mov #11$, $lperr ; set loop on error pointer to 11$ 11$: mov #030340, PSW ; make previous mode user mov #100000, R2 ; load virtual address into R2 mfpi (R2)+ ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 12$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 12$: ; the following will test dstm=3 mfpi. mov #13$, $lperr ; set loop on error pointer to 13$ 13$: mov #030340, PSW ; make previous mode user mfpi @#100000 ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 14$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 14$: ; the following will test dstm=4 mfpi. mov #15$, $lperr ; set loop on error pointer to 15$ 15$: mov #030340, PSW ; make previous mode user mov #100002, R2 ; load virtual address into R2 mfpi -(R2) ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 16$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 16$: ; the following will test dstm=5 mfpi. mov #17$, $lperr ; set loop on error pointer to 17$ 17$: mov #030340, PSW ; make previous mode user mov #100000, $tmp2 ; load test loc. virt. addr into loc. $tmp2 mov #<$tmp2+2>, R2 ; load addr. of $tmp2+2 into R2 mfpi @-(R2) ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 18$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 18$: ; the following will test dstm=6 mfpi. mov #19$, $lperr ; set loop on error pointer to 19$ 19$: mov #030340, PSW ; make previous mode user clr R2 ; make register 2 a zero mfpi 100000(R2) ; read from physical 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 20$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 20$: ; the following will test dstm=7 mfpi. mov #21$, $lperr ; set loop on error pointer to 21$ 21$: mov #030340, PSW ; make previous mode user mov #100000, $tmp2 ; load test loc. v.a. into $tmp2 mov #$tmp2, R2 ; load address of $tmp2 into R2 mfpi @0(R2) ; use $tmp2 to fetch virtual ; address of 60000 mov (KSP)+, R1 ; pop kernel stack into R1 cmp R0, R1 ; was data fetched same as stored beq 22$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 22$: mov #mgmerr, mmvec ; set m.m. vector to normal routine mov #1$, $lperr ; set loop pointer to start of test br tst47 ; branch to next test 23$: mov (KSP)+, trappc ; save PC & ps of trap mov (KSP)+, trapps ; mov sr0, wassr0 ; save sr0 for error typeout mov sr2, wassr2 ; save sr2 for error typeout bic #160000, sr0 ; clear error bits in sr0 and leave error 51 ; tried to read non-resident page ; mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) rti ;_____________________________________________________________________________ ; ; Test 47 - move to previous (user) i-space ; ; This test uses the 'mtpi' instruction to ensure that the ; previous mode is clocked correctly ; there is a description before each destination mode tested, ; if the correct mode is not enabled a non-resident abort ; will occur and trap to 20$, where the errors are reported. ; tst47: scope ; 1$: mov #77406, kipdr4 ; kernel i-space page 4 read/write mov #77406, uipdr4 ; user i-space page 4 read/write mov #600, kipar4 ; map kernel i page 4 to 12k mov #600, uipar4 ; map user i page 4 to 12k mov #20$, mmvec ; set m.m. vector to 20$ ; the following will test dstm=0 mtpi 2$: mov #030340, PSW ; make previous mode user mov #7777, -(KSP) ; push data on kernel stack mtpi USP ; load user stack pointer mfpi USP ; read user stack pointer mov (KSP)+, R1 ; pop kernel stack into R1 cmp #7777, R1 ; was user stack pointer changed beq 3$ ; branch if it was error 50 ; user stack pointer not changed ; 3$: mov #030340, PSW ; make previous mode user mov #usestk, -(KSP) ; get ready to restore user s. point mtpi USP ; restore user stack pointer 4$: ; this will test dstm=1 mtpi. mov #5$, $lperr ; set loop on error pointer to 5$ mov #100000, R2 ; load virtual address into R2 mov #125252, R0 ; load test data into R0 5$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel i page 4 non-resident mtpi (R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov (R2), R1 ; read from address 60000 cmp R0, R1 ; see if data was stored at correct place beq 6$ ; branch if store was correct error 47 ; incorrect store ; 6$: ; the following will test dstm=2 mtpi. mov #8$, $lperr ; set loop on error pointer to 8$ mov #030340, PSW ; make previous mode user mov #125252, R0 ; load test data into R0 mov #100000, R2 ; load virtual address into R2 8$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel pagf 4 non-resident mtpi (R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resisent mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 9$ ; branch if store was correct error 47 ; incorrect store ; 9$: ; this will test dstm - 3 mtpi. mov #10$, $lperr ; set loop on error pointer to 10$ mov #030340, PSW ; make previous mode user mov #52525, R0 ; load test data into R0 10$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel i page 4 non-resident mtpi @#100000 ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 11$ ; branch if store was correct error 47 ; incorrect store ; 11$: ; this will test dstm - 4 mtpi. mov #12$, $lperr ; set loop on error pointer to 12$ mov #030340, PSW ; make previous mode user mov #125252, R0 ; load test data into R0 12$: mov R0, -(KSP) ; push test data on kernel stack mov #100002, R2 ; load virtual address into R2 clrb kipdr4 ; make kernel i page 4 non-resident mtpi -(R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 13$ ; branch if store was correct error 47 ; incorrect store ; 13$: ; the following will test dstm=5 mtpi. mov #14$, $lperr ; set loop on error pointer to 14$ mov #030340, PSW ; make previous mode user mov #52525, R0 ; load test data into R0 mov #<$tmp2+2>, R2 ; load addr. of loc. $tmp2+2 into R2 mov #100000, $tmp2 ; load virt. addr. of test loc. into $tmp2 14$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel page 4 non-resident mtpi @-(R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 15$ ; branch if store was correct error 47 ; incorrect store ; 15$: ; this will test dstm - 6 mtpi. mov #16$, $lperr ; set loop on error pointer to 16$ mov #030340, PSW ; make previous mode user mov #52525, R0 ; load test data into R0 clr R2 ; make register 2 zero 16$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel i page 4 non-resident mtpi 100000(R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 17$ ; branch if store was correct error 47 ; incorrect store ; 17$: ; the following will test dstm=7 mtpi. mov #18$, $lperr ; set loop on error pointer to 18$ mov #030340, PSW ; make previous mode user mov #125252, R0 ; load test data into R0 mov #100000, $tmp2 ; load virt. addr. of test location ; into location $tmp2 mov #$tmp2, R2 ; load address of $tmp2 into R2 18$: mov R0, -(KSP) ; push test data on kernel stack clrb kipdr4 ; make kernel page 4 non-resident mtpi @0(R2) ; load test data into physical 60000 movb #006, kipdr4 ; make kernel page 4 resident mov @#100000, R1 ; read from address 60000 cmp R0, R1 ; see if data was stored correctly beq 19$ ; branch if store was correct error 47 ; incorrect store ; 19$: mov #1$, $lperr ; set loop pointer to start of test mov #mgmerr, mmvec ; restore m.m. vector to normal routine br tst50 ; branch to next test 20$: mov (KSP)+, trappc ; save PC & ps of trap mov (KSP)+, trapps ; mov sr0, wassr0 ; save sr0 for error typeout mov sr2, wassr2 ; save sr2 for error typeout bic #160000, sr0 ; clear error bits in sr0 error 51 ; tried to load a n.r. page 4 ; mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rti ; return to test ;_____________________________________________________________________________ ; ; Test 50 - move from previous (kernel) i-space to user mode ; ; This test checks that if the previous mode is kernel the ; fetch is from kernel space. ; There is a description before each destination mode tested, ; if the correct mode is not enabled a non-resident abort ; will occur and trap to 21$, where the errors are reported. ; tst50: scope ; 1$: mov #77406, R0 ; make all user i-space pages resident ; read/write, length 200 blocks mov #10, R2 ; set loop counter to 8 mov #uipdr0, R1 ; load address of first pdr in R1 2$: mov R0, (R1)+ ; load pci with 77406 sob R2, 2$ ; loop until 8 user pdrs loaded mov #3$, $lperr ; set loop on error to 3$ 3$: mov #140340, PSW ; go to user mode for this test mov #77406, kipdr4 ; kernel i-space page 4 read/write mov #600, kipar4 ; map kernel i page 4 to 12k mov #600, uipar4 ; map user i page 4 to 12k mov #36514, R0 ; load data pattern into R0 mov R0, @#100000 ; load data pattern into phy 60000 mov #100000, R2 ; load virtual address into R2 ; the following will test dstm=0 mfpi mov #21$, mmvec ; set m.m. vector to 21$ clrb uipdr4 ; make user i-space page 4 non-resident mov #140340, PSW ; make previous mode kernel present user 4$: mfpi KSP ; put kernel stack pointer on user stack cmp #usestk, USP ; was something pushed on stack at 1$ beq 5$ ; branch if nothing was pushed mov (USP)+, R0 ; pop user stack into R0 mov #kerstk, R1 ; expecting 1100 as KSP cmp R0, R1 ; did you get the right pointer? beq 6$ ; branch if you did error 46 ; wrong thing was pushed on stack ; br 6$ ; branch to next try 5$: error 50 ; nothing pushed on stack ; 6$: ; the following will test dstm=1 mfpi. mov #7$, $lperr ; set loop on error pointer to 7$ 7$: mov #140340, PSW ; make previous mode kernel present user mov #36514, R0 ; load data expected into R0 mov #100000, R2 ; load virtual address into R2 mfpi (R2) ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 8$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 8$: ; the following will test dsm=2 mfpi. mov #9$, $lperr ; set loop on error pointer to 9$ 9$: mov #140340, PSW ; make previous mode kernel present user mov #100000, R2 ; load virtual address into R2 mfpi (R2)+ ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 10$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 10$: ; the following will test dstm=3 mfpi. mov #11$, $lperr ; set loop on error pointer to 11$ 11$: mov #140340, PSW ; make previous mode kernel present user mfpi @#100000 ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 12$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 12$: ; the following will test dstm=4 mfpi. mov #13$, $lperr ; set loop on error pointer to 13$ 13$: mov #140340, PSW ; make previous mode kernel present user mov #100002, R2 ; load virtual address into R2 mfpi -(R2) ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 14$ ; branch if correct data was fetched error 46 ; wrong data was fetched ; 14$: ; the following will test dstm=5 mfpi. mov #15$, $lperr ; set loop on error pointer to 15$ 15$: mov #140340, PSW ; make previous mode kernel present user mov #100000, $tmp2 ; load test loc. virt. addr into loc. $tmp2 mov #<$tmp2+2>, R2 ; load address of $tmp2+2 into R2 mfpi @-(R2) ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 16$ ; branch if correct data fetched error 46 ; wrong data was fetched ; 16$: ; the following will test dstm=6 mfpi. mov #17$, $lperr ; set loop on error pointer to 17$. 17$: mov #140340, PSW ; make previous mode kernel present user clr R2 ; make register 2 a zero mfpi 100000(R2) ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 18$ ; branch if correct data fetched error 46 ; wrong data was fetched ; 18$: ; the following will test dstm=7 mfpi. mov #19$, $lperr ; set loop on error pointer to 19$ 19$: mov #140340, PSW ; make previous mode kernel present user mov #100000, $tmp2 ; load test loc. virt. addr. into $tmp2 mov #$tmp2, R2 ; load address of $tmp2 into R2 mfpi @0(R2) ; read from physical 60000 mov (USP)+, R1 ; pop user stack into R1 cmp R0, R1 ; was data fetched same as stored beq 20$ ; branch if correct data fetched error 46 ; wrong data was fetched ; 20$: mov #mgmerr, mmvec ; set m.m. vector to normal routine mov #00340, PSW ; go back to kernel mode, previous kernel mov #1$, $lperr ; set loop pointer to start of test br tst51 ; branch to next text 21$: mov (KSP)+, trappc ; save PC & ps of trap mov (KSP)+, trapps ; mov sr0, wassr0 ; save sr0 for error typeout mov sr2, wassr2 ; save sr2 for error typeout bic #160000, sr0 ; clear error bits in sr0 error 51 ; tried to read non-resident page ; mov trapps, -(KSP) ; put PC & ps of trap on stack mov trappc, -(KSP) ; rti ; return to test ;_____________________________________________________________________________ ; ; Test 51 - move from/to d-space = move from/to i-space ; ; This test checks that since there is no distinction ; between instruction and data space in the 11/34 ; mfpd & mtpd should be decoded the same as mfpi & mtpi. ; tst51: scope ; 1$: mov #030340, PSW ; make previous mode=user, current=kernel mfpd USP ; mfpd should act like mfpi putting ; user stack pointer on the kernel stack cmp #kerstk, KSP ; was something pushed on kernel stack? beq 2$ ; branch if no mov (KSP)+, R0 ; pop kernel stack into R0 mov #usestk, R1 ; expecting to get 700 as USP cmp R0, R1 ; did get right pointer value? beq 3$ ; branch if yes error 53 ; wrong thing was pushed on stack ; for tighter scope loop ; replace error call with ; "br 1$" = 000763 br 3$ ; branch to next try 2$: error 54 ; nothing pushed on stack ; 3$: mov #4$, $lperr ; set loop on error pointer to 4$ 4$: mov #7777, -(KSP) ; push data on kernel stack mtpd USP ; load the user stack pointer mfpd USP ; read user stack pointer mov (KSP)+, R1 ; pop kernel stack into R1 cmp #7777, R1 ; was user stack pointer changed? beq 5$ ; branch if yes error 54 ; user stack pointer not changed ; 5$: mov #usestk, -(KSP) ; get ready to restore user stk. ptr. mtpd USP ; restore user stack pointer mov #1$, $lperr ; set loop pointer to start of test ;_____________________________________________________________________________ ; ; Test 52 - move from previous i-space (previous-current-kernel) ; ; This test checks that if both previous and current modes ; are kernel, and the source mode is 0, the destination ; stack is not decremented before access. ; "mfpi KSP" should push the non-decremented value ; of KSP (1100) onto the stack (at loc. 1076). ; tst52: scope ; 1$: clr @#psw ; set previous = current = kernel mov #stack, R0 ; setup value for stack pointer mov R0, KSP ; load stack pointer mfpi KSP ; the value "stack" should be pushed ; before being decremented mov (KSP), R1 ; read data which was pushed cmp R0, R1 ; was the original value of the ; stack pointer pushed? beq 2$ ; branch if yes error 46 ; mfpi fetched wrong data ; 2$: tst -(R0) ; setup expected stack pointer value cmp KSP, R0 ; was the stack pointer decremented? beq 3$ ; branch if yes error 50 ; stack not pushed by the mfpi ; for tighter scope loop ; replace error call with ; "br 1$" = 000762 3$: mov #stack, KSP ; restore stack pointer .sbttl "END OF PASS ROUTINE" ;_____________________________________________________________________________ ; ; Increment the pass number ($pass) ; type "end pass #xxxxx total number of errors since last report yyyyy" ; where xxxxx and yyyyy are decimal numbers ; if sw12=1 inhibit trace trap ; if theres a monitor go to it ; if there isn't jump to loop ; $eop: scope ; clr $tstnm ; zero the test number clr $times ; zero the number of iterations inc $pass ; increment the pass number bic #100000, $pass ; (don't allow a neg. number dec (PC)+ ; loop? $eopct: .word 1 ; bgt $doagn ; yes mov (PC)+, @(PC)+ ; restore counter $endct: .word 1 ; $eopct ; type , 65$ ; type asciz string .if ne HOEP ; halt ; halt on end-of-pass .iff ; br 64$ ; get over the asciz .endc ; .if ne SKIP ; 65$: .asciz <15> ; .iff ; 65$: .asciz <12><15>/END PASS #/ ; .endc ; .even ; 64$: mov $pass, -(SP) ; save $pass for typeout ; type pass number typds ; go type-decimal ascii with sign type , 67$ ; type asciz string br 66$ ; get over the asciz 67$: .asciz / TOTAL ERRORS SINCE LAST REPORT / .even 66$: mov $erttl, -(SP) ; save $erttl for typeout ; total number of errors typds ; go type-decimal ascii with sign type , $crlf ; type carriage return, line feed clr $erttl ; clear error total $get42: mov @#42, R0 ; get monitor address beq $doagn ; branch if no monitor clr -(SP) ; insure the "T"-bit is clear mov #$clr.t, -(SP) ; setup for an rti or rtt br $rtrn ; go do an rti or rtt to load the PSW ; with a cleared "T"-bit $clr.t: mov @#42, R0 ; insure R0 contains the monitors beq $doagn ; return address reset ; clear the world $endad: jsr PC, (R0) ; go to monitor nop ; save room nop ; for nop ; act11 ; $doagn: trap ; push old PSW and PC on stack bic #20, (SP) ; clear the "T"-bit bit #bit12, @swr ; run with trace trap? bne 1$ ; br if no com $tbit ; is it time for trace trap bmi 1$ ; br if no bis #20, (SP) ; set trace trap 1$: mov #$loop, -(SP) ; jump to start of test $rtrn: rti ; return-this is changed to ; an "rtt" if "rtt" is a legal ; instruction $loop: jmp @(PC)+ ; return $rtnad: .word loop ; $tbit: .word 0 ; "T"-bit state indicator $enull: .byte -1, -1, 0 ; null character string .even ; .sbttl "SCOPE HANDLER ROUTINE" ;_____________________________________________________________________________ ; ; This routine controls the looping of subtests. It will increment ; and load the test number ($tstnm) into the display reg. (display <7:0>) ; and load the error flag ($erflg) into display <15:08> ; The switch options provided by this routine are: ; sw14=1 loop on test ; sw11=1 inhibit iterations ; sw09=1 loop on error ; sw08=1 loop on test in swr <7:0> ; Call: ; scope ; scope=iot ; $scope: ckswr ; test for change in soft-swr 1$: bit #bit14, @swr ; loop on present test? bne $over ; yes if sw14=1. ; #####start of code for the xor tester##### $xtstr: br 6$ ; if running on the "xor" tester change ; this instruction to a "nop" (nop=240) mov @#errvec, -(SP) ; save the contents of the error vector mov #5$, @#errvec ; set for timeout tst @#177060 ; time out on xor? mov (SP)+, @#errvec ; restore the error vector br $svlad ; go to the next test 5$: cmp (SP)+, (SP)+ ; clear the stack after a time out mov (SP)+, @#errvec ; restore the error vector br 7$ ; loop on the present test 6$:; #####end of code for the xor tester##### bit #bit08, @swr ; loop on spec. test? beq 2$ ; br if no cmpb @swr, $tstnm ; on the right test? swr <7:0> beq $over ; br if yes 2$: tstb $erflg ; has an error occurred? beq 3$ ; br if no cmpb $ermax, $erflg ; max. errors for this test occurred? bhi 3$ ; br if no bit #bit09, @swr ; loop on error? beq 4$ ; br if no 7$: mov $lperr, $lpadr ; set loop address to last scope br $over ; ; 4$: clrb $erflg ; zero the error flag clr $times ; clear the number of iterations to make br 1$ ; escape to the next test 3$: bit #bit11, @swr ; inhibit iterations? bne 1$ ; br if yes tst $pass ; if first pass of program beq 1$ ; inhibit iterations inc $icnt ; increment iteration count cmp $times, $icnt ; check the number of iterations made bge $over ; br if more iteration required 1$: mov #1, $icnt ; reinitialize the iteration counter mov $mxcnt, $times ; set number of iterations to do $svlad: incb $tstnm ; count test numbers movb $tstnm, $testn ; set test number in apt mailbox mov (SP), $lpadr ; save scope loop address mov (SP), $lperr ; save error loop address clr $escape ; clear the escape from error address movb #1, $ermax ; only allow one(1) error on next test $over: mov $tstnm, @display ; display test number mov $lpadr, (SP) ; fudge return address rti ; fixes ps $mxcnt: 200 ; max. number of iterations .sbttl "ERROR HANDLER ROUTINE" ;_____________________________________________________________________________ ; ; This routine will increment the error flag and the error count, ; save the error item number and the address of the error call ; and go to errtyp on error ; The switch options provided by this routine are: ; sw15=1 halt on error ; sw13=1 inhibit error typeouts ; sw10=1 bell on error ; sw09=1 loop on error ; Call: ; error n ; error=emt and n=error item number ; $error: ckswr ; test for change in soft-swr mov R0, $reg0 ; save the contents of R0 mov R1, $reg1 ; save the contents of R1 mov R2, $reg2 ; save the contents of R2 mov R3, $reg3 ; save the contents of R3 mov R4, $reg4 ; save the contents of R4 mov R5, $reg5 ; save the contents of R5 movb $tstnm, testno ; save the test number 7$: incb $erflg ; set the error flag beq 7$ ; don't let the flag go to zero mov $tstnm, @display ; display test number and error flag bit #bit10, @swr ; bell on error? beq 1$ ; no - skip type , $bell ; ring bell 1$: inc $erttl ; count the number of errors mov (SP), $errpc ; get address of error instruction sub #2, $errpc ; movb @$errpc, $itemb ; strip and save the error item code bit #bit13, @swr ; skip typeout if set bne 20$ ; skip typeouts jsr PC, errtyp ; go to user error routine type , $crlf ; ; 20$: cmpb #aptenv, $env ; running in apt mode bne 2$ ; no, skip apt error report movb $itemb, 21$ ; set item number as error number jsr PC, $aty4 ; report fatal error to apt 21$: .byte 0 ; .byte 0 ; 22$: br 22$ ; apt error loop 2$: tst @swr ; halt on error bpl 3$ ; skip if continue halt ; halt on error! ckswr ; test for change in soft-swr 3$: bit #bit09, @swr ; loop on error switch set? beq 4$ ; br if no mov $lperr, (SP) ; fudge return for looping 4$: tst $escape ; check for an escape address beq 5$ ; br if none mov $escape, (SP) ; fudge return address for escape ; 5$: cmp #$endad, @#42 ; act-11 auto-accept? bne 6$ ; branch if no halt ; yes 6$: rti ; return .sbttl "ERROR MESSAGE TYPEOUT ROUTINE" ;_____________________________________________________________________________ ; ; This routine uses the "item control byte" ($itemb) to determine which ; error is to be reported. It then obtains, from the "error table" ($errtb), ; and reports the appropriate information concerning the error. ; Notes: ; 1) this routine provides an automatic "carriage return-line feed" ; for "em", "dh", and "dt". ; 2) two spaces are typed after each number for "dt" ; 3) for $itemb=0, just the error PC is typed ; 4) the available formats for typing data are: ; of format ; 0 type a 6 digit octal number (from 16-bit binary) ; 1 type a decimal number without leading zeros ; 2 type a 16 digit binary number ; 3 type a 6 digit octal number (from 18-bit binary) ; errtyp: type , $crlf ; "carriage return" & "line feed" mov R0, -(SP) ; save R0 clr R0 ; pickup the item index bisb @#$itemb, R0 ; bne 1$ ; if item number is zero, just ; type the PC of the error mov $errpc, -(SP) ; save $errpc for typeout ; error address typoc ; go type-octal ascii(all digits) br 13$ ; get out 1$: dec R0 ; adjust the index so that it will asl R0 ; work for the error table asl R0 ; asl R0 ; add #$errtb, R0 ; form table pointer mov (R0)+, 2$ ; pickup "error message" pointer beq 3$ ; skip typeout if no pointer type ; type the "error message" 2$: .word 0 ; "error message" pointer goes here type , $crlf ; "carriage return" & "line feed" 3$: mov (R0)+, 4$ ; pickup "data header" pointer beq 5$ ; skip typeout if 0 type ; type the "data header" 4$: .word 0 ; "data header" pointer goes here type , $crlf ; "carriage return" & "line feed" 5$: mov R1, -(SP) ; save R1 mov (R0)+, R1 ; pickup "data table" pointer beq 12$ ; br if no data to be typed mov (R0)+, R0 ; pickup "data format" pointer 6$: tstb (R0) ; is it format 0? bne 7$ ; br if no ; ; This code is for octal (16-bit) format (df=0) ; mov @(R1)+, -(SP) ; save @(R1)+ for typeout typoc ; go type-octal ascii(all digits) br 11$ ; ; This code is for decimal format (df=1) ; 7$: cmpb (R0), #1 ; is it format 1? bne 8$ ; branch if no mov @(R1)+, -(SP) ; save @(R1)+ for typeout typds ; go type-decimal ascii with sign br 11$ ; ; This code is for binary format (df=2) ; 8$: cmpb (R0), #2 ; is it format 2? bne 9$ ; branch if no mov @(R1)+, -(SP) ; save @(R1)+ for typeout typbn ; go type-binary ascii br 11$ ; ; This code is for octal (18-bit) format (df=3) ; 9$: mov (R1)+, -(SP) ; put address of first loc. on stack jsr PC, $db20 ; convert two locs. to an ascii string add #5, (SP) ; only need 6 characters not 11 mov (SP)+, 10$ ; put address of ascii chars. at 10$ type ; type octal value of 18-bit binary no. 10$: .word 0 11$: tst (R1) ; is there another number? beq 12$ ; br if no type , 14$ ; type two(2) spaces tstb (R0)+ ; point to new "data format" br 6$ ; loop 12$: mov (SP)+, R1 ; restore R1 13$: mov (SP)+, R0 ; restore R0 type , $crlf ; "carriage return" & "line feed" rts PC ; return 14$: .asciz / / ; two(2) spaces .even .sbttl "***** SUBROUTINES USED BY THIS PROGRAM *****" .sbttl "TURN OFF T-BIT AND SAVE CURRENT PSW" ;_____________________________________________________________________________ ; ; This subroutine is used to turn off the trace trap bit in the PSW ; if it is on. The processor status is saved in "tbitps" so that ; the PSW can be restored to its previous condition when conditions ; warrant T-bit trapping. ; toff: bit PSW, #tbit ; is the T-bit set in the PSW? beq 1$ ; exit if no mov PSW, -(SP) ; push present PSW on the stack mov (SP), tbitps ; also save it in "tbitps" for ; restoring later bic #tbit, (SP) ; clear the T-bit (bit 4) in the PSW mov #1$, -(SP) ; push PC of "rts" on stack rtt ; "return" to 1$ with T-bit off 1$: rts PC ; return to program .sbttl "TURN ON T-BIT AND RESTORE PREVIOUS PSW" ;_____________________________________________________________________________ ; ; This subroutine is used to restore the processor status to its ; previous condition by restoring the "T-bit PSW" saved by the ; "toff" subroutine in the "tbitps" location. ; ton: bit tbitps, #tbit ; was T-bit on in the previous PSW? beq 1$ ; exit if no mov tbitps, -(SP) ; push previous PSW on the stack mov #340, tbitps ; reset the "tbitps" location mov #1$, -(SP) ; push PC of "rts" on stack rtt ; "return" to 1$ with T-bit restored 1$: rts PC ; return to program .sbttl "SET ALL WRITEABLE BITS IN ALL PAR/PDR'S" ;_____________________________________________________________________________ ; ; This subroutine is used by the par/pdr dual addressing test ; to set all writeable bits in all kernel and use par's and ; pdr's to a 1. The "initial state" of having all bits=1 is ; used to see that only one register is cleared in response to ; a single par or pdr address. ; setreg: mov #10, R2 ; load loop counter with an b mov #kipdr0, R1 ; load address of first pdr into R1 1$: mov #-1, (R1)+ ; set bits in kernel pdr to 1 sob R2, 1$ ; loop to 1$ until all kernel pdr's loaded mov #10, R2 ; load loop counter with an 8 mov #kipar0, R1 ; load address of first par into R1 2$: mov #-1, (R1)+ ; set bits in a kernel par to 1 sob R2, 2$ ; loop to 2$ until all kernel par's loaded mov #10, R2 ; load loop counter with an b mov #uipdr0, R1 ; load address of first pdr into R1 3$: mov #-1, (R1)+ ; set bits in a user pdr to 1 sob R2, 3$ ; loop to 3$ until all user pdr's loaded mov #10, R2 ; load loop counter with an 8 mov #uipar0, R1 ; load address of first par into R1 4$: mov #-1, (R1)+ ; set bits in a user par to 1 sob R2, 4$ ; loop to 4$ until all user par's loaded rts PC ; return to test .sbttl "READ & COMPARE KERNEL & USER PAR/PDR'S" ;_____________________________________________________________________________ ; ; This subroutine is used by par/pdr dual addressing test to ; read all the par's and pdr's to see that only one register ; was cleared in response to a single par or pdr address. ; Any failures found by the par/pdr dual addressing test will ; be reported by this subroutine. ; cmpreg: mov #kipdr0, R1 ; load address of first kernel pdr in R1 mov #10, R4 ; load loop counter with an 8 mov #77416, R5 ; put expected pdr contents in R5 1$: mov (R1), R2 ; read a kernel pdr into R2 cmp R2, R5 ; are all writeable bits set al expected? beq 2$ ; branch 1f yes cmp R1, R0 ; was it the reg. that was cleared? beq 2$ ; branch if yes error 16 ; a pdr was effected by clearing a different par/pdr ; 2$: add #2, R1 ; form next kernel pdr address sob R4, 1$ ; loop to 1$ until all kernel pdr's checked mov #kipar0, R1 ; load address of first kernel par in R1 mov #10, R4 ; load loop counter with an 8 mov #7777, R5 ; put expected par contents in R5 3$: mov (R1), R2 ; read a kernel par into R2 cmp R2, R5 ; are all writeable bits set as expected? beq 4$ ; branch if yes cmp R1, R0 ; was it the reg. that was cleared? beq 4$ ; branch if yes error 16 ; a par was effected by clearing a different par/pdr ; 4$: add #2, R1 ; form next kernel par address sob R4, 3$ ; loop to 3$ until all kernel par's checked mov #uipdr0, R1 ; load address of first user pdr in R1 mov #10, R4 ; load loop counter with an 8 mov #77416, R5 ; put expected pdr contents in R5 5$: mov (R1), R2 ; read a user pdr into R2 cmp R2, R5 ; are all writable bits set as expected? beq 6$ ; branch if yes cmp R1, R0 ; was it the reg. that was cleared? beq 6$ ; branch if yes error 16 ; a pdr was effected by clearing a different par/pdr ; 6$: add #2, R1 ; form next user pdr address sob R4, 5$ ; loop to 5$ until all user pdr's checked mov #uipar0, R1 ; load address of first user par in R1 mov #10, R4 ; load loop counter with an 8 mov #7777, R5 ; put expected par contents in R5 7$: mov (R1), R2 ; read a user par into R2 cmp R2, R5 ; are all writeable bits set as expected? beq 8$ ; branch if yes cmp R1, R0 ; was it the reg. that was cleared? beq 8$ ; branch if yes error 16 ; a par was effected by clearing a different par/pdr ; 8$: add #2, R1 ; form next user par address sob R4, 7$ ; loop to 7$ until all user par's checked rts PC ; return to test .sbttl "CONVERT VIRTUAL ADDRESS TO PHYSICAL ADDRESS" ;_____________________________________________________________________________ ; ; This subroutine is used to form an 18-bit physical address ; (pba) from the 16-bit virtual address (vba) and the appropriate ; page address register (par). The same method used by the memory ; management logic is used. vba <15:13> selects which par/pdr ; is to be used, vba <5:0>+pba <5:0>, and vba <12:6> is added ; to par <11:00> to give pba <17:6>. Bits <17:16> of the ; physical address are left in loc. "pbahi" and bits <15:00> ; are left in loc. "pbalo". The PSW's "current mode" bits ; are used to select the kernel or user par/pdr's. The routine ; is entered with loc. "virt1" containing the 16-bit virtual ; address. ; formpa: mov #kipar0, R2 ; load address of first kernel par in R2 bit #140000, PSW ; in user mode? beq 1$ ; branch if no mov #uipar0, R2 ; load address of first user par in R2 1$: mov virt1, R0 ; load virtual addr. (vba) into R0 ash #-14, R0 ; get bits <15:13> down to bits <3:1> bic #177761, R0 ; mask of all bits but bits <3:1> add R0, R2 ; add offset to base par address mov (R2), R0 ; get bits <11:00> from appropriate par mov R0, R2 ; copy par bits <11:00> into R2 mov virt1, pbalo ; put virtual addr. in loc. "pbalo" bic #160000, pbalo ; clear off bits <15:13> of original vba ash #-12, R2 ; get par <11:00> down to bits <1:0> of R2 bic #177774, R2 ; clear off all bits but bits <1:0> ash #6, R0 ; shift par <9:0> to <15:6> of R0 bic #77, R0 ; clear bits <5:0> of R0 add R0, pbalo ; in effect, add vba <12:0> to par <9:0> ; (par <9:0> in bits <15:6> of R0 adc R2 ; add any carry to R2 mov R2, pbahi ; put bits <17:16> of physical addr. in pbahi rts PC ; return to program .sbttl "TTY INPUT ROUTINE" ;_____________________________________________________________________________ ; .enabl lsb ; Software switch register change routine. ; Routine is entered from the trap handler, and will ; service the test for change in software switch register trap call ; when operating in tty flag mode. ; $ckswr: cmp #swreg, swr ; is the soft-swr selected? bne 15$ ; branch if no tstb @$tks ; char there? bpl 15$ ; if no, don't wait around movb @$tkb, -(SP) ; save the char bic #^c177, (SP) ; strip-off the ascii cmp #7, (SP)+ ; is it a cc$trol g? bne 15$ ; no, return to user cmpb $autob, #1 ; are we running in auto-mode? beq 15$ ; branch if yes type , $cntlg ; echo the control-g ("g) $gtswr: type , $mswr ; type current contents mov swreg, -(SP) ; save swreg for typeout typoc ; go type-octal ascii(all digits) type , $mnew ; prompt for new swr 19$: clr -(SP) ; clear counter clr -(SP) ; the new swr 7$: tstb @$tks ; char there? bpl 7$ ; if not try again movb @$tkb, -(SP) ; pick up char bic #^c177, (SP) ; make it 7-bit ascii cmp (SP), #3 ; is it a control-c? bne 9$ ; branch if not type , $cntlc ; yes, echo control-c (^c) add #6, SP ; clean up stack cmpb $intag, #1 ; reenable tty keyboard interrupts? bne 8$ ; branch if no mov #100, @$tks ; allow tty keyboard interrupts 8$: jmp cntrlc ; control-c restart 9$: cmp (SP), #25 ; is it a control-u? bne 10$ ; branch if not type , $cntlu ; yes, echo control-u ("u) 20$: add #6, SP ; ignore previous input br 19$ ; let's try it again 10$: cmp (SP), #15 ; is it a ? bne 16$ ; branch if no tst 4(SP) ; yes, is it the first char? beq 11$ ; branch if yes mov 2(SP), @swr ; save new swr 11$: add #6, SP ; clear up stack 14$: type , $crlf ; echo and cmpb $intag, #1 ; re-enable tty kbd interrupts? bne 15$ ; branch if not mov #100, @$tks ; re-enable tty kbd interrupts 15$: rti ; return 16$: jsr PC, $typec ; echo char cmp (SP), #60 ; char < 0? blt 18$ ; branch if yes cmp (SP), #67 ; char > 7? bgt 18$ ; branch if yes bic #60, (SP)+ ; strip-off ascii tst 2(SP) ; is this the first char beq 17$ ; branch if yes asl (SP) ; no, shift present asl (SP) ; char over to make asl (SP) ; room for new one. 17$: inc 2(SP) ; keep count of char bis -2(SP), (SP) ; set in new char br 7$ ; get the next one 18$: type , $ques ; type ? br 20$ ; simulate control-u .dsabl lsb ;_____________________________________________________________________________ ; ; This routine will input a single character from the tty ; Call: ; rdchr ; input a single character from the tty ; return here ; character is on the stack ; ; with parity bit stripped off ; $rdchr: mov (SP), -(SP) ; push down the PC mov 4(SP), 2(SP) ; save the ps 1$: tstb @$tks ; wait for bpl 1$ ; a character movb @$tkb, 4(SP) ; read the tty bic #^c<177>, 4(SP) ; get rid of junk if any cmp 4(SP), #23 ; is it a control's? bne 3$ ; branch if no 2$: tstb @$tks ; wait for a character bpl 2$ ; loop until its there movb @$tkb, -(SP) ; get character bic #^c177, (SP) ; make it 7-bit ascii cmp (SP)+, #21 ; is it a control-q? bne 2$ ; if not discard it br 1$ ; yes, resume 3$: cmp 4(SP), #140 ; is it upper case? blt 4$ ; branch if yes cmp 4(SP), #175 ; is it a special char? bgt 4$ ; branch if yes bic #40, 4(SP) ; make it upper case 4$: rti ; go back to user ;_____________________________________________________________________________ ; ; This routine will input a string from the tty ; Call: ; rdlin ; input a string from the tty ; return here ; address of first character will be on the stack ; ; terminator will be a byte of all 0's ; $rdlin: mov R3, -(SP) ; save R3 clr -(SP) ; clear the rubout key 1$: mov #$ttyin, R3 ; get address 2$: cmp #$ttyin+8., R3 ; buffer full? blos 4$ ; br if yes rdchr ; go read one character from the tty movb (SP)+, (R3) ; get character cmpb #3, (R3) ; is it a control-c? bne 10$ ; branch if no type , $cntlc ; type a control-c (^c) tst (SP) + ; clean rubout key off of the stack mov (SP)+, R3 ; restore R3 jmp cntrlc ; goto control-c restart 10$: cmpb #177, (R3) ; is it a rubout bne 5$ ; br if no tst (SP) ; is this the first rubout? bne 6$ ; br if no movb #'\, 9$ ; type a back slash type , 9$ ; mov #-1, (SP) ; set the rubout key 6$: dec R3 ; backup by one cmp R3, #$ttyin ; stack empty? blo 4$ ; br if yes movb (R3), 9$ ; setup to typeout the deleted char. type , 9$ ; go type br 2$ ; go read another char. 5$: tst (SP) ; rubout key set? beq 7$ ; br if no movb #'\, 9$ ; type a back slash type , 9$ ; clr (SP) ; clear the rubout key 7$: cmpb #25, (R3) ; is character a ctrl u? bne 8$ ; br if no type , $cntlu ; type a control "u" br 1$ ; go start over 8$: cmpb #22, (R3) ; is character a "^r"? bne 3$ ; branch if no clrb (R3) ; clear the character type , $crlf ; type a "cr" & "lf" type , $ttyin ; type the input string br 2$ ; go pickup another chacter 4$: type , $ques ; type a '?' br 1$ ; clear the buffer and loop 3$: movb (R3), 9$ ; echo the character type , 9$ ; cmpb #15, (R3)+ ; check for return bne 2$ ; loop if not return clrb -1(R3) ; clear return (the 15) type , $lf ; type a line feed tst (SP)+ ; clean rubout key from the stack mov (SP)+, R3 ; restore R3 mov (SP), -(SP) ; adjust the stack and put address of the mov 4(SP), 2(SP) ; first ascii character on it mov #$ttyin, 4(SP) ; rti ; return ; 9$: .byte 0 ; storage for ascii char. to type .byte 0 ; terminator $ttyin: .blkb 8. ; reserve 8 bytes for tty input $cntlc: .asciz /^C/<15><12> ; control "c" $cntlu: .asciz /^U/<15><12> ; control "u" $cntlg: .asciz /^G/<15><12> ; control "g" $mswr: .asciz <15><12>/SWR = / ; $mnew: .asciz / NEW = / ; .even ; .sbttl "CONTROL-C SERVICING ROUTINE" ;_____________________________________________________________________________ ; ; The following code is executed when a control-c has ; been typed instead of a new switch rfg. value. ; (in other words, after a control-g was typed). ; A new switch reg. value will be asked for, ; the test number and pass number will be typed, ; and then the program will go to "end-of-pass" and continue ; cntrlc: mov $pass, $tmp5 ; get the value of "$pass" inc $tmp5 ; form current pass no. type , cmsg ; type the test stops message movb $tstnm, 1$ ; save the test number mov 1$, -(SP) ; save 1$ for typeout typoc ; go type-octal ascii(all digits) type , 2$ ; type 2 spaces mov $tmp5, -(SP) ; save $tmp5 for typeout typds ; go type-decimal ascii with sign gtswr ; ask for new swr value jmp $eop+2 ; continue at $eop+2 1$: .word 0 ; buffer for test number 2$: .asciz / / ; two spaces and the stop message cmsg: .ascii /JUMPING TO END-OF-PASS/<15><12> .asciz /TESTNO PASSNO/<15><12> .even .sbttl "TYPE ROUTINE" ;_____________________________________________________________________________ ; ; Routine to type asciz message. Message must terminate with a 0 byte. ; The routine will insert a number of null characters after a line feed. ; Note1: $null contains the character to be used as the filler character. ; Note2: $fills contains the number of filler characters required. ; Note3: $fillc contains the character to fill after. ; Call: ; 1) using a trap instruction ; type , mesadr ; mesadr is first address of an asciz string ; or ; type ; mesadr ; $type: tstb $tpflg ; is there a terminal? bpl 1$ ; br if yes halt ; halt here if no terminal br 3$ ; leave 1$: mov R0, -(SP) ; save R0 mov @2(SP), R0 ; get address of asciz string cmpb #aptenv, $env ; running in apt mode bne 62$ ; no, go check for apt console bitb #aptspool, $envm ; spool message to apt beq 62$ ; no, go check for console mov R0, 61$ ; setup message address for apt jsr PC, $aty3 ; spool message to apt 61$: .word 0 ; message address 62$: bitb #aptcsup, $envm ; apt console suppressed bne 60$ ; yes, skip type out 2$: movb (R0)+, -(SP) ; push character to be typed onto stack bne 4$ ; br if it isn't the terminator tst (SP)+ ; if terminator pop it off the stack 60$: mov (SP)+, R0 ; restore R0 3$: add #2, (SP) ; adjust return PC rti ; return 4$: cmpb #ht, (SP) ; branch if beq 8$ ; cmpb #crlf, (SP) ; branch if not bne 5$ ; tst (SP)+ ; pop equiv type ; type a cr and lf $crlf clrb $charcnt ; clear character count br 2$ ; get next character 5$: jsr PC, $typec ; go type this character 6$: cmpb $fillc, (SP)+ ; is it time for filler chars.? bne 2$ ; if no go get next char. mov $null, -(SP) ; get # of filler chars. needed ; and the null char. 7$: decb 1(SP) ; does a null need to be typed? blt 6$ ; br if no-go pop the null off of stack jsr PC, $typec ; go type a null decb $charcnt ; do not count as a count br 7$ ; loop ; ; Horizontal tab processor ; 8$: movb #' , (SP) ; replace tab with space 9$: jsr PC, $typec ; type a space bitb #7, $charcnt ; branch if not at bne 9$ ; tab stop tst (SP)+ ; pop space off stack br 2$ ; get next character $typec: tstb @$tps ; wait until printer is ready bpl $typec ; movb 2(SP), @$tpb ; load char to 3c typed into data reg. cmpb #cr, 2(SP) ; is character a carriage return? bne 1$ ; branch if no clrb $charcnt ; yes-clear character count br $typex ; exit 1$: cmpb #lf, 2(SP) ; is character a line feed? beq $typex ; branch if yes incb (PC)+ ; count the character $charcnt: .word 0 ; character count storage $typex: rts PC ; .sbttl "APT COMMUNICATIONS ROUTINE" ;_____________________________________________________________________________ ; $aty1: movb #1, $fflg ; to report fatal error $aty3: movb #1, $mflg ; to type a message br $atyc ; $aty4: movb #1, $fflg ; to only report fatal error $atyc: ; mov R0, -(SP) ; push R0 on stack mov R1, -(SP) ; push R1 on stack tstb $mflg ; should type a message? beq 5$ ; if not: br cmpb #aptenv, $env ; operating under apt? bne 3$ ; if not: br bitb #aptspool, $envm ; should spool messages? beq 3$ ; if not: br mov @4(SP), R0 ; get message addr. add #2, 4(SP) ; bump return addr. 1$: tst $msgtype ; see if done w/ last xmission? bne 1$ ; if not: wait mov R0, $msgad ; put addr in mailbox 2$: tstb (R0)+ ; find end of message bne 2$ ; sub $msgad, R0 ; sub start of message asr R0 ; get message lngth in words mov R0, $msglgt ; put length in mailbox mov #4, $msgtype ; tell apt to take msg. br 5$ ; ; 3$: mov @4(SP), 4$ ; put msg addr in jsr linkage add #2, 4(SP) ; bump return address mov 177776, -(SP) ; push 177776 on stack jsr PC, $type ; call type macro 4$: .word 0 ; 5$: ; 10$: tstb $fflg ; should report fatal error? beq 12$ ; if not: br tst $env ; running under apt? beq 12$ ; if not: br 11$: tst $msgtype ; finished last message? bne 11$ ; if not: wait mov @4(SP), $fatal ; get error # add #2, 4(SP) ; bump return addr. inc $msgtype ; tell apt to take error 12$: clrb $fflg ; clear fatal flag clrb $lflg ; clear log flag clrb $mflg ; clear message flag mov (SP)+, R1 ; pop stack into R1 mov (SP)+, R0 ; pop stack into R0 rts PC ; return $mflg: .byte 0 ; messg. flag $lflg: .byte 0 ; log flag $fflg: .byte 0 ; fatal flag .even ; ; aptsize = 200 ; aptenv = 001 ; aptspool = 100 ; aptcsup = 040 ; .sbttl "BINARY TO ASCII AND TYPE ROUTINE" ;_____________________________________________________________________________ ; ; This routine is used to change a 16-bit binary number to a 16-bit ; binary-ascii number and type it. ; Call: ; mov number, -(SP) ; number to be typed ; typbn ; type it ; $typbn: mov R1, -(SP) ; save R1 on the stack mov 6(SP), R1 ; get the input number sec ; set "c" so can keep track of the number of bits 1$: movb #'0, $bin ; set character to an ascii "0". rol R1 ; get this bit beq 2$ ; done? adcb $bin ; no-set the character equal to this bit type , $bin ; go type this bit clc ; clear "c" so can keep track of bits br 1$ ; go do the next bit 2$: mov (SP)+, R1 ; pop the stack into R1 mov 2(SP), 4(SP) ; adjust the stack mov (SP)+, (SP) ; rti ; return to user ; $bin: .byte 0, 0 ; storage for ascii char. and terminator .sbttl "BINARY TO OCTAL (ASCII) AND TYPE" ;_____________________________________________________________________________ ; ; This routine is used to change a 16-bit binary number to a 6-digit ; octal (ascii) number and type it. ; $typos-enter here to setup suppress zeros and number of digits to type ; Call: ; mov num, -(SP) ; number to be typed ; typos ; call for typeout ; .byte n ; n=1 to 6 for number of digits to type ; .byte m ; m=1 or 0 ; ; 1=type leading zeros ; ; 0=suppress leading zeros ; $typon----enter here to type out with the same parameters as the last ; $typos or $typoc ; Call: ; mov num, -(SP) ; number to be typed ; typon ; call for typeout ; $typoc---enter here for typeout of a 16 bit number ; Call: ; mov num, -(SP) ; number to be typed ; typoc ; call for typeout ; $typos: mov @(SP), -(SP) ; pickup the mode movb 1(SP), $ofill ; load zero fill switch movb (SP)+, $omode+1 ; number of digits to type add #2, (SP) ; adjust return address br $typon ; $typoc: movb #1, $ofill ; set the zero fill switch movb #6, $omode+1 ; set for six(6) digits $typon: movb #5, $ocnt ; set the iteration count mov R3, -(SP) ; save R3 mov R4, -(SP) ; save R4 mov R5, -(SP) ; save R5 movb $omode+1, R4 ; get the number of digits to type neg R4 ; add #6, R4 ; subtract it for max. allowed movb R4, $omode ; save it for use movb $ofill, R4 ; get the zero fill switch mov 12(SP), R5 ; pickup the input number clr R3 ; clear the output word 1$: rol R5 ; rotate msb into "c" br 3$ ; go do msb 2$: rol R5 ; form this digit rol R5 ; rol R5 ; mov R5, R3 ; 3$: rol R3 ; get lsb of this digit decb $omode ; type this digit? bpl 7$ ; br if no bic #177770, R3 ; get rid of junk bne 4$ ; test for 0 tst R4 ; suppress this 0? beq 5$ ; br if yes 4$: inc R4 ; don't suppress anymore 0's bis #'0, R3 ; make this digit ascii 5$: bis #' , R3 ; make ascii if not already movb R3, 8$ ; save for typing type , 8$ ; go type this digit 7$: decb $ocnt ; count by 1 bgt 2$ ; br if more to do blt 6$ ; br if done inc R4 ; insure last digit isn't a blank br 2$ ; go do the last digit 6$: mov (SP)+, R5 ; restore R5 mov (SP)+, R4 ; restore R4 mov (SP)+, R3 ; restore R3 mov 2(SP), 4(SP) ; set the stack for returning mov (SP)+, (SP) ; rti ; return ; 8$: .byte 0 ; storage for ascii digit .byte 0 ; terminator for type routine $ocnt: .byte 0 ; octal digit counter $ofill: .byte 0 ; zero fill switch $omode: .word 0 ; number of digits to type .sbttl "CONVERT BINARY TO DECIMAL AND TYPE ROUTINE" ;_____________________________________________________________________________ ; ; This routine is used to change a 16-bit binary number to a 5-digit ; signed decimal (ascii) number and type it. Depending on whether the ; number is positive or negative a space or a minus sign will be typed ; before the first digit of the number. Leading zeros will always be ; replaced with spaces. ; Call: ; mov num, -(SP) ; put the binary number on the stack ; typds ; go to the routine ; $typds: mov R0, -(SP) ; push R0 on stack mov R1, -(SP) ; push R1 on stack mov R2, -(SP) ; push R2 on stack mov R3, -(SP) ; push R3 on stack mov R5, -(SP) ; push R5 on stack mov #20200, -(SP) ; set blank switch and sign mov 20(SP), R5 ; get the input number bpl 1$ ; br if input is pos. neg R5 ; make the binary number pos. movb #'-, 1(SP) ; make the ascii number neg. 1$: clr R0 ; zero the constants index mov #$dblk, R3 ; setup the output pointer movb #' , (R3)+ ; set the first character to a blank 2$: clr R2 ; clear the bcd number mov $dtbl(R0), R1 ; get the constant 3$: sub R1, R5 ; form this bcd digit blt 4$ ; br if done inc R2 ; increase the bcd digit by 1 br 3$ ; ; 4$: add R1, R5 ; add back the constant tst R2 ; check if bcd digit=0 bne 5$ ; fall through if 0 tstb (SP) ; still doing leading 0's? bmi 7$ ; br if yes 5$: aslb (SP) ; msd? bcc 6$ ; br if no movb 1(SP), -1(R3) ; yes-set the sign 6$: bis #'0, R2 ; make the bcd digit ascii 7$: bis #' , R2 ; make it a space if not already a digit movb R2, (R3)+ ; put this character in the output buffer tst (R0)+ ; just incrementing cmp R0, #10 ; check the table index blt 2$ ; go do the next digit bgt 8$ ; go to exit mov R5, R2 ; get the lsd br 6$ ; go change to ascii 8$: tstb (SP)+ ; was the lsd the first non-zero? bpl 9$ ; br if no movb -1(SP), -2(R3) ; yes-set the sign for typing 9$: clrb (R3) ; set the terminator mov (SP)+, R5 ; pop stack into R5 mov (SP)+, R3 ; pop stack into R3 mov (SP)+, R2 ; pop stack into R2 mov (SP)+, R1 ; pop stack into R1 mov (SP)+, R0 ; pop stack into R0 type , $dblk ; now type the number mov 2(SP), 4(SP) ; adjust the stack mov (SP)+, (SP) ; rti ; return to user ; $dtbl: .word 10000. ; .word 1000. ; .word 100. ; .word 10. ; $dblk: .blkw 4 ; .sbttl "SAVE AND RESTORE R0-R5 ROUTINES" ;_____________________________________________________________________________ ; ; Save R0-R5, call: ; ; savreg ; ; Upon return from $savreg the stack will look like: ; top---(+16) ; +2---(+18) ; +4----R5 ; +6----R4 ; +8----R3 ; +10---R2 ; +12---R1 ; +14---R0 ; $savreg: mov R0, -(SP) ; push R0 on stack mov R1, -(SP) ; push R1 on stack mov R2, -(SP) ; push R2 on stack mov R3, -(SP) ; push R3 on stack mov R4, -(SP) ; push R4 on stack mov R5, -(SP) ; push R5 on stack mov 22(SP), -(SP) ; save PSW of main flow mov 22(SP), -(SP) ; save PC of main flow mov 22(SP), -(SP) ; save PSW of call mov 22(SP), -(SP) ; save PC of call rti ; ;_____________________________________________________________________________ ; ; Restore R0-R5, call: ; ; resreg ; $resreg: mov (SP)+, 22(SP) ; restore PC of call mov (SP)+, 22(SP) ; restore PSW of call mov (SP)+, 22(SP) ; restore PC of main flow mov (SP)+, 22(SP) ; restore PSW of main flow mov (SP)+, R5 ; pop stack into R5 mov (SP)+, R4 ; pop stack into R4 mov (SP)+, R3 ; pop stack into R3 mov (SP)+, R2 ; pop stack into R2 mov (SP)+, R1 ; pop stack into R1 mov (SP)+, R0 ; pop stack into R0 rti ; .sbttl "DOUBLE LENGTH BINARY TO OCTAL ASCII CONVERT ROUTINE" ;_____________________________________________________________________________ ; ; This routine will convert a 32-bit unsigned binary number to an ; unsigned octal asciz number, call: ; ; mov #pntr, -(SP) ; pointer to low word of binary number ; jsr PC, @#$db20 ; call the routine ; rts PC ; the address of the first asciz char. is on the stack ; ; $db20: savreg ; save all registers mov 2(SP), R1 ; pickup the pointer to low word mov #$octvl+13., R5 ; pointer to data table mov #12., R4 ; do eleven characters mov #^c7, R3 ; mask mov (R1)+, R0 ; lower word mov (R1)+, R1 ; highword clr R2 ; terminator 1$: movb R2, -(R5) ; put character in data table mov R0, R2 ; get this digit dec R4 ; count this character bgt 3$ ; br if not the last digit beq 2$ ; br if it is the last digit inc R5 ; all digits done-adjust pointer for first mov R5, 2(SP) ; asciz char. & put it on the stack resreg ; restore all registers rts PC ; return to user 2$: asr R3 ; position the mask for the last digit 3$: ror R1 ; position the binary number for ror R0 ; the next octal digit ror R1 ; ror R0 ; ror R1 ; ror R0 ; bic R3, R2 ; mask out all junk add #'0, R2 ; make this char. ascii br 1$ ; go put it in the data table $octvl: .blkb 14. ; reserve data table .sbttl "TRAP DECODER" ;_____________________________________________________________________________ ; ; This routine will pickup the lower byte of the "trap" instruction ; and use it to index through the trap table for the starting address ; of the desired routine. Then using the address obtained it will ; go to that routine. ; $trap: mov R0, -(SP) ; save R0 mov 2(SP), R0 ; get trap address tst -(R0) ; backup by 2 movb (R0), R0 ; get right byte of trap asl R0 ; position for indexing mov $trpad(R0), R0 ; index to table rts R0 ; go to routine ; this is use handle the "getpri" macro $trap2: mov (SP), -(SP) ; move the PC down mov 4(SP), 2(SP) ; move the PSW down rti ; restore the PSW .sbttl "TRAP TABLE" ;_____________________________________________________________________________ ; ; This table contains the starting addresses of the routines called ; by the "trap" instruction routine ; $trpad: .word $trap2 ; $type ; call=type trap+1(104401) tty typeout routine $typoc ; call=typoc trap+2(104402) type octal number (with leading zeros) $typos ; call=typos trap+3(104403) type octal number (no leading zeros) $typon ; call=typon trap+4(104404) type octal number (as per last call) $typds ; call=typds trap+5(104405) type decimal number (with sign) $typbn ; call=typbn trap+6(104406) type binary (ascii) number $gtswr ; call=gtswr trap+7(104407) get soft-swr setting $ckswr ; call=ckswr trap+10(104410) test for change in soft-swr $rdchr ; call=rdchr trap+11(104411) tty typein character routine $rdlin ; call=rdlin trap+12(104412) tty typein string routine $savreg ; call=savreg trap+13(104413) save R0-R5 routine $resreg ; call=resreg trap+14(104414) restore R0-R5 routine ; type = trap+1 ; (104401) tty typeout routine typoc = trap+2 ; (104402) type octal number (with leading zeros) typos = trap+3 ; (104403) type octal number (no leading zeros) typon = trap+4 ; (104404) type octal number (as per last call) typds = trap+5 ; (104405) type decimal number (with sign) typbn = trap+6 ; (104406) type binary (ascii) number .if ne INSWR ; gtswr = 240 ; nop .iff ; gtswr = trap+7 ; (104407) get soft-swr setting .endc ; ckswr = trap+10 ; (104410) test for change in soft-swr rdchr = trap+11 ; (104411) tty typein character routine rdlin = trap+12 ; (104412) tty typein string routine savreg = trap+13 ; (104413) save R0-R5 routine resreg = trap+14 ; (104414) restore R0-R5 routine .sbttl "POWER DOWN AND UP ROUTINES" ;_____________________________________________________________________________ ; ; Power down routine ; $pwrdn: mov #$illup, @#pwrvec ; set for fast up mov #340, @#pwrvec+2 ; prio 7 mov R0, -(SP) ; push R0 on stack mov R1, -(SP) ; push R1 on stack mov R2, -(SP) ; push R2 on stack mov R3, -(SP) ; push R3 on stack mov R4, -(SP) ; push R4 on stack mov R5, -(SP) ; push R5 on stack mov @swr, -(SP) ; push @swr on stack mov SP, $savSP ; save SP mov #$pwrup, @#pwrvec ; set up vector halt ; br .-2 ; hang up ;_____________________________________________________________________________ ; ; Power up routine ; $pwrup: mov #$illup, @#pwrvec ; set for fast down mov $savSP, SP ; get SP clr $savSP ; wait loop for the tty 1$: inc $savSP ; wait for the inc bne 1$ ; of word mov (SP)+, @swr ; pop stack into @swr mov (SP)+, R5 ; pop stack into R5 mov (SP)+, R4 ; pop stack into R4 mov (SP)+, R3 ; pop stack into R3 mov (SP)+, R2 ; pop stack into R2 mov (SP)+, R1 ; pop stack into R1 mov (SP)+, R0 ; pop stack into R0 mov #$pwrdn, @#pwrvec ; set up the power down vector mov #340, @#pwrvec+2 ; prio: 7 type ; report the power failure $pwrmg: .word pwrmsg ; power fail message pointer mov (PC)+, (SP) ; restart at start $pwrad: .word start ; restart address bic #20, 2(SP) ; clear "T"-bit clr $tbit ; clear the "T"-bit flag rti ; ; $illup: halt ; the power up sequence was started br .-2 ; before the power down was complete $savSP: .word 0 ; put the SP here ;_____________________________________________________________________________ ; pwrmsg: .asciz <12><15>/ POWER FAILURE - RESTARTING /<12><15> .even .sbttl "ERROR MESSAGES, DATA HEADERS-TABLES & FORMATS" em1: .asciz /UNEXPECTED CPU TRAP TO LOC. 004/ em2: .asciz /UNEXPECTED MEM. MGMT. TRAP TO LOC. 250/ em3: .asciz /PRIORITY BITS SET WRONG IN PSW/ em4: .asciz /MODE BITS SET WRONG IN PSW/ em5: .asciz /DUAL ADDRESSING BETWEEN HI&LO BYTES OF PSW/ em6: .asciz /KERNEL R6 CHANGED BY WRITING USER R6/ em7: .asciz /A MEMORY MGMT. REG. TIMED OUT/ em10: .asciz /SUMMARY OF MEM. MGMT. REG. TIMEOUTS/ em11: .asciz /MEM. MGMT. REG. WOULD NOT CLEAR/ em12: .asciz /MEM. MGMT. REG. BITS NOT SET CORRECTLY/ em13: .asciz /SR0 EFFECTED BY WRITE TO PSW/ em14: .asciz /SR1 DID NOT READ ALL ZEROS/ em15: .asciz /DUAL ADDRESSING BETWEEN BYTES OF PAR OR PDR/ em16: .asciz /DUAL ADDRESSING BETWEEN PAR-PDR'S/ em17: .asciz /PHYS. ADDR. FORMED WRONG IN MAINT. MODE/ em20: .asciz /PHYS. ADDR. FORMED WRONG IN RELOCATE MODE/ em21: .asciz /W-BIT DID NOT GET SET IN PDR/ em22: .asciz /W-BIT SET IN MORE THAN ONE PDR/ em23: .asciz /W-BIT NOT CLEARED BY WRITING TO PDR/ em24: .asciz /WRITING SR0 SET W-BIT IN KIPDR7/ em25: .asciz /W-BIT GOT SET DURING ODD ADDR. ABORT/ em26: .asciz /MEMORY MGMT. ACCESS ABORT DID NOT OCCUR/ em27: .asciz /ACCESS ERROR DID NOT ABORT INSTRUCTION/ em30: .asciz /SR0 DID NOT REPORT ACCESS ERROR CORRECTLY/ em31: .asciz /DID NOT LOCKUP CORRECT VIRTUAL ADDR./ em32: .asciz /PAGE LGTH. ABORT OCCURRED WHEN IT SHOULDN'T HAVE/ em33: .asciz /PAGE LGTH. ABORT DID NOT OCCUR WHEN IT SHOULD HAVE/ em34: .asciz /SR0 DID NOT REPORT PAGE LGTH. ABORT CORRECTLY/ em37: .asciz /SR0 OR SR2 CHANGED BY A SECOND ABORT/ em40: .asciz /SR0 OR SR2 WERE NOT "RESET" BY A RESET/ em41: .asciz /SR2 NOT TRACKING CORRECTLY/ em42: .asciz /DID NOT TRAP THRU KERNEL SPACE/ em43: .asciz /KT ERROR SERVICED ON ODD ADDR. ERROR/ em44: .asciz /SR0 OR SR2 CHANGED BY ODD ADDR. ERROR/ em45: .asciz /ERROR DURING "DOUBLE ERROR" (KT & ODD ADDR.)/ em46: .asciz /MFPI INSTRUCTION PUSHED WRONG DATA/ em47: .asciz /MTPI INSTRUCTION LOADED WRONG DATA/ em50: .asciz /STACK NOT PUSHED BY MFPI-MTPI/ em51: .asciz /KERNEL PAGE ACCESS INSTEAD OF USER: MFPI-MTPI/ em52: .asciz /WRONG PDR'S REFERENCED WHILE IN RELOCATE MODE/ em53: .asciz /MFPD INSTRUCTION PUSHED WRONG DATA/ em54: .asciz /STACK NOT PUSHED BY MFPD-MTPD/ em55: .asciz /PAR OR PDR CHANGED BY A RESET/ em56: .asciz /ILLEGAL MODE 01 NOT ABORTED/ em57: .asciz /SR0 DID NOT REPORT ILLEGAL MODE 01 CORRECTLY/ em60: .asciz /PSW CHANGED BY AN RTI IN USER MODE/ em61: .asciz /MAINT. MODE (SR0 <8>) NOT DISABLED BY A RESET/ em62: .asciz /DATA INCORRECT AFTER A MAINT. MODE WRITE/ em63: .asciz /SOURCE RELOCATED IN MAINT. MODE/ em64: .asciz /NON RESIDENT ABORT DID NOT OCCUR/ em65: .asciz /ERROR FLAG FOR NR ABORT (BIT15) IN SR0 DID NOT SET/ em66: .asciz /SR2 DID NOT FREEZE THE VIRTUAL ADDRS OF THE ABORTD INTR/ em67: .asciz /2ND NON RESIDENT ABORT DID NOT OCCUR/ em70: .asciz /2ND NON RESIDENT ABORT CAUSED SR2 TO CHANGE/ em71: .asciz /SR0 WAS NOT CLEARED BY INIT. / dh1: .asciz /OLD PC OLD PSW R6 WAS TESTNO ERRORPC/ dh2: .asciz /OLD PC OLD PSW R6 WAS SR0 SR2 TESTNO ERRORPC/ dh3: .asciz /WROTE READ TESTNO ERRORPC/ dh7: .asciz /ADDRESS TESTNO ERRORPC/ dh10: .ascii /REGISTER-ADDRS NUM OF/ .asciz /AND-ED OR-ED TIMOUTS TESTNO ERRORPC/ dh11: .ascii /REGISTR READ READ-(BINARY)/ .asciz /ADDRESS (OCTAL) 5432109876543210 TESTNO ERRORPC/ dh12: .ascii /REGISTR WROTE READ READ-(BINARY)/ .asciz /ADDRESS (OCTAL) (OCTAL) 5432109876543210 TESTNO ERRORPC/ dh13: .asciz /READ TESTNO ERRORPC/ dh16: .ascii /PAR-PDR PAR-PDR/ .asciz /CLEARED EFFECTD EXPECTD RECEIVD TESTNO ERRORPC/ dh17: .ascii /PHYSICL VIRTUAL/ .asciz /ADDRESS ADDRESS KIPAR4 TESTNO ERRORPC/ dh20: .ascii /PHYSICL PAR 4 PAR 5/ .asciz /ADDRESS VBA VBA PAR 4 PAR 5 PSW TESTNO ERRORPC/ dh21: .ascii /PDR VIRTUAL/ .asciz /TESTED ADDRESS TESTNO ERRORPC/ dh22: .ascii /PDR IN PDR VIRTUAL/ .asciz /ERROR TESTED ADDRESS TESTNO ERRORPC/ dh23: .asciz /PDR TESTNO ERRORPC/ dh24: .asciz /PDR WAS EXPECTD TESTNO ERRORPC/ dh26: .asciz /PDR 4 PSW TESTNO ERRORPC/ dh30: .asciz /SR0 WAS EXPECTD PDR 4 PSW TESTNO ERRORPC/ dh31: .asciz /SR2 WAS EXPECTD PDR 4 PSW TESTNO ERRORPC/ dh32: .asciz /V.B.A. KIPDR4 SR0 WAS SR2 WAS TESTNO ERRORPC/ dh33: .asciz /V.B.A. KIPDR4 TESTNO ERRORPC/ dh34: .asciz /V.B.A. KIPDR4 SR0 WAS EXPECTD TESTNO ERRORPC/ dh35: .asciz /V.B.A. KIPDR4 SR2 WAS EXPECTD TESTNO ERRORPC/ dh36: .asciz /SR2 WAS EXPECTD TESTNO ERRORPC/ dh37: .ascii /FIRST ABORT SECOND ABORT/ .asciz /SR0 WAS SR2 WAS SR0 WAS SR2 WAS TESTNO ERRORPC/ dh40: .asciz /SR0 WAS SR2 WAS TESTNO ERRORPC/ dh42: .asciz /PSW WAS R6 WAS TESTNO ERRORPC/ dh44: .ascii /EXPECTED RECEIVED/ .asciz /SR0 SR2 SR0 WAS SR2 WAS TESTNO ERRORPC/ dh45: .ascii /EXPECTED:/ .ascii /PSW PC SR0 SR2/ .ascii /170017 (3$+4) 020147 (3$)/ .ascii /RECEIVED:/ .asciz /PSW PC SR0 SR2 TESTNO ERRORPC/ dh46: .ascii /DATA DATA/ .asciz /EXPECTD RECEIVD TESTNO ERRORPC/ dh50: .asciz /TESTNO ERRORPC/ dh51: .asciz /SR0 WAS SR2 WAS TESTNO ERRORPC/ dh52: .ascii /PHYSICL PAR 4/ .asciz /ADDRESS V.B.A. PAR 4 SR0 WAS SR2 WAS PSW TESTNO ERRORPC/ dh57: .asciz /SR0 WAS EXPECTD TESTNO ERRORPC/ dh60: .asciz /PSW WAS EXPECTD TESTNO ERRORPC/ dh61: .asciz /SR0 SR2 TESTNO ERRORPC/ dh62: .asciz /SR2 EXP SR2 REC TESTNO ERRORPC/ dh63: .asciz /SR0 EXP SR0 REC TESTNO ERRORPC/ .even dt1: .word trappc, trapps, wasSP, testno, $errpc, 0 dt2: .word trappc, trapps, wasSP, wassr0, wassr2, testno, $errpc, 0 dt3: .word $reg0, $reg1, testno, $errpc, 0 dt7: .word $reg0, testno, $errpc, 0 dt10: .word andadr, oradr, tonum, testno, $errpc, 0 dt11: .word $reg0, $reg1, $reg1, testno, $errpc, 0 dt12: .word $reg0, $reg1, $reg2, $reg2, testno, $errpc, 0 dt13: .word $reg0, testno, $errpc, 0 dt16: .word $reg0, $reg1, $reg5, $reg2, testno, $errpc, 0 dt17: .word pbalo, virt1, $reg4, testno, $errpc, 0 dt20: .word pbalo, virt1, virt2, $reg4, $reg5, $tmp0, testno, $errpc, 0 dt21: .word $reg5, $reg3, testno, $errpc, 0 dt22: .word $reg0, $reg5, $reg3, testno, $errpc, 0 dt23: .word $reg5, testno, $errpc, 0 dt24: .word $reg2, $reg1, testno, $errpc, 0 dt26: .word $reg2, $tmp0, testno, $errpc, 0 dt30: .word wassr0, $reg3, $reg2, $tmp0, testno, $errpc, 0 dt31: .word wassr2, $reg4, $reg2, $tmp0, testno, $errpc, 0 dt32: .word $reg0, $reg4, wassr0, wassr2, testno, $errpc, 0 dt33: .word $reg0, $reg4, testno, $errpc, 0 dt34: .word $reg0, $reg4, wassr0, $reg2, testno, $errpc, 0 dt35: .word $reg0, $reg4, wassr2, $reg3, testno, $errpc, 0 dt36: .word wassr2, $reg1, testno, $errpc, 0 dt37: .word $tmp0, $tmp2, wassr0, wassr2, testno, $errpc, 0 dt40: .word wassr0, wassr2, testno, $errpc, 0 dt42: .word $reg1, $reg2, testno, $errpc, 0 dt44: .word $reg0, $reg1, wassr0, wassr2, testno, $errpc, 0 dt45: .word $reg1, $reg3, wassr0, wassr2, testno, $errpc, 0 dt46: .word $reg0, $reg1, testno, $errpc, 0 dt50: .word testno, $errpc, 0 dt51: .word wassr0, wassr2, testno, $errpc, 0 dt52: .word pbalo, virt1, $reg4, wassr0, wassr2, $tmp0, testno, $errpc, 0 dt57: .word wassr0, $reg1, testno, $errpc, 0 dt60: .word $reg1, $reg2, testno, $errpc, 0 dt64: .word wassr2, $reg4, testno, $errpc, 0 dt65: .word wassr0, wassr2, testno, $errpc, 0 dt66: .word corsr2, wassr2, testno, $errpc, 0 dt67: .word corsr0, wassr0, testno, $errpc, 0 df1: .byte 0, 0, 0, 0, 0 df2: .byte 0, 0, 0, 0, 0, 0, 0 df3: .byte 0, 0, 0, 0 df7: .byte 0, 0, 0 df10: .byte 0, 0, 1, 0, 0 df11: .byte 0, 0, 2, 0, 0 df12: .byte 0, 0, 0, 2, 0, 0 df13: .byte 0, 0, 0 df16: .byte 0, 0, 0, 0, 0, 0 df17: .byte 3, 0, 0, 0, 0 df20: .byte 3, 0, 0, 0, 0, 0, 0, 0 df21: .byte 0, 0, 0, 0 df22: .byte 0, 0, 0, 0, 0 df23: .byte 0, 0, 0 df24: .byte 0, 0, 0, 0 df30: .byte 0, 0, 0, 0, 0, 0 df46: .byte 0, 0, 0, 0 df50: .byte 0, 0 df51: .byte 0, 0, 0, 0 df52: .byte 3, 0, 0, 0, 0, 0, 0, 0 df57: .byte 0, 0, 0, 0 df60: .byte 0, 0, 0, 0 df61: .byte 0, 0, 0, 0 ;_____________________________________________________________________________ ; .end