import "io" manifest { iv_none = 0, iv_memory = 1, iv_pagefault = 2, iv_unimpop = 3, iv_halt = 4, iv_divzero = 5, iv_unwrop = 6, iv_timer = 7, iv_privop = 8, iv_keybd = 9, iv_badcall = 10, iv_pagepriv = 11, iv_debug = 12, iv_intrfault = 13 } let ivec = table 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 let set_handler(int, fn) be if int >= 0 /\ int <= 13 then ivec ! int := fn let int_enable() be assembly { LOAD R1, [] SETSR R1, $INTVEC LOAD R1, 0 SETFL R1, $IP } let int_disable() be assembly { LOAD R1, 1 SETFL R1, $IP } let otherhandler(intcode, address, info) be { ireturn } let address, value1, value2, pageno, bad, prevbad let start() be { let last = ! 0x101; let patt1 = 0x5A5A5A5A, patt2 = 0x12345678; set_handler(iv_memory, otherhandler); int_enable(); pageno := (last + 1027) >> 11; prevbad := true; out("last = %x, pageno = %d\n", last, pageno); while pageno < 0b1000000000000000000000 do { address := pageno << 11; value1 := ! address; value2 := 1 ! address; ! address := patt1; 1 ! address := patt2; bad := ! address /= patt1 \/ 1 ! address /= patt2; test bad then unless prevbad do out("page %08x = %d not there\n", pageno, pageno) else if prevbad then out("page %08x = %d OK\n", pageno, pageno); prevbad := bad; ! address := value1; 1 ! address := value2; pageno +:= 1 } outs("done\n"); }