OBJNAM ED.SBR ; Created 23-Aug-85, last modified 23-Jan-86 ; Puts specified Interactive BASIC line into user's input buffer for ; editing using the VUE-like system line input editing facility. ; by Irv Bromberg, Medic/OS Consultants, Toronto, Canada RADIX 10 VEDIT=19 VMINOR=2 VMAJOR=4 VSUB=0 IF EQ,1 Assembled under AMOS/L 1.3 program 4.2(19) size is 908 bytes, hash code is 001-606-273-412. Calling syntax: XCALL ED,LineSpec where LineSpec is a floating expression specifying BASIC line# to be edited or is a string containing an ED.SBR command. The valid ED.SBR commands are: xcall ed,"F" edit first line xcall ed,"L" edit last line xcall ed,"N" edit next line (same as XCALL ED with no parameter) xcall ed,"P" edit previous line xcall ed,"I" insert line The insert line command brings up the last edited line number followed by a space provided that that line number does not already exist. It therefore inserts AFTER the last edited line. You may wish to leave gaps between line numbers for later use, in that case use the insert line command repeatedly (convenient if a RELIEF function key is defined for this, see below) until the desired line number appears OR simply backspace to change the line number to leave the desired gap, being careful not to use an existing line number. Because of the way RELIEF handles programmable functions it is convenient to program the following functions into RELIEF.TBL: @f=xcall ed,"f" ; Funct-f =edit first line @l=xcall ed,"l" ; Funct-l =edit last line @n=xcall ed,"n" ; Funct-n =edit next line @p=xcall ed,"p" ; Funct-p =edit previous line @i=xcall ed,"i" ; Funct-i =insert line @e=xcall ed,$ ; Funct-e =allow line# to be input This allows the desired function key to be hit without having to clear the currently edited line since RELIEF automatically clears the current input line before processing the programmable function keycode. The specified line is displayed for editing using the VUE-like system line editor (LINEED, RELIEF, or AMOS/L 1.4 system line editor) Any Horizontal Tab control characters in the source code of the line will be converted to single spaces as the line is displayed, so that the line editor will not get confused. The cursor will be left at the end of the line to be edited. If the line is too long for the user's terminal's type-ahead input buffer a warning will be issued (excess cannot be displayed). ED.SBR can only be invoked from Interactive BASIC - when it is called from a compiled BASIC program it will display an error message and signal a Control-C Operator Interrupt to BASIC. The default line number is the line after the last line edited by ED.SBR, or the first line if ED.SBR is being called for the first time since the BASIC.LIT command was invoked (the last edited line number is stored in the filename extension word of the memory module containing the program being edited - this word is not used by BASIC and therefore use of it does not interfere with BASIC programming). When a line number greater than the last existing line number is specified ED displays the number of the last existing line. Attempt to go to next line after the last line causes the last line to be returned (except for Insert command). SCALE is supported (scaled floating values) for line numbers. Edit history: 3.1(15) 4-Dec-85 Released to AMUS, for publication in AMUS.LOG. 3.2(16) 11-Dec-85 Added support for SCALE (scaled floating values). Use user stack for floating workspace. 4.0(17) 16-Dec-85 Major rewrite to add ED.SBR string commands 4.1(18) 17-Dec-85 "Next" to stop at end of program instead of errmsg. 18-Dec-85 Made SCALE support optional by conditional assembly. 30-Dec-85 Changed back SCALE to required assembly. 4.2(19) 23-Jan-86 Fix to work with RELIEF's new KBD re-display patch, need to TRMICP a ^S before the line and a ^Q after it. ENDC SEARCH SYS SEARCH SYSSYM SEARCH TRM JCB =A0 Impure =A0 Prog =A1 LastLn =A2 ASCBUF =A2 ArgBas =A3 String =A3 Worksp =A4 TCB =A5 Float =A6 Atemp =A6 Line =D0 Char =D1 CrtCmd =D1 Number =D1 Length =D2 Count =D3 LineNo =D4 LastNo =D5 Ptype =D6 Dtemp =D6 Total =D7 HT=9 CR=13 XON=17 XOFF=19 SPACE=32 CTRL=-64 Cmd=^H0FF00 SCALE=128 ; =offset to SCALE value in BASIC impure area PHDR -1,0,PH$REE!PH$REU ; re-entrant & re-usable TST @Impure ; are we in Interactive BASIC? BNE Go TYPECR MOV JOBCUR,JCB ORW #J.CCC,JOBSTS(JCB) ; signal error to BASIC program RTN Go: MOV @Impure,Prog LEA LastLn,-6(Prog) ; last edited line stored in EXT word CLR LineNo ; pre-clear for word move MOVW (LastLn),LineNo CLR Length ; pre-clear for word moves CLR Line ; pre-clear last line number ADD #2,Prog ; now pointing to first line length TSTW @ArgBas ; any parameters passed? JEQ Next ; no, go to next line MOVB 2(ArgBas),Ptype ; get parameter type CMPB Ptype,#4 ; line number must be floating JEQ GetFlt CMPB Ptype,#2 ; is it string? BNE Syntax ; yes, go parse the string Parse: MOV 4(ArgBas),Atemp ; index the string MOVB @Atemp,Char ; get the command character UCS ; make it uppercase CMPB Char,#'F ; "First"? BNE 10$ CLR LineNo ; set next after zero JMP Next 10$: CMPB Char,#'L ; "Last"? JEQ FndLast CMPB Char,#'N ; "Next"? JEQ Next ; yes, goto next line CMPB Char,#'P ; "Previous"? JEQ FndPrev CMPB Char,#'I ; "Insert"? JEQ Insert Syntax: TTYI ASCII "?Syntax: XCALL ED,LineSpec" BYTE CR ASCII "LineSpec may be line number (floating expression) or" BYTE CR ASCII "F=First L=Last N=Next P=Previous I=Insert" BYTE CR,0 Empty: BYTE ' ,0 ; empty line for insert EVEN RTN Insert: ; find last edited line number INCW LineNo ; make sure next line# doesn't exist 10$: MOV Line,LastNo ADDW Length,Prog MOVW @Prog,Length MOVW 2(Prog),Line CMPW Line,#-1 ; trap reached end of prog BEQ OK CMPW Line,LineNo BLO 10$ BNE OK TYPECR RTN ; return to BASIC OK: LEA Prog,Empty ; point to empty line for insertion SUB #4,Prog MOVW #1,Length ; only one space there JMP Found FndPrev:MOV Line,LastNo ; find previous line number MOV Prog,Atemp ; save pointer ADDW Length,Prog MOVW @Prog,Length MOVW 2(Prog),Line CMPW Line,#-1 ; trap reached end of prog BEQ 10$ CMPW Line,LineNo BLO FndPrev 10$: MOV Atemp,Prog ; restore pointer to Prev line MOVW @Prog,Length MOVW 2(Prog),Line MOVW Line,LineNo JMP Found Next: MOV Line,LastNo MOV Prog,Atemp ; in case we pass end of program ADDW Length,Prog MOVW @Prog,Length MOVW 2(Prog),Line CMPW Line,#-1 ; trap reached end of prog BEQ SetLast CMPW Line,LineNo BLOS Next MOVW Line,LineNo JMP Found FndLast:MOV Line,LastNo ; search for last line MOV Prog,Atemp ; save pointer ADDW Length,Prog MOVW @Prog,Length MOVW 2(Prog),Line CMPW Line,#-1 ; trap reached end of prog BNE FndLast SetLast:MOV Atemp,Prog ; recall pointer MOVW @Prog,Length MOVW 2(Prog),Line ; recall line# MOVW Line,LineNo JMP Found GetFlt: MOV 4(ArgBas),Float ; get address of specified line# SUB #6,SP ; get some workspace MOV SP,Worksp ; point there MOVB (Float)+,(Worksp)+ ; get line# MOVB (Float)+,(Worksp)+ MOVB (Float)+,(Worksp)+ MOVB (Float)+,(Worksp)+ MOVB (Float)+,(Worksp)+ MOVB (Float)+,(Worksp)+ MOV SP,Worksp ; restore pointer MOV Scale(Impure),D7 ; scale factor in use? BEQ GetNum NEG D7 FPWR @Worksp,D7 ; yes, adjust the scaled value GetNum: FFTOL @Worksp,LineNo ; get specified line number ADD #6,SP ; return stack workspace TST LineNo BNE ChkTop Range: TYPECR RTN ChkTop: CMP LineNo,#65533 ; make sure line# within range BHI Range NxtLin: MOV Line,LastNo ADDW Length,Prog ; skip to next line MOVW @Prog,Length ; get next line length MOVW 2(Prog),Line ; get next line number CMPW Line,#-1 ; -1 means end of program found BEQ Passed CMPW Line,LineNo ; is this the matching line number? BLO NxtLin ; too low, keep searching BEQ Found ; yes, found it NotFnd: TYPECR RTN Passed: MOV LastNo,Number ; get last line number found BEQ Nil ; nothing found TYPE ; passed last existing line number DCVT 0,OT$TRM!OT$LSP ; so show what that line number is CRLF RTN Nil: TYPECR RTN Found: MOVW LineNo,@LastLn ; save last edited line# MOV JOBCUR,JCB MOV JOBTRM(JCB),TCB MOV T.IBS(TCB),Count SUB #5,Count ; allow for CR LF NULL, DBF pre-decr ; found specified line#, cursor up and clear eos to keep things neat MOVW #Cmd!3,CrtCmd ; cursor up TCRT MOVW #Cmd!10,CrtCmd ; clear to eos TCRT LEA String,4(Prog) ; now skip ahead to first blank/tab 10$: MOVB (String)+,Char CMPB Char,#SPACE BEQ 20$ CMPB Char,#HT ; have to output HT as single space BEQ 20$ ; else line editor will get confused DEC Length BR 10$ 20$: MOV LineNo,Number ; copy for DCVT SUB #8,SP ; get some memory workspace MOV SP,ASCBUF DCVT 0,OT$MEM!OT$TSP ; output line# to input buffer CLRB (ASCBUF) ; terminate with NULL MOV ASCBUF,Total SUB SP,Total ; calculate length of line number ADD Length,Total ; add length of line CMP Total,Count ; check if we have enough room BLOS PutNum ; yes, no warning Warning:TTYI ASCII "%Warning - Line longer than Input Buffer, " ASCII "excess cannot be displayed" BYTE CR,0 EVEN WaitOIP:TSTB T.STS(TCB) ; Wait for OIP to finish before BPL 10$ ; continuing SLEEP #500 ; sleep wastes less CPU time than BR WaitOIP ; a tight loop would 10$: ; output has finished PutNum: CLR Char MOVB #XOFF,Char ; suspend terminal output TRMICP ORW #J.TIW,JOBSTS(JCB) ; fake input wait state MOV SP,ASCBUF ; restore pointer to start of number NxtDig: MOVB (ASCBUF)+,Char ; get next digit BEQ PutLin ; terminate on NULL TRMICP DBF Count,NxtDig PutLin: ADD #8,SP ; return used workspace NxtChr: MOVB (String)+,Char ; reached NULL terminator in string? BEQ Done CMPB Char,#HT ; if it's a tab, convert to a space BNE 10$ MOVB #SPACE,Char 10$: TRMICP ; force it as input to self DBF Count,NxtChr Done: ANDW #^C,JOBSTS(JCB) ; undo fake input wait state MOVB #XON,Char ; re-enable terminal output TRMICP RTN ; (leave cursor positioned at the end of the displayed line) END .