// IfsRamTest.bcpl -- Initialization-time hardware check
// Copyright Xerox Corporation 1981
// Last modified January 27, 1981  5:29 PM by Taft


external
[
// outgoing procedures
RamTest

// incoming procedures
IFSError; Random

// outgoing statics

// incoming statics
]

manifest
[
ecBadRam = 60
ecBadSRegister = 61
]

//----------------------------------------------------------------------------
let RamTest(image) be
//----------------------------------------------------------------------------
// Tests the Ram and does not return if it is bad.
// If image eq 0, reads and writes using random data, and also tests
// the S-registers.
// If image ne 0, verifies that the Ram contents are equal to image,
// and does not touch the S-registers.
[
let WriteRam = table  // WriteRam(lvData, addr)
   [
    55001B	// sta 3 1 2
   115000B	// mov 0 3
    21400B	// lda 0 0 3
    35401B	// lda 3 1 3
    61012B	// wrtram
    35001B	// lda 3 1 2
     1401B	// jmp 1 3
   ]
let ReadRam = table  // ReadRam(lvData, addr)
   [
    55001B	// sta 3 1 2
   115000B	// mov 0 3
    61011B	// rdram
    41401B	// sta 0 1 3
    20406B	// lda 0 c2000
   107000B	// add 0 1
    61011B	// rdram
    41400B	// sta 0 0 3
    35001B	// lda 3 1 2
     1401B	// jmp 1 3
     2000B	// c2000: 2000
   ]
let JumpRam = table  // JumpRam(arg, addr)
   [
    61010B	// jmpram
     1401B	// jmp 1 3
   ]

// Control RAM test
let buf = vec 4000B
if image ne 0 then buf = image
for i = 1 to (image eq 0? 10, 1) do
   [
   if image eq 0 then
      for addr = 0 to 1777B do
         [
         buf!(2*addr) = Random(); buf!(2*addr+1) = Random()
         WriteRam(buf+2*addr, addr)
         ]

   let inst = vec 1
   for addr = 0 to 1777B do
      [
      ReadRam(inst, addr)
      if inst!0 ne buf!(2*addr) % inst!1 ne buf!(2*addr+1) then
         IFSError(ecBadRam, addr, inst!0, inst!1,
          buf!(2*addr), buf!(2*addr+1))
      ]
   ]

// S-register test
if image eq 0 then
   [
   structure MI: [ rsel bit 5; blank bit 11; blank bit 16 ]
   let writeR = table
      [
      014000B; 101001B	// L← AC0, SWMODE;
      000110B; 102020B	// Sxx← L, :START;
      ]
   let readR = table
      [
      000060B; 101001B	// L← Sxx, SWMODE;
      014030B; 102020B	// AC0← L, :START;
      ]

   for i = 1 to 10 do
      [
      WriteRam(writeR, 1000B)
      for addr = 41B to 77B do
         [
         buf!addr = Random()
         (writeR+2)>>MI.rsel = addr
         WriteRam(writeR+2, 1001B)
         JumpRam(buf!addr, 1000B)
         ]

      WriteRam(readR+2, 1001B)
      for addr = 41B to 77B do
         [
         readR>>MI.rsel = addr
         WriteRam(readR, 1000B)
         let value = JumpRam(nil, 1000B)
         if value ne buf!addr then
            IFSError(ecBadSRegister, addr, value, buf!addr)
         ]
      ]
   ]
]