// FastStreamsB.Bcpl -- Fast Memory stream routines -- BCPL part // Copyright Xerox Corporation 1979 // Last modified July 12, 1979 3:49 PM by Taft get "Streams.d" // This code works together with the machine code in FastStreamsA.asm. // Note: positions and itemSizes in fast streams are always measured // in bytes. They are truncated for word streams, except that // end positions are rounded up, so that all the data will always be // read, along with some garbage if the length of the stream is not // an even number of items. external [ // outgoing procedures InitializeFstream; SetupFstream SetEof; EofError; ItemSize; StreamError // incoming procedures Errors // incoming statics from FastStreamsA.asm fastChStream; fastWstream ] manifest [ // error codes ecBadItemSize = 1301 ecEof = 1302 ecBadStreamOperation = 1303 ] // This declaration must agree with the machine-language declaration // in FastStreamsA.asm //---------------------------------------------------------------------------- structure FSx: // internal, expanded version of FS //---------------------------------------------------------------------------- [ @FS = [ blank word offset FS.fsp/16 // note that the length of the structure from here to the end is // publicly declared as 12. in Streams.d (though it is 11 actually) charPtr word // 1 for left byte, 0 for right wordPtr word // points to word containing the last byte, not next count word // -(number of items left+1) dirty word eof word putOverflow word getOverflow word getCC word itemSize word // in bytes; must be 1 or 2 endPos word // relative addr of first byte not included in count savedGets word ] ] manifest lFSx = size FSx/16 //---------------------------------------------------------------------------- let InitializeFstream(fs, itemSize, PutOv, GetOv, GetCC; numargs na) be //---------------------------------------------------------------------------- [ let template = selecton itemSize into [ case charItem: fastChStream case wordItem: fastWstream default: Errors(fs, ecBadItemSize) ] for i = 0 to lFSx-1 do [ let t = template!i if (t & 177700b) ne 0 then t = @t fs!i = t ] fs>>FSx.putOverflow = PutOv fs>>FSx.getOverflow = GetOv if na ge 5 then fs>>FSx.getCC = GetCC ] // the following functions take advantage of the fact that if // itemSize is 1 or 2, shifting by itemSize-1 is the same as // multiplying or dividing by itemSize //---------------------------------------------------------------------------- and SetupFstream(fs, wordBase, currentPos, endPos) be //---------------------------------------------------------------------------- [ // Note that endPos is rounded up, although everything else is truncated let m = -fs>>FSx.itemSize // truncation mask let i = fs>>FSx.itemSize-1 currentPos = (currentPos+i) & m endPos = (endPos+i) & m fs>>FSx.charPtr = 1-(currentPos & 1) fs>>FSx.wordPtr = wordBase+(currentPos rshift 1)-fs>>FSx.charPtr // the (+1) in the next statement reflects the fact that the // count must be one more than the number of items left fs>>FSx.count = -(((endPos-currentPos) rshift i)+1) fs>>FSx.endPos = endPos ] //---------------------------------------------------------------------------- and SetEof(fs, newValue) be // set or reset the eof flag //---------------------------------------------------------------------------- if fs>>FSx.eof ne newValue then [ fs>>FSx.eof = newValue test newValue ifso [ fs>>FSx.savedGets = fs>>FSx.gets; fs>>FSx.gets = EofError ] ifnot fs>>FSx.gets = fs>>FSx.savedGets ] //---------------------------------------------------------------------------- and EofError(fs) = fs>>FS.error(fs, ecEof) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and StreamError(fs) be fs>>FS.error(fs, ecBadStreamOperation) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and ItemSize(fs) = fs>>FSx.itemSize //---------------------------------------------------------------------------- // See FastStreamsA.asm for the following //---------------------------------------------------------------------------- // and CurrentPos(fs) = //---------------------------------------------------------------------------- // fs>>FSx.endPos+((fs>>FSx.count+1) lshift (fs>>FSx.itemSize-1)) //---------------------------------------------------------------------------- // and Dirty(fs) = fs>>FSx.dirty ne 0 //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // and SetDirty(fs, flag) be fs>>FSx.dirty = flag //----------------------------------------------------------------------------