;^Z80^
TITLE FILE: DDP_MANAG:TOS      HEWLETT-PACKARD: DDP_MANAGER  (c) Coleco 1983 Confidential
;NAME ^Rev 01 - DTT^

De_DDP_MANAGER MACRO              ;Header Rev. 5
                .GOTO Ede_DDP_MANAGER

 Project:       H132, VS

 ******************************
 *                            *
 *  DDP_MANAGER           DTT   *
 *                            *
 ******************************

       Rev History
       Rev.  Date         Name      Change
        1             DTT       DEVICE_ID --> DEV_ID
        0    9/9/83   DTT       Initial Pseudo Code

 Function:

      CONTROLS THE DIGITAL DATA PACK FOR READS AND WRITES SETUP BY TAPE_INTERFACE

Ede_DDP_MANAGER  MEND
Pseudo_code_DDP_MANAGER    MACRO  ;Pseudocode macro area
                   .GOTO Ep_DDP_MANAGER



Ep_DDP_MANAGER  MEND


;Inputs/Outputs passed in registers
;  CALLED EVERY 60th SECOND BY THE NMI


TAPE1          EQU  08H
READ_TAPE      EQU  81H
WRITE_TAPE     EQU  82H
KILL_TAPE      EQU  87H
 INCLUDE P_DCB_EQ.ASM                  ;INCLUDE P_DCB_EQU:EOS
 INCLUDE EOS_ERRS.ASM                  ;INCLUDE EOS_ERRS:EOS

;*EXTERNAL DATA AREAS USED:

                EXT _START_RD_1_BLOCK
                EXT _FIND_DCB
                EXT _START_WR_1_BLOCK
                EXT _END_RD_1_BLOCK

NEXT_STATE      MACRO LP1
         LD     A,LP1                          ;SOMETHING IN THE COMMAND BUFFER!
         LD     [D_TAPE_STATE],A
         LD     HL,[STATE_VECTORS+LP1+LP1]
         LD     [NEXT_STATE_ADDRESS],HL
         JP     END_OF_STATE_MACHINE
         MEND



       GLOBAL  DEV_ID
       GLOBAL  INITIALIZE_DDP,INITIALIZE_TAPE,INIT_TAPE,INIT_DDP
INITIALIZE_DDP:
INITIALIZE_TAPE:
INIT_TAPE:
INIT_DDP:
INIT_CODE:
         XOR    A
         LD     (D_CSA),A
         LD     (D_TAPE_STATE),A
         DEC    A
         LD     (D_OVERLAY_NUMBER),A
         LD     HL,(STATE_VECTORS+0000)          ;IDLE STATE
         LD     (NEXT_STATE_ADDRESS),HL
         RET
STATE_VECTORS:
         DEFW   STATE_IDLE                       ;STATE 0
         DEFW   STATE_1                          ;      1  REQUEST FOR I/O FOR 1 BLOCK
         DEFW   STATE_2                          ;      2  TEST FOR COMPLETE AND REQUEST STATUS
         DEFW   STATE_3                          ;      3  TEST STATUS
LEN_INIT EQU $-INIT_CODE
;*
;*

         DEFS   1BH-LEN_INIT    ;MAKE SURE THE MANAGER VECTOR IS AT THE SAME LOC AS THE S/IO_MANAGER


       GLOBAL  DDP_MANAGER
       GLOBAL  TAPE_MANAGER
TAPE_MANAGER:
DDP_MANAGER:
;*  BEGIN        (Ordinarily registers are restored; retain only the pushes and pops you need.)
;*
;*
;*
;*                FALL THRU TO CASE STATEMENT     ;IF STATE = 6,7
;*                                                ;FILE IS TRYING TO CLOSE
;*
;*
;*        CASE    D_TAPE_STATE,(IDLE,STATE_1,STATE_2,STATE_3,INIT_DDP)
;*
CASE_STATE:
;*
;*
         LD     HL,[NEXT_STATE_ADDRESS]
         JP     [HL]
;*
;*        IF THE MACHINE IS IDLE IT'S OK TO TEST FOR ANOTHER I/O REQUEST
;*
STATE_IDLE:                                     ;STATE 0
         LD     A,[D_CSA]                 ;TEST THE COMMAND STATUS AREA
         OR     A
         JP     P,END_OF_STATE_MACHINE    ;IF THE CSA CONTAINS AN ERROR CODE DON't PROCESS IT
;*
;*               FALL THROUGH TO STATE 1
;*
STATE_1:
AB_REQ:  LD     A,(D_CSA)                          ;IF COMMAND IS TO KILL DDP COMMAND
         CP     KILL_TAPE
         JP     Z,INIT_DDP
;*
;*        REQUEST TO WRITE/READ A RECORD
;*

         LD     HL,(XFER_ADDR)
         LD     DE,(BLOCK_NUM)
         LD     BC,0000H
         LD     A,(D_CSA)
         CP     READ_TAPE
         LD     A,(DEV_ID)
         JR     NZ,EOS_TAPE_WRITE
EOS_TAPE_READ:
         CALL   _START_RD_1_BLOCK
         JR     RET_ADDR
EOS_TAPE_WRITE:
         CALL   _START_WR_1_BLOCK


