;-*-MIDAS-*- TITLE LPT SIMULATOR FOR MEMOREX A=1 B=2 C=3 D=4 E=5 P=17 DSKBI=10 ;FILE INPUT TTYI=11 ;CONTROLLING TERMINAL IN AND OUT TTYO=12 OUTO=13 ;IMAGE MODE TO OUTPUT TERMINAL OUTI=14 ;INPUT FROM OUTPUT TERMINAL LPDL==40 ;LENGTH OF PDL. IBSZ==40 OBSZ==40 DEFINE SYSCAL A,B .CALL [SETZ ? SIXBIT \A\ ? B ((SETZ))] TERMIN SNOOZE: LOC 42 JSR TSINT LOC SNOOZE GO: MOVE P,[-LPDL,,PDL-1] PUSHJ P,TTYOPN ;ALSO GETS TTY TYPE AND SETS TTYSTS. .BREAK 12,[..RJCL,,JCLBUF] SETOM CTLCF ;IF COMMAND IS VIA JCL, EXIT AFTERWARD. SKIPE JCLBUF JRST RDSP1 ;HERE TO RESTART AFTER ABORTING OR FINISHING A LISTING. RDSPEC: PUSHJ P,TTYOPN ;REOPEN TTY CHANNELS AND RESET TTYST1, TTYST2. MOVE P,[-LPDL,,PDL-1] .LOGOUT SETZM CTLCF PUSHJ P,RDLINE ;READ COMMAND FROM TTY. RDSP1: LDB A,[350700,,JCLBUF] CAIN A,^M ;LINE IS NULL => REPROMPT OR SUICIDE (IF WAS ^C). JRST DONE1 MOVE A,[440700,,JCLBUF] MOVEM A,JBPT ;SET UP DEFAULTS MOVSI A,'DSK MOVEM A,IDEV MOVSI A,'TTY MOVEM A,ODEV .SUSET [.RSNAME,,A] MOVEM A,ISNAME MOVEM A,OSNAME MOVSI A,(SIXBIT \>\) SETZM IFN1 SETZM OFN1 MOVEM A,IFN2 MOVEM A,OFN2 PUSHJ P,FR ;SKIPS IF NON-NULL FILE SPEC JRST [ MOVEI A,[ASCIZ \ No file specified?\] PUSHJ P,7TYPE JRST RDSPEC] CAIE A,"_ JRST [ PUSHJ P,ISTORE MOVSI 5,'TTY SETZB 6,7 SETZ 10, PUSHJ P,OSTORE JRST OPN1] PUSHJ P,OSTORE PUSHJ P,FR ;READ INPUT SPEC JRST [ MOVEI A,[ASCIZ \ No input file specified?\] PUSHJ P,7TYPE JRST RDSPEC] PUSHJ P,ISTORE OPN1: PUSHJ P,OPENI OPN2: MOVSI A,'TTY PUSHJ P,OPENO SYSCAL TTYSET,[ 1000,,OUTO [120202,,020202] [130212,,121212] [2001,,0]] JRST [ MOVEI A,[ASCIZ \ Can only output to a terminal!\] PUSHJ P,7TYPE JRST RDSPEC] SYSCAL OPEN,[ 1000,,OUTI ? 5000,,.UII ODEV ? OFN1 ? OFN2 ? OSNAME] .LOSE %LSFIL SKIPE AUTOFF ;IF TTY HAS AUTOMATIC FF, JUST DO ONE. JRST [ SETZM VPOS PUSHJ P,OFFPH1 JRST OPN3] MOVEI A,[ASCIZ \ Adjust paper to top of page and type any char on output console. Type (on either console) ^S to abort, or ^G to abort and kill LPX. \] PUSHJ P,7TYPE .IOT OUTI,A OPN3: .SUSET [.SIMSK2,,[<1_OUTI>]] JRST STARTO ;STORE THE FILENAMES IN 5 THRU 10 (PUT THERE BY FR) IN IDEV - ISNAME ISTORE: SKIPE 5 MOVEM 5,IDEV SKIPE 6 MOVEM 6,IFN1 SKIPE 7 MOVEM 7,IFN2 SKIPE 10 MOVEM 10,ISNAME POPJ P, ;STORE THE FILENAMES IN 5 THRU 10 (PUT THERE BY FR) IN ODEV - OSNAME OSTORE: SKIPE 5 MOVEM 5,ODEV SKIPE 6 MOVEM 6,OFN1 SKIPE 7 MOVEM 7,OFN2 SKIPE 10 MOVEM 10,OSNAME POPJ P, ;HERE TO BEGIN PRINTING THE FILE. STARTO: SETZM VPOS SETZM HPOS OLOOP: PUSHJ P,READC CAIN A,^L ;CHECK FOR ^L FIRST, SO A ^L WHEN WE ARE AT THE BOTTOM MARGIN JRST [ PUSHJ P,OFF JRST OLOOP] ;DOESN'T CAUSE A BLANK PAGE. MOVE B,VPOS CAML B,VSIZE ;IF ABOUT TO TYPE ON LINE PAST BOTTOM MARGIN, PUSHJ P,OFF ;ADVANCE TO NEW PAGE. CAIGE A,40 JRST OCTL CAIN A,177 JRST OCTL ONRM: PUSHJ P,ONRMC JRST OLOOP ;HERE TO OUTPUT A CTL CHAR OR RUBOUT. OCTL: CAIN A,33 JRST [ MOVEI A,"$ ;OUTPUT ALTMODE AS $. JRST ONRM] PUSH P,[OLOOP] CAIN A,^I ;TAB, BS, FF, CR AND LF ARE SPECIAL. JRST OTAB CAIN A,^H JRST OBS CAIN A,^M JRST OCR CAIN A,^J JRST OLF PUSH P,A ;OTHER CONTROLS COME OUT AS UPARROW-WHATEVER. MOVEI A,"^ PUSHJ P,ONRMC POP P,A ADDI A,100 JRST ONRMC OCR: SETZM HPOS MOVEI A,^M JRST WRITEC OBS: SKIPE HPOS SOS HPOS JRST WRITEC OTAB: MOVE B,HPOS TRZ B,7 ADDI B,10 CAMLE B,HSIZE MOVE B,HSIZE CAMG B,HPOS JRST [ PUSHJ P,OCRLF JRST OTAB] CAME B,HSIZE JRST [ MOVEM B,HPOS JRST WRITEC] SUB B,HPOS ADDM B,HPOS MOVEI A,40 OTAB1: PUSHJ P,WRITEC SOJG B,OTAB1 POPJ P, ;OUTPUT A NORMAL 1-POSITION PRINTING CHARACTER, CONTINUING LINE IF NECESSARY. ONRMC: MOVE B,HPOS CAMLE B,HSIZE PUSHJ P,OCRLF AOS HPOS ;OUTPUT CHARACTER IN A TO OUTPUT DEVICE. WRITEC: SKIPE SFTWR ;ON SOFTWARE TTY, QUOTE EACH CHAR WITH A %TDQOT. JRST [ PUSH P,A ;THIS PREVENTS LOSSAGE IF GOING THROUGH A CRTSTY. MOVEI A,%TDQOT PUSHJ P,WRITE1 POP P,A JRST WRITE1] WRITE1: IDPB A,OPTR SOSLE OCNT POPJ P, ;FORCE OUT OUR OUTPUT BUFFER. WRITEB: PUSH P,A PUSH P,B MOVEI B,OBSZ*4 SUB B,OCNT MOVE A,[441000,,OBUF] MOVEM A,OPTR SYSCAL SIOT,[ MOVEI OUTO ? A ? B] .LOSE %LSFIL MOVEI A,OBSZ*4 MOVEM A,OCNT POP P,B POP P,A POPJ P, ;READ A CHARACTER FROM THE INPUT FILE. READC: SOSGE ICNT PUSHJ P,READB ILDB A,IPTR POPJ P, ;REFILL THE INPUT BUFFER. READB: SKIPE EOFFLG JRST DONE PUSH P,A PUSH P,B MOVE A,IPTR ;MOVE THE WORD OF READ-AHEAD MOVE B,1(A) MOVEM B,IBUF ;TO THE TOP OF THE BUFFER. MOVE A,[440700,,IBUF] MOVEM A,IPTR MOVE A,[1-IBSZ,,IBUF+1] .IOT DSKBI,A ;FILL THE REST OF THE BUFFER. MOVEI B,-IBUF(A) IMULI B,5 ;PUT # OF CHARS NOW IN BUFFER IN ICNT. MOVEM B,ICNT JUMPGE A,READB1 ;DIDN'T FILL IT ALL => SETOM EOFFLG ; THIS IS LAST STUFF, EOF AT NEXT READB. SOS A HRLI A,010700 ;ALSO FLUSH PADDING (^@ OR ^C) IN LAST WORD. READB2: LDB B,A CAIE B,^C JUMPN B,READBX SOS ICNT ;SIMPLY DON'T INCLUDE THEM IN THE # CHARS. ADD A,[70000,,] JUMPGE A,READB2 ;DON'T TRY TO FLUSH PADDING EXCEPT FROM LAST WORD. JRST READBX READB1: MOVNI B,5 ;GOT A FULL BUFFER => REMOVE LAST WORD FROM # CHARS, ADDM B,ICNT ;SO THAT IT WILL BE LEFT AS READ-AHEAD FOR THE NEXT READB. ;THIS IS SO THAT NO WORD IS PROCESSED UNTIL WE KNOW WHETHER ;IT IS THE LAST WORD OF THE FILE OR NOT. READBX: SOS ICNT ;COMPENSATE FOR THE FACT THAT WE DON'T SOS AFTER RETURNING POP P,B ;FROM READB. POPAJ: POP P,A POPJ P, ;DO A CRLF ON THE TERMINAL. OCRLF: PUSH P,A PUSHJ P,OCR PUSHJ P,OLF JRST POPAJ ;DO A LINEFEED ON THE TERMINAL. OLF: MOVEI A,^J AOS B,VPOS JRST WRITEC ;DO A FORMFEED ON THE TERMINAL. OFF: SKIPE AUTOFF JRST OFFPHY PUSH P,A MOVE B,VSIZE ;HERE ON TERMINAL WITHOUT HARDWARE FF. ADD B,VSPACE ;LF VSIZE+VSPACE-VPOS TIMES. SUB B,VPOS MOVEI A,^J JUMPE B,OFF1 PUSHJ P,WRITEC SOJG B,.-1 OFF1: SETZM VPOS POP P,A POPJ P, ;HERE TO FORMFEED ON A TERMINAL WITH HARDWARE FOR IT. OFFPHY: PUSH P,A MOVEI A,^J PUSHJ P,WRITEC ;OUTPUT A ^J FIRST, TO MAKE OUTPUT HAVE CRLF. POP P,A OFFPH1: PUSH P,A ;ENTER HERE AT START OF LISTING. MOVEI A,^L PUSHJ P,WRITEC MOVE B,VSIZE ;AFTERWARD, SEE HOW MANY LINES THE FF WILL MOVE THE PAPER, ADD B,VSPACE SUB B,VPOS IMUL B,FFPAD ;SEE HOW MANY PADDING CHARS ARE NEEDED, JUMPE B,OFF1 MOVEI A,177 OFF3: PUSHJ P,WRITEC ;AND OUTPUT THAT MANY. SOJG B,OFF3 JRST OFF1 ;COME HERE AT END OF INPUT FILE. DONE: SKIPN VPOS SKIPE HPOS ;FEED PAGE UNLESS THAT WAS JUST DONE. PUSHJ P,OFF PUSHJ P,WRITEB .CLOSE OUTO, .CLOSE OUTI, .CLOSE DSKBI, .CLOSE TTYI, .CLOSE TTYO, DONE1: SKIPN CTLCF JRST RDSPEC ;COME HERE FOR ^G OR ^C, TO COMMIT SUICIDE. DIE: .LOGOUT .BREAK 16,140000 CPOPJ: POPJ P, 7TYPE: HRLI A,440700 LP6: ILDB C,A JUMPE C,CPOPJ .IOT TTYO,C JRST LP6 ;READ FILE SPEC RDLINE: MOVEI A,[ASCIZ \ _\] PUSHJ P,7TYPE MOVE A,[440700,,JCLBUF] SETZ D, RDLIN1: .IOT TTYI,C CAIE C,^D CAIN C,^U JRST RDLINE CAIN C,^C ;^C TURNS INTO ^M, BUT SETS FLAG TO CAUSE SUICIDE. JRST [ SETOM CTLCF MOVEI C,^M JRST .+1] CAIN C,^M JRST [ IDPB C,A POPJ P,] CAIE C,177 JRST [ IDPB C,A AOJA D,RDLIN1] SOJL D,RDLINE LDB C,A ADD A,[70000,,] SKIPGE A SUB A,[430000,,1] SKIPN DISPLA JRST [ .IOT TTYO,C JRST RDLIN1] CAIGE C,40 PUSHJ P,RUBOUT PUSHJ P,RUBOUT JRST RDLIN1 RUBOUT: IRPC X,,[X] .IOT TTYO,["X] TERMIN POPJ P, FR: MOVE B,[ILDB A,JBPT] MOVE C,[-3,,["/ ? "_ ? ^M]] JRST FNR"GETFIL .BEGIN FNR ;ITS STYLE COMMAND LINE SCANNER ; NON-SKIP RETURN FOR NULL FILE SPEC ;CALL WITH PUSHJ P,FNR"FNR ;CLOBBERS ACS WITH RECKLESS ABANDON ;ORIGINALLY FROM AI:PJ;FNR >, HACKED BY RLB ;MODIFIED BY RMS TO READ SWITCHES, FOR LPX'S SAKE. BREAK==1 ;RETURNS WITH CHARACTER THAT BROKE SCAN IN==2 ;XCT'ING CAUSES NEXT CHARACTER TO APPEAR IN BREAK BRKTAB==3 ;AOBJN POINTER TO BREAK TABLE SCOTAB==4 ;AOBJN POINTER TO "SINGLE CHAR OBJECT" TABLE DEV==5 ;RETURNS DEV,FN1,FN2,SNAME FN1==DEV+1 FN2==DEV+2 SNAME==DEV+3 AC==11 CH==12 ACPTR==13 TEMP==14 LIMBO==15 ;SCANNER READ AHEAD CHARACTER ;CANNOT LEAVE NAME UNTIL ZERO GETCC: SKIPN BREAK,LIMBO ;GET CHAR FOR COMMAND LINE SCANNER XCT IN SETZM LIMBO CPOPJ: POPJ P, NAME: PUSHJ P,GETCC ;BREAK OFF WORD FROM INPUT STREAM CAIE BREAK,40 ;IGNORE LEADING SPACES CAIN BREAK,11 ;TABS TOO JRST NAME MOVE ACPTR,[440600,,AC] TDZA AC,AC NAME1: PUSHJ P,GETCC PUSHJ P,BRKTST POPJ P, ;FOUND A BREAK CHARACTER NAME2: CAIL BREAK,140 ;CONVERT LC TO UPPER. SUBI BREAK,40 CAIGE BREAK,40 ;IGNORE CONTROL CHARS. JRST NAME1 MOVEI CH,-40(BREAK) TLNE ACPTR,770000 ;IGNORE EVERYTHING AFTER 6 CHARACTERS IDPB CH,ACPTR JRST NAME1 ;^Q QUOTES NEXT CHARACTER ;FAILS TO SKIP ON BREAK CHARACTER BRKTST: CAIN BREAK,11 MOVEI BREAK,40 CAIN BREAK,21 ;^Q JRST [ PUSHJ P,GETCC JRST BRKT1] CAIN BREAK,40 POPJ P, CAIE BREAK,": CAIN BREAK,"; POPJ P, SKIPL TEMP,BRKTAB JRST BRKT1 CAMN BREAK,(TEMP) POPJ P, AOBJN TEMP,.-2 BRKT1: AOS (P) POPJ P, ;THIS ROUTINE SCANS COMMAND LINE FOR FILE SPECIFICATION GETFIL: SETZB FN1,FN2 SETZB DEV,SNAME SETZM LIMBO HRRZS (P) GETF1: PUSHJ P,NAME ;BREAK OFF FIRST NAME JUMPE AC,GETF2 HRROS (P) ;NON-NULL NAME => WE SHOULD SKIP RETURN. CAIN BREAK,": JRST [ MOVE DEV,AC JRST GETF1] CAIN BREAK,"; JRST [ MOVE SNAME,AC JRST GETF1] ;THIS MUST BE FN1 OR FN2 JUMPN FN1,[ MOVE FN2,AC JRST GETF2] MOVE FN1,AC GETF2: CAIN BREAK,"/ JRST SWITCH CAIE BREAK,^M CAIN BREAK,"_ CAIA JRST GETF1 SKIPGE (P) AOS (P) POPJ P, ;COME HERE AFTER A "/" IS READ, IN THE MIDDLE OF A FILESPEC. SWITCH: SETZ AC, SWIT1: PUSHJ P,GETCC CAIL BREAK,140 SUBI BREAK,40 CAIN BREAK,"A JRST [ SETOM AUTOFF MOVEM AC,FFPAD JRST GETF1] CAIN BREAK,"P JRST [ MOVEM AC,VSIZE JRST GETF1] CAIN BREAK,"S JRST [ MOVEM AC,VSPACE JRST GETF1] CAIL BREAK,"0 CAILE BREAK,"9 JRST [ MOVEI A,[ASCIZ \ Invalid switch - Must be /A, /P, or /S.\] PUSHJ P,7TYPE JRST RDSPEC] IMULI AC,10. ADDI AC,-"0(BREAK) JRST SWIT1 .END OPENO: SYSCAL OPEN,[ 1000,,OUTO 5000,,.UIO+%TJCTN+%TJMOR ;ORDINARY IMAGE MODE, NO CONTINUATION. ODEV ? OFN1 ? OFN2 ? OSNAME] JRST [ MOVEI A,[ASCIZ \CAN'T OPEN OUTPUT DEVICE\] PUSHJ P,7TYPE SUB P,R70+1 JRST RDSPEC] SYSCAL CNSGET,[ 1000,,OUTO 2000,,A 2000,,HSIZE 2000,,TCTYP] .LOSE %LSFIL MOVE A,TCTYP CAIE A,%TNSFW ;IF SOFTWARE TTY, USE SUPERIMAGE OUTPUT AND QUOTE WITH %TDQOT. JRST OPENO1 SETOM SFTWR SYSCAL OPEN,[ %CLIMM,,OUTO ? %CLBIT,,.UIO+%TJSIO ? ODEV ? OFN1 ? OFN2 ? OSNAME] .LOSE %LSFIL ;OPEN SUPERIMAGE OUTPUT CHANNEL. OPENO1: MOVE A,[441000,,OBUF] MOVEM A,OPTR MOVEI A,OBSZ*4 MOVEM A,OCNT POPJ P, OPENI: SYSCAL OPEN,[1000,,DSKBI ? 5000,,6 IDEV ? IFN1 ? IFN2 ? ISNAME] JRST [ MOVEI A,[ASCIZ \ CAN'T OPEN INPUT FILE\] PUSHJ P,7TYPE SUB P,R70+1 JRST RDSPEC] SETZM OCNT SETZM EOFFLG MOVE A,[350700,,IBUF-1] MOVEM A,IPTR HRROI A,IBUF .IOT DSKBI,A POPJ P, TTYOPN: .OPEN TTYI,[20,,'TTY] .VALUE .OPEN TTYO,[21,,'TTY] .VALUE SYSCAL TTYSET,[ 1000,,TTYI [232222,,222222] [232222,,221232]] .VALUE SYSCAL CNSGET,[ 1000,,TTYI 2000,,A 2000,,A 2000,,A] .VALUE ANDI A,3 MOVEM A,DISPLA .SUSET [.SMSK2,,[<1_TTYI>]] .SUSET [.SPICLR,,[-1]] POPJ P, TSINT: 0 ;GETS INTERRUPT WORD IPCLOK: 0 ;GETS LOC INTERRUPTED FROM PUSH P,D PUSH P,E MOVE D,TSINT TRNE D,<1_OUTI> JRST [ MOVEI E,OUTI JRST TTYINT] TRNE D,<1_TTYI> JRST [ MOVEI E,TTYI JRST TTYINT] INTEX: POP P,E POP P,D .DISMISS IPCLOK TTYINT: .ITYIC E, ;HERE FOR INTERRUPT ON A TERMINAL, E HAS CHANNEL. JRST INTEX CAIE E,^G CAIN E,^S CAIA JRST INTEX .RESET OUTI, ;IF IT'S AN ABORT, FLUSH ALL INPUT. .RESET TTYI, CAIN E,^S .DISMIS [RDSPEC] .DISMIS [DIE] VSIZE: 60. ;# OF REAL DATA LINES PER PAGE. VSPACE: 6 ;# OF BLANK LINES BETWEEN PAGES. AUTOFF: 0 ;NONZERO => TERMINAL HAS HARDWARE FORMFEED. FFPAD: 0 ;# OF RUBOUTS TO PAD EACH HARDWARE FF WITH. HSIZE: 0 ;WIDTH OF TERMINAL. TCTYP: 0 SFTWR: 0 ;NONZERO => SOFTWARE TTY, USE SUPERIMAGE OUT AND %TDQOT. VPOS: 0 ;CURRENT VERT POSITION ON PAGE. HPOS: 0 ;CURRENT COLUMN IN LINE. DISPLA: 0 ;NONZERO => TTY: (NOT OUTPUT DEV!) IS A DISPLAY. CTLCF: 0 ;NONZERO => SUICIDE ON FINISHING THIS FILE. IDEV: 0 IFN1: 0 IFN2: 0 ISNAME: 0 ODEV: 0 OFN1: 0 OFN2: 0 OSNAME: 0 OPTR: 0 ;BP TO STUFF OBUF OCNT: 0 ;# CHARS EMPTY IN OBUF. OBUF: BLOCK OBSZ ;WE USE 8-BIT BYTES IN OBUF. ;THIS IS BECAUSE FOR SOFTWARE TTYS WE DO SUPERIMAGE OUT. IPTR: 0 ;BP TO FETCH FROM IBUF ICNT: 0 ;# CHARS OF DATA LEFT IN IBUF. IBUF: BLOCK IBSZ EOFFLG: 0 ;NONZERO => HAVE ALREADY REACHED EOF AND FLUSHED PADDING. JBPT: 0 ;BYTE POINTER FOR COMMAND LINES R70: 0,,0 1,,1 JCLBUF: BLOCK 20 PDL: BLOCK LPDL PAT: PATCH: BLOCK 30 PATCHE: -1 END GO