; Originally was compiled with MACY-11, an assembler running on the PDP-10. ; The source is modifiedd to be translated with regular MACRO-11. ; ; IDENTIFICATION ; -------------- ; Product code: AC-F138D-MC ; Product name: CJKDAD0 KTF11-AA memory management diagnostic ; Date: Jan-81 ; Maintainer: Diagnostic Programming ; ; 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) 1979, 1981 Digital Equipment Corp., Maynard, Mass. 01754 ; ; Program history ; ; Date Revision Reason for revision ; ; January, 1979 A First release. This program was assembled ; using the PDP-11 maindec sysmac package ; (maindec-11-dzqac-c3), Jan 19, 1977. ; June, 1979 B Subroutine formpa modified error ; information stored in R0, R2. This ; revision saves the registers on ; entry to the routine and restores ; them on exit. ; November, 1979 C Corrections were made to the multi- ; tester support code. Also code was ; added to allow program operation while ; line clock is interrupting. ; January, 1981 D Expanded "read and write while in relocate ; mode" test to allow up to 1.92mw of memory ; to be tested. Corrected bugs in the ; "relocation and adder" tests to allow ; 22-bit addressing to be turned on ard tested. ; Removed reset instructon from tests ; where they were not required. Put in ; code to skip tests after first pass in ; APT mode that required resets for testing. ; ; 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 ; 5.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 ; 4.6 Relocation throughout memory ; ; 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 KDF11 processor with a minimum of 16k 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. PDP11 maindec sysmac package ; 5. XXDP user's manual ; ; 1.4 Preliminary programs ; ; Before this memory management diagnostic is run. the ; following CPU diagnostic should be run: ; ; CJKDB DCF11-AA CPU 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. Since 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) ; ; 2.3 Control switch settings ; ; Switch octal value 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 ; ; ; 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 ; swtich 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 30 seconds. ; ; 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 "slperr". After reporting ; the error. "slperr" 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 loaction ; 022060. The "registr address" tells us that we were ; testing memory management's status rgister 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 nlmber and number of errors are decimal numbers. ; ; 4.3 T-bit +rapping ; ; 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 "restrt:" ; ; 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 ; 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 ; ------------------------------------------------------------------- ; / 0 0 0 0 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 01 (bit 15) selects the user (=1) or ; kernel (=0) set of par's/pdr's ; ; 4.6 Relocation throughout memory ; ; A feature was added to allow the construction of physical ; bus addresses above the normal 16k limit. The setting ; of the location $madr1 in the e-table with one of the ; following constants will access locations between 60000 and ; 67600 of each 16k group up to the maximum memory on the system. ; The first location of each block(32 words) is written and read. ; See test #25 in the listing for more details. ; ; const. max. mem. const. max. mem. const. max. mem. ; ------ ---------- ------ --------- ------ ---------- ; 0/600 16k 50600 656k 120600 1296k ; 1600 32k 51600 672k 121600 1312k ; 2600 48k 52600 688k 122600 1328k ; 3600 64k 53600 704k 123600 1344k ; 4600 80k 54600 720k 124600 1360k ; 5600 96k 55600 736k 125600 1376k ; 6600 112k 56600 752k 126600 1392k ; 7600 128k 57600 768k 127600 1408k ; 10600 144k 60600 784k 130600 1424k ; 11600 160k 61600 800k 131600 1440k ; 12600 176k 62600 816k 132600 1456k ; 13600 192k 63600 832k 133600 1472k ; 14600 208k 64600 848k 134600 1488k ; 15600 224k 65600 864k 135600 1504k ; 16600 240k 66600 880k 136600 1520k ; 17600 256k 67600 896k 137600 1536k ; 20600 272k 70600 912k 140600 1552k ; 21600 288k 71600 928k 141600 1568k ; 22600 304k 72600 944k 142600 1584k ; 23600 320k 73600 960k 143600 1600k ; 24600 336k 74600 976k 144600 1616k ; 25600 352k 75600 992k 145600 1632k ; 26600 368k 76600 1008k 146600 1648k ; 27600 384k 77600 1024k 147600 1664k ; 30600 400k 100600 1040k 150600 1680k ; 31600 416k 101600 1056k 151600 1696k ; 32600 432k 102600 1072k 152600 1712k ; 33600 448k 103600 1088k 153600 1728k ; 34600 464k 104600 1104k 154600 1744k ; 35600 480k 105600 1120k 155600 1760k ; 36600 496k 106600 1136k 156600 1776k ; 37600 512k 107600 1152k 157600 1702k ; 40600 528k 110600 1168k 160600 1808k ; 41600 544k 111600 1184k 161600 1824k ; 42600 560k 112600 1200k 162600 1840k ; 43600 576k 113600 1216k 163600 1856k ; 44600 592k 114600 1232k 164600 1872k ; 45600 608k 115600 1248k 165600 1888k ; 46600 624k 116600 1264k 166600 1904k ; 47600 640k 117600 1280k 167600 1920k ; ; 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 ; 2. Turn on T-bit and restore previous psw ; 3. Set all writeable bits in all par/pdr's ; 4. Pead 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 09 ; 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 VM3FX = 0 ; fixes for VM3 SKIP = 0 ; skip/minimize prints ;_____________________________________________________________________________ ; .asect ; . = 0 ; loop on test .title CJKDAD0 KTF11-AA MMU DIAG. .nlist cnd, mc, md ; .list me ; ;_____________________________________________________________________________ ; .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" ; stack = 1100 ; initial address of the stack pointer *** 1100 *** ; .equiv emt, error - basic definition of error call .if ne NOSCO ; scope = 240 ; nop .iff ; scope = iot ; .equiv iot, scope - basic definition of scope call .endc ; ; miscellaneous definitions 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 ; stklmt = 177774 ; stack limit register pirq = 177772 ; program interrupt request register dswr = 177570 ; hardware switch register ddisp = 177570 ; hardware display register type = 104401 ; trap+1 tty typeout routine typoc = 104402 ; trap+2 type octal number (with leading zeros) typos = 104403 ; trap+3 type octal number (no leading zeros) typon = 104404 ; trap+4 type octal nlmber (as per last call) typds = 104405 ; trap+5 type decimal number (with sign) typbn = 104406 ; trap+6 type binary (ascii) number .if ne INSWR ; gtswr = 240 ; nop .iff ; gtswr = 104407 ; trap+7 get soft-swr setting .endc ; ckswr = 104410 ; trap+10 test for change in soft-swr rdchr = 104411 ; trap+11 tty type in character routine rdlin = 104412 ; trap+12 tty typein string routine savreg = 104413 ; trap+13 save R0-R5 routine resreg = 104414 ; trap+14 restore R0-R5 routine ; ; general purpose register definitions R0 = %0 ; general register R1 = %1 ; general register R2 = %2 ; general register R3 = %3 ; general register R4 = %4 ; general register R5 = %5 ; general register R6 = %6 ; general register R7 = %7 ; general register SP = %6 ; stack pointer PC = %7 ; program counter ; ; priority level definitions pr = 0 ; priority level 0 pr1 = 40 ; priority level 1 pr2 = 100 ; priority level 2 pr3 = 140 ; priority level 3 pr4 = 200 ; priority level 4 pr5 = 240 ; priority level 5 pR6 = 300 ; priority level 6 pR7 = 340 ; priority level 7 ; sw15 = 100000 ; "switch register" switch definitions sw14 = 40000 ; sw13 = 20000 ; sw12 = 10000 ; sw11 = 4000 ; sw10 = 2000 ; sw9 = 1000 ; sw8 = 400 ; sw7 = 200 ; sw6 = 100 ; sw5 = 40 ; sw4 = 20 ; sw3 = 10 ; sw2 = 4 ; sw1 = 2 ; sw0 = 1 ; ; bit15 = 100000 ; data bit definitions (bit0 to bit15) bit14 = 40000 ; bit13 = 20000 ; bit12 = 10000 ; bit11 = 4000 ; bit10 = 2000 ; bit9 = 1000 ; bit8 = 400 ; bit7 = 200 ; bit6 = 100 ; bit5 = 40 ; bit4 = 20 ; bit3 = 10 ; bit2 = 4 ; bit1 = 2 ; bit0 = 1 ; ; 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 ; sr0 = 177572 ; KT11 status register addresses sr1 = 177574 ; sr2 = 177576 ; sr3 = 172516 ; ; uipdr0 = 177600 ; user "I" page descriptor registers uipdr1 = 177602 ; uipdr2 = 177604 ; uipdr3 = 177606 ; uipdr4 = 177610 ; uipdr5 = 177612 ; uipdR6 = 177614 ; uipdR7 = 177616 ; ; uipar0 = 177640 ; user "I" page address registers uipar1 = 177642 ; uipar2 = 177644 ; uipar3 = 177646 ; uipar4 = 177650 ; uipar5 = 177652 ; uipar6 = 177654 ; uipar7 = 177656 ; ; kipdr0 = 172300 ; kernel "I" page descriptor registers kipdr1 = 172302 ; kipdr2 = 172304 ; kipdr3 = 172306 ; kipdr4 = 172310 ; kipdr5 = 172312 ; kipdr6 = 172314 ; kipdr7 = 172316 ; ; kipar0 = 172340 ; kernel "I" page address registers kipar1 = 172342 ; kipar2 = 172344 ; kipar3 = 172346 ; kipar4 = 172350 ; kipar5 = 172352 ; kipar6 = 172354 ; kipar7 = 172356 ; ; ksp = SP ; .equiv SP, ksp usp = SP ; .equiv SP, usp tbit = bit4 ; .equiv bit4, tbit wbit = bit6 ; .equiv bit6, wbit 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)" . = 200 ; 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 14 ; run tim of longest test $pastm: .word 20 ; run time in secs. of 1st pass on 1 unit (quick verify) $unitm: .word 5 ; additional runtime (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 ; ;_____________________________________________________________________________ ; .sbttl "COMMON TAGS" ; This table contains various common storage locations ; used in the program. . = 1100 ; $cmtag: ; start of common tags .word 0 ; $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: 177560 ; tty kbd status $tkb: 177562 ; tty kbd buffer $tps: 177564 ; tty printer status reg. address $tpb: 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 ; "terminal available" flag (bit<07>=0 - yes) $regad: .word 0 ; contains the address from ; which ($reg0) was obtained $reg0: .word 0 ; contains (($rfgad)+0) $reg1: .word 0 ; contains (($regad)+2) $reg2: .word 0 ; contains (($regad)+4) $reg3: .word 0 ; contains ((sregad)+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: 0 ; max. number of iterations $escape: 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 $xoff = 23 ; $xon = 21 ; ;_____________________________________________________________________________ ; .sbttl "APT MAILBOX-ETABLE" .even ; $mail: ; APT mailbox $msgty: .word 0 ; amsgty - message type code $fatal: .word 0 ; afatal - fatal error number $testn: .word 0 ; atestn - test number $pass: .word 0 ; apass - pass count $devct: .word 0 ; adevct - device count $unit: .word 0 ; aunit - I/O unit number $msgad: .word 0 ; amsgad - message address $msglg: .word 0 ; amsglg - message length $etable: ; APT environment table $env: .byte 0 ; aenv - environment byte $envm: .byte 0 ; aenvm - environment mode bits $swreg: .word 0 ; aswreg - APT switch register $uswr: .word 0 ; auswr - user switches $cpuop: .word 0 ; acpuop - 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 ; amams1 - high address, m.s. byte $mtyp1: .byte 0 ; amtyp1 - mem. type, blk#1 ; mem. type byte - (high byte) ; 900 nsec core=001 ; 300 nsec bipolar=002 ; 500 nsec mos=003 $madr1: .word 0 ; amadr1 - high address, blk#1 ; mem. last addr.=3 bytes, $etend: ; this word and low of "type" above ; testno: .word 0 ; holds test number for typeouts wasr6: .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 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 $errpo. ; 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 R6 was testno errorpc dt1 ; trappc, trapps, wasr6, testno, $erppc, 0 df1 ; 0, 0, 0, 0, 0 ; item 2 em2 ; unexpected mem. mgmt. trap to loc. 250 dh2 ; old PC old psw R6 was sr0 sr2 testno errorpc dt2 ; trappc, trapps, wasr6, 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 pead testno errorpc dt3 ; $reg0, $reg1, testno, $errpc, 0 df3 ; 0, 0, 0, 0 ; item 6 em6 ; kernel R6 changed by writing user R6 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 10 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 dh17 ; physical virtual ; address address kipar4 testno errorpc dt17 ; pbalo, irt1, $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 timeout 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 ; wassp2, $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 wassr2 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 R6 was testno errorpc dt42 ; $reg1, $reg2, testno, $errpc, 0 df24 ; 0, 0, 0, 0 ; item 43 em43 ; kt error not serviced on timeout error dh23 ; pdr testno errorpc dt23 ; $reg5, testno, $errpc, 0 df23 ; 0, 0, 0 ; item 44 em44 ; sr0 or sr2 changed by timeout 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, 0 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 ; pbal0, 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) 5432109876543210 testno errorpc dt11 ; $reg0, $rfg1, $reg1, testno, $errpc, 0 df11 ; 0, 0, 2, 0, 0 ; item 56 em56 ; psw changed by an rti in user mode dh56 ; psw was expectd testno errorpc dt56 ; $reg1, $reg2, testno, $errpc, 0 df56 ; 0, 0, 0, 0 ;_____________________________________________________________________________ ; .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 inc @#$msgtype ; tell APT there was an error 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, @#wasr6 ; save stack pointer value emt +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 inc @#$msgtype ; tell APT there was an error 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, @#wasr6 ; 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 emt +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 ; start: ; .sbttl "INITIALIZE THE COMMON TAGS" ; clear the common tags ($cmtag) area mov #$cmtag, R6 ; first location to be cleared clr (R6)+ ; clear memory location cmp #swr, R6 ; done? bne .-6 ; loop back if no mov #stack, SP ; setup the stack pointer ; ; initialize 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 ; initialize 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 ps 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 ; ; initialize the error counter for eop report ($erttl). ; 70$: clr @#$erttl ; clear error counter .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 72$: .if ne VM3FX .if ne SKIP .asciz <15><0><0><0><0><0><0><0> .iff .asciz /CJKDAD0/ .endc .iff .asciz /CJKDAD0 KTF11-AA MMU DIAG./ .endc ; .even ; 71$: ; restrt: ; 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 management 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 emt +3 ; priority bits set wrong in psw ; for tighter scope loop ; replace error call with ; "br 2$" = 000770 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" ; tst2: scope ; 1$: mov #2$, @#$lperr ; set loop on error pointer to 2$ clr R0 ; initialize R0 with mode bits = 0000 2$: clr @#ps ; initialize psw bis R0, @#ps ; bit set the psw mode bits with R0 mov @#ps, 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 @#ps ; clear psw for error report emt +4 ; mode bits set wrong in psw ; for tighter scope loop ; replace error call with ; "br 2$" = 000763 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 @#ps ; 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. ; tst3: scope ; 1$: mov #2$, @#$lperr ; set loop on error pointer to 2$ 2$: clr @#ps ; clear the psw mov #360, R0 ; put the high byte data into R0 movb R0, @#ps+1 ; write the high byte of the psw mov @#ps, 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 @#ps ; clear psw for error report emt +5 ; low byte effected by write to high byte of psw ; for tighter scope loop ; replace error call with ; "br 2$" = 000760 3$: mov #4$, @#$lperr ; set loop on error pointer to 4$ 4$: clr @#ps ; clear the psw mov #340, R0 ; put the low byte data into R0 movb R0, @#ps ; write the low byte of the psw mov @#ps, 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 @#ps ; clear psw for error report emt +5 ; high byte effected by write to low byte of psw ; for tighter scope loop ; replace error call with ; "br 2$" = 000736 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 R6 is set to 1100, user R6 is set to 700, then ; kernel R6 is read to be sure its still 1100. ; tst4: scope ; clr @#ps ; go to kernel mode mov #kerstk, ksp ; set kernel stack pointer to 1100 mov #140000, @#ps ; go to user mode mov #usestk, usp ; set user stack pointer to 700 clr @#ps ; back to kernel mode cmp #kerstk, ksp ; is kernel R6 still 1100? beq tst5 ; branch if kernel R6 is okay mov #kerstk, R0 ; save data written for error report mov ksp, R1 ; save data read after user R6 was written emt +6 ; kernel R6 changed by writing user R6 ; for tighter scope loop ; replace error call with ; 000756 ;_____________________________________________________________________________ ; ; The next five (5) tests will try to address all of the ; memory management registers (sr0, sr1, sr2, sr3, 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, sr3 timeout test ; This test addresses the memory management status registers ; 0, 1, 2, and 3. 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 "dr" 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 tst @#172516 ; check sr3 for response ; if it times out go to 5$ 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 emt +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 emt +7 ; one of the status regs. timed out ; for tighter scope loop ; replace error call with ; "br 2$" = 000756 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 emt +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 emt +7 ; one of the kipars timed out ; for tighter scope loop ; replace error call with ; "br 2$" = 000756 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 emt +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 emt +7 ; one of the kipdrs timed out ; for tighter scope loop ; replace error call with ; "br 2$" = 000756 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 ; nitialize "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 ponter to 1$ tst @#tonum ; did any of the uipars time out? beq 4$ ; branch if no emt +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 emt +7 ; one of the uipars timed out ; for tighter scope loop ; replace error call with ; "br 2$" = 000756 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-u1pdr7) 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 emt +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 emt +7 ; one of the uipdrs timed out ; for tighter scope loop ; replace error call with ; "br 2$" = 000756 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. ; The rest of 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" emt +11 ; sr0<15:13> not cleared by a "reset" ; for tighter scope loop ; replace error call with ; "br 1$" = 000770 2$: mov #2$, @#$lperr ; set loop on error pointer to 2$ 8$: mov @#sr2, @#wassr2 ; read contents of sr2 mov #8$, R1 ; load expected contents into R1 cmp R1, @#wassr2 ; is sr2 tracking? beq 3$ ; branch if yes emt +41 ; sr2 not "tracking" virtual addresses ; for tighter scope loop ; replace error call with ; "br 2$" = 000767 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 emt +12 ; bits were set wrong in sr0 ; for tighter scope loop ; replace error call with ; "br 4$" = 000772 6$: mov #5$, R4 ; load expected contents of sr2 in R4 mov @#sr2, @#wassr2 ; read sr2 cmp R4, @#wassr2 ; did sr2 lock up when error ; bit set in sri? beq 7$ ; branch if yes emt +64 ; sr2 did not lock up ; for tighter scope loop ; replace error call with ; "br 4$" = 000761 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 @#ps ; 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 emt +13 ; sr0 effected by a write to the psw ; for tighter scope loop ; replace error call with ; "br 1$" = 000767 2$: clr @#sr0 ; be sure sr0 is 0 before leaving clr @#ps ; be sure psw is 0 before leaving ;_____________________________________________________________________________ ; ; TEST 14 - test that sr1 reads all zeros ; This tests checks that status register 1 ; responds with all zeros, and that only bits<5:4> ; of status register 3 are writeable. ; tst14: scope ; 1$: mov #-1, R0 ; fill R0 with all ones mov @#sr1, R0 ; read sr1 into R0 beq 2$ ; branch if sr1 reads all zeros emt +14 ; sr1 did not read all zeros ; for tighter scope loop ; replace error call with ; 000772 2$: mov #-1, @#sr3 ; try to write ones to sr3 .if ne VM3FX ; cmp #177777, @#sr3 ; all bits should be ones on VM3 .iff ; cmp #60, @#sr3 ; only bits <5:4> should be ones .endc ; beq 3$ ; emt +12 ; didn't read back a "60" 3$: tstb @#$env ; test APT environment bit beq 6$ ; if clear, not on APT so do test tst @#$pass ; if on APT test pass counter beq 6$ ; if clear, first pass so do test clr @#sr3 ; if on APT and not first pass fudge test br 7$ ; 6$: reset ; clears sr3 7$: ; .if ne VM3FX ; cmp #177717, @#sr3 ; .iff ; tst @#sr3 ; verify that it was cleared .endc ; 4$: ; beq tst15 ; branch if sr3 read all zeros emt +12 ; sr3 didn't read all zeros ;_____________________________________________________________________________ ; ; TEST 15 - bit test of kernel & user par's ; The following test checks the bits <15:00> of both the kernel ; and user page address registers. A "0" is rotated thru ; the registers from left to right. ; tst15: scope ; .if ne VM3FX ; mov #20, @#sr3 ; .endc ; 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 emt +11 ; par would not clear ; for tighter scope loop ; replace error call with ; "br 3$" = 000774 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 par before loading data bis R4, (R0) ; bit set the test pattern into the par mov (R0), R2 ; read the par into R2 cmp R4, R2 ; does data written=data read? beq 6$ ; branch if yes mov R4, R1 ; setup for error reporting emt +12 ; par bits did not set correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000767 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. ; 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 emt +11 ; pdr would not clear ; for tighter scope loop ; replace error call with ; "br 3$" = 000774 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 emt +12 ; pdr bits did not set correctly ; for tighter scope loop ; replace error call with ; "br 5$" = 000767 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 & user par's ; The following test writes to both bytes of the kernel & user ; par's seperately to see that writing to one does not effect ; the other. ; 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 & unusfd bits out of the data cmp R1, R2 ; was only the low byte written to beq 4$ ; branch if yes emt +15 ; high byte effected by writing low byte in par ; for tighter scope loop ; replace error call with ; "br 3$" = 000766 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 #000377, R1 ; mask low byte cmp R1, R2 ; was only the high byte written to? beq 6$ ; branch if yes emt +15 ; low byte effected by writing high byte in par ; for tighter scope loop ; replace error call with ; "br 5" = 000765 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 use 1 par's 7$: mov #1$, @#$lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; TEST 20 - test for dual byte addressing of kernel s user pdr's ; The following test writes to both bytes of the kernel & user ; pdr's seperately to see that writing to one does not effect ; the other. ; 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 emt +15 ; high byte effected by writing low byte in pdr ; for tighter scope loop ; replace error call with ; "br 3$" = 000766 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 s unused bits out of data cmp R1, R2 ; was only the high byte written to? beq 6$ ; branch if yes emt +15 ; low byte effected by writing high byte in pdr ; for tighter scope loop ; replace error call with ; "br 5$" = 000765 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. ; 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 jsr PC, @#setreg ; set all bits in all par's in pdr's 2$: mov #kerstk, ksp ; setup stack pointer clr (R0) ; clear one of the kernel pdr's jsr PC, @#cmpreg ; see if other par/pdr's were effected mov #-1, (R0)+ ; res tore all ones, and setup for next pdr 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 clr (R0) ; clear one of the kernel par's jsr PC, @#cmpreg ; see if other par/pdr's were effected mov #-1, (R0)+ ; restore all ones, and setup for next par 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 clr (R0) ; clear one of the user pdr's jsr PC, @#cmpreg ; see if other par/pdr's were effected mov #-1, (R0)+ ; restore all ones, and setup for next updr 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 8 mov #uipar0, R0 ; load address of first user par in R0 5$: mov #kerstk, ksp ; setup stack pointer clr (R0) ; clear one of the user par's jsr PC, @#cmpreg ; see if other par/pdr's were effected mov #-1, (R0)+ ; restore all ones, and setup for next upar 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 dar/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 ; tstb @#$env ; test APT environment bit beq 1$ ; if clear, not on APT so do test tst @#$pass ; if on APT test pass counter bne 10$ ; if not first pass skip test 1$: jsr PC, @#setreg ; set all bits in all par's and pdr's reset ; issue an "init" by executing a reset .if ne VM3FX ; mov #20, @#sr3 ; .endc ; 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 ves emt +55 ; kernel pdr affected by a reset ; for tighter scope loop ; replace error call with ; "br 2$" = 000773 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 8 4$: mov (R0), R1 ; read a kernel par into R1 cmp #177777, R1 ; are all the bits still set? beq 5$ ; branch if yes emt +55 ; kernel par affected by a reset ; for tighter scope loop ; replace error call with ; "br 4$" = 000773 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 if yes emt +55 ; user pdr affected by a reset ; for tighter scope loop ; replace error call with ; "br 6$" = 000773 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 #177777, R1 ; are all the bits still set? beq 9$ ; branch if yes emt +55 ; user par affected by a reset ; for tighter scope loop ; replace error call with ; "br 8$" = 000773 9$: add #2, R0 ; form address of next user par sob R4, 8$ ; loop to 8$ until all user par's checked 10$: ;_____________________________________________________________________________ ; ; TEST 23 - 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 ; memory management adder. The values are such ; that no carries are generated out of the adder. ; The method used to see that the right physical bus address ; is formed by the adder is to waite a pattern to virtual ; location with memory mgmt., and ; then read that location using the physical address that should ; have been formed to see if the test pattern got there. ; 22-bit and 18-bit addressing are used. ; tst23: 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 - kipar6 are loaded mov #177600, (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 8 3$: mov R1, (R0)+ ; map all 8 pages 128 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 <15:00> mov (R0), @#$tmp0 ; save contents at test location clr @#sr3 ; set up for 18 bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125250 using adder (par4 + vht addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125250 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 5$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 4$" = 000742 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 <15:00> mov (R0), @#$tmp0 ; save contents at test location clr @#sr3 ; set up for 18 bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125251 using adder (par4 + vint addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125251 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 7$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 6$" = 000742 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 <15:00> mov (R0), @#$tmp0 ; save contents at test location bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125252 using adder (par4 + virt addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125252 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 9$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 8$" = 000742 9$: ; 10$: mov #10$, @#$lperr ; set loop on error pointer to 10$ mov #ps, 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 a bits <11:00> clr (R0) ; clear the psw clr @#sr3 ; set up for 18 bit addressing bis #bit0, @#sr0 ; turn on memory management mov R2, (R1) ; load psw using adder (para + virt addr.) clr @#sr0 ; turn off mem. mgmt (sr0=0) mov (R0), R3 ; read psw back without using mem. mgmt. clr (R0) ; clear the psw bic #37, R3 ; mask T-bit & cc bits out of data read cmp R2, R3 ; was psw written? beq 11$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical addr. for typing emt +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 kipara ; for tighter scope loop ; replace error call with ; "br 10$" = 000742 11$: mov #11$, @#$lperr ; set loop on error pointer to 11$ mov #ps, 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 #177600, R4 ; load R4 with par value mov R4, @#kipar4 ; load kernel par 4 bits <15:00> bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on memory management mov R2, (R1) ; load psw using adder (para * virt. addr.) clr @#sr0 ; turn off mem. mgmt (sr0=0) mov (R0), R3 ; read psw back without using mem. mgmt. clr (R0) ; clear the psw bic #37, R3 ; mask T-bit & cc bits out of data read cmp R2, R3 ; was psw written? beq 12$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form physical addr. jsr PC, @#formpa ; go form physical addr. cor typing emt +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 kipara ; for tighter scope loop ; replace error call with ; "br 11$" = 000743 12$: mov #1$, @#$lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; TEST 24 - 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 ; and check "wraparound" to address 000000 by ; using virtual addr. 111400 and kipar4 = 177664. ; 22-bit addressing is used. ; tst24: scope ; 1$: ; kernel par's and pdr's have been ; set up by the previous test 2$: mov #2$, @#$lperr ; set loop on error pointer to 2$ mov #66476, R0 ; load physical addr. pba into R0 mov #114376, R1 ; load virtual addr. vba into R1 mov #125253, R2 ; load test pattern into R2 mov #521, R4 ; load R4 with par value mov R4, @#kipar4 ; load kernel par 4 bits <15:00> mov (R0), @#$tmp0 ; save contents at test location bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125253 using adder (par4 + virt addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125253 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 3$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 2$" = 000742 3$: ; 4$: mov #4$, @#$lperr ; set loop on error pointer to 4$ mov #62276, R0 ; load physical addr. pba into R0 mov #107376, R1 ; load virtual addr. vba into R1 mov #125254, R2 ; load test pattern into R2 mov #527, R4 ; load R4 with par value mov R4, @#kipar4 ; load kernel par 4 bits <15:00> mov (R0), @#$tmp0 ; save contents at test location bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125254 using adder (par4 + virt addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125254 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 5$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 4$" = 000742 5$: ; 6$: mov #6$, @#$lperr ; set loop on error pointer to 6$ mov #62076, R0 ; load physical addr. pba into R0 mov #104576, R1 ; load virtual addr. vba into R1 mov #125255, R2 ; load test pattern into R2 mov #553, R4 ; load R4 with par value mov R4, @#kipar4 ; load kernel par 4 bits <15:00> mov (R0), @#$tmp0 ; save contents at test location bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125255 using adder (par4 + virt addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125255 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 7$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 6$" = 000742 7$: ; 8$: mov #8$, @#$lperr ; set loop on error pointer to 8$ mov #00000, R0 ; load physical addr. pba into R0 mov #111400, R1 ; load virtual addr. vba into R1 mov #125256, R2 ; load test pattern into R2 mov #177664, R4 ; load R4 with par value mov R4, @#kipar4 ; load kernel par 4 bits <15:00> mov (R0), @#$tmp0 ; save contents at test location bis #bit4, @#sr3 ; set up for 22-bit addressing bis #bit0, @#sr0 ; turn on mem. mgnt. mov R2, (R1) ; load 125256 using adder (par4 + virt addr.) clr @#sr0 ; turn off memory mgmt. mov (R0), R3 ; read 125256 back without using mem. mgmt. mov @#$tmp0, (R0) ; restore original contents to test loc. cmp R2, R3 ; was same pattern read back that was ; written using memory management? beq 9$ ; branch if yes mov R1, @#virt1 ; save virtual addr. to form phys. addr jsr PC, @#formpa ; go form physical address for typing emt +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 ; for tighter scope loop ; replace error call with ; "br 8$" = 000742 9$: ; mov #1$, @#$lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; TEST 25 - 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 set up 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 ; par/pdr's 0-3 to execute. par7/pdr7 are used to access the ; I/O page. ; While testing in kernel mode, user pages 4 8 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 9$ where the trap is reported. ; By setting the location $madr1 in the e-table to a constant, ; as described in the documentation, this test will continue ; accessing locations throughout memory by increasing the value ; of par4 and par5. ; tst25: scope ; 1$: clr @#ps ; 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-uipar6 are loaded mov #177600, (R0) ; map user 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 mov #5$, @#$lperr ; set loop on error pointer to 5$ mov #9$, @#mmvec ; set m. m. trap vector to 9$ bis #bit4, @#sr3 ; set up for 22-bit addressing mov #bit0, @#sr0 ; turn on memory management 10$: 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 ; 4$: mov @#ps, @#$tmp0 ; save psw in case of error mov #100100, R0 ; put virtual addr. that uses 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 emt +20 ; reading loc. using par5 and a virt. ; addr. did not find data written when using ; par4 and virt. address. ; for tighter scope loop ; replace error call with ; "br 5$" = 000765 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-67600 all tried? bne 5$ ; branch if no bit #140000, @#ps ; 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 p/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, @#ps ; go to user mode br 4$ ; go back and read/write in user mode 7$: clr @#ps ; go back to kernel mode before leaving cmp R5, @#$madr1 ; have we checked all memory? bge 8$ ; branch if yes add #1000, R4 ; load with next value for par4 add #1000, R5 ; load with next value for par5 mov R4, @#kipar4 ; load kernal par4 mov R5, @#kipar5 ; load kernal par5 movb #6, @#kipdr4 ; map kernal space r/w while testing movb #6, @#kipdr5 ; jmp @#10$ ; continue test 8$: mov #77406, @#kipdr4 ; remap kernel pages read/write mov #77406, @#kipdr5 ; mov #600, R5 ; 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 tst26 ; go to next test 9$: mov (ksp)+, @#trappc ; save PC & 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 emt +52 ; m.m. trap while in relocate mode - ; referenced wrong set of pdr's ; 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 to test ;_____________________________________________________________________________ ; ; TEST 26 - 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 is being checked. ; tst26: scope ; 1$: mov #340, @#ps ; lock out all possible interrupts 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 till 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 emt +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 #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 emt +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 if yes emt +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 ;_____________________________________________________________________________ ; ; TEST 27 - W-bit logic test, user pdr's ; This test writes to eight (8) different virtual addresses ; (vba's = 17776, 37776, 57776, 77776, 117770, 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 is being checked. ; tst27: scope ; 1$: mov #140000, @#ps ; 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 till 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 emt +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 emt +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 if yes emt +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 @#ps ; back to kernel mode before leaving ;_____________________________________________________________________________ ; ; TEST 30 - test "W-bit" special cases ; This test checks two special cases of the W-bit. first case is ; that the W-bit should not set in pdr 7 when writing to ; status reg sr0 (kernel pdr 7 is used). Second case is that ; the W-bit is still set if the "dato" is aborted due to a ; timeout error (kernel pdr6 & virtual addr 140000 are used). ; tst30: 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 emt +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, @#kipdr6 ; load kernel pdR6 with 77406 to clear W-bit mov #4$, @#errvec ; set up loc. 4 to 4$ for odd addr. abort clr @#140000 ; cause timeout abort thru loc. 4 4$: mov #kerstk, ksp ; restore the stack pointer mov @#kipdr6, R2 ; read kipdr6 into R2 bis #100, R1 ; R1-77506 cmp R1, R2 ; was W-bit set? beq 5$ ; branch if yes emt +25 ; W-bit was not set during a timeout abort ; for tighter scope loop ; replace error call with ; "br 3$" = 000757 5$: mov R1, @#kipdr6 ; restore kipdr6 to 77406 mov #1400, @#kipar6 ; restore kipar6 to 1400 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 31 - 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 = 064 and ; then physical addr. 60000 is accessed to cause the abort. ; tst31: scope ; 1$: mov #600, R0 ; load data for par's into R0 mov R0, @#kipar3 ; map kernel par's 364 to 12-16k mov R0, @#kipar4 ; mov R0, @#uipar3 ; map user par's 364 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 @#ps, @#$tmp0 ; save psw in case of error 4$: inc (R1) ; try to ref. it using pdr4 - should trap to 5$ emt +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 emt +27 ; instruction was not aborted, loc. goi 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 emt +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 R4 with what sr2 should read cmp R4, @#wassr2 ; did sr2 lockup right virtual addr. ( 4$)? beq 8$ ; branch if yes emt +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=064 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, @#ps ; 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 @#ps ; go back to kernel mode br 2$ ; go back & test acf=4 in same mode 10$: clr @#ps ; 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 32 - 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. ; tst32: 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 @#ps, @#$tmp0 ; save psw in case of error 4$: inc (R1) ; try to write using pdr4 - should trap to 5$ emt +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 emt +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 emt +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 emt +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, @#ps ; go to user mode br 2$ ; repeat test in user mode 9$: clr @#ps ; 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 ft1vec. ;_____________________________________________________________________________ ; ; 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 ; xpansion, one of those three virtual addresses will cause a ; "page length abort" while the other two won't. ; Status register 0 8 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 33 - 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). ; tst33: 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 #daltb1, R0 ; dal table for virtual addr's. to select pdr4. mov #pdrtb1, R4 ; pdr table for pdr4 (coincides with dal table). mov #6, R1 ; set up loop counter. mov #9$, @#mmvec ; setup m.m. trap vector for unexpected aborts mov #2$, @#$lperr ; set loop on error pointer to 2$ mov #kerstk, ksp ; make sure stack pointer is all set up ; test non-abort cases (vba < or = plf) ; 2$: mov (R4)+, @#kipdr4 ; load kipdr4 with page length value tst @(R0)+ ; access virtual addr. (vba < or = plf) ; no abort should occur!!! sob R1, 2$ ; done?...no- test next combination of dal & pdr. ; test abort cases (vba > plf) ; 3$: mov #5, R1 ; set up loop counter. mov #daltb2, R0 ; dal table mov #pdrtb2, R4 ; pdr table mov #4$, @#$lperr ; set loop on error pointer to 4$ mov #6$, @#mmvec ; setup m.m. trap vector for expected abort 4$: mov (R4)+, @#kipdr4 ; load kipdr4 with page length value .if ne VM3FX ; add #2 ,R0 ; on VM3 R0 is not incremented if exception occurs 5$: tst @-2(R0) ; .iff ; 5$: tst @(R0)+ ; access virtual addr. (vba > plf - abort to 6$) .endc ; emt +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 emt +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 emt +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 sob R1, 4$ ; done?..no - get next dal & pdr pair jmp @#10$ ; yes... 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 emt +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 jmp @#tst34 ; dal table for upward expansion (non-abort cases) daltb1: 100000 106100 102300 102500 113700 104600 117700 ; pdr table for kpdr4 (non-abort cases) pdrtb1: 000006 052006 045006 052006 074406 025006 077406 ; dal table (abort cases) daltb2: 100100 110100 116600 112700 117000 117700 ; pdr table (abort cases) pdrtb2: 000006 030406 046406 042006 073406 077006 ;_____________________________________________________________________________ ; ; TEST 34 - 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). ; tst34: scope ; 1$: mov #daltb3, R0 ; dal table for virtual addr's. to select pdr4. mov #pdrtb3, R4 ; pdr table for pdr4 (coincides with dal table). mov #6, R1 ; set up loop counter. mov #9$, @#mmvec ; setup m.m. trap vector for unexpected aborts mov #2$, @#$lperr ; set loop on error pointer to 2$ mov #kerstk, ksp ; make sure stack pointer is all set up ; test non-abort cases (vba > or = plf) 2$: mov (R4)+, @#kipdr4 ; load kipdr4 with page length value tst @(R0)+ ; access virtual addr. (vba > or = plf) ; no abort should occur!!! sob R1, 2$ ; done?...no- test next combination of cal & pdr. ; test abort cases (vba < plf) ; 3$: mov #5, R1 ; set up loop counter. mov #daltb4, R0 ; dal table mov #pdrtb4, R4 ; pdr table mov #4$, @#$lperr ; set loop on error pointer to 4$ mov #6$, @#mmvec ; setup m.m. trap vector for expected abort 4$: mov (R4)+, @#kipdr4 ; load kipdr4 with page lenght value .if ne VM3FX ; add #2, R0 ; 5$: tst @-2(R0) ; .iff ; 5$: tst @(R0)+ ; access virtual addr. (vba < plf - abort to 6$) .endc ; emt +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 emt +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 emt +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 sob R1, 4$ ; done?..no - get next dal & pdr pair jmp @#10$ ; yes... 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 emt +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 jmp @#tst35 ; address to m.m. trap vector ;_____________________________________________________________________________ ; ; dal table for downward expansion (non-abort cases) daltb3: 117700 111600 115400 115200 104000 113100 100000 ; pdr table (non-abort cases) pdrtb3: 77416 25416 32416 25416 03016 52416 00016 ; dal table (abort cases) daltb4: 117600 107600 101100 105000 100700 100000 ; pdr table (abort cases) pdrtb4: 77416 47016 31016 35416 04016 00416 ;_____________________________________________________________________________ ; ; TEST 35 - sr2 bit test ; This test checks the bits in memory management register 2 by ; causing "read-only aborts" at virtual addresses between 100000 ; to 110000 (physical addresses 060000-070000). 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. ; tst35: 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 #60002, R0 ; load R0 with virtual addr. which uses pdr3 mov #100002, 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 emt +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 add R1, R1 ; setup to form next virtual address mov R1, R0 ; setup R0 to form next virt. addr. to load bis #100000, R1 ; form virtual addr. that should be locked up next bis #60000, R0 ; point R0 to next virt. addr. to load cmp R1, #110000 ; have all vba's 100000-110000 been tested? blos 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 36 - 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. ; tst36: 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 emt +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 tracking mov #4$, R1 ; put expected virtual PC in R1 cmp R1, @#wassr2 ; did sr2 contain virtual PC at 4$ beq 5$ ; branch if yes emt +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 emt +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 emt +40 ; sr0 or sr2 not "reset" by a reset ; for tighter scope loop ; replace error call with ; "br 6$" = 000676 14$: mov #1, @#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 emt +41 ; sr2 not tracking correctly ; for tighter scope loop ; replace error call with ; "br 6$" = 000663 16$: 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 37 - 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. A timeout error is used ; to cause a trap to "4". ; tst37: 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 @#ps ; 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, @#ps ; 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 @#160000 ; cause timeout error trap to "4" ; should pick up new PC=4$ from kernel ; loc. 4, not PC=3$ from user loc. 4 (=60004) 3$: mov @#ps, R1 ; save psw for error mov SP, R2 ; save value of stack pointer for error clr @#ps ; be sure back in kernel mode emt +42 ; did not trap thru kernel space ; for tighter scope loop ; replace error call with ; "br 2$" = 000740 4$: clr @#ps ; 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, @#ps ; go to user mode mov #usestk, usp ; restore user stack pointer clr @#ps ; 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 40 - 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. ; tst40: 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, @#ps ; 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 @#ps, R1 ; read new psw into R1 bic #7437, R1 ; mask off cond. code, T-bit, and unused bits clr @#ps ; go back to kernel mode cmp R2, R1 ; did psw stay in user, priority=o? beq 4$ ; branch if yes emt +60 ; psw changed by an rti from user ; for a tighter scope loop ; replace error call with ; "br 2$" = 000760 4$: mov #1$, @#$lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; TEST 41 - kt error serviced before timeout error ; This test checks to see that if a certain virtual address that ; would cause a memory management error causes a timeout ; error first, the timeout 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 ; tst41: scope ; 1$: mov #77006, R5 ; load pdR7 data into R5 mov R5, @#kipdr7 ; map page 7 r/w plf=176 mov #3$, @#4 ; set cpu trap vector to address of 3$ mov #4$, @#250 ; set m.m. trap vector to address of 4$ mov #2$, @#$lperr ; set loop on error pointer to 2$ 2$: inc @#177700 ; cause plf abort and potential timeout 3$: emt +43 ; trapped thru cpu trap vector but shouldn't have ; for tighter scope loop ; replace error call with ; "br 2$" = 000776 4$: mov #kerstk, ksp ; restore stack pointer after trapping mov @#sr0, @#wassr0 ; read status reg.o 5$: mov @#sr2, @#wassr2 ; read status reg. 2 mov #40017, R0 ; load expected sr0 contents into R0 cmp R0, @#wassr0 ; sr0 plf error bit set? beq 6$ ; branch if yes emt +44 ; sr0 didn't report plf error ; for tighter scope loop ; replace error call with ; "br 2$" = 000741 6$: mov #2$, R1 ; load expected sr2 contents into R1 cmp R1, @#wassr2 ; was sr2 locked by plf abort? beq 7$ ; branch if yes emt +44 ; sr2 didn't lock up virtual address ; for tighter scope loop ; replace error call with ; "br 2$" = 000741 7$: bic #160000, @#sr0 ; clear error bits that were set in sr0 mov #timerr, @#4 ; restore address of normal cpu trap handler mov #mgmerr, @#250 ; restore address of normal m.m. trap handler mov #77406, @#kipdr7 ; remap page 7 to read/write plf=177 mov #1$, @#$lperr ; reset loop on error pointer to 1$ ;_____________________________________________________________________________ ; ; TEST 42 - PC & psw saved for kt error during service of timeout 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 a timeout 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. ; tst42: 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 (timeout) 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, @#ps ; go to user mode mov #100002, usp ; set user stack ptr. so second push is in pg. 3 3$: tst @#177700 ; cause timeout 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 @#ps ; be sure in kernel mode mov #kerstk, ksp ; restore kernel stack pointer mov #140000, @#ps ; go to user mode mov #usestk, usp ; restore user stack pointer clr @#ps ; go back to kernel mode clr @#$tmp0 ; clear error indicator cmp R1, #170017 ; was the psw saved the one picked up by the ; timeout 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 timeout 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$: ; ; .if ne VM3FX ; cmp @#wassr2, #4$ ; VM3 specifics for SR2 on timed-out commands .iff ; cmp @#wassr2, #3$ ; did sr2 lock up virtual addr. of last .endc ; ; instruction successfully fetched? beq 8$ ; branch if yes inc @#$tmp0 ; sr2 did not lock up addr. of timeout inst. 8$: tst @#$tmp0 ; any "errors" during trap sequence? beq 9$ ; branch if no emt +45 ; the wrong PC or psw were saved ; or sr0 or sr2 did not report r/o ; error during timeout - kt trap ; sequence ; for tighter scope loop ; replace error call with ; "br 21" = 000710 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 43 - 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. ; tst43: 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, @#ps ; 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 did emt +46 ; wrong thing was pushed on stack ; for tighter scope loop ; replace error call with ; "br 5$" = 000763 br 8$ ; branch to next try 7$: emt +50 ; nothing pushed on stack ; for tighter scope loop ; replace error call with ; "br 5$" = 000761 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, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 9$" = 000766 10$: ; the following will test dstm=2 mfpi. mov #11$, @#$lperr ; set loop on error pointer to 11$ 11$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 11$" = 00c766 12$: ; the following will test dstm=3 mfpi. mov #13$, @#$lperr ; set loop on error pointer to 13$ 13$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 13$" = 000767 14$: ; the following will test dstm=4 mfpi. mov #15$, @#$lperr ; set loop on error pointer to 15$ 15$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 15$" = 000766 16$: ; ; the following will test dstm=5 mfpi. mov #17$, @#$lperr ; set loop on error pointer to 17$ 17$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 17$" = 000763 18$: ; the following will test dstm=6 mfpi. mov #19$, @#$lperr ; set loop on error pointer to 19$ 19$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 19$" = 000766 20$: ; the following will test dstm=7 mfpi. mov #21$, @#$lperr ; set loop on error pointer to 21$ 21$: mov #030340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 21$" = 000762 22$: mov #mgmerr, @#mmvec ; set m.m. vector to normal routine mov #1$, @#$lperr ; set loop pointer to start of test br tst44 ; 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 emt +51 ; tried to read non-resident page ; 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 ; ;_____________________________________________________________________________ ; ; TEST 44 - 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. ; tst44: 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, @#ps ; 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 emt +50 ; user stack pointer not changed ; for tighter scope loop ; replace error call with ; "br 2$" = 000764 3$: mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 5$" = 000765 6$: ; the following will test dstm=2 mtpi. mov #8$, @#$lperr ; set loop on error pointer to 8$ mov #030340, @#ps ; 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 page 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 correctlv beq 9$ ; branch if store was correct emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 8$" = 000764 9$: ; this will test dstm=3 mtpi. mov #10$, @#$lperr ; set loop on error pointer to 10$ mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 10$" = 000763 11$: ; this will test dstm=4 mtpi. mov #12$, @#$lperr ; set loop on error pointer to 12$ mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 12$" = 000762 13$: ; the following will test dstm=5 mtpi. mov #14$, @#$lperr ; set loop on error pointer to 14$ mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 14$" = 000764 15$: ; this will test dstm=6 mtpi. mov #16$, @#$lperr ; set loop on error pointer to 16$ mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 16$" = 000763 17$: ; the following will test dstm=7 mtpi. mov #18$, @#$lperr ; set loop on error pointer to 18$ mov #030340, @#ps ; 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 emt +47 ; incorrect store ; for tighter scope loop ; replace error call with ; "br 18$" = 000763 19$: mov #1$, @#$lperr ; set loop pointer to start of test mov #mgmerr, @#mmvec ; restore m.m. vector to normal routine br tst45 ; branch to next test 20$: mov (ksp)+, @#trappc ; save PC s 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 emt +51 ; tried to load a n.r. page 4 ; 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 to test ;_____________________________________________________________________________ ; ; TEST 45 - 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. ; tst45: 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 pdr with 77406 sob R2, 2$ ; loop until 8 user pdrs loaded mov #3$, @#$lperr ; set loop on error to 3$ 3$: mov #140340, @#ps ; 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, @#ps ; 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 emt +46 ; wrong thing was pushed on stack ; for tighter scope loop ; replace error call with ; "br 4$" = 000766 br 6$ ; branch to next try 5$: emt +50 ; nothing pushed on stack ; for tighter scope loop ; replace error call with ; "br 4$" = 000764 6$: ; the following will test dstm=1 mfpi. mov #7$, @#$lperr ; set loop on error pointer to 7$ 7$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 7$" = 000764 8$: ; the following will test dsm=2 mfpi. mov #9$, @#$lperr ; set loop on error pointer to 9$ 9$: mov #140340, @#ps ; make previous mode kernel present user mov #100000, R2 ; load virtual address into R2 mfpi (R2)+ ; ead 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 9$" = 000766 10$: ; the following will test dstm=3 mfpi. mov #11$, @#$lperr ; set loop on error pointer to 11$ 11$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 11$" = 000767 12$: ; the following will test dstm=4 mfpi. mov #13$, @#$lperr ; set loop on error pointer to 13$ 13$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 13$" = 000766 14$: ; the following will test dstm=5 mfpi. mov #15$, @#$lperr ; set loop on error pointer to 15$ 15$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 15$" = 000763 16$: ; the following will test dstm=6 mfpi. mov #17$, @#$lperr ; set loop on error pointer to 17$. 17$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 17$" = 000766 18$: ; the following will test dstm=7 mfpi. mov #19$, @#$lperr ; set loop on error pointer to 19$ 19$: mov #140340, @#ps ; 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 emt +46 ; wrong data was fetched ; for tighter scope loop ; replace error call with ; "br 19$" = 000762 20$: mov #mgmerr, @#mmvec ; set m.m. vector to normal routine mov #00340, @#ps ; go back to kernel mode, previous kernel mov #1$, @#$lperr ; set loop pointer to start of test br tst46 ; 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 emt +51 ; tried to read non-resident page ; 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 to test ;_____________________________________________________________________________ ; ; TEST 46 - 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 FONZ-11 ; mfpd & mtpd should be decoded the same as mfpi & mtpi. ; tst46: scope ; 1$: mov #030340, @#ps ; 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 ; or 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 emt +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$: emt +54 ; nothing pushed on stack ; for tighter scope loop ; replace error call with ; "br 1$" = 000761 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 emt +54 ; user stack pointer not changed ; for tighter scope loop ; replace error call with ; "br 4$" = 000767 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 47 - 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). ; tst47: scope ; 1$: clr @#ps ; 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 emt +46 ; mfpi fetched wrong data ; for tighter scope loop ; replace error call with ; "br 1$" = 000766 2$: tst -(R0) ; setup expected stack pointer value cmp ksp, R0 ; was the stack pointer decremented? beq 3$ ; branch if yes emt +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 of pass #xxxx" ; total number of errors since last report yyyy ; where xxxx and yyyy 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 asciz with sign type , 67$ ; type ascii string br 66$ ; get over the asciz 67$: .asciz /;TOTAL ERRORS SINCE LAST START AT 200 / .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 $get42: mov @#42, R0 ; get monitor address beq doagin ; 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: reset ; clear the world $endad: jsr PC, (R0) ; go to monitor nop ; save room nop ; for nop ; ACT-11 doagin: mov @#4, @#$tmp0 ; save contents of location 4 mov #1$, @#4 ; set up vector in case of trap mov #1, @#164000 ; notify multi-tester of pass complete br 2$ ; if no trap don't touch stack 1$: add #4, SP ; reset stack in case of trap 2$: mov @#$tmp0, @#4 ; restore contents of loaction 4 $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 restrt ; $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> ; She switch options provided by this routine are: ; sw14=1 loop on test ; sw11=1 inhibit iterations ; sw9=1 loop on error ; sw8=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 10 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 ; ; #####end of code for the xor tester##### ; 6$: bit #bit8, @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 #bit9, @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 ; sw9=1 loop on error ; Call ; emt +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 #bit9, @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", "th" 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: ; df 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 @#ps, #tbit ; is the T-bit set in the psw? beq 1$ ; exit if no mov @#ps, -(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 8 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 8 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$: cmp (R1), R5 ; are all writeable bits set as expected? beq 2$ ; branch if yes cmp R1, R0 ; was it the reg. that was cleared? beq 2$ ; branch if yes mov (R1), R2 ; save contents of improperly cleared register emt +16 ; a pdr was effected by clearing a different par/pdr ; for tighter scope loop ; replace error call with ; an "rts PC" = 000207 2$: add #2, R1 ; form next 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 #177777, R5 ; put expected par contents in R5 3$: cmp (R1), 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 mov (R1), R2 ; save contents of improperly cleared register emt +16 ; a par was effected by clearing a different par/pdr ; for tighter scope loop ; replace error call with ; an "rts PC" = 000207 4$: add #2, R1 ; form next 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$: cmp (R1), R5 ; are all writeable bits set an expected beq 6$ ; branch if yes cmp R1, R0 ; was it the reg. that was cleared? beq 6$ ; branch if yes mov (R1), R2 ; save contents of improperly cleared register emt +16 ; a pdr was effected by clearing a different par/pdr ; for tighter scope loop ; replace error call with ; an "rts PC" = 000207 6$: add #2, R1 ; form next 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 #177777, R5 ; put expected par contents in R5 7$: cmp (R1), 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 mov (R1), R2 ; save contents of improperly cleared register emt +16 ; a par was effected by clearing a different par/pdr ; for tighter scope loop ; replace error call with ; an "rts PC" = 000207 8$: add #2, R1 ; form next 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 or 22-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 <15:00> to give pba <21:6>. Bits <21: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. If 18-bit addressing is selected in sr3, then ; pba<21:18> are cleared in "pbahi". ; formpa: mov R0, -(SP) ; push R0 on stack mov R2, -(SP) ; push R2 on stack mov #kipar0, R2 ; load address of first kernel par in R2 bit #140000, @#ps ; 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 <15:00> from appropriate par mov R0, R2 ; copy par bits <15: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 <15:10> down to bits <5:0> of R2 bic #177700, R2 ; clear off all bits but bits <5: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 <21:16> of physical addr. in pbahi bit #bit4, @#sr3 ; see if 18 or 22-bit addressing bne 2$ ; branch if 22-bit addressing bic #74, @#pbahi ; clear bits <5:2> 2$: ; mov (SP)+, R2 ; pop stack into R2 mov (SP)+, R0 ; pop stack into R0 rts PC ; return to program .sbttl "TTY INPUT ROUTINE" .enabl lsb ; ;_____________________________________________________________________________ ; ; Software switch register change routine. ; Routine is entered frc*1 ?? 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 Control-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 o'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" & "if" 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 reg. 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: $pills 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 @$tks ; char in kbd buffer? bpl 10$ ; br if not mov @$tkb, -(SP) ; get char bic #177600, (SP) ; strip extraneous bits cmpb #$xoff, (SP) ; was char xoff bne 102$ ; br if not 101$: ; tstb @$tks ; wait for char bpl 101$ ; movb @$tkb, (SP) ; get char bic #177600, (SP) ; strip it cmpb #$xon, (SP) ; was it xon? bne 101$ ; br if not 102$: ; tst (SP)+ ; fix stack 10$: ; tstb @$tps ; wait until printer is ready bpl 10$ ; movb 2(SP), @$tpb ; load char to be 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, @#$msgtypf ; 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. ; $typosenter here to setup suppress zeros and number of digits to type ; Call: ; mov num, (SP) ; number to be typed ; typos ; call for tvpeout ; .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 o'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 o'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: 10000. ; 1000. ; 100. ; 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 ps of main flow mov 22(SP), -(SP) ; save PC of main flow mov 22(SP), -(SP) ; save ps 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 ps of call mov (SP)+, 22(SP) ; restore PC of main flow mov (SP)+, 22(SP) ; restore ps 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 ; return ; 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 ; high word 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 to 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 ; 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 nlmber (as per last call) $typds ; trap+5(104405) type decimal number (with sign) $typbn ; trap+6(104406) type binary (ascii) number $gtswr ; trap+7(104407) get soft-swr setting $ckswr ; trap+10(104410) test for change in soft-swr $rdchr ; trap+11(104411) tty type in 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, @#$savR6 ; 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 @#$savR6, SP ; get SP clr @#$savR6 ; wait loop for the tty 1$: inc @#$savR6 ; 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 restrt $pwrad: .word restrt ; 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 $savR6: .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 /PHYSICAL ADDRESS FORMED WRONG/ 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 TIMEOUT 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 NOT SERVICED ON TIMEOUT ERROR/ em44: .asciz /SR0 OR SR2 CHANGED BY TIMEOUT ERROR/ em45: .asciz /ERROR DURING "DOUBLE ERROR" (KT & TIMEOUT)/ 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 /PSW CHANGED BY AN RTI IN USER MODE/ 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/ dh56: .asciz /PSW WAS EXPECTD TESTNO ERRORPC/ .even ; dt1: .word trappc, trapps, wasr6, testno, $errpc, 0 dt2: .word trappc, trapps, wasr6, 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 dt56: .word $reg1, $reg2, 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 df56: .byte 0, 0, 0, 0 ;_____________________________________________________________________________ ; .end