* INSTALL_DBS CODE SECTION - PROVIDES CHECKING AND INSTALLATION FUNCTIONS
* CHECK A JUST EDITED LINE
D$       SETSTR   [.LEFT(.FILE,4)]
         INCLUDE  [D$]_QDOS_TRAP_IN
         INCLUDE  [D$]_QDOS_VECT_IN
         INCLUDE  [D$]_QDOS_DATA_IN
         INCLUDE  [D$]_DATA_IN
         INCLUDE  [D$]_INST_IN
         XDEF     POST_CHK
         XDEF     CHK_CODE,CK_BAUD2,CK_PAR,CK_CONT,CK_255
*
         SECTION  CODE
* THIS ROUTINE CHECKS THE FIELDS AFTER EDITING, SOME SUBROUTINES APPENDING THE
*  APPROPRIATE VALUES ONTO THE INSTALL BUFFER, OR PLACING THEM IN THE CHECKING
*  BUFFER.
POST_CHK
         CLR.W    INS_BUFL(A3)      START AT THE BEGINNING OF THE INSTALL BUFF
         CMPI.B   #10,D1            GENERAL CHECKS FOR FIELDS 1 TO 9
         BCC.L    CHK_CODE          JUMP IF PRINTER CODES TO CHECK
*
         SUBQ.B   #1,D1             INDEX INTO THE FIRST CHECK TABLE
         EXT.W    D1
         LSL.W    #1,D1
         ADD.W    CHK_TAB1(PC,D1.W),D1
         JMP      CHK_TAB1(PC,D1.W)
*
CHK_TAB1
* 100 DATA -64,"FILENAME$"
         DC.W     NO_CHECK-*        DO NOT CHECK FILENAME$
* 110 DATA -9,"DRIVER$"
         DC.W     NO_CHECK-*        DO NOT CHECK PRINTER$
* 115 DATA -64,"COMMENT$"
         DC.W     NO_CHECK-*        DO NOT CHECK COMMENT$
* 120 DATA -17,"PORT$"
         DC.W     NO_CHECK-*        DO NOT CHECK PORT$
* 130 DATA 1,"BAUD%"
         DC.W     CK_BAUD-*         CHECK BAUD%
* 140 DATA -8,"PARITY$"
         DC.W     CK_PAR-*          CHECK PARITY$
* 150 DATA -5,"CONTINUOUS$"
         DC.W     CK_CONT-*         CHECK CONTINUOUS$
* 160 DATA 1,"PAGE_LENGTH%"
         DC.W     CK_255-*          CHECK PAGE_LENGTH%
* 170 DATA 1,"WIDTH%"
         DC.W     CK_255-*          CHECK WIDTH%
*
* CONVERT STRING (A1) TO AN UNSIGNED WORD INTEGER IN D1
CN_DTOI  MOVEM.L  D2/A0/A1,-(SP)
         MOVE.W   (A1)+,A0          A0 = BUFFER END PTR
         ADDA.L   A1,A0
         CMPA.L   A1,A0
         BEQ.S    CNDI_BAD          ERROR IF BLANK LINE
         MOVEQ    #0,D1             D1 = RUNNING TOTAL
         MOVEQ    #0,D2             D2 = CHARACTER HOLDER
CNDI_LP
         MULU     #10,D1            DO A DECIMAL SHIFT
         CMPI.L   #$00007FFF,D1     IF AN OVERFLOW OCCURS, EXIT
         BHI.S    CNDI_BAD

         MOVE.B   (A1)+,D2          GET NEXT CHAR
         SUBI.B   #'0',D2           CONVERT ASCII TO NUMERIC
         BCS.S    CNDI_BAD          ERROR IF BAD CHARACTER
         CMPI.B   #9,D2
         BHI.S    CNDI_BAD          AGAIN, ERROR IF BAD CHARACTER
         ADD.L    D2,D1

         CMPA.L   A1,A0             LOOP UNTIL ALL CHARS DONE
         BHI.S    CNDI_LP
         MOVEM.L  (SP)+,D2/A0/A1
         MOVE     #4,CCR            SET THE Z FLAG - OK
         RTS
