; > Command2
GETMODE BL PROMPT
 = "New Mode [0/3 or D/K/T]:",0
 ALIGN
GETM1 SWI READC
 BCS ESCAPE
 TEQ R0,#"0"
 TEQNE R0,#"3"
 ANDNE R0,R0,#&DF
 TEQNE R0,#"K"
 TEQNE R0,#"D"
 TEQNE R0,#"T"
 BNE GETM1
 BL EDITMD
 BL YCHECK
 B EDITAL
MKMVE LDRB R0,[AP,#MARKS]
 CMP R0,#2
 BNE TWOMARK
 BL EDITVS
 LDR R7,[AP,#MARKTB+4]
 LDR R6,[AP,#MARKTB]
 CMP R6,R7
 BEQ CLEARMARKS
 BL COPYSUB
 LDR R7,[AP,#MARKTB+4]
 LDR R4,[AP,#MARKTB]
 CMP R4,R7
 LDRCS R7,[AP,#MARKTB]
 LDRCS R4,[AP,#MARKTB+4]
 BL MARKADR
 MOV R6,R4
 MOV R4,R7
 BL MARKADR
 MOV R7,R4
 LDR R4,[AP,#GE]
 CMP R6,R4
 BCS MKMVD1 ;lower mark is after gap, so both are
 CMP R7,R4
 BCS MKMVD0 ;only higher mark is after gap
;delete by moving R7 to GS down to R6
 LDR R4,[AP,#GS]
MKMVD2 LDRB R0,[R7],#1
 STRB R0,[R6],#1
 TEQ R7,R4
 BNE MKMVD2
 STR R6,[AP,#GS]
 B MKCLR1
MKMVD0 STR R6,[AP,#GS] ;delete lower stuff
 B MKMVD9
;delete by moving GE to R6 to hang from R7
MKMVD1 BEQ MKMVD9
MKMVD3 LDRB R0,[R6,#-1]!
 STRB R0,[R7,#-1]!
 TEQ R6,R4
 BNE MKMVD3
MKMVD9 STR R7,[AP,#GE]
 BL NORMAL
 B MKCLR1
MKDEL LDRB R0,[AP,#MARKS]
 CMP R0,#1
 BCC ONEMARK
 BLNE TOONEMK
 BL GPFINE
 MOV R0,R4
 LDR R4,[AP,#MARKTB]
 BL MARKADR
 CMP R4,R0
 STRCC R4,[AP,#GS]
 STRCS R4,[AP,#GE]
 BL NORMAL
 STRB R6,[AP,#X]
;clear marks and fullscreen update and set modified
MKCLR1 MOV R0,#1
;clear marks and fullscreen update and change modify
MKCLR2 LDRB UPDATE,[AP,#MODIFY]
 TEQ UPDATE,#4
 STRNEB R0,[AP,#MODIFY]
;clear marks and fullscreen update
CLEARMARKS MOV UPDATE,#FULLSCREEN
;clear marks and any update
MKCLR4 MOV R0,#0
 STRB R0,[AP,#MARKS]
 B EDITST
NEWTEXT BL PROMPT
 = "Clear text [Y (dated),shf-f9 (auto-exec),D {discard}/N]",0
 MOV R3,#128+16+9
 MOV R0,#&81
 MOV R1,#&81
 MOV R2,#3
 SWI BYTE
 TEQ R1,#"D"
 TEQNE R1,#"d"
 BEQ NEWTEXTD
 BL YESNO2
 STMFD SP!,{R2}
 BL INITAR
 MOV UPDATE,#FULLSCREEN
 LDMFD SP!,{R1}
 TEQ R1,#"Y"
 BEQ EDITST
 STR R0,[AP,#FLLOAD]
 MVN R0,#0
 STR R0,[AP,#FLEXEC]
 B EDITST
NEWTEXTD MOV R0,#4
 STRB R0,[AP,#MODIFY]
 B EDITST
TABCTL LDRB R0,[AP,#TABMOD]
 EOR R0,R0,#&FF
 STRB R0,[AP,#TABMOD]
 B EDITST
ALLOWC BL INITUS
 MOV R0,#255
 STRB R0,[ARGP,#ERRCTL]
 B EDITST
;C set if R0 not wordc
WORDC CMP R0,#"0"
 BCC WORDCX
 CMP R0,#"9"+1
 MOVCC PC,R14
 AND R0,R0,#&DF
 CMP R0,#"A"
 BCC WORDCX
 CMP R0,#"Z"+1
 MOV PC,R14
WORDCX CMP R0,#0 ;set carry
 MOV PC,R14
WORDLEFT BL LENGTH
 LDRB R2,[AP,#X]
 CMP R2,R0
 STRHIB R0,[AP,#X] ;if off right of line
 BHI EDITOR
 LDR R1,[AP,#GE]
WORDL1 BL WORDLT
 LDRB R0,[R1,R2]
 BL WORDC
 BCC WORDL1
WORDL3 LDRB R0,[R1,R2]
 BL WORDC
 STRCCB R2,[AP,#X]
 BCC CURRT
 BL WORDLT
 B WORDL3
WORDLT TEQ R2,#0
 BNE WORDL2
 LDR R1,[AP,#GS]
 LDR R4,[AP,#START]
 CMP R4,R1
 BCS EDITOR
 STMFD SP!,{R14}
 BL CMOVEU
 BICS UPDATE,UPDATE,#ABORT
 BLNE REDRAW
 MOV UPDATE,#NONE+ABORT
 BL LENGTH
 LDR R1,[AP,#GE]
 LDMFD SP!,{R14}
 ADD R2,R0,#1
WORDL2 SUB R2,R2,#1
 MOV PC,R14
WORDRT CMP R2,#WIDTH-1
 CMPNE R0,#TERM
 BNE WORDR2
 ADD R1,R1,R2
 LDR R4,[AP,#END]
 CMP R1,R4
 BCS EDITOR
 STMFD SP!,{R14}
 BL CMOVED
 BICS UPDATE,UPDATE,#ABORT
 BLNE REDRAW
 LDMFD SP!,{R14}
 MOV UPDATE,#NONE+ABORT
 LDR R1,[AP,#GE]
 MVN R2,#0
WORDR2 ADD R2,R2,#1
 MOV PC,R14
WORDRIGHT BL LENGTH
 LDR R1,[AP,#GE]
 LDRB R2,[AP,#X]
 CMP R2,R0
 MOVCS R2,R0
 STRCSB R2,[AP,#X]
 B WORDR3
WORDR1 BL WORDRT
WORDR3 LDRB R0,[R1,R2]
 BL WORDC
 BCC WORDR1
 B WORDS3
WORDS1 BL WORDRT
WORDS3 LDRB R0,[R1,R2]
 BL WORDC
 BCS WORDS1
 STRB R2,[AP,#X]
 B EDITOR
PAGEDN BL PAGECL
 BL LINEFW
 BL GPFWD
 B EDITOR
;calculations for page movement
PAGECL LDRB R0,[AP,#ELINE]
 LDRB R1,[AP,#SLINE]
 SUB R0,R0,R1
 MOV UPDATE,#FULLSCREEN+ABORT
 MOV PC,R14
PAGEUP BL PAGECL
 BL LINEBK
 BL GPBACK
 B EDITOR
;move on to next window
TOGWIN MOV UPDATE,#NONE
 BL REDRAW
 BL TOGWI0
 B EDITAL
; LDR R0,[AP,#START]
; LDR R1,[AP,#GS]
; LDR R2,[AP,#GE]
; LDR R3,[AP,#END]
; CMP R0,R1
; CMPEQ R2,R3
; BNE EDITAL
; BL STATAL
; BL REDRAW
; STR AP,[ARGP,#PANICA]
; B LOADFILE
TOGWI0 STMFD SP!,{R14}
 ADD R4,ARGP,#AREA0
 TEQ R4,AP
 ADDEQ R4,ARGP,#AREA1 ;R4 new window
 LDRB R14,[R4,#ONSCREEN]
 TEQ R14,#0 ;is selected window ONSCREEN?
 BLEQ WINON ;no, then make it go on
 LDMFD SP!,{R14}
TOGWI1 ADD R6,ARGP,#AREA0
 ADD R7,ARGP,#AREA1
 TEQ AP,R6
 ADDEQ AP,ARGP,#AREA1
 ADDNE AP,ARGP,#AREA0
 STR AP,[ARGP,#USINGAP]
 LDR R3,[R6,#GE]
 LDR R4,[R7,#GS]
 CMP R3,R4
 ADDCS R6,ARGP,#AREA1
 ADDCS R7,ARGP,#AREA0
 TEQ AP,R6
;R6 and R7 are now LOW window and HIGH window
 LDR R3,[R6,#GE] ;0:GE
 LDR R4,[R7,#GS] ;1:GS
 LDREQ R2,[R7,#GE]
 SUBEQ R1,R4,R2 ;decrease pointers by -(high:GE - high:GS)
 BEQ TOGTO0
;toggling to high window. Move low:GE to high:GS down to low:GS
 LDR R0,[R6,#GS]
 SUB R1,R3,R0 ;decrease pointers by low:GE - low:GS
;TOGTO1 LDRB R0,[R3],#1
; STRB R0,[R2],#1
; TEQ R3,R4
; BNE TOGTO1
 STMFD SP!,{R1,R14}
 MOV R1,R3
 SUB R2,R4,R3
 BL MOVEBYTESUP
 LDMFD SP!,{R1,R14}
 B TOGWI2
;toggling to low window. Move low:GE to high:GS up to high:GE
TOGTO0 LDRB R0,[R4,#-1]!
 STRB R0,[R2,#-1]!
 CMP R4,R3
 BCS TOGTO0
;Update low:GE, low:END, low:TOP, high:PAGE, high:START, high:GS by subtracting R1
TOGWI2 LDR R0,[R6,#GE]
 SUB R0,R0,R1
 STR R0,[R6,#GE]
 LDR R0,[R6,#END]
 SUB R0,R0,R1
 STR R0,[R6,#END]
 LDR R0,[R6,#TOP]
 SUB R0,R0,R1
 STR R0,[R6,#TOP]
 LDR R0,[R7,#PAGE]
 SUB R0,R0,R1
 STR R0,[R7,#PAGE]
 LDR R0,[R7,#START]
 SUB R0,R0,R1
 STR R0,[R7,#START]
 LDR R0,[R7,#GS]
 SUB R0,R0,R1
 STR R0,[R7,#GS]
 MOV PC,R14
WINON MOV UPDATE,#BOTHSCREEN
 MOV R1,#1
 STRB R1,[R4,#ONSCREEN]
 LDRB R3,[ARGP,#MINY] ;format both windows to half space
 LDRB R2,[ARGP,#MAXY]
 SUB R1,R2,R3
 ADD R1,R3,R1,LSR #1
 STRB R1,[AP,#ELINE]
 ADD R1,R1,#1
 STRB R1,[R4,#SLINE]
 STRB R2,[R4,#ELINE]
 B YCHECK
;current window off and move on to next one
WINOFF MOV R2,#0
 STRB R2,[AP,#ONSCREEN] ;turn this window off
 ADD R4,ARGP,#AREA0
 TEQ R4,AP
 ADDEQ R4,ARGP,#AREA1
 STR R4,[ARGP,#USINGAP]
 LDRB R2,[R4,#ONSCREEN]
 TEQ R2,#0
 BNE WINSW2
;no other window so swap the two windows
 MOV R2,#1
 STRB R2,[R4,#ONSCREEN]
WINSW2 LDRB R2,[ARGP,#MINY]
 STRB R2,[R4,#SLINE]
 LDRB R2,[ARGP,#MAXY]
 STRB R2,[R4,#ELINE]
 MOV UPDATE,#FULLSCREEN
 BL YCHECK
 BL TOGWI1
 B EDITAL
GROWWIN LDRB R0,[AP,#SLINE]
 ADD R4,ARGP,#AREA0
 TEQ R4,AP
 ADDEQ R4,ARGP,#AREA1
 LDRB R3,[ARGP,#MINY]
 TEQ R0,R3
 BNE GROWW1
 LDRB R0,[AP,#ELINE] ;if top line at 0 cannot grow up
 LDRB R3,[ARGP,#MAXY]
 SUB R3,R3,#6
 CMP R0,R3
 BCS EDITOR ;no room to grow down
 ADD R0,R0,#1
 STRB R0,[AP,#ELINE]
 ADD R0,R0,#1
 STRB R0,[R4,#SLINE]
GROWW2 MOV UPDATE,#BOTHSCREEN+ABORT
 BL YCHECK
 B EDITAL
GROWW1 SUBS R0,R0,#1
 ADD R3,R3,#6
 CMP R0,R3
 BCC EDITOR
 STRB R0,[AP,#SLINE]
 SUB R0,R0,#1
 STRB R0,[R4,#ELINE]
 B GROWW2
;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"
EDITMD STMFD SP!,{R0}
 MOV R0,#161
 MOV R1,#8
 MOV R2,#0
 SWI BYTE
 BIC R2,R2,#6
 LDMFD SP,{R3}
 CMP R3,#"0"
 BICEQ R2,R2,#1
 CMP R3,#"3"
 ORREQ R2,R2,#1
 CMP R3,#"T"
 ORREQ R2,R2,#2
 CMP R3,#"K"
 ORREQ R2,R2,#4
 CMP R3,#"D"
 ORREQ R2,R2,#6
 MOV R0,#162
 MOV R1,#8
 SWI BYTE
 LDMFD SP!,{R0}
USEEDITMD STRB R0,[ARGP,#TUTMODE]
 LDRB R3,[ARGP,#TUTMODE+1]
 [ WIDTH=80
 [ ARTHUR=0
 MOV R4,#128
 |
 MOV R4,#0
 ]
 |
 MOV R4,#16
 ]
 MOV R1,#0
 LDRB R2,[ARGP,#MAXY]
 TEQ R0,#"T"
 MOVEQ R1,#1
 MOVEQ R4,R3
 TEQ R0,#"K"
 MOVEQ R1,#13
 MOVEQ R4,R3
 TEQ R0,#"D"
 MOVEQ R1,#16
 MOVEQ R4,R3
 TEQ R0,#"0"
 MOVEQ R2,#31
 TEQ R0,#"3"
 [ WIDTH=80
 [ ARTHUR=0
 MOVEQ R4,#128+3
 |
 MOVEQ R4,#3
 ]
 |
 MOVEQ R4,#17
 ]
 MOVEQ R2,#24
 STRB R4,[ARGP,#TUTMODE+1]
 TEQ R4,R3
 SWINE WRITEI+22
 MOV R0,R4
 SWINE WRITEC
 STRB R2,[ARGP,#MAXY]
 STRB R1,[ARGP,#MINY]
 STMFD SP!,{R14}
 BL SCRIMI
 LDMFD SP!,{R14}
 ADD R4,ARGP,#AREA0
 LDRB R0,[R4,#ONSCREEN]
 TEQ R0,#0
 BEQ EDITM1
 ADD R5,ARGP,#AREA1
 LDRB R0,[R5,#ONSCREEN]
 TEQ R0,#0
 BEQ EDITM2
 LDRB R6,[R4,#ELINE]
 LDRB R7,[R5,#ELINE]
 CMP R6,R7 ;R4 window is on bottom ?
 ADDCC R4,ARGP,#AREA1
 ADDCC R5,ARGP,#AREA0
 LDRB R6,[R5,#SLINE]
 SUB R6,R2,R1
 ADD R6,R1,R6,LSR #1
 STRB R6,[R5,#ELINE]
 ADD R6,R6,#1
 STRB R6,[R4,#SLINE]
 STRB R1,[R5,#SLINE]
 STRB R2,[R4,#ELINE]
 B YCHECK
EDITM1 ADD R4,ARGP,#AREA1
EDITM2 STRB R1,[R4,#SLINE]
 STRB R2,[R4,#ELINE] ;and now Ycheck
;mangle both windows Y coordinate, TSM and BSM to be inside window. R0 kept
YCHECK STMFD SP!,{R14}
 ADD R4,ARGP,#AREA0
 BL YCHEK1
 LDMFD SP!,{R14}
 ADD R4,ARGP,#AREA1
;mangle [R4]'s Y coordinate etc.
YCHEK1 LDRB R1,[R4,#SLINE]
 LDRB R2,[R4,#ELINE]
 SUB R5,R2,R1
 SUB R5,R5,#2 ;total vertical size allowed
 MOV R3,#4 ;TSM
 STRB R3,[R4,#TSM]
 CMP R5,#4
 SUBHI R5,R5,#3 ;BSM
 STRB R5,[R4,#BSM]
 STRB R5,[R4,#Y]
 MOV PC,R14
NEXTLN ADD R7,ARGP,#AREA0
 TEQ R7,AP
 ADDEQ R7,ARGP,#AREA1
 LDR R2,[R7,#GE]
 LDR R5,[R7,#END]
NEXTL1 CMP R2,R5
 BCS BADLN
NEXTL2 LDRB R1,[R2],#1
NEXTL3 TEQ R1,#TERM
 BEQ NEXTL1
 TEQ R1,#" "
 BNE NEXTL2
 BL NEXTLSB
 TEQ R1,#"L"
 BNE NEXTL2
 BL NEXTLSB
 TEQ R1,#"I"
 BNE NEXTL2
 BL NEXTLSB
 TEQ R1,#"N"
 BNE NEXTL2
 BL NEXTLSB
 TEQ R1,#"E"
 BNE NEXTL2
 LDRB R1,[R2],#1
 TEQ R1,#" "
 BNE NEXTL3
NEXTL6 LDRB R1,[R2],#1
 TEQ R1,#" "
 BEQ NEXTL6
 TEQ R1,#TERM
 BEQ NEXTL1
 CMP R1,#"9"
 BHI NEXTL2
 CMP R1,#"0"
 BCC NEXTL2
 SUB R2,R2,#1
 MOV R3,R2 ;ge
NEXTL4 CMP R3,R5
 BCS BADLN
 LDRB R0,[R3],#1
 TEQ R0,#TERM
 BNE NEXTL4
 MOV R1,#1
 STRB R1,[R7,#Y]
 STR R3,[R7,#GE]
 STR R3,[R7,#GS] ;program compact, so ok
 MOV UPDATE,#BOTHSCREEN
 B EDITL0
NEXTLSB LDRB R1,[R2],#1
 TEQ R1,#TERM
 BEQ NEXTL1
 BIC R1,R1,#&20
 MOV PC,R14
BADLN BL MSG
 = "No more error lines in other window",0
 ALIGN
 MACRO
$L BYTE3 $A
$L = $A,($A) :SHR: 8,($A) :SHR: 16
 MEND
 [ RELEASE=0
STRUCT BL PROMPT
 = "Case Def Else eXcept finallY For If Loop locK Mod Proc Repeat Type While",0
 BL CSRXY
 BL BIGCUR
 SWI READC
 BL NMLCUR
 BCS ESCAPE
 BIC R0,R0,#&20
 ADR R1,STRUCOFF
 ADR R9,CSTRU
STRUCFIND LDR R2,[R1],#4
 AND R3,R2,#255
 CMP R3,R0
 BEQ STRUC0
 CMP R2,#0
 BNE STRUCFIND
 BL MSG
 = "Unknown structure",0
 ALIGN
STRUCOFF = "C"
 BYTE3 (0)
 = "D"
 BYTE3 (DSTRU-CSTRU)
 = "E"
 BYTE3 (ESTRU-CSTRU)
 = "F"
 BYTE3 (FSTRU-CSTRU)
 = "I"
 BYTE3 (ISTRU-CSTRU)
 = "L"
 BYTE3 (LSTRU-CSTRU)
 = "K"
 BYTE3 (KSTRU-CSTRU)
 = "M"
 BYTE3 (MSTRU-CSTRU)
 = "P"
 BYTE3 (PSTRU-CSTRU)
 = "R"
 BYTE3 (RSTRU-CSTRU)
 = "T"
 BYTE3 (TSTRU-CSTRU)
 = "W"
 BYTE3 (WSTRU-CSTRU)
 = "X"
 BYTE3 (XSTRU-CSTRU)
 = "Y"
 BYTE3 (YSTRU-CSTRU)
 & 0
 [ STYLE=1
CSTRU
 = "CASE  OF",TERM
 = "  ",TERM
 = "END; (* case *)",TERM,0,5,0
DSTRU
 = "(* -> Def.",1,TERM,"*)",TERM
 = "(*************************** -*- Mode: Modula -*- ***************************)",TERM
 = "(* Title:       <purpose etc.>                                              *)",TERM
 = "(* Author:      <insert your name here>                                     *)",TERM
; = "(* LastEdit:    ??????????????                                              *)",TERM
 = "(*              <details>                                                   *)",TERM
 = "(****************************************************************************)",TERM,TERM
 = "(*",TERM
 = "  $Revision$",TERM
 = "  $Author$",TERM
 = "  $Date$",TERM
 = "  $Source$",TERM
 = "  $State$",TERM
 = "*)",TERM
 = TERM
 = "DEFINITION MODULE ",1,";",TERM
 = TERM
 = "FROM  IMPORT ",TERM
 = TERM
 = "EXPORT QUALIFIED ",TERM
 = TERM
 = "END ",1,".",TERM,0,5,18
ESTRU
 = "IF  THEN",TERM
 = "  ",TERM
 = "ELSE",TERM
 = "  ",TERM
 = "END; (* if *)",TERM,0,3,0
FSTRU
 = "FOR := TO  DO",TERM
 = "  ",TERM
 = "END; (* for *)",TERM,0,4,0
ISTRU
 = "IF  THEN",TERM
 = "  ",TERM
 = "END; (* if *)",TERM,0,3,0
LSTRU
 = "LOOP",TERM
 = "  ",TERM
 = "END; (* loop *)",TERM,0,2,1
KSTRU
 = "LOCK  DO",TERM
 = "  ",TERM
 = "END; (* lock *)",TERM,0,5,0
MSTRU
 = "(* -> Mod.",1,TERM,"*)",TERM
 = "(*************************** -*- Mode: Modula -*- ***************************)",TERM
 = "(* Title:       <purpose etc.>                                              *)",TERM
 = "(* Author:      <insert your name here>                                     *)",TERM
; = "(* LastEdit:    ??????????????                                              *)",TERM
 = "(*              <details>                                                   *)",TERM
 = "(****************************************************************************)",TERM,TERM
 = "(*",TERM
 = "  $Revision$",TERM
 = "  $Author$",TERM
 = "  $Date$",TERM
 = "  $Source$",TERM
 = "  $State$",TERM
 = "*)",TERM
 = TERM
 = "IMPLEMENTATION MODULE ",1,";",TERM
 = TERM
 = "END ",1,".",TERM,0,0,17
PSTRU
 = "PROCEDURE ",1,";",TERM
 = "  BEGIN",TERM
 = "    ",TERM
 = "  END ",1,";",TERM,0,10,0
RSTRU
 = "REPEAT",TERM
 = "  ",TERM
 = "UNTIL ;",TERM,0,6,2
TSTRU
 = "TYPE",TERM
 = "  ",TERM
 = "  END;",TERM,0,2,1
WSTRU
 = "WHILE  DO",TERM
 = "  ",TERM
 = "END; (* while *)",TERM,0,6,0
XSTRU
 = "TRY",TERM
 = "EXCEPT",TERM
 = "END; (* try *)",TERM,0,3,0
YSTRU
 = "TRY",TERM
 = "FINALLY",TERM
 = "END; (* try *)",TERM,0,3,0
 |
CSTRU
 = "CASE ",TERM
 = "OF",TERM
 = "   ",TERM
 = "END; (* case *)",TERM,0,5,0
DSTRU
 = "(* -> Def.",1,TERM,"*)",TERM
 = "(*************************** -*- Mode: Modula -*- ***************************)",TERM
 = "(* Title:       <purpose etc.>                                              *)",TERM
 = "(* Author:      <insert your name here>                                     *)",TERM
; = "(* LastEdit:    ??????????????                                              *)",TERM
 = "(*              <details>                                                   *)",TERM
 = "(****************************************************************************)",TERM,TERM
 = "(*",TERM
 = "  $Revision$",TERM
 = "  $Author$",TERM
 = "  $Date$",TERM
 = "  $Source$",TERM
 = "  $State$",TERM
 = "*)",TERM
 = TERM
 = "DEFINITION MODULE ",1,";",TERM
 = TERM
 = "FROM  IMPORT ",TERM
 = TERM
 = "EXPORT QUALIFIED ",TERM
 = TERM
 = "END ",1,".",TERM,0,5,18
ESTRU
 = "IF ",TERM
 = "THEN",TERM
 = "   ",TERM
 = "ELSE",TERM
 = "   ",TERM,"END; (* if *)",TERM,0,3,0
FSTRU
 = "FOR := TO ",TERM
 = "DO",TERM
 = "   ",TERM
 = "END; (* for *)",TERM,0,4,0
ISTRU
 = "IF ",TERM
 = "THEN",TERM
 = "   ",TERM,"END; (* if *)",TERM,0,3,0
LSTRU
 = "LOOP",TERM
 = "   ",TERM
 = "END; (* loop *)",TERM,0,3,1
KSTRU
 = "LOCK  DO",TERM
 = "   ",TERM
 = "END; (* lock *)",TERM,0,5,0
MSTRU
 = "(* -> Mod.",1,TERM,"*)",TERM
 = "(*************************** -*- Mode: Modula -*- ***************************)",TERM
 = "(* Title:       <purpose etc.>                                              *)",TERM
 = "(* Author:      <insert your name here>                                     *)",TERM
; = "(* LastEdit:    ??????????????                                              *)",TERM
 = "(*              <details>                                                   *)",TERM
 = "(****************************************************************************)",TERM,TERM
 = "(*",TERM
 = "  $Revision$",TERM
 = "  $Author$",TERM
 = "  $Date$",TERM
 = "  $Source$",TERM
 = "  $State$",TERM
 = "*)",TERM
 = TERM
 = "IMPLEMENTATION MODULE ",1,";",TERM
 = TERM
 = "END ",1,".",TERM,0,0,17
PSTRU
 = "PROCEDURE ",1,";",TERM
 = "BEGIN",TERM
 = TERM
 = "END ",1,";",TERM,0,10,0
RSTRU
 = "REPEAT",TERM
 = "   ",TERM
 = "UNTIL ;",TERM,0,6,2
TSTRU
 = "TYPE",TERM
 = "   ",TERM
 = "   END;",TERM,0,3,1
WSTRU
 = "WHILE ",TERM
 = "DO",TERM
 = "   ",TERM
 = "END; (* while *)",TERM,0,6,0
XSTRU
 = "TRY",TERM
 = "EXCEPT",TERM
 = "END; (* try *)",TERM,0,3,0
YSTRU
 = "TRY",TERM
 = "FINALLY",TERM
 = "END; (* try *)",TERM,0,3,0
 ]
 ALIGN
STRUC0 ADD R9,R9,R2,LSR #8
 MOV R8,#0
 TEQ R0,#"D"
 TEQNE R0,#"M"
 BNE STRUCA
 BL PROMPT
 = "Module name:",0
 BL READLRNOCOPY
 B STRUCB
STRUCA TEQ R0,#"P"
 BNE STRUCB
 BL PROMPT
 = "Procedure name:",0
 BL READLRNOCOPY
 SUB R8,R1,ARGP
 SUB R8,R8,#STRACC
STRUCB BL EDITVS
 BL GPFINE
 LDRB R2,[AP,#X] ;R2 becomes number of spaces to indent
 LDR R1,[AP,#GS]
STRUC3 LDRB R0,[R9],#1
 TEQ R0,#1
 BNE STRUC5
 ADD R3,ARGP,#STRACC
STRUC6 LDRB R0,[R3],#1
 TEQ R0,#CR
 BEQ STRUC3
 STRB R0,[R1],#1
 B STRUC6
STRUC5 STRB R0,[R1],#1
 TEQ R0,#TERM
 BNE STRUC3
 MOVS R3,R2
 BEQ STRUC2
 MOV R0,#" "
STRUC4 STRB R0,[R1],#1
 SUBS R3,R3,#1
 BNE STRUC4
STRUC2 LDRB R0,[R9]
 TEQ R0,#0
 BNE STRUC3
 LDRB R0,[R9,#1]!
 ADD R0,R0,R2
 ADD R0,R0,R8
 STRB R0,[AP,#X]
 LDR R4,[AP,#GS]
 STR R1,[AP,#GS]
 LDR R6,[AP,#START]
 SUB R6,R4,R6 ;old character number
 SUB R1,R1,R4 ;amount inserted
 LDRB R5,[AP,#MARKS]
 BL INSRT2
 BL GPBACK
 BL NORMAL
 LDRB R0,[R9,#1]
 LDRB R2,[AP,#Y]
 ADD R2,R0,R2
 LDRB R3,[AP,#BSM]
 CMP R2,R3
 MOVCS R2,R3
 STRB R2,[AP,#Y]
 BL LINEFW
 BL GPFWD
 B FULLMOD
 ]
ENTCHAR BL PROMPT
 = "Type character or {space}:",0
 SWI READC
 TEQ R0,#" "
 BNE ENTGOT
ENTCODE BL PROMPT
 = "Type character code in decimal:",0
 BL READLRNOCOPY
 ADD R2,ARGP,#STRACC
 MOV R3,#0
 MOV R7,#0
 BL GETNEW
 TEQ R3,#0
 BEQ EDITBN
 MOV R0,R7
ENTGOT STMFD SP!,{R0}
 BL MODSTT
 BL CSRXY
 LDMFD SP!,{R0}
 LDRB R2,[AP,#INSERT]
 TEQ R0,#TERM
 B ETEXT
FORMAT MOV R0,#0
 STRB R0,[AP,#X]
 LDRB R7,[AP,#Y]
 LDR R1,[AP,#GE]
 LDRB R6,[AP,#MODIFY]
FORMATNXT MOV R2,#0 ;offset down line
 MOV R3,#256 ;last space
FORMATLP LDRB R0,[R1,R2]
 CMP R0,#TERM
 BNE FORMAT1
 ADD R4,R2,R1
 LDR R5,[AP,#END]
 CMP R4,R5
 MOVCS R4,R1
 BCS FORMATDONE
 LDRB R5,[R4,#1]!
 CMP R5,#" "
 BLS FORMATDONE
 CMP R5,#","
 CMPNE R5,#"."
 CMPNE R5,#";"
 CMPNE R5,#":"
 BEQ FORMATDONE
 CMP R2,#0
 BEQ FORMATDONE
 MOV R0,#" " 
 STRB R0,[R1,R2]
 MOV R6,#1
FORMAT1 CMP R0,#" "
 MOVEQ R3,R2
 ADD R2,R2,#1
 CMP R2,#78
 BCC FORMATLP
 CMP R3,#256
 BEQ FORMATSPLIT
 MOV R0,#TERM
 STRB R0,[R1,R3]!
 MOV R6,#1
 ADD R7,R7,#1
 ADD R1,R1,#1
 B FORMATNXT
FORMATDONE LDRB UPDATE,[AP,#MODIFY]
 TEQ UPDATE,#4
 STRNEB R6,[AP,#MODIFY]
 MOV UPDATE,#FULLSCREEN+ABORT
 LDRB R6,[AP,#BSM]
 ADD R7,R7,#1
 CMP R6,R7
 STRCSB R7,[AP,#Y]
 BL GPFWD
 B EDITST
FORMATSPLIT LDRB R4,[AP,#MODIFY]
 TEQ R4,#4
 STRNEB R6,[AP,#MODIFY]
 LDRB R6,[AP,#BSM]
 ADD R7,R7,#1
 CMP R6,R7
 STRCSB R7,[AP,#Y]
 MOV R4,R1
 BL GPFWD
 BL MSG
 = "Unsplittable line",0
 [ OLDMAIL=-1
MAILHDR = LF,"SonOfEcomail 3",LF,"To: ",CR
MAILCC = "CC: ",CR
MAILSUBJ = "Subject: ",CR
 ALIGN
MAIL BL PROMPT
 = "List of people to mail to:",0
 BL READLRNOCOPY
 ADD R2,ARGP,#MSTACK ;pointer to message header buffer
 ADR R1,MAILHDR
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF ;destination field
 STMFD SP!,{R2}
 BL PROMPT
 = "Carbon copy to this list of people:",0
 BL READLRNOCOPY
 SUB R2,R1,ARGP
 TEQ R2,#STRACC
 BEQ NOCC
 LDMFD SP!,{R2}
 ADR R1,MAILCC
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF
 STMFD SP!,{R2}
NOCC BL PROMPT
 = "Subject of message:",0
 BL READLRNOCOPY
 LDMFD SP!,{R2}
 ADR R1,MAILSUBJ
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF ;subject field
 MOV R9,R2 ;pointer in proper register for rest
 MOV R0,#0
 MOV R1,#0
 SWI ARGS
 STMFD SP!,{R0} ;save current fsyst
 MOV R0, #&C6
 MOV R1, #0
 MOV R2, #0
 SWI BYTE ;exec file off
 STRB R1, [SP, #1] ;old handle
 MOV R0,#143
 MOV R1,#18
 MOV R2,#5
 SWI BYTE ;select econet
 MOV R2,R9
 ADR R1,MAILDATE
 BL MOVNM1
 SUB R9,R2,#1
 ADD R1,ARGP,#TRANS
 MOV R0,#0
 STR R0,[R1,#4]
 STR R0,[R1,#8]
 MOV R0,#&400
 ORR R0,R0,#&10000000
 STR R0,[R1]
 MOV R0,#&14
 SWI WORD
 LDRB R2,[R1,#4] ;day of month
 BL MAILDEC
 MOV R0,#" "
 STRB R0,[R9],#1
 BL GETMTABLE ;address of months
 LDRB R4,[R1,#5]
 AND R2,R4,#15 ;month of year
 ADD R3,R3,R2,LSL #3 ;index table
 SUB R3,R3,#4
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 MOV R0,#" "
 STRB R0,[R9],#1
 MOV R2,R4,LSR #4
 ADD R2,R2,#81
 BL MAILDEC
 MOV R0,#" "
 STRB R0,[R9],#1
 LDRB R2,[R1,#6]
 BL MAILDEC ;hour
 MOV R0,#":"
 STRB R0,[R9],#1
 LDRB R2,[R1,#7]
 BL MAILDEC ;minute
 MOV R2,R9
 ADR R1,MAILRETURN
 BL MOVNM1
 SUBS R9,R2,#1
 ADD R1,ARGP,#TRANS
 MOV R0,#&600
 ORR R0,R0,#&20000000
 STR R0,[R1]
 MOV R0,#&14
 SWI WORD
 ADD R2,R1,#4
 B MAILNAMLEN
MAILDATE = "Date: ",CR
MAILRETURN = LF,"From: ",CR
MAILFILE = "$.Mail.PostBox.00",CR
MAILFILEOFFSET * 15
MAILFULLNAME = "&.Mail.Defaults",CR
 ALIGN
MAILNAMLEN LDRB R0,[R2],#1
 STRB R0,[R9],#1
 CMP R0,#" "
 BHI MAILNAMLEN
 ADR R1,MAILFULLNAME
 MOV R0,#&40
 SWI OPEN ;try finding &.Mail.Defaults
 CMP R0,#0
 BEQ MAILNOFULLNAME
 AND R1,R0,#255
 MOV R0,#4
 MOV R2,R9
 MOV R3,#256
 MOV R4,#0
 SWI MULTIPLE
 MOV R0,#0
 SWI OPEN ;close mail.defaults
MAILDEFAULTSEND LDRB R0,[R9],#1
 CMP R0,#4
 BHI MAILDEFAULTSEND
MAILNOFULLNAME LDRB R0,[R9,#-1]!
 CMP R0,#32
 BCC MAILNOFULLNAME
 ADD R9,R9,#1
 MOV R0,#10
 STRB R0,[R9],#1
 STRB R0,[R9],#1
 ADR R0,MAILERRHAN
 ADD R1,ARGP,#TRANS
 ADD R1,R1,#128
 MOV R2,#0
 MOV R3,#0
 SWI CONTROL
 ADR R1,MAILFILE
 ADD R2,ARGP,#TRANS
 BL MOVNM1
MAILOPEN BL PROMPT
 = "trying: ",0
 ADD R1,ARGP,#TRANS
MAILSDNAMEPRIME LDRB R0,[R1],#1
 CMP R0,#" "
 SWICS WRITEC
 BCS MAILSDNAMEPRIME
 MOV R0,#&C0
 ADD R1,ARGP,#TRANS
 SWI OPEN
 CMP R0,#0
 BEQ ERML2
 AND R1,R0,#255
 MOV R0,#2
 SWI ARGS
 CMP R2,#0
 BNE MAILERRHANCLOSE
 STMFD SP!,{R1,R2}
 BL INITHAN ;reset error handler
 BL PROMPT
 = "Mailing: ",0
 ADD R1,ARGP,#TRANS
MAILSDNAME LDRB R0,[R1],#1
 CMP R0,#" "
 SWICS WRITEC
 BCS MAILSDNAME
 LDMFD SP!,{R1,R2}
 MOV R0,#2
 SWI ARGS
 MOV R4,R2
 MOV R0,#1
 ADD R2,ARGP,#MSTACK
 SUB R3,R9,R2
 SWI MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#START]
 LDR R3,[AP,#GS]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#GE]
 LDR R3,[AP,#END]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#0
 SWI OPEN
 MOV R0,#143
 MOV R1,#18
 LDRB R2,[SP]
 SWI BYTE
 LDRB R1,[SP,#1]
 MOV R0,#&C6
 MOV R2,#0
 SWI BYTE ;reset exec file
 ADD SP,SP,#4
 BL STATUS
 BL INFORR
 = "Mailed.",0
 MOV UPDATE,#FULLSCREEN
 B EDITOR
MAILERRHANCLOSE MOV R0,#0
 SWI OPEN
 B MAILERRHANGO
MAILERRHAN BL SETARGP
MAILERRHANGO ADD R5,ARGP,#TRANS
 LDRB R0,[R5,#MAILFILEOFFSET+1]
 ADD R0,R0,#1
 STRB R0,[R5,#MAILFILEOFFSET+1]
 CMP R0,#"9"+1
 BCC MAILOPEN
 MOV R0,#"0"
 STRB R0,[R5,#MAILFILEOFFSET+1]
 LDRB R0,[R5,#MAILFILEOFFSET]
 ADD R0,R0,#1
 STRB R0,[R5,#MAILFILEOFFSET]
 CMP R0,#"9"+1
 BCC MAILOPEN
ERML2 BL INITHAN
 LDMFD SP!,{R2}
 MOV R0,#143
 MOV R1,#18
 SWI BYTE
 BL MSG
 = "Catastrophe: $.mail.postbox.## not found",0
 ALIGN
MAILDEC MOV R0,#"0"
MAILDECLOOP SUBS R2,R2,#10
 ADDCS R0,R0,#1
 BCS MAILDECLOOP
 TEQ R0,#"0"
 STRNEB R0,[R9],#1
 ADD R0,R2,#"0"+10
 STRB R0,[R9],#1
 MOV PC,R14
 ]
 [ OLDMAIL=0
MAILHDR = LF,"SonOfEcomail 2.1",LF,"To: ",CR
MAILCC = "CC: ",CR
MAILSUBJ = "Subject: ",CR
MAILDATE = "Date: ",CR
 ALIGN
MAIL BL PROMPT
 = "List of people to mail to:",0
 BL READLRNOCOPY
 ADD R2,ARGP,#MSTACK ;pointer to message header buffer
 ADR R1,MAILHDR
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF ;destination field
 STMFD SP!,{R2}
 BL PROMPT
 = "Carbon copy to this list of people:",0
 BL READLRNOCOPY
 SUB R2,R1,ARGP
 TEQ R2,#STRACC
 BEQ NOCC
 LDMFD SP!,{R2}
 ADR R1,MAILCC
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF
 STMFD SP!,{R2}
NOCC BL PROMPT
 = "Subject of message:",0
 BL READLRNOCOPY
 LDMFD SP!,{R2}
 ADR R1,MAILSUBJ
 BL MOVNM1
 SUB R2,R2,#1
 BL MOVBUF ;subject field
 MOV R9,R2 ;pointer in proper register for rest
 MOV R0,#0
 MOV R1,#0
 SWI ARGS
 STMFD SP!,{R0} ;save current fsyst
 MOV R0, #&C6
 MOV R1, #0
 MOV R2, #0
 SWI BYTE ;exec file off
 STRB R1, [SP, #1] ;old handle
 MOV R0,#143
 MOV R1,#18
 MOV R2,#5
 SWI BYTE ;select econet
 MOV R2,R9
 ADR R1,MAILDATE
 BL MOVNM1
 SUB R9,R2,#1
 ADD R1,ARGP,#TRANS
 MOV R0,#0
 STR R0,[R1,#4]
 STR R0,[R1,#8]
 MOV R0,#&400
 ORR R0,R0,#&10000000
 STR R0,[R1]
 MOV R0,#&14
 SWI WORD
 LDRB R2,[R1,#4] ;day of month
 BL MAILDEC
 MOV R0,#" "
 STRB R0,[R9],#1
 BL GETMTABLE ;address of months
 LDRB R4,[R1,#5]
 AND R2,R4,#15 ;month of year
 ADD R3,R3,R2,LSL #3 ;index table
 SUB R3,R3,#4
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 LDRB R0,[R3],#1
 STRB R0,[R9],#1
 MOV R0,#" "
 STRB R0,[R9],#1
 MOV R2,R4,LSR #4
 ADD R2,R2,#81
 BL MAILDEC
 MOV R0,#" "
 STRB R0,[R9],#1
 LDRB R2,[R1,#6]
 BL MAILDEC ;hour
 MOV R0,#":"
 STRB R0,[R9],#1
 LDRB R2,[R1,#7]
 BL MAILDEC ;minute
 MOV R2,R9
 ADR R1,MAILRETURN
 BL MOVNM1
 SUBS R9,R2,#1
 ADD R1,ARGP,#TRANS
 MOV R0,#&600
 ORR R0,R0,#&20000000
 STR R0,[R1]
 MOV R0,#&14
 SWI WORD
 ADD R2,R1,#4
 B MAILNAMLEN
MAILRETURN = LF,"From: ",CR
MAILFILE = "$.Mail.PostBox0",CR
MAILFILEOFFSET * 14
MAILFULLNAME = "&.Mail.Defaults",CR
 ALIGN
MAILNAMLEN LDRB R0,[R2],#1
 STRB R0,[R9],#1
 CMP R0,#" "
 BHI MAILNAMLEN
 ADR R1,MAILFULLNAME
 MOV R0,#&40
 SWI OPEN ;try finding &.Mail.Defaults
 CMP R0,#0
 BEQ MAILNOFULLNAME
 AND R1,R0,#255
 MOV R0,#4
 MOV R2,R9
 MOV R3,#256
 MOV R4,#0
 SWI MULTIPLE
 MOV R0,#0
 SWI OPEN ;close mail.defaults
MAILDEFAULTSEND LDRB R0,[R9],#1
 CMP R0,#4
 BHI MAILDEFAULTSEND
MAILNOFULLNAME LDRB R0,[R9,#-1]!
 CMP R0,#32
 BCC MAILNOFULLNAME
 ADD R9,R9,#1
 MOV R0,#10
 STRB R0,[R9],#1
 STRB R0,[R9],#1
 ADR R0,MAILERRHAN
 ADD R1,ARGP,#TRANS
 ADD R1,R1,#128
 MOV R2,#0
 MOV R3,#0
 SWI CONTROL
 ADR R1,MAILFILE
 ADD R2,ARGP,#TRANS
 BL MOVNM1
MAILOPEN MOV R0,#&C0
 ADD R1,ARGP,#TRANS
 SWI OPEN
 CMP R0,#0
 BEQ MAILERRHAN
MAILSD AND R0,R0,#255
 STMFD SP!,{R0,R2}
 BL INITHAN ;reset error handler
 BL PROMPT
 = "Mailing: ",0
 ADD R1,ARGP,#TRANS
MAILSDNAME LDRB R0,[R1],#1
 CMP R0,#" "
 SWICS WRITEC
 BCS MAILSDNAME
 LDMFD SP!,{R1,R2}
 MOV R0,#2
 SWI ARGS
 MOV R4,R2
 MOV R0,#1
 ADD R2,ARGP,#MSTACK
 SUB R3,R9,R2
 SWI MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#START]
 LDR R3,[AP,#GS]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#GE]
 LDR R3,[AP,#END]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#1
 ADR R2,MAILEND
 MOV R3,#2
 SWI MULTIPLE
 MOV R0,#0
 SWI OPEN
 MOV R0,#143
 MOV R1,#18
 LDRB R2,[SP]
 SWI BYTE
 LDRB R1,[SP,#1]
 MOV R0,#&C6
 MOV R2,#0
 SWI BYTE ;reset exec file
 ADD SP,SP,#4
 BL STATUS
 BL INFORR
 = "Mailed.",0
 B EDITOR
MAILEND = 4,4,0,0
MAILERRHAN BL SETARGP
 ADD R5,ARGP,#TRANS
 LDRB R0,[R5,#MAILFILEOFFSET]
 ADD R0,R0,#1
 STRB R0,[R5,#MAILFILEOFFSET]
 CMP R0,#"8"
 BCC MAILOPEN
ERML2 LDMFD SP!,{R2}
 MOV R0,#143
 MOV R1,#18
 SWI BYTE
 BL MSG
 = "Catastrophe: $.mail.postbox# not found",0
 ALIGN
MAILDEC MOV R0,#"0"
MAILDECLOOP SUBS R2,R2,#10
 ADDCS R0,R0,#1
 BCS MAILDECLOOP
 TEQ R0,#"0"
 STRNEB R0,[R9],#1
 ADD R0,R2,#"0"+10
 STRB R0,[R9],#1
 MOV PC,R14
 ]
 [ OLDMAIL=1
MAILEC = "$.EcoMail.Out.",CR
MAILNM = ".MailBox",CR
 ALIGN
MAIL BL PROMPT
 = "Type user name to send text to:",0
 BL READLRNOCOPY
 MOV R0,#0
 MOV R1,#0
 SWI ARGS
 STMFD SP!,{R0} ;current fsyst
 MOV R0, #&C6
 MOV R1, #0
 MOV R2, #0
 SWI BYTE ; exec file off
 STRB R1, [SP, #1]
 MOV R0,#143
 MOV R1,#18
 MOV R2,#5
 SWI BYTE ;net
 ADR R1,MAILEC
 ADD R2,ARGP,#TRANS
 BL MOVNM0
 SUB R2,R2,#1
 ADD R4,R2,#10
 BL MOVBUF
 STRB R0,[R4]
 ADD R1,ARGP,#TRANS
 MOV R0,#&C0
 SWI OPEN
 TEQ R0,#0
 BNE MAILSD
 ADD R2,ARGP,#TRANS
 MOV R0,#"$"
 STRB R0,[R2],#1
 MOV R0,#"."
 STRB R0,[R2],#1
 BL MOVBUF
 SUB R2,R2,#1
 ADR R1,MAILNM
 BL MOVNM0
 ADD R1,ARGP,#TRANS
 MOV R0,#&C0
 SWI OPEN
 TEQ R0,#0
 BEQ ERML2
MAILSD AND R0,R0,#255
 STMFD SP!,{R0,R2}
 BL PROMPT
 = "Mailing: ",0
 ADD R1,ARGP,#TRANS
MAILSDNAME LDRB R0,[R1],#1
 CMP R0,#" "
 SWICS WRITEC
 BCS MAILSDNAME
 LDMFD SP!,{R1,R2}
 MOV R0,#2
 SWI ARGS
 MOV R4,R2
 MOV R0,#1
 LDR R2,[AP,#START]
 LDR R3,[AP,#GS]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#GE]
 LDR R3,[AP,#END]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R6,R1
 ADD R1,ARGP,#TRANS
 MOV R2,#6
 STR R2,[R1]
 BL MAILWORD
 LDRB R7,[R1,#2]
 LDRB R2,[R1,#1]
 STRB R2,[R1,#2]
 MOV R2,#7
 STRB R2,[R1]
 BL MAILWORD
 MOV R0,#6
 ADD R2,ARGP,#MSTACK
 SWI MULTIPLE
 ADD R1,ARGP,#TRANS
 STRB R7,[R1,#2]
 BL MAILWORD
 MOV R1,R6
 MOV R0,#1
 ADR R2,MAILEN1
 MOV R3,#MAILEN2-MAILEN1
 SWI MULTIPLE
 MOV R0,#1
 ADD R2,ARGP,#MSTACK
 LDRB R3,[R2],#1
 ADD R2,R2,R3
 LDRB R3,[R2],#1
 SWI MULTIPLE
MAILFATAL1 MOV R1,R6
 MOV R0,#1
 ADR R2,MAILEN2
 MOV R3,#4
 SWI MULTIPLE
 MOV R0,#0
 SWI OPEN
 MOV R0,#143
 MOV R1,#18
 LDRB R2,[SP]
 SWI BYTE
 LDRB R1,[SP,#1]
 MOV R0,#&C6
 MOV R2,#0
 SWI BYTE ;reset exec file
 ADD SP,SP,#4
 BL STATUS
 BL INFORR
 = "Mailed.",0
 B EDITOR
MAILEN1 = TERM,TERM,"Mailed from Twin by network user: "
MAILEN2 = TERM,TERM,26,TERM
 ALIGN
MAILWORD MOV R0,#&13
 SWI WORD
 LDRB R2,[R1]
 TEQ R2,#0
 MOVNE PC,R14
 B MAILFATAL1
ERML2 LDMFD SP!,{R2}
 MOV R0,#143
 MOV R1,#18
 SWI BYTE
 BL MSG
 = "Mailbox not found",0
 ALIGN
 ]
CHLFCR LDR R4,[AP,#START]
 BL GPBACK
 LDR R4,[AP,#GE]
 LDR R5,[AP,#END]
CHLC1 TEQ R4,R5
 BEQ CHLC2
 LDRB R0,[R4],#1
 TEQ R0,#LF
 TEQNE R0,#CR
 BNE CHLC1
 EOR R0,R0,#CR :EOR: LF
 STRB R0,[R4,#-1]
 B CHLC1
CHLC2 LDRB R0,[AP,#MODIFY]
 EOR R0,R0,#2
 B FULLMD
DELLINE LDR R1,[AP,#GE]
 LDR R2,[AP,#END]
 TEQ R1,R2
 BEQ EDITOR
 MOV R0,#0
 STRB R0,[AP,#X]
DELLI1 LDRB R0,[R1],#1
 TEQ R0,#TERM
 BNE DELLI1
 CMP R1,R2
 MOVCS R1,R2
 LDR R6,[AP,#GE]
 SUB R6,R1,R6 ;number of characters to move marks by
 STR R1,[AP,#GE]
 MOV UPDATE,#CSRONWARDS+ABORT
 LDR R2,[AP,#GS]
 LDR R1,[AP,#START]
 SUB R4,R2,R1
 B DELATMARK
STFIL2 BL STATUS
 B STFIL3
STFILE MOV UPDATE,#FULLSCREEN+ABORT
STFIL3 LDR R4,[AP,#START]
 BL GPBACK
CURST MOV R0,#0
 STRB R0,[AP,#X]
 B EDITOR
CUREND BL LENGTH
 STRB R0,[AP,#X]
 B EDITOR
CUREDF MOV UPDATE,#FULLSCREEN+ABORT
 LDR R4,[AP,#END]
 BL GPFWD
 BL NORMAL
 STRB R6,[AP,#X]
 LDRB R6,[AP,#BSM]
 STRB R6,[AP,#Y]
 B EDITOR
TABEXP LDR R4,[AP,#START]
 BL GPBACK
 MOV R0,#0
 STRB R0,[AP,#MARKS]
 LDR R4,[AP,#GE]
 LDR R5,[AP,#START]
 LDR R6,[AP,#END]
TABEX1 MOV R7,R5
 CMP R4,R6
 BCS TABEXX
 ADD R8,R5,#2048
 CMP R8,R4
 BCS TABEXX2
TABEX2 LDRB R0,[R4],#1
 STRB R0,[R5],#1
 TEQ R0,#TERM
 BEQ TABEX1
 TEQ R0,#9
 BNE TABEX2
 SUB R5,R5,#1
 SUB R3,R5,R7
 AND R3,R3,#7
 RSB R3,R3,#8
 MOV R0,#" "
TABEX3 STRB R0,[R5],#1
 SUBS R3,R3,#1
 BNE TABEX3
 B TABEX2
TABEXX STR R5,[AP,#GS]
 STR R6,[AP,#GE]
 B STFILE
TABEXX2 STR R5,[AP,#GS]
 STR R4,[AP,#GE]
 BL MSG
 = "No room: can't expand the TABs any more",0
 ALIGN
CONNECT ADD R0,ARGP,#AREA0
 ADD R1,ARGP,#AREA1
 LDRB R2,[R0,#PUSHNO]
 LDRB R3,[R1,#PUSHNO]
 CMP R2,#"0"
 CMPEQ R3,#"0"
 BNE CONNECTE3
 BL PROMPT
 = "Connect to which buffer? [0-9,+,-]",0
 ALIGN
CONNECTCHAR SWI READC
 BCS ESCAPE
 LDRB R1,[AP,#BUFFNO]
 CMP R0,#"+"
 ADDEQ R0,R1,#1
 CMP R0,#"-"
 SUBEQ R0,R1,#1
 CMP R0,#"0"
 BCC CONNECTEX
 CMP R0,#"9"
 BLS CONNECTGT
CONNECTEX BL SCRIMI
 BL APTOBUFF
 BL OTHERAP
 BL APTOBUFF
 BL OTHERAP
 ADD R8,ARGP,#ENDIT
CONNECTSHOW SWI NEWLINE
 LDRB R0,[R8,#BUFFNO]
 SWI WRITEC
 SWI WRITES
 = " -> ",0
CONSTAT0 LDRB R2,[R8,#MODIFY]
 TEQ R2,#0
 BNE CONSTAT4A
 BL VSTRNG
 = "Original """,0
 B CONSTAT4B
CONSTAT4C BL VSTRNG
 = "LF  CR """,0
 B CONSTAT4B
CONSTAT4D BL VSTRNG
 = "Discarded""",0
 B CONSTAT4B
CONSTAT4A TEQ R2,#2
 BEQ CONSTAT4C
 TEQ R2,#4
 BEQ CONSTAT4D
 BL VSTRNG
 = "Modified """,0
 ALIGN
CONSTAT4B ADD R1,R8,#NAMBUFF
CONNECTSHOW2 LDRB R0,[R1],#1
 CMP R0,#" "
 SWICS WRITEC
 BCS CONNECTSHOW2
 SWI WRITEI+""""
 LDRB R0,[R8,#BUFFNO]
 BL BUFFSUB
; BL WORDHX
 CMP R0,#"9"
 BCC CONNECTSHOW
 SWI WRITES
 = 10,13,"Now try :",0
 B CONNECTCHAR
CONNECTGT LDRB R1,[AP,#BUFFNO]
 CMP R1,R0
 BEQ EDITST
 BL OTHERAP
 LDRB R1,[AP,#BUFFNO]
 CMP R1,R0
 BEQ CONNECTFOUND1
 BL OTHERAP
 STMFD SP!,{R0} ;save desired buffer
 BL TOGWI1 ;put all space into temporary place
 BL APTOBUFF ;save current state of other window to allow ladder climb
 BL OTHERAP ;get back my AP
 BL APTOBUFF ;save old buffer's state from window to buffer
 LDMFD SP!,{R7}
 ADD R8,ARGP,#ENDIT
CONNECTFIND LDRB R0,[R8,#BUFFNO]
 CMP R0,R7
 BEQ CONNECTFOUND
 BL BUFFSUB
 B CONNECTFIND
CONNECTFOUND MOV R0,#28
CONNECTAPCOPY LDRB R1,[R8,R0]
 STRB R1,[AP,R0]
 ADD R0,R0,#1
 CMP R0,#256
 BCC CONNECTAPCOPY
 ADD R4,R8,#256
 STR R4,[AP,#PAGE]
 ADD R3,R4,#1
 STR R3,[AP,#START]
 LDRB R1,[R8,#CHARSTOGS]
 LDRB R2,[R8,#CHARSTOGS+1]
 ORR R1,R1,R2,LSL #8
 LDRB R2,[R8,#CHARSTOGS+2]
 ORR R1,R1,R2,LSL #16
 LDRB R2,[R8,#CHARSTOGS+3]
 ORR R1,R1,R2,LSL #24
 ADD R1,R3,R1
 STR R1,[AP,#GS]
 STR R1,[AP,#GE]
 LDRB R1,[R8,#TOTALCHARS]
 LDRB R2,[R8,#TOTALCHARS+1]
 ORR R1,R1,R2,LSL #8
 LDRB R2,[R8,#TOTALCHARS+2]
 ORR R1,R1,R2,LSL #16
 LDRB R2,[R8,#TOTALCHARS+3]
 ORR R1,R1,R2,LSL #24
 ADD R1,R1,R8
 STR R1,[AP,#TOP]
 SUB R1,R1,#1
 STR R1,[AP,#END]
 MOV R4,AP
 BL YCHEK1
 BL OTHERAP ;get back space's AP
 BL TOGWI1 ;recover all space
 MOV UPDATE,#FULLSCREEN
 B EDITST
CONNECTFOUND1 LDRB R0,[AP,#ONSCREEN]
 BL OTHERAP
 TEQ R0,#0
 BNE CONNECTFOUND2 ;other window onscreen so simply toggle
 STRB R0,[AP,#ONSCREEN] ;turn old info off
 BL TOGWI1 ;exchange windows
 MOV R0,#1
 STRB R0,[AP,#ONSCREEN]
 LDRB R3,[ARGP,#MINY]
 LDRB R2,[ARGP,#MAXY]
 STRB R2,[AP,#ELINE]
 STRB R3,[AP,#SLINE]
 MOV R4,AP
 BL YCHEK1
 MOV UPDATE,#FULLSCREEN
 B EDITAL
CONNECTFOUND2 BL TOGWI0
 MOV UPDATE,#THELOT
 B EDITAL
CONNECTE3 BL MSG
 = "Can't connect when there are Pushed buffers",0
 ALIGN
;move R8 up one buffer in the tree
BUFFSUB LDRB R1,[R8,#TOTALCHARS]
 LDRB R2,[R8,#TOTALCHARS+1]
 ORR R1,R1,R2,LSL #8
 LDRB R2,[R8,#TOTALCHARS+2]
 ORR R1,R1,R2,LSL #16
 LDRB R2,[R8,#TOTALCHARS+3]
 ORR R1,R1,R2,LSL #24
 ADD R8,R8,R1
 MOV PC,R14
PATHLOAD LDRB R0,[AP,#MODIFY]
 TST R0,#1
 BEQ PATHLOADF1
 MOV R0,#19
 BL PRMPTX
 = "Overwrite text [Y,ctrl shift f2/N]:",0
 MOV R3,#&B0+2
 BL YESNO1
 MOV R0,#4
 STRB R0,[AP,#MODIFY]
PATHLOADF1 BL PROMPT
 = "Type filename to load (via *path):",0
 BL READFL
 BL INFILE
 BEQ NONAME
 ADR R7,PATHLOADNAME
PATHLOAD0 LDRB R0,[R7]
 CMP R0,#0
 BEQ LOADFN
 MOV R0,#&FF
 MOV R1,R7
 ADD R2,ARGP,#MSTACK
 MOV R3,#0
 SWI FILE
PATHLOAD01 LDRB R0,[R7],#1
 CMP R0,#" "
 BHI PATHLOAD01
 STMFD SP!,{R7}
 ADD R8,ARGP,#MSTACK
 MOV R0,#&FF
 STRB R0,[R8,R4] ;end mark!
 MOV R9,#0 ;no | pain, yet!
PATHLOAD2 ADD R2,ARGP,#TRANS
 MOV R3,R2
PATHLOAD3 BL TSTESC
 LDRB R0,[R8],#1
 TEQ R0,#&FF
 BEQ PATHLOAD4 ;run out of choices!
 CMP R0,#"|"
 MOVEQ R9,#1 ;hah! | detected: pain to come
 CMPNE R0,#10
 CMPNE R0,#13
 BEQ PATHLOAD3A
 STRB R0,[R2],#1
 B PATHLOAD3
PATHLOAD4 CMP R9,#0
 LDMEQFD SP!,{R7}
 BEQ PATHLOAD0
 SUB R8,R8,#1 ;examine end of *path file again
 MOV R9,#0 ;not | any more
PATHLOAD3A CMP R2,R3
 MOVNE R0,#"."
 STRNEB R0,[R2],#1
 ADD R1,ARGP,#STRACC ;copy tail
 BL MOVNM0
 LDR R7,[AP,#END]
 LDR R6,[AP,#START]
 BL PROMPT
 = "Trying ",0
 ADD R1,ARGP,#TRANS
 BL WRITNAM1
 BL SELFWD
 MOV R0,#5
 SWI FILE
 TEQ R0,#0
 BEQ PATHLOAD2
 TEQ R0,#2
 BEQ PATHLOAD2
 SUBS R2,R7,R4 ;load addr:=<desired end>-length
 BCC NOROOM
 CMP R6,R2
 BHI NOROOM
 MOV R0,#&FF
 ADD R1,ARGP,#TRANS
 MOV R3,#0
 SWI FILE
 STR R2,[AP,#FLLOAD]
 STR R3,[AP,#FLEXEC]
 SUB R4,R7,R4 ;r4 becomes loaded address
 STR R4,[AP,#GE]
 STR R6,[AP,#GS]
 ADD R2,AP,#NAMBUFF
 ADD R1,ARGP,#TRANS
 BL MOVNM0
 ADD SP,SP,#4
 B LOADFEND
PATHLOADNAME = "*path m2path",0
 ALIGN
APPEND BL PROMPT
 = "Append to file:",0
 BL READFL
 ADD R1,ARGP,#STRACC
 MOV R0,#&C0
 SWI OPEN
 CMP R0,#0
 BEQ LOADFN
 AND R0,R0,#255
 STMFD SP!,{R0}
 BL PROMPT
 = "Appending to ",0
 BL WRITNAM
 LDMFD SP!,{R1}
 MOV R0,#2
 SWI ARGS
 MOV R4,R2
 MOV R0,#1
 LDR R2,[AP,#START]
 LDR R3,[AP,#GS]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#1
 LDR R2,[AP,#GE]
 LDR R3,[AP,#END]
 SUBS R3,R3,R2
 SWINE MULTIPLE
 MOV R0,#0
 SWI OPEN
 MOV R0,#0
 STRB R0,[AP,#MODIFY]
 B EDITST
BUFPUSHNO BL MSG
 = "Sorry: I can push no more buffers",0
 ALIGN
BUFPUSH LDRB R0,[AP,#PUSHNO]
 CMP R0,#126
 BCS BUFPUSHNO
 LDR R1,[AP,#GS]
 MOV R2,AP
 ADD R4,R1,#256 ;current gap start+256
 LDR R5,[AP,#GE]
 CMP R4,R5 ;current gap end
 BCC BUFPUSH1
 BL MSG
 = "Not enough memory to push the buffer",0
 ALIGN
BUFPUSH1 LDRB R0,[R2],#1 ;move AP info to GS
 STRB R0,[R1],#1
 TEQ R1,R4
 BNE BUFPUSH1
 MOV R6,R4
 MOV R7,R5
 BL INITSP ;new space based on old GS +256 (in R4) to old GE (in R5)
 LDRB R0,[AP,#PUSHNO]
 ADD R0,R0,#1
 STRB R0,[AP,#PUSHNO]
 MOV UPDATE,#FULLSCREEN
 B EDITST
BUFPOP LDRB R0,[AP,#PUSHNO]
 CMP R0,#"0"
 BNE BUFPOP1
 BL MSG
 = "Can't pop any more buffers",0
 ALIGN
BUFPOP1 LDRB R0,[AP,#MODIFY]
 TST R0,#1
 BEQ BUFPOP2
 MOV R0,#19
 BL PRMPTX
 = "Destroy current buffer with Pop? [Y,ctrl shift f5/N]:",0
 MOV R3,#&B0+5
 BL YESNO1
BUFPOP2 LDR R4,[AP,#PAGE]
 LDR R3,[AP,#TOP] ;new GE
 SUB R6,R4,#256 ;old info, new GS
 ADD R2,AP,#4
 ADD R5,R6,#4 ;don't copy first word (TSM, BSM, SLINE, ELINE)
BUFPOP3 LDRB R0,[R5],#1
 STRB R0,[R2],#1
 TEQ R5,R4
 BNE BUFPOP3 ;copy info
 LDR R0,[AP,#PAGE]
 LDR R1,[AP,#GS]
 STR R6,[AP,#GS]
 SUB R4,R1,R0 ;Old GS-old PAGE
 SUB R5,R6,R4 ;new GS-(Old GS-old PAGE)
 STR R5,[AP,#PAGE]
 ADD R5,R5,#1
 STR R5,[AP,#START] ;new START = new PAGE +1
 LDR R0,[AP,#GE]
 LDR R1,[AP,#TOP]
 STR R3,[AP,#GE]
 SUB R4,R1,R0 ;old TOP-old GE
 ADD R5,R3,R4 ;new GE+(old TOP-old GE)
 STR R5,[AP,#TOP]
 SUB R5,R5,#1
 STR R5,[AP,#END] ;new END = new TOP-1
 MOV R4,AP
 BL YCHEK1
 MOV UPDATE,#FULLSCREEN
 B EDITST
GETMAIL BL DISPC2
 MOV R0,#0
 MOV R1,#0
 SWI ARGS
 STMFD SP!,{R0} ;save current fsyst
 MOV R0, #&C6
 MOV R1, #0
 MOV R2, #0
 SWI BYTE ;exec file off
 STRB R1,[SP,#1] ;old handle
 MOV R0,#143
 MOV R1,#18
 MOV R2,#5
 SWI BYTE ;select econet
 ADR R1,GETMAILMAIN
 BL GETMAILSUB
 ADR R1,GETMAILSECOND
 BL GETMAILSUB
 MOV R0,#143
 MOV R1,#18
 LDRB R2,[SP]
 SWI BYTE
 LDRB R1,[SP,#1]
 MOV R0,#&C6
 MOV R2,#0
 SWI BYTE ;reset exec file
 ADD SP,SP,#4
 B EDITST
GETMAILMAIN = "&.MailBox",CR
GETMAILSECOND = "&.Mail.InTray",CR
GETMAILSUB STMFD SP!,{R1,R14}
 BL PROMPT
 = "Reading ",0
 LDR R1,[SP]
 BL WRITNAM1
 MOV R0,#&C0
 SWI OPEN
 ANDS R1,R0,#255
 BEQ GETMAILSUBEXIT
 MOV R0,#2
 SWI ARGS
 TEQ R2,#0
 BEQ GETMAILSUBX
 STMFD SP!,{R1,R2}
 MOV R1,R2
 BL INSRTX
 LDMFD SP!,{R1,R2}
 MOV R3,R2 ;number of bytes
 MOV R2,R4 ;address to start insert
 MOV R0,#4
 SWI MULTIPLE
 MOV R0,#3
 MOV R2,#0
 SWI ARGS
 STMFD SP!,{R1}
 BL SCRIMI
 LDRB UPDATE,[AP,#MODIFY]
 TEQ UPDATE,#4
 MOV UPDATE,#1
 STRNEB UPDATE,[AP,#MODIFY]
 MOV UPDATE,#FULLSCREEN+ABORT
 LDMFD SP!,{R1}
GETMAILSUBX MOV R0,#0
 SWI OPEN ;close
GETMAILSUBEXIT LDMFD SP!,{R1,PC}
BOTHDN BL BOTHON
 BEQ PAGEDN
 BL OTHERAP
 BL PAGECL
 BL LINEFW
 BL GPFWD
 BL OTHERAP
 BL PAGECL
 BL LINEFW
 BL GPFWD
 MOV UPDATE,#BOTHSCREEN+ABORT
 B EDITOR
BOTHUP BL BOTHON
 BEQ PAGEUP
 BL OTHERAP
 BL PAGECL
 BL LINEBK
 BL GPBACK
 BL OTHERAP
 BL PAGECL
 BL LINEBK
 BL GPBACK
 MOV UPDATE,#BOTHSCREEN+ABORT
 B EDITOR
BOTHON ADD R0,ARGP,#AREA0
 TEQ R0,AP
 ADDEQ R0,ARGP,#AREA1
 LDRB R0,[R0,#ONSCREEN]
 TEQ R0,#0
 MOV PC,R14
OTHERAP ADD R6,ARGP,#AREA0
 TEQ R6,AP
 ADDEQ R6,ARGP,#AREA1
 MOV AP,R6
 MOV PC,R14
 LNK TaskMan
