// TableMaker.bcpl -- converts a file into a table contained in a loadable .br file // Last modified April 6, 1982 1:12 PM by Taft // Bldr TableMaker GP get "Streams.d" external [ SetupReadParam; ReadParam OpenFile; Closes; Resets; Endofs; Puts; ReadBlock; WriteBlock; FileLength; Wl MoveBlock; Zero ] //---------------------------------------------------------------------------- structure BRFile: // Bcpl binary format //---------------------------------------------------------------------------- [ bcplVersionNumber word fileLength word blank word // must be zero nameTableOffset word blank word // must be zero labelTableOffset word blank word // must be zero codeOffset word blank word // must be zero chainTableOffset word blank word // must be zero zchainTableOffset word blank word 3 // must be zero labelTable word 3 = [ labelCount word // must be 1 labelNameNumber word // must be 1 labelPC word // must be 1 ] chainTable word 1 // must be zero zchainTable word 1 // must be zero nameTable word 3 = [ nameCount word // must be 1 nameDescriptor word // must be 140b blank word nameString word 0 // actually @String ] code word 2 = [ codeLength word codeFirst word 1 // should be zero data word 0 ] ] manifest [ lenBRFile = offset BRFile.nameString/16 // + name string + data bcplVersionNumber = 2 lshift 8 ] structure String: [ length byte; char^1,1 byte ] //---------------------------------------------------------------------------- let TableMaker() be //---------------------------------------------------------------------------- [ let inputFileName, outputFileName, staticName = vec 127, vec 127, vec 127 inputFileName!0 = 0; outputFileName!0 = 0; staticName!0 = 0 let string, switchVec = vec 127, vec 127 SetupReadParam() [ // repeat if ReadParam($P, 0, string, switchVec, true) eq -1 then break let destString = selecton switchVec!0 into [ case 0: inputFileName case 1: selecton switchVec!1 into [ case $I: case $i: inputFileName case $O: case $o: outputFileName case $S: case $s: staticName default: Fail("Undefined switch") ] default: Fail("Too many switches") ] MoveBlock(destString, string, string>>String.length rshift 1 +1) ] repeat let inputFile = 0 if inputFileName!0 ne 0 then inputFile = OpenFile(inputFileName, ksTypeReadOnly, wordItem) if inputFile eq 0 then Wl("Input file not found.*n") if inputFile eq 0 then inputFile = ReadParam("IW", "Input file: ", inputFileName) for i = 1 to inputFileName>>String.length do if inputFileName>>String.char^i eq $. then [ inputFileName>>String.length = i-1; break ] if staticName!0 eq 0 then MoveBlock(staticName, inputFileName, inputFileName>>String.length rshift 1 +1) if outputFileName!0 eq 0 then outputFileName = inputFileName let dot = 0 for i = 1 to outputFileName>>String.length do if outputFileName>>String.char^i eq $. then [ dot = i; break ] if dot eq 0 then [ dot = outputFileName>>String.length +1 outputFileName>>String.char^dot = $. outputFileName>>String.char^(dot+1) = $b outputFileName>>String.char^(dot+2) = $r outputFileName>>String.length = dot+2 ] let outputFile = OpenFile(outputFileName, ksTypeWriteOnly, wordItem) if outputFile eq 0 then Fail("Can't open output file") let fileLength = vec 1 FileLength(inputFile, fileLength) let dataLength = fileLength!0 lshift 15 + fileLength!1 rshift 1 if (fileLength!1 & 1) ne 0 then dataLength = dataLength+1 Resets(inputFile) WriteBRFileHeader(outputFile, dataLength, staticName) until Endofs(inputFile) do [ manifest lenDataVec = 12*256 let data = vec lenDataVec let words = ReadBlock(inputFile, data, lenDataVec) WriteBlock(outputFile, data, words) ] Closes(inputFile) Closes(outputFile) ] //---------------------------------------------------------------------------- and Fail(message) be //---------------------------------------------------------------------------- [ Wl(message) Wl("Command syntax is: TableMaker inputFile outputFile/o staticName/s") abort ] //---------------------------------------------------------------------------- and WriteBRFileHeader(stream, dataLength, labelName) be //---------------------------------------------------------------------------- // ripped off from LoadMB.bcpl, courtesy of Peter Deutsch [ let brFile = vec lenBRFile; Zero(brFile, lenBRFile) let nameLength = labelName>>String.length/2+1 brFile>>BRFile.bcplVersionNumber = bcplVersionNumber brFile>>BRFile.fileLength = offset BRFile.data/16 + nameLength + dataLength brFile>>BRFile.nameTableOffset = offset BRFile.nameTable/16 brFile>>BRFile.labelTableOffset = offset BRFile.labelTable/16 brFile>>BRFile.codeOffset = offset BRFile.code/16 + nameLength brFile>>BRFile.chainTableOffset = offset BRFile.chainTable/16 brFile>>BRFile.zchainTableOffset = offset BRFile.zchainTable/16 brFile>>BRFile.labelCount = 1 brFile>>BRFile.labelNameNumber = 1 brFile>>BRFile.labelPC = 1 brFile>>BRFile.nameCount = 1 brFile>>BRFile.nameDescriptor = 140b WriteBlock(stream, brFile, lenBRFile) WriteBlock(stream, labelName, nameLength) Puts(stream, dataLength+1) // codeLength Puts(stream, 0) // codeFirst ]