RET_ADDR:
         NEXT_STATE 2

;*
;*               TEST FOR ACCEPTANCE/COMPLETION OF I/O REQUEST
;*
STATE_2:
         LD     A,(DEV_ID)              ;TEST THE STATUS OF THE FILE
         CALL   _END_RD_1_BLOCK
         JP     NC,END_OF_STATE_MACHINE           ;BETTER RETRY STATE 2
;*
;*        AT THIS POINT THE COMMAND HAS BEEN ACCEPTED BY THE NETWORK
;*        IF THE ZERO FLAG IS NOT SET THERE HAVE BEEN ERRORS (09BH=TIMEOUT)
;*

         JR     NZ,STATE_1                         ;BETTER RETRY STATE 1
;*
;*        IF NO ERRORS THEN SET UP REQUEST STATUS OF THE TAPE DRIVE
;*        THIS TESTS THE CHECK SUM (CRC) OF THE DATA XMITTED BY THE TAPE
;*
STATE_2_OK:
;*
         LD   A,(DEV_ID)                          ;STATUS COMMAND
         CALL _FIND_DCB
         LD   (IY+D_COM_STAT),DCB_STATUS
         NEXT_STATE 3
;*
;*        IN STATE 3 TEST FOR ACCEPTANCE OF THE REQUEST FOR STATUS COMMAND
;*
STATE_3:
         LD   A,(DEV_ID)
         CALL _FIND_DCB                            ;WAS THE STATUS REQUEST ACKNOWLEDGED????
         BIT  CMND_COMPLETE_BIT,(IY+D_COM_STAT)
         JP   Z,END_OF_STATE_MACHINE
;*
;*        IF THE COMMAND IS NOT YET ACCEPTED, COME BACK TO STATE 3 NEXT PASS
;*
         LD   A,(IY+D_COM_STAT)                   ;STATUS COMMAND ACCEPTED
         CP   080H
         JR   NZ,STATE_2_OK                        ;COULD NOT GET STATUS?
;*
;*
;*
                                                   ;SAVE THE STATUS IN REGISTER B
         LD   A,(DEV_ID)                        ;CHECK FOR SECONDARY DEVICE ID
         AND  0F0H
         LD   A,(IY+D_STATUS_FLAGS)
         JR   Z,DEV_0_CHECK                        ;SECONDARY_DEV_ID=0
         RR   A                                    ;GET STATUS INTO THE LOW NIBBLE
         RR   A
         RR   A
         RR   A
DEV_0_CHECK:
         AND  0FH
         JP   NZ,ERROR                             ;A BAD STATUS
;*
;*        IF THE COMMAND IS ACCEPTED AND THERE ARE NO ERRORS INCREMENT THE CSA DATA
;*
         LD   HL,(XFER_ADDR)                        ; A BLOCK HAS BEEN WRITTEN OR READ
         LD   DE,(BLOCK_NUM)                        ;UPDATE THE D_CSA AREA!
         LD   BC,0400H
         LD   A,(RANGE)
         DEC  A
         JP   Z,INIT_DDP                           ;DONE WITH OVERLAY?
;*
;*        IF THE RANGE WAS DECREMENTED TO ZERO WE ARE DONE ELSE (WE ARE NOT?)
;*
         LD   (RANGE),A
         INC  DE
         LD   (BLOCK_NUM),DE
         ADD  HL,BC
         LD   (XFER_ADDR),HL

         JP   STATE_1

;*
;*               ERROR PROCESSING FROM REQUEST STATUS
;*
ERROR:
;*               Errors occur after request status
;*               Possible errors are 1=CRC error (bad data on tape)
;*               2=block not found   3=no tape in drive  4=no drive
;*               The user program is expected to test for errors via
;*               TEST_TAPE in the TAPE_INTERFACE module.
;*
;*
          LD   (D_CSA),A                        ;SAVE THE ERROR CODE IN THE CSA
          LD   HL,(STATE_VECTORS+0)             ;NEXT STATE = IDLE
          LD   (NEXT_STATE_ADDRESS),HL


;*  END (DDP_MANAGER)

END_OF_STATE_MACHINE:
       XOR A
       RET
;************************************************************************
;*****           DEV_ID IS DEFAULT 08 FOR TAPE DRIVE 0           *****
;************************************************************************


DEV_ID      DEFB TAPE1


;************************************************************************
;************************************************************************
;************************************************************************
       GLOBAL D_OVERLAY_NUMBER
       GLOBAL D_TAPE_STATE
       GLOBAL D_CSA
;*--------------------------------------------------------------
;*THE NEXT_STATE_ADDRESS MAY BE PUT IN DATA,PROG,OR COMN (IT'S ALL RAM TO ADAM)
;*
NEXT_STATE_ADDRESS DEFS 2
;*--------------------------------------------------------------
;*               BY MAKING THE CSA COMMON IT IS EASILY LINKED
;*               INTO EXISTING CODE
 DATA
D_OVERLAY_NUMBER DEFS 1
D_TAPE_STATE     DEFS 1
D_CSA            DEFS 6
XFER_ADDR EQU D_CSA+1
BLOCK_NUM EQU XFER_ADDR+2
RANGE     EQU BLOCK_NUM+2