10 SUB EXT_PROC_BUF_AST(LONG MY_BUFFER_PAR, DUM2, DUM3, DUM4, DUM5) !====================================================================== !PROGRAM---------------------VERSION-------------------LANGUAGE-------- !EXT_PROC_BUF_AST 4 BASIC ! !DESCRIPTION----------------------------------------------------------- !AST to run when data is available in an input buffer (MY_BUFFER). !Writes buffer to terminal and either requeues another port read if !more data is expected or an unsolicited input mailbox read if no more !is expected. ! !====================================================================== %TITLE "Port read AST routine" %IDENT "EXT_PROC_BUF_AST 92.11.02" %SBTTL "DOCUMENTATION SECTION" !********************************************************************** ! OPTIONS !********************************************************************** OPTION TYPE = EXPLICIT ! Explicit declarations only 100 !********************************************************************** ! DOCUMENTATION SECTION !********************************************************************** ! !====================================================================== ! MODIFICATION HISTORY !====================================================================== !VERSION--------AUTHOR------------------DATE------------APPROVAL------- ! 1 Keith Walker 88.02.04 1723 ! 2 Keith Walker 89.06.09 M102_0_49 ! 3 Keith Walker 89.06.16 M102_0_55 ! 4 Keith Walker 92.11.02 E102ISD_0_30 ! !====================================================================== ! COMPILE/LINK INSTRUCTIONS !====================================================================== !$BASIC EXT_PORT_READ_AST !$LINK 102900,- ! EXT_READ_PORT_AST, EXT_UNSOL_MBX_AST,- ! EXT_PROC_BUF_AST, EXT_WRITE_TERM_AST,- ! EXT_SCRIPT_INTERP, EXT_SCREEN_HDR,- ! EXT_MENU, EXT_CONNECT_LOOP, EXT_PARSE,- ! CHKRGHTS, EXT_FT_MENU, XMODEM !====================================================================== !********************************************************************** ! FILES ACCESSED !********************************************************************** ! NAME MODE CHANNEL DESCRIPTION !-------------- ------ ------- ------------------------------- ! !********************************************************************** %PAGE %SBTTL "DECLARATION SECTION" 200 !====================================================================== ! DECLARATION SECTION !====================================================================== !********************************************************************** ! DECLARATIONS FROM %INCLUDE FILES !********************************************************************** %INCLUDE "EXT_COMMON.BAS" !********************************************************************** ! CONSTANTS !********************************************************************** !********************************************************************** ! RECORDS !********************************************************************** !********************************************************************** ! MAPS !********************************************************************** !********************************************************************** ! COMMONS !********************************************************************** !********************************************************************** ! VARIABLES !********************************************************************** DECLARE LONG & I, & FUNC_STAT, !function return status & MY_BUFFER !buffer number DECLARE QUAD & TIMEOUT !timeout for requeue !********************************************************************** ! ARRAYS !********************************************************************** !********************************************************************** ! FUNCTIONS !********************************************************************** !********************************************************************** ! EXTERNAL CONSTANTS !********************************************************************** EXTERNAL LONG CONSTANT & IO$_READVBLK, & IO$_WRITEVBLK, & IO$M_NOECHO, & IO$M_TIMED, & SS$_ABORT, & SS$_BADESCAPE, & SS$_NORMAL, & SS$_PARTESCAPE, & SS$_TIMEOUT !********************************************************************** ! EXTERNAL FUNCTIONS !********************************************************************** EXTERNAL LONG & EXT_READ_PORT_AST, & EXT_WRITE_TERM_AST, & EXT_UNSOL_MBX_AST EXTERNAL LONG FUNCTION & SYS$BINTIM, & SYS$SETIMR, & SYS$QIO, & SYS$DCLAST !********************************************************************** ! EXTERNAL SUBPROGRAMS !********************************************************************** %PAGE %SBTTL "INITIALIZATION SECTION" 300 !====================================================================== ! INITIALIZATION SECTION !====================================================================== ON ERROR GOTO ERROR_HANDLING !********************************************************************** ! PRINT USING FORMATS !********************************************************************** !********************************************************************** ! VARIABLES !********************************************************************** MY_BUFFER = LOC(MY_BUFFER_PAR) !********************************************************************** ! FILE OPENS !********************************************************************** %PAGE %SBTTL "MAIN LOGIC SECTION" 1000 !====================================================================== ! MAIN LOGIC SECTION !====================================================================== !we are here because we got either data or an error on the port... DBG_READ_CNT = DBG_READ_CNT + 1 !check for error... IF (PORT_BUF(MY_BUFFER)::IOSB(IOSB_STATUS) AND 1%) = 0% THEN IF PORT_BUF(MY_BUFFER)::IOSB(IOSB_STATUS) <> SS$_TIMEOUT AND & PORT_BUF(MY_BUFFER)::IOSB(IOSB_STATUS) <> SS$_PARTESCAPE AND & PORT_BUF(MY_BUFFER)::IOSB(IOSB_STATUS) <> SS$_BADESCAPE THEN PORT_BUF(MY_BUFFER)::BUF_IN_USE = FALSE !release the buffer BUFS_USED = BUFS_USED - 1% GOTO QUEUE_MBX_READ END IF END IF !determine the number of bytes in the buffer... PORT_BUF(MY_BUFFER)::BUF_CNT = PORT_BUF(MY_BUFFER)::IOSB(IOSB_BUF_LEN) !if there is a terminator, include it in buffer count... IF PORT_BUF(MY_BUFFER)::IOSB(IOSB_TERM) <> 0% THEN PORT_BUF(MY_BUFFER)::BUF_CNT = PORT_BUF(MY_BUFFER)::BUF_CNT + & PORT_BUF(MY_BUFFER)::IOSB(IOSB_TERM_SIZE) END IF !if buffer is empty (we timed out), restart unsolicited input wait... IF PORT_BUF(MY_BUFFER)::BUF_CNT = 0% THEN PORT_BUF(MY_BUFFER)::BUF_IN_USE = FALSE !release the buffer BUFS_USED = BUFS_USED - 1% GOTO QUEUE_MBX_READ ELSE !count for debugging... DBG_DATA_CNT = DBG_DATA_CNT + 1 DBG_BYTE_CNT = DBG_BYTE_CNT + PORT_BUF(MY_BUFFER)::BUF_CNT END IF !for seven-bit input, strip parity bit... IF SEVENBIT_FLAG THEN FOR I = 0 TO PORT_BUF(MY_BUFFER)::BUF_CNT - 1 PORT_BUF(MY_BUFFER)::BUF_FER(I) = & PORT_BUF(MY_BUFFER)::BUF_FER(I) AND 127% NEXT I END IF IF VIEW_FLAG THEN !write the buffer to the terminal... FUNC_STAT = SYS$QIO(!efn!, & TERM_CHAN BY VALUE, & IO$_WRITEVBLK BY VALUE, & PORT_BUF(MY_BUFFER)::IOSB(IOSB_STATUS) BY REF, & EXT_WRITE_TERM_AST BY REF, MY_BUFFER BY VALUE, & PORT_BUF(MY_BUFFER)::BUF_FER(0) BY REF, & PORT_BUF(MY_BUFFER)::BUF_CNT BY VALUE, & !p3!, !p4!, !p5!, !p6!) ELSE !we don't write to the terminal, but we want to do the AST anyway... FUNC_STAT = SYS$DCLAST(EXT_WRITE_TERM_AST BY REF, & MY_BUFFER BY VALUE, !acmode!) END IF IF (FUNC_STAT AND 1%) = 0% THEN !If we can't write the buffer, we can give up on it, but before we !do, we must return it to the pool of free buffers... PORT_BUF(MY_BUFFER)::BUF_IN_USE = FALSE !release the buffer BUFS_USED = BUFS_USED - 1% END IF !---------------------------------------------------------------------- !If buffer was fairly full (>= 5 char), set timer to 0 (immediate), !otherwise wait 1/20 sec. ! !The objective here is to continue reading fast if data is coming in !fast, but not to burn up more CPU time than we have to. We assume !that if we have received more than 5 characters, there is probably !more stuff waiting for us in the typeahead buffer. In that case, we !want to get it right away. If there were less than 5 characters, we !have probably caught up to the modem, so we can delay to give the !modem time to send us a few more characters. ! !On a VAX 11/750, the delay is probably unnecessary, since the elapsed !time involved in reading the current buffer will be long enough to !give us a good chance of having received more characters. On a faster !CPU (e.g. an 8600), however, we might end up in a tight loop, reading !only 1 or 2 characters per iteration, and blow away a lot of CPU time, !so we wait a bit. !---------------------------------------------------------------------- IF PORT_BUF(MY_BUFFER)::BUF_CNT >= 5% THEN FUNC_STAT = SYS$BINTIM("0 00:00:00", TIMEOUT) DBG_NODELAY_CNT = DBG_NODELAY_CNT + 1 ELSE FUNC_STAT = SYS$BINTIM("0 00:00:00.05", TIMEOUT) DBG_DELAY_CNT = DBG_DELAY_CNT + 1 END IF REQUEUE_MYSELF: GOTO END_OF_PROGRAM IF NOT CONT_FLAG BUF_ATTEMPTS = 0% FUNC_STAT = SYS$SETIMR(!efn!, TIMEOUT, EXT_READ_PORT_AST, & READ_PORT_TIMER BY VALUE) GOTO END_OF_PROGRAM IF (FUNC_STAT AND 1%) = 1% !OK QUEUE_MBX_READ: GOTO END_OF_PROGRAM IF NOT CONT_FLAG DBG_UNSOL_CNT = DBG_UNSOL_CNT + 1 MBX_ACTIVE = TRUE FUNC_STAT = SYS$QIO(!efn!, & MBX_CHAN BY VALUE, & IO$_READVBLK BY VALUE, & MBX_IOSB(0%) BY REF, & EXT_UNSOL_MBX_AST BY REF, , & MBX_BUF BY REF, & MAX_MBX_SIZE BY VALUE, , , , ) GOTO END_OF_PROGRAM %PAGE %SBTTL "SUBROUTINE DEFINITION SECTION" 15000 !====================================================================== ! SUBROUTINE DEFINITION SECTION !====================================================================== %PAGE %SBTTL "FUNCTION DEFINITION SECTION" 20000 !====================================================================== ! FUNCTION DEFINITION SECTION !====================================================================== %PAGE %SBTTL "ERROR HANDLING SECTION" 25000 !====================================================================== ! ERROR HANDLING SECTION !====================================================================== ERROR_HANDLING: ON ERROR GOTO 0 !====================================================================== ! END OF PROGRAM !====================================================================== END_OF_PROGRAM: 32767 END SUB