PAGE 75,128 TITLE ERROR - Error Handling Routines for RBBS PAGE .XLIST INCLUDE CCBBS.MAC INCLUDE CCBBS.DEF .LIST ;------------------------------------------------------- ;SYSTEM DATA SEGMENT ;------------------------------------------------------- SYSDATA SEGMENT PARA PUBLIC 'DATA' EXTRN ABORT:BYTE,DEBUGF:BYTE,RETCODE:BYTE EXTRN CDTASK:WORD EXTRN DOSUSER:WORD DUMPDS DB 'CCDUMP.FIL',0 ;DUMP DATA SET ;ERROR MESSAGES DW STKSTR-BLANKS-2 BLANKS DB ' ' DW ERRMS01-STKSTR-2 STKSTR DB 'STACK AT ' DW ERRMS02-ERRMS01-2 ERRMS01 DB 'FATAL ERROR # ' DW ERRMS03-ERRMS02-2 ERRMS02 DB ' ENCOUNTERED AT ' DW STRAX-ERRMS03-2 ERRMS03 DB 'BUFFER POOL ELEMENTS' DW STRBX-STRAX-2 STRAX DB 'AX=' DW STRCX-STRBX-2 STRBX DB 'BX=' DW STRDX-STRCX-2 STRCX DB 'CX=' DW STRSI-STRDX-2 STRDX DB 'DX=' DW STRDI-STRSI-2 STRSI DB 'SI=' DW STRCS-STRDI-2 STRDI DB 'DI=' DW STRDS-STRCS-2 STRCS DB 'CS=' DW STRES-STRDS-2 STRDS DB 'DS=' DW STRSS-STRES-2 STRES DB 'ES=' DW ENDSTR-STRSS STRSS DB 'SS=' ENDSTR EQU $ HEXTBL DB '0123456789ABCDEF' ;HEX CONVERSION TABLE CRASH DB 0 ;RECURSIVE ERROR FLAG ERRCDE DW 0 ;ERROR CODE DW 0,128,-1,0 ;BUFFER HEADER ERRBUF DW 0 ;EMERGENCY BUFFER SYSDATA ENDS ;------------------------------------------------------- ;CODE SEGMENT ;------------------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' EXTRN WAITRT:NEAR,WRMSG:NEAR,CONWRT:NEAR EXTRN ILINEB:NEAR,MOVSTR:NEAR,LOGDSK:NEAR EXTRN PADB:NEAR,STRIP:NEAR,APPDSB:NEAR EXTRN MOVSTL:NEAR,FRELBF:NEAR EXTRN RSTALL:NEAR,FNKEY:NEAR,YIELD:NEAR EXTRN MVCSTR:NEAR,MVZSTR:NEAR EXTRN GETBUF:NEAR,FREBUF:NEAR,GETSBF:NEAR EXTRN DOSDAT:NEAR,DOSTIM:NEAR PUBLIC ERROR,PRWORD,PRBYTE,ERRINT ASSUME CS:CSEG,DS:NOTHING,ES:SYSDATA ERRINT PROC NEAR ;INITIALIZATION ROUTINE PUSH AX PUSH SI MOV AX,120 ;EMERGENCY BUFFER SIZE CALL GETSBF ;GET IT MOV ERRBUF,SI ;SAVE FOR EMERGENCY USE POP SI POP AX RET ERRINT ENDP ERROR PROC NEAR ;SAVE ALL REGISTERS IN TCB PUSH BX MOV BX,CDTASK ;TCB ADDRESS MOV WORD PTR [BX+USRCX],CX MOV ERRCDE,AX ;ERROR CODE POP AX ;ORIGINAL BX MOV WORD PTR [BX+USRBX],AX MOV WORD PTR [BX+USRDX],DX MOV WORD PTR [BX+USRSI],SI MOV WORD PTR [BX+USRDI],DI MOV WORD PTR [BX+USRBP],BP POP AX ;RETURN ADDRESS MOV WORD PTR [BX+USRIP],AX POP AX ;ORIGINAL AX MOV WORD PTR [BX+USRAX],AX MOV WORD PTR [BX+USRSP],SP STI ;ALLOW INTERRUPTS CMP CRASH,0 ;RECURSIVE ENTRY? JNZ ERR00 ;YES - BOMB IMMEDIATELY JMP ERR30 ;ANALYZE ERROR ;DISPLAY ERROR NUMBER AND LOCATION ERR00: CMP CRASH,-1 ;SINGLE RECURSION? JZ ERR01 ;YES CALL YIELD ;LET DISPATCHER ABEND SYSTEM JMP ERR00 ;LOOP WITH ERROR ON SCREEN ERR01: DEC CRASH ;DOUBLE RECURSION MOV SI,OFFSET ERRMS01 ;'FATAL ERROR # CALL CWRCON ;WRITE ON LOCAL CONSOLE MOV AX,ERRCDE ;ERROR CODE CALL PRWORD ;DISPLAY MOV SI,OFFSET ERRMS02 ;ENCOUNTERED AT CALL CWRCON MOV AX,WORD PTR [BX+USRIP] ;RETURN ADDRESS SUB AX,3 ;LENGTH OF CALL INSTRUCTION CALL PRWORD ;DISPLAY RETURN ADDRESS CALL CNCRLF ;NEW LINE ;DISPLAY STACK MOV SI,OFFSET STKSTR ;STACK CALL CWRCON ;DISPLAY MOV AX,WORD PTR [BX+USRSP] ;STACK POINTER CALL PRWORD ;DISPLAY CALL CNCRLF ;NEW LINE MOV AX,WORD PTR [BX+USRSP] ;STACK POINTER OR AL,AL ;AT TOP OF STACK? JZ ERR15 ;YES - NO DISPLAY XOR DX,DX MOV DH,AH ;MSB OF STACK INC DH ;TOP OF STACK SUB DX,AX ;# OF BYTES ON STACK SHR DX,1 ;# OF WORDS ON STACK MOV BP,AX ;CURRENT STACK POINTER ERR05: MOV CX,DX ;REMAINING WORDS JCXZ ERR15 ;DONE CMP CX,10 ;MAX PER LINE JLE ERR10 ;NO PROBLEM MOV CX,10 ;ENFORCE LIMIT ERR10: SUB DX,CX ;REMAINING WORDS ERR12: MOV AX,[BP] ;STACK ELEMENT CALL PRWORD ;DISPLAY IT MOV SI,OFFSET BLANKS ;2 SPACES CALL CWRCON ;DISPLAY ADD BP,2 ;NEXT ELEMENT LOOP ERR12 CALL CNCRLF ;NEW LINE JMP ERR05 ;NEXT LINE ERR15: CALL ILINEB ;FORMAT BUFFER MOV DI,OFFSET STRAX ;'AX=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,[BX+USRAX] ;AX CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRBX ;'BX=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,WORD PTR [BX+USRBX] CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRCX ;'CX=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,[BX+USRCX] ;CX CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRDX ;'DX=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,[BX+USRDX] ;DX CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRSI ;'SI=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,[BX+USRSI] ;SI CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRDI ;'DI=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,[BX+USRDI] ;DI CALL MVWORD ;PLACE IN BUFFER CALL WRTCON ;WRITE TO SCREEN CALL CNCRLF ;NEW LINE CALL ILINEB ;FORMAT BUFFER MOV DI,OFFSET STRCS ;'CS=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,CS ;CODE SEGMENT CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRDS ;'DS=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,DS CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRES ;'ES=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,ES CALL MVWORD ;PLACE IN BUFFER ADD WORD PTR [SI-2],2 ;BLANKS MOV DI,OFFSET STRSS ;'SS=' CALL MVCSTR ;MOVE TO BUFFER MOV AX,SS CALL MVWORD ;PLACE IN BUFFER CALL WRTCON ;WRITE TO SCREEN CALL CNCRLF ;NEW LINE MOV ABORT,0 ;LET DISPATCHER WORK MOV BX,DS:TSKCNT+2 ;MUST USE CONSOLE TCB MOV WORD PTR [BX],0 ;MAKE DISPATCHABLE MOV AX,5 ;SELECT DEBUG CALL FNKEY ;ENTER DEBUG ERR20: MOV ABORT,255 ;SET ABORT SWITCH MOV RETCODE,16 ;FATAL ERROR CALL WAITRT ;LET SCHEDULER ABEND TASK JMP ERR20 ;JUST IN CASE ERR30: DEC CRASH ;SHOW ERROR RTN IN CONTROL CMP ERRCDE,10H ;ERROR IN LOG FILE? JZ ERR31 ;YES - CAN NOT USE LOG CMP ERRCDE,11H ;SYSTEM MESSAGES ERROR? JZ ERR31 ;YES - USE CONSOLE RTNS CMP DOSUSER,0 ;DOS LOCKED? JZ ERR32 ;NO PROBLEM ERR31: JMP ERR01 ;DISPLAY ON CONSOLE ERR32: CMP ERRCDE,201H ;OUT OF MEMORY? JNZ ERR33 ;NO PROBLEM MOV AX,ERRBUF ;USE EMERGENCY BUFFER OR AX,AX ;EXIST? JZ ERR20 ;NO - IMMEDIATE SHUTDOWN MOV [BX+USRLB],AX ;AS LINE BUFFER ERR33: CALL ILINEB ;FORMAT BUFFER MOV DI,OFFSET ERRMS01 ;'FATAL ERROR #' CALL MVCSTR MOV AX,ERRCDE ;ERROR CODE CALL MVWORD ;MOVE TO BUFFER MOV DI,OFFSET ERRMS02 ;'ENCOUNTERED AT' CALL MVCSTR MOV AX,WORD PTR [BX+USRIP] ;INSTRUCTION ADDRESS SUB AX,3 ;LENGTH OF CALL INSTRUCTION CALL MVWORD ;MOVE TO BUFFER CALL LOGDSK ;LOG ERROR MESSAGE ;WRITE SELECTED INFORMATION TO DUMP DATA SET CALL ILINEB ;FORMAT BUFFER MOV AX,0 ;DUMP HEADER ID CALL STWORD ;STORE IN BUFFER MOV AX,14 ;DATA LENGTH CALL STWORD ;STORE IN BUFFER MOV AX,0 ;DUMP PROGRAM VERSION CALL STWORD ;STORE IN BUFFER MOV AX,ERRCDE ;ERROR CODE CALL STWORD ;STORE IN BUFFER MOV AX,CDTASK ;ACTIVE TASK CALL STWORD ;STORE IN BUFFER CALL DOSDAT ;CURRENT DATE MOV AX,CX ;YEAR CALL STWORD ;STORE IN BUFFER MOV AX,DX ;MONTH AND DAY CALL STWORD ;STORE IN BUFFER CALL DOSTIM ;CURRENT TIME OF DAY MOV AX,CX ;HOUR AND MINUTE CALL STWORD ;STORE IN BUFFER MOV AX,DX ;SECONDS CALL STWORD ;STORE IN BUFFER CALL ERRLOG ;LOG TO DISK CALL LSTBUF ;DISPLAY BUFFER POOL CALL ILINEB ;FORMAT BUFFER MOV DX,900H ;TOP OF STACK SHR DX,1 ;# OF WORDS ON STACK MOV BP,0 ;BOTTOM OF STACK ERR34: MOV CX,DX ;REMAINING WORDS JCXZ ERR40 ;DONE CMP CX,32 ;MAX PER LINE JLE ERR36 ;NO PROBLEM MOV CX,32 ;ENFORCE LIMIT ERR36: SUB DX,CX ;REMAINING WORDS MOV AX,2 ;STACK ELEMENT ID CALL STWORD ;PUT IN BUFFER MOV AX,BP ;STACK ADDRESS CALL STWORD ;PUT IN BUFFER MOV AX,CX ;# OF ELEMENTS FOR THIS LINE SHL AX,1 ;DATA LENGTH CALL STWORD ;PUT IN BUFFER ERR39: MOV AX,[BP] ;STACK ELEMENT CALL STWORD ;PLACE IN BUFFER ADD BP,2 ;NEXT ELEMENT LOOP ERR39 CALL ERRLOG ;LOG TO DISK CALL ILINEB ;FORMAT BUFFER JMP ERR34 ;NEXT LINE ERR40: CMP ERRCDE,202H ;FREE INVALID STRING? JZ ERR60 ;YES ERR50: JMP ERR20 ;SET ABORT FLAG ERR60: MOV AX,WORD PTR [BX+USRIP] ;RETURN ADDRESS PUSH AX ;PUT ON STACK CALL RSTALL ;RESTORE REGISTERS MOV CRASH,0 ;RESET RECURSION FLAG RET ;LET CALLER DECIDE ;WRITE STRING IN DS:SI TO LOCAL CONSOLE WRTCON: PUSH SI PUSH CX MOV CX,WORD PTR [SI-2] ;LENGTH JCXZ WRTC21 ;JUST IN CASE WRTC10: LODSB CALL CONWRT ;WRITE ONE CHAR TO CONSOLE CMP AL,13 ;CARRIAGE RETURN? JNZ WRTC20 ;NO MOV AL,10 ;LINE FEED CALL CONWRT ;WRITE LINE FEED WRTC20: LOOP WRTC10 ;KEEP IT MOVING WRTC21: POP CX POP SI RET ;WRITE STRING IN ES:SI TO LOCAL CONSOLE CWRCON: PUSH SI PUSH CX MOV CX,WORD PTR ES:[SI-2] ;LENGTH JCXZ CWRC21 ;JUST IN CASE CWRC10: MOV AL,ES:[SI] INC SI CALL CONWRT ;WRITE ONE CHAR TO CONSOLE CMP AL,13 ;CARRIAGE RETURN? JNZ CWRC20 ;NO MOV AL,10 ;LINE FEED CALL CONWRT ;WRITE LINE FEED CWRC20: LOOP CWRC10 ;KEEP IT MOVING CWRC21: POP CX POP SI RET ;WRITE CRLF TO LOCAL CONSOLE CNCRLF: PUSH AX MOV AL,13 ;C/R CALL CONWRT MOV AL,10 ;L/F CALL CONWRT POP AX RET ;PRINT HEX CHARS ON LOCAL CONSOLE PRWORD: PUSH AX XCHG AL,AH CALL PRBYTE ;PRINT ONE BYTE POP AX PRBYTE: PUSH AX PUSH CX MOV CL,4 ROR AL,CL ;REVERSE NIBBLES CALL PRHEX ;PRINT ONE DIGIT POP CX POP AX PRHEX: AND AL,0FH ;ISOLATE LOW NIBBLE PUSH BX MOV BX,OFFSET HEXTBL XLAT ES:HEXTBL ;TRANSLATE TABLE POP BX CALL CONWRT ;WRITE TO CONSOLE RET ;APPEND HEX CHARS TO BUFFER MVWORD: PUSH DI PUSH AX MOV AX,WORD PTR [SI-2] ;CURRENT TARGET LENGTH MOV DI,AX ;SAVE TARGET LENGTH ADD AX,4 ;HEX DIGITS CMP AX,WORD PTR [SI-6] ;MAX LENGTH JBE MVWO10 ;NO PROBLEM PUSH CX MOV CX,AX ;NEW TOTAL LENGTH CMP SI,WORD PTR [BX+USRLB] ;IS THIS LINE BUFFER? PUSHF ;REMEMBER ANSWER CALL PADB ;EXTEND BUFFER CALL STRIP ;ADJUST LENGTH POPF ;WAS IT LINE BUFFER? POP CX JNZ MVWO10 ;NO MOV WORD PTR [BX+USRLB],SI ;UPDATE POINTER MVWO10: MOV WORD PTR [SI-2],AX ;NEW LENGTH POP AX ;HEX VALUE TO DISPLAY ADD DI,SI ;POINT PAST END OF STRING CALL MVWO30 ;HEX TO ASCII POP DI RET MVWO30: PUSH AX XCHG AL,AH CALL MVWO40 ;HANDLE ONE BYTE POP AX MVWO40: PUSH AX PUSH CX MOV CL,4 ROR AL,CL ;REVERSE NIBBLES CALL MVWO50 ;HANDLE ONE DIGIT POP CX POP AX MVWO50: AND AL,0FH ;ISOLATE LOW NIBBLE PUSH BX MOV BX,OFFSET HEXTBL XLAT ES:HEXTBL POP BX MOV [DI],AL ;PLACE DIGIT IN BUFFER INC DI RET ;APPEND HEX VALUES TO BUFFER STWORD: PUSH DI PUSH AX MOV AX,WORD PTR [SI-2] ;CURRENT TARGET LENGTH MOV DI,AX ;SAVE TARGET LENGTH ADD AX,2 ;WORD SIZE CMP AX,WORD PTR [SI-6] ;MAX LENGTH JBE STWO10 ;NO PROBLEM PUSH CX MOV CX,AX ;NEW TOTAL LENGTH CMP SI,WORD PTR [BX+USRLB] ;IS THIS LINE BUFFER? PUSHF ;REMEMBER ANSWER CALL PADB ;EXTEND BUFFER CALL STRIP ;ADJUST LENGTH POPF ;WAS IT LINE BUFFER? POP CX JNZ STWO10 ;NO MOV WORD PTR [BX+USRLB],SI ;UPDATE POINTER STWO10: MOV WORD PTR [SI-2],AX ;NEW LENGTH POP AX ;HEX VALUE TO DISPLAY ADD DI,SI ;POINT PAST END OF STRING MOV WORD PTR [DI],AX ;PUT IN BUFFER POP DI RET ;DISPLAY BUFFER POOL ELEMENTS LSTBUF: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,2 ;ALLOCATE LOCAL STORAGE MOV DI,OFFSET BFRHD ;START OF BUFFER POOL LSTB10: MOV [BP-2],DI ;START OF STRING HEADER CALL ILINEB ;FORMAT BUFFER MOV AX,1 ;BUFFER POOL ELEMENT CALL STWORD ;PUT IN BUFFER MOV AX,DI ;ADDRESS IN BUFFER CALL STWORD ;PUT IN BUFFER MOV CX,[DI+QELEN] ;BUFFER ELEMENT LENGTH CMP CX,122 ;TOO LONG? JBE LSTB20 ;NO PROBLEM MOV CX,122 ;ALL THAT WILL FIT LSTB20: MOV AX,CX ;DATA LENGTH CALL STWORD ;PUT IN BUFFER CALL MOVSTL ;MOVE TO BUFFER LSTB30: CALL ERRLOG ;WRITE TO LOG MOV DI,[BP-2] ;START OF ELEMENT CMP WORD PTR [DI+QELEN],0 ;VALID LENGTH? JZ LSTB40 ;NO - QUIT ADD DI,WORD PTR [DI+QELEN] ;NEXT ELEMENT JC LSTB40 ;SEGMENT WRAP CMP DI,DS:BFRTL ;PAST END OF AREA? JNB LSTB40 ;YES JMP LSTB10 ;KEEP TRUCKING LSTB40: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME CALL FRELBF ;FREE LINE BUFFER CLC RET ;WRITE TO DUMP DATA SET ERRLOG: FRAME 1 PUSH SI ;PASS STRING ADDRESS MOV AX,80 ;BUFFER LENGTH CALL GETBUF ;WORK BUFFER MOV [BP-2],SI ;WORK BUFFER ADDRESS MOV DI,OFFSET DUMPDS ;FILE NAME STRING CALL MVZSTR ;MOVE TO BUFFER PUSH SI ;PASS FILE NAME STRING CALL APPDSB ;APPEND TO FILE MOV SI,[BP-2] ;WORK BUFFER ADDRESS CALL FREBUF ;FREE WORK BUFFER EXITF ERROR ENDP CSEG ENDS END