CNDI_BAD
         MOVEM.L  (SP)+,D2/A0/A1
         MOVE     #0,CCR            CLEAR THE Z FLAG - ERROR
         RTS
*
* NO CHECK MADE
NO_CHECK
         MOVEQ    #0,D1             CONTINUE ON
         MOVEQ    #0,D0             NO ERROR
         RTS
*
* CHECK THE BAUD RATE
MS_BAUD  DC.W     13,'Bad baud rate'  ERROR MESSAGE
CK_BAUD
         LEA      MS_BAUD(PC),A2
         BSR.S    CN_DTOI           EVALUATE THE STRING
         BNE.S    C_BD_ERR          JUMP IF ERROR
*
CK_BAUD2
         MOVEM.L  D2/A1,-(SP)
         LEA      BAUDLIST(PC),A1   MUST BE ONE OF THE GIVEN LIST
         MOVE.W   (A1)+,D2          GET THE QUANTITY-1
C_BD_LP
         CMP.W    (A1)+,D1          IS IT THIS VALUE?
         DBEQ     D2,C_BD_LP        DROP OUT IF SO, ELSE LOOP
         MOVEM.L  (SP)+,D2/A1
*
         BNE.S    C_BD_ERR          JUMP IF ERROR
         MOVE.W   D1,BUFF(A3)       STORE THE BAUD RATE
         MOVEQ    #0,D1             SIGNAL OK
         MOVEQ    #0,D0
         RTS
*
C_BD_ERR
         MOVEQ    #-1,D1            SIGNAL ERROR: RE-EDIT
         MOVEQ    #0,D0
         RTS
BAUDLIST DC.W     7-1
         DC.W     75,300,600,1200,2400,4800,9600
*
* CHECK THE PARITY
MS_PAR   DC.W     15,'Bad parity type'
CK_PAR
         LEA      MS_PAR(PC),A2
         CMPI.W   #5,(A1)
         BHI.S    C_PA_ERR          ERROR IF STRING LONGER THAN 5 CHARACTERS
         LEA      BUFF(A3),A0
         MOVE.L   #'    ',(A0)      FILL BUFFER OUT WITH SPACES
         MOVE.W   #'  ',4(A0)
         MOVEM.L  A1,-(SP)
         MOVE.W   (A1)+,D1          GET THE LENGTH
         BRA.S    C_PA_BLE          GO INTO COPY LOOP
C_PA_BLP
         MOVE.B   (A1)+,(A0)        COPY STRING INTO BUFFER
         BCLR     #5,(A0)+          MAKE UPPERCASE
C_PA_BLE DBRA     D1,C_PA_BLP
         MOVEM.L  (SP)+,A1
*
         MOVEM.L  D2/D3,-(SP)
         MOVE.L   BUFF(A3),D2       GET STRING PADDED WITH SPACES IN D2,D3
         MOVE.W   BUFF+4(A3),D3
         LEA      PAR_LIST(PC),A0   SEARCH THE PARITY LIST
         MOVE.W   (A0)+,D1          GET QUANTITY-1
C_PA_CLP
         CMP.L    (A0),D2           IS THIS THE ENTRY?
         BNE.S    C_PA_CLE          JUMP IF NOT
         CMP.W    4(A0),D3          MAKE TOTALLY SURE
C_PA_CLE
         ADDQ.L   #8,A0             POINT TO NEXT ENTRY
         DBEQ     D1,C_PA_CLP       DROP OUT IF FOUND, ELSE LOOP
         MOVEM.L  (SP)+,D2/D3
*
         BNE.S    C_PA_ERR          JUMP IF ERROR
         MOVE.B   -(A0),BUFF(A3)    STORE THE INSTALL VALUE
         MOVEQ    #0,D1             SIGNAL OK
         MOVEQ    #0,D0
         RTS
*
C_PA_ERR
         MOVEQ    #-1,D1            SIGNAL ERROR: RE-EDIT
         MOVEQ    #0,D0
         RTS
PAR_LIST DC.W     5-1
         DC.W     'NONE  ',0        TYPE, INSTALL VALUE
         DC.W     'SPACE ',1
         DC.W     'MARK  ',2
         DC.W     'ODD   ',3
         DC.W     'EVEN  ',4
