; ERROR PROCESSING 
 .SKIP
; CONTROLLER ERRORS <HD>
;  0  (1)  NO ERROR
; 20  (2)  CAN'T FIND BLOCK HEADER
; 74  (76)  DOOR OPEN
; 23  (5)  CHECKSUM ERROR IN DATA
; 24  (6)  BYTE DECODING ERROR
; 25  (7)  WRITE-VERIFY ERROR
; 26  (8)  WRITE W/ WRITE PROTECT ON
; 27  (9)  SEEK ERROR (USER SHOULD NOT GET THIS
; 29  (11) DISK I.D. MISMATCH
 .SKIP
; COMMAND ERRORS
; 30  GENERAL SYNTAX
; 31  INVALID COMMAND
; 32  LONG LINE
; 33  INVALID FILNAME
; 34  NO FILE GIVEN
 .SKIP
; 50  RECORD NOT PRESENT
; 51  OVERFLOW IN RECORD
; 52  FILE TOO LARGE
 .SKIP
; 60  FILE OPEN FOR WRITE
; 61  FILE NOT OPEN
; 62  FILE NOT FOUND
; 63  FILE EXISTS
; 64  FILE TYPE MISMATCH
; 65  NO BLOCK
; 66  ILLEGAL TRACK OR SECTOR
; 67  ILLEGAL SYSTEM T OR S
 .SKIP
; 70  NO CHANNELS AVAILABLE
; 71  DIRECTORY ERROR
; 72  DISK FULL
; 74  DOOR OPEN <HD>
; 75  BAD MEDIA <HD>
 .SKIP
;  1  FILES SCRATCHED RESPONSE
 .SKIP2
BADSYN =$30
BADCMD =$31
LONGLN =$32
BADFN =$33
NOFILE =$34
NOREC =$50
RECOVF =$51
BIGFIL =$52
FILOPN =$60
FILNOP =$61
FLNTFD =$62
FLEXST =$63
MISTYP =$64
BADTS =$66
NOCHNL =$70
BAMERR =$71
DSKFUL =$72
CBMV2 =$73
DNRDY = $74 ;DRIVE NOT READY
VERLK = $76 ;VERIFY LOCK
HDBMED = $75 ;BAD MEDIA <HD>
 .PAGE
; ERROR MESSAGE TABLE
;   LEADING ERRROR NUMBERS,
;   TEXT WITH 1ST & LAST CHARS 
;   OR'ED WITH $80,
;   TOKENS FOR KEY WORDS ARE
;   LESS THAN $10 (AND'ED W/ $80)
 .SKIP 2
ERRTAB ;" OK"
 .BYT 0,$A0,'O',$CB
;"READ ERROR"
 .BYT $20,$22,$23,$24,$27
 .BYT $D2,'EAD',$89
;" FILE TOO LARGE"
 .BYTE $52,$83,' TOO LARG',$C5
;" RECORD NOT PRESENT"
 .BYTE $50,$8B,6,' PRESEN',$D4
;"OVERFLOW IN RECORD"
 .BYTE $51,$CF,'VERFLOW '
 .BYTE 'IN',$8B
;" WRITE ERROR"
 .BYT $25,$28,$8A,$89
;" WRITE PROTECT ON"
 .BYT $26,$8A,' PROTECT O',$CE
;" DISK ID MISMATCH"
 .BYT $29,$88,' ID',$85
;"SYNTAX ERROR"
 .BYT $30,$31,$32,$33,$34
 .BYT $D3,'YNTAX',$89
;" WRITE FILE OPEN"
 .BYT $60,$8A,3,$84
;" FILE EXISTS"
 .BYT $63,$83,' EXIST',$D3
;" FILE TYPE MISMATCH"
 .BYT $64,$83,' TYPE',$85
;"ILLEGAL TRACK OR SECTOR" <HD>
.BYTE $66,$67,$C2,'AD T/',$D3
;" FILE NOT OPEN"
 .BYT $61,$83,6,$84
;" FILE NOT FOUND"
 .BYT $62,$83,6,$87
;" FILES SCRATCHED"
 .BYT 1,$83,'S SCRATCHE',$C4
;"NO CHANNEL"
 .BYT $70,$CE,'O CHANNE',$CC
;"BAM ERROR" <HD>
 .BYT $71,$C2,'AM',$89
;" DISK FULL"
 .BYT $72,$88,' FUL',$CC
;"CBM DOS V1.0 8060"
 .BYTE $73,$C3,'BM DOS V3.0 807',$B0
;"BAD MEDIA"
 .BYTE $75,$C2,'AD MEDI',$C1
;"DRIVE NOT READY" <HD>
 .BYTE $74,$8C,$06,' READ',$D9
;"VALIDATE LOCK" <HD>
 .BYTE $76,$D6,'ALIDATE LOC',$CB
 .SKIP
ETOKEN
; ERROR TOKEN KEY WORDS
;   WORDS USED MORE THAN ONCE
;"ERROR"
 .BYT 9,$C5,'RRO',$D2
;"WRITE"
 .BYT $A,$D7,'RIT',$C5
;"FILE"
 .BYT 3,$C6,'IL',$C5
;"OPEN"
 .BYT 4,$CF,'PE',$CE
;"MISMATCH"
 .BYT 5,$CD,'ISMATC',$C8
;"NOT"
 .BYT 6,$CE,'O',$D4
;"FOUND"
 .BYT 7,$C6,'OUN',$C4
;"DISK"
 .BYT 8,$C4,'IS',$CB
;"RECORD"
.BYTE $B,$D2,'ECOR',$C4
;"DRIVE"
 .BYTE $0C,$C4,'RIV',$C5
ENDER
 .PAGE
;RECURSIVE (2) ERROR MESSAGE ROUTINE
MOVERR
 STY ERDST ;SAVE DESTINATION ADDR
 LDX #<ERRTAB ;PT TO ERROR TABLE
 STX ERPTR ;*
 LDX #>ERRTAB ;*
MER0
 STX ERPTR+1 ;*
 LDY #0 ;OFFSET
 PHA ;SAVE TOKEN #
MER1
 PLA ;ERROR #
 CMP (ERPTR),Y ;CHK IF RIGHT TOKEN
 BEQ MER3 ;BR IF IT IS
 INC ERPTR ;BUMP TO NEXT
 BNE MER2 ;BR IF NO CARRY
 INC ERPTR+1 ;BUMP HIGH ALSO
MER2
 PHA ;SAVE TOKEN #
 LDA #<ENDER ;CHK IF AT END OF TABLE
 CMP ERPTR ;*
 BNE MER1 ;BR IF NOT END OF TABLE
 LDA #>ENDER ;CHK HIGH BYTE ALSO
 CMP ERPTR+1 ;*
 BNE MER1 ;BR IF NOT END
 RTS ;EXIT TO CALLER
MER3 ;FOUND THE TOKEN
 INY ;SKIP PAST TOKEN NUMBERS
 LDA (ERPTR),Y ;*
 BPL MER3 ;*
 AND #$7F ;MAKE POSITIVE
MER4
 CMP #$10 ;CHK IF ANOTHER TOKEN
 BCC MER6 ;BR IF IT IS
 STY ERSRC ;SAVE OFFSET TO SOURCE
 LDY ERDST ;GET OFFSET TO DESTINATION
 STA (CB+2),Y ;SAVE CHAR IN DEST
 INY ;BUMP TO NEXT
 STY ERDST ;SAVE
MER5
 LDY ERSRC ;RESTORE OFFSET TO SOURCE
 INY ;BUMP TO NEXT CHAR
 LDA (ERPTR),Y ;GET NEXT CHAR
 BPL MER4 ;BR IF NOT END/TOKEN
 PHA ;SAVE LAST CHAR
 AND #$7F ;TURN OFF FLAG BIT
 CMP #$10 ;CHK IF TOKEN
 BCC MER7 ;BR IF TOKEN
 LDY ERDST ;OFFSET TO DESTINATION
 STA (CB+2),Y ;STORE LAST BYTE
 INY ;LEAVE Y AT LAST + 1
 STY ERDST ;SAVE DESTINATION ADDR
 PLA ;BALANCE STACK
 RTS ;EXIT TO CALLER
MER6
 PHA ;SAVE TOKEN #
MER7
 PHA ;SAVE TOKEN #
 STY ERSRC ;SAVE OFFSET TO SOURCE
 LDY ERDST ;GET OFFSET TO DESTINATION
 LDA #$20 ;ASSUMED LEADING SPACE
 STA (CB+2),Y ;*
 INY ;BUMP TO NEXT
 STY ERDST ;SAVE DESTINATION OFFSET
 PLA ;TOKEN #
 TAX ;SAVE
 LDA ERPTR ;SAVE SOURCE POINTER
 PHA ;*
 LDA ERPTR+1 ;*
 PHA ;*
 LDA ERSRC ;SAVE SOURCE OFFSET
 PHA ;*
 TXA ;A=TOKEN #
 LDX #<ETOKEN ;ADDR OF TOKEN TABLE
 STX ERPTR ;*
 LDX #>ETOKEN ;*
 JSR MER0 ;GO MOVE TOKEN
 PLA ;RESTORE SOURCE OFFSET
 STA ERSRC ;*
 PLA ;RESTORE SOURCE POINTER
 STA ERPTR+1 ;*
 PLA ;*
 STA ERPTR ;*
 PLA ;CHK IF END TOKEN
 BPL MER5 ;BR IF NOT END
 RTS ;EXIT
 .SKIP2
; CONTROLLER ERROR ENTRY
;   .A= ERROR #
;   .X= JOB #
ERROR PHA
 STX JOBNUM
 TXA
 ASL A ;<HD>
 TAX
 LDA HDRS,X ;RECALL TRACK,SECTOR <HD>
 STA TRACK
 LDA HDRS+1,X ;<HD>
 STA SECTOR
 .SKIP
 PLA
 ORA #$20
 TAX
 DEX
 DEX
 TXA
 PHA
 LDA CMDNUM
 CMP #VAL
 BNE ERR2
 LDA #$FF
 STA CMDNUM
 PLA ;<FIX>
 JSR ERRMSG
 JSR INITDR ;INIT FOR VALIDATE
 JMP CMDER3 ;GO COMMON
ERR2
 PLA
CMDER2
 JSR ERRMSG
CMDER3
 JSR CLRCB ;CLEAR CMDBUF
 LDA #0
 STA ERWORD ;CLEAR AFTER ERROR
 LDA #1 ;SET ERROR SWITCH <HD>
 STA BLINK
 JSR FREICH ;FREE INTERNAL CHANNEL
 LDA #0 ;CLEAR POINTERS
 STA BUFTAB+CBPTR
 LDA ORGSA
 AND #$0F
 STA SA
 CMP #$F
 BEQ ERR10
 SEI
 LDA LSNACT
 BNE LSNERR
 LDA TLKACT
 BEQ ERR10
 .SKIP
; TALKER ERROR RECOVERY
;  IF COMMAND CHANNEL, RELEASE DAV
;  IF DATA CHANNEL, FORCE NOT READY
;   AND RELEASE CHANNEL
TLKERR
 JSR FNDRCH
 JMP TLERR ;TILL WE KNOW WHAT TO DO
 .SKIP
; LISTENER ERROR RECOVERY
;  IF COMMAND CHANNEL, RELEASE RFD
;  IF DATA CHANNEL, FORCE NOT READY
;   AND RELEASE CHANNEL
LSNERR
 JSR FNDWCH
TLERR
 JSR TYPFIL
 CMP #RELTYP
 BNE ERR09 ;BR IF NOT RELATIVE
 LDA LSTE ;GET ERROR #
 CMP #$30 ;CHK IF READ ERROR
 BCC ERR09 ;BR IF SO
 CMP #BADTS ;ILLEGAL T&S
 BNE ERR10 ;BR IF NOT
ERR09
 JSR FRECHN
ERR10
 SEI ;DISABLE INTERRUPTS
 LDX #$7F ;RELOAD IRQ LEVEL SP
 TXS ;*
 JSR SEWAT ;SET UP FOR ATTN
 TSX ;SAVE SP
 STX IRQSP ;*
 LDA IRQMOD ;CHK WHICH LEVEL TO RET TO
 BEQ ERR11 ;BR IF NOT IRQ LEVEL
 JMP IRQEX ;EXIT IRQ
ERR11
 JMP REENAB
 .SKIP2
; CONVERT HEX TO BCD
HEXDEC TAX
 LDA #0
 PHP ;SAVE STATE
 PHA ;SAVE THIRD DIGIT ON STACK<HD>
 SEI ;DISABLE
 SED
HEX0 CPX #0
 BEQ HEX5
 CLC
 ADC #1
 BCC HEX1 ;BR IF < 100
 PLA ;GET 3RD DIGIT <HD>
 ADC #0 ;ADD 1 TO 3RD DIGIT
 PHA
 LDA #0 ;RESTORE A
HEX1 ;<HD>
 DEX
 JMP HEX0
HEX5
 TAX ;SAVE LOW 2 DIGITS  <HD>
 PLA ;GET 3RD DIGIT
 PLP ;RESTORE STATUS
 ORA #0 ;SET FLAGS
 BEQ HEX2 ;BR IF NO SIGNIFICANCE
 JSR BCD2 ;STORE 3RD DIGIT
HEX2
 TXA ;<HD>
 .SKIP
; CONVERT BCD TO ASCII DEC
;  RETURN BCD IN .X
;  STORE ASCII IN (TEMP)Y
BCDDEC TAX
 LSR A
 LSR A
 LSR A
 LSR A
 JSR BCD2
 TXA
BCD2
 AND #$F
 ORA #$30
 STA (CB+2)Y
 INY
 RTS
 .SKI
;
;  MOVE OK MSG TO BUFFER
;
OKERR
 JSR ERROFF ;TURN OFF LIGHTS
 LDA #0 ;OK MSG NUMBER
;
; TRANSFER ERROR MESSAGE TO
;  ERROR BUFFER
;
ERRTS0
 LDY #0
 STY TRACK
 STY SECTOR
;
; ERROR NUMBER IS IN REG A
;
ERRMSG
 STA LSTE ;SAVE LAST ERROR NUMBER
 LDY #0
 LDX #<ERRBUF
 STX CB+2
 LDX #>ERRBUF
 STX CB+3
 JSR BCDDEC ;CONVERT ERROR #
 LDA #',
 STA (CB+2),Y
 INY
 LDA ERRBUF
 STA CHNDAT+ERRCHN
 TXA ;ERROR # IN .X
 LDX #0
 JSR MOVERR ;MOVE MESSAGE
 .SKIP
ERMSG2 LDA #',
 STA (CB+2),Y
 INY
 LDA TRACK
 JSR HEXDEC ;CONVERT TRACK #
 LDA #',
 STA (CB+2),Y
 INY
 LDA SECTOR ;CONVERT SECTOR #
 ROL A ;MOVE HEAD TO LOW 2 BITS <HD>
 ROL A
 ROL A
 AND #$03 ;LEAVE ONLY 2 BITS
 JSR BCD2 ;STORE THE HEAD #
 LDA SECTOR ;NOW DO THE SECTOR
 AND #$3F ;TURN OFF THE HEAD # <HD>
 JSR HEXDEC
 DEY
 TYA
 CLC ;FIX
 ADC #<ERRBUF
 STA LSTCHR+ERRCHN ;SET LAST CHAR
 INC CB+2
 LDA #5 ;SET GET SWITCH
 STA REGET+ERRCHN ;*
 RTS
.END
