TITLE SCROLL SAVER ; Written for PDS-1D compatible IMLACs, uses DMS display addressing ; modification. Includes ARDS graphics simulator. ; This source code was reconstructed from an Imlac block loader file ; from Purdue University, by taking the ML file IMLAC; SSV 52 dated ; 1973-01-07 and editing it to match. ; 22 (06/07/74) minor fixes to PXMIT and SPXMIT. %VERSIO==22. .INSRT IMSRC;IMDEFS > .ADDR.=1 REPT=2000 CTRL=1000 SHIFT=400 LEFT=40 ; LEFTMOST CHARACTER POSITION TOP=1700 ; TOPMOST CHARACTER POSITION PXACK=6 ; IMEDIT'S ACK CHARACTER CRIKY=17777 ; HIGH DISPLAY LIST ADDRESS ; MACRO FOR DISPATCH TABLES DEFINE DSP DISCOD,DISGO DISCOD DISGO TERMIN LOC 1 DAC ASAVE RAR 1 DAC LSAVE ; SAVE ON INTERRUPT JMP AFT100 ; LOCATIONS 24 THROUGH 37 ARE DEFINED TO CONTAIN ; CONSTANTS AND VARIABLES OF INTEREST TO PROGRAMS THAT ; MIGHT BE OVERLAID ON TOP OF SSV LOC 24 JMSTAB: LIST40 ; 24/ TABLE OF CHARACTER DJMSS BUFEND: CRIKY ; 25/ END OF SSVS DISPLAY BUFFER ; PROGRAM START UP LOCATIONS LOC 100 JMP GO100 ; NON ERASING STARTUP JMP INIT ; ERASING STARTUP DSTART: 0 ; RESTART DISPLAY (ONLY ENABLED INTERRUPT) DCF SCF DLA DON I JMP DSTART ; here for refresh interrupt AFT100: LAC [DORIG] JMS DSTART TAUTO: ISZ TICKER ; TICK BOMB JMP GLV CLA ; IT EXPLODED HERE KRB ; GET CURRENT KEYBOARD SAM KCHAR ; SEE IF KEY HELD DOWN LONG ENOUGH JMP GLV ; NO LWC 1 DAC TICKER ; YES SET 10 PER SECOND REPEAT ONCE IT BLOWS UP LAC [JMP CONTIN] DAC LOOPY ; IMPURE DISPATCH, THE ONLY WAY !! GLV: JMP RESTRZ DUD: ISZ TWITCH ; TICK THE TWITCHY JMP RESTRZ ; NORMAL RESTORE LWC 12 DAC TWITCH ; RESET THE TWITCH TICKER LAC DCURT ; TWITCH THE TWTICHY XOR [DJMP DFORM#DNOP,] DAC DCURT RESTRZ: JMS NUMZIT ; DISPLAY LENGTH OF BUFFER LEFT LAC LSAVE ; RESTORE PROGRAM CONTROL RAL 1 LAC ASAVE ION I JMP 0 ASAVE: 0 LSAVE: 0 TICKER: 0 TWITCH: -12 INITA: 0 ; SUBROUTINE INIT CALL POINT INIT: JMS ZTTY ; GET IN TTY MODE JMS UCASE ; GET IN UPPER CASE MODE JMS ATON ; GET IN AUTO REPEAT MODE JMS CLRS ; CLEARS THE SCREEN JMP GOBOTH GO100: LAW [0] ; FWEEP INTERRUPT (IMLAC SAYS IT HELPS) JMS DSTART ; START DISPLAY DOF ; AND THEN TURN OFF FOR POWER UP GOBOTH: LAW REF ; SCREEN REFRESH INTERRUPT ARM ION LOOPY: KSN ; SKIP NO KEYBOARD JMS KEYIN RSN ; SKIP NO TTY JMS TTYIN JMP LOOPY CLRS: 0 ; CLEAR THE SCREEN SUBROUTINE CLA I DAC [CURRY-1] ; SET THE LIST BOUNDARY I DAC BUFEND ; SET THE DHLT DAC LNCNT' ; SET ZERO LINES ON SCREEN DAC LNPOS' ; POINTING AT THE FIRST LINE LAC [DJMS DCURT,] I DAC [CURRY] ; SET THE INLINE CURSOR LAC BUFEND JMS ADRJMP I DAC [CURRY+1] ; SET BUFFER DJMP LAC [DLYA TOP,] I DAC [DARROW] ; SET THE LINE POSITION CURSOR LAC [DJMP CURRY] I DAC [TWANG] ; SET THE VARIABLE START POINTER LAC BUFEND DAC TWONG' ; SET THE VARIABLE END POINTER DAC CHRPNT' ; CURRENT CHARACTER POINTER LAC [CURRY] DAC CURPNT' ; CURSOR SHOVE POINTER LAC [CURRY-1] DAC TWONK' ; SET THE VARIBLE START-1 POINTER I JMP CLRS HOME: 0 ; FIND END OF LIST JMS RTAR JMP .-1 ; RIGHT ARROW FOREVER I JMP HOME HOMEUP: 0 ; FIND BEGINNING OF LIST JMS LFAR JMP .-1 ; LEFT ARROW FOREVER I JMP HOMEUP UPAR: 0 ; MOVES CURSOR UP ONE LINE JMS LBEG ; TO BEGINNING OF CURRENT LINE JMS LFAR ; END OF PREVIOUS LINE JMS LBEG ; TO ITS BEGINNING I JMP UPAR LBEG: 0 ; MOVES CURSOR TO BEGINNING OF CURRENT LINE LWC 1 DAC ARFLG JMS LFAR ; CONTINUE UNTIL BUMPED JMP .-1 CLA DAC ARFLG ; MAKE SURE FLAG ISN'T SET FOR OTHER ROUTINES I JMP LBEG DNAR: 0 ; MOVES CURSOR DOWN ONE LINE LWC 1 DAC ARFLG JMS RTAR JMP .-1 ; CONTINUE CLA DAC ARFLG ; MAKE SURE FLAG ISN'T SET AFTER THIS ROUTINE JMS RTAR I JMP DNAR I JMP DNAR ; ALLOW FOR IDIOCY OF TYPIST DOWN: 0 ; SAME AS DNAR EXCEPT WILL INSERT CR-LF TO MOVE DOWN LWC 1 DAC ARFLG ; SET FLAG JMS RTAR JMP .-1 ; RTAR SKIP RETURNS ONE BEFORE LINE FEED CLA DAC ARFLG ; NULL FLAG JMS RTAR ; JUMP OVER LAST LINE FEED I JMP DOWN ; EXIT HERE IF NO CR-LF PAIR IS NEEDED TO MOVE DOWN LWC 1 ADD CURPNT DAC TEMPNT LAC [DJMS D015,] I SAM TEMPNT JMS INSERT JMS LNFD I JMP DOWN RTAR: 0 ; MOVES CURSOR ONE RIGHT LAW 1 ADD CURPNT DAC TEMPNT' IAC DAC TEM2' LAW 1 ADD CHRPNT DAC TEMP2' I LAC CHRPNT ASN ; END OF DLIST? JMP RFAIL ; YES SAM [DJMS D012,] JMP RTDO ISZ ARFLG ; SKIP ON END OF LINE? JMP RTEST ; NO RFAIL: ISZ RTAR I JMP RTAR ; ERROR SKIP RETURNS RTEST: JMS ILNPOS SUB [34.] ; GETTING HIGH? ASP JMP RTDO ; NO JMS BOTUP ; YES, DO A ROLLUP OF THE SCREEN BY 10 LINES JMS TOPUP RTDO: LAC TEMP2 JMS ADRJMP I DAC TEM2 ; NEW DJMP I LAC CHRPNT I DAC CURPNT ; MOVE CHAR UP LAC [DJMS DCURT,] I DAC TEMPNT ; NEW DJMS ISZ CHRPNT ISZ CURPNT ; UPDATE POINTERS I JMP RTAR LFAR: 0 ; MOVES CURSOR ONE LEFT LWC 1 ADD CURPNT DAC TEMPNT LWC 1 ADD CHRPNT DAC TEMP2 I LAC TEMPNT ASN ; START OF DLIST? JMP LFAIL SAM [DJMS D012,] JMP LFDO+1 ISZ ARFLG ; FAIL ON BEGINNING OF LINE? JMP LTEST ; NO LFAIL: ISZ LFAR I JMP LFAR ; SKIP RETURN LTEST: JMS DLNPOS SUB [11.] ASM ; GETTING LOW ? JMP LFDO ; NO JMS TOPDN JMS BOTDN ; YES, ROLL DOWN THE SCREEN BY 10 LINES LFDO: I LAC TEMPNT I DAC TEMP2 ; MOVE CHAR DOWN LAC TEMP2 DAC CHRPNT ; UPDATE CHRPNT JMS ADRJMP I DAC CURPNT ; NEW DJMP LAC [DJMS DCURT,] I DAC TEMPNT ; NEW DJMS LAC TEMPNT DAC CURPNT ; UPDATE CURPNT I JMP LFAR ARFLG: 0 INSERT: 0 ; INSERT CHARACTER ROUTINE XAM CHRPNT SUB [1] XAM CHRPNT I DAC CHRPNT ; PUT CHAR IN THE LIST LAC CURPNT DAC 10 LAC CHRPNT JMS ADRJMP I DAC 10 ; NEW DJMP JMS BUFCK ; CHECK IF BUFFER FULL JMS RTAR I JMP INSERT DELETE: 0 ; DELETE CHARACTER ROUTINE I LAC CHRPNT ASN I JMP DELETE ; EXIT FOR DELETING END OF LIST SAM [DJMS D012,] JMP DELI JMS DLNCNT ; DELETING A LINE FEED SAM [33.] ; GETTING LOW? JMP DELI JMS BOTUP ; BRING BOTTOM UP JMP DELI JMS TOPDN ; ELSE PULL TOP DOWN NOP DELI: ISZ CHRPNT ; MOVE POINTER DOWN LAC CURPNT DAC 10 LAC CHRPNT JMS ADRJMP I DAC 10 ; NEW DJMP I JMP DELETE BUFCK: 0 ; BUFFER SIZE CHECKER LWC 5 ADD CHRPNT SUB CURPNT DAC TBUF' ; FIND FREE SPACE IN BUFFER SAM [499.] ; READY TO WARN ? JMP ZROCK LAC MODEF ASN BEL ; WARN EDIT MODE USERS ZROCK: ISZ TBUF ; BUFFER CHOCKING? I JMP BUFCK LAC MODEF ; TIME FOR THE BIG CEASE! DELETES THE FIRST TEN LINES ASN BEL LWC 10. DAC LOOP ; SET LOOP FOR 10 LINE SEARCH LAC [CURRY-1] DAC 10 ; SET GET POINTER DAC 11 ; SET PUT POINTER SMULCH: I LAC 10 ; MOVES REGISTER 10 THROUGH THE CHARACTER LIST SAM [DJMS D012,] JMP SMULCH ; LOOP GOES UNTIL LINE FEED FOUND ISZ LOOP JMP SMULCH ; GOES UNTIL 10 LINE FEEDS FOUND I LAC 10 ; GETS I DAC 11 ; PUTS SAM [DJMS DCURT,] ; DONE? JMP .-3 ; CHARACTER MOVING UP LOOP I LAC 10 I DAC 11 ; MOVES THE LAST CHAR, WHICH IS THE DJMP TO SECOND BLOCK I LAC [TWANG] ; LOAD STARTING DJMP JMS JMPADR ; GET ADDRESS SUB 10 ADD 11 JMS ADRJMP ; NEW DJMP I DAC [TWANG] ; NEW TWANG POINTER LAC TWONK SUB 10 ADD 11 DAC TWONK ; RESET TWONK POINTER LAC CURPNT SUB 10 ADD 11 DAC CURPNT ; RESET CURPNT POINTER I JMP BUFCK NUMZIT: 0 ; ROUTINE DISPLAYS AMOUNT OF BUFFER SPACE LEFT ON THE SCREEN CLA DAC DFLAG' ; ZERO TO KILL LEADING ZEROS LAC [DNUM1-1] DAC 17 ; OUTPUT POINTER IN 17 LWC 4 DAC LOOPIN' LAW SUBT DAC SUBPNT' LWC 4 ADD CHRPNT SUB CURPNT DAC TNUM' GOZAP: CLA XAM TNUM ; LOAD BUFFER SIZE SUBR: I SUB SUBPNT ; DIVIDE LOOP FOR BASE CONVERSION ASP JMP .+3 ISZ TNUM ; INCREMENT DIGIT COUNT JMP SUBR I ADD SUBPNT XAM TNUM ; LOAD DIGIT, STORE DIVIDEND ASZ JMP NONA ; NO SAM DFLAG ; SUPPRESS LEADING ZEROS ? JMP NONA+1 ; NO LAC [DNOP] I DAC 17 ; KILLS THAT LEADING ZERO JMP WHAMZ NONA: ISZ DFLAG ADD [LZERO] ; GET ADDRESS OF PROPER DJMP DAC GRAB' I LAC GRAB I DAC 17 ; PUT IT OUT IN THE DISPLAY LIST WHAMZ: ISZ SUBPNT ISZ LOOPIN ; CHECK FOR ALL FOUR DIGITS JMP GOZAP ; CONTINUE TO CONTINUE I JMP NUMZIT ; EXIT SUBT: 1000. ; TABLE OF POWERS OF TEN 100. 10. 1. ABPOS: 0 ; ABSOLUTE POSITIONING ROUTINE JMS TGET DAC HPOS' ; HORIZONTAL POSITION JMS TGET DAC VPOS' ; VERTICAL POSITION LAW 1 SUB VPOS ADD LNPOS ; FIND DELTA VERTICAL + = UP, - = DOWN ASN JMP GOAL2-1 ; GOOD ALREADY ASP ; MOVE UP? JMP DOWNY ; NO CIA DAC LOOPR' ; SET LOOP FOR MOVE UP UPM: JMS UPAR ISZ LOOPR JMP UPM JMP GOAL2 ; DONE MOVING UP DOWNY: DAC LOOPR DNM: JMS DOWN ; MOVES DOWN ISZ LOOPR JMP DNM JMP GOAL2 ; DONE MOVING DOWN JMS LBEG ; GET TO BEGINNING OF THE LINE GOAL2: LAW 1 SUB HPOS ASN I JMP ABPOS ; THERE ALREADY !, NORMAL EXIT DAC LOOPR ; ST LOOP FOR POSITIONING FCHEK: I LAC CHRPNT SAM [DJMS D015,] JMP .+2 ; HIT CARRIGE RETURN? JMP SPACED ; YES! ASN ; HIT THE END? JMP SPACED ; YES! JMS RTAR ; DO IT! ISZ LOOPR JMP FCHEK ; CONTINUE TO MOVE RIGHT I JMP ABPOS SPACED: LAC [DJMS D040,] JMS INSERT ; INSERT SPACES IF NO CHARS THERE ALREADY ISZ LOOPR JMP SPACED I JMP ABPOS ; DONE! LDELT: 0 ; DELETES THE CURRENT LINE JMS LBEG JMS DELRT I JMP LDELT LDELO: 0 ; DELETES LINE PLUS CR - LF JMS LDELT JMS DELETE JMS DELETE ; KILLS THE CR-LF AT THE END OF IT ALL I JMP LDELO DELUP: 0 ; DELETE TO TOP OF BUFFER JMS LFAR ; DELETES UNTIL LEFT ARROW SKIP FAILS JMP .+2 I JMP DELUP JMS DELETE JMP DELUP+1 DELDN: 0 ; DELETE TO END OF BUFFER I LAC CHRPNT ASN ; DELETES UNTIL 0 AT END REACHED I JMP DELDN JMS DELETE JMP DELDN+1 DELLF: 0 ; DELETE LEFT TO BEGINNING OF LINE JMS LFAR JMP .+2 I JMP DELLF I LAC CHRPNT SAM [DJMS D012,] JMP .+3 JMS RTAR I JMP DELLF JMS DELETE JMP DELLF+1 DELRT: 0 ; DELETE RIGHT TO END OF LINE I LAC CHRPNT ASN I JMP DELRT LAC CHRPNT DAC 10 I LAC 10 ; LOADS CONTENTS OF CHRPNT+1 SAM [DJMS D012,] JMP .+2 I JMP DELRT ; IF A LINE FEED IS 2 CHARS AWAY, EXIT! JMS DELETE ; GET THE LAST BUGGER!! JMP DELRT+1 ; HERE TO ACTUALLY DELETE ; DELETE CHARACTER TO RIGHT OF CURSOR FDELT: 0 LAC MODEF ; CONSOLE MODE ASZ JMP .+4 ; TTY MODE JMS LFAR JMS DELETE ; LOCAL OR EDIT, REMOVE CHAR I JMP FDELT LAW 177 JMS XMIT I JMP FDELT TXMIT: 0 ; KEYBOARD TRANSMITTER WITH LOCAL MODE XAM MODEF' ASM ; SKIPS ONLY IN TTY MODE JMP FEEDME ; ELSE DO LOCAL MODE KLUDGE XAM MODEF JMS XMIT ; SEND IT TO THE PDP-10 I JMP TXMIT FEEDME: XAM MODEF ; IN LOCAL MODE ISZ DNOPF' ; PDP-10 LAST TYPIST ? JMP UHNUHN ; NO DAC TEM1' ; YES, ADD A DNOP TO MARK THE DIVIDING LINE LAC [DNOP] JMS INSERT LAC TEM1 UHNUHN: SAM [015] ; PASSING A CARRIGE RETURN IN LOCAL MODE ? JMP FOOBOO ; NO, CONVERT JUST THIS CHAR JMS CVDISP ; YES, ADD A LINE FEED TO IT ! JMS LNFD I JMP TXMIT FOOBOO: JMS CVDISP I JMP TXMIT XMIT: 0 ; TRANSMIT ROUTIINE TSF JMP .-1 TPC I JMP XMIT RCRLF: 0 LAC [DJMS D015,] JMS INSERT JMS LNFD JMS UPAR I JMP RCRLF ADRJPL: 0 ; TURNS A POINTER INTO THE RIGHT LAC TWONK ; GET POINTER TO ADDRESS-1 IAC JMS ADRJMP ; MAKE IT A DJMP I DAC [TWANG] I JMP ADRJPL ADRJMP: 0 ; MAKES AN ADDRESS INTO A DJMP SUB [010000] ASM ; SKIPS IF < 10000 ADD [070000] ADD [070000] I JMP ADRJMP JMPADR: 0 ; MAKES A DJMP INTO AN ADDRESS AND [107777] ; GET RID OF NO.6 BIT ASP XOR [110000] ; TRANSFER THE 10000 BIT I JMP JMPADR ILNPOS: 0 ; INCREMENT LINE POSITION CURSOR LWC 25 I ADD [DARROW] I DAC [DARROW] ; FIX DLIST DOWNWARD ISZ LNPOS ; FIX COUNTER LAC LNPOS ; LOAD FOR RETURNING IT I JMP ILNPOS DLNPOS: 0 ; DECREMENT LINE POSITION CURSOR LAW 25 I ADD [DARROW] I DAC [DARROW] LWC 1 ADD LNPOS DAC LNPOS ; FIX COUNTER I JMP DLNPOS DLNCNT: 0 ; DECREMENT LINE COUNTER LWC 1 ADD LNCNT DAC LNCNT I JMP DLNCNT TTGLE: 0 ; CURSOR TWITCH TOGGLE LAC GLV XOR [DUD#RESTRZ] DAC GLV LAC [DNOP] DAC DCURT ; FORCES NORMAL CURSOR ON SWITCHOFF I JMP TTGLE PXMIT: 0 ; PAGE TRANSMIT ROUTINE JMS HOMEUP ; GET TO THE TOP OF THE WORLD SMOOCH: JMS CASCII ; GET ASCII VALUE OF NEXT THING IN DLIST ASZ JMP TOAD I JMP PXMIT ; NORMAL EXIT HERE TOAD: JMS XMIT ; SEND CHARACTER SAM [015] JMP RTO JMS TGET ; GET NEXT CHARACTER HERE SAM [PXACK] ; ACK CHARACTER? JMP .-2 ; NO RTO: JMS RTAR ; KEEP USER INFORMED OF PROGRESS JMP SMOOCH PXERS: 0 ; PAGE TRANSMIT WITH SCREEN CLEAR JMS PXMIT JMS CLRS I JMP PXERS LXMIT: 0 ; LINE TRANSMIT ROUTINE LAC MODEF ASP I JMP LXMIT ; PREVENTS TTY MODE HANGUP LAW 15 JMS TXMIT ; ADDS A CR TO THE LINE LLOOP: JMS LFAR ; SEARCH BACK FOR THE START OF IMLAC'S TYPINGS JMP .+2 JMP RLOOP I LAC CHRPNT ; GET CHAR SAM [DNOP] JMP LLOOP RLOOP: JMS RTAR JMS CASCII JMS XMIT SAM [015] JMP RLOOP JMS RTAR I JMP LXMIT SPXMIT: 0 ; SLOW PAGE XMIT WITH ECHO SUPRESSION JMS HOMEUP ; GO TO TOP OF SCREEN MOOCH: JMS CASCII ; GET ASCII VALUE OF CURRENT CHARACTER ASZ ; 0 = END OF THE JOB JMP TOADY I JMP SPXMIT TOADY: SAM [012] ; DON'T TRANSMIT LINE FEEDS JMS SXMIT ; SLOW XMIT SUBROUTINE JMS RTAR JMP MOOCH SXMIT: 0 ; SLOW TRANSMIT DAC TEM1 LWC 7777 DAC LOOP GOZ: RCF ; INPPUT CLEARING HERE ISZ LOOP JMP .-2 ; DELAY LOOP IS HERE LAC TEM1 JMS XMIT ; DO IT! I JMP SXMIT TABR: 0 ; SMART TAB ROUTINE CLA DAC TABDIS' ; CLEAR DISPLACEMENT LAC CURPNT DAC TEMPNT SBACK: LWC 1 ; BACK UP THE POINTER ONE ADD TEMPNT DAC TEMPNT I LAC TEMPNT ; LOAD CHARCATEER IN BACKWARD SEARCH ASN ; FOUND A ZERO - DONE! JMP COOLY SAM [DJMS D015,] JMP .+2 JMP COOLY ; FOUND A CR - DONE! SAM [DJMS D012,] JMP .+2 JMP SBACK ; FOUND A LF - CONTINUE SAM [DNOP] JMP .+2 JMP SBACK ; FOUND A DNOP - CONTINUE JMS TABCK JMP RFOOF LAC TABDIS ; FOUND A TAB - CHARACTER COUNT TO NEXT MODULO 8 VALUE AND [170] ADD [10] DAC TABDIS JMP SBACK RFOOF: ISZ TABDIS ; ALL ELSE - ADD ONE TO CHARACTER COUNT JMP SBACK COOLY: LAC TABDIS ; LOAD DISPLACEMENT AND [170] SUB [140] ASM I JMP TABR ; DO NOTHING IF ALL THE WAY OVER SAR 2 ADD [DJMS D011+30] ; GET ADDRESS OF CORRECT TAB (ONE OF 12 POSSIBLE ONES) JMS INSERT I JMP TABR TABCK: 0 ; ROUTINE TO CHECK FOR ARGUMENT BEING A TAB OR NOT DAC TEM1' ; SAVE ARGUMENT AND [7777] SUB [D011] ASP ; SKIPS IF >= MINIMUM POSSIBLE TAB JMP NOSKIP SUB [D010-D011] ASP ; SKIPS IF > MAXIMUM POSSIBLE TAB ISZ TABCK ; SKIP RETURN ON FINDING A TAB NOSKIP: LAC TEM1 ; RELOAD THE ORIGINAL ARGUMENT I JMP TABCK ; RETURN COMCOM: 0 ; COMMENT KLUDGE PROGRAM (RYANPROG) I LAC CHRPNT ; LOAD CURRENT CHARACTER SAM [DJMS D015,] ; FOUND THE END OF THE LINE JMP MORLOK PLOF: JMS TABR ; INSERT A TAB LAC TABDIS SUB [D010-D011] ASP ; SKIPS IF TABBED OVER FAR ENOUGH BY NOW JMP PLOF ; ELSE CONTINUE TO RIGHT ARROW LAC [DJMS D073,] ; AUTOMATIC SEMICOLON JMS INSERT LAC [DJMS D040,] ; AUTOMATIC SPACE, TOO (CLASS?) JMS INSERT I JMP COMCOM MORLOK: JMS RTAR ; GO FURTHER RIGHT IN CURRENT LINE JMP COMCOM+1 JMP PLOF ; RTAR FAIL = END OF THE MAIN PROGRAM, TREAT LIKE A CR ASETR: 0 ; HANDLES CONTROL "A" SHEISS JMS TGET ADD [AXTAB] DAC TEMPNT SUB [AXEND] ; CHECK TABLE LIMIT ASM ; SKIPS IF O.K. I JMP ASETR I LAC TEMPNT ; LOAD ADDRESS OF SELECTED ROUTINE ASN ; IS A ROUTINE ASSIGNED ? I JMP ASETR ; FORGET IT IF A ZERO ENTRY DAC TEMPNT ; STORE IT I JMS TEMPNT ; I JMS TO IT I JMP ASETR AXTAB: 0 RLOADM+NOP ; ^A^A -- JUMP TO 40 TECURS+NOP ; ^A^B -- INSERT TECO CURSOR HOMEUP+NOP ; ^A^C -- HOME UP HOMEUP+NOP ; ^A^D HOMEUP+NOP ; ^A^E TENM+NOP ; ^A^F -- JUMP TO 10000 ZEDIT+NOP ; ^A^G -- EDIT MODE ZTTY+NOP ; ^A^H -- TTY MODE AXEND: ; convert two chars into number, sign-bit, and dot-bit GRFIN: 0 JMS TGET ; read character DAC TEMPNT AND [177740] ASN ; control character? JMP GRFIN1 ; yes, end of graphics ; not control character, buffer it LAC TEMPNT ; get character I JMP GRFIN ; return if not ran out ; control character, game is up GRFIN1: LAC TEMPNT JMP TTYIN1 ; regular tty input TGET: 0 ; TTY GET ROUTINE RSF JMP .-1 CLA RRC AND [177] ; PROTECTION !! I JMP TGET ; insert TECO cursor in buffer TECURS: 0 LAC [DJMS XFORM,] JMS INSERT I JMP TECURS TOPUP: 0 ; SCROLLS TOP UP TEN LINES LWC 10. DAC LOOP INHALE: ISZ TWONK ; LOOP SEARCHES FOR LINE FEEDS I LAC TWONK SAM [DJMS D012,] JMP INHALE JMS DLNCNT JMS DLNPOS ISZ LOOP ; 10TH LINE FEED YET? JMP INHALE JMS ADRJPL ; YES, CHANGE THE TWANG POINTER TO MOVE THE VIEWPORT I JMP TOPUP TOPDN: 0 ; UNDOES WHAT TOPUP DOES LWC 10. DAC LOOP ; SEARCHES BACKWARD FOR 10 LINES I LAC TWONK ASZ ; CHECK LIMITING CASE FIRST JMP .+3 ISZ TOPDN I JMP TOPDN ; SKIP RETURNS IF NO MORE TO PEEL DOWN PEEL: LWC 1 ADD TWONK DAC TWONK ; BACK UP THE TWONK POINTER FOR SEARCHING I LAC TWONK ASN JMP PRONK SAM [DJMS D012,] ; FINDS LINE FEEDS JMP PEEL ISZ LOOP ; 10 OF THEM SKIPS JMP PEEL PRONK: JMS ADRJPL ; CHANGE DISPATCHER LAW 10. ; CHANGE POINTERS & COUNTERS FOR 10 LINE SHIFT ADD LNCNT DAC LNCNT LAW 10. ; BORING, ISN'T IT! ADD LNPOS DAC LNPOS LWC 322 I ADD [DARROW] I DAC [DARROW] I JMP TOPDN BOTDN: 0 ; SCROLLS BOTTOM DOWN 10 LINES BY INSERTING A 01 IN DISPLAY LIST LWC 10. DAC LOOP PULL: LWC 1 ; BACKWARD SEARCH FOR 3 LINE FEEDS ADD TWONG DAC TWONG I LAC TWONG SAM [DJMS D012,] ; FINDS THE LINE FEEDS JMP PULL JMS DLNCNT ISZ LOOP ; FINDS THE 3RD ONE AND SKIPS JMP PULL LAW 1 I DAC TWONG ; PUT 000001 IN LIST AND KILL DISPLAY WITHOUT CREATING A I JMP BOTDN ; FALSE ENDING OF THE LIST (MARKED BY 000000) BOTUP: 0 ; UNDOES THE BOTTOM DOWN ROUTINE I LAC TWONG ASZ JMP .+3 ISZ BOTUP ; SKIP RETURNS IF NO MORE TO ROLL UP INTO VIEW I JMP BOTUP LAC [DJMS D012,] ; UNBLOCKS THE LIST AT TWONG POINTER I DAC TWONG LAW 10. ADD LNCNT DAC LNCNT PUSH: ISZ TWONG I LAC TWONG AND [177776] ASZ ; SEARCHES DOWN FOR THE NEXT 000001 OR 000000 JMP PUSH ; CONTINUE LOOKING I JMP BOTUP ; NORMAL EXIT LNFD: 0 ; LINE FEED ROUTINE LAC [DJMS D012,] JMS INSERT ; PUT IN DLIST ISZ LNCNT ; INCREMENT LINE COUNT LAC LNCNT SAM [44.] ; TOO MUCH ON SCREEN YET? I JMP LNFD ; NO, GO AWAY! LAC LNPOS ; LOAD LINE POSITION SUB [22.] ASP JMP DOWNR JMS TOPUP ; LNCNT >= 20, ROLL UP TOP ON LNFD INSERTIONS I JMP LNFD DOWNR: JMS BOTDN ; LNCNT < 20, ROLL DOWN BOTTOM ON LNFD INSERTIONS I JMP LNFD DONG: 0 BEL I JMP DONG RLOADM: 0 ; JUMPS TO 40 IOF ; SAVE WEIRD BUGS JMP 40 TENM: 0 IOF I JMP [10000] EDITLN: 0 ; TOGGLE LINE AT 70 CHARACTER PAPER MARGIN I LAC [DEDLIN] XOR [DNOP#] I DAC [DEDLIN] I JMP EDITLN LINE70: DGD LINELX: DLXA 1442 DLYA TOP DGB DLYA 0 DRJM ; process two ards graphics codes GETARD: 0 ; get and process n1 JMS GRFIN ; get a character between 100 and 177 AND [77] ; ignore all but 6 bits RAR 1 ; shift sign bit into link DAC POS' ; save 5 most sig bits ; sign bit? CLA ; zero if link not set LSZ ; link zero? LWC 1 ; minus one if is DAC SIGN' ; save in sign ; get and process n2 JMS GRFIN DAC POS1' ; save it ; dots bit? AND [40] ASZ ; if dots bit not on, skip LWC 1 ; -1 if one, so isz will skip DAC DOTS' ; save it ; do pos=> LAC POS1 AND [37] SAL 3 SAL 2 IOR POS AND [1777] DAC POS ; save in pos and return in ac I JMP GETARD ; get number into co-ordinate format SETDL: 0 ISZ SIGN JMP SETDL1 LAC POS ; if pos negative CIA dac pos ; if pos positive SETDL1: LAW 1000 ADD POS DAC POS I JMP SETDL SETPNT: 0 ; x coordinate JMS GETARD ; two chars JMS SETDL ; frob into coordinates XOR [DLXA 0,] ; make it a dlxa DAC XPOS' ; save it ; y co-ordinate JMS GETARD JMS SETDL XOR [DLYA 0,] DAC YPOS' ; insert them LAC [DGD] JMS INSERT LAC XPOS JMS INSERT LAC YPOS JMS INSERT JMP SETPNT+1 I JMP SETPNT LNGVCT: 0 ; x JMS GETARD ; two chars DAC XPOS ; x relative ; check dots bit CLA ; invisible? ISZ DOTS ; if dots=-1, invisible LAC [20000] ; not invisible DAC LONG1 ; check sign bit LAC [40000] ISZ SIGN ; if sign=-1, then negative CLA DAC LONG2 ; y JMS GETARD DAC YPOS ; check dots bit LAC [60000] ; dotted? ISZ DOTS ; if dots=-1, dotted CLA ; not dotted IOR LONG1 DAC LONG1 ; sign bit LAC [20000] ISZ SIGN CLA IOR LONG2 ; don't forget x may have sign, too! DAC LONG2 JMS VCTDO JMP LNGVCT+1 ; short vectors -- no one uses them ever SHTVCT: 0 LAC [40000] DAC LONG1 JMS GRFIN RAR 1 DAC XPOS CLA LSN JMP SHTY LAC [40000] SHTY: DAC LONG2 JMS GRFIN RAR 1 DAC YPOS LSN JMP SHTDO LAC [20000] IOR LONG2 DAC LONG2 SHTDO: JMS VCTDO JMP SHTVCT+1 ; hack difference and bit for which is greater VCTDO: 0 LAC YPOS ; y SUB XPOS ; minus x DAC LONG0 ; (y-x) ; check whether y or x greater ASZ ; nothing if x=y ASP ; skip if y>x, must hack JMP LNGPUT ; x>y is the normal case, super win ; here y was greater than x, must switch them CIA DAC LONG0 ; -(y-x) ; exchange x and y -- greater in first word always LAC XPOS XAM YPOS DAC XPOS LAC [10000] ; indicate y was greater IOR LONG2 DAC LONG2 LNGPUT: LAC LONG0 AND [7777] IOR [40000] JMS INSERT LAC XPOS IOR LONG1 IOR [100000] ; so can't look like DHLT JMS INSERT LAC YPOS IOR LONG2 IOR [100000] ; ditto JMS INSERT ; insert them I JMP VCTDO LONG0: 0 LONG1: 0 LONG2: 0 ZMODE: 0 LAC MODEF ASZ JMP .+3 JMS ZTTY I JMP ZMODE JMS ZEDIT I JMP ZMODE ZTTY: 0 ; SETS TTY MODE LWC 1 DAC MODEF LAC [DNOP] I DAC [DTTY] I JMP ZTTY ZEDIT: 0 ; SETS EDIT MODE CLA DAC MODEF LAC [DJMP DEDIT,] I DAC [DTTY] I JMP ZEDIT ZCASE: 0 ; COMPLEMENTS CHARACTER CASE LAC CASEF ASN ; SKIPS ON UPPER CASE JMP .+3 JMS LCASE ; SET LOWER CASE I JMP ZCASE JMS UCASE I JMP ZCASE UCASE: 0 LAW 40 ; SETS UPPER CASE HERE DAC CASEF' LAC [DNOP] I DAC [DUCF] LAC [DJMP DFORM,] I DAC [DCURT] I JMP UCASE LCASE: 0 ; SETS LOWER CASE CLA DAC CASEF LAC [DJMP DAUTF,] I DAC [DUCF] LAC [DNOP] I DAC [DCURT] I JMP LCASE ZAUTO: 0 ; TOGGLE TAUTO (AUTO REPEAT) LAC TAUTO ASP ; SKIPS IF IT WAS ON JMP .+3 JMS ATOFF ; TURN IT OFF I JMP ZAUTO jms aton I JMP ZAUTO ATON: 0 ; SET TAUTO TO ON LAC [ISZ TICKER] DAC TAUTO LAC [DNOP] I DAC [DAUTF] I JMP ATON ATOFF: 0 ; SET TAUTO TO OFF LAC [NOP] DAC TAUTO LAC [DJMP DBELLI,] I DAC [DAUTF] I JMP ATOFF KEYIN: 0 ; KEYBOARD INPUT SUBROUTINE CAL KRC DAC KCHAR' LWC 20 DAC TICKER ; SET 1/2 SECOND AUTO REPEAT BOMB CONTIN: LAC [KSN] DAC LOOPY ; CURE THE IMPURE ! LAW KEYDIS-1 DAC 10 ; LOAD INDEX LWC KEYSIZ DAC LOOP' LAC KCHAR JMS DISPCH JMP DSPR JMP XTR AND [CTRL] ; CONTROL BIT ON? ASN JMP .+5 LAC KCHAR AND [37] JMS XMIT I JMP KEYIN LAC KCHAR ; ELSE CHECK NORMAL RANGES AND [377] SUB [240] ; IN RANGE 240 TO 277? ASP I JMP KEYIN ; <240, IGNORE IT SUB [40] ASM JMP MISS ; >277 AND [77] JMP XTR ; YES, CONVERT & XMIT MISS: SUB [001] ; IN RANGE 301 TO 372? ASP I JMP KEYIN SUB [72] ASM I JMP KEYIN ADD [373] AND [177] ; YES, CONVERT & XMIT XOR CASEF ; SET THE CASE PROPERLY XTR: JMS TXMIT ; POITIVE=CHAR CONVERSION I JMP KEYIN DSPR: JMS IMPER I JMP KEYIN IMPER: 0 ; SUBROUTINE DISPATCH SUBROUTINE DAC IMP I JMS IMP I JMP IMPER I JMP IMPER ; SOME CAN SKIP RETURN IMP: 0 ; IMPURE LOCATION KEYDIS: DSP 202,LXMIT+NOP DSP CTRL+204,DELDN+NOP DSP 204,DNAR+NOP DSP 205,RTAR+NOP DSP CTRL+205,DELRT+NOP DSP CTRL+206,DELUP+NOP DSP 206,UPAR+NOP DSP CTRL+210,DELLF+NOP DSP 210,LFAR+NOP DSP CTRL+SHIFT+211,RLOADM+NOP DSP CTRL+211,INITA+NOP DSP SHIFT+211,ZTTY+NOP DSP 212,12 DSP SHIFT+212,DOWN+NOP DSP 214,14 DSP SHIFT+214,ZMODE+NOP DSP 215,15 DSP SHIFT+215,RCRLF+NOP DSP SHIFT+216,SPXMIT+NOP DSP CTRL+216,PXERS+NOP DSP 216,PXMIT+NOP DSP 217,HOME+NOP DSP SHIFT+217,HOMEUP+NOP DSP SHIFT+230,LDELT+NOP DSP 230,TTGLE+NOP DSP CTRL+230,CLRS+NOP DSP SHIFT+231,ZAUTO+NOP DSP 231,ZCASE+NOP DSP 232,FDELT+NOP DSP 233,33 DSP CTRL+SHIFT+233,TENM+NOP DSP 234,LDELO+NOP DSP 235,COMCOM+NOP DSP SHIFT+235,EDITLN+NOP DSP 236,37 DSP CTRL+237,FDELT+NOP DSP 237,11 DSP SHIFT+240,40 DSP CTRL+240,40 DSP CTRL+254,133 DSP CTRL+255,137 DSP CTRL+256,135 DSP CTRL+257,134 DSP SHIFT+260,10 DSP CTRL+260,174 DSP CTRL+266,176 DSP CTRL+267,140 DSP CTRL+270,173 DSP CTRL+271,175 DSP CTRL+272,136 DSP CTRL+273,100 DSP CTRL+SHIFT+301,133 DSP CTRL+SHIFT+302,134 DSP CTRL+SHIFT+303,135 DSP CTRL+SHIFT+304,136 DSP CTRL+SHIFT+305,137 DSP CTRL+SHIFT+306,100 DSP CTRL+SHIFT+314,34 DSP CTRL+SHIFT+315,35 DSP CTRL+SHIFT+316,36 DSP CTRL+SHIFT+317,37 DSP CTRL+SHIFT+320,0 DSP 377,177 DSP SHIFT+377,FDELT+NOP DSP CTRL+SHIFT+377,CLRS+NOP KEYSIZ=<.-KEYDIS>/2 TTYIN: 0 ; TELETYPE SUBROUTINE LWC 1 DAC DNOPF ; SET FLAG THAT PDP-10 WAS THE LAST TYPIST CAL RRC TTYIN1: JMS CVDISP I JMP TTYIN CVDISP: 0 ; CONVERTS ASCII TO DISPLAY LIST AND [177] ; PROTECTION DAC TCHAR' LAC MODEF ASM ; TTY MODE? JMP CVEDIT ; NO LAW TTYDIS-1 DAC 10 ; SET INDEX LWC TTYSIZ DAC LOOP JMP BSTART CVEDIT: LAW EDTDIS-1 DAC 10 LWC EDTSIZ DAC LOOP BSTART: LAC TCHAR JMS DISPCH JMP TDSPR JMP GOOLIN SUB [40] ; IN RANGE 40 TO 135? ASP I JMP TTYIN ; < 40, IGNORE IT SUB [137] ASM I JMP TTYIN ; >176, IGNORE IT ADD [137+LIST40] DAC TEMPNT I LAC TEMPNT GOOLIN: JMS INSERT I JMP CVDISP TDSPR: JMS IMPER ; dispatch I JMP CVDISP EDTDIS: DSP 177,DELETE+NOP ; ^? -- reverse delete TTYDIS: DSP 001,ASETR+NOP ; ^A -- dispatch on next character DSP 007,DONG+NOP DSP 010,DJMS D010 ; ^H -- insert backspace DSP 011,TABR+NOP ; ^I -- tab DSP 012,lnfd+NOP DSP 013,down+NOP DSP 015,DJMS D015 ; ^M -- INSERT CR DSP 016,ABPOS+NOP DSP 017,LFAR+NOP DSP 020,DELDN+NOP DSP 021,DELRT+NOP DSP 022,CLRS+NOP DSP 023,LDELT+NOP DSP 024,HOMEUP+NOP DSP 025,HOME+NOP DSP 030,DELETE+NOP DSP 031,RTAR+NOP DSP 032,UPAR+NOP DSP 033,DJMS D033 ; normal alt-mode EDTSIZ=<.-EDTDIS>/2 DSP 014,CLRS+NOP DSP 035,SETPNT+NOP DSP 036,LNGVCT+NOP DSP 037,SHTVCT+NOP TTYSIZ=<.-TTYDIS>/2 LIST40: DJMS D040, ? DJMS D041, ? DJMS D042, ? DJMS D043 DJMS D044, ? DJMS D045, ? DJMS D046, ? DJMS D047 DJMS D050, ? DJMS D051, ? DJMS D052, ? DJMS D053 DJMS D054, ? DJMS D055, ? DJMS D056, ? DJMS D057 LZERO: DJMS D060, ? DJMS D061, ? DJMS D062, ? DJMS D063 DJMS D064, ? DJMS D065, ? DJMS D066, ? DJMS D067 DJMS D070, ? DJMS D071, ? DJMS D072, ? DJMS D073 DJMS D074, ? DJMS D075, ? DJMS D076, ? DJMS D077 DJMS D100, ? DJMS D101, ? DJMS D102, ? DJMS D103 DJMS D104, ? DJMS D105, ? DJMS D106, ? DJMS D107 DJMS D110, ? DJMS D111, ? DJMS D112, ? DJMS D113 DJMS D114, ? DJMS D115, ? DJMS D116, ? DJMS D117 DJMS D120, ? DJMS D121, ? DJMS D122, ? DJMS D123 DJMS D124, ? DJMS D125, ? DJMS D126, ? DJMS D127 DJMS D130, ? DJMS D131, ? DJMS D132, ? DJMS D133 DJMS D134, ? DJMS D135, ? DJMS D136, ? DJMS D137 DJMS D140, ? DJMS D141, ? DJMS D142, ? DJMS D143 DJMS D144, ? DJMS D145, ? DJMS D146, ? DJMS D147 DJMS D150, ? DJMS D151, ? DJMS D152, ? DJMS D153 DJMS D154, ? DJMS D155, ? DJMS D156, ? DJMS D157 DJMS D160, ? DJMS D161, ? DJMS D162, ? DJMS D163 DJMS D164, ? DJMS D165, ? DJMS D166, ? DJMS D167 DJMS D170, ? DJMS D171, ? DJMS D172, ? DJMS D173 DJMS D174, ? DJMS D175, LISTN: DJMS D176 CASCII: 0 ; CONVERTS DISPLAY LIST TO ASCII I LAC CHRPNT ; LOAD FROM INDEX SAM [DNOP] JMP .+3 JMS RTAR JMP CASCII+1 JMS TABCK ; CHECKS FOR A TAB JMP .+3 LAW 11 JMP BLAPO SAM [DJMS D010,] JMP .+3 ; CHECKS FOR A BACKSPACE LAW 10 JMP BLAPO SAM [DJMS D012,] JMP .+3 ; CHECKS FOR A LINE FEED LAW 12 JMP BLAPO SAM [DJMS D015,] JMP .+3 ; CHECKS FOR A CARRIGE RETURN LAW 15 JMP BLAPO SAM [DJMS D033,] JMP .+3 ; CHECKS FOR AN ALTMODE LAW 33 JMP BLAPO DAC TCHAR LAW LIST40-1 DAC 10 ; POINTER TO TABLE LWC LISTN-LIST40+1 DAC LOOP ; LIMIT SEARCH LAC TCHAR WHOPIE: I SAM 10 ; COMPARE JMP .+2 JMP CMATCH ISZ LOOP ; CHECK FOR LIMIT! JMP WHOPIE CLA ; NOT IN TABLE, RETURNS A ZERO JMP BLAPO CMATCH: LWC LIST40-40 ADD 10 ; GET ASCII BLAPO: DAC TCHAR ; SAVE THE CHARACTER FOR HIGH LEVEL MISUSE I JMP CASCII DISPCH: 0 ; comparison loop DISCMP: I SAM 10 ; MATCH? JMP .+2 ; NO MATCH JMP DISMAT ; MATCH! ISZ 10 ; SKIP SECOND WORD OF ENTRY ISZ LOOP ; ALL OF IT? JMP DISCMP ; NO, LOOP ; failed -- no matches ISZ DISPCH JMP DISXIT ; won -- return second word of table entry DISMAT: I LAC 10 ASM DISXIT: ISZ DISPCH I JMP DISPCH VARIABLES CONSTANTS 0 DCURT: DNOP ; REGULAR CURSOR INC E,D0M1 INC D0M3,B30 INC B30,B30 INC D03,D20 INC D01,T DJMP CURRET DFORM: INC E,D0M1 ; CURSOR WITH PRONGS INC B0M3,B30 INC B30,B30 INC B03,D20 INC D01,T CURRET: INC E,DM30 INC DM30,DM30 INC DM20,X XFORM: DJMS XXFORM ; TECO CURSOR DJMS XXFORM DJMS XXFORM DRJM XXFORM: INC E,DM3M3 ; I-BEAM CURSOR INC DM3M3,DM20 INC B30,B30 INC B30,B30 INC DM30,DM30 INC B03,B03 INC B03,B03 INC B03,B03 INC B03,B03 INC DM30,DM30 INC B30,B30 INC B30,B30 INC DM3M3,DM1M3 INC D0M3,D0M3 INC D0M3,D0M3 INC X,X DNOP INC E,DM10 INC BM2M3,BM2M3 INC B20,B20 INC B20,B20 INC BM23,BM23 INC D10,X DWAIT: INC E,P INC P,P ; 40 MICROSECOND WAIT INC P,P INC P,P INC P,P INC P,P INC P,P INC P,P INC P,P INC P,140 D011: DLXA 170 DJMP DWAIT DLXA 320 DJMP DWAIT DLXA 450 DJMP DWAIT DLXA 600 DJMP DWAIT DLXA 730 DJMP DWAIT DLXA 1060 DJMP DWAIT DLXA 1210 DJMP DWAIT DLXA 1340 DJMP DWAIT DLXA 1470 DJMP DWAIT DLXA 1620 DJMP DWAIT DLXA 1750 DJMP DWAIT DLXA 2100 DJMP DWAIT D010: INC E,DM20 ; BACKSPACE INC DM30,DM30 INC DM30,X D012: INC E,D0M3 ; LINE FEED INC D0M3,D0M3 INC D0M3,D0M3 INC D0M3,D0M3 INC X,X D015: DLXA LEFT ; CARRIAGE RETURN DRJM D033: DJMS D117 ; ALTMODE DJMS D010 DJMP D044 .INSRT DSK:IMSRC;SSV CHARS DORIG: DADR DHVS 1 DEDLIN: DNOP DGD DLYA TOP+40 DLXA LEFT DJMS D123 ; SSV.22 DJMS D123 DJMS D126 DJMS D056 DJMS D062 DJMS D062 DGD DLXA LEFT+300 DJMS D103 ; CBUF= DJMS D102 DJMS D125 DJMS D106 DJMS D075 DNUM1: DNOP DNOP DNOP DNOP DGD DLXA LEFT+600 DTTY: DNOP DJMS D124 ; TTY DJMS D124 DJMS D131 DJMP DMODE DEDIT: DJMS D105 ; EDIT DJMS D104 DJMS D111 DJMS D124 DMODE: DJMS D040 DJMS D115 ; MODE DJMS D117 DJMS D104 DJMS D105 DUCF: DJMP DAUTF DGD DLXA LEFT+1100 DJMS D055 ; -UC- DJMS D125 DJMS D103 DJMS D055 DAUTF: DNOP DGD DLXA LEFT+1220 DJMS D055 ; -AUTO- DJMS D101 DJMS D125 DJMS D124 DJMS D117 DJMS D055 DBELLI: DGD DLXA 0 DARROW: 0 DJMS D075 ; => DJMS D076 DGD DLXA LEFT DLYA TOP TWANG: 0 ; DISPLAY DISPATCH POINT NO. 1 0 ; BUFFER ZERO TO MARK THE BEGINNING OF IT ALL CURRY: 0 ; START OF ACTIVE DLIST 0 END INIT