head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.19.59;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.00.42;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.39.09;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.17.49;  author jwh;  state Exp;
branches ;
next     54.3;

54.3
date     91.08.21.12.34.27;  author jwh;  state Exp;
branches ;
next     54.2;

54.2
date     91.08.21.09.45.22;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.23.33;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.24.45;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.08.23;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.07.42;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.22.58;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.07.15;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.13.08;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.10.53.56;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.40.42;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.15.48.01;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.22.05.51;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.13.56.16;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.41.18;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.24.11;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.11.46.29;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.31.17;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.22.31;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.35.39;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.14.26;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.27.32;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.16.02.46;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.36.22;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.11.43.32;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.18.04.40;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.42.14;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.26.43;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.10.54.58;  author dew;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.23.55;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.12.59.31;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.09.20.37;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     87.08.31.09.37.37;  author jws;  state Exp;
branches ;
next     23.1;

23.1
date     87.08.26.10.14.14;  author bayes;  state Exp;
branches ;
next     22.1;

22.1
date     87.08.17.10.57.05;  author bayes;  state Exp;
branches ;
next     21.1;

21.1
date     87.08.12.13.42.21;  author bayes;  state Exp;
branches ;
next     20.1;

20.1
date     87.07.30.10.55.05;  author bayes;  state Exp;
branches ;
next     19.1;

19.1
date     87.06.01.08.11.37;  author jws;  state Exp;
branches ;
next     18.1;

18.1
date     87.05.20.15.07.27;  author bayes;  state Exp;
branches ;
next     17.1;

17.1
date     87.04.30.10.23.16;  author jws;  state Exp;
branches ;
next     16.1;

16.1
date     87.04.26.15.36.06;  author jws;  state Exp;
branches ;
next     15.1;

15.1
date     87.04.13.09.08.11;  author jws;  state Exp;
branches ;
next     14.1;

14.1
date     87.04.01.15.08.51;  author jws;  state Exp;
branches ;
next     13.1;

13.1
date     87.02.28.18.22.31;  author jws;  state Exp;
branches ;
next     12.1;

12.1
date     87.02.02.13.11.45;  author jws;  state Exp;
branches ;
next     11.1;

11.1
date     87.01.19.09.37.36;  author jws;  state Exp;
branches ;
next     10.1;

10.1
date     86.12.24.10.45.09;  author jws;  state Exp;
branches ;
next     9.1;

9.1
date     86.12.12.14.20.49;  author bayes;  state Exp;
branches ;
next     8.1;

8.1
date     86.11.27.11.42.22;  author jws;  state Exp;
branches ;
next     7.1;

7.1
date     86.11.20.13.31.18;  author hal;  state Exp;
branches ;
next     6.1;

6.1
date     86.11.04.17.40.28;  author paws;  state Exp;
branches ;
next     5.1;

5.1
date     86.10.28.16.25.38;  author hal;  state Exp;
branches ;
next     4.1;

4.1
date     86.09.30.19.34.38;  author hal;  state Exp;
branches ;
next     3.1;

3.1
date     86.09.01.11.44.20;  author hal;  state Exp;
branches ;
next     2.1;

2.1
date     86.07.30.14.29.04;  author hal;  state Exp;
branches ;
next     1.1;

1.1
date     86.06.30.14.20.04;  author danm;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@*       BUBBLE MEMORY CARD READ/WRITE DRIVERS
*       11 JAN 1983
*
	NOSYMS
