.TITLE CC0RT .IDENT /X01/ .NLIST BEX .ENABL LC ; ; C COMPILER ; ROOT ; ; VERSION X01 ; ; DAVID G. CONROY 13-JAN-78 ; LAST UPDATED: 20-JUN-79 ; ADDED REGISTER DUMP ON TRAPS. ; PANIC MESSAGES TO TTY ONLY. ; .GLOBL CCABRT .GLOBL CCERR .GLOBL CCTTY .GLOBL TODPTR .GLOBL TODBUF .GLOBL TPS .GLOBL NERRS .GLOBL DFLAG .GLOBL IFLAG .GLOBL VFLAG .GLOBL PFLAG .GLOBL SFLAG .GLOBL TFLAG .GLOBL MFLAG .GLOBL LFLAG .GLOBL EFDB .GLOBL SFDB .GLOBL IFDB .GLOBL AFDB .GLOBL $DENY .MCALL CALL .MCALL CALLR .MCALL RETURN .MCALL FSRSZ$ .MCALL FDBDF$ .MCALL PUT$S .MCALL FDOP$A .MCALL QIO$ .MCALL WTSE$S .MCALL DIR$ .MCALL EXIT$S .MCALL SVTK$S .MCALL GTIM$S FSRSZ$ 4 ; ; GLOBAL DATA. ; EFDB: FDBDF$ ;ERROR STREAM FDOP$A 2 ; SFDB: FDBDF$ ;SOURCE STREAM FDOP$A 3 ; IFDB: FDBDF$ ;INTERMEDIATE STREAM FDOP$A 4 ; AFDB: FDBDF$ ;ASM OUTPUT STREAM FDOP$A 5 ; TODPTR: .WORD TODBUF ;TIME POINTER. TODBUF: .BLKW 8. ;TIME BUFFER. TPS: .BLKW 1 ;TICKS PER SECOND. NERRS: .WORD 0 ;ERROR COUNTER DFLAG: .BYTE 0 ;-D TOGGLE IFLAG: .BYTE 0 ;-I TOGGLE VFLAG: .BYTE 0 ;-V TOGGLE PFLAG: .BYTE 0 ;-P TOGGLE SFLAG: .BYTE 0 ;-S TOGGLE TFLAG: .BYTE 0 ;-T TOGGLE MFLAG: .BYTE 0 ;-M TOGGLE LFLAG: .BYTE 0 ;-L TOGGLE .EVEN ; ; LOCAL DATA. ; SST: .WORD CCSST0 ;SST TRANSFER TABLE .WORD CCSST1 ; .WORD CCSST2 ; .WORD CCSST3 ; .WORD CCSST4 ; .WORD CCSST5 ; .WORD CCSST6 ; .WORD CCSST7 ; MSGBUF: .BLKB 64. ;MESSAGE OUTPUT BUFFER .EVEN LD0: .BYTE 3,0 ;PREPROCESSOR .RAD50 /CC000 / ; LD1: .BYTE 3,0 ;PARSER .RAD50 /CC100 / ; LD2: .BYTE 3,0 ;CODE GENERATOR .RAD50 /CC200 / ; LD3: .BYTE 3,0 ;WRAPUP .RAD50 /CC300 / ; TMP: .BLKW 8. ;FOR GTIM$S TT: QIO$ IO.WVB,1,1,,,,<0,0,40> ; ; MESSAGES. ; MSG01: .ASCIZ 'Abort in phase 0' MSG02: .ASCIZ 'Abort loading phase 0' MSG03: .ASCIZ 'Out of space' MSG04: .ASCIZ 'Trap type 0' MSG05: .ASCIZ 'pc=' MSG06: .ASCIZ 'ps=' MSG07: .ASCIZ 'sp=' MSG08: .ASCIZ 'r0=' .EVEN ;+ ; ** CCMAIN - MAINLINE ; ; THIS IS THE MAINLINE OF THE C COMPILER. IT READS IN EACH OVERLAY OF ; THE COMPILER AND PASSES CONTROL TO IT. ; CARE IS TAKEN TO ASSURE THAT THE LOAD FAILURE AND ABORT MESSAGES GO ; SOMEWHERE THAT THE USER WILL SEE THEM, EVEN IF HE/SHE/IT SEES THEM ; TWICE. ;- .ENABL LSB CCMAIN: SVTK$S #SST,#8. ;GRAB ALL SST VECTORS CALL STIMER ;STORE TIMER. MOV #LD0,R0 ;LOAD PREPROCESSOR CALL $LOAD ; BCS 10$ ;BR ON LOAD FAILURE CALL CC000 ;PREPROCESS CALL STIMER ;STORE TIMER. TST NERRS ;ANY ERRORS BNE 20$ ;IF YES, QUIT INCB MSG01+15. ;FIX PHASE NUMBERS INCB MSG02+20. ; MOV #LD1,R0 ;LOAD PARSER CALL $LOAD ; BCS 10$ ;BR ON LOAD FAILURE CALL CC100 ;PARSE CALL STIMER ;STORE TIMER. TST NERRS ;ANY ERRORS BNE 20$ ;IF YES, QUIT INCB MSG01+15. ;FIX PHASE NUMBERS INCB MSG02+20. ; MOV #LD2,R0 ;LOAD CODE GENERATOR CALL $LOAD ; BCS 10$ ;BR ON LOAD FAILURE CALL CC200 ;CODE CALL STIMER ;STORE TIMER. BR 20$ ;DONE 10$: MOV #MSG02,R0 ;ERROR LOADING A PHASE CALL CCERR ;TO ERROR FILE CALL CCTTY ;TO TTY BR 20$ ; ;+ ; ** CCSSTN - SST INTERCEPTOR ; ; THERE ROUTINES INTERCEPT ALL COMPILER TRAPS. THE NAME OF THE GAME IS ; TO GET YOUR FILES CLOSED. ; ; THE SST CATCH VECTORS POINT INTO THE ARRAY OF INCB INSTRUCTIONS; THE ; ERROR CODE IN THE MESSAGE GETS COUNTED UP BY THEM. ;- CCSST7: INCB MSG04+10. ;ADJUST THE MESSAGE CCSST6: INCB MSG04+10. ; CCSST5: INCB MSG04+10. ; CCSST4: INCB MSG04+10. ; CCSST3: INCB MSG04+10. ; CCSST2: INCB MSG04+10. ; CCSST1: INCB MSG04+10. ; CCSST0: MOV R2,-(SP) ;SAVE R2 MOV R1,-(SP) ; R1 MOV R0,-(SP) ; R0 MOV #MSG04,R0 ;SAY TRAP TYPE N CALL CCTTY ; MOV #MSGBUF,R2 ;POINT AT BUFFER MOV #MSG05,R0 ;PC MOV 6(SP),R1 ; CALL OCTAL ; MOV #MSG06,R0 ;PS MOV 10(SP),R1 ; CALL OCTAL ; MOV #MSG07,R0 ;SP MOV SP,R1 ; SUB #12,R1 ; CALL OCTAL ; CLRB -(R2) ;TO TTY MOV #MSGBUF,R0 ; CALL CCTTY ; MOV #MSGBUF,R2 ;BUFFER POINTER MOV (SP)+,R1 ;R0 CALL OCTAL1 ; MOV (SP)+,R1 ;R1 CALL OCTAL2 ; MOV (SP)+,R1 ;R2 CALL OCTAL2 ; MOV R3,R1 ;R3 CALL OCTAL2 ; MOV R4,R1 ;R4 CALL OCTAL2 ; MOV R5,R1 ;R5 CALL OCTAL2 ; CLRB -(R2) ;TO TTY MOV #MSGBUF,R0 ; CALL CCTTY ; BR CCABR1 ;GO DIE IN PEACE ;+ ; ** $DENY - $ALLOC DENIAL ; ; THIS ROUTINE IS INVOKED BY $ALLOC WHEN THERE IS NO CORE LEFT. THIS ; IS A FATAL ERROR. ; THE COMPILER IS ABORTED VIA THE USUAL ROUTE, WITH THE MESSAGE "OUT ; OF SPACE" GOING TO THE USER. ;- $DENY: MOV #MSG03,R0 ;OUT OF SPACE ;+ ; ** CCABRT - COMPILER ABORT ; ** CCABR1 - COMPILER ABORT (ALTERNATE ENTRY) ; ; THIS ENTRY IS CALLED (VIA A JUMP) TO ABORT THE COMPILER. THE TEXT ; OF THE ABORT MESSAGE IS WRITTEN TO THE TTY, FOLLOWED BY A MESSAGE ; WHICH TELLS YOU WHICH PHASE OF THE COMPILER DIED. ASSORTED COUNTS ; AND FLAGS ARE SET TO INSURE THAT THE WRAPUP OVERLAY DOESN'T MAKE ; ANYTHING GO AWAY. ; ; THE ALTERNATE ENTRY CCABR1 IS BASICLY THE SAME, EXCEPT THAT IF A ; MESSAGE IS REQUIRED YOU MUST PUT IT OUT YOURSELF; THIS IS USED BY ; THE SST TRAP INTERCEPTOR. ; ; INPUTS: ; R0=PTR TO ABORT MESSAGE (CCABRT) ;- CCABRT: CALL CCTTY ;ABORT MESSAGE CCABR1: MOV #MSG01,R0 ;THEN ABORT IN PHASE X CALL CCTTY ; CLR NERRS ;INSURE NOTHING IS DELETED INCB IFLAG ; INCB SFLAG ; 20$: MOVB #'3,MSG02+20. ;SET PHASE 3 IN MESSAGE MOV #LD3,R0 ;LOAD WRAPUP OVERLAY CALL $LOAD ; BCS 30$ ;BR ON LOAD FAILURE CALL CC300 ;WRAPUP BR 40$ ; 30$: MOV #MSG02,R0 ;CANNOT LOAD WRAPUP CALL CCTTY ; 40$: EXIT$S ;SO LONG .DSABL LSB ;+ ; ** CCERR - WRITE OUT ERROR COMMENTS ; ; THIS ROUTINE IS USED BY ALL COMPILER PHASES TO PUT OUT MESSAGES TO ; THE ERROR STREAM. ; ; INPUTS: ; R0=PTR TO MESSAGE STRING ;- CCERR: MOV R0,-(SP) ;SAVE THINGS MOV R1,-(SP) ; MOV R2,-(SP) ; MOV R0,R1 ;POINTER MOV R0,R2 ;COMPUTE LENGTH 10$: TSTB (R2)+ ; BNE 10$ ; DEC R2 ; SUB R1,R2 ; PUT$S #EFDB,R1,R2 ;PUT OUT THE MESSAGE MOV (SP)+,R2 ;RESTORE AND RETURN MOV (SP)+,R1 ; MOV (SP)+,R0 ; RETURN ; ;+ ; ** CCTTY - WRITE ERROR TO TI: ; ; THIS ROUTINE IS USED TO WRITE DISASTER MESSAGES TO THE TI:. THIS ; INCREASES THE CHANCES OF THE MESSAGE GETTING OUT. ; ; INPUTS: ; R0=PTR TO MESSAGE STRING ; ; USES: ; R0 ;- CCTTY: MOV R0,TT+Q.IOPL ;SET ADDRESS 10$: TSTB (R0)+ ;COMPUTE LENGTH OF MESSAGE BNE 10$ ; DEC R0 ; SUB TT+Q.IOPL,R0 ; MOV R0,TT+Q.IOPL+2 ;SET INTO DPB DIR$ #TT ;WRITE TO TI: WTSE$S #1 ; RETURN ;DONE ;+ ; ** STIMER -- STORE TIMER. ; ; GRAB THE CURRENT TIME OF DAY FROM THE SYSTEM, CONVERT IT TO CLOCK ; TICKS AND SAVE THE VALUE IN THE NEXT FREE SLOT IN THE TIME BUFFER ; (IGNORING OVERFLOW). ; ; USES: ; ALL ;- STIMER: GTIM$S #TMP ;GET TIMES. MOV #TMP+G.TIHR,R4 ;POINT AT HOURS. CLR R2 ;GET LONG HOURS. MOV (R4)+,R3 ; MOV #60.,R0 ;ADD IN MINUTES. CALL $DMUL ; ADD (R4)+,R1 ; ADC R0 ; MOV R0,R2 ;ADD IN SECONDS. MOV R1,R3 ; MOV #60.,R0 ; CALL $DMUL ; ADD (R4)+,R1 ; ADC R0 ; MOV R0,R2 ;ADD IN TICKS. MOV R1,R3 ; MOV TMP+G.TICP,R0 ; MOV R0,TPS ;SAVE THEM. CALL $DMUL ; ADD (R4)+,R1 ; ADC R0 ; MOV R0,@TODPTR ;SAVE THIS LONG INTEGER. ADD #2,TODPTR ; MOV R1,@TODPTR ; ADD #2,TODPTR ; RETURN ;FINISHED. ;+ ; ** OCTAL -- BINARY TO OCTAL ASCII ; ** OCTAL1 -- BINARY TO OCTAL ASCII (ALTERNATE ENTRY) ; ** OCTAL2 -- BINARY TO OCTAL ASCII (ALTERNATE ENTRY) ; ; THESE ROUTINES CONVERT A WORD TO OCTAL ASCII. THE MESSAGE POINTED TO ; BY R0 IS COPIED TO THE BUFFER FIRST. THE ALTERNATE ENTRY OCTAL1 SETS ; R0 TO MSG08 BEFORE DROPPING INTO OCTAL. THE ALTERNARE ENTRY OCTAL2 ; ALSO INCREMENTS THE REGISTER NUMBER IN THE MESSAGE. ; ; A BLANK IS PUT IN THE BUFFER AFTER THE CONVERTED DIGITS. ; ; INPUTS: ; R0=MESSAGE POINTER (OCTAL) ; R1=NUMBER ; R2=BUFFER POINTER ; ; OUTPUTS: ; R2=UPDATED ; ; USES: ; R0, R1 ;- OCTAL2: INCB MSG08+1 ;NEXT REGISTER OCTAL1: MOV #MSG08,R0 ;MESSAGE OCTAL: MOVB (R0)+,(R2)+ ;COPY MESSAGE BNE OCTAL ; DEC R2 ; MOVB #'0,(R2) ;TOP DIGIT ASL R1 ; ADCB (R2)+ ; MOV #5,-(SP) ;LOOP COUNTER 10$: MOV #6,R0 ;'0' >> 3 ASL R1 ;GET A DIGIT ROL R0 ; ASL R1 ; ROL R0 ; ASL R1 ; ROL R0 ; MOVB R0,(R2)+ ;TO BUFFER DEC (SP) ;LOOP UNTIL FINISHED BNE 10$ ; TST (SP)+ ;REMOVE COUNTER MOVB #' ,(R2)+ ;APPEND A BLANK RETURN ; .END CCMAIN