-- Em3270BufferDefs.Mesa

-- Revised for Star 3.0g + TI by Lui                     30-Jun-83 14:25:55
-- Owner: Lui
-- Created by: Stepak

-- Em3270BufferDefs provides the necessary types and procedures to allow data insertion into and extraction from the main 3270 buffer.  The buffer it defines is the backing store which all other processes view as their data source and sink. --

DIRECTORY
    CharDefs USING [Char],
    Em3270PrivDefs,
    SchemaDefs USING [Lschema],
    StandardDefs USING [Bv],
    VDTDefs USING [CharPos,LschemaVDT];
  
Em3270BufferDefs: DEFINITIONS =
BEGIN OPEN Em3270PrivDefs,StandardDefs;

-- ============================
-- Public Types --
-- ============================

CharPos: TYPE = VDTDefs.CharPos;-- char positions in buffer
WriteError: TYPE = {attribute, protected, noRoomInField, unformatted, alphaInNumericField, okay};

-- ======================
-- Public Constants
-- ======================

bufferSize: CARDINAL = lineSize*numberOfRows;  -- number of chars in 3270 buffer
lineSize: CARDINAL = 80;  -- number of characters per line on screen
numberOfRows: CARDINAL = 24;  -- number of lines per screen

-- ===========================
--Synchronization Routines --
-- ===========================

Reserve: PROCEDURE [my: LptBufferData];
--  This entry procedure is used to lock out any calls to the buffer manager by a procedure other than the one which called 'Reserve' originally. When 'Release' is called later, the 'unreserved' variable is BROADCASTed, and the buffer is unlocked. The 'Reserve' and 'Release' procs are used to lock out the host and keyboard of a single instance of the emulator from each other.  Processes relating to other instances of the emulator are not locked out. Any 'host' or 'keyboard' actions which change the buffer data should be surrounded by the Reserve-Release pair.    --
		    
Release: PROCEDURE[my:LptBufferData];
-- This entry procedure BROADCASTs the 'unreserved' condition variable. This unlocks the buffer. --
  
-- ===========================
-- Public Procedures --
-- ===========================

BackSpaceKey: PROCEDURE [my:LptBufferData];
-- Implements the back-space key. It causes the cursor to move one position to the left on the screen. The cursor may be moved into any character location, including unprotected and protected alphameric character and attribute character locations. If the cursor is in the first position of a line, the back-space causes the cursor to be positioned in the last position of the previous line.  If the cursor is location 0 then it will move to the last position in the buffer. --

BackTabKey: PROCEDURE [my:LptBufferData];
-- Implements the back-tab key. When the cursor is located in the attribute character position or the first alphameric character location of an unprotected data field or in any character location of a protected data field, this key moves the cursor to the first alphameric character location of the first preceding unprotected data field.  When the cursor is located in any alphameric character location of an unprotected data field other than the first location, this key moves the cursor to the first alphameric character location of that field.  In a display with no unprotected fields, the cursor is repositioned to character location 0. The cursor wraps from the beginning of the first line on the display and continues at the end of the last line if necessary.--

ClearBuffer: PUBLIC PROCEDURE [my:LptBufferData];
-- The entire buffer is filled with null characters. The host buffer address and the cursor are set to 0. The caller should call 'DisplayBuffer' to update screen, since this routine will not. --

Create: PROCEDURE [lschemaVDT:VDTDefs.LschemaVDT, lptToTransFile: BaseOISToEFile] RETURNS [my: LptBufferData];
-- Allocates storage for the variables associated with a buffer instance. Returns a pointer to this storage. --

DeleteKey: PROCEDURE [my:LptBufferData]
			RETURNS [aStatus:WriteError ← okay]; 
-- Implements delete key. If the cursor is located in an alphameric character location in an unprotected field, deletes the character from the location identified by the cursor. Sets the 'modified' parameter for the field. The cursor does not move.  All remaining characters in the unprotected field, to the right of the cursor and on the same row, will shift one character location to the left.  Vacated character locations at the end of the row will be filled with nulls.  If the unprotected filed encompasses more than one row, characters in row other than the row identified by the cursor will not be affected. If the cursor is located in an attribute location or is within a protected data field, the keyboard is disabled, no character locations are cleared, the cursor is not moved, and the MDT bit is not set.  --

Destroy: PROCEDURE [my:LptBufferData];
-- Frees storage allocated for the variables associated with a buffer instance. --