*
	MNAME   BUB_DVR
	DEF     BUB_DVR_BUB_DVR
	DEF     BUB_DVR_BUBGETINFO
	DEF     BUB_DVR_BUBDORESET
	DEF     BUB_DVR_BUBDOREAD
	DEF     BUB_DVR_BUBDOWRITE
	DEF     BUB_DVR_BUBDOISR

	PAGE
	SRC     MODULE BUB_DVR;
	SRC     EXPORT
	SRC     TYPE
	SRC     BSTATETYPE = (B_IDLE,
	SRC                   B_READING,
	SRC                   B_WRITING);
	SRC
	SRC     BERRORTYPE = (BNOERROR,
	SRC                   BTIMEOUT,
	SRC                   BOPFAILED,
	SRC                   BBADINTERUPT,
	SRC                   BBADSECTOR,
	SRC                   BBADCOUNT,
	SRC                   BNOTBUBBLE,
	SRC                   BBADDATA,
	SRC                   BIOFAIL);
	SRC
	SRC     BBUFP   = ^CHAR;
	SRC     INFOPTR = ^INFOREC;
	SRC     CARDPTR = ^INTEGER;
	SRC
	SRC     BUFREC= RECORD CASE BOOLEAN OF
	SRC               TRUE : (BUFI : INTEGER);
	SRC               FALSE: (BREC : BBUFP);
	SRC             END;
	SRC
	SRC     INFOREC = RECORD
	SRC                 MAXBYTES : INTEGER;
	SRC                 PRIORITY : 0..255;
	SRC                 RUNSTATE : BSTATETYPE;
	SRC                 ERRORCODE: BERRORTYPE;
	SRC
	SRC                 BSTART   : INTEGER;
	SRC                 BBUFFER  : BUFREC;
	SRC                 BCOUNT   : INTEGER;
	SRC                 BRETRY   : INTEGER;
	SRC
	SRC                 BSPAGE   : INTEGER;
	SRC                 BUFSTART : BBUFP;
	SRC                 BUFADDR  : BBUFP;
	SRC                 BUFEND   : BBUFP;
	SRC                 BLOCKSIZE: INTEGER;
	SRC               END;
	SRC
	SRC     PROCEDURE BUBGETINFO(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDORESET(ANYVAR CARD: CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOREAD(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOWRITE(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOISR(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC END;

	PAGE
*       EQUATES FOR RECORD OFFSETS AND CARD OPERATIONS
*
INFOP           EQU     A0
CARDP           EQU     A1
STATUSP         EQU     A2
COMMANDP        EQU     A2
DATAP           EQU     A3
BUFFP           EQU     A4
*
*       RUNSTATES
B_IDLE          EQU     0
B_READING       EQU     1
B_WRITING       EQU     2
*
*       ERRORCODES
BNOERROR        EQU     0
BTIMEOUT        EQU     1
BOPFAILED       EQU     2
BBADINTERUPT    EQU     3
BBADSECTOR      EQU     4
BBADCOUNT       EQU     5
BNOTBUBBLE      EQU     6
BBADDATA        EQU     7
BIOFAIL         EQU     8
*
*       INFO RECORD OFFSETS
MAXBYTES        EQU     0       INTEGER
PRIORITY        EQU     4       WORD
RUNSTATE        EQU     6       WORD
ERRORCODE       EQU     8       WORD
BSTART          EQU     10      INTEGER
BBUFFER         EQU     14      LONG
BCOUNT          EQU     18      INTEGER
BRETRY          EQU     22      INTEGER
BSPAGE          EQU     26      INTEGER
BUFSTART        EQU     30      LONG
BUFADDR         EQU     34      LONG
BUFEND          EQU     38      LONG
BLOCKSIZE       EQU     42      LONG
*
*       CARD OFFSETS
CARD_ID         EQU     1
INT_REG         EQU     3
INFO_REG        EQU     5
DATA_REG        EQU     9
COMMAND         EQU     11
STATUS          EQU     11
*
*       STATUS BITS
BUSY            EQU     7
OP_DONE         EQU     6
OP_FAIL         EQU     5
TIME_ERR        EQU     4
CORRECTABLE     EQU     3
UNCORRECT       EQU     2
PARITY_ERR      EQU     1
FIFO_AVAIL      EQU     0
	PAGE
*       INTERUPT REG BITS
INT_E           EQU     7       ENABLED
INT_R           EQU     6       REQUESTED
*
*       BUBBLE COMMAND CODES
WRT_MASKED      EQU     16
INITIALIZE      EQU     17
READ_DATA       EQU     18
WRITE_DATA      EQU     19
READ_SEEK       EQU     20
READ_LOOP_REG   EQU     21
WRT_LOOP_REG    EQU     22
WRT_LOOP        EQU     23
READ_FSA        EQU     24
ABORT_CMD       EQU     25
WRT_SEEK        EQU     26
READ_LOOP       EQU     27
READ_CORRECT    EQU     28
RESET_FIFO      EQU     29
MBM_PURGE       EQU     30
SOFT_RESET      EQU     31
CLEAR_INT       EQU     32      CLEAR INTERUPT
*
*       REG ADDRESS COUNTER VALUES
UTILITY         EQU     10      UTILITY REGISTER
BLR_LSB         EQU     11      BLOCK LENGTH REG LSB
BLR_MSB         EQU     12      BLOCK LENGTH REG MSB
ENABLE          EQU     13      ENABLE REGISTER
ADDR_LSB        EQU     14      ADDRESS LSB
ADDR_MSB        EQU     15      ADDRESS MSB
FIFO            EQU     00      FIFO DATA BUFFER
*
*       CARD INTERUPT ENABLE/DISABLE
ENABLE_INTS     EQU     128
DISABLE_INTS    EQU     000
*
*       MISC CONSTANTS
PAGESIZE        EQU     64      CODE EXPLICITY ASSUMES THIS VALUE
MAXPAGES        EQU     2048

	PAGE
*
*       INTERNAL ROUTINE TO WAIT FOR A COMMAND TO FINISH.
*       HAS A TIME OUT LIMIT
*
	DC.W    0
COMMAND_DONE    EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),CARDP
	LEA     STATUS(CARDP),STATUSP
	CLR.B   12(A6)          COMMAND_DONE := FALSE
	MOVEQ   #-1,D0          MAXIMUM COUNT FOR TIMEOUT

R76     BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT REQUEST
	DBNE    D0,R76
	BNE.S   R142
	BRA.S   CD_EXIT                 NO INTERUPT

R142    MOVEQ   #-1,D0                  RE-INIT LOOP JWS 7/11/85
R140    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	DBEQ    D0,R140
	BEQ.S   R152
	BRA.S   CD_EXIT                 BUSY DIDN'T GO AWAY

R152    BTST    #OP_DONE,(STATUSP)      CHECK STATUS
	BEQ.S   R190                    COMMAND FAILED
	MOVE.B  #1,12(A6)               COMMAND_DONE := TRUE;

R190    MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R196    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R196

CD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #4,SP
	JMP     (A0)

	PAGE
*               EXTERNAL ENTRY POINT TO GET CONFIGURATION INFO
*               ABOUT THE CARD
*               ALSO USED BY BUBDORESET,BUBDOREAD AND BUBDOWRITE
*               TO VALIDATE THE CARD TYPE AND GET MAXBYTES
*               ( THE SIZE OF THE BUBBLE MEMORY UNIT )
	DC.W    0
BUB_DVR_BUBGETINFO      EQU     *
BUBGETINFO      EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),A0        INFOP
	MOVEA.L (A0),INFOP
	MOVEA.L 12(A6),A1       CARDP
	MOVEA.L (A1),CARDP

	CLR.W   RUNSTATE(INFOP)                 RUNSTATE := B_IDLE
	MOVE.W  #BNOTBUBBLE,ERRORCODE(INFOP)    ERRORCODE := BNOTBUBBLE
	CMPI.B  #30,CARD_ID(CARDP)              CHECK CARD ID
	BNE.S   GI_EXIT
	MOVE.B  INFO_REG(CARDP),D0      COPY INFO REG INTO D0
	BTST    #7,D0                   CHECK EXTENSION BIT OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #4,D0                   CHECK FSA FIELD OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #3,D0                   BOTH BITS
	BNE.S   GI_EXIT
*                       NO PROBLEMS SO FILL IN MAXBYTES AND PRIORITY
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	ANDI.L  #7,D0           GET SIZE FIELD
	ADDQ.L  #1,D0           ADD 1
	MOVEQ   #10,D1          MULTIPLY BY 1024
	ASL.L   D1,D0
	BTST    #5,INFO_REG(CARDP)      1 MEG OR 4 MEG PARTS
	BEQ.S   R356
	MOVEQ   #9,D1   4 MEG PARTS
	ASL.L   D1,D0   MULTIPLY BY 512
	BRA.S   R366
R356    ASL.L   #7,D0   1 MEG PARTS     MULTIPLY BY 128
R366    MOVE.L  D0,(INFOP)      SET MAXBYTES
	MOVE.B  INT_REG(CARDP),D0       GET PRIORITY
	LSR.W   #4,D0   FROM FIELD OF INTERUPT REG ON CARD
	ANDI.W  #3,D0
	ADDQ.W  #3,D0
	MOVE.W  D0,PRIORITY(INFOP)
GI_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               INTERNAL ROUTINE TO LOAD THE BUBBLE CONTROLER
*               PARAMETER REGISTERS PRIOR TO MAJOR OPERATIONS
*
	DC.W    0
INITIALREGS     EQU     *
	LINK    A6,#0
	MOVEA.L 16(A6),CARDP
	MOVEA.L 12(A6),INFOP
	LEA     DATA_REG(CARDP),DATAP
	MOVE.B  #BLR_LSB,COMMAND(CARDP) point RAC at BLR_LSB

	MOVE.B  BLOCKSIZE+3(INFOP),(DATAP)      set LSB of BLOCK LENGTH REG.
	MOVE.B  BLOCKSIZE+2(INFOP),D0   get msb
	ADD.W   #16,D0                  set bit to use 2 FSA channels
	MOVE.B  D0,(DATAP)                      set MSB of BLOCK LENGTH REG.

	MOVEQ   #0,D1           clear MFBTR bit enable burst on last page
	ADD.L   8(A6),D1 add in operation peculiar bits from parameter list
	MOVE.B  D1,(DATAP)                      set ENABLE REG.

	MOVE.B  BSPAGE+3(INFOP),(DATAP)         set LSB of ADDRESS REG.
	MOVE.B  BSPAGE+2(INFOP),(DATAP)         set MSB of ADDRESS REG.

	UNLK    A6
	MOVEA.L (SP)+,A0
	ADDA.W  #12,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO "INITIALIZE" THE
*               BUBBLE MEMORY CONTROLER FOR READ/WRITE OPERATIONS
*               ALSO USED TO ABORT ANY CURRENT READ/WRITE OPERATION
*               (A6)
*               -4      BITCOUNT
*               -8      BYTECOUNT
*              -12      ABORT RETRY COUNTER
*              -16      SAVED CARD ADDRESS
*              -20      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDORESET      EQU     *
	LINK    A6,#-20
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK CARD TYPE
	MOVEA.L 8(A6),A0        GET INFOREC POINTER
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)
	BNE     RS_EXIT
	MOVE.L  INFOP,-20(A6)   SAVE INFOP
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.L  CARDP,-16(A6)   SAVE CARDP

	MOVE.B  #0,CARD_ID(CARDP)       RESET THE CARD
	MOVE.L   #300,D0         KILL AT LEAST 200 MICRO SECONDS         (rdq)
WAIT200 DBF     D0,WAIT200      *** TIMEING LOOP ***

	MOVE.B  #3,-12(A6)      SET RETRY COUNT FOR ABORT COMMAND
R700    LEA     COMMAND(CARDP),COMMANDP
*                                       ENABLE INTERUPTS ON OPDONE
	MOVE.B  #ENABLE,(COMMANDP)      POINT RAC AT ENABLE REG
	MOVE.B  #1,DATA_REG(CARDP)      SET ENABLE REG

	MOVE.B  #ABORT_CMD,(COMMANDP)   ABORT ANY CURRENT OPERATION
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR IT TO FINISH
	TST.B   (SP)+   DID IT FINISH OK ?
	BNE.S   R800            IF FINISHED OK THEN PROCEEDE
	SUBQ.B  #1,-12(A6)      DECRIMENT RETRY COUNTER
	BEQ     R1176           IF COUNT DONE THEN GIVE UP
	MOVEA.L -16(A6),CARDP   RELOAD CARDP
	BRA     R700            TRY AGAIN

R800    MOVEA.L -20(A6),INFOP           RETRIEVE INFOP
	MOVE.L  MAXBYTES(INFOP),D7      BSPAGE := MAXBYTES DIV 64 - 1;
	ASR.L   #6,D7   DIV 64
	SUBQ.L  #1,D7   - 1
	MOVE.L  D7,BSPAGE(INFOP)

	MOVE.L  #1,BLOCKSIZE(INFOP)     BLOCKSIZE := 1 PAGE
	MOVE.L  -16(A6),-(SP)   CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIXUP THE PARAMETER REGS

	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #INITIALIZE,COMMAND(CARDP)
R922    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT
	BEQ     R922                    (ON FIFO HALF FULL)
R944    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	BNE     R944
	BTST    #OP_DONE,(COMMANDP)     DID IT WORK ?
	BEQ     R1162
	MOVE.L  CARDP,-(SP)     CARD^
	MOVEA.L 8(A6),A1
	MOVE.L  (A1),-(SP)      INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX PARAMETER REGS
*                               { THIS ALSO STOPS CURRENT INTERUPT }
	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #READ_LOOP_REG,(COMMANDP)       READ BOOT LOOP REGISTER
R1018   BTST    #INT_R,INT_REG(CARDP)           WAIT FOR INTERUPT
	BEQ     R1018
R1040   CLR.L   -4(A6)          BITCOUNT := 0
	CLR.L   -8(A6)          BYTECOUNT := 0
R1048   BTST    #BUSY,STATUS(CARDP)     WHILE BUSY DO
	BEQ.S   R1124
R1068   BTST    #FIFO_AVAIL,STATUS(CARDP)       WHILE FIFO_AVAIL DO
	BEQ     R1048           IF FIFO EMPTY THEN CHECK BUSY
	ADDQ.L  #1,-8(A6)       INCREMENT BYTECOUNT
	MOVE.B  DATA_REG(CARDP),D0      READ THE DATA BYTE
*                               COUNT THE 1 BITS IN LOW BYTE OF D0
	MOVEQ   #0,D1   COUNT := 0
	MOVEQ   #7,D2   LOOP COUNTER
	MOVEQ   #0,D3   ZERO CONSTANT
COUNTL  LSL.B   #1,D0   SHIFT HI BIT TO X
	ADDX.B  D3,D1   ADD 0 + X + COUNT { WILL NEVER BE MORE THAN 8 }
	DBRA    D2,COUNTL

	ADD.L   D1,-4(A6)       ADD COUNT TO BIT COUNT
	BRA     R1068   END WHILE FIFO_AVAIL

R1124   MOVEQ   #40,D1          MUST HAVE EXACTLY 40 BYTES
	CMP.L   -8(A6),D1
	BNE.S   R1150
	CMPI.L  #270,-4(A6)     MUST HAVE EXACTLY 270 BITS
	BEQ.S   RS_EXIT
R1150   MOVEA.L -20(A6),INFOP   WRONG BYTE / BIT COUNT
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1162   MOVEA.L -20(A6),INFOP   INITIALIZE OPERATION FAILED
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1176   MOVEA.L -20(A6),INFOP   FAILED TO RESPOND TO ABORT COMMAND
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
RS_EXIT UNLK A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOREAD
*               ALSO USED BY BUBDOISR TO RESTART A FAILED READ OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTREAD       EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A1       CARD
	MOVE.L  (A1),-4(A6)
	MOVEA.L 8(A6),A0        INFO
	MOVE.L  (A0),-8(A6)
	MOVEA.L (A0),INFOP      INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	MOVEA.L -4(A6),CARDP    CARD^
	MOVE.B  #ENABLE,COMMAND(CARDP)  SET RAC TO ENABLE REG.
	MOVE.B  #1,DATA_REG(CARDP)      ENABLE INTERUPT ON OPDONE
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE                    WAIT FOR IT
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1332
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  -8(A6),-(SP)    INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -8(A6),INFOP
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_READING,RUNSTATE(INFOP)      SHOW NOW READING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #READ_DATA,COMMAND(CARDP)       START READ OPERTATION
	BRA.S   SR_EXIT
R1332   MOVEA.L -8(A6),INFOP            RESET FIFO FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
SR_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA READ OPERATIONS
*
	DC.W    0
BUB_DVR_BUBDOREAD       EQU     *
	LINK    A6,#0
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE<>BNOERROR
	BNE     RD_EXIT                 THEN QUIT
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP      CARD^

	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1420           CAN'T BE NEGATIVE
	TST.B   D0              MUST BE MULTIPLE OF 256
	BEQ.S   R1428
R1420   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     RD_EXIT

R1428   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTE COUNT
	BLE.S   R1450           MUST BE GREATER THAN ZERO
	ADD.L   D1,D0           BCOUNT + BSTART
	CMP.L   (INFOP),D0      CAN'T BE GREATER THAN MAXBYTES
	BLE.S   R1456
R1450   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA.S   RD_EXIT
R1456   MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
	MOVE.L  D1,BUFEND(INFOP)        SET COUNT IN BUFEND
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP BYTECOUNT
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1480
	MOVE.L  #MAXPAGES,D1
R1480   MOVE.L  D1,BLOCKSIZE(INFOP)
*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)
	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO COUNT)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       FINISH UP AND ISSUE THE READ COMMAND
RD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOWRITE
*               ALSO USED BY BUBDOISR TO RESTART A FAILED WRITE OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTWRITE      EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A0       CARD
	MOVE.L  (A0),-4(A6)     SAVE CARD^
	MOVEA.L 8(A6),A0        INFO
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-8(A6)    SAVE INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE:= BNOERROR
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -4(A6),CARDP
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR/RESET THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR FIFO TO RESET
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1734
	MOVEA.L -8(A6),INFOP    OK SO CONTINUE
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_WRITING,RUNSTATE(INFOP)      SHOW NOW WRITING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)      START THE OPERATION
	BRA.S   SW_EXIT

R1734   MOVEA.L -8(A6),INFOP            FIFO RESET FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)

SW_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA WRITE OPERATIONS
*               (A6)
*               -4      UNUSED          (COMPILER TEMP OPTIMIZED OUT)
*               -8      SAVED CARD ADDRESS
*              -12      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDOWRITE      EQU     *
	LINK    A6,#-12
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE <> BNOERROR
	BNE     WT_EXIT                 THEN EXIT
	MOVEA.L 12(A6),A1
	MOVE.L  (A1),-8(A6)     CARD^
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-12(A6)
	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1820                   CAN'T BE NEGATIVE
	TST.B   D0                      MUST BE MULTIPLE OF 256
	BEQ.S   R1830
R1820   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1830   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTECOUNT
	BLE.S   R1860                   MUST BE GREATER THAN ZERO
	TST.B   D1
	BNE.S   R1860                   MUST BE MULTIPLE OF 256
	ADD.L   D1,D0
	CMP.L   (A0),D0         IF (BCOUNT+BSTART)<=MAXBYTES
	BLE.S   R1876           THEN CONTINUE
