%- - - - - - - - - - - - - - - - -% 27.09.88 VERSION 56
%-      DX   -%
%- - - - - - - - - - - - - - - - -%
LOCALS :DX
  DATA ATICK,AITREQ
%%DATA INITFL=0
  DATA BUFFER(&80)                      %"" 
  DATA CIO=0,IOBUFF(&100),IOLENG=&100,IOSECT=0
  DATA A:PHIS                           %  . 

  EQUALS ERROR=&8000,INIBIT=&4000
  EQUALS READY=&80,ITEN=&40,DONE=&20,UNIT=&10,FUNC=&0E,GO=&01
  DATA DXERR=ERROR,INIT=INIBIT          %  CSR

  EQUALS DRVRDY=&80
  EQUALS ESECTO=&20,ETRACK=&28          % 

  EQUALS QTRACK=&4D,QSECT=&1A

  EQUALS ITADDR=&B4,ITPRI=4             % , 
  DATA A:CSR=&FE78 ,A:DBR=&FE7A         %  
  DATA CSR  ,DBR                        %  
  DATA ASECT ,ATRACK ,STATUS ,ECODES    % 
  DATA DATIND                           %  

  DATA WAIDAT,WAIGET                    %  

  DATA MARK ,BUSDAT
%                                       %  
  DATA TASKS=WRBUFF.RDBUFF.WRSECT.RDSECT.NILTSK.RDSTAT.WRBAD.RDERR
  DATA WMASK=INIBIT+ITEN+UNIT+FUNC+GO   %A  CSR
  DATA RMASK=ERROR+READY+DONE           %A  CSR

  DATA ASTART=START                     %  . 
  DATA ASTOP=STOP
  DATA NFUNC
  BYTES BYT[1]

%--      RESET'A --
PROGRAM FLOPPY(AITREQ,ATICK)
  CIO:=#DISLAB
  GOSUB RESET
  RETURN ,

