;*; Updated on 31-Aug-89 at 1:41 PM by Steve Archuleta; edit time: 0:03:38 ;******************************* ;* IntraNetwork CB * ;* * ;* by Dave Heyliger * ;* AMUS Staff * ;* * ;* NOTE: you need * ;* * ;* CB.M68 * ;* CBCLR.M68 * ;* CBSYS.M68 * ;******************************* ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; "Go ahead... make me rich!" ; ; translated: THIS BABY IS FREE FOR ANYONE AND EVERYONE. The ONLY way ; this program will generate money is if someone decides ; to cheat, sell it, and get caught by me or other members ; etc. Then in come the lawyers and bingo: I'm rich! ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;########################################################################## ; How it works, General Instructions, What You Need: ; ; CB works by storing pointers to user partitions of everyone who is on CB. ; When a user on CB modifies their "message" to other users, it changes a ; "hash" (the count of the number of characters). When there is a hash change ; OR a user quits OR a new user comes on, the messages are updated. CB offers ; unique "handles" for everyone who is on (SPECIAL TSASS VERSION uses ; INITIALS as the handle automatically). CB also offers dynamic screen editing ; that adds great effects! You will find CB addicting and fun - guaranteed. ; ; FOR CB TO WORK, you MUST modify this file. There are TWO versions contained ; in this source code file. 1) "PUBLIC" version and 2) "TSASS" version. For ; those who don't run TSASS (Dravac), you MUST comment out the "TSASS" ; portion and visa versa. It is clearly marked in the code, and it involves ; placing ";"s before an entire paragraph of code. After reading the code you ; will see where to place the series of ";"s. ; You will also need a funny file called CB.SYS. This is just a one block file ; that contains absoulely NOTHING! You MUST place CB.SYS in System Memory (it ; only takes up 512 bytes). You do this by storing CB.SYS on DSK0:[1,4] and ; from within your AMOSL.INI file you have a SYSTEM CB.SYS line before the ; final SYSTEM line. Reboot your system and you are ready to go. If you have ; the space, place CB.LIT (the assembled version of this file) on DSK0:[1,4] ; too so you can call up CB from anywhere. The file CB.SYS can be generated ; from a very small file called CBSYS.M68. Be sure to RENAME it to CB.SYS! ; Finally, a file called CBCLR.M68 creates CBCLR.LIT (CB Clear). If for any ; reason CB.SYS gets "mucked", type CBCLR and it will reset CBSYS to all "0"s. ;############################################################################ OBJNAM CB.LIT ;final product ;--- SEARCH appropriate files ; SEARCH SYS SEARCH SYSSYM SEARCH TRM ;--- define a version number ; VMAJOR=1. VMINOR=0. VEDIT=100. ;original version by Dave Heyliger VEDIT=101. ;loosing chars @ 1200 bps, 1 liner cor ;--- variables ; .OFINI .OFDEF GLOBAL,120 ;global transmitter that all will see .OFDEF FLAG,2 ;indication of change in CB.SYS .OFDEF PRMCNT,2 ;"perminent" user count .OFDEF CBSYS,4 ;System Module CB.SYS .OFDEF USRNUM,2 ;"variable" user count .OFDEF HASHES,24 ;the hash code array .OFDEF USRLST,140 ;24 user pointers allowed .OFSIZ IMPSIZ PHDR -1,0,PH$REE!PH$REU ;define a program header ;--- Macro Definitions ; DEFINE PRTTAB AA,BB ;PRINT TAB (#,#) MOVB #AA,D1 LSLW D1,#10 MOVB #BB,D1 TCRT ENDM DEFINE OVER AA,BB ;TAB OVER special tab function MOVB AA,D1 LSLW D1,#10 MOVB BB,D1 TCRT ENDM DEFINE PRTONE AA ;PRINT TAB ((#+5),1) ADD #5,AA MOVB AA,D1 LSLW D1,#10 MOVB #1,D1 TCRT ENDM DEFINE HOME AA ;moves cursor "HOME" on your input line MOVB #3,D1 LSLW D1,#10 MOVB AA,D1 TCRT ENDM ;--- Image mode, no echo, no control-C, and get .OFDEF pointer (A3) ; JOBIDX A6 ;A6 points to JCB LEA A4,JOBTYP(A6) ;A4 points to processing word ANDW #^B1111111101111111,@A4 ;set no ctrlc MOV JOBTRM(A6),A4 ;A4 points to the terminal def. tbl. ORW #T$IMI!T$ECS,@A4 ;Force image mode, suppress echo GETIMP IMPSIZ,A3 ;A3 points to variables ;--- See if user wants to get on... ; CBINI: PRTTAB 377,0 ;clear the screen PRTTAB 2,1 ;tab over TYPE < There are > ;start of msg CALL SERCH ;fill CBSYS variable - find CB.SYS CLR D1 ;data registers are funny, so clear MOVB 20(A1),D1 ;D1 contains count of current users PUSH D1 ;save the count DCVT 0,OT$TRM ;blast out current number TYPE < user(s) currently on.> POP D1 ;retrieve the count CMPB D1,#30 ;all full?? BNE ROOM ;nope, still some room TYPECR < Sorry, but the airways are full!> JMP QOFF ;type above msg and quit ROOM: TYPE < Would you like to connect? y or n > QON: SLEEP #2500. ;sleep a bit to not burn CPU TCKI ;any input??? BNE QON ;waiting for reply still.... KBD ;get the reply UCS ;create upper case for comparison CMPB D1,#131 ;"Y"???? JNE QOFF ;nope, so quit ;--- TSASS LOGON ROUTINE ; ; Place semi-colons in front of this entire paragraph if you do NOT ; use TSASS! ; ; USRBAS A1 ;get the pseudo base of memory ; SUB #572,A1 ;A1 points to the initials ; LEA A5,GLOBAL(A3) ;time to .INI global message space ; MOVB #377,(A5)+ ;"ON" byte set (checked by others) ; MOVB #0,(A5)+ ;"HASH" set to zero (no input yet) ; MOVB #'[,(A5)+ ;move in the HANDLE information ; MOV #4,D4 ;four times we will do this: ;MOVHDL: MOVB (A1)+,(A5)+ ; move in the char ; DEC D4 ; one less char to move in ; BNE MOVHDL ; and get next char ;STLMOR: MOVB #'],(A5)+ ;move in more HANDLE info ; MOVB #40,(A5)+ ;a space ; MOVB #'-,(A5)+ ;a dash ; MOVB #40,(A5)+ ;a space ; CLRB @A5 ;a null ;--- PUBLIC LOGON ROUTINE ; ; Place semi-colons in front of this entire paragraph if you do ; use TSASS! (original version has this paragraph commented out) ; LEA A5,GLOBAL(A3) ;time to .INI global message space MOVB #377,(A5)+ ;"ON" byte set (checked by others) MOVB #0,(A5)+ ;"HASH" set to zero (no input yet) MOVB #'[,(A5)+ ;move in the HANDLE information PRTTAB 4,30 ;tab to here TYPE < Enter in a 4-letter handle ____> PRTTAB 4,64 ;return tab to here CLR D3 ;D3 will be a counter LOGON: CMP D3,#4 ;all full? JEQ APPEND ;yup, time to append some characters KBD ;wait for ONE character L1: CMPB D1,#177 ;rubout? BNE L3 ;nope, don't do code below CMPB D3,#0 ;rubout, but room? BNE L2 ;if not "0" then room to go back SCOLD: MOV #7,D1 ;get a bell TTY ;beep BR LOGON ;and try again L2: PRTTAB 377,5 ;cursor left one column MOVB #137,D1 ;put a "_" in D1 TTY ;blast it out PRTTAB 377,5 ;move left back over the "_" DECB D3 ;adjust count DEC A5 ;adjust pointer CLRB @A5 ;delete the character from the var. JMP LOGON ;and ready for next key entry L3: CMPB D1,#172 ;is it a z or more? BGT SCOLD ;then ding CMPB D1,#40 ;is it a space? BEQ L4 ;then AOK CMPB D1,#101 ;A or less? BLT SCOLD ;then ding L4: UCS ;convert to upper case TTY ;type it out MOVB D1,(A5)+ ;ok character INC D3 ;count one more JMP LOGON ;and do it again APPEND:MOVB #'],(A5)+ ;move in more HANDLE info MOVB #40,(A5)+ ;a space MOVB #'-,(A5)+ ;a dash MOVB #40,(A5)+ ;a space CLRB @A5 ;a null ;--- fill in information about CB: ; 1) get the "permanent user count" from CB.SYS ; 2) get everyone else's global message location ; 3) place YOUR global message location in CB.SYS ; CBINFO: CALL SERCH ;find CB.SYS LEA A4,GLOBAL(A3) ;A4 gets global msg buffer LEA A5,USRLST(A3) ;A5 points to user pointer array LEA A2,PRMCNT(A3) ;A3 points to "perm" count CBIN: JLOCK ;-------------------------------------------------------- INCB 20(A1) ;increment total user count in CBSYS MOVB 20(A1),@A2 ;get the count into user memory LEA A1,24(A1) ;point A1 to user pointers NXTUSR: CMP @A1,#0 ;is there a user pointer? BEQ INYOU ;if not, put yourself in MOV (A1)+,(A5)+ ;else move in the user pointer BR NXTUSR ;and get next user INYOU: MOV A4,@A1 ;blast in your global ^ to CBSYS JUNLOK ;-------------------------------------------------------- LEA A5,USRNUM(A3) ;record "variable" user number too MOVB @A2,@A5 ;by saving the "permanent" count ;--- set the "flag" for all other users currently on CB.SYS modification ; MOVB @A2,D3 ;move in a counter DECB D3 ;don't count yourself! CMPB D3,#0 ;only one on? BEQ CBSCRN ;yup, so skip rest of this portion LEA A5,USRLST(A3) ;else repoint A5 to pointer arrays FLAGON: MOV (A5)+,A4 ;get a pointer ADD #120,A4 ;bypass GLOBAL area MOVB #1,@A4 ;turn on the FLAG DECB D3 ;one less guy to do BNE FLAGON ;if more, do it again LEA A5,FLAG(A3) ;get YOUR flag MOVB #1,@A5 ;and turn it on ;--- Generate the transmission screen - give directions ; CBSCRN: PRTTAB 377,44 ;screen off PRTTAB 377,0 ;clear screen PRTTAB 377,13 ;dim on PRTTAB 377,40 ;reverse on TYPE < Hit [CR] to clear line > PRTTAB 377,14 ;dim off TYPE < IntraNetwork CB (1.0) > PRTTAB 377,13 ;dim on TYPE < ESCape to quit > PRTTAB 377,41 ;reverse off PRTTAB 377,14 ;dim off PRTTAB 3,2 ;move to here TYPE < YOU: > ;your prompt PRTTAB 377,35 ;cursor off PRTTAB 377,45 ;screen on MOVB #10,D5 ;D5 is column of where YOU are editing TOP: ;--- Main loop! ; if input to your terminal, process it ; if only one on, hang out ; if others on (and "hash" of msg has changed), type out messages ; if "new" user on or "old" user off, redo pointers and count ; and update individuals screen ; SLEEP #500 ;hang out a bit so CPU don't burn TCKI ;any input lately? BNE X ;nope CALL OWNINP ;yup, so get the input and return here X: LEA A4,FLAG(A3) ;get the flag (modification of users) CMPB @A4,#1 ;is it on?? BNE P ;nope, so dont adjust pointer array MOV #7,D1 ;get a bell TTY ;and inform that a new user is on CALL UPDATE ;update the pointers and count MORUSR: LEA A2,PRMCNT(A3) ;get the perm count CMPB (A4)+,(A2)+ ;if usernumber < perminent count BGE EUPDAT ; then don't clear bottom line ONLESS: DEC A2 ;repoint A2 to "old" count MOVB @A2,D3 ;setup D3 to bottom row number PRTONE D3 ;move to the bottom row LEA A2,SPACES ;get spaces TTYL @A2 ;clear bottom row (1 less user on CB) EUPDAT: LEA A2,PRMCNT(A3) ;always move the variable user count LEA A1,USRNUM(A3) ;to the "permanent" non-variable count MOVB @A1,(A2)+ ;move it on in CMPB @A1,#1 ;only one on? BNE CHKMSG ;nope, so check the messages LEA A4,FLAG(A3) ;yup, so we need to clear the FLAG CLRB @A4 ;like this! BR TOP ;and return to top CHKMSG: CALL GETMSG ;else get the message(s) BR TOP ;and return to TOP P: LEA A4,PRMCNT(A3) ;get the user number CMPB @A4,#1 ;only one on? BEQ TOP ;then be boring (sleep) BR CHKMSG ;else examine others msgs ;--- UPDATE subroutine: updates user pointers and number of users on CB ; UPDATE: LEA A4,CBSYS(A3) ;get the pointer to CB.SYS MOV @A4,A1 ;and place the pointer into A1 LEA A4,USRNUM(A3) ;A4 points to user number LEA A2,GLOBAL(A3) ;get YOUR user pointer LEA A5,USRLST(A3) ;array of user pointers JLOCK ;--------------------------------------------------- MOVB 20(A1),@A4 ;A4 gets user count LEA A1,24(A1) ;point A1 to user pointers NEXT1: CMP @A1,#0 ;is there a user pointer? BEQ NOMORE ;nope, all done CMP A2,@A1 ;YOUR user pointer??? BNE GRBUSR ;nope, so branch to grab user ADD #4,A1 ;else bypass it BR NEXT1 ;and try again GRBUSR: MOV (A1)+,(A5)+ ;move in the user pointer BR NEXT1 ;and try again NOMORE: JUNLOK ;--------------------------------------------------- RTN ;--- DING subroutine - if past your CB "buffer", BEEP and instruct ; DING: MOV #7,D1 ;get a bell TTY ;BEEP! PRTTAB 4,5 ;place cursor here LEA A5,ERRMSG ;get the error message TTYL @A5 ;blast out error message TICKI: TCKI ;any input yet? BEQ INPCHK ;yup, see if an OK key...([CR] or DEL) SLEEP #2500 ;else don't burn CPU time BR TICKI ;and try again INPCHK: KBD ;get the key (only DEL and CR allowed) CMPB D1,#177 ;rubout?? BEQ OKKEY ;then ok key CMPB D1,#15 ;return?? BEQ OKKEY ;then ok key MOV #7,D1 ;else get a bell TTY ;and scold them again! BR TICKI ;and give them another chance OKKEY: PUSH D1 ;save the key PRTTAB 4,5 ;back to the row LEA A5,SPACES ;ready for clear TTYL @A5 ;clear the ERROR message POP D1 ;retrieve the key CMPB D1,#15 ;[CR]?? JEQ HITCR ;yup, so clear out the message CALL BCKONE ;nope, must be DEL, so process RTN ;and return (from "OWNINP") ;--- if an ESC. key was hit, modify CB.SYS, return to AMOS, and set "flag". ; EXIT: LEA A4,CBSYS(A3) ;get the pointer to CB.SYS MOV @A4,A1 ;and place the pointer into A1 LEA A2,GLOBAL(A3) ;get YOUR user pointer LEA A5,USRLST(A3) ;array of user pointers JLOCK ;--------------------------------------------------- LEA A1,20(A1) ;point A1 to user count DECB @A1 ;one less user on CB ADD #4,A1 ;point to Global msg list MOV A1,A4 ;A4 points there too NEXT2: CMP @A1,#0 ;is there a user pointer? BEQ FLGSET ;nope, time to set everones flags CMP A2,@A1 ;YOUR user pointer? (we want this) BNE NOTYOU ;nope, so leave it alone BUMPEM: ADD #4,A4 ;bypass YOUR pointer (with A4 only) MOV @A4,(A1)+ ;and bump this guy over YOUR pointer CMP @A4,#0 ;more to bump? BNE BUMPEM ;yup BR FLGSET ;nope NOTYOU: ADD #4,A1 ;get next location ADD #4,A4 ;get next location BR NEXT2 ;and get next user (maybe YOU now) FLGSET: LEA A2,PRMCNT(A3) ;get the number of users MOVB @A2,D3 ;D3 is our counter CMPB D3,#1 ;only one on? BEQ OFF ;yup, so no flags to set LEA A5,USRLST(A3) ;A5 to start (old) pointer array NXTFLG: MOV (A5)+,A4 ;get a pointer ADD #120,A4 ;bypass GLOBAL area MOVB #1,@A4 ;turn on the FLAG DECB D3 ;one less guy to do BNE NXTFLG ;if more, do it again OFF: JUNLOK ;--------------------------------------------------- QOFF: JOBIDX A6 ;get JCB LEA A4,JOBTYP(A6) ;get processing word ORW #^B10000000,@A4 ;set controlc MOV JOBTRM(A6),A4 ;get terminal definition stuff ANDW #17774,@A4 ;return screen to normal PRTTAB 377,0 ;clear the screen PRTTAB 377,34 ;cursor on EXIT ;return to AMOS SERCH: ;--- Setup pointer to get find CB.SYS ; LEA A2,BUFFER ;point A2 to ascii CB.SYS LEA A4,CBSYS(A3) ;point A4 to variable CBSYS FILNAM @A4 ;convert ascii CB.SYS ---> RAD50 SRCH @A4,A1 ;A1 points to CB.SYS LEA A4,CBSYS(A3) ;A4 points to variable to hold pointer MOV A1,@A4 ;move in the pointer to CBSYS RTN OWNINP: ;--- own user input to get ; MOVB #10,D5 ;HOME location less data LEA A5,GLOBAL(A3) ;message line ADD #13,A5 ;bypass perminent info FNDNUL: CMPB @A5,#0 ;at a null yet? BEQ INKY ;yup INC A5 ;else try next location INCB D5 ;and move cursor position (hash+10) BR FNDNUL ;and try again INKY: HOME D5 ;move cursor to correct spot SUBB #10,D5 ;make D5 be the hash value (sneaky!) PUSHB D5 ;save this baby (it goes everywhere) KBD ;get the input CMPB D1,#40 ;space or less? BLT SPECL ;yup, so special processing CMPB D1,#177 ;chech for rubout JLT BYPASS ;if NOT, bypass the following YESRUB: CALL BCKONE ;RUBOUT, so erase, and LEA A5,GLOBAL(A3) ;get the message space junk INC A5 ;point past ON/OFF byte POPB @A5 ;move in "new" hash value (from D5) DECB @A5 ;one less in hash RTN ;and return SPECL: POPB D5 ;restore stack (from D5) CMPB D1,#33 ;escape? JEQ EXIT ;yup, time to EXIT CMPB D1,#15 ;return? BEQ HITCR ;yup, time to clear message JMP NXTCHR ;else disregard bogus input HITCR: LEA A5,GLOBAL(A3) ;get the message junk INC A5 ;bypass ON/OFF byte CLRB @A5 ;hash now "0" ADD #12,A5 ;bypass handle et.al. MOVB #77,D3 ;number of nulls to move in MORNUL: CLRB (A5)+ ;place in a null DECB D3 ;one less null to blast BNE MORNUL ;still more to clear MOVB #10,D5 ;get ready to go home HOME D5 ;home we are (cursor wise) MOVB #120,D3 ;counter MOVB #40,D1 ;space character CLRYOU: TTY ;type out a space DECB D3 ;one less space to type BNE CLRYOU ;still more to type RTN ;end of clearing transmission BYPASS: POPB D5 ;restore stack (from D5) CMP D5,#77 ;hash too big? (there is a limit!) JGE DING ;yup, so inform user too many chrs TTY ;else blast out new input character MOVB D1,(A5)+ ;and store the character in edit LEA A5,GLOBAL(A3) ;get the message space junk INC A5 ;point past ON/OFF byte MOVB D5,@A5 ;move in "new" hash value INCB @A5 ;one more in hash (so new msg shows) NXTCHR: TCKI ;any input waiting? JEQ OWNINP ;yup, so repeat this section RTN ;else return to main loop ;--- BCKONE subroutine - erases a character on transmission input ; BCKONE: CMPB D5,#0 ;room to go back? BLE NOROOM ;nope DEC A5 ;move A5 back one CLRB @A5 ;and null it PRTTAB 377,5 ;backspace cursor MOVB #40,D1 ;move in a space TTY ;type it out PRTTAB 377,5 ;and back up DECB D5 ;column is one less NOROOM: RTN ;done erasing ;--- GETMSG subroutine - analyse other users activities and act accordingly ; GETMSG: LEA A1,FLAG(A3) ;get the flag CMPB @A1,#1 ;major update on CB? BNE NMAJOR ;nope, so don't type all msgs out CALL ALLOUT ;yup - type all msgs no matter what RTN ;and return to TOP NMAJOR: CALL HSHCMP ;else just compare hashes (maybe type) RTN ;and return to TOP ;--- ALLOUT subroutine: type out all msgs no matter what ; ALLOUT: LEA A6,USRNUM(A3) ;get the number of user msgs to type LEA A4,USRLST(A3) ;A4 points to user pointers AO: CLR D4 ;D4 is our "space" counter register MOV (A4)+,A5 ;A5 points to OTHERS global msg CLR D3 ;D3 will be our row number MOVB @A6,D3 ;first get the count PRTONE D3 ;and tab to this row JLOCK ;------------------------------------------------------ CMPB (A5)+,#377 ;CB ON?? BNE AOUL ;nope - unlock and continue INC A5 ;bypass the hash code total AOSTAR: CMPB @A5,#0 ;at a NULL yet?? BEQ AOUL ;yup, no more typing needed INC D4 ;else one less space to type MOVB (A5)+,D1 ;and get the character of the msg TTY ;type it out BR AOSTAR ;and see if we are at the NULL yet AOUL: JUNLOK ;------------------------------------------------------ MOV #40,D1 ;get a space SPCOUT: TTY ;type it out INC D4 ;one less space to type CMP D4,#107 ;last space out? BLE SPCOUT ;nope LEA A6,USRNUM(A3) ;get the user count DECB @A6 ;one less user to mess with CMPB @A6,#1 ;only you left? BNE AO ;nope, do above all over again CALL NXTGET ;update user count since it's mucked RTN ;and return to TOP ;--- HSHCMP subroutine: compare hash codes, type msg out if different ; HSHCMP: LEA A6,USRNUM(A3) ;get the user count LEA A4,USRLST(A3) ;A4 points to user pointers LEA A2,HASHES(A3) ;A3 points to hash codes HC: MOV (A4)+,A5 ;A5 points to OTHERS global msg PUSH A5 ;save the pointer INC A5 ;point to the hash code CMMB @A5,(A2)+ ;same hash as last time? BNE NEWHSH ;no, different hash, so output POP A5 ;else restore stack LEA A6,USRNUM(A3) ;get the user count DECB @A6 ;one less user to test CMPB @A6,#1 ;only you left? BNE HC ;nope, still more users on CALL NXTGET ;else update user count RTN ;and return to TOP NEWHSH: DEC A2 ;different hash, so repoint A2 MOVB @A5,(A2)+ ;move in different hash for next time MOV #11,D4 ;12 spaces we KNOW don't need typed ADDB @A5,D4 ;plus hash (although a bit much) POP A5 ;point to msg CLR D3 ;D3 will be the row number MOVB @A6,D3 ;add user count to the row number ADD #5,D3 ;move it down by 5 JLOCK ;------------------------------------------------------ CMPB (A5)+,#377 ;CB ON?? BNE HCUL ;nope CMPB (A5)+,#0 ;no message to type (due to [cr]?) BNE STLSTF ;still stuff to type so branch OVER D3,D4 ;tab over to here CLR D4 ;D4 is our space counter MOV #40,D1 ;D1 contains a space CLRMSG: TTY ;start clearing the msg spc by spc INC D4 ;one less space to type CMP D4,#105 ;done clearing??? BLE CLRMSG ;nope BR HCUL ;yup, blow by rest of JLOCK STLSTF: SUB #7,D4 ;don't lose any characters. OVER D3,D4 ;tab to here DEC D4 ADD D4,A5 ;make A5 point to "end" of prev. msg TTYL @A5 ;and then type out new additions HCUL: JUNLOK ;------------------------------------------------------ MOV #40,D1 ;get a space TTY ;type out a few spaces TTY ;just incase of backrubs LEA A6,USRNUM(A3) ;get the user count DECB @A6 ;one less user CMPB @A6,#1 ;only you left? JNE HC ;nope, do this mess again CALL NXTGET ;else update user count RTN ;and return to TOP ;--- NXTGET subroutine: updates user count for TOP ; NXTGET: LEA A1,USRNUM(A3) ;get user count (variable) LEA A4,PRMCNT(A3) ;and the "permanent count" MOVB @A4,(A1)+ ;reset variable user number LEA A1,FLAG(A3) ;get the flag CLRB @A1 ;clear it even if it is already clear RTN ;and return to caller BUFFER: ASCII /CB.SYS/ ;the file that is in SYSTEM memory EVEN SPACES: ASCII / / BYTE 0 EVEN ERRMSG: ASCII / End of buffer... hit [CR] to clear or RUBOUT to edit/ BYTE 0 EVEN END .