*
* CHECK CONTINUOUS
MS_CONT  DC.W     28,'String must be "YES" or "NO"'
CK_CONT
         LEA      MS_CONT(PC),A2
         CMPI.W   #2,(A1)           IF STRING IS OF LENGTH 2, SHOULD BE "NO"
         BEQ.S    C_CN_NO
         CMPI.W   #3,(A1)           SHOULD BE LENGTH 3 OTHERWISE
         BNE.S    C_CN_ERR          ERROR IF NOT
*
         MOVE.L   2(A1),D1
         ANDI.L   #$DFDFDF00,D1     MAKE LETTERS UPPERCASE
         MOVE.B   #' ',D1           PUT A SPACE IN THE LSB
         CMPI.L   #'YES ',D1
         BNE.S    C_CN_ERR          ERROR IF NOT YES
         MOVE.B   #1,BUFF(A3)       STORE: CONTINUOUS FORMS
*
         MOVEQ    #0,D1
         MOVEQ    #0,D0
         RTS
*
C_CN_NO
         MOVE.W   2(A1),D1
         ANDI.W   #$DFDF,D1         MAKE LETTERS UPPERCASE
         CMPI.W   #'NO',D1
         BNE.S    C_CN_ERR          ERROR IF NOT NO
         CLR.B    BUFF(A3)          STORE: NOT CONTINUOUS FORMS
*
         MOVEQ    #0,D1
         MOVEQ    #0,D0
         RTS
*
C_CN_ERR
         MOVEQ    #-1,D1            SIGNAL ERROR: RE-EDIT
         MOVEQ    #0,D0
         RTS
*
* CHECK WIDTH AND LENGTH ARE AT MOST 255
MS_BAD   DC.W     10,'Bad number'
MS_255   DC.W     19,'Maximum size is 255'
CK_255
         LEA      MS_BAD(PC),A2
         BSR.L    CN_DTOI           EVALUATE THE STRING
         BNE.S    C_255_ER          JUMP IF ERROR
*
         LEA      MS_255(PC),A2
         CMPI.W   #255,D1
         BHI.S    C_255_ER          JUMP IF OUT OF RANGE
*
         MOVEQ    #0,D1
         MOVEQ    #0,D0
         RTS
*
C_255_ER
         MOVEQ    #-1,D1            SIGNAL ERROR: RE-EDIT
         MOVEQ    #0,D0
         RTS
*
* SEE IF NEXT CHAR IS THE END OF AN ITEM
S_ITEM_E
         CMPA.L   A1,A2
         BEQ.S    SITEM_EN          JUMP IF END OF STRING
         MOVE.B   (A1),D1
         CMPI.B   #',',(A1)
         BEQ.S    SITEM_EN          JUMP IF END OF ITEM
         CMPI.B   #';',(A1)
SITEM_EN
         RTS                        NOT END, Z=0; END, Z=1

*
* CHECK PRINTER CODE STRINGS
CHK_CODE
         MOVEM.L  D2/D3/A1/A2,-(SP)
         MOVE.W   (A1)+,A2
         ADDA.L   A1,A2             A2 = STRING END PTR
         MOVEQ    #0,D2             NUMBER OF ITEMS
         CMPA.L   A1,A2
         BEQ.L    S_OK              A BLANK LINE IS OK
