// // Routine to read a MU binary into core // last edited 21-MAR-75 12:15 // external // entry procedures [ ReadMU ] external // entry statics [ MuSeqNo ] external [ GETS; ENDOFS; BSTORE ] structure [ lh byte; rh byte ] structure BS: [ length byte; char↑1,255 byte ] manifest nmems = 3 static [ stream memnos MuSeqNo W2ram Wcon DefName ] let ReadMU(strm, writeram, writecon, definename; numargs n) = valof // strm is a word-oriented input stream // writeram(addr, hi, lo) writes into RAM // writecon(addr, value) writes constant // definename(addr, string, memid) defines name // returns 0 if OK, otherwise error string [ stream = strm W2ram = ((n ls 2) % (writeram eq 0)? noop, writeram) Wcon = ((n ls 3) % (writecon eq 0)? noop, writecon) DefName = ((n ls 4) % (definename eq 0)? noop, definename) let curmemx, curaddr = -1, 0 let memnames = vec nmems memnames!0 = "R" memnames!1 = "CONSTANT" memnames!2 = "INSTRUCTION" let memwidths = table[ 16;16;32 ] let memsizes = table[ 63;255;-1 ] let mnos = vec nmems memnos = mnos BSTORE(memnos, -1, nmems) [ if ENDOFS(stream) then resultis "Unexpected end of stream" let blocktype = GETS(stream) switchon blocktype into [ case 0: // end of data resultis 0 case 2: // set address [ let memno = GETS(stream) let addr = GETS(stream) let memx = findmem(memno) switchon memx into [ case 1: [ curaddr = fixCONaddr(addr); endcase ] case 2: [ curaddr = fixINSaddr(addr); endcase ] default: resultis "Bad memory #" ] curmemx = memx endcase ] case 1: // data word [ MuSeqNo = GETS(stream) switchon curmemx into [ case 1: [ readCONdata(curaddr); endcase ] case 2: [ readINSdata(curaddr); endcase ] default: resultis "Data for undefined memory" ] curaddr = curaddr+1 endcase ] case 4: // define memory [ let memno = GETS(stream) let width = GETS(stream) let name = vec 128 readname(name) for j = 0 to nmems-1 do if strequal(name, memnames!j) then [ if width ne memwidths!j then resultis "Bad width" memnos!j = memno endcase ] resultis "Bad memory name" ] case 5: // define symbol [ let memno = GETS(stream) let val = GETS(stream) let name = vec 128 readname(name) let memx = findmem(memno) if memx eq -1 then resultis "Bad memory #" DefName(val, name, (table[$R;$C;$I])!memx) endcase ] default: resultis "Invalid block type" ] ] repeat ] and noop(x, y, z) be [ ] and findmem(memno) = valof [ for j = 0 to nmems-1 do if memnos!j eq memno then resultis j resultis -1 ] and readname(strg) be [ let j = 0 [ let wd = GETS(stream) if wd<<lh eq 0 break j = j+1 strg>>BS.char↑j = wd<<lh if wd<<rh eq 0 break j = j+1 strg>>BS.char↑j = wd<<rh ] repeat strg>>BS.length = j ] and strequal(str1, str2) = valof [ for i = 1 to str1>>BS.length do if str1>>BS.char↑i ne str2>>BS.char↑i resultis false resultis true ] and revbits(x, n, mask) = valof // reverse low n bits of x [ let y = 0 for j = 1 to n do [ y = y lshift 1 + (x & mask) x = x rshift 1 ] resultis y ] and fixCONaddr(addr) = valof [ structure CA: [ blank bit 8; a bit 3; b bit 4; c bit 1 ] resultis revbits(addr<<CA.b, 4, 1) lshift 4 + addr<<CA.a lshift 1 + addr<<CA.c ] and fixINSaddr(addr) = valof [ resultis (addr𫓸) + revbits((not addr)Ź, 8, 1) ] and readCONdata(addr) be Wcon(addr, not GETS(stream)) and readINSdata(addr) be [ // data word is reversed by nibbles (ugh) let wd0 = revbits(GETS(stream), 4, #10421) let wd1 = revbits(GETS(stream), 4, #10421) W2ram(addr, wd0, wd1) ]