;> Editor
 LEADR &1D0000
ORIGIN
CR * 13
LF * 10
TERM * LF
STYLE * 1 ;style 0 JGT, 1 Book
RELEASE * 0 ;looses GCAL and m2 structs; reverts to oldmail
 [ RELEASE=1
OLDMAIL * 1
ARTHUR * 0
WIDTH * 80
 |
WIDTH * 80; 132
OLDMAIL * -1 ;-1=SonOfEcomail 3, 0=SonOfEcomail, 1=Ecomail
ARTHUR * 1 ;1 for new callback stuff
 ]
; There are 10 buffers, 0 to 9, available. They are laid out in memory in
; consecutive memory chunks with 0 at the lowest address. Each buffer has:
; info area (256 bytes)      page start      gs ge  end top
; |                          |    | (page+1) |  |   |   | (end+1)

 ^ 0
WRITEC # 1
WRITES # 1
WRITE0 # 1
NEWLINE # 1
READC # 1
CLI # 1
BYTE # 1
WORD # 1
FILE # 1
ARGS # 1
BGET # 1
BPUT # 1
MULTIPLE # 1
OPEN # 1
READLINE # 1
CONTROL # 1
GETENV # 1
EXIT # 1
SETENV # 1
INTON # 1
INTOFF # 1
CALLBACK # 1
ENTERSWI # 1
BREAKPT # 1
BREAKCT # 1
UNUSEDSWI # 1
SETMEMC # 1
SETCALLBACK # 1
WRITEI * 256
 ^ 0
NONE # 1
TOCRLONG # 1 ;update to next Newline: the line is getting longer
TOCRSHORT # 1 ;ditto but shorter
CSRONWARDS # 1
HARDUP # 1
HARDDN # 1
FULLSCREEN # 1
BOTHSCREEN # 1
THELOT # 1
ABORT * &80 ;abortable if set
;variables accessed off ARGP
 ^ 0
MINY # 1
MAXY # 1
TUTMODE # 2

ERRCTL # 1 ;also gives cursor editing if 255
TASK # 1
BCOL # 1
OLDUPDATE # 1

MAXFLD # 1
TABCHA * MAXFLD
CFILEH # 1
ESCFLG # 1
TASKLINK # 1

WIPESTYLE # 1
 # 3

USINGAP # 4
REPADR # 4
HIMEM # 4
;7*4 so far
FIELDT # 20
SCRIM # 32 ;20*4 so far
CALLER # 16
FRBUFF # 80
GRBUFF # 80 ;256 so far
STRACC # 256
TRANS # 256 ;xlated search strings
AREA0 # 256
AREA1 # 256
MSTACK # 1024 ;holds *path
TASKBUF # 1024
ENDIT # 0

 ^ 0 ;allocation relative to areas
TSM # 1
BSM # 1
SLINE # 1
ELINE # 1 ;not copied into buffer area
PAGE # 4
TOP # 4
START # 4
GS # 4
GE # 4
END # 4
;only number of characters and offset of gap copied into buffer area
;see next allocation section
MARKTB # 4*2 ;character numbers
FLEXEC # 4 ;a read time to flexec does lsb of flload
FLLOAD # 4

X # 1
Y # 1
MODIFY # 1 ;lsb general mod; next bit lf<>cr mod
MARKS # 1

INSERT # 1
SHOWCR # 1
TABMOD # 1
BUFFNO # 1
PUSHNO # 1
TASKQ # 1 ;1 if a task is running in this window
ONSCREEN # 1 ;set if onscreen

NAMBUFF # 54

 ^ 0 ;allocation of buffer information when in buffer
;this is mostly as above with the exception of the first 7 words which are:
CHARSTOGS # 4
TOTALCHARS # 4

R0 RN 0
R1 RN 1
R2 RN 2
R3 RN 3
R4 RN 4
R5 RN 5
R6 RN 6
R7 RN 7
R8 RN 8
R9 RN 9
R10 RN 10
R11 RN 11
R12 RN 12
R13 RN 13
R14 RN 14
R15 RN 15
PC RN R15
SP RN R13
AP RN R12
ARGP RN R11
UPDATE RN R10
FLAGR RN R9
;Flagr contains the following bitpositioned flags for replace
REPLFLAG * 1
SENSFLAG * 2
MULFFLAG * 4
METAFLAG * 8
;Symbols for translated strings
 ^ &80
NSENSYM # 1
WILDSYM # 1
NOTSYM # 1
ALPHASYM # 1
DIGSYM # 1
SUBRSYM # 1
SETSYM # 1
ESCSYM # 1

MAXSYM # 1
MULTSYM # 1
TERMSYM # 1

FIELDSYM # 1
FOUNDSYM # 1

 B MAIN
 MACRO
$L PACK $A,$B
$L = $A,($A):SHR:8,$B,($B):SHR:8
 MEND
SETSTART ADR R1,ORIGIN
 MOV PC,R14
INCORE BL RDHEX
 MOV R6,R5
 TEQ R2,#","
 BNE EDITAL
 BL RDHEX
 CMP R2,#";"
 TEQNE R2,#0
 BNE EDITAL
 BCC INCOR0
 ADD R7,ARGP,#CALLER
REMCAL LDRB R2,[R0],#1
 STRB R2,[R7],#1
 TEQ R2,#0
 BNE REMCAL
