/#E8# OS/8 EMACS CORE FUNCTIONS

	OCTAL
BELL=7		/ SPECIAL CHARACTERS
TAB=11
LF=12
CR=15
ESC=33
SP=40
BS=10
ZERO="0&177
LBRAK="[&177
SEMI=";&177
DOT=".&177
COMMA=",&177

/ NEW LINE IN BUFFER. GENERALLY CAN BE ANY CONTROL CHAR,
/ BUT THERE IS ONE PLACE (INSF1) THAT ASSUMES IT'S CR: IN
/ FILE INPUT TO CONVERT CR/LF TO NL BY DISCARDING LF.
NL=CR

/ DISPLAY SCREEN DIMENSIONS. WD * (HT+1) MUST BE <= 3968 TO AVOID
/ RUNNING INTO OS/8 USE OF LAST PAGE OF FIELD 1
	DECIMAL
IFNDEF SCRWD <SCRWD=80>
IFNDEF SCRHT <SCRHT=42>
TXTHT=SCRHT-2	/ SCREEN HEIGHT MINUS MODE LINES
	OCTAL	

/ FIELD DEFINITIONS
IFNDEF MEMSIZ <MEMSIZ=10>
BUFFLD=CDF 20		/ TEXT BUFFER START
ENDFLD=MEMSIZ^10+CDF	/ TEXT BUFFER END
CODFLD=CDF 0		/ CODE
SCRFLD=CDF 10		/ SCREEN COPY