S_LOOP
         MOVE.B   (A1),D1           THE TYPE OF ITEM MUST BE DECIDED FIRST
         CMPI.B   #'$',D1
         BEQ.L    S_HEX             JUMP IF A HEX NUMBER
         CMPI.B   #39,D1
         BEQ.L    S_CHAR            JUMP IF AN ASCII CHAR (')
         CMPI.B   #'"',D1
         BEQ.L    S_CHAR            JUMP IF AN ASCII CHAR (")
         CMPI.B   #'9',D1
         BLS.L    S_DEC             JUMP IF A DECIMAL NUMBER
* IT IS THEREFORE AN ASCII CONTROL CODE
         LEA      BUFF(A3),A0
         MOVE.L   #'    ',(A0)
         BCLR     #5,D1             MAKE UPPERCASE
         MOVE.B   D1,(A0)+          STORE FIRST CHAR
         ADDQ.L   #1,A1
*
         BSR.S    S_ITEM_E
         BEQ.L    S_ERROR           MUST NOT BE OUT OF CHARS
         BCLR     #5,D1             MAKE UPPERCASE
         MOVE.B   D1,(A0)+
         ADDQ.L   #1,A1
*
         BSR.S    S_ITEM_E
         BEQ.S    S_CC_CHK          IF NO 3RD CHAR, CHECK THE ITEM
         BCLR     #5,D1             MAKE UPPERCASE
         MOVE.B   D1,(A0)+
         ADDQ.L   #1,A1
*
S_CC_CHK
         MOVE.L   BUFF(A3),D1       GET THE ITEM IN D1, PADDED WITH $00'S
         LEA      ASCIILIS(PC),A0   SEARCH FOR THE ITEM
         MOVE.W   (A0)+,D3          GET THE QUANTITY-1
S_CC_CLP
         CMP.L    (A0),D1           IS IT THIS ENTRY?
         ADDQ.L   #6,A0             INCREMENT PTR WITHOUT CORRUPTING CCR
         DBEQ     D3,S_CC_CLP       DROP OUT IF FOUND, ELSE LOOP
*
         BNE.L    S_ERROR           EXIT IF ERROR
         MOVE.W   -(A0),D1
         BRA.L    S_STORE           GO TO STORE THE VALUE
ASCIILIS
         DC.W     33-1
         DC.W     'NUL ',0
         DC.W     'SOH ',1
         DC.W     'STX ',2
         DC.W     'ETX ',3
         DC.W     'EOT ',4
         DC.W     'ENQ ',5
         DC.W     'ACK ',6
         DC.W     'BEL ',7
         DC.W     'BS  ',8
         DC.W     'HT  ',9
         DC.W     'LF  ',10
         DC.W     'VT  ',11
         DC.W     'FF  ',12
         DC.W     'CR  ',13
         DC.W     'SO  ',14
         DC.W     'SI  ',15
         DC.W     'DLE ',16
         DC.W     'DC1 ',17
         DC.W     'DC2 ',18
         DC.W     'DC3 ',19
         DC.W     'DC4 ',20
         DC.W     'NAK ',21
         DC.W     'SYN ',22
         DC.W     'ETB ',23
         DC.W     'CAN ',24
         DC.W     'EM  ',25
         DC.W     'SUB ',26
         DC.W     'ESC ',27
         DC.W     'FS  ',28
         DC.W     'GS  ',29
         DC.W     'RS  ',30
         DC.W     'US  ',31
         DC.W     'DEL ',127
* CHECK A HEX DIGIT, AND REDUCE IT TO ITS NUMERICAL EQUIVALENT
S_HEX_CK
         BSET     #5,D1             MAKE LOWERCASE
         SUBI.B   #'0',D1
         BCS.S    SHEX_BAD          IF BAD CHAR, ERROR
         CMPI.B   #9,D1
         BLS.S    SHEX_OK           IF CHAR OK, JUMP
         SUBI.B   #'a'-'0',D1
         BCS.S    SHEX_BAD          IF BAD CHAR, ERROR
         CMPI.B   #'f'-'a',D1
         BHI.S    SHEX_BAD          IF BAD CHAR, ERROR
         ADDI.B   #$A,D1            MAKE 0-5 BECOME $0A-$0F
SHEX_OK
         CMP.L    D0,D0             SET THE Z FLAG
         RTS
SHEX_BAD
         MOVE     #0,CCR            CLEAR THE Z FLAG
         RTS
* COME HERE FOR A HEX ITEM
S_HEX
         ADDQ.L   #1,A1
         BSR.L    S_ITEM_E          IS THE NEXT CHAR AT THE END
         BEQ.L    S_ERROR
         MOVEQ    #0,D3
*
         BSR.S    S_HEX_CK          CHECK THE CHAR
         BNE.L    S_ERROR
         MOVE.B   D1,D3             STORE ITS VALUE
*
         ADDQ.L   #1,A1
         BSR.L    S_ITEM_E          IS THE 2ND CHAR AT THE END
         BEQ.S    S_STO_D3          IF SO, STORE FIRST DIGIT AS VALUE
*
         LSL.B    #4,D3             MAKE 1ST DIGIT MOST SIGNIFICANT NIBBLE
         BSR.S    S_HEX_CK          CHECK THE CHAR
         BNE.S    S_ERROR
         ADD.B    D3,D1             STORE 2ND AS THE LEAST SIGNIFICANT NIBBLE
         ADDQ.L   #1,A1
         BRA.S    S_STORE
*
* COME HERE IF THE ITEM IS AN ASCII CHARACTER
S_CHAR
         ADDQ.L   #1,A1
         CMPA.L   A1,A2             IS THE NEXT CHAR AT THE END
         BEQ.S    S_ERROR
         MOVE.B   (A1)+,D1          GET THE VALUE
         BRA.S    S_STORE
*
* COME HERE IF THE ITEM IS A DECIMAL NUMBER
S_DEC
         MOVEQ    #0,D3             ACCUMULATOR
         BRA.S    S_DEC_LM
S_DEC_LP
         BSR.L    S_ITEM_E          WAS THAT THE LAST CHAR OF THAT ITEM?
         BEQ.S    S_STO_D3          DROP OUT OF LOOP IF SO
         MULU     #10,D3            DECIMAL SHIFT ACCUMULATOR
         CMPI.W   #$00FF,D3         MUST NOT EXCEED 255
         BHI.S    S_ERROR
S_DEC_LM
         SUBI.B   #'0',D1           MUST BE IN RANGE '0' TO '9'
         BCS.S    S_ERROR
         CMPI.B   #9,D1             '0' TO '9' IS CONVERTED TO $00 TO $09
         BHI.S    S_ERROR
         ADD.W    D1,D3             ADD DIGIT INTO ACCUMULATOR
         ADDQ.L   #1,A1             POINT TO NEXT CHAR
         BRA.S    S_DEC_LP
*
* COME HERE TO STORE BYTE IN D3
S_STO_D3
         MOVE.L   D3,D1
*
* WHEN EVALUTATED THE EXPRESSION, STORE THE VALUE IN THE INSTALL STRING
S_STORE
         ADDQ.W   #1,D2             INCREMENT THE ITEM COUNT
         CMPI.B   #11,D2
         BHI.S    S_LONG            JUMP IF TOO MANY ITEMS
*
         MOVE.W   INS_BUFL(A3),D3   GET THE INSTALL STRING LENGTH
         ADD.W    D2,D3             POINT D3 TO VALUE STORE BYTE
         MOVE.B   D1,INS_BUFF(A3,D3.W)  STORE THE CHARACTER
*
         BSR.L    S_ITEM_E
         BNE.S    S_ERROR
         ADDQ.L   #1,A1             SKIP ANY COMMA/SEMICOLON, DO NOT CHANGE CCR
         CMPA.L   A2,A1             IS THIS THE END OF THE STRING?
         BLS.L    S_LOOP            JUMP IF NOT
*
S_OK
         MOVE.W   INS_BUFL(A3),D3   GET THE INSTALL STRING LENGTH
         MOVE.B   D2,INS_BUFF(A3,D3.W)  STORE THE ITEM COUNT
         ADDQ.W   #1,D2
         ADD.W    D2,INS_BUFL(A3)   UPDATE THE INSTALL STRING LENGTH
*
         MOVEM.L  (SP)+,D2/D3/A1/A2
         MOVEQ    #0,D1
         MOVEQ    #0,D0
         RTS
*
S_ERROR  
         MOVEM.L  (SP)+,D2/D3/A1/A2
         LEA      MS_BADST(PC),A2
         MOVEQ    #-1,D1
         MOVEQ    #0,D0
         RTS
*
S_LONG
         MOVEM.L  (SP)+,D2/D3/A1/A2
         LEA      MS_LONG(PC),A2
         MOVEQ    #-1,D1
         MOVEQ    #0,D0
         RTS
*
MS_BADST DC.W     18,'Bad string item(s)'
MS_LONG  DC.W     15,'Maximum 11 items'
         END