INCOR0 CMP R5,R6
 BLS EDITAL
 LDR R7,[AP,#GE]
INCOR1 LDRB R0,[R5,#-1]!
 STRB R0,[R7,#-1]!
 CMP R5,R6
 BNE INCOR1
 STR R7,[AP,#GE]
 B EDITAL
RDHEX MOV R5,#0
 MOV R4,#32-4
RDHEX1 LDRB R2,[R0],#1
 CMP R2,#"0"
 BCC EDITAL
 CMP R2,#"9"+1
 BCC RDHEX2
 CMP R2,#"A"
 BCC EDITAL
 CMP R2,#"F"+1
 BCS EDITAL
 SUB R2,R2,#"A"-"9"-1
RDHEX2 AND R2,R2,#&F
 ORR R5,R5,R2,LSL R4
 SUBS R4,R4,#4
 BPL RDHEX1
 LDRB R2,[R0],#1
 MOV PC,R14
INITHAN ADR R0,ERRHAN
 ADD R1,ARGP,#TRANS
 ADR R2,ESCHAN
 ADR R3,EVTHAN
 SWI CONTROL
 MOV PC,R14
ERRHAN BL SETARGP
 ADD R4,ARGP,#TRANS
 ADD R4,R4,#8
 B MSGIN
ESCHAN B ESCHAM
EVTHAN B EVTHAM
TSTESC LDRB ARGP,[ARGP,#ESCFLG]
 TST ARGP,#&80
 BEQ SETARGP ;and so exit
ESCAPE MOV R0,#&7E
 SWI BYTE
 BL SETARGP
 BL SELFWD
 BL ERRDEF
 BL SCRIMI
 BL INITED
 MOV R0,#0
 STRB R0,[ARGP,#ERRCTL]
 SWI WRITEI+13
 B EDITAL
MAIN TSTP PC,#0 ;Go to User mode
ENTRY BL SETARGP
 SWI GETENV
 MOV SP,R1
 ADD R2,ARGP,#ENDIT
 CMP R2,SP
 BCC ENTRY1
 SWI WRITES
 = "Insufficient memory to (re)start Twin at this address",10,13,0
 SWI EXIT
ENTRY1 LDRB R1,[R0],#1
 CMP R1,#0
 BEQ NOTWARM
 CMP R1,#" "
 BNE ENTRY1
WARM1 LDRB R1,[R0],#1
 CMP R1,#" "
 BEQ WARM1
 CMP R1,#"-"
 BNE NOTWARM
 LDRB R1,[R0],#1
 BIC R1,R1,#" "
 CMP R1,#"W"
 BNE NOTWARM1
 LDRB R1,[R0],#1
 CMP R1,#"A"
 CMPNE R1,#"a"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#"R"
 CMPNE R1,#"r"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#"M"
 CMPNE R1,#"m"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#0
 BNE NOTWARM
 BL INITED
 BL SETARGP
 LDR SP,[ARGP,#HIMEM]
 LDR AP,[ARGP,#USINGAP]
 BL INITHAN
 MOV R0,#0
 STRB R0,[ARGP,#ERRCTL]
 B REENTER
NOTWARM1 CMP R1,#"H"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#"E"
 CMPNE R1,#"e"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#"L"
 CMPNE R1,#"l"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#"P"
 CMPNE R1,#"p"
 BNE NOTWARM
 LDRB R1,[R0],#1
 CMP R1,#0
 BNE NOTWARM
 SWI WRITES
 = "Twin understands -help, -warm and <file> or <file> <file>",10,13,0
 SWI EXIT
NOTWARM MOV R0,#CR
 STRB R0,[ARGP,#FRBUFF]
 STRB R0,[ARGP,#GRBUFF]
 STRB R0,[ARGP,#TUTMODE+1]
 ADD R1,ARGP,#STRACC
 STRB R0,[R1]
 MOV R0,#0
 STR R0,[ARGP,#ERRCTL] ;clear errctl, task, bcol, oldupdate
 STR R0,[ARGP,#MAXFLD] ;clear macxfld, cfileh, escflg, tasklink
 STRB R0,[ARGP,#CALLER]
 STR SP,[ARGP,#HIMEM]
 MOV R0,#0
 MOV R1,#1
 SWI BYTE
 CMP R1,#3
 MOVCC R0,#45
 STRB R0,[ARGP,#WIPESTYLE]
 SUB R7,SP,#1024
 ADD AP,ARGP,#AREA1
 MOV R8,#"9"
INITBUFFLOOP SUB R6,R7,#2
 BL INITSP
 STRB R8,[AP,#BUFFNO]
 MOV R0,#"0"
 STRB R0,[AP,#PUSHNO]
 MOV R1,#1
 STRB R1,[AP,#ONSCREEN] ;on so that when selected its ok
 BL APTOBUFF
 SUB R7,R6,#256
 SUB R8,R8,#1
 CMP R8,#"0"
 BNE INITBUFFLOOP
 MOV R0,#0
 STRB R0,[AP,#ONSCREEN] ;turn buffer 1, window 1 off
 ADD AP,ARGP,#AREA0
 ADD R6,ARGP,#ENDIT
 ADD R6,R6,#256
 BL INITSP
 STRB R8,[AP,#BUFFNO]
 STRB R8,[AP,#PUSHNO]
 MOV R1,#1
 STRB R1,[AP,#ONSCREEN]
 BL INITED
 BL DEFCHR
 MOV R0,#161
 MOV R1,#8
 MOV R2,#0
 SWI BYTE
;The mode is kept in CMOS RAM. The bottom 3 bits have the following meanings:
;Bit 0 = 0 is mode 0 (16); = 1 is mode 3 (17)
;Bits 1 and 2: 0=plain, 1="T", 2="K", 3="D"
 STMFD SP!,{R2}
 TST R2,#1
 MOVEQ R0,#"0"
 MOVNE R0,#"3"
 BL USEEDITMD
 LDMFD SP!,{R2}
 MOV R2,R2,LSR #1
 ANDS R2,R2,#3
 BEQ INITSCREENDONE
 CMP R2,#2
 MOVEQ R0,#"K"
 MOVCC R0,#"T"
 MOVHI R0,#"D"
 BL USEEDITMD
INITSCREENDONE ADD AP,ARGP,#AREA0
 BL INITHAN
;see if there's a name waiting to be read in
 SWI GETENV
EDITE1 LDRB R2,[R0],#1
 CMP R2,#0
 BEQ EDITAL
 CMP R2,#" "
 BNE EDITE1 ;skip to end of first keyword section
EDITE2 LDRB R2,[R0],#1
 CMP R2,#" "
 BEQ EDITE2
 CMP R2,#0
 BEQ EDITAL ;go past any spaces
 TEQ R2,#"@"
 BEQ INCORE
 ADD R4,ARGP,#STRACC
EDITE3 STRB R2,[R4],#1
 LDRB R2,[R0],#1
 CMP R2,#" "
 BHI EDITE3
 MOV R5,#CR
 STRB R5,[R4],#1
 BNE EDITE4 ;didn't stop on a space
EDITF1 LDRB R2,[R0],#1
 CMP R2,#" "
 BEQ EDITF1
 BCC EDITE4
 STMFD SP!,{R0,R1,R2,R3}
 BL LOADF2 ;load in first file
 BL TOGWI0 ;second window (sets BOTHSCR update)
 BL STATAL
 BL REDRAW
 LDMFD SP!,{R0,R1,R2,R3}
 ADD R4,ARGP,#STRACC
EDITE5 STRB R2,[R4],#1
 LDRB R2,[R0],#1
 CMP R2,#" "
 BHI EDITE5
 MOV R2,#CR
 STRB R2,[R4],#1
EDITE4 BL LOADF2
EDITAL BL STATAL
EDITOR STR AP,[ARGP,#USINGAP]
 LDR SP,[ARGP,#HIMEM]
 BL TSTESC
 BL CUROFF
 BL REDRAW
 BL CSRXY
 BL CURON
 TST R7,#1
 MOV R0,R7,LSR #8
 BNE EDITXX
 BL TASKRD
 BCS ESCAPE
EDITXX MOV UPDATE,#NONE+ABORT
 CMP R0,#&C0
 BCS EDITTXT
 SUBS R1,R0,#128
 BCC EDITTXT
 LDRB R2,[ARGP,#ERRCTL]
 TEQ R2,#255
 BEQ EDITTXT
 LDRB R2,[ARGP,#TUTMODE]
 TEQ R2,#"D"
 BNE EDITJP
 STMFD SP!,{R0,R1}
 MOV R0,#&7D
 SWI BYTE
 SWI WRITEI+26
 SWI WRITEI+31
 SWI WRITEI+0
 SWI WRITEI+10
 ADR R3,TXTTAB
 TST R1,#1
 BIC R1,R1,#1
 LDR R3,[R3,R1,LSL #1]
 MOVEQ R3,R3,LSL #16
 MOV R3,R3,LSR #16
 ADD R3,PC,R3
AJ1 * .+4
EDITI0 SWI NEWLINE
 LDRB R0,[R3]
 TEQ R0,#0
 BEQ EDITI9
 MOV R0,R3
 SWI WRITE0
 SUB R2,R0,R3
 MOV R3,R0
 CMP R2,#55
 BCS EDITI0
 MOV R0,#" "
EDITI2 SWI WRITEC
 ADD R2,R2,#1
 TEQ R2,#55
 BNE EDITI2
 B EDITI0
EDITI9 SWI WRITEI+25
 SWI WRITEI+4
 SWI WRITEI+0
 SWI WRITEI+0
 SWI WRITEI+0
 SWI WRITEI+2
 SWI WRITEI+25
 SWI WRITEI+21
 SWI WRITEI+96
 SWI WRITEI+3
 SWI WRITEI+0
 SWI WRITEI+2
 MOV R0,#&7C
 SWI BYTE
 BL DECWIN
 BL CSRXY
 LDMFD SP!,{R0,R1}
 B EDITJP
TXTTAB
 PACK F0-AJ1,F1-AJ1
 PACK F2-AJ1,F3-AJ1
 PACK F4-AJ1,F5-AJ1
 PACK F6-AJ1,F7-AJ1
 PACK F8-AJ1,F9-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK SHFF0-AJ1,SHFF1-AJ1
 PACK SHFF2-AJ1,SHFF3-AJ1
 PACK SHFF4-AJ1,SHFF5-AJ1
 PACK SHFF6-AJ1,SHFF7-AJ1
 PACK SHFF8-AJ1,SHFF9-AJ1
 PACK SHFTAB-AJ1,SHFCOP-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK CTLF0-AJ1,CTLF1-AJ1
 PACK CTLF2-AJ1,CTLF3-AJ1
 PACK CTLF4-AJ1,CTLF5-AJ1
 PACK CTLF6-AJ1,CTLF7-AJ1
 PACK CTLF8-AJ1,CTLF9-AJ1
 PACK CTLTAB-AJ1,CTLCOP-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK CTSHFF0-AJ1,CTSHFF1-AJ1
 PACK CTSHFF2-AJ1,CTSHFF3-AJ1
 PACK CTSHFF4-AJ1,CTSHFF5-AJ1
 PACK CTSHFF6-AJ1,CTSHFF7-AJ1
 PACK CTSHFF8-AJ1,CTSHFF9-AJ1
 PACK CTSHFTAB-AJ1,CTSHFCOP-AJ1
 PACK BLANK-AJ1,BLANK-AJ1
 PACK CTSHFDN-AJ1,CTSHFUP-AJ1

EDITJP ADR R2,EDCTBL
 LDR R2,[R2,R1,LSL #2]
 ADD PC,PC,R2
AJ2 * .+4
EDCTBL
 & EDITLINE-AJ2 ;f0
 & EDSTAR-AJ2   ;f1
 & LOADFILE-AJ2 ;f2
 & SAVEFILE-AJ2 ;f3
 & FIND-AJ2     ;f4
 & GLOBAL-AJ2   ;f5
 & SETMARK-AJ2  ;f6
 & MKCPY-AJ2    ;f7
 & PRINT-AJ2    ;f8
 & OLDTEXT-AJ2  ;f9
 & TABKEY-AJ2   ;f10
 & DELABV-AJ2   ;copy
 & CURLT-AJ2    ;left
 & CURRT-AJ2    ;right
 & CURDWN-AJ2   ;down
 & CURUP-AJ2    ;up

 & CRTOGGLE-AJ2 ;shf-f0
 & IOTOGGLE-AJ2 ;shf-f1
 & INSRTF-AJ2   ;shf-f2
 & MARGINS-AJ2  ;shf-f3
 & RETLANG-AJ2  ;shf-f4
 & GETMODE-AJ2  ;shf-f5
 & CLEARMARKS-AJ2       ;shf-f6
 & MKMVE-AJ2    ;shf-f7
 & MKDEL-AJ2    ;shf-f8
 & NEWTEXT-AJ2  ;shf-f9
 & TABCTL-AJ2   ;shf-f10
 & ALLOWC-AJ2   ;shf-copy
 & WORDLEFT-AJ2 ;shf-left
 & WORDRIGHT-AJ2        ;shf-right
 & PAGEDN-AJ2   ;shf-down
 & PAGEUP-AJ2   ;shf-up

 & TOGWIN-AJ2   ;ctrl-f0
 & GROWWIN-AJ2  ;ctrl-f1
 & WINOFF-AJ2   ;ctrl-f2
 & NEXTLN-AJ2   ;ctrl-f3
 [ RELEASE=1
 & EDITOR-AJ2
 |
 & STRUCT-AJ2   ;ctrl-f4
 ]
 & ENTCHAR-AJ2  ;ctrl-f5
 & FORMAT-AJ2   ;ctrl-f6
 & MAIL-AJ2     ;ctrl-f7
 & CHLFCR-AJ2   ;ctrl-f8
 & TASKMAN-AJ2  ;ctrl-f9
 & TABEXP-AJ2   ;ctrl-f10
 & DELLINE-AJ2  ;ctrl-copy
 & CURST-AJ2    ;ctrl-left
 & CUREND-AJ2   ;ctrl-right
 & CUREDF-AJ2   ;ctrl-down
 & STFILE-AJ2   ;ctrl-up

 & CONNECT-AJ2  ;ctrl+shift-f0
 & EDITOR-AJ2   ;ctrl+shift-f1
 & PATHLOAD-AJ2 ;ctrl+shift-f2
 & APPEND-AJ2   ;ctrl+shift-f3
 & EDITOR-AJ2   ;ctrl+shift-f4
 & BUFPOP-AJ2   ;ctrl+shift-f5
 & BUFPUSH-AJ2  ;ctrl+shift-f6
 & GETMAIL-AJ2  ;ctrl+shift-f7
 & TASKLNK-AJ2  ;ctrl+shift-f8
 & TASKBOT-AJ2  ;ctrl+shift-f9
 & EDITOR-AJ2   ;ctrl+shift-f10
 & EDITOR-AJ2   ;ctrl+shift-copy
 & EDITOR-AJ2   ;ctrl+shift-left
 & EDITOR-AJ2   ;ctrl+shift-right
 & BOTHDN-AJ2   ;ctrl+shift-down
 & BOTHUP-AJ2   ;ctrl+shift-up

EDITTXT LDRB R2,[AP,#TASKQ]
 TEQ R2,#1
 BEQ TASKENTER
 LDRB R2,[AP,#INSERT]
 TEQ R0,#&7F
 BEQ DELTXT
 TEQ R0,#CR
 [ TERM=LF
 TEQNE R0,#LF
 ]
ETEXT BEQ EDCR
 BL EDITVS
 TEQ R2,#0
 BEQ EDOVER
EDINST MOV R1,#1
 BL INSRTX
 STRB R0,[R4]
 BL CHOUT
 MOV UPDATE,#TOCRLONG+ABORT
 LDRB R2,[AP,#X]
 ADD R2,R2,#1
 STRB R2,[AP,#X]
 TEQ R2,#WIDTH
 BNE EDITMT
 B EDNEWL
EDOVER LDRB R2,[AP,#X]
 LDR R3,[AP,#GE]
 LDRB R1,[R2,R3]
 TEQ R1,#TERM
 BEQ EDINST
 STRB R0,[R2,R3]
 BL CHOUT
 BL MODTXT
 MOV UPDATE,#TOCRLONG+ABORT
 B CURRT
EDCR TEQ R2,#0
 BEQ EDCROV
 BL LENGTH
 LDRB R2,[AP,#X]
 CMP R2,R0
 MOVCS R2,R0
 STRCSB R2,[AP,#X]
 BLCS CSRXY
 MOV R1,#1
 BL INSRTN
 MOV R0,#TERM
 STRB R0,[R4]
 BL CROUT
 LDRB R2,[AP,#X]
 ADDNE R2,R2,#1
EDNEWL LDRB R0,[AP,#Y]
 LDRB R1,[AP,#SLINE]
 ADD R0,R0,R1
 BL WIPENOW
 BL DECWIN
 MOV R0,#0
 STRB R0,[AP,#X]
 BL CMOVED
 BICS UPDATE,UPDATE,#ABORT
 BLNE REDRAW
 MOV UPDATE,#CSRONWARDS+ABORT
 B EDITMT
EDCROV BL MODTXT
 B CURNL
DELOVR SUBS R1,R1,#1
 MOV R0,#" "
 LDR R2,[AP,#GE]
 STRCSB R1,[AP,#X]
 STRCSB R0,[R2,R1]
 SWICS WRITEI+127
 BCS EDITMT
 BL CMOVEU
 BICS UPDATE,UPDATE,#ABORT
 BLNE REDRAW
 MOV UPDATE,#NONE+ABORT
 LDR R0,[AP,#GS]
 LDR R2,[AP,#START]
 TEQ R0,R2
 BEQ EDITOR
 BL LENGTH
 STRB R0,[AP,#X]
 B EDITOR
DELTXT BL LENGTH
 LDRB R1,[AP,#X]
 CMP R1,R0
 BHI CURLT ;if off end of line del=cursor left
 LDRB R2,[AP,#INSERT]
 TEQ R2,#0
 BEQ DELOVR
 SUBS R1,R1,#1
 STRCSB R1,[AP,#X]
 BCS DELABV
 LDR R0,[AP,#GS]
 LDR R2,[AP,#START]
 TEQ R0,R2
 BEQ EDITOR
 BL CMOVEU
 BICS UPDATE,UPDATE,#ABORT
 BLNE REDRAW
 MOV UPDATE,#NONE+ABORT
 BL LENGTH
 STRB R0,[AP,#X]
DELABV LDR R2,[AP,#GE]
 LDRB R0,[AP,#X]
 ADD R2,R2,R0
 LDR R1,[AP,#END]
 CMP R2,R1
 BCS EDITOR
 BL LENGTH
 LDRB R1,[AP,#X]
 CMP R1,R0
 BHI EDITOR ;off right of line
 MOVEQ UPDATE,#CSRONWARDS+ABORT
 MOVNE UPDATE,#TOCRSHORT+ABORT
 LDR R2,[AP,#GS]
 LDR R1,[AP,#START]
 SUB R4,R2,R1
 LDRB R2,[AP,#X] ;delete char at X
 ADD R4,R4,R2 ;character number affected
 LDR R1,[AP,#GE] ;R1 orig GE
 ADD R0,R1,#1
 STR R0,[AP,#GE]
 B DELAT2
DELAT1 LDRB R3,[R1,R2]
 STRB R3,[R0,R2]
DELAT2 SUBS R2,R2,#1
 BPL DELAT1
 MOV R6,#1 ;One character
DELATMARK LDRB R5,[AP,#MARKS]
 B DELAT4
DELAT3 ADD R2,AP,R5,LSL #2
 LDR R3,[R2,#MARKTB]
 CMP R3,R4
 SUBHI R3,R3,R6 ;if mark after deleted character it is adjusted
 STRHI R3,[R2,#MARKTB]
DELAT4 SUBS R5,R5,#1
 BCS DELAT3
EDITMT BL MODTXT
 B EDITOR
EDITVS STMFD SP!,{R0,R2,R14}
 BL LENGTH
 LDRB R2,[AP,#X]
 SUBS R1,R2,R0
 BLS EDITVX
 SWI WRITEI+31
 SWI WRITEC
 MOV R2,R0
 LDRB R0,[AP,#Y]
 SWI WRITEC
 SWI WRITEI+32 ;overwrite end of line in case it was a newline
 BL CSRXY
 BL INSRTN
 MOV R0,#" "
EDITV0 STRB R0,[R4],#1
 SUBS R1,R1,#1
 BNE EDITV0
EDITVX LDMFD SP!,{R0,R2,PC}
CSRXY SWI WRITEI+31
 LDRB R0,[AP,#X]
 SWI WRITEC
 LDRB R0,[AP,#Y]
 SWI WRITEC
 MOV PC,R14
;initialise keyboard for editor
INITED MOV R0,#4
 MOV R1,#2
 SWI BYTE
 MOV R0,#229
 MOV R1,#0
 MOV R2,#0
 SWI BYTE
 MOV R0,#230
 MOV R1,#0
 MOV R2,#0
 SWI BYTE
 MOV R0,#&DB
 MOV R1,#128+10
 MOV R2,#0
 SWI BYTE ;tab key pretends to be soft key 10
 MOV R0,#&E4
 MOV R1,#&B0
 MOV R2,#0
 SWI BYTE
 MOV R0,#&E3
 MOV R1,#&A0
 MOV R2,#0
 SWI BYTE
 MOV R0,#&E2
 MOV R1,#&90
 MOV R2,#0
 SWI BYTE
 MOV R1,#&80
INITEX MOV R0,#&E1
 MOV R2,#0
 SWI BYTE
 MOV PC,R14
;Return cursor-keys & softkeys to 'normal' state.
INITUS MOV R0,#&DB
 MOV R1,#9
 MOV R2,#0
 SWI BYTE ;tab key emits 9
 MOV R0,#4
 MOV R1,#0
 SWI BYTE
 MOV R0,#&E2
 MOV R1,#&80
 MOV R2,#0
 SWI BYTE
 MOV R0,#&E3
 MOV R1,#&90
 MOV R2,#0
 SWI BYTE
 MOV R0,#&E4
 MOV R1,#0
 MOV R2,#0
 SWI BYTE
 MOV R1,#1
 B INITEX
;init space and area to R6, R7
INITSP STR R6,[AP,#PAGE]
 STR R7,[AP,#TOP]
 MOV R0,#0
 STRB R0,[AP,#SHOWCR]
 STRB R0,[AP,#TASKQ]
 MOV R0,#1
 STRB R0,[AP,#INSERT]
;routine to init an area
INITAR LDR R4,[AP,#PAGE]
 LDR R5,[AP,#TOP]
 MOV R2,#TERM
 STRB R2,[R4],#1
 STRB R2,[R5,#-1]!
 [ TERM<>CR
 MOV R2,#CR
 ]
 STRB R2,[AP,#NAMBUFF]
 STR R4,[AP,#START]
 STR R4,[AP,#GS]
 STR R5,[AP,#GE]
 STR R5,[AP,#END]
 MOV R0,#0
 STR R0,[AP,#X] ;clear X, Y, MODIFY, MARKS
 STRB R0,[AP,#TABMOD]
 MVN R0,#0
 STR R0,[AP,#FLLOAD]
 MOV R0,#1 ;try for date stamped start up
 ADD R1,AP,#FLEXEC
 SWI WORD
 LDR R2,[AP,#FLLOAD]
 CMN R2,#255
 BCS DATES1
 B DATES2
DATEST LDR R2,[AP,#FLLOAD]
 CMN R2,#256
 BCC DATES1
 LDRB R0,[AP,#MODIFY]
 TST R0,#1
 BEQ DATES1
 MOV R0,#1
 ADD R1,AP,#FLEXEC
 LDMIA R1,{R3,R4}
 SWI WORD
 LDR R2,[AP,#FLLOAD]
 CMN R2,#1
 BEQ DATES1
 CMN R2,#255
 BCS DATES1
 STMIA R1,{R3,R4}
 SWI WRITES
 = 13,7,"Date Stamped file to Save AND clock not set: continue [Y/N]?",0
 SWI READC
 BCS ESCAPE
 TEQ R0,#"Y"
 TEQNE R0,#"y"
 BNE ESCAPE
DATES2 MOV R2,#0
 STR R2,[AP,#FLLOAD]
 MVN R3,#0
 STR R3,[AP,#FLEXEC]
DATES1 LDR R3,[AP,#FLEXEC]
 MOV R0,#0
 ADD R1,ARGP,#STRACC
 MOV PC,R14
;copy relevant AP contents into buffer information block
APTOBUFF LDR R3,[AP,#PAGE]
 SUB R0,R3,#256 ;buffer information block
 MOV R1,R0
 MOV R2,AP ;copy all the AP info
APTOBUFF1 LDRB R4,[R2],#1
 STRB R4,[R1],#1
 CMP R1,R3
 BCC APTOBUFF1
 LDR R4,[AP,#START]
 LDR R2,[AP,#GS]
 SUB R1,R2,R4
 STRB R1,[R0,#CHARSTOGS]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#CHARSTOGS+1]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#CHARSTOGS+2]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#CHARSTOGS+3]
 LDR R1,[AP,#TOP]
 SUB R1,R1,R3 ;TOP-PAGE
 ADD R1,R1,#256
 STRB R1,[R0,#TOTALCHARS]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#TOTALCHARS+1]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#TOTALCHARS+2]
 MOV R1,R1,LSR #8
 STRB R1,[R0,#TOTALCHARS+3]
 MOV PC,R14
BRKSUB SWI WRITEC
 SUBS R1,R1,#1
 BNE BRKSUB
VSTRNG BIC R0,R14,#&FC000003
 SWI WRITE0
 ADD R0,R0,#3
 BIC PC,R0,#3
MSG BIC R4,R14,#&FC000003
MSGIN BL SETARGP
 BL ERRDEF
 LDRB R0,[ARGP,#ERRCTL]
 CMP R0,#1
 BEQ MSGB
 BL INITED
 BL SELFWD
 MOV R0,#&7D
 SWI BYTE
 SWI WRITEI+31
 SWI WRITEI+0
 LDRB R1,[AP,#SLINE]
 LDRB R0,[AP,#ELINE]
 SUB R3,R0,R1
 SUB R0,R3,#3
 SWI WRITEC
 SWI WRITEI+""
 MOV R0,#""
 MOV R1,#WIDTH-22
 BL BRKSUB
 = "Shift f5 D for info",0
 MOV R0,#" "
 MOV R1,#WIDTH-2
 BL BRKSUB
 = "",0
 MOV R0,#""
 MOV R1,#WIDTH-37
 BL BRKSUB
 = "Press Escape or RETURN to continue",11,11,9,0
 MOV R0,R4
 SWI WRITE0
 MOV R0,#&7C
 SWI BYTE
MSGA SWI READC
 BCS ESCAPE
 TEQ R0,#CR
 BNE MSGA
 BL NORMAL
 BL SCRIMI
 MOV UPDATE,#FULLSCREEN
 B EDITST
MSGB MOV R0,R4
 SWI WRITE0
 SWI NEWLINE
 B STAREX
;defaults for error handling
ERRDEF LDR AP,[ARGP,#USINGAP]
 SUB SP,AP,ARGP
 TEQ SP,#AREA0
 TEQNE SP,#AREA1
 ADDNE AP,ARGP,#AREA0
 STRNE AP,[ARGP,#USINGAP]
 LDR SP,[ARGP,#HIMEM]
 MOV PC,R14
;initialise scrim
SCRIMI MOV UPDATE,#THELOT
 ADD R4,ARGP,#SCRIM
 ADD R5,R4,#32
 MOV R0,#WIDTH
SCRIM1 STRB R0,[R4],#1
 TEQ R4,R5
 BNE SCRIM1 ;clear scrim
 MOV PC,R14
;define initial characters
DEFCHR ADR R2,ICHARS
DEFCR0 LDRB R0,[R2],#1
 TEQ R0,#0
 MOVEQ PC,R14
 SWI WRITEI+23
 SWI WRITEC
 MOV R1,#8
DEFCR1 LDRB R0,[R2],#1
 SWI WRITEC
 SUBS R1,R1,#1
 BNE DEFCR1
 B DEFCR0
ICHARS
 = "",&7E,&C3,&9D,&B1,&9D,&C3,&7E,&00
 = "",&00,&18,&38,&7F,&38,&18,&00,&00
 = "",&00,&18,&1C,&FE,&1C,&18,&00,&00
 = "",&18,&18,&18,&18,&7E,&3C,&18,&00
 = "",&00,&18,&3C,&7E,&18,&18,&18,&18
 = "",&00,&00,&00,&1F,&00,&00,&00,&00
 = "",&00,&00,&00,&F8,&00,&00,&00,&00
 = "",&00,&00,&00,&FF,&00,&00,&00,&00
 = "",&00,&00,&00,&FF,&18,&18,&18,&18
 = "",&18,&18,&18,&18,&18,&18,&18,&18
 = "",&18,&18,&18,&1F,&18,&18,&18,&18
 = "",&18,&18,&18,&F8,&18,&18,&18,&18
 = "",&18,&18,&18,&FF,&00,&00,&00,&00
 = "",&18,&18,&18,&FF,&18,&18,&18,&18
 = "",&00,&00,&00,&07,&0C,&18,&18,&18
 = "",&00,&00,&00,&E0,&30,&18,&18,&18
 = "",&18,&18,&0C,&07,&00,&00,&00,&00
 = "",&18,&18,&30,&E0,&00,&00,&00,&00
 = 0
 ALIGN
;move gap such that GE=R4
GPTO LDR R0,[AP,#GS]
 CMP R4,R0
 BCS GPFWD
 B GPBACK
;move gap to start of current line. Exit with R6 as X pos'n
NORMAL STMFD SP!,{R14}
 BL FINDX
 LDR R4,[AP,#GS]
 SUB R4,R4,R6
 LDMFD SP!,{R14}
;move gap back such that GS=R4
GPBACK LDR R0,[AP,#GS]
 LDR R1,[AP,#GE]
 B GPBAC1
GPBAC0 LDRB R2,[R0,#-1]!
 STRB R2,[R1,#-1]!
GPBAC1 CMP R0,R4
 BHI GPBAC0
 STR R0,[AP,#GS]
 STR R1,[AP,#GE]
 MOV PC,R14
;set gap to character resolution
GPFINE LDRB R0,[AP,#X]
 LDR R4,[AP,#GE]
 ADD R4,R4,R0
;move gap forward such that GE=R4
GPFWD STMFD SP!,{R14}
 LDR R0,[AP,#GS]
 LDR R1,[AP,#GE]
 SUB R2,R4,R1
 BL MOVEBYTESUP
 STR R0,[AP,#GS]
 STR R1,[AP,#GE]
 LDMFD SP!,{PC}
;Move block of bytes in store UP
;R0 is (byte) destination address; will be updated
;R1 is (byte) source address; will be updated
;R2 is number of bytes to move
MOVEBYTESUP TEQ R2,#0 ;exit immediately if no bytes to move
 MOVEQ PC,R14
 STMFD SP!,{R2,R3,R4,R5,R6}
;first get word aligned with destination
MVBYTESUPALIGN LDRB R3,[R1],#1
 STRB R3,[R0],#1
 SUBS R2,R2,#1
 BEQ MVBYTESUPDONE
 TST R0,#3
 BNE MVBYTESUPALIGN
 BICS R3,R2,#3 ;R3 is number of words to move
 BEQ MVBYTESUPEND ;less than one word to go.
;now move in words
 SUB R2,R2,R3 ;will move this number
 MOVS R4,R1,LSL #31 ;work out what the alignment is
 BIC R4,R1,#3 ;word base address
 ADD R1,R1,R3 ;source will move by this number of words
 BCS MVBYTESUP2OR3 ;2 or 3
 LDMMIIA R4!,{R6}
 BMI MVBYTESUP1 ;1
MVBYTESUP0 LDR R5,[R4],#4 ;source word aligned with dest
 STR R5,[R0],#4
 SUBS R3,R3,#4
 BNE MVBYTESUP0
 B MVBYTESUPEND
MVBYTESUP1 MOV R5,R6 ;source one byte out
 LDMIA R4!,{R6}
 MOV R5,R5,LSR #8
 ORR R5,R5,R6,LSL #24
 STR R5,[R0],#4
 SUBS R3,R3,#4
 BNE MVBYTESUP1
 B MVBYTESUPEND
MVBYTESUP2OR3 LDMIA R4!,{R6}
 BMI MVBYTESUP3
MVBYTESUP2 MOV R5,R6 ;source two bytes out
 LDMIA R4!,{R6}
 MOV R5,R5,LSR #16
 ORR R5,R5,R6,LSL #16
 STR R5,[R0],#4
 SUBS R3,R3,#4
 BNE MVBYTESUP2
 B MVBYTESUPEND
MVBYTESUP3 MOV R5,R6 ;source three bytes out
 LDMIA R4!,{R6}
 MOV R5,R5,LSR #24
 ORR R5,R5,R6,LSL #8
 STR R5,[R0],#4
 SUBS R3,R3,#4
 BNE MVBYTESUP3
MVBYTESUPEND TEQ R2,#0
 BEQ MVBYTESUPDONE
MVBYTESUPEND1 LDRB R3,[R1],#1
 STRB R3,[R0],#1
 SUBS R2,R2,#1
 BNE MVBYTESUPEND1
MVBYTESUPDONE LDMFD SP!,{R2,R3,R4,R5,R6}
 MOV PC,R14
;R4:= address of start of line R0 lines back from GS. R0 is remaining undone
LINEBK LDR R4,[AP,#GS]
 TEQ R0,#0
 MOVEQ PC,R14 ;no lines back at all
 LDR R3,[AP,#START]
LINBK1 CMP R4,R3
 MOVLE R4,R3
 MOVLE PC,R14 ;can't go further back than the start!
 SUB R4,R4,#WIDTH
 LDRB R1,[R4,#WIDTH-1]
 TEQ R1,#TERM
 BNE LINBK2 ;if previous char not a TERM then it must be a full line
 MOV R1,R4
 STMFD SP!,{R6,R14}
 MOV R2,#WIDTH-1
 BL FINDX2
 CMP R6,#0
 ADCNE R4,R4,R2 ;adds in an extra 1
 LDMFD SP!,{R6,R14}
LINBK2 SUBS R0,R0,#1
 BNE LINBK1
 MOV PC,R14
;go back from GS by WIDTH until a cr is found on the line. This is the X pos in R6
FINDX LDR R1,[AP,#GS]
FINDX1 SUB R1,R1,#WIDTH
 MOV R2,#WIDTH
;entry from line back. An offset is in R2 at end
FINDX2 SUBS R2,R2,#1
 BMI FINDX1
 LDRB R6,[R1,R2]
 CMP R6,#TERM
 BNE FINDX2
 RSB R6,R2,#WIDTH-1
 MOV PC,R14
;R4:= address of start of line R0 lines forward from GE. R0 is remaining undone
LINEFW LDR R4,[AP,#GE]
 TEQ R0,#0
 MOVEQ PC,R14 ;no lines fwd at all
 LDR R3,[AP,#END]
 TEQ R4,R3
 MOVEQ PC,R14 ;can't go further fwd
LINFW1 ADD R2,R4,#WIDTH
LINFW2 LDRB R1,[R4],#1
 CMP R4,R2
 TEQNE R1,#TERM
 BNE LINFW2
 CMP R4,R3
 BHI LINFW3
 SUBS R0,R0,#1
 BNE LINFW1
 MOV PC,R14
LINFW3 SUB R4,R2,#WIDTH
 MOV PC,R14
;as insrtn but at X
INSRTX LDRB R2,[AP,#X]
;move GE back to allow R1 chars to be inserted starting at R2 from current GE
;returns R4 equal to empty address
INSRTN TEQ R1,#0
 MOVEQ PC,R14
 LDR R3,[AP,#GE]
 SUBS R4,R3,R1 ;move down by R1 chars
 BCC NOROOM
 LDR R5,[AP,#GS]
 CMP R5,R4
 BHI NOROOM
 STR R4,[AP,#GE]
 LDR R6,[AP,#START]
 SUB R6,R5,R6
 ADD R6,R6,R2 ;character number
 ADD R2,R3,R2
 B INSRT0
INSRT1 LDRB R5,[R3],#1
 STRB R5,[R4],#1
INSRT0 TEQ R3,R2
 BNE INSRT1
 LDRB R5,[AP,#MARKS]
 B INSRT2
INSRT3 ADD R3,AP,R5,LSL #2
 LDR R2,[R3,#MARKTB]
 CMP R2,R6
 ADDCS R2,R2,R1
 STRCS R2,[R3,#MARKTB]
INSRT2 SUBS R5,R5,#1
 BCS INSRT3
 MOV PC,R14
;compute length of current line. answer in R0
LENGTH LDR R4,[AP,#GE]
 ADD R2,R4,#1
 ADD R1,R4,#WIDTH
LENGT1 LDRB R0,[R4],#1
 TEQ R0,#TERM
 TEQNE R4,R1
 BNE LENGT1
 SUB R0,R4,R2
 MOV PC,R14
 LNK Command
