! ! Buffer format ! ! BASE start of the space allocated to the buffer ! SIZE size of the space allocated to the buffer, in bytes ! %record %format Buff Fm ( %integer Base, Size ) ! ! for machine-code ! %const %integer Buff Base = 0, Buff Size = 4 ! ! Commonest stream-private block is the one containing all the RMS ! structures needed for a file. ! %from IMP %include RMS %record %format FD Fm ( - %record(Fab Fm) Fab, %record(Rab Fm) Rab, %record(Nam Fm) Nam, %string(255) Resultant ) ! ! Stream control block "accessor" ! ! The buffer currently in use is described by S_THISB. ! ! base ! | ! |<-----------size------------>| ! +--+--+--+--+--+--+--+--+--+--+--+ ! | | | | | | | | | | | | ! +--+--+--+--+--+--+--+--+--+--+--+ ! ^ ^ ! | | ! | | ! notional notional ! pointer limit ! NPTR NLIM ! ! For both input and output, the notional pointer points at the next ! unprocessed character slot in the buffer. The buffer has no unprocessed ! character slots if NPTR>=NLIM. The notional NPTR and NBUF are derived from ! the PTR and LIM in the accessor record by adding the constants PTROFF or ! LIMOFF. For example, to test if a buffer is completely processed, the ! comparison is: ! ! S_PTR+PTROFF >= S_LIM+LIMOFF ! ! To go from nominal to actual, subtract OFF ! To go from actual to nominal, add OFF ! %const %integer Ptr Off = 1, Lim Off = 1 ! ! (1) For use as an INPUT SCB ! ! LIM points to the last character in the buffer ! PTR points to the most recently used character ! i.e. one before the next symbol. ! The buffer is empty if LAST SYMBOL >= LIMIT ! because all characters have been consumed. ! ! (2) For use as an OUTPUT SCB ! ! LIM points to the last valid space in the buffer ! PTR points to the most recently WRITTEN character ! space. The buffer is therefore full if ! LIMIT >= LAST SYMBOL because all available ! character positions have been filled up. ! ! (0) Generic Fields ! ! RAB and FAB are pointers to a record and file access block ! respectively; note that these need NOT necessarily ! be the appropriate RMS structures. ! ! Handler routines are all CALLed. The arguments are as follows: ! Functions: ! ! CLOSE HANDLER (SCB,Mode) 0 => CLOSE, 1 => ABANDON ! COMPLETE HANDLER (SCB) ! POSITION HANDLER (SCB,Byteno) >=0 ! RESET HANDLER (SCB) ! ! BREAK HANDLER (used only on output); R1 = character to process ! BUFFER HANDLER (on input) ! BUFFER HANDLER (on output) R1 = preserved across JSB call ! %const %integer Max Handlers = 10 %record %format SCB Fm ( {0 } %integer LIM, {generic I/O system buffer limit} {4 } PTR, {generic I/O system char pointer} {8 } %short Breaks, {<=this value => break char} { >this value => normal char} - {10} %byte Last Put, {last character in previous buffer} {11} Ref Count, {no of uses of SCB at present} {12} ( %integer Break Handler, {called on special output characters} {16} Buffer Handler, {called on buffer overflow} {20} Position Handler, {called on complex conditioning ops} {24} Close Handler, {called to close the file} {28} Complete Handler, {COMPLETE OUTPUT or something...} {32} Reset Handler %or {RESET function} {12} %integer %array Handlers ( 1: Max Handlers ) ), {52} %record(Buff Fm) ThisB, {buffer currently in use for input} {56} ( %record(*) %name Rab, Fab %or {56} %integer User1, User2, User3 %or {56} %record(Fd Fm) %name Fd ), {**} %short Flags, {**} %integer Position, {position of current buffer or <0} {**} %record(Buff Fm) AllocB, {buffer allocated if any} {**} NameB ) {object name buffer if any} ! ! Flags for SCBs ! %const %integer SCB Flag Abandoned = 1<<0 {at least one ABANDON call} ! ! handler offsets within the SCB ! (used by in-line assembler) ! %const %integer Break H = 12, Buffer H = 16, Position H = 20, Close H = 24, Complete H = 28 %const %integer ThisB Ad = 52, RAB Ad = 56, User1 Ad = 56, FAB Ad = 60, User2 Ad = 60, User3 Ad = 64 ! ! Some useful procedure specs ! %external %record(SCB Fm) %map %spec New SCB %alias "IMP___NEW_SCB" ( %integer Buffer If Any ) %external %record(SCB Fm) %name %spec In Scb %alias "IMP___IN_SCB" %external %record(SCB Fm) %name %spec Out Scb %alias "IMP___OUT_SCB" %external %routine %spec Set Object Name %alias "IMP___SET_OBJECT_NAME" - ( %record(SCB Fm) %name S, %string(*) %name T )