R1860   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1876   MOVEA.L -8(A6),CARDP    CARD^
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1880
	MOVE.L  #MAXPAGES,D1
R1880   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
	ASL.L   #6,D1           CONVERT BLOCKSIZE BACK TO BYTES
	MOVE.L  D1,BUFEND(INFOP)        SAVE IT IN BUFEND

*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)

	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO SIZE)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTWRITE      FINISH UP AND ISSUE THE WRITE COMMAND
WT_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*                       INTERUPT SERVICE ROUTINE
*
	DC.W    0
BUB_DVR_BUBDOISR        EQU     *
	LINK    A6,#0
	MOVEA.L 12(A6),A1       GET CARD ADDRESS
	MOVEA.L (A1),CARDP              CARD BASE ADDRESS
	LEA     STATUS(CARDP),STATUSP   STATUS REG ADDRESS
	LEA     DATA_REG(CARDP),DATAP   DATA REG ADDRESS

	MOVEA.L 8(A6),A0        GET INFOREC ADDRESS
	MOVEA.L (A0),INFOP              INFOREC BASE ADDRESS
	MOVEA.L BUFADDR(INFOP),BUFFP    BUFFER ADDRESS

	CMPI.W  #B_READING,RUNSTATE(A0) JUMP ACCORDING TO RUNSTATE
	BEQ.S   READING
	BGT     WRITING

*       IN B_IDLE STATE ... HAVE UNEXPECTED INTERUPT
IDLE    MOVE.W  #BBADINTERUPT,ERRORCODE(INFOP)  set ERRORCODE
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    disable interupt enable
IDLE1   BTST    #INT_E,INT_REG(CARDP)   wait for enable bit to clear
	BNE.S   IDLE1
	BRA     ISRDONE                 all done

*       IN B_READING    ... HAVE DATA OR END OF OPERATION
READING BTST    #BUSY,(STATUSP)
	BEQ.S   R2232
*                       BUSY SO HAVE DATA TO READ
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2132   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST END OF BUFFER
	BEQ.S   R2143
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ.S   R2135
R2133   MOVE.B  (DATAP),(BUFFP)+        READ THE DATA
	BRA.S   R2132

R2135   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
	BRA     ISRDONE                 THEN EXIT

R2143   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
*                                       THEN DISCARD UNWANTED DATA
R2196   BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ     ISRDONE                 EXIT IF FIFO IS EMPTY
	MOVE.B  (DATAP),D0              READ & DISCARD
	BRA.S   R2196
*                       NOT BUSY SO END OF OPERATION
*       DID ANYTHING GO WRONG ?
R2232   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2240
	BTST    #OP_FAIL,(STATUSP)
	BNE.S   R2240
	BTST    #UNCORRECT,(STATUSP)
	BEQ.S   R2348
	MOVE.W  #BBADDATA,ERRORCODE(INFOP)      SET BADDATA ERROR
*       SOMETHING WENT WRONG SO TRY TO RESTART THE CURRENT REQUEST
R2240   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R2280   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2280

	SUBQ.L  #1,BRETRY(INFOP)        DECRIMENT RETRY COUNTER
	BLT.S   R2334
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       RESTART THE CURRENT REQUEST
	BRA     ISRDONE

*       TOO MANY RETRIES
R2334   CLR.W   RUNSTATE(INFOP)  SET RUNSTATE TO B_IDLE
	TST.W   ERRORCODE(INFOP) IS ERRORCODE ALREADY SET ?
	BNE     ISRDONE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA     ISRDONE

*       OPERATION COMPLETED OK
*               READ ANY DATA LEFT IN THE FIFO
R2348   MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2350   CMP.L   BUFFP,D0        CHECK BUFFER ADDRESS AGAINST END OF BUFFER
	BEQ.S   R2412
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),(BUFFP)+
	BRA.S   R2350
*               DISCARD THE REST OF THE DATA
R2412   BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),D1      DISCARD THE DATA
	BRA.S   R2412

R2440   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT REQUEST
R2454   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2454

	CMP.L   BUFFP,D0        IF ALL DATA READ
	BEQ     R3008           THEN OPERATION COMPLETED
	MOVE.L  BLOCKSIZE(INFOP),D0             INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP
R2550   ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R2586
	MOVE.L  #MAXPAGES,D1
R2586   MOVE.L  D1,BLOCKSIZE(INFOP)

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #READ_DATA,COMMAND(CARDP)
	BRA     ISRDONE

*       IN B_WRITEING STATE ... HAVE DATA TO WRITE OR END OF OPERATION
WRITING BTST    #BUSY,(STATUSP)
	BEQ.S   R2716
*                               NORMAL WRITE OPERATION
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2664   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST BUFFER END
	BEQ.S   R2712
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2712
	MOVE.B  (BUFFP)+,(DATAP)         WRITE THE DATA
	NOP                              FIX FOR 68020 BAR 7/11/85
	NOP                              FIX FOR 68020 BAR 7/11/85
	BRA.S   R2664

R2712   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	BRA     ISRDONE
*               NOT BUSY SO OPERATION IS DONE
*               DID ANYTHING GO WRONG?
R2716   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2750
	BTST    #OP_FAIL,(STATUSP)
	BEQ.S   R2820
*                       SOMETHING WENT WRONG SO TRY TO RESTART
R2750   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2752   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2752

	SUBQ.L  #1,BRETRY(INFOP)        CHECK THE RETRY COUNTER
	BLT.S   R2806
	MOVE.L  12(A6),-(SP)    TRY AGAIN
	MOVE.L  8(A6),-(SP)
	JSR     STARTWRITE
	BRA.S   ISRDONE
*               TOO MANY RETRIES
R2806   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA.S   ISRDONE
*                       NO ERRORS SO FINISH UP
R2820   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2830   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2830

	MOVE.L  BBUFFER(INFOP),D0       CALCULATE END OF BUFFER ADDRESS
	ADD.L   BCOUNT(INFOP),D0
	CMP.L   BUFFP,D0        ANY MORE TO BE WRITTEN ?
	BEQ.S   R3008
	MOVE.L  BLOCKSIZE(INFOP),D0     INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
	MOVE.L  D0,BUFEND(INFOP)        SAVE BASE FOR BUFEND
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE IS ASSUMED TO HAVE 64 BYTES
R2926   ASR.L   #6,D1   DIVIDE BY 64    D1 NOW IS PAGES LEFT
	CMPI.L  #MAXPAGES,D1    CLIP PAGES AT MAXPAGES
	BLT.S   R2962
	MOVE.L  #MAXPAGES,D1
R2962   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
*                               RE-CALCULATE END OF BUFFER
	ASL.L   #6,D1           CONVERT BLOCKSIZE TO BYTES (MULTIPLY BY 64)
	ADD.L   D1,BUFEND(INFOP)        ADD IT TO BASE

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)
	BRA.S   ISRDONE
R3008   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
ISRDONE UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

BUB_DVR_BUB_DVR EQU     *
	RTS

@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 827
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 827
*       BUBBLE MEMORY CARD READ/WRITE DRIVERS
*       11 JAN 1983
*
	NOSYMS
