.TITLE BILLWRK -- BILLER WORKHORSE .IDENT /V2.0/ ;DOES THE ACTUAL BILLING FOR BILLER ; ;THE BASIC OUTLINE IS THE FOLLOWING: ; ; 1) VERIFY THAT BILLING DATES ARE LEGIT --EXIT IF ERROR-- ; 2) COPY LOG.SYS TO LOG.TMP, COUNTING/MARKING BOOTS AND SHUTUPS ; --IF SL, SPOOL LOG.SYS-- ; 3) OPEN BILL.LST, WRITE HEADER, CLEAR TOTAL ACCUMULATORS ; 4) FIND LOWEST ALPHABETICAL PROJECT NUMBER IN LOG,HEL,XXX ENTRIES ; --IF NONE, GO TO 11-- ; 5) CLEAR PROJECT ACCUMULATORS, WRITE PROJECT HEADER ; 6) FIND LOWEST LAST NAME UNDER CURRENT PROJECT # ; --IF NONE, GO TO 10-- ; 7) CLEAR USER ACCUMULATORS ; 8) FIND EVERY PROJECT, NAME, DATE MATCH AND ACCUMULATE TOTAL TIMES ; --MARK THESE ENTRIES BY SETTING 1ST CHAR TO B-- ; 9) WRITE USER ENTRY IN BILL.LST ; --GO TO 6-- ;10) WRITE PROJECT TOTAL IN BILL.LST ; --GO TO 4-- ;11) WRITE TOTAL ENTRY, BOOTS AND SHUTUPS IN BILL.LST AND CLOSE ; --IF SB, SPOOL BILL.LST-- ;12) IF -M, RESET ALL MARKERS ;13) SLAVE TI:, OPEN LOG.SYS, WRITE UNMARKED ENTRIES AND CLOSE, UNSLAVE TI: ; --IF -W, CREATE NEW LOG.SYS....ELSE OVERWRITE ORIGINAL-- ;14) IF SR, SPOOL LOG.SYS ;15) RETURN TO TIO FOR OPTION PROMPT ; MODIFIED: ; 9-APR-80 BILL LB0:[0,0]LOG.SYS, USING SY0: AND LB0: FOR LOG.TMP ; 9-APR-80 DON'T COPY MULTIPLE TOP-LINES IN LOG.SYS .MCALL PUSH,POP .MCALL FDBDF$,FDBF$A,FDOP$A,FDAT$R,FSRSZ$,OPEN$W,OPEN$U,OPNT$D .MCALL CLOSE$,MRKT$S,WTSE$S,OPNS$U .PSECT WRKDAT,RW,D,REL,CON CR=15 FF=14 LF=12 SPC=40 .NLIST BEX LL.TT=4 LL.UIC=8. LL.LNM=16. LL.PRJ=31. LL.DAT=42. LL.ON=51. LL.TTL=57. PRJLEN=LL.DAT-LL.PRJ-1 NAMLEN=LL.PRJ-LL.LNM-1 PROJ: .BLKB PRJLEN ;BEST ALPHANUMERIC PROJECT STRING PROJW: .BLKB PRJLEN ;1ST OCCURENCE OF BEST USER PROJECT STRING PRJT: .BLKB PRJLEN ;ALPHANUMERIC TEST PROJECT STRING NAME: .BLKB NAMLEN ;BEST USER NAME STRING TERR: .ASCII /LOG.TMP ERROR #/ TERRN: .ASCIZ / / SERR: .ASCII /LOG.SYS ERROR #/ SERRN: .ASCIZ / / BERR: .ASCII /BILL.LST ERROR #/ BERRN: .ASCIZ / / ERRSP: .ASCII /SPOOL ERROR #/ ERRSPN: .ASCIZ / / .EVEN .LIST BEX ACCTOT: .WORD 0,0,0,0 ;TOTAL HRS, TOTAL MINS, ## OF XXX, ## OF HEL ACCPRJ: .WORD 0,0,0,0 ACCNAM: .WORD 0,0,0,0 HRACC: .WORD 0 MINACC: .WORD 0 BOOTS: .WORD 0 SHUTS: .WORD 0 NRECS: .WORD 0 ;NUMBER OF RECORDS IN LOG.TMP (OR LOG.SYS) SREC: .WORD 0 ;SAVED RECORD NUMBER (TOP OF CURRENT PROJECT) NMREC: .WORD 0 ;SAVED REC # (TOP OF CURRENT NAME) OPENTM: .WORD 0 ;CTR FOR LOG.SYS FILE OPEN LTREC: .WORD 0 ;RECORD NUMBER FOR RANDOM ACCESS BLCNT: .WORD 60. ;NUMBER OF LF'S TO GO TO BILL.LST BEFORE FF SYSLUN=3 SYSEFN=3 TMPLUN=4 TMPEFN=4 BILLUN=5 BILEFN=5 WAITEFN=6 LOGTMP: .WORD 4,SY0,0,0,7,LTMP BILLST: .WORD 4,SY0,0,0,8.,BLST SYSFDB: FDBDF$ FDBF$A SYSEFN FDOP$A SYSLUN,LOGSYS TMPFDB: FDBDF$ FDBF$A TMPEFN FDOP$A TMPLUN,LOGTMP BILFDB: FDBDF$ FDBF$A BILEFN FDOP$A BILLUN,BILLST FSRSZ$ 3,,WRKDAT .PSECT WRKINS,RO,I,REL,CON .NLIST BEX LOGSYS: .WORD 4,LB0,5,UIC00,7,LSYS SY0: .ASCII /SY0:/ LB0: .ASCII /LB0:/ UIC00: .ASCII /[0,0]/ LSYS: .ASCII /LOG.SYS/ LTMP: .ASCII /LOG.TMP/ BLST: .ASCII /BILL.LST/ BADDAT: .ASCIZ /?IMPROPER DATES?/ WAITLS: .ASCIZ /--WAITING FOR LOG.SYS--/ BADENT: .ASCIZ /**WARNING -- IMPROPER LOG.SYS ENTRY DELETED**/ BLGO: .ASCIZ /...BILLING.../ .LIST BEX .EVEN BILL:: MOV #DATLO,R0 ;GET DATE STRING CALL CNVDAT ;TURN TO A NUMBER MOV R0,DATLOW MOV #DATHI,R0 ;GET THE END DATE CALL CNVDAT MOV R0,DATHIG CMP R0,DATLOW ;LEGAL DATES? BHIS 1$ ; YES...START THE BILLING MOV #BADDAT,R0 ; NO...PRINT MSG AND QUIT JMP WRITE ;RETURN FROM WRITE GOES BACK TO BILLER ;2) 1$: MOV #BLGO,R0 ;PRINT ...BILLING... CALL WRITE CALL OPENLS ;OPEN LOG.SYS BCS ERRORS CALL OPENLT ;OPEN LOG.TMP BCS 37$ ;ERRORT MOV #SYSFDB,R3 ;SOURCE FOR COPFIL MOV #TMPFDB,R4 ;DEST CLR LTREC ;FLAG TO MARK BOOTS AND SHUTUPS CALL COPFIL ;COPY LOG.SYS TO LOG.TMP, COUNT BOOTS/SHUTUPS BCS 64$ ;ERR--FIND OUT WHICH FILE CLOSE$ #SYSFDB ;CLOSE LOG.SYS TSTB SWSL ;SPOOL LOG.SYS? BMI 10$ ; NOPE MOV #LOGSYS,R1 CALL SPOOL BCS SPERR ;3) 10$: CALL OPENBL ;OPEN BILL.LST AND WRITE HEADER BCS ERRORB MOV #ACCTOT,R0 ;CLEAR TOTAL ACC CLR (R0)+ CLR (R0)+ CLR (R0)+ CLR (R0)+ ;4) 30$: CALL LOWPRJ ;FIND LOWEST PROJECT BEQ 50$ ; NONE 37$: BCS ERRORT ;5) MOV #ACCPRJ,R5 ;CLEAR PROJ ACC CLR (R5)+ CLR (R5)+ CLR (R5)+ CLR (R5)+ CALL BPRJH ;WRITE PROJECT HEADER BCS ERRORB ;6) 35$: CALL LOWNAM ;FIND LOWEST NAME W/ THIS PROJECT BEQ 40$ ; NONE BCS ERRORT ;7) & 8) CALL ADDALL ;ADD ALL APPROPRIATE TIMES, MARK ENTRIES BCS ERRORT ;9) CALL BNAM ;WRITE NAME ENTRY BCS ERRORB BR 35$ ;GO BACK FOR NEXT NAME ;10) 40$: CALL BPRJ ;WRITE PROJECT TOTAL BCS ERRORB BR 30$ ;GO BACK FOR NEXT PROJECT ;11) 50$: CALL BTOT ;WRITE FINAL STUFF TO BILL.LST AND CLOSE BCS ERRORB TSTB SWSB ;SPOOL BILL.LST? BMI 55$ ; NOPE MOV #BILLST,R1 CALL SPOOL BCS SPERR ;12) 55$: TSTB SWM ;RESET MARKERS? (MAKES BILLING INVISIBLE) BPL 60$ ; NO-- THIS IS THE 'M' SWITCH CALL MKRES ; YES--THIS IS '-M'....ALL 'B' MARKS REVERT BCS ERRORT ;13) 60$: CALL SLAVE ;SLAVE TI: TO SECURE LOG.SYS WRITEBACK TSTB SWW ;WRITEBACK TO LOG.SYS? BPL 62$ ; YES CALL OPNWLS ; NO...OPEN A NEW LOG.SYS BR 63$ ;** THIS COULD BE USEFUL WHEN LOG.SYS CRAPS OUT 62$: CALL OPENLS ;OPEN LOG.SYS AGAIN 63$: BCS ERRORS MOV #TMPFDB,R3 ;SRC FOR COPFIL MOV #SYSFDB,R4 ;DEST MOV #1,LTREC ;FLAG NO MARKING BOOTS AND SHUTUPS CALL COPFIL ;LOG.SYS <- LOG.TMP (EXCEPT MARKED ENTRIES) 64$: BCS ERR ; IF ERROR, FIND WHICH FILE CALL CLSYS ;CLOSE AND TRUNCATE LOG.SYS BCS ERRORS CLOSE$ #TMPFDB ;CLOSE LOG.TMP (IT IS MARKED FOR DELETE) BCS ERRORT CALL NOSLAVE ;UNSLAVE TI: ;14) TSTB SWSR ;SPOOL RESULTANT LOG.SYS? BMI 65$ ; NOPE MOV #LOGSYS,R1 CALL SPOOL BCS SPERR ;15) 65$: RETURN ;BACK TO BILLER (THEN TO TIO) ;ERROR ROUTINES ERRORS: MOV #SYSFDB,R1 ;ERROR ON LOG.SYS MOV #SERRN,R0 ;SET UP ADDRESS FOR I/O CODE INSERT MOV #SERR,R5 ;SET ADDRESS OF WHOLE ERROR STRING BR ERROR ERRORT: MOV #TMPFDB,R1 ;ERROR ON LOG.TMP MOV #TERRN,R0 MOV #TERR,R5 BR ERROR ERRORB: MOV #BILFDB,R1 ;ERROR ON BILL.LST MOV #BERRN,R0 MOV #BERR,R5 BR ERROR SPERR: MOV #ERRSP,R5 ;ERROR IN SPOOLING A FILE MOV #ERRSPN,R0 BR ERRORA ;ERROR CODE IS ALREADY IN R1 ERR: CMP R0,#SYSFDB ;ERROR IN COPFIL BEQ ERRORS ; IT WAS ON LOG.SYS BR ERRORT ;OR ELSE IT WAS IN LOG.TMP ERROR: TSTB F.ERR+1(R1) ;ERROR IN FDB? BMI 3$ ;NO MOVB F.ERR(R1),R1 ;YES...PUT CODE IN R1 BR ERRORA 3$: MOV $DSW,R1 ;GET ERROR CODE FROM DIRECTIVE STATUS WORD ERRORA: MOV #15412,R2 ;SIGNED, 3-DIGIT, SPACE FILLED, BASE 10 # CALL CBTA ;TURN IT TO ASCII MOV R5,R0 ;GET ADDRESS OF ERROR STRING CALL WRITE ;WRITE ERROR MSG CALL NOSLAVE ;MAKE SURE TI: ISN'T SLAVED CLOSE$ #SYSFDB CLOSE$ #TMPFDB CLOSE$ #BILFDB ;CLOSE FILES (EVEN IF NOT OPEN) RETURN ;BACK TO BILLER, THEN TO TIO ;SUBROUTINES FOR BILLWRK ; ;FIRST, THE LOG FILE MANIPULATORS (OPENLS,OPENLT,PUTTMP,GETTMP,RESET,ETC.) ;OPENLS OPENS LOG.SYS (3 MINUTES WAITING TIME IF FILE ERROR) ;ONCE OPEN, PUTS THE # OF RECORDS IN IT IN NRECS ;USES R0,R4,R5 OPENLS: CLR OPENTM ;CLEAR WAIT TIMER 1$: OPNS$U #SYSFDB,,,#0 ;OPEN FOR UPDATE, SEQUENTIAL, PUT$ TRUNCATION BCS 3$ ; CAN'T OPEN IT MOV F.EFBK+2(R0),R5 ;GET LAST BLOCK # MOV F.FFBY(R0),R4 ;LAST BYTE # DEC R5 ASH #3,R5 ASH #-6,R4 ADD R4,R5 MOV R5,NRECS ;NUMBER OF RECORDS INTO NRECS (FOR COPFIL) CLC RETURN 3$: TST OPENTM ;1ST TIME? BNE 5$ ;NOPE MOV #WAITLS,R0 ; YES...LET THE USER KNOW WHAT'S UP CALL WRITE 5$: INC OPENTM CMP OPENTM,#180. ;3 MINUTES? BGT 2$ ;YES...GIVE UP CALL WAIT1 ;WAIT A SECOND BR 1$ ;AND TRY AGAIN 2$: SEC RETURN ;ERROR ;CLSYS CLOSES (TRUNCATES) LOG.SYS CLSYS: MOV #SYSFDB,R0 JMP .TRNCL ;FDATLG SETS THE FILE CREATION SPECS IN A GIVEN FDB FOR A LOG-LIKE FILE ;...IT IS USED TO CREATE LOG.TMP AND A NEW LOG.SYS ; INPUTS: R0 - FDB TO INITIALIZE ;USES R5 FDATLG: MOV NRECS,R5 ;GET # OF RECORDS ASH #-3,R5 ;8 PER BLOCK INC R5 ;# OF BLOCKS TO ALLOCATE NEG R5 ;NON-CONTIGUOUS FDAT$R R0,#R.FIX,#FD.BLK!FD.CR,#64.,R5,#-1 ;SET FILE OPEN CHARACTERISTICS RETURN ;OPNWLS CREATES A NEW LOG.SYS FILE ON DK3 (DOESN'T USE GETDEV) OPNWLS: MOV #SYSFDB,R0 ;SET FDB ADDRESS CALL FDATLG ;INITIALIZE FILE OPEN SPECS OPEN$W R0,,,#0 ;CREATE, SEQUENTIAL RETURN ;OPENLT OPENS LOG.TMP WITH SIZE OF LOG.SYS ; TRIES TO OPEN ON DK1:...IF ERROR, TRIES DK3: THEN DK2: ;USES R0,R4,R5 OPENLT: MOV #TMPFDB,R0 CALL FDATLG ;SET OPEN SPECS FOR LOG FILE CLR R5 5$: CALL GETDEV ;R4<-DEVICE STRING BCS 7$ ; NO MORE DEVICES TO TRY MOV R4,LOGTMP+2 ;SET DEVICE STRING ADDRESS OPNT$D R0,,,#FD.RAN ;OPEN TMP, MARK FOR DELETE, RANDOM ACCESS BCS 5$ 7$: RETURN ;RESET SETS THE LOG.TMP RECORD NUMBER FOR GETS AND PUTS TO 1 ;(ACTUALLY TO ZERO, SINCE GETTMP INCREMENTS BEFORE GET$) RESET: CLR LTREC ;CLR SOFTWARE STORED RECORD NUMBER RETURN ;SAVREC SAVES THE LOG.TMP RECORD NUMBER FOR FUTURE RESTORE ; (USED TO SAVE TOP OF CURRENT PROJECT) SAVREC: MOV LTREC,SREC DEC SREC ;GETTMP INCREMENTS IT RETURN ;RESREC RESTORES THE LOG.TMP RECORD NUMBER FROM A PREVIOUS SAVREC RESREC: MOV SREC,LTREC RETURN ;NEXT GETTMP WILL GET THE SAVED RECORD ;SAVNR AND RESNR ARE JUST LIKE SAVREC AND RESREC EXCEPT ;THEY ARE USED TO SAVE TOP OF CURRENT NAME SAVNR: MOV LTREC,NMREC DEC NMREC RETURN RESNR: MOV NMREC,LTREC RETURN ;GETTMP GETS A RECORD FROM LOG.TMP INTO BUF ;RETURNS Z-SET IF EOF (CHECK THIS FIRST) AND C-SET IF ERROR ;GETTMP GETS THE NEXT RECORD (AFTER THE ONE JUST GOT) ;USES R0,R1,R2,R3 GETTMP: INC LTREC ;INC SOFTWARE RECORD # MOV LTREC,R3 MOV #TMPFDB,R0 MOV #BUF,R1 MOV #64.,R2 CALL GETR ;GET A RANDOM RECORD BCS 3$ CLZ RETURN 3$: CMPB F.ERR(R0),#IE.EOF ;END-OF-FILE? BEQ 5$ SEC 5$: RETURN ;PUTTMP WRITES A RECORD TO LOG.TMP FROM BUF (ALWAYS THE SAME RECORD JUST READ) ;RETURNS C-SET IF ERROR ;USES R0,R1,R2,R3 PUTTMP: MOV LTREC,R3 ;GET RECORD # MOV #TMPFDB,R0 MOV #BUF,R1 MOV #64.,R2 JMP PUTR ;PUT A RANDOM RECORD ;NOW THE SUBROUTINES TO DO THE BILL.LST MANIPULATION .PSECT WRKDAT .NLIST BEX BDKN: .ASCIZ /BILL.LST OPENED ON / BHEAD: .ASCII \*** BILLING LIST FOR \ BDATL: .ASCII \##/##/## THRU \ BDATH: .ASCII \##/##/## RATE = $\ BBR: .ASCIZ \##.## PER HOUR\ BPH: .ASCIZ /PROJECT: / BPHS: .ASCIZ /XXXXXXXXXX/ BNM: .ASCII / / BNMS: .ASCIZ /NNNNNNNNNNNNNN/ BLINE: .ASCII / HEL:/ BHEL: .ASCII /### XXX:/ BXXX: .ASCII /### TOTAL TIME: / BTM: .ASCII /##.## CHARGE: $/ BCHG: .ASCIZ /####.##/ CRLFS: .ASCIZ BPF: .ASCIZ / TOTAL: / BPF1: .ASCIZ / <-> / BTT: .ASCIZ /*** GRAND TOTAL / BBS: .ASCII / BOOTS:/ BB: .ASCII /### SHUTUPS:/ BS: .ASCIZ /###/ BLNK: .ASCII / / ;BUFFER AND FLAGS FOR BILL.LST OUTPUT: BCRFLG: .BYTE 0 ; -1 IF READY TO PRINT...0 IF NO PRINTING CHARS IN BBUF BBUF: .BLKB 120. ;GOOD AND LONG, SINCE OVERFLOW CHECKING ISN'T DONE .EVEN BCRCNT: .WORD 0 ; # OF CHARS IN BUFFER BBPTR: .WORD BBUF ;BUFFER PTR .LIST BEX .PSECT WRKINS ;OPENBL OPENS BILL.LST ON A DISK WITH ROOM FOR IT (SEE OPENLT DOCUMENTATION) ; THEN WRITES HEADER INFO (BILL DATES AND RATE) OPENBL: MOV NRECS,R5 ;GET # OF RECORDS IN LOG FILE ASH #-6,R5 ;DIV BY 8 FOR # OF BLOCKS INC R5 ;THEN DIV BY 8 TO GUESS AT BILL.LST SIZE NEG R5 ;NON-CONTIGOUS MOV #BILFDB,R0 FDAT$R R0,#R.VAR,#0,,R5,#-2 CLR R5 5$: CALL GETDEV ;R4<-DEVICE STRING PTR (DK1,3,2) BCC 7$ ;NO SPACE ANYWHERE RETURN 7$: MOV R4,BILLST+2 ;SET IN DATASET DESCRIPTOR OPEN$W R0,,,#0 BCS 5$ ;ERROR...TRY ANOTHER DISK 10$: CMP R4,#SY0 ;OPENED ON USER DEFAULT DISK? BEQ 12$ ; YES...DON'T PRINT MSG MOV #BDKN,R0 CALL WRITE ;PRINT WHICH DISK BILL.LST GOT OPENED ON MOV R4,R0 MOV #4,R1 CALL WRIT1 ;WRITE DISK NUMBER FROM DATASET DESCRIPTOR MOV #CRLFS,R0 CALL WRITE 12$: MOV #BDATL,R1 ;NOW SET UP THE HEADER MOV #DATLO,R0 ;MOVE THE DATES IN CALL MOV8 MOV #BDATH,R1 MOV #DATHI,R0 CALL MOV8 MOV #BBR,R0 ;SET PTR TO RATE AREA CALL MOVRAT ;CONVERT THE BILLING RATE MOV #BHEAD,R1 ;SET PTR TO HEADER STRING JMP OUTBIL ;AND PRINT IT ;BPRJH PRINTS THE HEADER FOR A PROJECT ENTRY IN BILL.LST BPRJH: MOV #BPH,R1 ;PRINT 'PROJECT: ' CALL BPRJPR ;PRINT THE LINE BCS 1$ CALL BCRLF ;AND THAT'S ALL 1$: RETURN ;BNAM PRINTS A USER ENTRY BNAM: MOV #BNMS,R0 MOV #NAME,R1 MOV #NAMLEN,R2 ;MOVE THE NAME STRING 5$: MOVB (R1)+,(R0)+ SOB R2,5$ MOV #BNM,R1 CALL OUTBIL ;SEND BEGINNING OF LINE BCS 10$ MOV #ACCNAM,R5 ;SET ACCUMULATOR PTR CALL CHGLIN ;AND SEND THE ACCUMULATOR VALUES AND CHARGE BCS 10$ CALL BCRLF 10$: RETURN ;BPRJ PRINT THE PROJECT TOTAL LINE BPRJ: CALL BCRLF BCS 10$ MOV #BPF,R1 ;PRINT ' TOTAL: ' CALL OUTBIL ;PRINT PROJECT NAME BCS 10$ MOV #ACCPRJ,R5 ;SET PROJECT ACC CALL CHGLIN ;AND SEND CHARGE LINE BCS 10$ MOV #BPF1,R1 ;PRINT PROJECT AFTER CHARGE CALL BPRJPR BCS 10$ CALL BCRLF BCS 10$ CALL BCRLF 10$: RETURN ;BTOT PRINTS THE TOTAL SHPIEL AT THE END OF A BILLING RUN BTOT: CALL BCRLF BCS 10$ MOV #BTT,R1 CALL OUTBIL ;PRINT '*** TOTAL' BCS 10$ MOV #ACCTOT,R5 CALL CHGLIN ;PRINT TOTAL CHARGES, ETC. BCS 10$ CALL BCRLF BCS 10$ MOV #BTT,R1 CALL OUTBIL BCS 10$ MOV #BB,R0 ;SET BOOTS AND SHUTUPS MOV BOOTS,R1 CALL B3OUT MOV #BS,R0 MOV SHUTS,R1 CALL B3OUT ;CONVERT TO ASCII (3 DIGITS) MOV #BBS,R1 CALL OUTBIL BCS 10$ CALL BILPUT ;FLUSH OUTPUT BUFFER (PROBABLY NOT NECESSARY) BCS 10$ MOV #BILFDB,R0 CLOSE$ R0 ;CLOSE BILL.LST 10$: RETURN ;SUPPORT SUBRS ;BPRJPR PRINTS THE PROJECT NAME WITH NO ; INPUTS: R1 - PTR TO STRING TO PRINT AT BEGINNING OF LINE BPRJPR: CALL OUTBIL ;PRINT EITHER 'PROJECT:' OR 'TOTAL:' BCS 10$ MOV #BPHS,R1 ;SET POSITION IN OUTPUT STRING MOV #PROJW,R0 ;SET THE USER STRING MOV #PRJLEN,R2 TSTB PROJ ;IF ZERO, THIS IS A BLANK STRING BNE 5$ MOV #BLNK,R0 ;IN WHICH CASE, PRINT A SPECIAL PROJECT NAME 5$: MOVB (R0)+,(R1)+ SOB R2,5$ MOV #BPHS,R1 ;POINT TO PROJECT VALUE STRING JMP OUTBIL ;AND SEND IT OUT 10$: RETURN ;B3OUT AND B2OUT MERELY SET R2 AND GO TO CBTA (THE BINARY TO ASCII ROUTINE) B3OUT: MOV #17012,R2 ;BLANK FILL, 3 CHARS, UNSIGNED JMP CBTA B2OUT: MOV #11012,R2 ;ZERO FILL, 2 CHARS, UNSIGNED JMP CBTA ;CHGLIN PRINTS THE ACCUMULATED VALUES AND CHARGE ; TAKES R5 SET TO ADDRESS OF ACCUMULATOR TO USE CHGLIN: MOV #BHEL,R0 MOV 6(R5),R1 ;SET # OF HEL ENTRIES CALL B3OUT MOV #BXXX,R0 MOV 4(R5),R1 ;SET NUMBER OF XXX ENTRIES CALL B3OUT MOV #BTM,R0 MOV (R5),R1 ;HOURS CALL B3OUT MOVB #':,(R0)+ MOV 2(R5),R1 ;MINUTES CALL B2OUT MOV (R5),R3 ;NOW DO THE CHARGE COMPUTATION MUL #60.,R3 ADD 2(R5),R3 ; (HOURS * 60.) + MINUTES MOV DOLLS,R1 MUL #100.,R1 ADD CENTS,R1 ; (DOLLARS * 100.) + CENTS MOV R3,R2 MUL R1,R2 ;R2,3 <- TOTAL MINUTES * TOTAL CENTS DIV #6000.,R2 ;R3<- CENTS OF CHARGE * 60. MOV R2,R1 ;R1<- DOLLARS OF CHARGE CLR R2 DIV #60.,R2 ;R2<- CENTS OF CHARGE (R3-REMAINDER) MOV R2,R3 MOV #BCHG,R0 MOV #20012,R2 ;NO FILL...4 CHARS CALL CBTA MOVB #'.,(R0)+ MOV R3,R1 CALL B2OUT ;PRINT CENTS CLRB (R0) ;ASCIZ MOV #BLINE,R1 ;SET TOP OF LINE CALL OUTBIL 10$: RETURN ;BCRLF PUTS A INTO BILL.LST ;OUTBIL BUFFERS OUTPUT TO BILL.LST AS FOLLOWS: ; IF BBUF HAS PRINTING CHARACTERS (SPACE OR GREATER) IN THE BUFFER ; AND A NON-PRINTING CHARACTER IS INSERTED, THE LINE WILL BE OUTPUT ; AS SOON AS EITHER A NULL OR A PRINTING CHAR IS ENCOUNTERED ; IF BBUF HAS NO PRINTING CHARS THEN THE LINE WILL NOT BE OUTPUT EVEN ; IF NON-PRINTING CHARACTERS ARE INSERTED ;**OUTBIL DOES NOT LOOK TO SEE IF THE BUFFER OVERFLOWS ;**BUT SINCE THE BUFFER IS 120. BYTES, THAT SHOULD BE BIG ENUF ;TO FLUSH THE BUFFER TO BILL.LST, CALL BILPUT ;INPUT--R1 - SRC STRING PTR ;R0,R1 SMASHED BCRLF: MOV #CRLFS,R1 ;SET STRING OUTBIL: MOV BBPTR,R0 ;GET BUFFER PTR 2$: CMPB (R1),#SPC ;PRINTING CHAR? BLT 5$ ;NO...HANDLE SPECIAL 3$: MOVB #1,BCRFLG ;YES...SET FLAG MOVB (R1)+,(R0)+ ;PUT CHAR IN BUFFER INC BCRCNT ;KEEP COUNT SINCE BILL.LST RECORDS ARE VARIABLE BR 2$ ;TRY NEXT CHAR 5$: TSTB (R1) ;END-OF-INPUT? BEQ 10$ ;YES...DONE NEGB BCRFLG ;0 IF NO PRINTING CHARS YET...ELSE 1 7$: CMPB (R1),#LF ;LINE FEED? BNE 8$ ; NO DEC BLCNT ;YES....GOT 60. OF 'EM? BGT 8$ ; NO MOV #60.,BLCNT ;YES....RESET CTR MOVB #FF,(R0)+ ;...AND PUT IN A FORM FEED INC R1 ;POINT PAST LF BR 9$ 8$: MOVB (R1)+,(R0)+ ;PUT CHAR IN BUFFER 9$: INC BCRCNT ;AND COUNT IT TSTB (R1) ;END OF LINE? BEQ 10$ CMPB (R1),#SPC ;PRINTING CHAR? BLT 7$ ;NO...INSERT IT INTO BUFFER TSTB BCRFLG ;YES....ALREADY GOT BOTH? BEQ 3$ ; NO...PUT IT IN BUFFER PUSH R1 ; YES...TIME TO WRITE A RECORD CALL BILPUT POP R1 BCS 20$ ;ERROR BR OUTBIL ;START OVER AGAIN 10$: TSTB BCRFLG ;WRITE FLAG SET? BPL 15$ ;NO CALL BILPUT ;YES...WRITE BUFFER TO BILL.LST RETURN 15$: MOV R0,BBPTR ;SAVE BUFFER PTR CLC 20$: RETURN ;BILPUT WRITES THE BUFFER AT BBUF TO BILL.LST AND RESETS THE PTRS AND FLAGS ; IT MAY BE CALLED TO FLUSH AN UNKNOWN BUFFER SINCE IT DOES NOTHING ; IF THE BUFFER IS EMPTY BILPUT: MOV BCRCNT,R2 ;GET COUNT BEQ 5$ ;BUFFER EMPTY MOV #BILFDB,R0 MOV #BBUF,R1 CALL PUT BCS 10$ 5$: MOV #BBUF,BBPTR ;RESET BUFFER PTR CLRB BCRFLG ;CLEAR PRINT FLAG CLR BCRCNT ;AND COUNTER 10$: RETURN ;SOME SUBROUTINES TO SUPPORT LOG.XXX AND BILL.LST SUBRS ;WAIT1 WAITS A SECOND WAIT1: MRKT$S #WAITEFN,#1,#2 BCS 1$ WTSE$S #WAITEFN ;NOW WAIT A SECOND! 1$: RETURN ;GETDEV ALLOWS LOG.TMP AND BILL.LST TO BE CREATED ON A DISK WITH ROOM FOR THEM ; INPUTS: R5 - 0 TO START; GETDEV MAINTAINS R5 FOR FUTURE CALLS ; OUTPUT: R4 - PTR TO DEVICE STRING FOR DATASET DESCRIPTOR ; (SY0: OR LB0: IN THAT ORDER) ; C-SET IF ALL POSSIBILITIES TRIED ;USES R4,R5 GETDEV: CMP R5,#1 BLT 2$ ;0->SET SY0: BEQ 3$ ;1->SET LB0: SEC ;2->SET ERROR RETURN 2$: MOV #SY0,R4 BR 10$ 3$: MOV #LB0,R4 10$: INC R5 CLC RETURN ;NOW SOME SUBROUTINES TO MAKE LOG FILE MANIPULATION EASIER ;COPFIL COPIES FROM ONE FILE TO ANOTHER ; STARTS AT CURRENT POSITION AND COPIES TIL END-OF-FILE ; RECORDS STARING WITH 'B' (MARKED) ARE IGNORED ; INPUTS: R3 - SOURCE FDB ; R4 - DESTINATION FDB ; LTREC - 0 TO MARK BOOT/SHUTUP ENTRIES....1 TO LEAVE THEM ALONE ; OUTPUT: NRECS - # OF RECORDS COPIED ; BOOTS - SET TO NUMBER OF BOOT ENTRIES WITHIN BILL DATES ; SHUTS - SET TO NUMBER OF SHUTUP ENTRIES WITHIN DATES ; C-SET IF ERROR ;USES R0-5 COPFIL: MOV #1,F.RCNM+2(R3) ;SET RANDOM ACCESS RECORD #S MOV #1,F.RCNM+2(R4) MOV #BUF,R1 MOV #64.,R2 CLR NRECS PUSH R4 CLR BOOTS CLR SHUTS 1$: MOV R3,R0 ;GET SRC FDB CALL GET ;GET A RECORD BCC 3$ CMPB F.ERR(R0),#IE.EOF ;END-OF FILE? BEQ 20$ ;YES...DONE 2$: POP ;ERROR---POP FDB SEC RETURN ;NO...ERROR 3$: CALL ENTYP ;GET ENTRY TYPE INTO R4 CMP R4,#6 BGT 1$ ;MARKED OR ILLEGAL ENTRY...SKIP IT BLT 4$ ;NORMAL ENTRY TST NRECS ;IS THIS TOP-LINE 1ST IN FILE? BNE 1$ ; NO, SKIP IT BR 10$ ;FIRST TOP LINE...GO ON 4$: CALL DATCMP ;WITHIN BILL DATES? BVS 1$ ;...ILLEGAL ENTRY...SKIP IT BNE 10$ ; NO...GO ON CMP R4,#4 BLT 10$ ;BR IF HEL, LOG, OR XXX ENTRY CMP R4,#5 BNE 5$ ;BR IF BOOT ENTRY INC SHUTS ;COUNT AS A SHUTUP BR 8$ 5$: INC BOOTS ;COUNT AS A BOOT 8$: TST LTREC ;MARK IT? BNE 10$ MOVB #'B,(R1) ;MARK IT 10$: MOV (SP),R0 ;GET DEST FDB CALL PUT ;WRITE THIS RECORD OUT BCS 2$ ; ERROR INC NRECS ;COUNT THE RECORDS WRITTEN BR 1$ 20$: CLC POP RETURN ;MARK SETS THE MARK BYTE (FIRST BYTE->B) IN THE CURRENT RECORD IN BUF ; AND WRITES THE RECORD BACK TO THE TMP FILE ;USES R0-R3 MARK: MOVB #'B,(R1) JMP PUTTMP ;MKRES RESETS THE TMP FILE AND RESETS ALL THE MARKED ENTRIES TO THEIR ; ORIGINAL STATE ;RETURNS C-SET IF ERROR ;USES R0-R5 MKRES: CALL RESET ;RESET LOG.TMP 1$: CALL GETTMP ;GET A RECORD BEQ 20$ ; DONE BCS 20$ ;ERROR CALL ENTYP ;FIND OUT WHICH RECORD IT IS CMP R4,#7 BLT 1$ ;UNMARKED...LEAVE IT ALONE BEQ 13$ ;BEL CMP R4,#9. BEQ 11$ ;BXX BLT 9$ ;BOG CMP R4,#12. BLT 5$ ;B** MOVB #'B,(R1) ;IT IS AN ERROR ENTRY...MARK IT SO IT GOES AWAY BR 15$ 5$: MOVB #'*,(R1) ;***BOOT OR ***SHUTUP BR 15$ 9$: MOVB #'L,(R1) ;LOG BR 15$ 11$: MOVB #'X,(R1) ;XXX BR 15$ 13$: MOVB #'H,(R1) ;HEL 15$: CALL PUTTMP BCC 1$ ;GO BACK FOR MORE 20$: RETURN ;SUBROUTINES TO GET APPROPRIATE RECORDS ;GETT1 GETS THE NEXT RECORD THAT IS A HEL, LOG, OR XXX ENTRY WITHIN BILL DATES ;RETURNS C-SET IF ERROR ; Z-SET IF EOF ; ELSE: R4 - ENTYP CODE FOR ENTRY TYPE ; PRJT - SET WITH ALPHANUMERIC PROJECT STRING ;USES R0-5 GETT1: CALL GETTMP ;GET A RECORD BEQ 10$ ;EOF BCS 10$ ;ERROR CALL ENTYP ;GET ENTRY TYPE CMP R4,#3 BGT GETT1 ;NOT PROPER ENTRY CALL DATCMP ;CHECK THE DATE BNE GETT1 ;N.G. CALL PRJALN ;THIS IS IT...SET THE PROJECT STRING FOR TEST CLZ CLC 10$: RETURN ;GETT2 GETS THE NEXT RECORD THAT PASSES GETT1 AND HAS THE SAME PROJECT AS PROJ ;RETURNS C-SET IF ERROR ; Z-SET IF EOF ; R4 - ENTYP CODE FOR ENTRY TYPE ;USES R0-5 GETT2: CALL GETT1 ;GET A HEL,LOG,XXX ENTRY WITHIN DATES BEQ 10$ ;EOF BCS 10$ ;ERROR MOV #PRJT,R2 ;POINT TO INPUT STRING MOV #PROJ,R0 ;POINT TO TEST STRING MOV #PRJLEN,R3 ;GET LENGTH TO COMPARE 5$: CMPB (R2)+,(R0)+ ;STRINGS THE SAME? BNE GETT2 ;NOPE...TRY NEXT ONE SOB R3,5$ CLC ;YES...SUCCESS! CLZ 10$: RETURN ;GETT3 GETS THE NEXT RECORD THAT PASSES GETT2 AND HAS THE SAME LAST NAME AS NAME ;RETURNS C-SET IF ERROR ; Z-SET IF EOF ; R4 - ENTYP CODE FOR ENTRY TYPE ;USES R0-5 GETT3: CALL GETT2 ;GET A HEL,LOG,XXX ENTRY WITHIN DATES BEQ 10$ ;EOF BCS 10$ ;ERROR MOV R1,R2 ADD #LL.LNM,R2 ;POINT TO INPUT STRING MOV #NAME,R0 ;POINT TO TEST STRING MOV #NAMLEN,R3 ;GET LENGTH TO COMPARE 5$: CMPB (R2)+,(R0)+ ;STRINGS THE SAME? BNE GETT3 ;NOPE...TRY NEXT ONE SOB R3,5$ CLC ;YES...SUCCESS! CLZ 10$: RETURN ;PRJALN MOVES THE ALPHANUMERICS FROM THE PROJECT STRING IN THE CURRENT RECORD ; TO PRJT, WHERE THEY CAN BE TESTED FOR MATCH WITH PROJ ; INPUTS: R1 - SET TO TOP OF RECORD BUFFER ;USES R0,R2-3 PRJALN: PUSH R1 ;SAVE R1 MOV R1,R0 ADD #LL.PRJ,R0 ;POINT TO USER STRING MOV #PRJLEN,R2 ;SET LENGTH OF USER STRING/PRJT MOV #PRJT,R3 ;DEST 5$: MOVB (R0)+,R1 ;GET CHAR FOR TESTING CMPB R1,#'0 BLT 10$ ;TOO LOW CMPB R1,#172 ;SMALL Z BGT 10$ ;TOO HIGH CMPB R1,#'9 BLE 8$ ;NUMERIC CMPB R1,#'A BLT 10$ ;NON-ALPHABETIC CMPB R1,#'Z BLE 8$ ;ALPHABETIC CMPB R1,#141 ;SMALL A BLT 10$ ;NON-ALPHA SUB #40,R1 ;CONVERT LOWER CASE TO UPPER 8$: MOVB R1,(R3)+ ;O.K. 10$: SOB R2,5$ ;EXHAUST THE INPUT STRING MOV #PRJT+PRJLEN,R2 ;GET END OF BUFFER + 1 SUB R3,R2 ;SUBTRACT LOC OF LAST CHAR + 1 BEQ 20$ ; PRJT FULL 15$: CLRB (R3)+ ;CLEAR TO END OF PRJT SOB R2,15$ 20$: POP R1 RETURN ;SUBROUTINES TO DO THE MAIN BILLING WORK ;LOWPRJ SEARCHES THE WHOLE LOG.TMP FILE FOR THE ALPHABETICALLY LOWEST PROJECT ;RETURNS: C-SET - ERROR ; Z-SET - NO MORE UNMARKED PROJECTS WITHIN BILLING DATES ; ELSE: PROJ - PROJECT STRING ; RECORD NUMBER OF 1ST OCCURENCE OF THE PROJECT SAVED LOWPRJ: CALL RESET ;RESET LOG.TMP TO 1ST RECORD MOV #PROJ,R4 ;INITIALIZE BEST VALUE MOV #PRJLEN,R5 3$: MOVB #177,(R4)+ SOB R5,3$ ;ALL BYTES ARE HIGHEST THEY CAN BE 10$: CALL GETT1 ;GET NEXT LOG, HEL, XXX WITH OK DATE BEQ 30$ ;NO MORE BCS 35$ ;ERROR MOV #PROJ,R4 ;SET BEST PTR MOV #PRJT,R3 ;SET TEST PTR MOV #PRJLEN,R5 15$: CMPB (R3)+,(R4)+ BLT 20$ ;NEW ENTRY IS BETTER! BGT 10$ ;WORSE...TRY NEXT SOB R5,15$ ;SAME SO FAR BR 10$ ;SAME PROJECT, TRY NEXT ONE 20$: DEC R4 ;THIS ONE IS BETTER DEC R3 ;BACK UP PTRS AND MOVE THE DIFFERING CHARS 25$: MOVB (R3)+,(R4)+ SOB R5,25$ MOV R1,R3 ADD #LL.PRJ,R3 ;SET PTR TO USER STRING MOV #PRJLEN,R5 MOV #PROJW,R4 ;MOVE USER STRING FOR PRINTING 27$: MOVB (R3)+,(R4)+ SOB R5,27$ CALL SAVREC ;SAVE THE RECORD NUMBER BR 10$ ;AND GO ON TO NEXT ENTRY 30$: CMPB PROJ,#177 ;CHAR ANY DIFFERENT? CLC ;(SET Z-BIT ACCORDINGLY) 35$: RETURN ;LOWNAM SEARCHES LOG.SYS FOR LOWEST NAME ENTRY WITH CURRENT PROJECT ; STARTS SEARCH AT 1ST OCCURRENCE OF THE PROJECT NAME ; SAVES RECORD # OF 1ST OCCURRENCE OF THIS NAME ;RETURNS: C-SET - ERROR ; Z-SET - NO MORE UNMARKED NAMES UNDER THIS PROJECT ; ELSE: NAME - LOWEST LAST NAME STRING ; RECORD NUMBER SAVED LOWNAM: CALL RESREC ;RESET LOG.TMP TO 1ST RECORD OF THIS PROJECT MOV #NAME,R4 ;INITIALIZE BEST VALUE MOV #NAMLEN,R5 3$: MOVB #177,(R4)+ SOB R5,3$ ;ALL BYTES ARE HIGHEST THEY CAN BE 10$: CALL GETT2 ;GET NEXT LOG, HEL, XXX WITH OK DATE, PROJECT BEQ 30$ ;NO MORE BCS 35$ ;ERROR MOV #NAME,R4 ;SET BEST PTR MOV R1,R3 ;SET TEST PTR ADD #LL.LNM,R3 MOV #NAMLEN,R5 15$: CMPB (R3)+,(R4)+ BLT 20$ ;NEW ENTRY IS BETTER! BGT 10$ ;WORSE...TRY NEXT SOB R5,15$ ;SAME SO FAR BR 10$ ;SAME PROJECT, TRY NEXT ONE 20$: DEC R4 ;THIS ONE IS BETTER DEC R3 ;BACK UP PTRS AND MOVE THE DIFFERING CHARS 25$: MOVB (R3)+,(R4)+ SOB R5,25$ CALL SAVNR ;SAVE THIS RECORD NUMBER BR 10$ ;AND GO ON TO NEXT ENTRY 30$: CMPB NAME,#177 ;CHAR ANY DIFFERENT? CLC ;(SET Z-BIT ACCORDINGLY) 35$: RETURN ;ADDALL ACCUMULATES ALL THE INFORMATION FOR THIS PROJECT/NAME ; ALL THE ACCUMULATORS ARE UPDATED: ; WORD 1 : HOURS LOGGED IN ; WORD 2 : MINUTES LOGGED IN ; WORD 3 : NUMBER OF SYSTEM CRASHES (XXX ENTRIES) ; WORD 4 : NUMBER OF REMAINING LOGONS (HEL ENTRIES) ;C-SET IF ERROR ADDALL: CLR HRACC ;CLEAR SUMMING AREAS CLR MINACC MOV #ACCNAM,R5 ;CLEAR NAME ACCUMULATOR CLR (R5)+ CLR (R5)+ CLR (R5)+ CLR (R5)+ CALL RESNR ;SET RECORD # TO 1ST RECORD W/ THIS NAME 10$: CALL GETT3 ;GET NEXT APPROPRIATE RECORD BEQ 30$ ;NO MORE BCS 40$ ;ERROR CALL MARK ;MARK THIS ENTRY CMP R4,#2 BEQ 20$ ;LOG BLT 15$ ;HEL INC ACCNAM+4 ;XXX BR 10$ ;GO ON 15$: INC ACCNAM+6 ;(HEL) BR 10$ ;GO ON 20$: CALL TIMADD ;(LOG) ADD IN THE TOTAL TIME BR 10$ ;GO ON 30$: MOV HRACC,ACCNAM ;SAVE HOURS MOV MINACC,ACCNAM+2 ;AND MINUTES MOV #60.,R4 ;60 IS USED AN AWFUL LOT FOR TIME ADDITION MOV #ACCPRJ+2,R5 ;ADD THIS TIME TO PROJECT ACCUMULATOR ADD HRACC,-2(R5) ADD MINACC,(R5) CMP (R5),R4 BLT 35$ SUB R4,(R5) ;OVER 60 MIN OVERFLOWS TO AN HOUR INC -2(R5) 35$: MOV #ACCTOT+2,R5 ;ADD THIS TIME TO TOTAL ACCUMULATORS ADD HRACC,-2(R5) ADD MINACC,(R5) CMP (R5),R4 BLT 38$ SUB R4,(R5) ;OVER 60 MIN OVERFLOWS TO AN HOUR INC -2(R5) 38$: ADD ACCNAM+4,ACCTOT+4 ;ADD HELS AND XXXS ADD ACCNAM+6,ACCTOT+6 ADD ACCNAM+4,ACCPRJ+4 ADD ACCNAM+6,ACCPRJ+6 CLC 40$: RETURN ;FINALLY, THE SUBROUTINES TO DO THE CONVENIENT LITTLE MANIPULATIONS ;CNVDAT CONVERTS AN ASCII DATE STRING TO A UNIQUE NUMBER PROPORTIONAL TO DATE ; INPUTS: R0 - DATE STRING PTR ; OUTPUT: R0 - CONVERTED DATE VALUE ;PRESERVES R1-5 CNVDAT: JSR R5,.SAVR1 ;SAVE R1-5 CALL CDTB ;CONVERT MONTH DEC R1 MOV R1,R5 MUL #31.,R5 CALL CDTB ;CONVERT DAY DEC R1 ADD R1,R5 CALL CDTB ;CONVERT YEAR MUL #372.,R1 ADD R1,R5 MOV R5,R0 RETURN ;RESTORE REGS AND RETURN ;DATCMP TESTS THE DATE IN THE CURRENT RECORD WITH THE BILLING DATES ; INPUTS: R1 - BUFFER ADDRESS (START OF RECORD) ; DATLOW - START DATE VALUE (CONVERTED BY CNVDAT) ; DATHIG - END DATE VALUE ; OUTPUT: CONDITION CODES SET SO THAT THE FOLLOWING APPLIES: ; BEQ - DATE IS WITHIN RANGE ; BNE - DATE IS NOT WITHIN RANGE ; BLO - DATE IS PREVIOUS TO START DATE ; BHI - DATE IS AFTER END DATE ; BVS - DATE IS ILLEGAL ;USES R0 DATCMP: MOV R1,R0 ADD #LL.DAT,R0 ;SET DATE PTR CALL CNVDAT ;CONVERT TO DATE VALUE CMP R0,#37199. ;TEST FOR LEGAL ENTRY (MUST BE CMP FOR C-BIT) BHI 3$ CMP R0,DATLOW ;TEST LOW END BLO 1$ CMP R0,DATHIG ;TEST HIGH END BHI 1$ SEZ ;DATE IS WITHIN RANGE 1$: CLV RETURN 3$: SEV RETURN ;TIMADD ADDS TOTAL CONNECT TIME IN CURRENT LOG ENTRY TO ACCUMULATORS ; INPUTS: R1 - BUFFER ADDRESS (START OF RECORD) ; OUTPUT: HRACC <- HRACC + LOG HOURS ; MINACC<-MINACC + LOG MINUTES ;USES R0 TIMADD: JSR R5,.SAVR1 ;SAVE R1-5 MOV R1,R0 ADD #LL.TTL,R0 ;SET PTR TO TIME CALL CDTB ;CONVERT HOURS ADD R1,HRACC ;ADD TO ACCUMULATOR CALL CDTB ;CONVERT MINUTES ADD R1,MINACC 1$: CMP MINACC,#60. ;OVERFLOW INTO HRACC BLT 2$ SUB #60.,MINACC INC HRACC BR 1$ 2$: RETURN ;ENTYP SETS A FLAG DEPENDING ON THE TYPE OF LOG ENTRY IN THE RECORD BUFFER ; INPUTS: R1 - BUFFER ADDRESS (START OF RECORD) ; OUTPUT: R4 - 1 : HEL ; 2 : LOG ; 3 : XXX ; 4 : ***BOOT ; 5 : ***SHUTUP ; 6 : * (TOP LINE) ; 7 : BEL (MARKED HEL) ; 8 : BOG (MARKED LOG) ; 9 : BXX (MARKED XXX) ; 10 : B**BOOT ; 11 : B**SHUTUP ; 12 : UNRECOGNIZABLE (ERROR MSG PRINTED ON TI:) ;USES R4,R5 ENTYP: MOVB 1(R1),R5 ;GET 2ND CHAR MOV #1,R4 ;1 CMPB R5,#'E ;HEL OR BEL? BEQ 2$ INC R4 ;2 CMPB R5,#'O ;LOG OR BOG? BEQ 2$ INC R4 ;3 CMPB R5,#'X ;XXX OR BXX? BEQ 2$ INC R4 ;4 CMPB R5,#'* ;***BOOT OR ***SHUTUP OR B**BOOT OR B**SHUTUP? BNE 6$ CMPB 3(R1),#'B ;***BOOT OR B**BOOT? BEQ 2$ INC R4 ;5 (MUST BE ***SHUTUP OR B**SHUTUP) 2$: CMPB (R1),#'B ;MARKED ENTRY? BNE 5$ 4$: ADD #6,R4 ;YES 5$: RETURN 6$: ADD #2,R4 ;6 CMPB R5,#SPC ;* (TOP LINE)? BEQ 5$ MOV R0,-(SP) ;SAVE R0,R1 MOV R1,-(SP) MOV #BADENT,R0 ;BAD ENTRY...PRINT MSG CALL WRITE ;COPFIL WILL MARK IT MOV (SP)+,R1 ;RESTORE R1,R0 MOV (SP)+,R0 BR 4$ ;NO...R4<-12. .END