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 UNCHECKED_DEALLOCATION; with UNCHECKED_CONVERSION; with CONVERSIONS; use CONVERSIONS; with CALENDAR; use CALENDAR; with PC_HW_488; use PC_HW_488; package body TERMINAL_488 is task body TERMINAL_488_TASK is RCV_PTR : MESSAGE_POINTER; SERVICE_REQUEST_INFO : SERIAL_POLL_RECORD; STATUS : STATUS_TYPE; INTERFACE_WAS_CLEARED : BOOLEAN := FALSE; TERMINAL_POLL_TIME : DURATION := 86400.0; NEXT_POLL_TIME : TIME; TRANSMITTED_LAST_POLL : BOOLEAN := FALSE; THE_EVENT : PC_STATUS_TYPE; THE_SERVICE_MASK : INTEGER_16 := 0; procedure RELEASE is new UNCHECKED_DEALLOCATION (MESSAGE_LINK, MESSAGE_POINTER); 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, 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; loop WAIT_FOR_EVENT(THE_EVENT'address, THE_SERVICE_MASK); -- exit when THE_EVENT.HW_STATUS(ATN); exit when STATUS_BIT_SET(THE_EVENT,ATN); delay 0.02; end loop; -- -- interface cleared? -- if THE_EVENT.HW_STATUS(DCAS) and then not(OLD_DCAS) then -- INTERFACE_WAS_CLEARED := TRUE; -- end if; -- -- update the old for next loop -- OLD_DCAS := THE_EVENT.HW_STATUS(DCAS); NEXT_POLL_TIME := CLOCK + TERMINAL_POLL_TIME; loop select 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; -- addressed as listener loop WAIT_FOR_EVENT(THE_EVENT'address, THE_SERVICE_MASK); -- if THE_EVENT.HW_STATUS(LACS) and then not(OLD_LACS) then if STATUS_BIT_SET(THE_EVENT,LACS) and then not(OLD_LACS) then RECEIVE_MESSAGE; end if; -- update the old for next loop -- OLD_LACS := THE_EVENT.HW_STATUS(LACS); OLD_LACS := STATUS_BIT_SET(THE_EVENT,LACS); exit when (NEXT_POLL_TIME + TERMINAL_POLL_TIME) - CLOCK <= 0.0; delay 0.02; end loop; else REQUEST_SERVICE(QUEUE_COUNT(SEND_QUEUE)); TRANSMITTED_LAST_POLL := TRUE; loop WAIT_FOR_EVENT(THE_EVENT'address, THE_SERVICE_MASK); -- addressed as talker -- if THE_EVENT.HW_STATUS(TACS) and then not(OLD_TACS) then if STATUS_BIT_SET(THE_EVENT,TACS) and then not(OLD_TACS) then HW_SEND(SEND_QUEUE, STATUS); if STATUS = OK then QUEUE_TASK.DEQUEUE(SEND_QUEUE); end if; end if; -- OLD_TACS := THE_EVENT.HW_STATUS(TACS); OLD_TACS := STATUS_BIT_SET(THE_EVENT,TACS); exit when QUEUE_COUNT(SEND_QUEUE) = 0; delay 0.02; end loop; end if; end if; end select; NEXT_POLL_TIME := CLOCK + TERMINAL_POLL_TIME; end loop; end TERMINAL_488_TASK; end TERMINAL_488;