// Read packed RAM image
// last edited by Levin: August 25, 1978  10:11 AM

external	// entries
[	ReadPackedRAM
	LoadPackedRAM
]

external	// O.S.
[	ReadBlock
	Ws; Wo
]


let ReadPackedRAM(st, lvR; numargs na) = valof
[	let v = vec #400
	ReadBlock(st, v, #21)	// read BR file header
	if (v!7 ne #17) % (v!#17 ne #4401) then	// bad file
	 [ Ws("Bad RAM image file*N"); resultis -1 ]
	ReadBlock(st, v, #400)	// constants
	if na ge 2 then @lvR = v!0		// RAM ID value
	let dif = checkconsts(v)
	for i = 0 by #200 to #1600 do
	 [ ReadBlock(st, v, #400)
	   wramvec(i, v, #200)
	 ]
	resultis dif
]

and LoadPackedRAM(v, lvR; numargs na) = valof
[	if na ge 2 then @lvR = v!0		// RAM ID value
	let dif = checkconsts(v)
	wramvec(0, v+#400, #2000)
	resultis dif
]

and checkconsts(v) = valof
[	let dif = 0
	let rct = table[ 0; #171001; #14030; #102020]
	for i = 1 to #377 do
	 [ rct!0 = (i&#370) lshift 8 + (i&7) lshift 4
	   wramvec(#1000, rct, 2)
	   let val, wd = v!i, jram(#1000)
	   if (val ne wd) & (val ne 0) then
	    [ Ws("Constant"); Wo(i)
	      Ws(" is "); Wo(wd)
	      Ws(", should be "); Wo(val)
	      Ws("*N")
	      dif = dif+1
	    ]
	 ]
	if dif ne 0 then
	 [ Wo(dif); Ws(" constants differ*N") ]
	resultis dif
]

and wramvec(addr, v, n) be
[	let writer = table [
	   #55001	// STA 3 1,2
	   #35003	// LDA 3 3,2
	   #61012	// WRTRAM
	   #35001	// LDA 3 1,2
	   #1401	// JMP 1,3
	 ]
	let p = v
	for i = 0 to n-1 do
	 [ writer(@p, addr+i, p!1); p = p+2 ]
]

and jram(loc, ac0) = (table[ #61010; #1401])(ac0, loc)