*
	MNAME   BUB_DVR
	DEF     BUB_DVR_BUB_DVR
	DEF     BUB_DVR_BUBGETINFO
	DEF     BUB_DVR_BUBDORESET
	DEF     BUB_DVR_BUBDOREAD
	DEF     BUB_DVR_BUBDOWRITE
	DEF     BUB_DVR_BUBDOISR

	PAGE
	SRC     MODULE BUB_DVR;
	SRC     EXPORT
	SRC     TYPE
	SRC     BSTATETYPE = (B_IDLE,
	SRC                   B_READING,
	SRC                   B_WRITING);
	SRC
	SRC     BERRORTYPE = (BNOERROR,
	SRC                   BTIMEOUT,
	SRC                   BOPFAILED,
	SRC                   BBADINTERUPT,
	SRC                   BBADSECTOR,
	SRC                   BBADCOUNT,
	SRC                   BNOTBUBBLE,
	SRC                   BBADDATA,
	SRC                   BIOFAIL);
	SRC
	SRC     BBUFP   = ^CHAR;
	SRC     INFOPTR = ^INFOREC;
	SRC     CARDPTR = ^INTEGER;
	SRC
	SRC     BUFREC= RECORD CASE BOOLEAN OF
	SRC               TRUE : (BUFI : INTEGER);
	SRC               FALSE: (BREC : BBUFP);
	SRC             END;
	SRC
	SRC     INFOREC = RECORD
	SRC                 MAXBYTES : INTEGER;
	SRC                 PRIORITY : 0..255;
	SRC                 RUNSTATE : BSTATETYPE;
	SRC                 ERRORCODE: BERRORTYPE;
	SRC
	SRC                 BSTART   : INTEGER;
	SRC                 BBUFFER  : BUFREC;
	SRC                 BCOUNT   : INTEGER;
	SRC                 BRETRY   : INTEGER;
	SRC
	SRC                 BSPAGE   : INTEGER;
	SRC                 BUFSTART : BBUFP;
	SRC                 BUFADDR  : BBUFP;
	SRC                 BUFEND   : BBUFP;
	SRC                 BLOCKSIZE: INTEGER;
	SRC               END;
	SRC
	SRC     PROCEDURE BUBGETINFO(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDORESET(ANYVAR CARD: CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOREAD(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOWRITE(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOISR(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC END;

	PAGE
*       EQUATES FOR RECORD OFFSETS AND CARD OPERATIONS
*
INFOP           EQU     A0
CARDP           EQU     A1
STATUSP         EQU     A2
COMMANDP        EQU     A2
DATAP           EQU     A3
BUFFP           EQU     A4
*
*       RUNSTATES
B_IDLE          EQU     0
B_READING       EQU     1
B_WRITING       EQU     2
*
*       ERRORCODES
BNOERROR        EQU     0
BTIMEOUT        EQU     1
BOPFAILED       EQU     2
BBADINTERUPT    EQU     3
BBADSECTOR      EQU     4
BBADCOUNT       EQU     5
BNOTBUBBLE      EQU     6
BBADDATA        EQU     7
BIOFAIL         EQU     8
*
*       INFO RECORD OFFSETS
MAXBYTES        EQU     0       INTEGER
PRIORITY        EQU     4       WORD
RUNSTATE        EQU     6       WORD
ERRORCODE       EQU     8       WORD
BSTART          EQU     10      INTEGER
BBUFFER         EQU     14      LONG
BCOUNT          EQU     18      INTEGER
BRETRY          EQU     22      INTEGER
BSPAGE          EQU     26      INTEGER
BUFSTART        EQU     30      LONG
BUFADDR         EQU     34      LONG
BUFEND          EQU     38      LONG
BLOCKSIZE       EQU     42      LONG
*
*       CARD OFFSETS
CARD_ID         EQU     1
INT_REG         EQU     3
INFO_REG        EQU     5
DATA_REG        EQU     9
COMMAND         EQU     11
STATUS          EQU     11
*
*       STATUS BITS
BUSY            EQU     7
OP_DONE         EQU     6
OP_FAIL         EQU     5
TIME_ERR        EQU     4
CORRECTABLE     EQU     3
UNCORRECT       EQU     2
PARITY_ERR      EQU     1
FIFO_AVAIL      EQU     0
	PAGE
*       INTERUPT REG BITS
INT_E           EQU     7       ENABLED
INT_R           EQU     6       REQUESTED
*
*       BUBBLE COMMAND CODES
WRT_MASKED      EQU     16
INITIALIZE      EQU     17
READ_DATA       EQU     18
WRITE_DATA      EQU     19
READ_SEEK       EQU     20
READ_LOOP_REG   EQU     21
WRT_LOOP_REG    EQU     22
WRT_LOOP        EQU     23
READ_FSA        EQU     24
ABORT_CMD       EQU     25
WRT_SEEK        EQU     26
READ_LOOP       EQU     27
READ_CORRECT    EQU     28
RESET_FIFO      EQU     29
MBM_PURGE       EQU     30
SOFT_RESET      EQU     31
CLEAR_INT       EQU     32      CLEAR INTERUPT
*
*       REG ADDRESS COUNTER VALUES
UTILITY         EQU     10      UTILITY REGISTER
BLR_LSB         EQU     11      BLOCK LENGTH REG LSB
BLR_MSB         EQU     12      BLOCK LENGTH REG MSB
ENABLE          EQU     13      ENABLE REGISTER
ADDR_LSB        EQU     14      ADDRESS LSB
ADDR_MSB        EQU     15      ADDRESS MSB
FIFO            EQU     00      FIFO DATA BUFFER
*
*       CARD INTERUPT ENABLE/DISABLE
ENABLE_INTS     EQU     128
DISABLE_INTS    EQU     000
*
*       MISC CONSTANTS
PAGESIZE        EQU     64      CODE EXPLICITY ASSUMES THIS VALUE
MAXPAGES        EQU     2048

	PAGE
*
*       INTERNAL ROUTINE TO WAIT FOR A COMMAND TO FINISH.
*       HAS A TIME OUT LIMIT
*
	DC.W    0
COMMAND_DONE    EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),CARDP
	LEA     STATUS(CARDP),STATUSP
	CLR.B   12(A6)          COMMAND_DONE := FALSE
	MOVEQ   #-1,D0          MAXIMUM COUNT FOR TIMEOUT

R76     BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT REQUEST
	DBNE    D0,R76
	BNE.S   R142
	BRA.S   CD_EXIT                 NO INTERUPT

R142    MOVEQ   #-1,D0                  RE-INIT LOOP JWS 7/11/85
R140    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	DBEQ    D0,R140
	BEQ.S   R152
	BRA.S   CD_EXIT                 BUSY DIDN'T GO AWAY

R152    BTST    #OP_DONE,(STATUSP)      CHECK STATUS
	BEQ.S   R190                    COMMAND FAILED
	MOVE.B  #1,12(A6)               COMMAND_DONE := TRUE;

R190    MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R196    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R196

CD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #4,SP
	JMP     (A0)

	PAGE
*               EXTERNAL ENTRY POINT TO GET CONFIGURATION INFO
*               ABOUT THE CARD
*               ALSO USED BY BUBDORESET,BUBDOREAD AND BUBDOWRITE
*               TO VALIDATE THE CARD TYPE AND GET MAXBYTES
*               ( THE SIZE OF THE BUBBLE MEMORY UNIT )
	DC.W    0
BUB_DVR_BUBGETINFO      EQU     *
BUBGETINFO      EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),A0        INFOP
	MOVEA.L (A0),INFOP
	MOVEA.L 12(A6),A1       CARDP
	MOVEA.L (A1),CARDP

	CLR.W   RUNSTATE(INFOP)                 RUNSTATE := B_IDLE
	MOVE.W  #BNOTBUBBLE,ERRORCODE(INFOP)    ERRORCODE := BNOTBUBBLE
	CMPI.B  #30,CARD_ID(CARDP)              CHECK CARD ID
	BNE.S   GI_EXIT
	MOVE.B  INFO_REG(CARDP),D0      COPY INFO REG INTO D0
	BTST    #7,D0                   CHECK EXTENSION BIT OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #4,D0                   CHECK FSA FIELD OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #3,D0                   BOTH BITS
	BNE.S   GI_EXIT
*                       NO PROBLEMS SO FILL IN MAXBYTES AND PRIORITY
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	ANDI.L  #7,D0           GET SIZE FIELD
	ADDQ.L  #1,D0           ADD 1
	MOVEQ   #10,D1          MULTIPLY BY 1024
	ASL.L   D1,D0
	BTST    #5,INFO_REG(CARDP)      1 MEG OR 4 MEG PARTS
	BEQ.S   R356
	MOVEQ   #9,D1   4 MEG PARTS
	ASL.L   D1,D0   MULTIPLY BY 512
	BRA.S   R366
R356    ASL.L   #7,D0   1 MEG PARTS     MULTIPLY BY 128
R366    MOVE.L  D0,(INFOP)      SET MAXBYTES
	MOVE.B  INT_REG(CARDP),D0       GET PRIORITY
	LSR.W   #4,D0   FROM FIELD OF INTERUPT REG ON CARD
	ANDI.W  #3,D0
	ADDQ.W  #3,D0
	MOVE.W  D0,PRIORITY(INFOP)
GI_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               INTERNAL ROUTINE TO LOAD THE BUBBLE CONTROLER
*               PARAMETER REGISTERS PRIOR TO MAJOR OPERATIONS
*
	DC.W    0
INITIALREGS     EQU     *
	LINK    A6,#0
	MOVEA.L 16(A6),CARDP
	MOVEA.L 12(A6),INFOP
	LEA     DATA_REG(CARDP),DATAP
	MOVE.B  #BLR_LSB,COMMAND(CARDP) point RAC at BLR_LSB

	MOVE.B  BLOCKSIZE+3(INFOP),(DATAP)      set LSB of BLOCK LENGTH REG.
	MOVE.B  BLOCKSIZE+2(INFOP),D0   get msb
	ADD.W   #16,D0                  set bit to use 2 FSA channels
	MOVE.B  D0,(DATAP)                      set MSB of BLOCK LENGTH REG.

	MOVEQ   #0,D1           clear MFBTR bit enable burst on last page
	ADD.L   8(A6),D1 add in operation peculiar bits from parameter list
	MOVE.B  D1,(DATAP)                      set ENABLE REG.

	MOVE.B  BSPAGE+3(INFOP),(DATAP)         set LSB of ADDRESS REG.
	MOVE.B  BSPAGE+2(INFOP),(DATAP)         set MSB of ADDRESS REG.

	UNLK    A6
	MOVEA.L (SP)+,A0
	ADDA.W  #12,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO "INITIALIZE" THE
*               BUBBLE MEMORY CONTROLER FOR READ/WRITE OPERATIONS
*               ALSO USED TO ABORT ANY CURRENT READ/WRITE OPERATION
*               (A6)
*               -4      BITCOUNT
*               -8      BYTECOUNT
*              -12      ABORT RETRY COUNTER
*              -16      SAVED CARD ADDRESS
*              -20      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDORESET      EQU     *
	LINK    A6,#-20
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK CARD TYPE
	MOVEA.L 8(A6),A0        GET INFOREC POINTER
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)
	BNE     RS_EXIT
	MOVE.L  INFOP,-20(A6)   SAVE INFOP
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.L  CARDP,-16(A6)   SAVE CARDP

	MOVE.B  #0,CARD_ID(CARDP)       RESET THE CARD
	MOVE.L   #300,D0         KILL AT LEAST 200 MICRO SECONDS         (rdq)
WAIT200 DBF     D0,WAIT200      *** TIMEING LOOP ***

	MOVE.B  #3,-12(A6)      SET RETRY COUNT FOR ABORT COMMAND
R700    LEA     COMMAND(CARDP),COMMANDP
*                                       ENABLE INTERUPTS ON OPDONE
	MOVE.B  #ENABLE,(COMMANDP)      POINT RAC AT ENABLE REG
	MOVE.B  #1,DATA_REG(CARDP)      SET ENABLE REG

	MOVE.B  #ABORT_CMD,(COMMANDP)   ABORT ANY CURRENT OPERATION
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR IT TO FINISH
	TST.B   (SP)+   DID IT FINISH OK ?
	BNE.S   R800            IF FINISHED OK THEN PROCEEDE
	SUBQ.B  #1,-12(A6)      DECRIMENT RETRY COUNTER
	BEQ     R1176           IF COUNT DONE THEN GIVE UP
	MOVEA.L -16(A6),CARDP   RELOAD CARDP
	BRA     R700            TRY AGAIN

R800    MOVEA.L -20(A6),INFOP           RETRIEVE INFOP
	MOVE.L  MAXBYTES(INFOP),D7      BSPAGE := MAXBYTES DIV 64 - 1;
	ASR.L   #6,D7   DIV 64
	SUBQ.L  #1,D7   - 1
	MOVE.L  D7,BSPAGE(INFOP)

	MOVE.L  #1,BLOCKSIZE(INFOP)     BLOCKSIZE := 1 PAGE
	MOVE.L  -16(A6),-(SP)   CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIXUP THE PARAMETER REGS

	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #INITIALIZE,COMMAND(CARDP)
R922    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT
	BEQ     R922                    (ON FIFO HALF FULL)
R944    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	BNE     R944
	BTST    #OP_DONE,(COMMANDP)     DID IT WORK ?
	BEQ     R1162
	MOVE.L  CARDP,-(SP)     CARD^
	MOVEA.L 8(A6),A1
	MOVE.L  (A1),-(SP)      INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX PARAMETER REGS
*                               { THIS ALSO STOPS CURRENT INTERUPT }
	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #READ_LOOP_REG,(COMMANDP)       READ BOOT LOOP REGISTER
R1018   BTST    #INT_R,INT_REG(CARDP)           WAIT FOR INTERUPT
	BEQ     R1018
R1040   CLR.L   -4(A6)          BITCOUNT := 0
	CLR.L   -8(A6)          BYTECOUNT := 0
R1048   BTST    #BUSY,STATUS(CARDP)     WHILE BUSY DO
	BEQ.S   R1124
R1068   BTST    #FIFO_AVAIL,STATUS(CARDP)       WHILE FIFO_AVAIL DO
	BEQ     R1048           IF FIFO EMPTY THEN CHECK BUSY
	ADDQ.L  #1,-8(A6)       INCREMENT BYTECOUNT
	MOVE.B  DATA_REG(CARDP),D0      READ THE DATA BYTE
*                               COUNT THE 1 BITS IN LOW BYTE OF D0
	MOVEQ   #0,D1   COUNT := 0
	MOVEQ   #7,D2   LOOP COUNTER
	MOVEQ   #0,D3   ZERO CONSTANT
COUNTL  LSL.B   #1,D0   SHIFT HI BIT TO X
	ADDX.B  D3,D1   ADD 0 + X + COUNT { WILL NEVER BE MORE THAN 8 }
	DBRA    D2,COUNTL

	ADD.L   D1,-4(A6)       ADD COUNT TO BIT COUNT
	BRA     R1068   END WHILE FIFO_AVAIL

R1124   MOVEQ   #40,D1          MUST HAVE EXACTLY 40 BYTES
	CMP.L   -8(A6),D1
	BNE.S   R1150
	CMPI.L  #270,-4(A6)     MUST HAVE EXACTLY 270 BITS
	BEQ.S   RS_EXIT
R1150   MOVEA.L -20(A6),INFOP   WRONG BYTE / BIT COUNT
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1162   MOVEA.L -20(A6),INFOP   INITIALIZE OPERATION FAILED
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1176   MOVEA.L -20(A6),INFOP   FAILED TO RESPOND TO ABORT COMMAND
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
RS_EXIT UNLK A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOREAD
*               ALSO USED BY BUBDOISR TO RESTART A FAILED READ OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTREAD       EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A1       CARD
	MOVE.L  (A1),-4(A6)
	MOVEA.L 8(A6),A0        INFO
	MOVE.L  (A0),-8(A6)
	MOVEA.L (A0),INFOP      INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	MOVEA.L -4(A6),CARDP    CARD^
	MOVE.B  #ENABLE,COMMAND(CARDP)  SET RAC TO ENABLE REG.
	MOVE.B  #1,DATA_REG(CARDP)      ENABLE INTERUPT ON OPDONE
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE                    WAIT FOR IT
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1332
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  -8(A6),-(SP)    INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -8(A6),INFOP
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_READING,RUNSTATE(INFOP)      SHOW NOW READING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #READ_DATA,COMMAND(CARDP)       START READ OPERTATION
	BRA.S   SR_EXIT
R1332   MOVEA.L -8(A6),INFOP            RESET FIFO FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
SR_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA READ OPERATIONS
*
	DC.W    0
BUB_DVR_BUBDOREAD       EQU     *
	LINK    A6,#0
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE<>BNOERROR
	BNE     RD_EXIT                 THEN QUIT
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP      CARD^

	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1420           CAN'T BE NEGATIVE
	TST.B   D0              MUST BE MULTIPLE OF 256
	BEQ.S   R1428
R1420   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     RD_EXIT

R1428   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTE COUNT
	BLE.S   R1450           MUST BE GREATER THAN ZERO
	ADD.L   D1,D0           BCOUNT + BSTART
	CMP.L   (INFOP),D0      CAN'T BE GREATER THAN MAXBYTES
	BLE.S   R1456
R1450   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA.S   RD_EXIT
R1456   MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
	MOVE.L  D1,BUFEND(INFOP)        SET COUNT IN BUFEND
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP BYTECOUNT
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1480
	MOVE.L  #MAXPAGES,D1
R1480   MOVE.L  D1,BLOCKSIZE(INFOP)
*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)
	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO COUNT)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       FINISH UP AND ISSUE THE READ COMMAND
