|
|
DataMuseum.dkPresents historical artifacts from the history of: CR80 Hard and Floppy Disks |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CR80 Hard and Floppy Disks Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 8848 (0x2290)
Types: TextFile
Names: »CH.IO.S«
└─⟦e12128f26⟧ Bits:30005200 8" Zilog MCZ/1 Floppy CR80FD_0026 ( TC 500 SEC. PROTOCOL BB V1 830407 NCJ )
└─⟦this⟧ »CH.IO.S«
!******************************************************************************
*
* CHANNEL_INPUT_OUTPUT MODULE
*
******************************************************************************!
CHANNEL_INPUT_OUTPUT MODULE
TYPE
BUFFER RECORD
[BUFF_HEAD ARRAY[4 WORD]
STAADR ^BYTE
DATA ARRAY[504 BYTE]]
REC_PTR ^BUFFER
CONFIG_TABLE ARRAY[10,4 BYTE]
CONFIG_TAB_PTR ^CONFIG_TABLE
QUEU_HEAD ARRAY[8 BYTE]
QUEU_HEAD_PTR ^QUEU_HEAD
PWQ_HEAD ARRAY[8 BYTE]
PWQ_PTR ^PWQ_HEAD
TRQ_HEAD ARRAY[8 BYTE]
TRQ_PTR ^TRQ_HEAD
PARAM_TABLE RECORD
[B ARRAY[20 BYTE]
W QUEU_HEAD_PTR
P CONFIG_TAB_PTR
PWQ PWQ_PTR
TRQ TRQ_PTR]
DATA_PTR ^PARAM_TABLE
PROCESS_TABLE RECORD
[B ARRAY[4 BYTE]
POLL_RATE WORD]
TABLE_PTR ^PROCESS_TABLE
CONSTANT
NO_CADERROR := 0
TRUE := %FF
FALSE := 0
OK := %0
LOOP_CODE := %31
EOT := 4
POL := %70
FSL := %73
CON := %07
ACK := %06
NACK := %15
DATA := 0
NO_OF_CLUSTERS := 10
OVERLOAD := %FF
EMPTY := 0
! CONSTANTS REFERRING TO OFFSET IN BUFFER !
STATUS_OFFSET := 2
P_C1 := 5
P_C2 := 6
D_C1 := 26
D_C2 := 25
DATA1_OFFSET := 13
DATA2_OFFSET := 14
LOOP_OFFSET := 27
TYPE_OFFSET := 4
EOT_OFFSET := 7
! CONSTANTS REFERRING TO OFFSET IN PARAMETER TABLE !
CR80_RESP_QUEU := 0
CH_NO := 6
CAD1 := 12
CAD2 := 13
ACK_STATUS := 16
! CONSTANTS REFERRING TO OFFSET IN PROCESS TABLE !
POLL_COMMAND := 0
EXTERNAL
TRQBUF PROCEDURE (CAD1,CAD2 BYTE,TRQ TRQ_PTR) RETURNS (BUF_PTR REC_PTR)
PUTBUF PROCEDURE (QUEU_ADDRESS QUEU_HEAD_PTR,BUF_PTR REC_PTR)
PUTPWQ PROCEDURE (QUEU_ADDRESS PWQ_PTR,BUF_PTR REC_PTR)
CHECK_CAD PROCEDURE (CAD1,CAD2 BYTE,PCT CONFIG_TAB_PTR) RETURNS (STATUS BYTE)
CL_ACCESS_INDIC PROCEDURE (I BYTE,PCT CONFIG_TAB_PTR,P DATA_PTR)
TX PROCEDURE (BUF_PTR REC_PTR,COMMAND BYTE,P DATA_PTR)
INOUT PROCEDURE (BUF_PTR REC_PTR)
GETBUF PROCEDURE (QUEU_ADDRESS QUEU_HEAD_PTR) RETURNS (BUF_PTR REC_PTR)
POLOVL PROCEDURE (P DATA_PTR) RETURNS (STATUS BYTE)
PUTMES PROCEDURE (QUEU_NO BYTE,BUF_PTR REC_PTR)
PWQBUF PROCEDURE (CAD1,CAD2 BYTE,PWQ PWQ_PTR) RETURNS (BUF_PTR REC_PTR)
CR80BUF PROCEDURE (BUF_PTR REC_PTR,P DATA_PTR)
DLCBUF PROCEDURE (BUF_PTR REC_PTR,DLC BYTE)
STAMP PROCEDURE (BUF_PTR REC_PTR,CH_NO BYTE)
ACCUM PROCEDURE (BUF_PTR REC_PTR,CH_NO BYTE)
DECREM PROCEDURE (BUF_PTR REC_PTR) RETURNS (STATUS BYTE)
GET_CAD PROCEDURE (PCT CONFIG_TAB_PTR) RETURNS (CL_NO,CAD1,CAD2 BYTE)
POLENQ PROCEDURE (BUF_PTR REC_PTR,CAD1,CAD2 BYTE)
!ECHO \f
!
INTERNAL
!*****************************************************************************
* PROCEDURE :POLL
*
* FUNCTION : THE PROCEDURE MANAGES THE GROUP POLL HANDLING OF CLUSTERS
*
* INPUTS : T : POINTER TO PROCESS TABLE
* P : POINTER TO PARAMETER TABLE
*
* OUTPUTS : NONE
****************************************************************************!
POLL PROCEDURE (T TABLE_PTR,P DATA_PTR)
LOCAL
OUTPUT_BUF_PTR REC_PTR
I BYTE
ENTRY
! RESET ACK STATUS !
P^.B[ACK_STATUS] := FALSE
DO
IF T^.B[POLL_COMMAND] = FALSE THEN EXIT FI
! IF CLUSTER STATUS = DOWN THEN EXIT !
I := CHECK_CAD (P^.B[CAD1],P^.B[CAD2],P^.P)
IF I = NO_OF_CLUSTERS THEN EXIT FI
! GET BUFFER IN POLL WAITING QUEUE !
OUTPUT_BUF_PTR := PWQBUF (P^.B[CAD1],P^.B[CAD2],P^.PWQ)
! IF NO BUFFERS THEN TERMINATE TRANSMISSION !
IF OUTPUT_BUF_PTR = NIL THEN
OUTPUT_BUF_PTR := GETBUF (P^.W)
DLCBUF (OUTPUT_BUF_PTR,EOT)
TX (OUTPUT_BUF_PTR,EOT,P)
EXIT
ELSE
! SET ACK STATUS !
P^.B[ACK_STATUS] := TRUE
! TIME STAMP BUFFER !
STAMP (OUTPUT_BUF_PTR,P^.B[CH_NO])
! TRANSMIT DATA BUFFER ON LINE !
TX (OUTPUT_BUF_PTR,DATA,P)
EXIT
FI
OD
END POLL
GLOBAL
!ECHO \f
!
!****************************************************************************
* PROCEDURE : CHANNEL_IO
*
* FUNCTION : THE PROCEDURE RECEIVES BUFFERS FROM LINE (GROUP POLL, FAST
* SELECT, CONTENTION POLL, ACK, NACK) AND TAKES THE NECESSARY
* ACTION
*
* INPUTS : BUF_PTR : POINTER TO RECEIVE BUFFER
* T : POINTER TO PROCESS TABLE
* P : POINTER TO PARAMETER TABLE
*
* OUTPUTS : NONE
***************************************************************************!
CHANNEL_IO PROCEDURE (BUF_PTR REC_PTR,T TABLE_PTR,P DATA_PTR)
LOCAL
OUTPUT_BUF_PTR REC_PTR
I,OPCODE,CL_AD1,CL_AD2 BYTE
ENTRY
DO
! IF BUFFER STATUS NOT OK THEN EXIT !
IF BUF_PTR^.BUFF_HEAD[STATUS_OFFSET] <> OK THEN
PUTBUF (P^.W,BUF_PTR)
EXIT
FI
OPCODE := BUF_PTR^.DATA[TYPE_OFFSET]
IF OPCODE
!*****************************************************************************!
CASE EOT THEN
! RESET ACK STATUS !
P^.B[ACK_STATUS] := FALSE
DO
! TRANSFER BUFFERS FROM TRANSM.QUEUE TO POLL WAITING QUEUE !
OUTPUT_BUF_PTR := TRQBUF (EMPTY,EMPTY,P^.TRQ)
IF OUTPUT_BUF_PTR = NIL THEN EXIT FI
PUTPWQ (P^.PWQ,OUTPUT_BUF_PTR)
OD
OPCODE := BUF_PTR^.DATA[EOT_OFFSET]
IF OPCODE
!****************************************************************************!
CASE POL THEN
! UPDATE CAD1,CAD2 INDICATION IN PARAMETER TABLE !
P^.B[CAD1] := BUF_PTR^.DATA[P_C1]
P^.B[CAD2] := BUF_PTR^.DATA[P_C2]
IF T^.B[POLL_COMMAND] = TRUE THEN
! GET INDEX NO. OF CLUSTER IN CONFIGURATION TABLE !
I := CHECK_CAD (P^.B[CAD1],P^.B[CAD2],P^.P)
! IF CLUSTER FOUND THEN SET CLUSTER ACCESS INDICATION !
IF I <> NO_OF_CLUSTERS THEN
CL_ACCESS_INDIC (I,P^.P,P)
FI
FI
! RETURN POLL BUFFER TO EMPTY BUFFER QUEUE !
PUTBUF (P^.W,BUF_PTR)
POLL (T,P)
!*****************************************************************************!
CASE FSL THEN
DO
! IF TERMINATION MESSAGE THEN ACK MESSAGE !
IF BUF_PTR^.DATA[DATA1_OFFSET] = %30 ANDIF BUF_PTR^.DATA[DATA2_OFFSET] = %49 THEN
DLCBUF (BUF_PTR,ACK)
TX (BUF_PTR,ACK,P)
EXIT
FI
! ACCUMULATE TIME IN BUFFER !
ACCUM (BUF_PTR,P^.B[CH_NO])
! REFORMAT BUFFER !
INOUT (BUF_PTR)
! GET INDEX NO. OF CLUSTER IN CONFIGURATION TABLE !
I := CHECK_CAD (BUF_PTR^.DATA[D_C1],BUF_PTR^.DATA[D_C2],P^.P)
! IF CLUSTER NOT FOUND THEN EXIT !
IF I = NO_OF_CLUSTERS THEN
DLCBUF (BUF_PTR,ACK)
TX (BUF_PTR,ACK,P)
EXIT
ELSE
IF T^.B[POLL_COMMAND] = TRUE THEN
! SET CLUSTER ACCESS INDICATION !
CL_ACCESS_INDIC (I,P^.P,P)
FI
FI
! CHECK LOOP INDICATION !
IF BUF_PTR^.DATA[LOOP_OFFSET] = LOOP_CODE THEN
IF DECREM (BUF_PTR) <> 0 THEN
IF POLOVL (P) <> OVERLOAD THEN
! IF NO POLL BUFFER OVERLOAD THEN ENQUE BUFFER IN POLL W.QUEUE !
PUTPWQ (P^.PWQ,BUF_PTR)
! ACK MESSAGE !
OUTPUT_BUF_PTR := GETBUF (P^.W)
DLCBUF (OUTPUT_BUF_PTR,ACK)
TX (OUTPUT_BUF_PTR,ACK,P)
ELSE
! NACK MESSAGE !
DLCBUF (BUF_PTR,NACK)
TX (BUF_PTR,NACK,P)
FI
ELSE
! SEND BUFFER TO CR80 !
CR80BUF (BUF_PTR,P)
FI
ELSE
! SEND BUFFER TO CR80 !
CR80BUF (BUF_PTR,P)
FI
EXIT
OD
!****************************************************************************!
CASE CON THEN
I,CL_AD1,CL_AD2 := GET_CAD (P^.P)
IF I <> NO_OF_CLUSTERS THEN
! REPLY ON CONTENTION BUFFER !
POLENQ (BUF_PTR,CL_AD1,CL_AD2)
TX (BUF_PTR,POL,P)
ELSE
! ENQUE BUFFER IN EMPTY BUFFER QUEUE !
PUTBUF (P^.W,BUF_PTR)
FI
ELSE
PUTBUF (P^.W,BUF_PTR)
FI
!*****************************************************************************!
CASE ACK THEN
PUTBUF (P^.W,BUF_PTR)
! TRANSFER BUFFERS FROM TRANSM.QUEUE TO EMPTY QUEUE !
DO
OUTPUT_BUF_PTR := TRQBUF (EMPTY,EMPTY,P^.TRQ)
IF OUTPUT_BUF_PTR = NIL THEN EXIT FI
PUTBUF (P^.W,OUTPUT_BUF_PTR)
OD
! IF ACK STATUS SET DO POLL PROCEDURE !
IF P^.B[ACK_STATUS] = TRUE THEN
POLL (T,P)
FI
!*****************************************************************************!
CASE NACK THEN
! RETURN NACK BUFFER TO EMPTY BUFFER QUEUE !
PUTBUF (P^.W,BUF_PTR)
! IF ACK STATUS SET THEN RETRANSMIT DATA BUFFER !
IF P^.B[ACK_STATUS] = TRUE THEN
OUTPUT_BUF_PTR := TRQBUF (EMPTY,EMPTY,P^.TRQ)
IF OUTPUT_BUF_PTR <> NIL THEN
! TIME STAMP BUFFER !
STAMP (OUTPUT_BUF_PTR,P^.B[CH_NO])
! RETRANSMIT BUFFER !
TX (OUTPUT_BUF_PTR,DATA,P)
ELSE
! RESET ACK STATUS !
P^.B[ACK_STATUS] := FALSE
FI
FI
!****************************************************************************!
ELSE
PUTBUF (P^.W,BUF_PTR)
FI
EXIT
OD
END CHANNEL_IO
END CHANNEL_INPUT_OUTPUT
!ECHO \f
!