%--    --
PROGRAM DX::RD(,MARK)
  (IF =A:CSR
    =CSR.AND.RMASK
  ELSE IF =A:DBR
    (IF WAIGET<>
      CSR='READY'.CCA..AND.CSR ; WAIGET=0
    IF)
    =(DBR+1):
  ELSE
    RETURN ,,2
  IF)
  (IF ,MARK<>
    BYT:= ; =BYT[
  IF)
  RETURN ,,0

%--    --
PROGRAM DX::WR(,MARK,BUSDAT)
  (IF =A:CSR                            %  ?
    IF WMASK,,MARK<> THEN =.AND.&FF
    CSR=.CCA..AND.CSR                   % W-
    IF BUSDAT.AND.WMASK,,MARK<> THEN =.AND.&FF
    CSR=.IOR.CSR                        % W-
    (IF CSR.AND.'GO'<>                  %  ?
      GOSUB FORK CSR.AND.'FUNC'         % 
    ELSE IF CSR:.AND.'INIBIT/&100'<>    % ?
      GOSUB RESET
    ELSE IF CSR.AND.'ITEN'<>
      IF CSR.AND.'DONE'<> THEN GOSUB PUTIT     %  IT
    IF)
  ELSE IF =A:DBR                        %  ?
    DBR=BUSDAT.AND.&FF
    (IF WAIDAT<>                        %  ?
      CSR='READY'.CCA..AND.CSR ; WAIDAT=0
    IF)
  ELSE
    RETURN ,,2                          %E  ...
  IF)
  RETURN ,,0

%--    --
SUBROUTINE FORK(NFUNC)
  (IF CSR.AND.'DONE'=                   %  ?
    CSR=CSR.IOR.DXERR
    STATUS=0
    RETURN:FORK
  IF)
  (TICWAI+2)=ASTART                     %   TICK
  @ATICK=1 ; #TICKFL=1                  %  .
  @AITREQ=0                             % ITREQ   .
  RETURN:FORK                           % CPU 
START =
  CSR=DXERR+'DONE+READY'.CCA..AND.CSR
  .BRX.@TASKS=,,NFUNC                   %  

%%  IF BUSDAT.AND.8<> THEN RETURN:CMDACC ,,2   % 1-   

%--     --
WRBUFF =
  (XCYCLE(DATIND)+ &80
    CSR=CSR.IOR.'READY' ; WAIDAT=1
    GOSUB TICWAI 12                     % 
    BUFFER(DATIND):=DBR                 %  
    GOSUB TICWAI 8                      % ,  - 
  XCYCLE)
  CSR='READY'.CCA..AND.CSR.IOR.'DONE'
  GOTO SVRET                            % 

%--     --
RDBUFF =
  (XCYCLE(DATIND)+ &80
    GOSUB TICWAI 8                      % ,    
    DBR=BUFFER(DATIND):
    CSR=CSR.IOR.'READY' ; WAIGET=1      % CPU,   !
    GOSUB TICWAI 10                     %   ...
  XCYCLE)
  CSR='READY'.CCA..AND.CSR.IOR.'DONE'
  GOTO SVRET                            % 

%--     --
WRSECT =
  GOSUB CHKST                           %   
  GOSUB CHKON                           %ON LINE ?
  CSR='READY'.CCA..AND.CSR
%                             -   -
  (CIO+1):=1
  =ATRACK*'QSECT'+ASECT                 % 
  IOSECT=>1                             % -> 
  A:PHIS=((IF = THEN =&80 ELSE =0))+IOBUFF    %CARRY -   
  !@A:PHIS=BUFFER,&80
  CALL :IO CIO\
  GOSUB TICWAI 50                       %  

  CSR='READY+DONE'.IOR.CSR
  IF ^A.AND.'ITEN'<> THEN GOSUB PUTIT   % 
  GOTO SVRET                            %

%--     --
RDSECT =
  GOSUB CHKST
  GOSUB CHKON
  CSR='READY'.CCA..AND.CSR
%                             -   -
  (CIO+1):=0
  =ATRACK*'QSECT'+ASECT                 % 
  IOSECT=>1                             % -> 
  A:PHIS=((IF = THEN =&80 ELSE =0))+IOBUFF    %CARRY -   
  CALL :IO CIO\
  !@BUFFER=A:PHIS,&80
  GOSUB TICWAI 60                       %  

  CSR='READY+DONE'.IOR.CSR
  IF ^A.AND.'ITEN'<> THEN GOSUB PUTIT   % 
  GOTO SVRET                            %

SUBROUTINE CHKST                        %   
  GOSUB TICWAI 8
  CSR='READY'.IOR.CSR ; WAIDAT=1
  GOSUB TICWAI 10                       % 
  (IF DBR<1 OR >'QSECT'
    STATUS='ESECTO' ; CSR=DXERR.IOR.CSR ; GOTO SVRET
      IF)
  ASECT=-1
  CSR='READY'.IOR.CSR ; WAIDAT=1        %READY     DBR
  GOSUB TICWAI 10                       % 
  (IF DBR<0 OR >'QTRACK-1'
    STATUS='ETRACK' ; CSR=DXERR.IOR.CSR ; GOTO SVRET
      IF)
  ATRACK=
  RETURN:CHKST

SUBROUTINE CHKON
  (IF CIO:=                             %  ?
    STATUS=0 ; ECODES=1 ; CSR=DXERR+'READY'.IOR.CSR   %DONE -
    GOTO SVRET
      IF)
  RETURN:CHKON

SUBROUTINE PUTIT
  #ITWORD=#ITWORD.IOR.'D:BIT' ; @AITREQ='ITPRI'
  RETURN:PUTIT

%--   --
RDSTAT =
  STATUS=((IF CIO:<> THEN ='DRVRDY' ELSE =0))
  DBR=
  CSR='READY+DONE'.IOR.CSR
  GOTO SVRET

%--    --
RDERR =
  DBR=ECODES
  CSR='READY+DONE'.IOR.CSR
  GOTO SVRET

NILTSK =                                %( "-60"  . )
WRBAD =                                 % "" 
  CSR=CSR.IOR.DXERR ; ECODES=1          %   
  GOTO SVRET

%--   --
SUBROUTINE TICWAI(@ATICK)
  #TICKFL=1
  RETURN ,          % VIRTUAL 'FALL THROUGH'
PROGRAM DX:TIC()                        % WAKEUP
% @ATICK=0                              %  ,  
  RETURN:TICWAI                         % 

%--   --
 <<SVRET>> =
  (TICWAI+2)=ASTOP                      %  WAKEUP  
STOP RETURN ,

PROGRAM DX:INF()
%%CSV DEBUG
  @AITREQ=0
  RETURN 'ITADDR'

%--   . RESET   &4000 ---
SUBROUTINE RESET
  (IF CIO:=
    CSR='READY'                         % 'DONE'
  ELSE
    (CIO+1):=0                          %
    IOSECT=&0D                          %0-  1- 
    CALL :IO CIO\
    !@BUFFER=IOBUFF,&80
%%  GOSUB CHKIT                         %  
    CSR='READY+DONE'
  IF)
  (TICWAI+2)=ASTOP                      %  
  @AITREQ=0
  RETURN:RESET