RD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOWRITE
*               ALSO USED BY BUBDOISR TO RESTART A FAILED WRITE OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTWRITE      EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A0       CARD
	MOVE.L  (A0),-4(A6)     SAVE CARD^
	MOVEA.L 8(A6),A0        INFO
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-8(A6)    SAVE INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE:= BNOERROR
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -4(A6),CARDP
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR/RESET THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR FIFO TO RESET
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1734
	MOVEA.L -8(A6),INFOP    OK SO CONTINUE
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_WRITING,RUNSTATE(INFOP)      SHOW NOW WRITING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)      START THE OPERATION
	BRA.S   SW_EXIT

R1734   MOVEA.L -8(A6),INFOP            FIFO RESET FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)

SW_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA WRITE OPERATIONS
*               (A6)
*               -4      UNUSED          (COMPILER TEMP OPTIMIZED OUT)
*               -8      SAVED CARD ADDRESS
*              -12      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDOWRITE      EQU     *
	LINK    A6,#-12
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE <> BNOERROR
	BNE     WT_EXIT                 THEN EXIT
	MOVEA.L 12(A6),A1
	MOVE.L  (A1),-8(A6)     CARD^
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-12(A6)
	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1820                   CAN'T BE NEGATIVE
	TST.B   D0                      MUST BE MULTIPLE OF 256
	BEQ.S   R1830
R1820   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1830   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTECOUNT
	BLE.S   R1860                   MUST BE GREATER THAN ZERO
	TST.B   D1
	BNE.S   R1860                   MUST BE MULTIPLE OF 256
	ADD.L   D1,D0
	CMP.L   (A0),D0         IF (BCOUNT+BSTART)<=MAXBYTES
	BLE.S   R1876           THEN CONTINUE
R1860   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1876   MOVEA.L -8(A6),CARDP    CARD^
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1880
	MOVE.L  #MAXPAGES,D1
R1880   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
	ASL.L   #6,D1           CONVERT BLOCKSIZE BACK TO BYTES
	MOVE.L  D1,BUFEND(INFOP)        SAVE IT IN BUFEND

*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)

	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO SIZE)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTWRITE      FINISH UP AND ISSUE THE WRITE COMMAND
WT_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*                       INTERUPT SERVICE ROUTINE
*
	DC.W    0
BUB_DVR_BUBDOISR        EQU     *
	LINK    A6,#0
	MOVEA.L 12(A6),A1       GET CARD ADDRESS
	MOVEA.L (A1),CARDP              CARD BASE ADDRESS
	LEA     STATUS(CARDP),STATUSP   STATUS REG ADDRESS
	LEA     DATA_REG(CARDP),DATAP   DATA REG ADDRESS

	MOVEA.L 8(A6),A0        GET INFOREC ADDRESS
	MOVEA.L (A0),INFOP              INFOREC BASE ADDRESS
	MOVEA.L BUFADDR(INFOP),BUFFP    BUFFER ADDRESS

	CMPI.W  #B_READING,RUNSTATE(A0) JUMP ACCORDING TO RUNSTATE
	BEQ.S   READING
	BGT     WRITING

*       IN B_IDLE STATE ... HAVE UNEXPECTED INTERUPT
IDLE    MOVE.W  #BBADINTERUPT,ERRORCODE(INFOP)  set ERRORCODE
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    disable interupt enable
IDLE1   BTST    #INT_E,INT_REG(CARDP)   wait for enable bit to clear
	BNE.S   IDLE1
	BRA     ISRDONE                 all done

*       IN B_READING    ... HAVE DATA OR END OF OPERATION
READING BTST    #BUSY,(STATUSP)
	BEQ.S   R2232
*                       BUSY SO HAVE DATA TO READ
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2132   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST END OF BUFFER
	BEQ.S   R2143
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ.S   R2135
R2133   MOVE.B  (DATAP),(BUFFP)+        READ THE DATA
	BRA.S   R2132

R2135   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
	BRA     ISRDONE                 THEN EXIT

R2143   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
*                                       THEN DISCARD UNWANTED DATA
R2196   BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ     ISRDONE                 EXIT IF FIFO IS EMPTY
	MOVE.B  (DATAP),D0              READ & DISCARD
	BRA.S   R2196
*                       NOT BUSY SO END OF OPERATION
*       DID ANYTHING GO WRONG ?
R2232   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2240
	BTST    #OP_FAIL,(STATUSP)
	BNE.S   R2240
	BTST    #UNCORRECT,(STATUSP)
	BEQ.S   R2348
	MOVE.W  #BBADDATA,ERRORCODE(INFOP)      SET BADDATA ERROR
*       SOMETHING WENT WRONG SO TRY TO RESTART THE CURRENT REQUEST
R2240   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R2280   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2280

	SUBQ.L  #1,BRETRY(INFOP)        DECRIMENT RETRY COUNTER
	BLT.S   R2334
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       RESTART THE CURRENT REQUEST
	BRA     ISRDONE

*       TOO MANY RETRIES
R2334   CLR.W   RUNSTATE(INFOP)  SET RUNSTATE TO B_IDLE
	TST.W   ERRORCODE(INFOP) IS ERRORCODE ALREADY SET ?
	BNE     ISRDONE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA     ISRDONE

*       OPERATION COMPLETED OK
*               READ ANY DATA LEFT IN THE FIFO
R2348   MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2350   CMP.L   BUFFP,D0        CHECK BUFFER ADDRESS AGAINST END OF BUFFER
	BEQ.S   R2412
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),(BUFFP)+
	BRA.S   R2350
*               DISCARD THE REST OF THE DATA
R2412   BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),D1      DISCARD THE DATA
	BRA.S   R2412

R2440   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT REQUEST
R2454   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2454

	CMP.L   BUFFP,D0        IF ALL DATA READ
	BEQ     R3008           THEN OPERATION COMPLETED
	MOVE.L  BLOCKSIZE(INFOP),D0             INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP
R2550   ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R2586
	MOVE.L  #MAXPAGES,D1
R2586   MOVE.L  D1,BLOCKSIZE(INFOP)

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #READ_DATA,COMMAND(CARDP)
	BRA     ISRDONE

*       IN B_WRITEING STATE ... HAVE DATA TO WRITE OR END OF OPERATION
WRITING BTST    #BUSY,(STATUSP)
	BEQ.S   R2716
*                               NORMAL WRITE OPERATION
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2664   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST BUFFER END
	BEQ.S   R2712
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2712
	MOVE.B  (BUFFP)+,(DATAP)         WRITE THE DATA
	NOP                              FIX FOR 68020 BAR 7/11/85
	NOP                              FIX FOR 68020 BAR 7/11/85
	BRA.S   R2664

R2712   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	BRA     ISRDONE
*               NOT BUSY SO OPERATION IS DONE
*               DID ANYTHING GO WRONG?
R2716   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2750
	BTST    #OP_FAIL,(STATUSP)
	BEQ.S   R2820
*                       SOMETHING WENT WRONG SO TRY TO RESTART
R2750   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2752   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2752

	SUBQ.L  #1,BRETRY(INFOP)        CHECK THE RETRY COUNTER
	BLT.S   R2806
	MOVE.L  12(A6),-(SP)    TRY AGAIN
	MOVE.L  8(A6),-(SP)
	JSR     STARTWRITE
	BRA.S   ISRDONE
*               TOO MANY RETRIES
R2806   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA.S   ISRDONE
*                       NO ERRORS SO FINISH UP
R2820   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2830   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2830

	MOVE.L  BBUFFER(INFOP),D0       CALCULATE END OF BUFFER ADDRESS
	ADD.L   BCOUNT(INFOP),D0
	CMP.L   BUFFP,D0        ANY MORE TO BE WRITTEN ?
	BEQ.S   R3008
	MOVE.L  BLOCKSIZE(INFOP),D0     INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
	MOVE.L  D0,BUFEND(INFOP)        SAVE BASE FOR BUFEND
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE IS ASSUMED TO HAVE 64 BYTES
R2926   ASR.L   #6,D1   DIVIDE BY 64    D1 NOW IS PAGES LEFT
	CMPI.L  #MAXPAGES,D1    CLIP PAGES AT MAXPAGES
	BLT.S   R2962
	MOVE.L  #MAXPAGES,D1
R2962   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
*                               RE-CALCULATE END OF BUFFER
	ASL.L   #6,D1           CONVERT BLOCKSIZE TO BYTES (MULTIPLY BY 64)
	ADD.L   D1,BUFEND(INFOP)        ADD IT TO BASE

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)
	BRA.S   ISRDONE
R3008   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
ISRDONE UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

BUB_DVR_BUB_DVR EQU     *
	RTS

@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.3
log
@
pws2rcs automatic delta on Wed Aug 21 12:27:56 MDT 1991
@
text
@@


54.2
log
@
pws2rcs automatic delta on Wed Aug 21 09:35:48 MDT 1991
@
text
@d1 827
@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@a0 827
*       BUBBLE MEMORY CARD READ/WRITE DRIVERS
*       11 JAN 1983
*
	NOSYMS