/ ASSERTION FAILURE
FAIL=JMS I [ASSERT

/ PAGE 0

	*10
SRCP,	0	/ AUTOINDEX USED IN SOME LOOPS
DSTP,	0
TMP0,	0
TMP1,	0

	*20
BUF,	0; BUFFLD	/ START OF TEXT BUFFER
BUFEND,	0; ENDFLD	/ END OF TEXT BUFFER
POINT,	0; ENDFLD	/ INSERT/DELETE POINT (END OF GAP)
MARK,	0; BUFFLD	/ SEE COMMENTS IN EE.PA
TOS,	0; BUFFLD	/ TOP OF SCREEN
GAP,	0; BUFFLD	/ START OF GAP
SRCHP,	0; 0		/ SEARCH POINTER

CHANGD,	0  		/ NON-ZERO IF FILE HAS CHANGED
MLHOLD,	0		/ HOLD MODE LINE FOR ONE CYCLE
MKFLAG,	0		/ MARK BEFORE (0) OR AFTER (1) POINT
AC24,	0; 0		/ 24-BIT ACCUMULATOR
DSKEP,	0  		/ DSK HANDLER ENTRY POINT
BACKCH,	0		/ IF NON-ZERO, RE-READ THIS CHARACTER

UPDOWN,	0		/ STATE FOR ^N, ^P
FIXLOC,	0

SRCHC,	0  		/ SFWD, SREV CHARACTER
GOSTOP,	0; 0		/ END ADDRESS FOR MOVING FWD, REV

/ A ZONE (ENTIRE BUFFER OR JUST REGION) FOR WRITING TO A FILE
WRBEG,	0	/ POINTER TO 15-BIT BEGINNING BELOW GAP
WREND,	0	/ POINTER TO 15-BIT END ABOVE POINT
WRNAME,	0	/ POINTER TO FILENAME
WRSIZE,	0	/ FILE SIZE IN OS/8 BLOCKS (256 WORDS)

/ VARIABLES NEED FOR SCREEN UPDATE. ON PAGE 0 SINCE THE CODE SPANS
/ MULTIPLE PAGES
ROW,	0	/ SCREEN POSITION DURING UPDATE
COL,	0
CURROW,	0	/ POSITION OF POINT (CURSOR) FOUND DURING UPDATE
CURCOL,	0
BUFP,	0	/ POINTER INTO BUFFER (FIELD BITS AT RNDFLD)
SCRLIN,	0	/ POINTER TO CURRENT SCREEN LINE
SCRP,	0  	/ POINTER INTO SCREEN COPY IN FIELD 1
RNDP,	0	/ POINTER INTO RENDER BUFFER IN FIELD 1
RNDFLG,	0	/ RENDERING BEFORE (0) OR AFTER (1) GAP
RNDESC,	0	/ NEGATIVE GAP OR BUFEND ADDRESS

/ TEMP REGISTERS USED BY 15-BIT ADDRESS ROUTINES
A15,	0
B15,	0
C15,	0

/ USED TO RECOVER DELETED CHARS
RCVPT,	0; ENDFLD	/ POINT RECOVER ZONE
RCVGP,	0; BUFFLD	/ GAP RECOVER ZONE
LASTPT,	0; ENDFLD	/ PREVIOUS POINT
LASTGP,	0; BUFFLD	/ PREVIOUS GAP

/ PAGE 0 LITERALS
/   SRCHP POINT GAP BELL 10 NL -10 SP BUF -SP BUFEND SCRWD 77 SSTRNG
/ PAGE 0 LINKS
/   WR6 INC15 SNE15 WRTTY SFWDPT RDTTY GOFWD SREVGP CLRMLT UPDATE WRMLT
/   SFWD GOREV LD24 SUB15 SREV UPPER DEC15 USR INSERT DIVIDE GET15
/   RNDFIN GOBEG WRDEC SCHSTR RNDINI ADD15 SETFN FIXMRK CLRFN GOEND
/   7600 OFFER FIX24 WRRND GETFIL LUFILE WRSTR SCINIT INSFIL SKIPAN
/   FILENM+3 DEVNUM ERMLT WRITEF

/ TOP LEVEL
	*200	/------------
	TLS
	JMS I [SCINIT
	JMS IOINIT
	JMP I [7600	/ FILE SYS ERR, QUIT

TOP,	TAD MLHOLD	/ CLEAR MODE LINE TEXT UNLESS BEING HELD
	SNA CLA
	JMS I [CLRMLT
	DCA MLHOLD

	JMS I [FIXMRK	/ FIX MARK IF NECESSARY
	JMS RCZONE	/ MAINTAIN RECOVER ZONE
	JMS I [UPDATE	/ UPDATE SCREEN

	TAD UPDOWN	/ HANDLE ^N ^P STATE
	SMA CLA
	JMP TOPA
	TAD UPDOWN
	CIA
	JMP TOPB
TOPA,	TAD CURCOL
TOPB,	DCA UPDOWN

	JMS I [RDTTY	/ GET AND PROCESS CHAR INPUT
	TAD [-SP
	SPA
	JMP CTRL
	
	TAD [SP		/ NORMAL CHARACTER, INSERT
	JMS I [INSERT
	JMP ERR
	JMP TOP

/ CONTROL CHAR
CTRL,	TAD [SP
	TAD (CTABLE
ALTEX,	DCA CMD
	TAD I CMD
	SNA
	JMP ERR
	DCA CMD
	JMS I CMD
	JMP ERR
	JMP TOP

/ ERROR
ERR,	TAD [BELL
	JMS I [WRTTY
	JMP TOP

/ ALT PREFIX (ESCAPE SEQUENCE START)
ALTPRE,	0
	JMS I [RDTTY
	JMS I [UPPER
	AND [77
	TAD (ALTTBL
	JMP ALTEX

/ ^X COMMANDS. CONTROL, UPPER, AND LOWER CASE LETTERS ARE ALL
/ THE SAME, DUE TO SOME CONTROL CHARS BEING INTERCEPTED BY
/ LINUX, MOBAXTERM, OR SIM
CTRLX,	0
	TAD (30
	JMS I [WRMLT
	JMS I [UPDATE
	
	JMS I [RDTTY
	AND (37
	TAD (XTABLE
	JMP ALTEX

CMD,	0

/ SOME CONTROL CHARS ARE JUST INSERTED
INSTAB,	0
	TAD (TAB
	JMS I [INSERT
	SKP
	ISZ INSTAB
	JMP I INSTAB

NEWLN,	0
	TAD [NL
	JMS I [INSERT
	SKP
	ISZ NEWLN
	JMP I NEWLN

/ LF = NL, TAB
NLTAB,	0
	JMS NEWLN
	JMP I NLTAB
	JMS INSTAB
	JMP I NLTAB
	ISZ NLTAB
	JMP I NLTAB

/ READ QUOTED CHARACTER
GETQ,	0
	TAD (21
	JMS I [WRMLT
	JMS I [UPDATE
	JMS I [RDTTY
	JMP I GETQ
	
/ QUOTED INSERT
QUOTE,	0
	JMS GETQ
	JMS I [INSERT
	SKP
	ISZ QUOTE
	JMP I QUOTE

/ ALT-Q. LIKE ^Q, BUT REGULAR LETTERS ARE INTERPRETED AS CTRL
/ DUE TO SOME CTRL CHARS BEING INTERCEPTED
AQUOTE,	0
	JMS GETQ
	TAD (-100
	SMA
	JMP AQA
	CLA
	JMP I AQUOTE
AQA,	AND (37
	JMS I [INSERT
	JMP I AQUOTE
	ISZ AQUOTE
	JMP I AQUOTE

/ EXIT TO OS/8
EXIT,	0
	JMS I [OFFER
	JMP I EXIT

IFDEF FSCROL <
	TAD (ESC
	JMS I [WRTTY
	TAD (143
	JMS I [WRTTY
>
IFNDEF FSCROL <
	TAD (SCRHT-1
	DCA ROW
	DCA COL
	JMS SETCUR
>
	TSF		/ WAIT FOR TTY TO BE DONE BEFORE
	JMP .-1		/ EXITING TO OS/8
	JMP I [7600

	PAGE	/------------ 0400

CTABLE,	SETMRK;	BEGLN;	BACK;	0;	DELFWD;	ENDLN;	FWD;	0
	DELREV;	INSTAB;	NLTAB;	KEOL;	REDRAW;	NEWLN;	NXTLN;	OPEN
	PRVLN;	QUOTE;	0;	ISRCH;	0;	0;	FWDSCR;	DELREG
	CTRLX;	YANK;	EXIT;	ALTPRE;	SCRLUP;	0;	0;	0

ALTTBL,	0;	BEGLN;	BACKWD;	0;	DLFWWD;	ENDLN;	FWDWD;	0
	DLRVWD;	0;	0;	0;	0;	0;	SCHNXT;	0
	0;	AQUOTE;	RECOVR;	ISRCH;	0;	0;	REVSCR;	WRREG
	0;	0;	0;	KEYS;	SCRLDN;	0;	0;	0

	0;	0;	0;	0;	0;	QREPL;	0;	0
	0;	0;	0;	0;	0;	0;	0;	0
	0;	0;	0;	0;	0;	0;	0;	0
	0;	0;	0;	0;	GOBEG;	0;	GOEND;	0

XTABLE,	0;	0;	0;	0;	0;	0;	FFILE;	0
	0;	INFILE;	0;	0;	0;	0;	0;	0
	0;	0;	RDMORE;	SVFILE;	0;	0;	0;	WRFILE
	EXGPM;	0;	0;	0;	0;	0;	0;	0

	
	PAGE	/------------ 0600
/ CHARACTER I/O

RDTTY,	0
	JMS REREAD
	JMP I RDTTY
	KSF
	JMP .-1
	KRB
	AND (177

	TAD (-177	/ CONVERT DELETE TO BACKSPACE TO HANDLE
	SNA		/ MODERN ENTER KEY, WHICH MIGHT SEND
	TAD (BS-177	/ EITHER	
	TAD (177
	JMP I RDTTY

/ WRITE 0-TERMINATED STRING TO SUBROUTINE WHOSE
/ ADDRESS FOLLOWS JMS
WRSTR,	0
	DCA WRSTRP
	TAD I WRSTR
	DCA WRSUB
	ISZ WRSTR
	
WRSTRA,	TAD I WRSTRP
	SNA
	JMP I WRSTR
	ISZ WRSTRP
	JMS I WRSUB
	JMP WRSTRA

WRSTRP,	0

/ WRITE AC DECIMAL, UNSIGNED, TO SUBROUTINE WHOSE
/ ADDRESS FOLLOWS JMS
WRDEC,	0
	DCA AC24
	DCA AC24+1
	TAD (W10BUF		/ SET UP BUFFER
	DCA W10P
	TAD I WRDEC		/ GET SUBROUTINE
	DCA WRSUB
	ISZ WRDEC

WRDECA,	TAD (12			/ NEXT DIGIT, REVERSE ORDER
	JMS I [DIVIDE
	TAD AC24+1
	TAD (ZERO
	DCA I W10P
	ISZ W10P
	DCA AC24+1
	TAD AC24
	SZA CLA
	JMP WRDECA

WRDECB,	STA			/ WRITE DIGITS IN REVERSE
	TAD W10P
	DCA W10P
	TAD I W10P
	JMS I WRSUB
	TAD W10P
	TAD (-W10BUF
	SZA CLA
	JMP WRDECB

	JMP I WRDEC

W10P,	0
W10BUF,	ZBLOCK 4
WRSUB,	0

W8CNT=W10P
W8NUM=W10BUF

/ WRITE AC OCTAL, UNSIGNED, TO SUBROUTINE WHOSE
/ ADDRESS FOLLOWS JMS.
WROCT,	0
	DCA W8NUM
	TAD I WROCT
	DCA WRSUB
	ISZ WROCT
	TAD (-4
	DCA W8CNT
WROCTA,	TAD W8NUM
	CLL RTL; RAL
	DCA W8NUM
	TAD W8NUM
	RAL
	AND (7
	TAD (ZERO
	JMS I WRSUB
	ISZ W8CNT
	JMP WROCTA
	JMP I WROCT

/ INSERT AC AT POINT
INSERT,	0
	DCA C15			/ BUFFER FULL (GAP == POINT)?
	TAD [GAP
	JMS I [SNE15; POINT
	JMP INSFUL
	ISZ INSERT

	TAD C15			/ NO, CHAR GOES IN GAP
	JMS PUT15; GAP
	TAD [GAP
	JMS I [INC15
	STA
	DCA CHANGD
	JMP I INSERT

INSFUL,	TAD (FULMSG		/ BUFFER FULL
	JMS I [WR6
	WRMLT
	ISZ MLHOLD
	JMP I INSERT
FULMSG,	TEXT / BUFFER FULL!/

/ 15-BIT POINTERS ARE TWO WORDS, ADDRESS FOLLOWED BY CDF THAT
/ HOLDS FIELD.

/ INCREMENT 15-BIT POINTER.
INC15,	0
	DCA A15
	ISZ I A15
	JMP I INC15
	ISZ A15
	TAD I A15
	TAD [10
	DCA I A15
	JMP I INC15
	
	PAGE	/------------ 1000

WRTTY,	0
	TSF
	JMP .-1
	TLS
	CLA
	JMP I WRTTY

/ DECREMENT 15-BIT POINTER
DEC15,	0
	DCA A15
	STA STL
	TAD I A15
	DCA I A15
	SNL
	JMP I DEC15
	ISZ A15
	TAD I A15
	TAD [-10
	DCA I A15
	JMP I DEC15

/ FETCH FROM 15-BIT POINTER
GET15,	0
	DCA A15
	TAD I A15
	DCA B15
	ISZ A15
	TAD I A15
	DCA .+1
	0
	TAD I B15
	CODFLD
	JMP I GET15

/ STORE AC AT 15-BIT POINTER WHOSE ADDRESS FOLLOWS JMS
PUT15,	0
	DCA C15
	TAD I PUT15
	ISZ PUT15
	DCA A15
	TAD I A15
	DCA B15
	ISZ A15
	TAD I A15
	DCA .+1
	0
	TAD C15
	DCA I B15
	CODFLD
	JMP I PUT15

/ SKIP IF TWO 15-BIT POINTERS ARE NOT EQUAL. AC AND FOLLOWING WORD
/ HAVE ADDRESS OF THE POINTERS
SNE15,	0
	DCA A15
	TAD I SNE15
	ISZ SNE15
	DCA B15

	TAD I A15
	CIA
	TAD I B15
	SZA CLA
	JMP SNE15A

	ISZ A15
	ISZ B15
	TAD I A15
	CIA
	TAD I B15
	SZA CLA
SNE15A,	ISZ SNE15
	JMP I SNE15

/ MOVE POINT FORWARD 1, SKIP IF OK
FWD,	0
	TAD [POINT		/ OK TO MOVE?
	JMS I [SNE15; BUFEND
	JMP I FWD
	ISZ FWD			/ YES, SKIP RETURN
	
	JMS I [SFWDPT		/ MOVE ONE FORWARD
	TAD [SRCHP
	JMS I [INC15
	JMS I [GOFWD
	JMP I FWD

/ MOVE POINT BACK 1, SKIP IF OK
BACK,	0
	TAD [BUF		/ OK TO MOVE?
	JMS I [SNE15; GAP
	JMP I BACK
	ISZ BACK		/ YES, SKIP RETURN

	JMS I [SREVGP
	TAD [SRCHP
	JMS I [DEC15
	JMS I [GOREV
	JMP I BACK
/#EA#

/ DELETE FORWARD
DELFWD,	0
	TAD [POINT		/ AT END (POINT == BUFEND)?
	JMS I [SNE15; BUFEND
	JMP I DELFWD
	ISZ DELFWD

	TAD [POINT		/ NO, JUST INCREMENT POINY
	JMS I [INC15
	STA
	DCA CHANGD

	JMP I DELFWD

/ DELETE REVERSE
DELREV,	0			/ BACK ONE AND THEN DELETE FORWARD
	JMS BACK
	JMP I DELREV
	JMS DELFWD
	FAIL
	ISZ DELREV
	JMP I DELREV

/ BEGINNING OF BUFFER. ASSUME BUFFER STARTS AT ADDRESS 0 IN SOME FIELD.
GOBEG,	0
	DCA SRCHP		/ SRCHP = BEGINNING OF BUFFE
	TAD (BUFFLD
	DCA SRCHP+1
	JMS I [GOREV		/ GO THERE
	ISZ GOBEG
	JMP I GOBEG

/ END OF BUFFER. ASSUME BUFFER ENDS AT ADDRESS 0 IN SOME FIELD
/ (INCLUDING IMAGINARY FIELD 10)
GOEND,	0
	DCA SRCHP		/ SRCHP = END OF BUFFER
	TAD (ENDFLD
	DCA SRCHP+1
	JMS I [GOFWD		/ GO THERE
	ISZ GOEND
	JMP I GOEND

/ OPEN NEW LINE
OPEN,	0
	JMS NEWLN
	JMP I OPEN
	JMS BACK
	FAIL
	ISZ OPEN
	JMP I OPEN

 	PAGE	/------------ 1200

REREAD,	0
	TAD BACKCH
	SZA
	JMP RERDA
	ISZ REREAD
	JMP I REREAD

RERDA,	DCA RDBACK
	DCA BACKCH
	TAD RDBACK
	JMP I REREAD
RDBACK,	0

/ END OF LINE
ENDLN,	0
	ISZ ENDLN		/ CAN'T FAIL
	JMS I [SFWDPT		/ SEARCH FORWARD FOR NL
	TAD [NL
	JMS I [SFWD
	JMP ENDLNA
	JMS I [GOFWD		/ FOUND GO THERE
	JMP I ENDLN
ENDLNA,	JMS I [GOEND		/ NOT FOUND, GO TO END
	FAIL 			/ CAN'T FAIL
	JMP I ENDLN
	
/ NEXT LINE
NXTLN,	0
	JMS I [SFWDPT		/ SEARCH FORWARD FOR NL
	TAD [NL
	JMS I [SFWD
	JMP I NXTLN
	TAD [SRCHP		/ SKIP OVER NL
	JMS I [INC15
	JMS I [GOFWD		/ GO THERE
	JMS FIXCOL
	ISZ NXTLN
	JMP I NXTLN

/ BEGINNING OF LINE
BEGLN,	0
	ISZ BEGLN		/ CAN'T FAIL
	JMS I [SREVGP		/ SEARCH BACK FOR NL
	TAD [NL
	JMS I [SREV
	JMP BEGLNA
	TAD [SRCHP		/ SKIP OVER NL
	JMS I [INC15
	JMS I [GOREV		/ GO THERE
	JMP I BEGLN
BEGLNA,	JMS I [GOBEG		/ NOT FOUND, GO TO BEGINNING
	FAIL
	JMP I BEGLN

/ PREVIOUS LINE
PRVLN,	0
	JMS I [SREVGP		/ SEARCH REVERSE FOR NL
	TAD [NL
	JMS I [SREV
	JMP I PRVLN
	JMS I [GOREV		/ GO THERE
	JMS BEGLN		/ THEN TO BEGINNING OF THAT LINE
	FAIL
	JMS FIXCOL
	ISZ PRVLN
	JMP I PRVLN

/ SEARCH FORWARD FROM SRCHP FOR CHAR IN AC. IF FOUND UPDATE SRCHP
/ AND SKIP. SRCHP >= POINT. FOR SPEED, DON'T USE 15-BIT ADDRESS
/ SUBROUTINES
SFWD,	0
	CIA
	DCA SRCHC
	TAD SRCHP+1
	DCA SFWDF

SFWDA,	TAD SRCHP	/ DONE (SRCHP == BUFEND)?
	SZA CLA
	JMP SFWDF
	TAD SFWDF
	TAD (-ENDFLD
	SNA CLA
	JMP SFWDC
	
SFWDF,	0		/ NOT DONE, MATCH?
	TAD I SRCHP
	TAD SRCHC
	SNA CLA
	JMP SFWDB
	ISZ SRCHP	/ NO MATCH, SRCHP++
	JMP SFWDA
	TAD SFWDF
	TAD [10
	DCA SFWDF
	JMP SFWDA

SFWDB,	TAD SFWDF	/ MATCH, STORE FINAL FIELD
	DCA SRCHP+1
	ISZ SFWD
SFWDC,	CODFLD
	JMP I SFWD

/ SEARCH REVERSE FROM SRCHP-1 FOR CHAR IN AC. IF FOUND UPDATE SRCHP
/ AND SKIP. SRCHP <= GAP. FOR SPEED, DON'T USE 15-BIT ADDRESS
/ SUBROUTINES
SREV,	0
	CIA
	DCA SRCHC
	TAD SRCHP+1
	DCA SREVF

SREVA,	TAD SRCHP	/ DONE (SRCHP == BUF)
	SZA CLA
	JMP SREVC
	TAD SREVF
	TAD (-BUFFLD
	SNA CLA
	JMP SREVD
	
SREVC,	STA STL		/ NOT DONE, --SRCHP
	TAD SRCHP
	DCA SRCHP
	SNL CLA
	JMP SREVF
	TAD SREVF
	TAD [-10
	DCA SREVF

SREVF,	0		/ MATCH?
	TAD I SRCHP
	TAD SRCHC
	SZA CLA
	JMP SREVA

SREVB,	TAD SREVF	/ YES
	DCA SRCHP+1
	ISZ SREV
SREVD,	CODFLD
	JMP I SREV

/ ASSERTION FAILURE, FATAL ERROR
ASSERT,	0
	TAD (FAILMS
	JMS I [WR6
	WRTTY
	TAD ASSERT
	JMS WROCT
	WRTTY
	JMP I [7600

 	PAGE	/------------ 1400

/ SET UP TO SEARCH FORWARD FROM POINT
SFWDPT,	0
	TAD POINT
	DCA SRCHP
	TAD POINT+1
	DCA SRCHP+1
	JMP I SFWDPT

/ SET UP TO SEARCH REVERSE FROM GAP
SREVGP,	0
	TAD GAP
	DCA SRCHP
	TAD GAP+1
	DCA SRCHP+1
	JMP I SREVGP

/ GO FORWARD FROM POINT TO SRCHP. POINT <= SRCHP <= BUFEND.
/ THIS IS POTENTIALLY THE SLOWEST EDIT OPERATION, SINCE IT
/ CAN MOVE LOTS OF CHARACTERS, SO DON'T USE 15-BIT ADDRESS
/ SUBROUTINES. 20 CYCLES = 30 US PER CHARACTER (8/I).
GOFWD,	0
	TAD SRCHP		/ GET -STOP ADDRESS
	CIA
	DCA GOSTOP
	TAD SRCHP+1
	CIA
	DCA GOSTOP+1
 
	TAD POINT+1		/ SET UP CDF INSTRUCTIONS
	DCA GOFWDP
	TAD GAP+1
	DCA GOFWDG

GOFWDA,	TAD POINT		/ AT STOP POINT?
	TAD GOSTOP
	SZA CLA
	JMP GOFWDP
	TAD GOFWDP
	TAD GOSTOP+1
	SZA CLA
	JMP GOFWDP
	
	CODFLD			/ YES, UPDATE POINT AND GAP
	TAD GOFWDP		
	DCA POINT+1
	TAD GOFWDG
	DCA GAP+1
	JMP I GOFWD		/ AND DONE

GOFWDP,	0     			/ MOVE CHAR FROM POINT TO GAP
	TAD I POINT
GOFWDG,	0
	DCA I GAP

	ISZ POINT		/ ++POINT
	JMP GOFWDB
	TAD GOFWDP
	TAD [10
	DCA GOFWDP
GOFWDB,	ISZ GAP			/ ++GAP
	JMP GOFWDA
	TAD GOFWDG
	TAD [10
	DCA GOFWDG

	JMP GOFWDA		/ NEXT

/ GO BACKWARDS FROM GAP TO SRCHP. BUF <= SRCHP <= GAP
/ 29 CYCLES = 43.5 US PER CHARACTER (8/I)
GOREV,	0
	TAD SRCHP		/ GET -STOP ADDRESS
	CIA
	DCA GOSTOP
	TAD SRCHP+1
	CIA
	DCA GOSTOP+1
	
	TAD POINT+1		/ SET UP CDF INSTRUCTIONS
	DCA GOREVP
	TAD GAP+1
	DCA GOREVG

GOREVA,	TAD GAP			/ AT STOP POINT?
	TAD GOSTOP
	SZA CLA
	JMP GOREVC
	TAD GOREVG
	TAD GOSTOP+1
	SZA CLA
	JMP GOREVC

	CODFLD			/ YES, UPDATE POINT AND GAP
	TAD GOREVP
	DCA POINT+1
	TAD GOREVG
	DCA GAP+1
	JMP I GOREV		/ DONE

GOREVC,	STA STL			/ --POINT
	TAD POINT
	DCA POINT
	SNL
	JMP GOREVB
	TAD GOREVP
	TAD [-10
	DCA GOREVP

GOREVB,	STA STL			/ --GAP
	TAD GAP
	DCA GAP
	SNL
	JMP GOREVG
	TAD GOREVG
	TAD [-10
	DCA GOREVG

GOREVG,	0			/ MOVE CHAR FROM GAP TO POINT
	TAD I GAP
GOREVP,	0
	DCA I POINT
	JMP GOREVA

/ COMPUTE NUMBER OF CHARS IN BUFFER, PUT IN AC24
BUFSIZ,	0
	TAD [BUFEND
	JMS I [LD24
	TAD [BUF
	JMS I [SUB15
	TAD [POINT
	JMS I [SUB15
	TAD [GAP
	JMS I [ADD15
	JMS I [FIX24
	JMP I BUFSIZ

/#EB# UPDATE SCREEN, MODE LINE

	PAGE	/------------ 1600

/ THESE MARKS MUST BE NEGATIVE AND DISTINCT. THE LSB IS CLEAR FOR EXTENDED
/ (LINE LONGER THAN SCRWD-1)
SMARK=STA		/ 7777 MARK END OF NORMAL SCREEN LINE
SMARKX=STL CLA RAR	/ 4000 MARK END OF EXTENDED SCREEN LOINE
RMARK=STA CLL RTL	/ 7775 MARK END OF NORMAL REDNER LINE
RMARKX=STA CLL RAL	/ 7776 MARK END OF EXTENDED RENDER LINE

RNDBUF=SCRWD^SCRHT	/ LOCATION OF RENDER BUFFER (ONE SCRWD LINE)
RNDEND=RNDBUF+SCRWD

/ CLEAR RENDER BUFFER, COL = 0
RNDINI,	0
	DCA COL
	TAD (RNDBUF
	DCA RNDP
	RMARK
	DCA RNDMRK
	JMP I RNDINI

/ END RENDER LINE
RNDFIN,	0
	TAD RNDMRK		/ MARK END
	SCRFLD
	DCA I RNDP
	CODFLD
	JMP I RNDFIN

RNDMRK,	0

/ RENDER CURRENT LINE OF TEXT BUFFER TO RENDER BUFFER
RENDER,	0
	JMS I [RNDINI
	TAD (-SCRWD
	DCA RNDLIM

RNDA,	TAD BUFP		/ POSSIBLE GAP OR END?
	TAD RNDESC
	SNA CLA
	JMP RNDB

RNDFLD,	0			/ FETCH CHAR FROM TEXT BUFFER
	TAD I BUFP
	ISZ BUFP		/ UPDATE BUFFER POINTER
	JMP RNDG
	DCA RNDTMP
	TAD RNDFLD
	TAD [10
	DCA RNDFLD
	TAD RNDTMP

RNDG,	TAD [-SP		/ CONTROL CHAR?
	SCRFLD
	SPA
	JMP RNDC

	TAD [SP			/ NO, PUT IN BUFFER
	DCA I RNDP
	ISZ RNDP
	ISZ RNDLIM		/ DID IT FIT?
	JMP RNDA

RNDZ,	STA			/ NO, BACK UP
	DCA RNDLIM
	STA
	TAD RNDP
	DCA RNDP
	RMARKX			/ SET EXTENDED LINE MARK
	DCA RNDMRK
	JMP RNDA

RNDB,	TAD RNDFLG		/ LOOKING FOR GAP OR END OF BUFFER?
	SZA CLA
	JMP RNDE
	TAD RNDFLD		/ SKIP OVER GAP?
	CIA
	TAD GAP+1
	SZA CLA
	JMP RNDFLD

	TAD POINT		/ YES, SKIP OVER GAP
	DCA BUFP
	TAD POINT+1
	DCA RNDFLD
	TAD ROW			/ SAVE CURSOR POSITION
	DCA CURROW
	TAD RNDLIM
	TAD [SCRWD
	DCA CURCOL

	ISZ RNDFLG		/ SET FLAG TO LOOK FOR END OF BUFFER
	DCA RNDESC
	TAD BUFP		/ END OF BUFFER ADDRESS IS 0
	SZA CLA
	JMP RNDFLD

RNDE,	TAD RNDFLD		/ END OF BUFFER?
	CIA
	TAD BUFEND+1
	SZA CLA
	JMP RNDFLD
	JMP RNDX		/ YES, DONE

RNDC,	TAD (SP-TAB		/ TAB?
	SZA
	JMP RNDF
	TAD RNDLIM		/ YES, GET NUMBER OF SPACES TO WRITE
	TAD [SCRWD
	AND (7
	TAD (7770
	DCA RNDTMP
RNDD,	TAD [SP			/ NEXT SPACE
	DCA I RNDP
	ISZ RNDP
	ISZ RNDLIM		/ DID IT FIT?
	SKP
	JMP RNDZ
	ISZ RNDTMP
	JMP RNDD
	JMP RNDA

RNDF,	TAD (TAB-NL		/ END OF LINE?
	SNA
	JMP RNDX

	TAD (NL+100		/ CONTROL CHAR
	DCA RNDTMP
	TAD (136		/ ^
	DCA I RNDP
	ISZ RNDP

	ISZ RNDLIM		/ DID IT FIT?
	SKP
	JMP RNDZ

	TAD RNDTMP		/ YES, CHAR
	DCA I RNDP
	ISZ RNDP	
	ISZ RNDLIM
	JMP RNDA
	JMP RNDZ
	
RNDX,	JMS I [RNDFIN		/ MARK END OF BUFFER
	JMP I RENDER

RNDLIM,	0
RNDTMP,	0

	PAGE  /------------------ 2000

/ WRITE RENDERED LINE TO SCREEN. COMPARE TO SCREEN COPY, BE
/ FRUGAL IN WRITING CHARACTERS TO TTY
WRSCR,	0
	STA			/ SCREEN COPY ADDRESS
	TAD SCRLIN
	DCA DSTP
	TAD (RNDBUF-1		/ RENDER BUF
	DCA SRCP
	DCA WRFLAG		/ FLAG = FALSE
	SCRFLD

WRSCRA,	TAD I SRCP		/ FAST SCAN FOR MISMATCH
	CIA   			/ END OF LINE IS ALWAYS A MISMATCH
	TAD I DSTP
	SNA CLA
	JMP WRSCRA

	TAD SRCP		/ RECOVER POINTERS
	DCA RNDP
	TAD DSTP
	DCA SCRP
	TAD RNDP		/ RECOVER COL
	TAD (-RNDBUF
	DCA COL

	TAD I RNDP		/ END OF BOTH?
	AND I SCRP
	SPA CLA
	JMP WRSCRX		/ YES, CHECK EXTENDED

	CODFLD			/ SOME DIFFERENCE
	JMS SETCUR		/ SET CURSOR TO BEGIN FIXING

WRSCRD,	SCRFLD
	TAD I RNDP		/ END OF SCREEN LINE,
	CMA			/ AND NOT END OF RENDER LINE?
	AND I SCRP
	SPA CLA
	ISZ WRFLAG		/ YES, SET FLAG
	TAD I RNDP		/ END OF RENDERED LINE?
	SPA
	JMP WRSCRC
	DCA I SCRP		/ NO, UPDATE SCREEN
	TAD I RNDP
	CODFLD
	JMS I [WRTTY
	ISZ RNDP
	ISZ SCRP
	JMP WRSCRD

WRSCRC,	CLA
	TAD I RNDP		/ END OF RENDERED LINE, EXTENDED?
	RAR
	SZL CLA
	JMP WRSCRB

	TAD (76			/ YES, SET EXTENDED MARKS
	JMS I [WRTTY
	ISZ WRFLAG		/ PREVENT CLEAR TO EOL
	SMARKX
	JMP WRSCRE
	
WRSCRB,	SMARK			/ END OF RENDERED LINE, MARK SCREEN
WRSCRE,	DCA I SCRP
	CODFLD
	TAD WRFLAG		/ CLEAR TO END OF LINE IF NECESSARY
	SZA CLA
	JMP I WRSCR
	TAD (CLREOL
	JMS I [WRSTR
	WRTTY
	JMP I WRSCR

WRSCRX,	TAD I RNDP		/ NO CHANGES SO FAR, EXTENDED BITS AGREE?
	TAD I SCRP
	CODFLD
	RAR
	SNL CLA
	JMP I WRSCR

	JMS SETCUR		/ SET CURSOR
	SCRFLD			/ FIX END OF LINE
	JMP WRSCRC

CLREOL,	ESC; LBRAK; "K; 0
WRFLAG,	0			/ ZERO MEANS OLD LINE LONGER THAN NEW

/ NEXT SCREEN ROW. SKIP IF NO CHARACTERS WAITING
NXTROW,	0
	ISZ ROW
	TAD SCRLIN
	TAD [SCRWD
	DCA SCRLIN
	KSF
	ISZ NXTROW
	JMP I NXTROW

/ UPDATE SCREEN
UPDATE, 0
	JMS SETTOS		/ SET TOP OF SCREEN

	DCA SCRLIN		/ INITIALIZATIONS
	DCA SCRP
	DCA ROW

	DCA RNDFLG		/ START BEFORE GAP
	TAD GAP
	CIA
	DCA RNDESC

	TAD TOS			/ BUFP = TOS
	DCA BUFP
	TAD TOS+1
	DCA RNDFLD
	
UPDA,	JMS RENDER		/ RENDER AND WRITE TEXT BUFFER
	JMS WRSCR
	JMS NXTROW
	JMP UPDB
	TAD ROW
	TAD (-TXTHT		/ LEAVE ROOM FOR STATUS LINES
	SZA CLA
	JMP UPDA

	JMS RMODE		/ RENDER AND WRITE MODE LINE
	JMS WRSCR
	JMS NXTROW
	JMP UPDB
	JMS RNDMLT
	JMS WRSCR

	TAD CURROW		/ SET CURSOR AT POINT
	DCA ROW
	TAD CURCOL
	DCA COL
	JMS SETCUR

UPDB,	JMP I UPDATE