DisplayBuffer: PROCEDURE [my:LptBufferData];
-- Used to update the display. (to accurately reflect a possibly updated buffer.  Non-displayable fields appear as blanks on the screen. Upon return, the current buffer address (cursor) is unchanged.  --

DuplicateKey: PROCEDURE [my:LptBufferData]
				RETURNS [aStatus: WriteError ← okay];
-- Implements the duplicate key. It causes a unique character code to be entered into the buffer, a Tab key operation to be performed, and the MDT bit to be set to TRUE. The DUP character, when stored in a device buffer, is displayed as an asterisk with an overscore. ??? Operation of this key when the cursor is located in an attribute character location or is within a protected data field disables the keyboard; no character locations are cleared, the cursor is not moved, and the MDT bit is not set. -- 

EnumAllFieldsAndNulls:PROCEDURE[my:LptBufferData,pvFieldAndNullsHit:Em3270PrivDefs.PvFieldAndNullsHit];
-- This procedure calls a user-specified procedure to process each sequence of an attribute followed by all the text and/or nulls up to the next attribute.  If the first field in the buffer is not preceded by an attribute, information concerning all the text up to, but not including the next attribute is passed. This is meant to be called by  'MakeDocument' to capture a copy of the buffer data. (includes nulls). --

EnumFields: PROCEDURE[my:LptBufferData,pvFieldHit:PvFieldHit,clientData:MDTStream,bvAll:Bv ← FALSE, accessMode: AccessMode ← keyMode] RETURNS [newClientData:MDTStream];
-- This procedure calls a user-specified procedure to process each sequence of non-nulls. This is used to implement the 'Read-Modified' command, and the nulls are suppressed, since the host does not want them. The search for modified-fields end when the last buffer location is checked.  If the last modified field wraps around the end of the buffer, the operation terminates after all the data in the field is transferred, and the buffer address at the end of the operation is the address of the next attribute in the buffer. If the last field wraps around, but was not modified, then the buffer address upon return is 0. If 'bvAll' is TRUE, all fields are considered, if FALSE, only modified fields. Defaults to just considering modified fields. --
-- If the accessMode is hostMode the search for modified fields begins at the CBA if the buffer is formatted. User generated read modified starts from 0, host generated read modified can start at any place. But where the search ends are the same for both. If the buffer is unformatted, the search always begins at 0 regardless of of who generated the RM.

EraseAllUnprotected: PROCEDURE[my:LptBufferData];
-- Implements the Erase-All-Unprotected command.  All the unprotected buffer character locations are filled with nulls. The MDT bit for each unprotected field is reset to 0.  The AID byte is reset.  The cursor is repositioned to the 1st character location in the 1st unprotected field of the buffer.  If no unprotected fields exist, the cursor is positioned to buffer location 0. --

EraseEOFKey: PROCEDURE [my:LptBufferData]
				RETURNS [aStatus:WriteError ← okay];
-- Implements the Erase EOF key.  If the cursor is located in an alphameric character location in an unprotected data field, this key clears the character location occupied by the cursor and all remaining character locations to the right in that field to nulls.  The operation can wrap from the end of the last line on the display to the end of the field. ('EraseChars' must be called 2 times in this case.)  The cursor does not move as a result of operating this key, and the MDT bit is set to 1.  If the cursor is located in an attribute character location or is within a protected data field, an input-inhibit condition is caused, and the keyboard is disabled. (no character locations are cleared, the cursor is not moved, and the MDT bit is not set.)  For unformatted buffers, all char locs from the cursor loc. to the end of the buffer are set to null. --

EraseInputKey: PROCEDURE [my:LptBufferData];
-- Implements the Erase Input key.  This key clears all unprotected character locations to nulls, resets the MDT bit to 0 in unprotected fields, and repositions the cursor to the first unprotected character location on the screen. If the buffer does not contain any unprotected data fields, no character locations are cleared and the cursor is repositioned to character location 0.  If the display contains no fields, the entire buffer is cleared to nulls and the cursor is repositioned to location 0. --

EraseUnprotectedToAddress: PROCEDURE [my:LptBufferData,stopPosition: CharPos];
-- This procedure inserts nulls in all unprotected buffer character locations, starting at the current buffer address and ending at, but not including, the specified stop address. When the stop address is lower than the current buffer address, this operation wraps from the bottom row of the buffer to the top row.  When the stop address equals the current address, all unprotected character locations in the buffer are erased.  Attribute characters are not affected. If there are no fields, then nothing is done. 'DisplayBuffer' must be called to update the screen. --

FieldMarkKey: PROCEDURE [my:LptBufferData]
				RETURNS [aStatus:WriteError ← okay];
-- Implements the field-mark key.  A unique character code is entered into the buffer at the current cursor location and the MDT bit for that field is set. (The buffer address is incremented also.) The field mark character is displayed as a ';' with a line over it.  If the cursor is located in an attribute character location or is within a protected data field, the keyboard is disabled, no character locations are cleared, the cursor is not moved, and the MDT bit is not set. --

FindNextAttribute: PROCEDURE[my:LptBufferData,currentPos:CharPos,
     stopPos:CharPos←0] RETURNS[attribPos: CharPos];
-- Searches the buffer for attribute characters, starting at 'currentPos', and proceeding up to (but not including) the position specified by 'stopPos'. If none are found, then 'attribPos' is set to 'bufferSize', which is the index past the end of the buffer., otherwise the index of the next attribute is returned in 'attribPos'.  Upon return, the current buffer address is unchanged.  --

GetBufferAddress: PROCEDURE [my:LptBufferData,aMode:AccessMode]
						RETURNS [CharPos];
						
GetCursor: PROCEDURE [my:LptBufferData] RETURNS [cursorPos:CharPos];
-- Returns the current position of the cursor on the screen. --

HomeKey: PROCEDURE [my:LptBufferData];
-- Implements the home key.  It moves the cursor to the first unprotected character position on the screen. If the buffer is unformatted or if the display has no unprotected data fields, the cursor is repositioned to character location 0.--

InsertCursor: PROCEDURE[my:LptBufferData];
-- This order repositions the cursor to the location specified by the current buffer address.  Execution of this order does not change the current buffer address. --

NewLineKey: PROCEDURE [my:LptBufferData]; 
-- Implements the newline key.  It moves the cursor to the first unprotected character location of the next line.  If the display has no unprotected data fields, the cursor is repositioned to character location 0.  If the display contains no fields, the cursor is repositioned to the first character position of the next line. (The NewLineKey is similar to the TabKey, but for the fact that we start searching on the next line.) --

ProgramTab: PROCEDURE [my:LptBufferData,bvInsertNulls: Bv]
			 RETURNS [bvInsertingNulls: Bv ← FALSE];
 -- This order advances the current buffer address to the address of the first character position of the next unprotected field.  If the PT is issued when the current buffer address is the location of an attribute byte of an unprotected field, the buffer address advances to the next location of that field. (one location.) If 'bvInsertNulls' is TRUE nulls are inserted in the buffer from the current buffer address to the end of the field, regardless of whether or not the current field is protected. If 'bvInsertNulls' is FALSE, then the buffer content is not modified for that field.  The PT order stops its search at the last location in the buffer.  If an attribute character for an unprotected field is not found by this point, the buffer address is set to location 0. (If the PT order finds an attribute character for an unprotected field in the last buffer location, the buffer address is also set to zero.)  'bvInsertingNulls' is set to TRUE if the PT order was still inserting nulls in each character location when it terminated.  If a 2nd PT order follows, it should continue to insert nulls from buffer location 0 to the end of the current field. (if 'bvInsertingNulls' was TRUE, then 'bvInsertNulls' should be TRUE on next call.). --

PutChar: PROCEDURE [my:LptBufferData,aChar: CharDefs.Char,inputMode:InputStatus ← systemAvailable]
			RETURNS [aStatus:WriteError ← okay];
-- This procedure is called by the keyboard input processor. Overwriting attribute chars is not allowed.  Writing into protected fields is not allowed. Writing a non-numeric character into a numeric field is illegal. Upon entry of a character into the last character location of an unprotected data field, the cursor is repositioned according to the attributes of the next field. If the next field is (1) alphameric & either unprotected or protected, or (2) numeric & unprotected, the cursor skips the attribute character & is positioned to the 1st character location in that field. If the field is numeric & protected, the cursor skips that field & is postioned to the 1st character location of the next unprotected field. If legal put, then set MDT bit for field.  --

RepeatToAddress: PROCEDURE [my:LptBufferData,aChar:CharDefs.Char,stopAddress: CharPos];
-- This order stores the character specified by 'aChar' in all buffer locations, starting at the current buffer address and ending at (but not including) the specified stop address. Invalid stop addresses are detected by the command processor, so no error detection is required here.  When the stop address is lower than the current buffer address, this operation wraps from the bottom row of the buffer to the top row.  When the stop address equals the current address, the specified character is stored in all buffer locations.  Attribute characters will be overwritten if they occur before the specified stop address. --

ResetAllModified: PROCEDURE[my:LptBufferData];
-- All the MDT bits in the attribute bytes are cleared. --

ResetAllUnprotectedModified: PROCEDURE[my:LptBufferData];
-- All the MDT bits in the attribute bytes of unprotected fields are cleared. --

SetBufferAddress: PROCEDURE [my:LptBufferData,newCBA:CharPos];
-- This order specifies a new buffer address from which write operations are to start or continue.  The command processor will check for invalid addresses in the command streams, and will call the buffer manager with valid addresses for 'newCBA'.

SetBufferAddressAndCursor: PROCEDURE [my:LptBufferData,
  						newCBAAndCursor:CharPos];
-- Sets both the CBA and cursor. --

SetCursor: PROCEDURE[my:LptBufferData,newCursor: CharPos,bvDisplayCursor:Bv ← TRUE];
-- Sets the position of the cursor on the screen, if 'bvDisplayCursor' is TRUE, and updates the auxilliary variable 'bufferAddress[keyMode]' used to keep track of the cursor position.  'bufferAddress[keyMode]' and the actual position of the cursor on the display should always be equal. (i.e. Use 'SetCursor' always, and not 'VDTDefs.SetCursorPos' alone.) --
	 
StartField: PROCEDURE [my:LptBufferData,newAttrib: CHARACTER];
-- Store attribute byte in high-order byte of word. The ESC char. is stored in the low-order byte to identify this word as an attribute.The attribute parameters are set and the buffer address is incremented. --

TabKey: PROCEDURE [my:LptBufferData];
-- Implements the tab key. It moves the cursor to the first character location of the next unprotected data field.  In a display with no unprotected fields, the cursor is repositioned to character location 0.  The cursor wraps from the end of the last line on the display and continues at the beginning of the top line if necessary.-- 

UpdateStatus: PROCEDURE [my:LptBufferData];
--  This procedure should be called by Command Processor at end of processing each burst of data from IBM host.
--  This procedure would update all the necessary Instance Data before someone else Reserves the buffer.
--  Currently only my.bvIsFormatted needs to be updated.

WriteBlock: PROCEDURE [my:LptBufferData,aBlock:--CmdDefs.-- LptTextRun,nChars:CharPos,aMode:AccessMode];
-- Called by the command processor. A block of characters is written into the buffer starting at the appropriate  buffer address (specified by 'aMode').  The address of the block of characters is specified by 'aBlock', and the number of characters to be stored is 'nChars'. After this call, the buffer address points to the location after the last location stored into. --

WriteChar: PROCEDURE [my:LptBufferData,aChar: CharDefs.Char,aMode:AccessMode];
-- This procedure is called by the command processor. Overwriting attribute chars. and protected fields is legal. The buffer address is incremented after writing.  --

-- ============
-- Program --
-- ============

Em3270BufferPack: PRIVATE PROGRAM;

END.

LOG

Jan. 11, 1982 - Stepak - Created from the ASD Buffer3278 source file
Jan. 29, 1982 - Stepak - Compiled successfully. Added buffer handles to
			procs. Added status param to buffer instance data.
Feb 2, 1982 - Stepak - added 2 zone handles.
Feb 8, 1982 - Stepak - put zone handles in pack.
Feb 16, 1982 - Stepak - changes params for SetBufferAddress,DisplayBuffer,ClearBuffer,StartField
Feb. 23,1982 - Stepak - added 'clientData' param to EnumFields & EnumAll... 
March 24, 1982 - Stepak - updated comments.
April 1, 1982 - Stepak - updated comments in 'StartField' to correspond with fix of AR #6326
April 2, 1982 - Stepak -updated comments in 'StartField' to correspond with 2nd fix of AR #6326
15-Jun-82 17:17:26  - Lui  - Added the procedure UpdateStatus.
 4-Aug-82 14:27:46  - Lui  - merge with Star2.1ar
 1-Sep-82  9:50:36  - Lui  - added hostLang to Create.
 9-Sep-82 16:52:24  - Lui  - changed hostLang in Create to lptToTransFil
30-Jun-83 14:23:59  - Lui  - added the parm currentPos to EnumFields(support for Read Modified)