with COMMON_TO_BOTH_488; use COMMON_TO_BOTH_488; with HW_SPECIFIC_TERMINAL_488; use HW_SPECIFIC_TERMINAL_488; with HW_SPECIFIC_EVENT_488; use HW_SPECIFIC_EVENT_488; with VAX_DEFS; use VAX_DEFS; with CONDITION_HANDLING; use CONDITION_HANDLING; with STARLET; use STARLET; with UNCHECKED_DEALLOCATION; with UNCHECKED_CONVERSION; with CONVERSIONS; use CONVERSIONS; with CALENDAR; use CALENDAR; package body TERMINAL_488 is task body TERMINAL_488_TASK is RCV_PTR : MESSAGE_POINTER; SERVICE_REQUEST_INFO : SERIAL_POLL_RECORD; STATUS : STATUS_TYPE; STATUS_RET : COND_VALUE_TYPE; INTERFACE_WAS_CLEARED : BOOLEAN := FALSE; TERMINAL_POLL_TIME : DURATION := 86400.0; NEXT_POLL_TIME : TIME; TRANSMITTED_LAST_POLL : BOOLEAN := FALSE; type AST_TYPE is record EVENT : MESSAGE_ID_TYPE; RELATED_INFO : DATA_BYTE; UNIT_NUMBER : DATA_BYTE; FILL : system.unsigned_byte; end record; for AST_TYPE use record EVENT at word*0 range 0..7; RELATED_INFO at word*0 range 8..15; UNIT_NUMBER at word*1 range 0..7; FILL at word*1 range 8..15; end record; AST_INFO : AST_TYPE; START_AST_IOSB : IOSB_RECORD := (STATUS => 0, FN_SPECIFIC => 0, STATUS_REGISTER => (others => FALSE), CONTROLLER_STATE => 0,FILL => 0, ADDRESSED_STATE => 0); pragma VOLATILE (START_AST_IOSB); function CONVERT_TO_AST_RECORD is new UNCHECKED_CONVERSION(SYSTEM.UNSIGNED_LONGWORD,AST_TYPE); procedure RELEASE is new UNCHECKED_DEALLOCATION (MESSAGE_LINK, MESSAGE_POINTER); procedure START_TERMINAL_AST is begin for I in 1..10 loop QIO(STATUS => STATUS_RET, EFN => EFLAG, CHAN => CHANNEL, FUNC => (VAX_DEFS.IO_SETMODE+VAX_DEFS.IO_M_ATTNAST+ IO_M_BUFFERED), IOSB => START_AST_IOSB'address, P1 => SYSTEM.TO_UNSIGNED_LONGWORD (TERMINAL_488_TASK.BUS_EVENT'ast_entry)); exit when STATUS_RET = STARLET.SS_NORMAL; end loop; end START_TERMINAL_AST; procedure REQUEST_SERVICE(SERVICE_REQUEST : SERVICE_REQUEST_TYPE) is begin SERVICE_REQUEST_INFO.SERVICE := SERVICE_REQUEST; SERVICE_REQUEST_INFO.REQUESTING_SERVICE := TRUE; -- must toggle -- And now send the request with the SRQ line pulled true. HW_SERVICE_REQUEST(SERVICE_REQUEST_INFO); end REQUEST_SERVICE; procedure RECEIVE_MESSAGE is --\ This procedure is called when the interface receives the command --\ ADDRESSED_AS_LISTENER from the interface bus. The procedure will --\ generate a new link in the RECEIVE_QUEUE, call a hardware specific --\ routine to get the message, and release the RECEIVE task so the message --\ can be sent to the user. COUNT : INTEGER_16 := 0; --Number of received bytes. STATUS : STATUS_TYPE := 0; begin HW_RECEIVE_MESSAGE(COUNT, STATUS); if STATUS = OK and COUNT > 0 then declare RECEIVED_MESSAGE : GENERAL_488_MESSAGE(COUNT); begin RECEIVED_MESSAGE.MESSAGE := RECEIVED_MESSAGE_PTR.MESSAGE.MESSAGE(1..COUNT); RCV_PTR := new MESSAGE_LINK' (null, 0.0, I488_IO_TRIES, RECEIVED_MESSAGE); QUEUE_TASK.QUEUE(RECEIVE_QUEUE, RCV_PTR); end; select IO_488.UNLOCK; else null; end select; end if; end RECEIVE_MESSAGE; begin accept START; INITIALIZE; RECEIVED_MESSAGE_PTR := new MESSAGE_LINK; NEXT_POLL_TIME := CLOCK + TERMINAL_POLL_TIME; START_TERMINAL_AST; loop select accept BUS_EVENT(AST_INFORMATION : system.unsigned_longword) do AST_INFO := CONVERT_TO_AST_RECORD(AST_INFORMATION); end BUS_EVENT; START_TERMINAL_AST; case AST_INFO.EVENT is when ADDRESSED_AS_LISTENER => -- terminal only RECEIVE_MESSAGE; when ADDRESSED_AS_TALKER => -- terminal only HW_SEND(SEND_QUEUE, STATUS); SEND_QUEUE.NEXT.IO_TRIES := SEND_QUEUE.NEXT.IO_TRIES - 1; if STATUS = OK or SEND_QUEUE.NEXT.IO_TRIES = 0 then QUEUE_TASK.DEQUEUE(SEND_QUEUE); end if; when INTERFACE_CLEAR => -- terminal only INTERFACE_WAS_CLEARED := TRUE; when others => null; end case; or accept TERMINAL_POLLING_RATE(POLL_TIME : in DURATION) do TERMINAL_POLL_TIME := POLL_TIME; end TERMINAL_POLLING_RATE; or delay NEXT_POLL_TIME - CLOCK; if INTERFACE_WAS_CLEARED then if SEND_QUEUE.NEXT = null or TRANSMITTED_LAST_POLL then REQUEST_SERVICE(0); TRANSMITTED_LAST_POLL := FALSE; else REQUEST_SERVICE(QUEUE_COUNT(SEND_QUEUE)); TRANSMITTED_LAST_POLL := TRUE; end if; end if; end select; NEXT_POLL_TIME := CLOCK + TERMINAL_POLL_TIME; end loop; end TERMINAL_488_TASK; end TERMINAL_488;