*
	MNAME   BUB_DVR
	DEF     BUB_DVR_BUB_DVR
	DEF     BUB_DVR_BUBGETINFO
	DEF     BUB_DVR_BUBDORESET
	DEF     BUB_DVR_BUBDOREAD
	DEF     BUB_DVR_BUBDOWRITE
	DEF     BUB_DVR_BUBDOISR

	PAGE
	SRC     MODULE BUB_DVR;
	SRC     EXPORT
	SRC     TYPE
	SRC     BSTATETYPE = (B_IDLE,
	SRC                   B_READING,
	SRC                   B_WRITING);
	SRC
	SRC     BERRORTYPE = (BNOERROR,
	SRC                   BTIMEOUT,
	SRC                   BOPFAILED,
	SRC                   BBADINTERUPT,
	SRC                   BBADSECTOR,
	SRC                   BBADCOUNT,
	SRC                   BNOTBUBBLE,
	SRC                   BBADDATA,
	SRC                   BIOFAIL);
	SRC
	SRC     BBUFP   = ^CHAR;
	SRC     INFOPTR = ^INFOREC;
	SRC     CARDPTR = ^INTEGER;
	SRC
	SRC     BUFREC= RECORD CASE BOOLEAN OF
	SRC               TRUE : (BUFI : INTEGER);
	SRC               FALSE: (BREC : BBUFP);
	SRC             END;
	SRC
	SRC     INFOREC = RECORD
	SRC                 MAXBYTES : INTEGER;
	SRC                 PRIORITY : 0..255;
	SRC                 RUNSTATE : BSTATETYPE;
	SRC                 ERRORCODE: BERRORTYPE;
	SRC
	SRC                 BSTART   : INTEGER;
	SRC                 BBUFFER  : BUFREC;
	SRC                 BCOUNT   : INTEGER;
	SRC                 BRETRY   : INTEGER;
	SRC
	SRC                 BSPAGE   : INTEGER;
	SRC                 BUFSTART : BBUFP;
	SRC                 BUFADDR  : BBUFP;
	SRC                 BUFEND   : BBUFP;
	SRC                 BLOCKSIZE: INTEGER;
	SRC               END;
	SRC
	SRC     PROCEDURE BUBGETINFO(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDORESET(ANYVAR CARD: CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOREAD(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOWRITE(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC     PROCEDURE BUBDOISR(ANYVAR CARD : CARDPTR; ANYVAR INFO : INFOPTR);
	SRC
	SRC END;

	PAGE
*       EQUATES FOR RECORD OFFSETS AND CARD OPERATIONS
*
INFOP           EQU     A0
CARDP           EQU     A1
STATUSP         EQU     A2
COMMANDP        EQU     A2
DATAP           EQU     A3
BUFFP           EQU     A4
*
*       RUNSTATES
B_IDLE          EQU     0
B_READING       EQU     1
B_WRITING       EQU     2
*
*       ERRORCODES
BNOERROR        EQU     0
BTIMEOUT        EQU     1
BOPFAILED       EQU     2
BBADINTERUPT    EQU     3
BBADSECTOR      EQU     4
BBADCOUNT       EQU     5
BNOTBUBBLE      EQU     6
BBADDATA        EQU     7
BIOFAIL         EQU     8
*
*       INFO RECORD OFFSETS
MAXBYTES        EQU     0       INTEGER
PRIORITY        EQU     4       WORD
RUNSTATE        EQU     6       WORD
ERRORCODE       EQU     8       WORD
BSTART          EQU     10      INTEGER
BBUFFER         EQU     14      LONG
BCOUNT          EQU     18      INTEGER
BRETRY          EQU     22      INTEGER
BSPAGE          EQU     26      INTEGER
BUFSTART        EQU     30      LONG
BUFADDR         EQU     34      LONG
BUFEND          EQU     38      LONG
BLOCKSIZE       EQU     42      LONG
*
*       CARD OFFSETS
CARD_ID         EQU     1
INT_REG         EQU     3
INFO_REG        EQU     5
DATA_REG        EQU     9
COMMAND         EQU     11
STATUS          EQU     11
*
*       STATUS BITS
BUSY            EQU     7
OP_DONE         EQU     6
OP_FAIL         EQU     5
TIME_ERR        EQU     4
CORRECTABLE     EQU     3
UNCORRECT       EQU     2
PARITY_ERR      EQU     1
FIFO_AVAIL      EQU     0
	PAGE
*       INTERUPT REG BITS
INT_E           EQU     7       ENABLED
INT_R           EQU     6       REQUESTED
*
*       BUBBLE COMMAND CODES
WRT_MASKED      EQU     16
INITIALIZE      EQU     17
READ_DATA       EQU     18
WRITE_DATA      EQU     19
READ_SEEK       EQU     20
READ_LOOP_REG   EQU     21
WRT_LOOP_REG    EQU     22
WRT_LOOP        EQU     23
READ_FSA        EQU     24
ABORT_CMD       EQU     25
WRT_SEEK        EQU     26
READ_LOOP       EQU     27
READ_CORRECT    EQU     28
RESET_FIFO      EQU     29
MBM_PURGE       EQU     30
SOFT_RESET      EQU     31
CLEAR_INT       EQU     32      CLEAR INTERUPT
*
*       REG ADDRESS COUNTER VALUES
UTILITY         EQU     10      UTILITY REGISTER
BLR_LSB         EQU     11      BLOCK LENGTH REG LSB
BLR_MSB         EQU     12      BLOCK LENGTH REG MSB
ENABLE          EQU     13      ENABLE REGISTER
ADDR_LSB        EQU     14      ADDRESS LSB
ADDR_MSB        EQU     15      ADDRESS MSB
FIFO            EQU     00      FIFO DATA BUFFER
*
*       CARD INTERUPT ENABLE/DISABLE
ENABLE_INTS     EQU     128
DISABLE_INTS    EQU     000
*
*       MISC CONSTANTS
PAGESIZE        EQU     64      CODE EXPLICITY ASSUMES THIS VALUE
MAXPAGES        EQU     2048

	PAGE
*
*       INTERNAL ROUTINE TO WAIT FOR A COMMAND TO FINISH.
*       HAS A TIME OUT LIMIT
*
	DC.W    0
COMMAND_DONE    EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),CARDP
	LEA     STATUS(CARDP),STATUSP
	CLR.B   12(A6)          COMMAND_DONE := FALSE
	MOVEQ   #-1,D0          MAXIMUM COUNT FOR TIMEOUT

R76     BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT REQUEST
	DBNE    D0,R76
	BNE.S   R142
	BRA.S   CD_EXIT                 NO INTERUPT

R142    MOVEQ   #-1,D0                  RE-INIT LOOP JWS 7/11/85
R140    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	DBEQ    D0,R140
	BEQ.S   R152
	BRA.S   CD_EXIT                 BUSY DIDN'T GO AWAY

R152    BTST    #OP_DONE,(STATUSP)      CHECK STATUS
	BEQ.S   R190                    COMMAND FAILED
	MOVE.B  #1,12(A6)               COMMAND_DONE := TRUE;

R190    MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R196    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R196

CD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #4,SP
	JMP     (A0)

	PAGE
*               EXTERNAL ENTRY POINT TO GET CONFIGURATION INFO
*               ABOUT THE CARD
*               ALSO USED BY BUBDORESET,BUBDOREAD AND BUBDOWRITE
*               TO VALIDATE THE CARD TYPE AND GET MAXBYTES
*               ( THE SIZE OF THE BUBBLE MEMORY UNIT )
	DC.W    0
BUB_DVR_BUBGETINFO      EQU     *
BUBGETINFO      EQU     *
	LINK    A6,#0
	MOVEA.L 8(A6),A0        INFOP
	MOVEA.L (A0),INFOP
	MOVEA.L 12(A6),A1       CARDP
	MOVEA.L (A1),CARDP

	CLR.W   RUNSTATE(INFOP)                 RUNSTATE := B_IDLE
	MOVE.W  #BNOTBUBBLE,ERRORCODE(INFOP)    ERRORCODE := BNOTBUBBLE
	CMPI.B  #30,CARD_ID(CARDP)              CHECK CARD ID
	BNE.S   GI_EXIT
	MOVE.B  INFO_REG(CARDP),D0      COPY INFO REG INTO D0
	BTST    #7,D0                   CHECK EXTENSION BIT OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #4,D0                   CHECK FSA FIELD OF INFO_REG
	BNE.S   GI_EXIT
	BTST    #3,D0                   BOTH BITS
	BNE.S   GI_EXIT
*                       NO PROBLEMS SO FILL IN MAXBYTES AND PRIORITY
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	ANDI.L  #7,D0           GET SIZE FIELD
	ADDQ.L  #1,D0           ADD 1
	MOVEQ   #10,D1          MULTIPLY BY 1024
	ASL.L   D1,D0
	BTST    #5,INFO_REG(CARDP)      1 MEG OR 4 MEG PARTS
	BEQ.S   R356
	MOVEQ   #9,D1   4 MEG PARTS
	ASL.L   D1,D0   MULTIPLY BY 512
	BRA.S   R366
R356    ASL.L   #7,D0   1 MEG PARTS     MULTIPLY BY 128
R366    MOVE.L  D0,(INFOP)      SET MAXBYTES
	MOVE.B  INT_REG(CARDP),D0       GET PRIORITY
	LSR.W   #4,D0   FROM FIELD OF INTERUPT REG ON CARD
	ANDI.W  #3,D0
	ADDQ.W  #3,D0
	MOVE.W  D0,PRIORITY(INFOP)
GI_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               INTERNAL ROUTINE TO LOAD THE BUBBLE CONTROLER
*               PARAMETER REGISTERS PRIOR TO MAJOR OPERATIONS
*
	DC.W    0
INITIALREGS     EQU     *
	LINK    A6,#0
	MOVEA.L 16(A6),CARDP
	MOVEA.L 12(A6),INFOP
	LEA     DATA_REG(CARDP),DATAP
	MOVE.B  #BLR_LSB,COMMAND(CARDP) point RAC at BLR_LSB

	MOVE.B  BLOCKSIZE+3(INFOP),(DATAP)      set LSB of BLOCK LENGTH REG.
	MOVE.B  BLOCKSIZE+2(INFOP),D0   get msb
	ADD.W   #16,D0                  set bit to use 2 FSA channels
	MOVE.B  D0,(DATAP)                      set MSB of BLOCK LENGTH REG.

	MOVEQ   #0,D1           clear MFBTR bit enable burst on last page
	ADD.L   8(A6),D1 add in operation peculiar bits from parameter list
	MOVE.B  D1,(DATAP)                      set ENABLE REG.

	MOVE.B  BSPAGE+3(INFOP),(DATAP)         set LSB of ADDRESS REG.
	MOVE.B  BSPAGE+2(INFOP),(DATAP)         set MSB of ADDRESS REG.

	UNLK    A6
	MOVEA.L (SP)+,A0
	ADDA.W  #12,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO "INITIALIZE" THE
*               BUBBLE MEMORY CONTROLER FOR READ/WRITE OPERATIONS
*               ALSO USED TO ABORT ANY CURRENT READ/WRITE OPERATION
*               (A6)
*               -4      BITCOUNT
*               -8      BYTECOUNT
*              -12      ABORT RETRY COUNTER
*              -16      SAVED CARD ADDRESS
*              -20      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDORESET      EQU     *
	LINK    A6,#-20
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK CARD TYPE
	MOVEA.L 8(A6),A0        GET INFOREC POINTER
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)
	BNE     RS_EXIT
	MOVE.L  INFOP,-20(A6)   SAVE INFOP
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.L  CARDP,-16(A6)   SAVE CARDP

	MOVE.B  #0,CARD_ID(CARDP)       RESET THE CARD
	MOVE.L   #300,D0         KILL AT LEAST 200 MICRO SECONDS         (rdq)
WAIT200 DBF     D0,WAIT200      *** TIMEING LOOP ***

	MOVE.B  #3,-12(A6)      SET RETRY COUNT FOR ABORT COMMAND
R700    LEA     COMMAND(CARDP),COMMANDP
*                                       ENABLE INTERUPTS ON OPDONE
	MOVE.B  #ENABLE,(COMMANDP)      POINT RAC AT ENABLE REG
	MOVE.B  #1,DATA_REG(CARDP)      SET ENABLE REG

	MOVE.B  #ABORT_CMD,(COMMANDP)   ABORT ANY CURRENT OPERATION
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR IT TO FINISH
	TST.B   (SP)+   DID IT FINISH OK ?
	BNE.S   R800            IF FINISHED OK THEN PROCEEDE
	SUBQ.B  #1,-12(A6)      DECRIMENT RETRY COUNTER
	BEQ     R1176           IF COUNT DONE THEN GIVE UP
	MOVEA.L -16(A6),CARDP   RELOAD CARDP
	BRA     R700            TRY AGAIN

R800    MOVEA.L -20(A6),INFOP           RETRIEVE INFOP
	MOVE.L  MAXBYTES(INFOP),D7      BSPAGE := MAXBYTES DIV 64 - 1;
	ASR.L   #6,D7   DIV 64
	SUBQ.L  #1,D7   - 1
	MOVE.L  D7,BSPAGE(INFOP)

	MOVE.L  #1,BLOCKSIZE(INFOP)     BLOCKSIZE := 1 PAGE
	MOVE.L  -16(A6),-(SP)   CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIXUP THE PARAMETER REGS

	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #INITIALIZE,COMMAND(CARDP)
R922    BTST    #INT_R,INT_REG(CARDP)   WAIT FOR INTERUPT
	BEQ     R922                    (ON FIFO HALF FULL)
R944    BTST    #BUSY,(STATUSP)         WAIT FOR NOT BUSY
	BNE     R944
	BTST    #OP_DONE,(COMMANDP)     DID IT WORK ?
	BEQ     R1162
	MOVE.L  CARDP,-(SP)     CARD^
	MOVEA.L 8(A6),A1
	MOVE.L  (A1),-(SP)      INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX PARAMETER REGS
*                               { THIS ALSO STOPS CURRENT INTERUPT }
	MOVEA.L -16(A6),CARDP   RETRIEVE CARDP
	LEA     STATUS(CARDP),STATUSP   { STATUSP is same as COMMANDP }
	MOVE.B  #READ_LOOP_REG,(COMMANDP)       READ BOOT LOOP REGISTER
R1018   BTST    #INT_R,INT_REG(CARDP)           WAIT FOR INTERUPT
	BEQ     R1018
R1040   CLR.L   -4(A6)          BITCOUNT := 0
	CLR.L   -8(A6)          BYTECOUNT := 0
R1048   BTST    #BUSY,STATUS(CARDP)     WHILE BUSY DO
	BEQ.S   R1124
R1068   BTST    #FIFO_AVAIL,STATUS(CARDP)       WHILE FIFO_AVAIL DO
	BEQ     R1048           IF FIFO EMPTY THEN CHECK BUSY
	ADDQ.L  #1,-8(A6)       INCREMENT BYTECOUNT
	MOVE.B  DATA_REG(CARDP),D0      READ THE DATA BYTE
*                               COUNT THE 1 BITS IN LOW BYTE OF D0
	MOVEQ   #0,D1   COUNT := 0
	MOVEQ   #7,D2   LOOP COUNTER
	MOVEQ   #0,D3   ZERO CONSTANT
COUNTL  LSL.B   #1,D0   SHIFT HI BIT TO X
	ADDX.B  D3,D1   ADD 0 + X + COUNT { WILL NEVER BE MORE THAN 8 }
	DBRA    D2,COUNTL

	ADD.L   D1,-4(A6)       ADD COUNT TO BIT COUNT
	BRA     R1068   END WHILE FIFO_AVAIL

R1124   MOVEQ   #40,D1          MUST HAVE EXACTLY 40 BYTES
	CMP.L   -8(A6),D1
	BNE.S   R1150
	CMPI.L  #270,-4(A6)     MUST HAVE EXACTLY 270 BITS
	BEQ.S   RS_EXIT
R1150   MOVEA.L -20(A6),INFOP   WRONG BYTE / BIT COUNT
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1162   MOVEA.L -20(A6),INFOP   INITIALIZE OPERATION FAILED
	MOVE.W  #BOPFAILED,ERRORCODE(INFOP)
	BRA.S   RS_EXIT
R1176   MOVEA.L -20(A6),INFOP   FAILED TO RESPOND TO ABORT COMMAND
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
RS_EXIT UNLK A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOREAD
*               ALSO USED BY BUBDOISR TO RESTART A FAILED READ OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTREAD       EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A1       CARD
	MOVE.L  (A1),-4(A6)
	MOVEA.L 8(A6),A0        INFO
	MOVE.L  (A0),-8(A6)
	MOVEA.L (A0),INFOP      INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE := BNOERROR
	MOVEA.L -4(A6),CARDP    CARD^
	MOVE.B  #ENABLE,COMMAND(CARDP)  SET RAC TO ENABLE REG.
	MOVE.B  #1,DATA_REG(CARDP)      ENABLE INTERUPT ON OPDONE
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE                    WAIT FOR IT
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1332
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  -8(A6),-(SP)    INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -8(A6),INFOP
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_READING,RUNSTATE(INFOP)      SHOW NOW READING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #READ_DATA,COMMAND(CARDP)       START READ OPERTATION
	BRA.S   SR_EXIT
R1332   MOVEA.L -8(A6),INFOP            RESET FIFO FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)
SR_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA READ OPERATIONS
*
	DC.W    0
BUB_DVR_BUBDOREAD       EQU     *
	LINK    A6,#0
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE<>BNOERROR
	BNE     RD_EXIT                 THEN QUIT
	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP      CARD^

	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1420           CAN'T BE NEGATIVE
	TST.B   D0              MUST BE MULTIPLE OF 256
	BEQ.S   R1428
R1420   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     RD_EXIT

R1428   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTE COUNT
	BLE.S   R1450           MUST BE GREATER THAN ZERO
	ADD.L   D1,D0           BCOUNT + BSTART
	CMP.L   (INFOP),D0      CAN'T BE GREATER THAN MAXBYTES
	BLE.S   R1456
R1450   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA.S   RD_EXIT
R1456   MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
	MOVE.L  D1,BUFEND(INFOP)        SET COUNT IN BUFEND
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP BYTECOUNT
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1480
	MOVE.L  #MAXPAGES,D1
R1480   MOVE.L  D1,BLOCKSIZE(INFOP)
*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)
	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO COUNT)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       FINISH UP AND ISSUE THE READ COMMAND
