.MCALL RETURN,CSI2,GCML,CSI1G,ENTER,LEAVE,CALL,TINIT,PSTR .MCALL FINIT$,ALUN$S,DIR$,EXIT$S,RCML$ .MCALL FSRSZ$,FDBDF$,FDOP$A,FDRC$A,FDAT$A,FDBF$A .MCALL NMBLK$,GCMLB$,CSI$,CSI$SW,CSI$SV,CSI$ND .MCALL OPEN$R,OPEN$W,PUT$,GET$,CLOSE$,PRINT$,GTIM$S ; ; START: MOV SP,SPSAVE ;SAVE STACK POINTER FINIT$ TINIT 5,15 ALUN$S #GCLUN,#"TI,#0 ;ASSIGN LUN TO USERS TERMINAL JMP GOTOIT ;GOTO MAIN PROGRAM TERMIN: EXIT$S ;TERMINATION OF PROGRAM ERRPFX::PSTR ^*<12><15>/FLY--/* RETURN DIE:: RCML$ #GCLBLK ;USED BY ERROR RUOTINES BIT #1,FILTST ;WAS OUTPUT FILE OPENED BEQ 1$ ;NO, SO DON'T DO ANYTHING MOV #FDOUT,R0 ;YES, SO DELETE OUTPUT FILE CALL .DLFNB 1$: BIT #2,FILTST ;WAS INPUT FILE OPENED BEQ 2$ ;NO, SO DON'T DO ANYTHING CLOSE$ #FDIN,IOERR ;YES, SO CLOSE IT 2$: JMP GOTOIT ;TO RESET GCML BLOCK AND RETURN TO MAIN PROGRAM SPSAVE: .WORD 0 ;STACK POINTER SAVER FILTST: .WORD 0 TIMBUF: .BLKW 10 ;TIME STORAGE LOCATION FSRSZ$ 4 ;FDB INIZIALIZATIONS FDOUT: FDBDF$ ;OUTPUT FILE FDB FDOP$A 1,CSIBLK+C.DSDS,NAMOUT,FO.WRT FDRC$A FDAT$A R.VAR,FD.CR,,-1,-1 FDBF$A 26 NAMOUT: NMBLK$ FLY,DMP,,SY,0 FDIN: FDBDF$ ;INPUT FILE FDB FDOP$A 2,CSIBLK+C.DSDS,NAMIN,FO.RD FDRC$A FDBF$A 30 NAMIN: NMBLK$ ,,,SY,0 GCLBLK: GCMLB$ 4,FLY,GCBUF,GCLUN ;GCML BLOCK GCBUF: .BLKW 41 CSI$ .EVEN CSIBLK: .BLKB C.SIZE TABLE: CSI$SW SP,SW.SP,,,NEG,SVALT ;SWITCH TABLE CSI$SW CL,SW.CL,,,,CLVAL CSI$SW TR,SW.TR,,,,SVALT CSI$SW NH,SW.NH,,,,SVALT CSI$SW WD,SW.WD,,,,SVALT CSI$ND SVALT: CSI$SV DECIMAL,OCOL,2 ;SWITCH VALUE TABLE CLVAL: CSI$SV DECIMAL,CMAX,2 CSI$ND SW.TR=1 ;SWITCH MASKS SW.NH=2 SW.WD=4 SW.SP=10 SW.CL=20 PAGSIZ=73 SPACE=40 GCLUN=3 ;GCML LUN FHED: ;THIS SUBROUTINE GETS THE DEVICE,UIC, AND FILENAME,TYPE, AND ;VERSION NUMBER FOR THE HEADER PRINTED BY FLY ; ENTER R0,R1,R2,R3,R4,R5 ;SAVE REGESITERS MOV #NAME,R0 ;GET BUFFER FOR HEADER MOVB FNB+N.DVNM,(R0)+ ;PUT DEVICE NAME IN BUFFER MOVB FNB+N.DVNM+1,(R0)+ MOV FNB+N.UNIT,R1 ;GET (BINARY) DEVICE NUMBER CLR R2 ;SET NO PADDING CALL $CBOMG ;PUT (ASCII) DEVICE NUMBER IN BUFFER MOVB #':,(R0)+ ;PUT : AFTER THE DEVICE MOV R0,R3 ;SAVE BUFFER LOCATION MOV #BUFFER,R0 ;GET DUMMY BUFFER ADRESS TST UICLEN ;WAS A UIC FOR THE INPUT FILE SPECIFIED BNE 5$ ;YES, AND WE ALL READY PUT IT IN THE BUFFER ;WHEN WE OPENED THE INPUT FILE MOV #0,R1 ;NO, SO GET THE DEFAULT UIC AND PUT IT CALL .GTUIC ;IN THE BUFFER BR 6$ 5$: ADD UICLEN,R0 ;UIC WAS SPECIFIED SO UPDATE R0 6$: MOV #FNB+N.FNAM,R5 ;GET FILENAME ADRESS MOV #3,R4 ;MAKE R4 A COUNTER 3$: MOV (R5)+,R1 ;GET (RADIX) FIRST THREE CHAR. CALL $C5TA ;CONVDERT TO ASCII AND SAVE SOB R4,3$ ;REPEAT TILL GOT ALL MOVB #'.,(R0)+ ;DONE, SO PUT . BEFORE FILE TYPE MOV FNB+N.FTYP,R1 ;NOW, GET FILE TYPE CALL $C5TA ;CONVERT TO ASCII AND SAVE MOVB #'!,(R0) ;SET MARKER FOR END OF BUFFER MOV #BUFFER,R0 ;RETURN R0 TO BEGINNING OF BUFFER 4$: CMPB (R0),#'! ;IS THIS THE END OF THE BUFFER BEQ 13$ ;IF SO WERE DONE OTHERWISE, CONTINUE CMPB (R0),#40 ;MOVING UIC,FILE NAME AND FILE TYPE, TO BEQ 14$ ;THE HEADER BUFFER, OMMITING ALL BLANKS. MOVB (R0)+,(R3)+ BR 4$ 14$: TSTB (R0)+ ;SKIP THE BLANK BR 4$ 13$: MOV R3,R0 ;RESTORE R0 TO CURRENT ADDRESS IN ;HEADER BUFFER MOVB #';,(R0)+ ;SEPERATE FILE TYPE AND VERSION MOV FNB+N.FVER,R1 ;GET FILE VERSION (BINARY) CLR R2 CALL $CBOMG ;CONVERT TO ASCII AND STORE LEAVE ;RESTORE REGISTERS RTS PC ;HURRAY, DONE BUFFER: .BLKB 20. ;DUMMY BUFFER UICLEN: .WORD 0 FNB=FDIN+F.FNB ;ADRESS OF INPUT FILE NAME BLOCK OPEN: BITB #CS.EQU,CSIBLK+C.STAT ;IS THERE AN OUTPUT FILE? BNE INPUT ;YES SO PARSE INPUT FILE OUT: CSI2 #CSIBLK,OUTPUT,#TABLE,CS2ERR ;PARSE OUTPUT FILE BITB #CS.EQU,CSIBLK+C.STAT ;IS IT OUTPUT OR INPUT FILE? BNE 10$ ;IT'S OUTPUT JSR PC,AID ;IT'S INPUT MOV #6,R0 ;NO OUTPUT FILE SPECIFIED MOV #CSIBLK+C.DSDS,R1 ;DEFAULT TO FILE NAME BLOCK 3$: CLR (R1)+ ;FOR FDB USAGE SOB R0,3$ BR 11$ ;NO =, SO NO POSSIBLE INVALID ;SWITCHES ON OUTPUT FILE 10$: CMP CSIBLK+C.MKW1,#0 ;ANY SWITCHES ON OUTPUT FILE BEQ 11$ ;NO, SO CONTINUE PSTR ^*/FLY -- INVALID TO SPECIFY SWITCH ON OUTPUT FILE/* JMP DIE ;YES,SO WRITE ERROR,AND START AGAIN BIS #1,FILTST ;SET FLAG, THAT OUTPUT FILE OPEN 11$: OPEN$W #FDOUT,,,,,,IOERR ;OPEN OUTPUT FILE RTS PC ;NO SO WERE DONE INPUT: CSI2 #CSIBLK,INPUT,#TABLE,CS2ERR ;PARSE INPUT FILE JSR PC,AID ;OPEN INPUT FILE BR OUT ;PARSE OUTPUT FILE AID: MOV CSIBLK+C.MKW1,SWITCH ;SAVE SWITCHES MOV CSIBLK+C.MKW2,NEGATE ;SAVE NEGATION VALUES BIS #2,FILTST ;SET FLAG, THAT INPUT FILE OPEN OPEN$R #FDIN,,,,,,IOERR ;OPEN INPUT FILE MOV CSIBLK+C.DIRD,UICLEN ;GET LENGTH OF DIRECTORY STRING TST UICLEN ;IS IT 0?? BEQ 3$ ;YES, SO DON'T DO ANYTHING MOV UICLEN,R1 ;NO, SO SAVE THE DIRECTORY STRING MOV #BUFFER,R2 MOV CSIBLK+C.DIRD+2,R3 5$: MOVB (R3)+,(R2)+ SOB R1,5$ 3$: MOV #FDIN+F.FNB+N.FNAM,R1 ;GET THE INPUT FILE NAME MOV #NAMOUT+N.FNAM,R2 ;AND PUT IT IN THE DEFAULT FILE MOV #3,R3 ;NAME BLOCK, SO THE OUTPUT FILE 6$: MOV (R1)+,(R2)+ ;HAS THE SAME NAME AS THE INPUT SOB R3,6$ ;FILE RTS PC ;RETURN TO CALLING SECTION GOTOIT: MOV SPSAVE,SP CLR OCOL CLR FILTST CLRB HEADER CLRB FORM CLR CMAX GCML #GCLBLK,,,TERMIN,GCERR CSI1G #CSIBLK,GCLBLK,CS1ERR TST CSIBLK+C.CMLD BNE 30$ JMP GOTOIT 30$: JSR PC,OPEN CMP OCOL,#0 BNE 3$ MOV #130.,OCOL BR 14$ 3$: CMP OCOL,#20. BGE 12$ MOV #20.,OCOL 12$: CMP OCOL,#130. BLE 13$ MOV #130.,OCOL 13$: CMP OCOL,#66. BGE 14$ BIS #SW.NH,SWITCH 14$: MOV #PAGSIZ,LMAX BIT #SW.NH,SWITCH BEQ 9$ ADD #2,LMAX 9$: CMP CMAX,#0 BGE 10$ MOV #0,CMAX 10$: CMP CMAX,#9. BLE 11$ MOV #9.,CMAX ; .SBTTL DATA FILE PROCESSING 11$: MOV #1,PAGEN ;SET PAGE COUNTER TO 1 MOV #DASH,R1 ;WRITE VERSION INFORMATION INTO BUFFER MOV #VERSON,R0 ;DASH MOV #VERLEN,R2 FILLV: MOVB (R0)+,(R1)+ DEC R2 BNE FILLV MOVB #SPACE,(R1)+ ;PUT A SPACE AFTER THE VERSION MOV #'-,R0 ;FILL IN REST OF BUFFER MOV #DATE-DASH-VERLEN-2,R2 ;DASH WITH DASHES FILL: MOVB R0,(R1)+ DEC R2 BNE FILL ; ;SHRINK THE HEADER IF NECESSARY ; BIT #SW.NH,SWITCH ;IS THERE A HEADER? BNE 4$ MOV #DASH+VERLEN+1,R1 ;START OF DASHES MOV #DATE,R0 ;END OF DASHES MOV #130.,R2 ;OLD HEADER LENGTH SUB OCOL,R2 ;NUMBER OF EXTRA DASHES BLE 4$ ;LOTS OF ROOM ASR R2 ;WE REMOVE TWO AT A TIME 3$: CLRB (R1)+ CLRB -(R0) DEC R2 BNE 3$ 4$: MOVB #SPACE,DATE-1 ; ENTER R0,R1,R2 JSR PC,FHED GTIM$S #TIMBUF MOV #TIMBUF,R1 MOV #DATE,R0 JSR PC,$DAT LEAVE MOV #BUFA,POUT ;???? MOV #2,R2 CLR ALL MOV CMAX,R0 BEQ MOST .SBTTL FIXED NUMBER OF COLUMNS ; ;SET UP WIDTHS FOR FIXED NUMBER OF COLUMNS. ; ENTER R0,R1,R2,R3 ;SAVE WORK REGISTERS MOV #WIDTH,R3 ;BUFFER "WIDTH" IS A COLUMN WIDTH LOOKUP TABLE CLR R2 ; 1$: INC R2 ;R2 IS COUNTER TAKING VALUES 1 TO 9 CLR R0 ;R0 IS TO CONTAIN QUOTIENT OF OCOL DIVIDED BY R2 MOV OCOL,R1 ;GET PAGE OUTPUT WIDTH DIV R2,R0 ;DIVIDE INTO COLUMNS MOVB R0,(R3)+ ;SAVE THE SIZE IN BUFFER WIDTH CMP R2,#9. ;DONE THE WORKS? BLT 1$ ;NO,REPEAT ; LEAVE ;DONE SO RESTORE THE REGISTERS ; MOVB WIDTH-1(R0),WIDE ;MOVE APPROPRIATE COLUMN WIDTH INTO WIDE SUB #2,WIDE NEXTP: MOV #L,PL ;L IS BUFFER CONTAINING BEGINNING ADRESS ;OF EACH COLUMN IN BUFFER "BLOCK" MOV #C,PCC ;C IS A BUFFER CONTAINING WIDTH OF EACH COLUMN MOV CMAX,COL ;PUT MAXIMUM NO. OF COLUMNS INTO COL MOV #BLOCK,R4 ;PUT STARTING ADRRESS OF STORAGE BUFFER IN R4 NCOL: MOV R4,@PL ;STORE ADRESS OF BEGINNING OF COLUMN IN L ADD R2,PL ;MOVE PL TO POINT TO NEXT WORD OF BUFFER "L" MOV LMAX,LINE ;MOVE MAXIMUM NO. OF LINES INTO LINE NEXTL: JSR PC,READL ;GO READ A LINE FROM INPUT FILE DEC LINE ;ARE WE AT BOTTOM OF PAGE? BGT NEXTL ;NO, GO GET ANOTHER LINE TST ALL ;YES, ARE WE AT END OF INPUT FILE? BNE LAST ;IF SO GOTO LAST MOVB WIDE,@PCC ;NOT EOF, SO STORE COLUMN WIDTH IN BUFFER C INC PCC ;PCC NOW POINTS TO NEXT AVAILABLE BYTE OF C DEC COL ;HAVE WE ENOUGH COLUMNS FOR A PAGE? BGT NCOL ;NO, SO GET ANOTHER COLUMN JSR PC,PRINT ;YES, SO PRINT THE PAGE JMP NEXTP ;READ IN NEXT PAGE LAST: MOV CMAX,R0 ;WE REACHED END OF INPUT FILE, SO SEE HOW MANY SUB COL,R0 ;COLUMNS WE HAVE FOR THIS PAGE INC R0 ;ADD 1 TO COLUMN COUNT MOV R0,CMAX ;RESET VALUE OF CMAX MOV R0,R3 REDO: MOVB WIDTH-1(R0),C-1(R3) DEC R3 BNE REDO JSR PC,PRINT BR DONE .SBTTL VARIABLE NUMBER OF COLUMNS MOST: MOV OCOL,WIDE NP: MOV OCOL,AVAIL MOV #L,PL MOV #C,PCC MOV #BLOCK,R4 NC: CLR MAX MOV LMAX,LINE MOV R4,@PL ADD R2,PL NL: JSR PC,READL CMP R3,MAX BLOS T3 MOV R3,MAX CMP R3,AVAIL BLOS T3 SUB R2,PL MOV @PL,PP MOV LINE,SLINE JSR PC,PRINTV MOV LMAX,R5 INC R5 ;? MOV SLINE,LINE SUB SLINE,R5 MOV #L+2,PL MOV #BLOCK,L MOV #C,PCC MOV #BLOCK,R4 MOV OCOL,AVAIL CLR CMAX MOV PP,R1 D2: MOVB (R1)+,R3 MOVB R3,(R4)+ BEQ WHERE D1: MOVB (R1)+,(R4)+ DEC R3 BNE D1 WHERE: DEC R5 BNE D2 T3: DEC LINE BGT NL INC CMAX MOVB MAX,@PCC INC PCC SUB MAX,AVAIL SUB R2,AVAIL BGE T4 CLR AVAIL T4: TST ALL BEQ NC JSR PC,PRINTV BR DONE ERR1: NOP ERR2: NOP .SBTTL COMPLETION PROCESSING DONE: CLOSE$ #FDIN,IOERR BIT #SW.SP,SWITCH BEQ 1$ BIT #SW.SP,NEGATE BEQ 2$ 1$: PRINT$ #FDOUT,IOERR JMP GOTOIT 2$: CLOSE$ #FDOUT,IOERR JMP GOTOIT .SBTTL SUBROUTINES .SBTTL READ A LINE READL: MOV R4,POLD CLR R3 TST SKIPR BEQ R MOV OVER,R1 MOVB #'>,-(R1) MOVB #'-,-(R1) MOVB #'-,-(R1) CLR SKIPR BR CONT R: GET$ #FDIN,#BUF,#202. MOV FDIN+F.NRBD,R1 ADD #BUF,R1 MOVB #15,(R1) BIT FDIN+F.ERR,#IE.EOF BNE EOT MOV #BUF,R1 CONT: INC R4 MOV #10,R5 ;***** NEXTC: MOVB (R1),R0 SUB #15,R0 BGT MOVE CMP #-1,R0 BEQ IGNORE ADD R2,R0 BGT EOL BEQ EOL ADD R2,R0 BGT EOL BEQ TAB IGNORE: INC R1 BR NEXTC EOT: CMP LINE,LMAX BEQ PRE E1: CLRB (R4)+ DEC LINE BGT E1 E2: INC ALL RTS PC PRE: INC COL CLR LINE ; DEC CMAX ;WHY??????????? ADD R2,AVAIL BR E2 TAB: CMP R3,R5 BLO FOUND ADD #10,R5 ;***** BR TAB FOUND: MOVB #SPACE,R0 INC R1 S: MOVB R0,(R4)+ INC R3 CMPB R3,WIDE BHIS TOWIDE CMPB R3,R5 BLO S BR NEXTC MOVE: MOVB (R1)+,(R4)+ INC R3 CMPB R3,WIDE BLO NEXTC TOWIDE: BIT #SW.TR,SWITCH BNE EOL ;NO CONTINUATION CMPB (R1),#15 BEQ EOL MOV R1,OVER INC SKIPR EOL: MOVB R3,@POLD RTS PC .SBTTL WRITE A PAGE PRINTV: CLR R0 MOV AVAIL,R1 MOV CMAX,R3 DIV R3,R0 ADJ: MOVB C-1(R3),R1 ADD R0,R1 MOVB R1,C-1(R3) DEC R3 BNE ADJ PRINT: MOV LMAX,LINE MOV #SPACE,R5 ENTER R0,R1,R2 MOV #ZZ,R0 MOV PAGEN,R1 MOV #1,R2 CALL $CBDMG LEAVE MOVB ZZ+3,PAGE CMPB PAGE,#'0 BNE XYZ MOVB #SPACE,PAGE XYZ: MOVB ZZ+4,PAGE+1 BIT #SW.NH,SWITCH ;OMIT HEADER? BNE 1$ ; YES PUT$ #FDOUT,#HEADER,#LH,IOERR MOVB #14,HEADER PUT$ #FDOUT,#DFN+7,#1,IOERR BR 2$ 1$: PUT$ #FDOUT,#FORM,#2,IOERR MOVB #14,FORM 2$: INC PAGEN NEWL: MOV #L,PL MOV #C,PCC MOV CMAX,COL MOV #BUFA,R1 NEWC: MOV @PL,R4 MOVB (R4)+,R0 MOVB R0,R3 BEQ B8 B6: MOVB (R4)+,(R1)+ DEC R0 BNE B6 B8: MOV R4,@PL DEC COL BLE CRLF MOVB @PCC,R0 SUB R3,R0 INC R0 B7: MOVB R5,(R1)+ ;IE SPACE DEC R0 BGT B7 MOVB #041,(R1)+ MOVB #40,(R1)+ ADD R2,PL ;IE #2 INC PCC BR NEWC CRLF: SUB #BUFA,R1 PUT$ #FDOUT,#BUFA,R1,IOERR DEC LINE BGT NEWL RTS PC .SBTTL CSI BLOCK & COMMAND STRING DUM: .BLKB 10 BUF: .BLKB 202. POUT: .WORD BUFA BUFA: .BLKB 202. .SBTTL VARIABLES AVAIL: .WORD 0 LINE: .WORD 0 COL: .WORD 0 CMAX: .WORD 0 MAX: .WORD 0 LMAX: .WORD 0 SAVE: .WORD 0 OVER: .WORD 0 WIDE: .WORD 0 SKIPR: .WORD 0 ALL: .WORD 0 POLD: .WORD 0 SLINE: .WORD 0 PP: .WORD 0 PL: .WORD 0 PCC: .WORD 0 L: .BLKW 20 C: .BLKB 20 OCOL: .WORD 204 WIDTH: .BYTE 204,101,52,37,30,24,22,20,16 .SBTTL SWITCHES .EVEN SWITCH: .WORD 0 ;SWITCH FLAGS .SBTTL TEXT STRINGS VERSON: .ASCII /FLY VER.1/ VERLEN=.-VERSON .EVEN PAGEN: .WORD 0 ZZ: .WORD 0,0,0 HEADER: .BYTE 14 DASH: .BLKB 64 NAME: .BLKB 26 MORED: .BLKB 43 DATE: .BLKB 11 .ASCII / PAGE / PAGE: .ASCII / / LH=.-HEADER .EVEN FORM: .BYTE 14,40 NEGATE: .WORD 0 DFN: .ASCII /FLY.DMP / ;PCC -> C & PL -> L FOR CURRENT COLUMN ;C CONTAINS COLUMN WIDTH ;L CONTAINS ADDRESS IN BLOCK OF START OF CURRENT LINE ;BLOCK CONTAINS PACKED LINES ; FIRST BYTE IS #CHARACTERS TO FOLLOW ; FOLLOWED BY CHARACTERS FOR LINE .END START