RD_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               FINAL STAGE OF BUBDOWRITE
*               ALSO USED BY BUBDOISR TO RESTART A FAILED WRITE OPERATION
*               (A6)
*               -4      SAVED CARD ADDRESS
*               -8      SAVED INFO RECORD ADDRESS
*
	DC.W    0
STARTWRITE      EQU     *
	LINK    A6,#-8
	MOVEA.L 12(A6),A0       CARD
	MOVE.L  (A0),-4(A6)     SAVE CARD^
	MOVEA.L 8(A6),A0        INFO
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-8(A6)    SAVE INFO^
	CLR.W   RUNSTATE(INFOP)         RUNSTATE := B_IDLE
	CLR.W   ERRORCODE(INFOP)        ERRORCODE:= BNOERROR
	MOVE.L  -4(A6),-(SP)    CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)      ENABLE RCD AND OPDONE FUNCTIONS
	JSR     INITIALREGS     FIX CONTROL REGS.
	MOVEA.L -4(A6),CARDP
	MOVE.B  #RESET_FIFO,COMMAND(CARDP)      CLEAR/RESET THE FIFO
	SUBQ.L  #2,SP           SPACE FOR FUNCTION VALUE
	MOVE.L  CARDP,-(SP)     CARD^
	JSR     COMMAND_DONE    WAIT FOR FIFO TO RESET
	TST.B   (SP)+           DID IT WORK ?
	BEQ.S   R1734
	MOVEA.L -8(A6),INFOP    OK SO CONTINUE
	MOVE.L  BUFSTART(INFOP),BUFADDR(INFOP)  SET BUFFER ADDRESS
	MOVE.W  #B_WRITING,RUNSTATE(INFOP)      SHOW NOW WRITING
	MOVEA.L -4(A6),CARDP
	MOVE.B  #ENABLE_INTS,INT_REG(CARDP)     ENABLE CARD INTERUPTS
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)      START THE OPERATION
	BRA.S   SW_EXIT

R1734   MOVEA.L -8(A6),INFOP            FIFO RESET FAILED
	MOVE.W  #BTIMEOUT,ERRORCODE(INFOP)

SW_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*               EXTERNAL ENTRY POINT TO START DATA WRITE OPERATIONS
*               (A6)
*               -4      UNUSED          (COMPILER TEMP OPTIMIZED OUT)
*               -8      SAVED CARD ADDRESS
*              -12      SAVED INFO RECORD ADDRESS
*
	DC.W    0
BUB_DVR_BUBDOWRITE      EQU     *
	LINK    A6,#-12
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     BUBGETINFO      FILL IN INFO FIELDS AND CHECK THE CARD TYPE
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP
	TST.W   ERRORCODE(INFOP)        IF ERRORCODE <> BNOERROR
	BNE     WT_EXIT                 THEN EXIT
	MOVEA.L 12(A6),A1
	MOVE.L  (A1),-8(A6)     CARD^
	MOVEA.L 8(A6),A0
	MOVEA.L (A0),INFOP      INFO^
	MOVE.L  INFOP,-12(A6)
	MOVE.L  BSTART(INFOP),D0        CHECK STARTING POSITION (BYTE)
	BMI.S   R1820                   CAN'T BE NEGATIVE
	TST.B   D0                      MUST BE MULTIPLE OF 256
	BEQ.S   R1830
R1820   MOVE.W  #BBADSECTOR,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1830   MOVE.L  BCOUNT(INFOP),D1        CHECK BYTECOUNT
	BLE.S   R1860                   MUST BE GREATER THAN ZERO
	TST.B   D1
	BNE.S   R1860                   MUST BE MULTIPLE OF 256
	ADD.L   D1,D0
	CMP.L   (A0),D0         IF (BCOUNT+BSTART)<=MAXBYTES
	BLE.S   R1876           THEN CONTINUE
R1860   MOVE.W  #BBADCOUNT,ERRORCODE(INFOP)
	BRA     WT_EXIT

R1876   MOVEA.L -8(A6),CARDP    CARD^
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    DISABLE CARD INTERUPTS
*               CALCULATE NUMBER OF PAGES FOR THIS OPERATION
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R1880
	MOVE.L  #MAXPAGES,D1
R1880   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
	ASL.L   #6,D1           CONVERT BLOCKSIZE BACK TO BYTES
	MOVE.L  D1,BUFEND(INFOP)        SAVE IT IN BUFEND

*               CALCULATE START PAGE FOR THIS OPERATION
	MOVE.L  BSTART(INFOP),D0
	ASR.L   #6,D0   DIVIDE BY 64
	MOVE.L  D0,BSPAGE(INFOP)

	MOVE.L  BBUFFER(INFOP),D0   GET CURRENT START OF BUFFER
	MOVE.L  D0,BUFSTART(INFOP)  MARK START OF BUFFER
	ADD.L   D0,BUFEND(INFOP)    MARK END OF BUFFER (ADD ADDRESS TO SIZE)
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTWRITE      FINISH UP AND ISSUE THE WRITE COMMAND
WT_EXIT UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

	PAGE
*
*                       INTERUPT SERVICE ROUTINE
*
	DC.W    0
BUB_DVR_BUBDOISR        EQU     *
	LINK    A6,#0
	MOVEA.L 12(A6),A1       GET CARD ADDRESS
	MOVEA.L (A1),CARDP              CARD BASE ADDRESS
	LEA     STATUS(CARDP),STATUSP   STATUS REG ADDRESS
	LEA     DATA_REG(CARDP),DATAP   DATA REG ADDRESS

	MOVEA.L 8(A6),A0        GET INFOREC ADDRESS
	MOVEA.L (A0),INFOP              INFOREC BASE ADDRESS
	MOVEA.L BUFADDR(INFOP),BUFFP    BUFFER ADDRESS

	CMPI.W  #B_READING,RUNSTATE(A0) JUMP ACCORDING TO RUNSTATE
	BEQ.S   READING
	BGT     WRITING

*       IN B_IDLE STATE ... HAVE UNEXPECTED INTERUPT
IDLE    MOVE.W  #BBADINTERUPT,ERRORCODE(INFOP)  set ERRORCODE
	MOVE.B  #DISABLE_INTS,INT_REG(CARDP)    disable interupt enable
IDLE1   BTST    #INT_E,INT_REG(CARDP)   wait for enable bit to clear
	BNE.S   IDLE1
	BRA     ISRDONE                 all done

*       IN B_READING    ... HAVE DATA OR END OF OPERATION
READING BTST    #BUSY,(STATUSP)
	BEQ.S   R2232
*                       BUSY SO HAVE DATA TO READ
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2132   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST END OF BUFFER
	BEQ.S   R2143
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ.S   R2135
R2133   MOVE.B  (DATAP),(BUFFP)+        READ THE DATA
	BRA.S   R2132

R2135   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
	BRA     ISRDONE                 THEN EXIT

R2143   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK BUFFER ADDRESS
*                                       THEN DISCARD UNWANTED DATA
R2196   BTST    #FIFO_AVAIL,(STATUSP)   CHECK FIFO
	BEQ     ISRDONE                 EXIT IF FIFO IS EMPTY
	MOVE.B  (DATAP),D0              READ & DISCARD
	BRA.S   R2196
*                       NOT BUSY SO END OF OPERATION
*       DID ANYTHING GO WRONG ?
R2232   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2240
	BTST    #OP_FAIL,(STATUSP)
	BNE.S   R2240
	BTST    #UNCORRECT,(STATUSP)
	BEQ.S   R2348
	MOVE.W  #BBADDATA,ERRORCODE(INFOP)      SET BADDATA ERROR
*       SOMETHING WENT WRONG SO TRY TO RESTART THE CURRENT REQUEST
R2240   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR INTERUPT REQUEST
R2280   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2280

	SUBQ.L  #1,BRETRY(INFOP)        DECRIMENT RETRY COUNTER
	BLT.S   R2334
	MOVE.L  12(A6),-(SP)    CARD
	MOVE.L  8(A6),-(SP)     INFO
	JSR     STARTREAD       RESTART THE CURRENT REQUEST
	BRA     ISRDONE

*       TOO MANY RETRIES
R2334   CLR.W   RUNSTATE(INFOP)  SET RUNSTATE TO B_IDLE
	TST.W   ERRORCODE(INFOP) IS ERRORCODE ALREADY SET ?
	BNE     ISRDONE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA     ISRDONE

*       OPERATION COMPLETED OK
*               READ ANY DATA LEFT IN THE FIFO
R2348   MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2350   CMP.L   BUFFP,D0        CHECK BUFFER ADDRESS AGAINST END OF BUFFER
	BEQ.S   R2412
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),(BUFFP)+
	BRA.S   R2350
*               DISCARD THE REST OF THE DATA
R2412   BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2440
	MOVE.B  (DATAP),D1      DISCARD THE DATA
	BRA.S   R2412

R2440   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT REQUEST
R2454   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2454

	CMP.L   BUFFP,D0        IF ALL DATA READ
	BEQ     R3008           THEN OPERATION COMPLETED
	MOVE.L  BLOCKSIZE(INFOP),D0             INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE SIZE IS ASSUMED TO BE 64 BYTES
	ADD.L   #63,D1  ROUND UP
R2550   ASR.L   #6,D1   DIVIDE BY 64    D1 IS NOW NUMBER OF PAGES
	CMPI.L  #MAXPAGES,D1    CLIP IT AT MAXPAGES
	BLT.S   R2586
	MOVE.L  #MAXPAGES,D1
R2586   MOVE.L  D1,BLOCKSIZE(INFOP)

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #READ_DATA,COMMAND(CARDP)
	BRA     ISRDONE

*       IN B_WRITEING STATE ... HAVE DATA TO WRITE OR END OF OPERATION
WRITING BTST    #BUSY,(STATUSP)
	BEQ.S   R2716
*                               NORMAL WRITE OPERATION
	MOVE.L  BUFEND(INFOP),D0        GET END OF BUFFER ADDRESS
R2664   CMP.L   BUFFP,D0        CHECK BUFFER AGAINST BUFFER END
	BEQ.S   R2712
	BTST    #FIFO_AVAIL,(STATUSP)   CHECK THE FIFO
	BEQ.S   R2712
	MOVE.B  (BUFFP)+,(DATAP)         WRITE THE DATA
	NOP                              FIX FOR 68020 BAR 7/11/85
	NOP                              FIX FOR 68020 BAR 7/11/85
	BRA.S   R2664

R2712   MOVE.L  BUFFP,BUFADDR(INFOP)    PUT BACK THE BUFFER ADDRESS
	BRA     ISRDONE
*               NOT BUSY SO OPERATION IS DONE
*               DID ANYTHING GO WRONG?
R2716   BTST    #TIME_ERR,(STATUSP)
	BNE.S   R2750
	BTST    #OP_FAIL,(STATUSP)
	BEQ.S   R2820
*                       SOMETHING WENT WRONG SO TRY TO RESTART
R2750   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2752   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2752

	SUBQ.L  #1,BRETRY(INFOP)        CHECK THE RETRY COUNTER
	BLT.S   R2806
	MOVE.L  12(A6),-(SP)    TRY AGAIN
	MOVE.L  8(A6),-(SP)
	JSR     STARTWRITE
	BRA.S   ISRDONE
*               TOO MANY RETRIES
R2806   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
	MOVE.W  #BIOFAIL,ERRORCODE(INFOP)
	BRA.S   ISRDONE
*                       NO ERRORS SO FINISH UP
R2820   MOVE.B  #CLEAR_INT,(COMMANDP)   CLEAR THE INTERUPT
R2830   BTST    #INT_R,INT_REG(CARDP)   WAIT FOR IT TO GO AWAY
	BNE.S   R2830

	MOVE.L  BBUFFER(INFOP),D0       CALCULATE END OF BUFFER ADDRESS
	ADD.L   BCOUNT(INFOP),D0
	CMP.L   BUFFP,D0        ANY MORE TO BE WRITTEN ?
	BEQ.S   R3008
	MOVE.L  BLOCKSIZE(INFOP),D0     INCREMENT START PAGE
	ADD.L   D0,BSPAGE(INFOP)

	MOVE.L  BUFADDR(INFOP),D0
	MOVE.L  D0,BUFSTART(INFOP)      SET NEW BUFFER ADDRESS
	MOVE.L  D0,BUFEND(INFOP)        SAVE BASE FOR BUFEND
*                       CALCULATE BLOCKSIZE FOR THIS OPERATION
	SUB.L   BBUFFER(INFOP),D0
	MOVE.L  BCOUNT(INFOP),D1
	SUB.L   D0,D1           D1 NOW IS BYTES LEFT
*                               PAGE IS ASSUMED TO HAVE 64 BYTES
R2926   ASR.L   #6,D1   DIVIDE BY 64    D1 NOW IS PAGES LEFT
	CMPI.L  #MAXPAGES,D1    CLIP PAGES AT MAXPAGES
	BLT.S   R2962
	MOVE.L  #MAXPAGES,D1
R2962   MOVE.L  D1,BLOCKSIZE(INFOP)
*                               FOR WRITE OPS, BUFEND IS END OF SEGMENT
*                               RE-CALCULATE END OF BUFFER
	ASL.L   #6,D1           CONVERT BLOCKSIZE TO BYTES (MULTIPLY BY 64)
	ADD.L   D1,BUFEND(INFOP)        ADD IT TO BASE

	MOVE.L  CARDP,-(SP)     CARD^
	MOVE.L  INFOP,-(SP)     INFO^
	MOVE.L  #$21,-(SP)
	JSR     INITIALREGS

	MOVEA.L 12(A6),A1
	MOVEA.L (A1),CARDP
	MOVE.B  #WRITE_DATA,COMMAND(CARDP)
	BRA.S   ISRDONE
R3008   CLR.W   RUNSTATE(INFOP) SET RUNSTATE TO B_IDLE
ISRDONE UNLK    A6
	MOVEA.L (SP)+,A0
	ADDQ.W  #8,SP
	JMP     (A0)

BUB_DVR_BUB_DVR EQU     *
	RTS

@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@@


24.1
log
@Automatic bump of revision number for PWS version 3.2
@
text
@@


23.1
log
@Automatic bump of revision number for PWS version 3.2P
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@@


21.1
log
@Automatic bump of revision number for PWS version 3.2M
@
text
@@


20.1
log
@Automatic bump of revision number for PWS version 3.2L
@
text
@@


19.1
log
@Automatic bump of revision number for PWS version 3.2K
@
text
@@


18.1
log
@Automatic bump of revision number for PWS version 3.2J
@
text
@@


17.1
log
@Automatic bump of revision number for PWS version 3.2I+
@
text
@@


16.1
log
@Automatic bump of revision number for PWS version 3.2I
@
text
@@


15.1
log
@Automatic bump of revision number for PWS version 3.2H
@
text
@@


14.1
log
@Automatic bump of revision number for PWS version 3.2G
@
text
@@


13.1
log
@Automatic bump of revision number for PWS version 3.2F
@
text
@@


12.1
log
@Automatic bump of revision number for PWS version 3.2E
@
text
@@


11.1
log
@Automatic bump of revision number for PWS version 3.2D
@
text
@@


10.1
log
@Automatic bump of revision number for PWS version 3.2C
@
text
@@


9.1
log
@Automatic bump of revision number for PWS version 3.2B
@
text
@@


8.1
log
@Automatic bump of revision number for PWS version 3.2A
@
text
@@


7.1
log
@Automatic bump of revision number for PWS version 3.2l
@
text
@@


6.1
log
@Automatic bump of revision number for PWS version 3.2k
@
text
@@


5.1
log
@Automatic bump of revision number for PWS version 3.2j
@
text
@@


4.1
log
@Automatic bump of revision number for PWS version 3.2i
@
text
@@


3.1
log
@Automatic bump of revision number for PWS version 3.2h
@
text
@@


2.1
log
@Auto bump rev number to 2.1 for sys 3.2e.
@
text
@@


1.1
log
@Initial revision
@
text
@@
