**********************************************************************
* TED - String editor
**********************************************************************
**********************************************************************
* Equates
**********************************************************************
DEFINE EDBUFSIZE #300
ASSEMBLE
EDMINMEM EQU 200 Mimumum memory left for SOL
RPL
* Subjob eauates
DEFINE Ed#STK ZERO
ASSEMBLE
edSTK EQU 0 Function: Visit stack
RPL
**********************************************************************
* Name: ED
* Stack: ( ob --> ob' )
* Description: General purpose object editor
**********************************************************************
ASSEMBLE
CON(1) 8
RPL
xNAME TED
tNAME xTED ED
::
CK1&Dispatch
str :: UFL?DoErr ZERO EdString ;
any EdObject
;
**********************************************************************
* Name: EdObject
* Stack: ( ob --> ob' )
* Description: Object editor
**********************************************************************
NULLNAME EdObject
::
UFL?DoErr
TedDecomp ZERO ( $ #pos )
BEGIN
EdString ( $' )
TedCompile ( ob' TRUE / $ #pos FALSE )
DUP ?SKIP ERRBEEP
UNTIL
EVAL ( --> ? ? .. ? )
;
**********************************************************************
* Name: EdString
* Stack: ( $ #pos --> $' )
* Description: String editor
**********************************************************************
NULLNAME EdString
::
TOADISP UnScroll TURNMENUOFF CLEARVDISP ( Prepare display )
FIFTYSIX TestSysFlag 1LAMBIND ( Save beep flag )
DoEd
FIFTYSIX 1GETABND ITE SetSysFlag ClrSysFlag ( Restore beep flag )
;
NULLNAME DoEd
::
FNT1
NULLHXS EDBUFSIZE EXPAND
4ROLL FREEINTEMP? ITE >TOPTEMP TOTEMPOB 4UNROLL
GARBAGE
* ( $ #pos fnt1 $buff )
CODE
FMTWIDTH EQU 32 Format to 32 chars wide
sTIMER2ON EQU 0 For LoPwrShutDn
sSCROLL EQU 0
sFNDCS EQU 0 Find with case ignore?
sBLKINV EQU 0 Invert? flag for display subroutines
sDELNOCLIP EQU 0 Block clip/cut mode
sBLINK EQU 1 Blink flag for key wait
sINPDEC EQU 2 Input decimal number?
sCHRMAIN EQU 2 Set if ChrCat is called from main Ed loop
sFIND EQU 3 Input find string?
sREPL? EQU 3 Input replace string?
*sBPOFF EQU 4
sLOWCS EQU 5 Lower case on?
sOVERWR EQU 6 OverWrite on?
sCURSOR EQU 7 Cursor on or off?
sDELAY EQU 8 Have to delay in keywait?
sREPEAT EQU 9 Key repeat on?
sDISPOK EQU 10 Display ok?
sLINBAD EQU 11 Display line is bad?
ABASE 0
CURSX ALLOC 2 Cursor X position on screen
CURSY ALLOC 1 Cursor Y position on screen
XOFF ALLOC 5 Cursor X-scroll offset
WANTX ALLOC 5 Wanted X-position
SAVEX ALLOC 2 Cursor X Temporary save during input
SAVEY ALLOC 1 Cursor Y Temporary save during input
SAVEPOS ALLOC 5 Cursor POS Temporary save during input
LASTKEY ALLOC 3 Last pressed key
EDARG ALLOC 5 Repeat count
CCCHR ALLOC 2 Current char in character browser
EDMODE ALLOC 3 ST flag save
EDCNTRWID ALLOC 1 Counter width. High bit set if decimal counter
EDCNTR ALLOC 8 Counter
* Start/End addresses:
STR ALLOC 5 Start of edit string
CUT ALLOC 5 Start of CUT string 00000 = No cut
MEMEND ALLOC 5 End of allocated memory
* Screen addresses:
CURPOS ALLOC 5 Cursor position
TOPPOS ALLOC 5 Position of 1st char on topmost displayed row
* Updatable, STR<=LOC<=STREND
* 00000 = none
UPDSTR ALLOC 0 Start of updateable pointers
STREND ALLOC 5 End of edit string
BLK ALLOC 5 Start position of block
BLKEND ALLOC 5 End position of block
MARKX ALLOC 5 Last different cursor position
MARK0 ALLOC 5 Mark 0 position
MARK1 ALLOC 5 Mark 1 position
MARK2 ALLOC 5 Mark 2 position
MARK3 ALLOC 5 Mark 3 position
MARK4 ALLOC 5 Mark 4 position
MARK5 ALLOC 5 Mark 5 position
MARK6 ALLOC 5 Mark 6 position
MARK7 ALLOC 5 Mark 7 position
MARK8 ALLOC 5 Mark 8 position
MARK9 ALLOC 5 Mark 9 position
UPDEND ALLOC 0 End of updateable pointers
* #94
FNDMAX EQU 20 Max lenght of find string
FNDLEN ALLOC 2 Lenght of find string
FND$ ALLOC 2*(FNDMAX) Find string storage
INPMAX EQU 20 Max lenght of input
INPOFF ALLOC 2 Offset to input display on row (past prompt)
INPLEN ALLOC 2 Input string lenght
INP$ ALLOC 2*(INPMAX) Input string storage
SAVEX2 ALLOC 2 Cursor X Temporary save during ChrCat
SAVEY2 ALLOC 1 Cursor Y Temporary save during ChrCat
* #ED
bRECORD EQU 0 Recording macro
bEXEC EQU 1 Executing macro
MACMAX EQU 50 Maximum number of macro keys
MACMODE ALLOC 1 Macro mode storage
MACLEN ALLOC 2 Number of macro keys
MACRUN ALLOC 2 Run position in list of macro keys
MACKEYS ALLOC 3*(MACMAX)
* #188
EDRSTK ALLOC 4*5 Save for ml RSTK if needed
* #1AC
REPSTACK ALLOC 4 Key repeat stack, 2 keys
EDSPEED ALLOC 1 Speed flag (0/F = slow/fast)
GOSBVL =SAVPTR
CLRST
GOSUBL InitDisp
GOSUBL InitBuf Init variables, memory etc
GOSBVL =getBPOFF Establish beep flag
GOSUBL InitClk Initialize clock
EdLoop GOSUBL DispEd Display screen
GOSUBL SetCurs Show cursor position
ST=1 sBLINK Wait for key with blink
GOSUBL WaitKey
GOSUBL AdjustKey Modify according to shift mode
GOSUB SaveKey Save as last key
GOSUB SaveMacro Save as macro key if necessary
GOSUBL SetMarkX Save current position
GOSUBL ClrCurs Cursor off
ST=1 sREPEAT Repeat enabled by default
argrep ST=1 sDISPOK Display is OK
ST=0 sLINBAD Line is OK
GOSUB DoEdKey Do key
BackToEd GOSUB MacroRun? Running a macro?
GOC nomrun Nope
GOSUBL DispEd Yes - show display
GOSUB RclMacKey Get next key
GOTO argrep And do it
nomrun GOSUB ArgRepeat? Repeating a key?
GOC noarun Nope
GOSUBL DispEd Yes - show display
GOSUB RclKey Recall the key
GOSBVL =chk_attn Abort if ATTN pressed
GONC argrep
GOSUB BadEdKey Beep for ATTN
noarun
BackToEdMain GOSUBL UpdMark0 Update last cursor position
GOTO EdLoop Loop
**********************************************************************
* Clear key-repeat counter
**********************************************************************
EdClrArg C=R4.F A
D1=C
D1=(2) EDARG
C=0 A
DAT1=C A
RTN
**********************************************************************
* Is key-repeat on?
**********************************************************************
ArgRepeat?
GOSUB RclKey Don't repeat modifiers
?B=0 XS
RTNYES
D1=(2) EDARG Check if ARG <> 0
C=DAT1 A
C=C-1 A
RTNC ARG = 0, no repeat
DAT1=C A Decrement
?C=0 A ARG = 1 means no repeat too
RTNYES
RTNCC
**********************************************************************
* Recall last pressed key
**********************************************************************
RclKey C=R4.F A
D1=C
D1=(2) LASTKEY
C=DAT1 X
B=C X
RTN
**********************************************************************
* Save key as last pressed key (for repeat and macro save)
**********************************************************************
SaveKey C=R4.F A
D1=C
D1=(2) LASTKEY
C=B X
DAT1=C X
RTN
**********************************************************************
* Is a macro sequence running?
**********************************************************************
MacroRun? C=R4.F A
D1=C
D1=(2) MACMODE
C=DAT1 1
?CBIT=0 bEXEC
RTNYES Not running
D1=(2) MACLEN Not running if last key in sequence
A=DAT1 B was just executed
D1=(2) MACRUN
C=DAT1 B
?C>A B
GOYES macrunend
RTNCC Running!
macrunend D1=(2) MACMODE last key was just done, finish
C=DAT1 B macro run
CBIT=0 bEXEC
DAT1=C 1
RTNSC
**********************************************************************
* Get next macro key in sequence, assuming macro run is on
**********************************************************************
RclMacKey C=R4.F A
D1=C
D1=(2) MACRUN
C=0 A
C=DAT1 B
C=C+1 B run position++
DAT1=C B
D1=(2) MACKEYS Fetch the key from sequence
AD1EX
A=A+C A
A=A+C A
A=A+C A
AD1EX
D1=D1- 6 Counteract the increment
A=DAT1 X
B=A X B[A] = key
RTN
**********************************************************************
* Clear macro sequence
**********************************************************************
EdClrMac C=R4.F A
D1=C
D1=(2) MACMODE
C=DAT1 1
CBIT=0 bEXEC
DAT1=C 1
?CBIT=0 bRECORD
RTNYES Not recording, no need to clear
CBIT=0 bRECORD
DAT1=C 1
D1=(2) MACLEN Error occurred during record,
C=0 A can't have partial saves
DAT1=C B
* Show warning
RTN
**********************************************************************
* Add a new key to macro sequence
**********************************************************************
SaveMacro ?B=0 XS Ignore modifiers!
RTNYES
C=R4.F A
D1=C
D1=(2) MACMODE
C=DAT1 1
?CBIT=0 bRECORD
RTNYES Record off - no save
D1=(2) MACLEN Check for overflow
A=0 A
A=DAT1 B
LC(2) MACMAX
?A>=C B
GOYES macsaver Overflow!
A=A+1 B
DAT1=A B lenght++
D1=(2) MACKEYS Save key to it's position in sequence
CD1EX
C=C+A A
C=C+A A
C=C+A A
CD1EX
D1=D1- 3
C=B X
DAT1=C X
RTNCC
macsaver A=0 A Clear macro modes due to error
DAT1=A B Lenght = 0
D1=(2) MACMODE
DAT1=A 1 RECORD = 0
* Show warning
RTN
**********************************************************************
* Key dispatchee to start macro execution
**********************************************************************
EdExecMac C=R4.F A
D1=C
D0=C
D0=(2) MACLEN
A=DAT0 B
?A=0 B
GOYES exemer No macro exists - error
D1=(2) MACMODE
C=DAT1 1
?CBIT=0 bRECORD
GOYES exmac5 Not recording - ok to exec
A=A-1 B Terminate recording first
DAT0=A B lenght--
?A=0 B
GOYES exemer
CBIT=0 bRECORD Record off
exmac5 CBIT=1 bEXEC Exec on
DAT1=C 1
D1=(2) MACRUN Start from first key in sequence
LC(2) 1
DAT1=C B
RTN
exemer GOTO BadEdKey
**********************************************************************
* Start recording new macro
**********************************************************************
EdStartMac ST=0 sREPEAT
C=R4.F A
D1=C
D1=(2) MACMODE
C=DAT1 1
?CBIT=1 bEXEC
GOYES macster
?CBIT=1 bRECORD
GOYES macster
CBIT=1 bRECORD
DAT1=C 1
C=0 A
D1=(2) MACLEN
DAT1=C B
RTN
macster GOTO BadEdKey
**********************************************************************
* Terminate macro record
**********************************************************************
EdEndMac ST=0 sREPEAT
C=R4.F A
D1=C
D1=(2) MACMODE
C=DAT1 1
?CBIT=0 bRECORD
GOYES macener
?CBIT=1 bEXEC
GOYES macener
CBIT=0 bRECORD
DAT1=C 1
D1=(2) MACLEN Pop end-key
C=DAT1 B
C=C-1 B
GOC macener
DAT1=C B
RTN
macener GOTO BadEdKey
**********************************************************************
* Execute main loop key
**********************************************************************
DoEdKey GOSUBL EdStrKey? String keys first so
GONC + other programs can use EdChrKey?
GOLONG DoEdStrKey
+ GOSUBL EdChrKey?
GONC +
GOLONG DoEdChrKey
+ GOSUBL DispatchKey:
EDKEY MACRO
CON(3) $1
CON(4) ($2)-(*)
EDKEY ENDM
* Shift modes
NS EQU #100
LS EQU #200
RS EQU #300
ANS EQU #400
ALS EQU #500
ARS EQU #600
EdKeyTab EDKEY (UPCODE)+(NS),EdUp
EDKEY (UPCODE)+(LS),EdPgUp
EDKEY (UPCODE)+(RS),EdFarUp
EDKEY (LEFTCODE)+(NS),EdLt
EDKEY (LEFTCODE)+(LS),EdWordLt
EDKEY (LEFTCODE)+(RS),EdFarLt
EDKEY (DOWNCODE)+(NS),EdDn
EDKEY (DOWNCODE)+(LS),EdPgDn
EDKEY (DOWNCODE)+(RS),EdFarDn
EDKEY (RIGHTCODE)+(NS),EdRt
EDKEY (RIGHTCODE)+(LS),EdWordRt
EDKEY (RIGHTCODE)+(RS),EdFarRt
EDKEY (Sfkey1)+(NS),SetBlk
EDKEY (Sfkey2)+(NS),SetBlkEnd
EDKEY (Sfkey3)+(NS),CopyBlk
EDKEY (Sfkey4)+(NS),DelBlk
EDKEY (Sfkey1)+(RS),SetBlkUp
EDKEY (Sfkey2)+(RS),SetBlkDown
EDKEY (Sfkey3)+(RS),EdSwapClip
EDKEY (Sfkey4)+(LS),EdDelNoClip
EDKEY (Sfkey4)+(RS),EdDelNoBlk
EDKEY (DELCODE)+(NS),EdDel
EDKEY (DELCODE)+(LS),EdDelLine
EDKEY (DELCODE)+(RS),EdDelRt
EDKEY (DELCODE)+(ANS),EdDel
EDKEY (BACKCODE)+(NS),EdBS
EDKEY (BACKCODE)+(LS),EdDelWrdLt
EDKEY (BACKCODE)+(RS),EdDelWrdRt
EDKEY (BACKCODE)+(ANS),EdBS
EDKEY (ENTERCODE)+(NS),EdExit
EDKEY (ENTERCODE)+(ANS),EdIndNL
EDKEY (MINUSCODE)+(ALS),EdIndPrg
EDKEY (PLUSCODE)+(ALS),EdIndList
EDKEY (=7CODE)+(LS),SetMark7
EDKEY (=7CODE)+(RS),GoMark7
EDKEY (=8CODE)+(LS),SetMark8
EDKEY (=8CODE)+(RS),GoMark8
EDKEY (=9CODE)+(LS),SetMark9
EDKEY (=9CODE)+(RS),GoMark9
EDKEY (=4CODE)+(LS),SetMark4
EDKEY (=4CODE)+(RS),GoMark4
EDKEY (=5CODE)+(LS),SetMark5
EDKEY (=5CODE)+(RS),GoMark5
EDKEY (=6CODE)+(LS),SetMark6
EDKEY (=6CODE)+(RS),GoMark6
EDKEY (=1CODE)+(LS),SetMark1
EDKEY (=1CODE)+(RS),GoMark1
EDKEY (=2CODE)+(LS),SetMark2
EDKEY (=2CODE)+(RS),GoMark2
EDKEY (=3CODE)+(LS),SetMark3
EDKEY (=3CODE)+(RS),GoMark3
EDKEY (=0CODE)+(RS),GoMark0
EDKEY (PRGCODE)+(RS),EdChrCat
EDKEY (PRGCODE)+(LS),EdInputChr
EDKEY (MATHCODE)+(LS),EdInputRow
EDKEY (MATHCODE)+(RS),EdInputPos
EDKEY (MATHCODE)+(NS),EdInputArg
EDKEY (CUSTCODE)+(NS),EdExecMac
EDKEY (CUSTCODE)+(LS),EdStartMac
EDKEY (CUSTCODE)+(RS),EdEndMac
EDKEY (USERCODE)+(LS),EdInitCntr
EDKEY (USERCODE)+(RS),EdOutCntr
EDKEY (NEXTCODE)+(RS),EdStatus
EDKEY (Sfkey5)+(RS),EdReplSPos
EDKEY (Sfkey5)+(LS),EdRepl?SPos
EDKEY (Sfkey6)+(NS),EdFind
EDKEY (Sfkey6)+(RS),EdRepl
EDKEY (Sfkey6)+(LS),EdRepl?
EDKEY (NEXTCODE)+(NS),EdFindNext
EDKEY (NEXTCODE)+(LS),EdFindPrev
EDKEY (USERCODE)+(NS),EdFindDelim
EDKEY (STOCODE)+(NS),DoEdStk
EDKEY (STOCODE)+(LS),PushStk1
EDKEY (STOCODE)+(RS),RclStk1
EDKEY (SHIFTCODE),EdModLS
EDKEY (ALTCODE),EdModRS
* EDKET (ALPHACODE),EdModA \
EDKEY (30)+(NS),AlphaOn By Dan
EDKEY (30)+(ANS),AlphaOff
EDKEY (30)+(ALS),TogCase /
EDKEY (CHSCODE)+(NS),TogBeep
EDKEY (CHSCODE)+(LS),TogCase
EDKEY (CHSCODE)+(RS),TogOver
EDKEY (EEXCODE)+(NS),TogSpeed
EDKEY (ATTNCODE)+(NS),EdON
EDKEY (ATTNCODE)+(RS),EdOFF
EDKEY 0,BadEdKey
**********************************************************************
* Dispatch from keytable in return stack
**********************************************************************
DispatchKey: C=RSTK
D0=C
DispatchKey C=R4.F A
D1=C
edkeylp A=DAT0 X
D0=D0+ 7
?A=0 X
GOYES gotkey4
?A#B X
GOYES edkeylp
gotkey4 D0=D0- 4
A=0 A
A=DAT0 4
?ABIT=0 15
GOYES gotPkey4
P= 4-1
A=-A WP
A=-A A
P= 0
gotPkey4 CD0EX
A=A+C A
PC=A
**********************************************************************
* Bad key - error
**********************************************************************
BadEdKey ST=0 sREPEAT No repeat
GOSUB EdClrArg No repeat count
GOSUB EdClrMac No macro save
ErrBeep ?ST=1 sBPOFF Fart
RTNYES
LC(2) #FB
GOVLNG =RCKBp
**********************************************************************
* Modifier keys
**********************************************************************
* EdModA GOSUB GetAnns
* ?ABIT=1 6
* GOYES clrmoda
* ABIT=1 6
* GONC edmodok
* clrmoda ABIT=0 6
* GOC edmodok
EdModLS GOSUB GetAnns
?ABIT=1 4
GOYES clrmodls
ABIT=1 4
ABIT=0 5
GONC edmodok
clrmodls ABIT=0 4
GOC edmodok
EdModRS GOSUB GetAnns
?ABIT=1 5
GOYES clrmodrs
ABIT=1 5
ABIT=0 4
GONC edmodok
clrmodrs
ABIT=0 5
* Note: REPEAT IS ENABLED! This allows changing between f.ex up and up+LS
edmodok ST=1 sREPEAT
DAT0=A B
RTN
GetAnns D0=(5) =aANNUNCIATORS
A=DAT0 A
D0=A
A=DAT0 B
RTN
**********************************************************************
* Set alpha annunciator on
**********************************************************************
AlphaOn GOSUB GetAnns
ABIT=1 6
DAT0=A B
D0=(5) =ANNCTRL
A=DAT0 B
ABIT=1 2
DAT0=A B
RTN
**********************************************************************
* Cleat alpha annunciator
**********************************************************************
AlphaOff GOSUB GetAnns
ABIT=0 6
DAT0=A B
D0=(5) =ANNCTRL
A=DAT0 B
ABIT=0 2
DAT0=A B
RTN
**********************************************************************
* Show editor status page
**********************************************************************
EdStatus GOSUBL EdClrArg Don't repeat again and again..
GOSUBL ClrDisp No room for text
GOSUBL GetDispRow1
D1=D1+ 10
GOSUBL Disp:Ret
CSTRING 'Editor Status'
GOSUBL GetText
B=C A
P= 3-1
GOSUBL DispRow:Ret
CSTRING 'Text size : '
GOSUBL Disp2Dec6B
D1=D1+ 3
GOSUB DispINS
GOSUBL GetCut
B=C A
A=R4 A
LC(5) EDSPEED
A=A+C A
D1=A
C=DAT1 S Speed flag
D=C S
P= 4-1
GOSUBL DispRow:Ret
CSTRING 'Clip size : '
GOSUBL Disp2Dec6B
D1=D1+ 3
GOSUB DispFAST
GOSUBL GetFree
B=C A
P= 5-1
GOSUBL DispRow:Ret
CSTRING 'Free memory : '
GOSUBL Disp2Dec6B
D1=D1+ 3
GOSUB DispCASE
GOSUBL GetWork
B=C A
P= 6-1
GOSUBL DispRow:Ret
CSTRING 'Work memory : '
GOSUBL Disp2Dec6B
D1=D1+ 3
GOSUB DispBEEP
GOSUBL GetCurPos
D1=(2) STR
A=DAT1 A
C=C-A A
B=C A
P= 8-1
GOSUBL DispRow:Ret
CSTRING 'Cursor pos : '
GOSUBL Disp2Dec6B
P= 9-1
GOSUBL DispRow:Ret
CSTRING 'Cursor X : '
C=R4.F A
D0=C
D0=(2) CURSX
C=0 A
C=DAT0 B
D0=(2) XOFF
A=DAT0 A
C=C+A A
C=C+1 A
GOSUBL DispDec6
P= 10-1
GOSUBL DispRow:Ret
CSTRING 'Cursor line : '
C=R4.F A
D0=C
D0=(2) STR
A=DAT0 A
D0=(2) CURPOS
C=DAT0 A
D0=A
C=C-A A
CSRB.F A
B=C A
D=0 A
LCASC '\n'
dsplinlp B=B-1 A
GOC dsplin10
A=DAT0 B
D0=D0+ 2
?A#C B
GOYES dsplinlp
D=D+1 A
GONC dsplinlp
dsplin10 D=D+1 A
C=D A
GOSUBL DispDec6
ST=0 sREPEAT
ST=0 sBLINK
GOSUBL WaitKey
GOSUBL ClrDisp
ST=0 sDISPOK
RTN
DispINS ?ST=1 sOVERWR
GOYES dspins10
GOSUBL Disp:Ret
CSTRING 'Insert'
RTN
dspins10 GOSUBL Disp:Ret
CSTRING 'Overwrite'
RTN
DispFAST GOSUBL Disp:Ret
CSTRING 'Fast: '
?D#0 S
GOYES dspfast10
dspfast10 GOTO DispON/OFF
DispCASE GOSUBL Disp:Ret
CSTRING 'Case: '
?ST=1 sLOWCS
GOYES dspcase10
dspcase10 GOTO DispON/OFF
DispBEEP GOSUBL Disp:Ret
CSTRING 'Beep: '
?ST=0 sBPOFF
GOYES dspbeep10
dspbeep10
* GOTO DispON/OFF
DispON/OFF GONC dspoff
GOSUBL Disp:Ret
CSTRING 'ON'
RTN
dspoff GOSUBL Disp:Ret
CSTRING 'OFF'
RTN
**********************************************************************
* Exit ED
**********************************************************************
EdExit GOSUB ShrinkEd
GOVLNG =GPPushFLoop
**********************************************************************
* Shrink edit buffer
**********************************************************************
ShrinkEd GOSUBL GetCutFree
D0=A
B=A A
A=DAT0 A
A=A-C A Fix link
DAT0=A A
D1=(2) STR
A=DAT1 A
D0=A
D0=D0- 5
A=DAT0 A Fix $len
A=A-C A
DAT0=A A
A=B A
GOVLNG =MOVERSD
**********************************************************************
* Pass control to STK system rpl sub program
**********************************************************************
DoEdStk GOSUB ShrinkEd
GOSUBL GetCurPos Push mode in R1 and curpos in R0
D1=(2) STR
A=DAT1 A
C=C-A A
CSRB.F A
R0=C curpos
LC(5) edSTK
R1=C mode
GOSBVL =PUSH2#
GOVLNG =PushTLoop
**********************************************************************
* Turn calc off
**********************************************************************
EdOFF GOSUBL EdClrArg
GOSUBL EdDeepSleep
RTN
**********************************************************************
* ON key just refreshes the display
**********************************************************************
EdON ST=0 sDISPOK
ST=0 sREPEAT
RTN
**********************************************************************
* Toggle beep flag
**********************************************************************
TogBeep ST=0 sREPEAT
D0=(5) aSystemFlags
C=DAT0 A
C=C+CON A,13
D0=C
C=DAT0 B
?ST=0 sBPOFF
GOYES edbeepon
CBIT=0 3
DAT0=C B
ST=0 sBPOFF
RTN
edbeepon CBIT=1 3
DAT0=C B
ST=1 sBPOFF
RTN
**********************************************************************
* Toggle upper/lower case
**********************************************************************
TogCase ST=0 sREPEAT No repeat
?ST=0 sLOWCS
GOYES edcaseon
ST=0 sLOWCS
RTN
edcaseon ST=1 sLOWCS
RTN
**********************************************************************
* Toggle insert/overwrite
**********************************************************************
TogOver ST=0 sREPEAT No repeat
?ST=0 sOVERWR
GOYES edoveron
ST=0 sOVERWR
RTN
edoveron ST=1 sOVERWR
RTN
**********************************************************************
* Toggle speed 0/F
**********************************************************************
TogSpeed ST=0 sREPEAT No repeat
AD1EX ->data
LC(5) EDSPEED
A=A+C A
D1=A
A=DAT1 S
A=-A-1 S 0/F --> F/0
DAT1=A S
RTN
**********************************************************************
* Delete current line
**********************************************************************
EdDelLine GOSUBL EdLineStart Set start of block
D1=(2) BLK
AD0EX
DAT1=A A
GOSUBL EdLine+ Set end of block
D1=(2) BLKEND
AD0EX
DAT1=A A
GOTO DelBlk Delete
**********************************************************************
* Delete rest of row
**********************************************************************
EdDelRt GOSUBL GetCurPos Set start of block
D1=(2) BLK
AD0EX
DAT1=A A
GOSUBL EdLineEnd Set end of block
D1=(2) BLKEND
AD0EX
DAT1=A A
GOTO DelBlk Delete
**********************************************************************
* Set block start
**********************************************************************
SetBlk GOSUBL GetCurPos
D1=(2) BLK
DAT1=C A
ST=0 sREPEAT
ST=0 sDISPOK
RTN
**********************************************************************
* Set block end
**********************************************************************
SetBlkEnd GOSUBL GetCurPos
D1=(2) BLKEND
DAT1=C A
ST=0 sREPEAT
ST=0 sDISPOK
RTN
**********************************************************************
* Set block from start to here
**********************************************************************
SetBlkUp D1=(2) STR
C=DAT1 A
D1=(2) BLK
DAT1=C A
GOTO SetBlkEnd
**********************************************************************
* Set block from here to end
**********************************************************************
SetBlkDown D1=(2) STREND
C=DAT1 A
D1=(2) BLKEND
DAT1=C A
GOTO SetBlk
**********************************************************************
* Mark P chars
**********************************************************************
MarkCharsP C=0 A
CPEX 0
MarkChars C=C+C A
MarkCharsC B=C A
GOSUBL GetCurPos
B=B+C A BLKEND
D1=(2) STREND
A=DAT1 A
?B>A A
RTNYES
D1=(2) BLK
DAT1=C A
D1=(2) BLKEND
C=B A
DAT1=C A
RTNCC
**********************************************************************
* Delete all but block. Clip not modified !
**********************************************************************
EdDelNoBlk GOSUBL GetBlk
GOC delblkerr
ST=0 sDISPOK
ST=0 sREPEAT
A=A+C A
D1=(2) CURPOS
C=DAT1 A
R1=C.F A
DAT1=A A
D1=(2) STREND
C=DAT1 A
C=C-A A
GOSUBL EdRemoveC
D1=(2) STR
A=DAT1 A
D1=(2) CURPOS
DAT1=A A
D1=(2) BLK
C=DAT1 A
C=C-A A
A=R1.F A
A=A-C A
R1=A.F A
GOSUBL EdRemoveC
GOSUB SetNoBlk
A=R1.F A
D0=A
GOLONG ToThisD0
**********************************************************************
* Delete block by moving it to the clip
**********************************************************************
EdDelNoClip ST=1 sDELNOCLIP
GOTO +
delblkerr GOLONG BadEdKey
EdDelBlk ST=0 sREPEAT No repeat since there's only 1 block
DelBlk ST=0 sDELNOCLIP
+ ST=0 sDISPOK Display will be invalid
GOSUBL GetBlk Get delimiters
GOC delblkerr No block marked!
D1=(2) CURPOS Set cursor to start of block
DAT1=A A
?ST=1 sDELNOCLIP
GOYES +
GOSUB Blk>Cut Move block to cut
GOC slowdelblk If failure then use slow memory swap
+ GOSUBL GetBlk Fast move was ok, get block
GOSUBL EdRemoveC And remove it
eddelblk10 GOSUBL ToThisPos Move to the new position
SetNoBlk C=R4.F A No block left
D1=C
C=0 A
D1=(2) BLK
DAT1=C A
D1=(2) BLKEND
DAT1=C A
RTN
slowdelblk GOSUBL GetBlk Use in-place memory swap to move
D0=A the block to cut
A=A+C A ->blockend
D1=(2) MEMEND
C=DAT1 A
D1=A
C=C-A A Free memory
GOSUBL EdBLKswap Swap memory
GOSUBL GetBlk Calculate new positions
D1=(2) MEMEND
A=DAT1 A
A=A-C A
D1=(2) CUT
DAT1=A A
D=C A
GOSUBL Update-D Update pointers
GOTO eddelblk10 The rest is the same
**********************************************************************
* Copy block to cursor position and clip
**********************************************************************
copyblkerr GOLONG BadEdKey
CopyBlk ST=0 sDISPOK
GOSUBL GetBlk
GOC copycut
GOSUB Blk>Cut
GOC copyblkerr
GOSUB SetNoBlk
copycut GOSUBL GetCut
GOC copyblkerr
GOSUB Cut>CurPos
GOC copyblkerr
GOLONG ToThisPos
**********************************************************************
* Copy clip to cursor position
**********************************************************************
Cut>CurPos GOSUBL GetCut
RTNC
GOSUBL EdAllocC
RTNC
GOSUBL GetCut
AD0EX
D1=A
GOSBVL =MOVEDOWN
GOSUBL GetCut
D1=(2) CURPOS
A=DAT1 A
A=A+C A
DAT1=A A
RTNCC
**********************************************************************
* Copy block to clip
**********************************************************************
Blk>Cut GOSUBL GetBlk
RTNC
D0=A ->BLK
B=C A BLKSIZE
GOSUBL GetCutFree
?C<B A
RTNYES
D1=(2) CUT
A=A-B A
DAT1=A A
D1=A
C=B A
GOVLNG =MOVEDOWN CC
**********************************************************************
* Swap text and clip
**********************************************************************
swapcliperr GOLONG BadEdKey
EdSwapClip ST=0 sREPEAT
GOSUBL GetCut
GOC swapcliperr
ST=0 sDISPOK
D=C A
GOSUBL GetFree
B=C A
GOSUBL GetText
?D<C A
GOYES +
GOSUB edswpTCT Text<=Cut Try to move Cut once
GONC edswpUpdPtr
GOSUB edswpCTC fail -> try to move Text once
GONC edswpUpdPtr
GOC edswpLowMem
+ GOSUB edswpCTC Text>Cut Try to move Text once
GONC edswpUpdPtr
GOSUB edswpTCT fail -> try to move Cut once
GONC edswpUpdPtr
edswpLowMem GOSUBL GetCut All failed, use (very) slow swap
D0=A
D1=(2) STREND
A=DAT1 A
D1=A
GOSBVL =MOVEDOWN Move cut to end of text
GOSUBL GetText
D0=A
A=A+C A
D1=(2) MEMEND
C=DAT1 A
D1=A A
C=C-A A
GOSUBL EdBLKswap then rot text above cut+free
edswpUpdPtr
GOSUBL GetCut Update end of STR and start of CUT
B=C A
GOSUBL GetText
D0=A
A=A+B A
D1=(2) STREND
DAT1=A A
D1=(2) MEMEND
A=DAT1 A
A=A-C A
D1=(2) CUT
DAT1=A A
D1=(2) BLK Clear BLK and marks
AD1EX
C=0 A
- AD1EX <-------+
DAT1=C A |
D1=D1+ 5 |
AD1EX |
LC(2) UPDEND |
?A<C B |
GOYES - --------+
GOLONG ToThisD0
edswpTCT GOSUBL GetCut Move Text, then Cut then Text
?C>B A
RTNYES No room to move text
B=C A Move up text by cut's size
GOSUBL GetText
A=A+C A
D0=A
A=A+B A
D1=A
D=C A len of text
GOSBVL =MOVEUP
GOSUBL GetCut Move Cut to start of buf
D0=A
B=A A
B=B+C A end of buf
D1=(2) STR
A=DAT1 A
D1=A
GOSBVL =MOVEDOWN
CD1EX Move up text to end of Buf
C=C+D A
D0=C
A=B A
D1=A
C=D A
GOVLNG =MOVEUP does RTNCC
edswpCTC GOSUBL GetText Move Cut, then Text then Cut
?C>B A
RTNYES No room to move Cut
B=C A Move Cut down by Text's size
GOSUBL GetCut
D0=A
A=A-B A
D1=A
D=C A len of cut
GOSBVL =MOVEDOWN
GOSUBL GetText Move Text to end of Buf
B=A A start of text
A=A+C A
D0=A
D1=(2) MEMEND
A=DAT1 A
D1=A
GOSBVL =MOVEUP
CD1EX Move cut down to start of Buf
C=C-D A
D0=C
A=B A
D1=A
C=D A
GOVLNG =MOVEDOWN does RTNCC
**********************************************************************
* Update last cursor position to MARK0
**********************************************************************
UpdMark0 GOSUBL GetCurPos
D1=(2) MARKX
A=DAT1 A
?A=C A
RTNYES Cursor didn't move, don't update!
D1=(2) MARK0
DAT1=A A
RTN
**********************************************************************
* Update mark X
**********************************************************************
SetMarkX GOSUBL GetCurPos
D1=(2) MARKX
DAT1=C A
RTN
**********************************************************************
* Set mark position
**********************************************************************
SetMark9 P=P+1
SetMark8 P=P+1
SetMark7 P=P+1
SetMark6 P=P+1
SetMark5 P=P+1
SetMark4 P=P+1
SetMark3 P=P+1
SetMark2 P=P+1
SetMark1 P=P+1
ST=0 sREPEAT
SetMark0 C=0 A
CPEX 0
A=C A
A=A+A A
A=A+A A
A=A+C A 5*N
GOSUBL GetCurPos
D1=(2) MARK0
CD1EX
C=C+A A
CD1EX
DAT1=C A
RTN
**********************************************************************
* Set cursor to mark
**********************************************************************
GoMark9 P=P+1
GoMark8 P=P+1
GoMark7 P=P+1
GoMark6 P=P+1
GoMark5 P=P+1
GoMark4 P=P+1
GoMark3 P=P+1
GoMark2 P=P+1
GoMark1 P=P+1
GoMark0 ST=0 sREPEAT
C=0 A
CPEX 0
A=C A
A=A+A A
A=A+A A
A=A+C A 5*N
C=R4.F A
LC(2) MARK0
C=C+A A
D1=C
C=DAT1 A
?C=0 A
GOYES cantgomark
D0=C
GOLONG ToThisD0
cantgomark GOLONG BadEdKey
**********************************************************************
* Insert stack level 1 string into cursor position
**********************************************************************
RclStk1 GOSUB GetStk$
GOC rclerr
GOSUBL EdAlloc
GOC rclerr
* Got string alright, insert it into text
GOSUBL GetCurPos
D1=C
GOSUB GetStk$ C[A] = chars D0 = ->text
C=C+C A
GOSBVL =MOVEDOWN
* Now remove it from stack
GOSUB GetStk$ B[A] = ->stklevel
C=B A
D1=C ->stklevel
GOSBVL =D0=DSKTOP
C=C-A A Nibbles to move
A=B A
D0=A ->stklevel
D1=D1+ 5 Overwrite the inserted string
GOSBVL =MOVEUP
GOSBVL =GETPTR Pop the vanished level
D1=D1+ 5
D=D+1 A
GOSBVL =SAVPTR
D0=(5) =aDEPTHSAVE Also fix UStackDepth!!
A=DAT0 A
D0=A
A=DAT0 A
A=A-CON A,5
DAT0=A A
ST=0 sDISPOK
RTN
rclerr GOLONG BadEdKey
* Fetch first user stack level =
GetStk$ D0=(5) =aEDITLINE
C=DAT0 A
D0=C
C=DAT0 A ->editline
D0=(5) =aDEPTHSAVE
A=DAT0 A
D0=A
A=DAT0 A depthsave
C=C-A A
D0=C ->stklevel
B=C A ->stklevel
A=DAT0 A
D0=A ->ob
A=DAT0 A
LC(5) =DOCSTR
?A#C A
RTNYES
D0=D0+ 5
C=DAT0 A $len
D0=D0+ 5 ->$body
C=C-CON A,5
RTNC CS: Too short
?CBIT=1 0
RTNYES CS: Extra nibble
CSRB.F A chars
RTNCC CC: String ok
**********************************************************************
* Push Blk or Cut to stack level 1
**********************************************************************
* Note: sREPEAT set to 0, so we can use R3
PushStk1
ST=0 sREPEAT
GOSUBL GetBlk Get BLK
GONC +
GOSUBL GetCut if none get CUT
- GOC rclerr if none -> badkey
A=0 A Set start to 0: start of CUT change
+ B=A A B : start of BLK/CUT
R1=C R1: size
D=C A
C=0 A
LC(2) 21 Stack:5 Temp:5+1 CSTR:5+5
D=D+C A Free= size + 21
GOSUBL GetFree Be sure there will be enough
?C<D A ROOM to avoid garbage
GOYES -
C=D A C=Free
D1=(2) MEMEND Update MEMEND
A=DAT1 A
D0=A ->Link
A=A-C A
DAT1=A A
A=DAT0 A Update Link
A=A-C A
DAT0=A A
D1=(2) STR Update $Len
A=DAT1 A
D0=A
D0=D0- 5
A=DAT0 A
A=A-C A
DAT0=A A
D1=(2) CUT Update CUT
A=DAT1 A
R3=A
A=A-C A
DAT1=A A
?B=0 A Using CUT ?
GOYES + YES-> use new satrt of CUT in A
A=B A NO-> use start of BLK in B
+ AR3EX A=->old cut C=Free R3=start of BLK/CUT
GOSBVL =MOVERSD shrink! (move also old CUT to new CUT)
C=R1 Size of BLK/CUT
GOSBVL =MAKE$N Make a string. Shouldn't garbage
but does a ST=0 sDISPOK (10)
A=R3
C=R1
AD0EX
AD1EX
GOSBVL =MOVEDOWN Copy BLK/CUT to this string
A=R0 A
GOSBVL =GPPushA Push it (just to take a slot in stack)
GOSBVL =SAVPTR
GOSUB GetStk$ B[A] = ->stklevel of DEPTHSAVE
GOSBVL =D1=DSKTOP Move down stack from DEPTHSAVE to
D0=C DSKTOP
D0=D0+ 5
B=B-C A Nibbles to move
C=B A
GOSBVL =MOVEDOWN
D1=D1- 5 Put string just above DEPTHSAVE
A=R0.F A (i.e. above edited string)
DAT1=A A
D0=(5) =aDEPTHSAVE Also fix UStackDepth
A=DAT0 A
D0=A
A=DAT0 A
A=A+CON A,5
DAT0=A A
GOLONG SetNoBlk Clear if any Block and end !
**********************************************************************
* Skip to end of word
**********************************************************************
EdBlack+ GOSUBL GetCurPos
Black+ LCASC ' '
A=DAT0 B
?A<=C B
RTNYES No black
blac+lp D0=D0+ 2
A=DAT0 B
?A>C B
GOYES blac+lp
C=R4.F A
D1=C
D1=(2) STREND
C=DAT1 A
AD0EX
?A<=C A
GOYES bl+eok
A=C A
bl+eok D0=A
RTNCC
**********************************************************************
* Move cursor up
**********************************************************************
upisbad GOLONG BadEdKey
EdUp GOSUB EdLine-
GOC upisbad Top Line
ST=0 sSCROLL
D1=(2) CURSY Update Y
A=DAT1 S
A=A-1 S
DAT1=A S
GONC upyok
ST=1 sSCROLL
A=0 S
DAT1=A S
D1=(2) TOPPOS
AD0EX
DAT1=A A
AD0EX
upyok GOSUBL ToThisWant
GOSUB NoScroll?
RTNC
GOLONG ViewUp
NoScroll?
?ST=0 sSCROLL
RTNYES
?ST=0 sDISPOK
RTNYES
RTN
**********************************************************************
* Move cursor down
**********************************************************************
dnisbad GOLONG BadEdKey
EdDn GOSUB EdLine+
GOC dnisbad Bottom Line
ST=0 sSCROLL
D1=(2) CURSY Update Y
A=DAT1 P
A=A+1 P
DAT1=A P
LC(1) 9 Max value
?A<=C P
GOYES dnyok
ST=1 sSCROLL
A=A-1 P
DAT1=A P
D1=(2) TOPPOS
A=DAT1 A
AD0EX
DAT1=A A Save line
GOSUB Line+
A=DAT1 A
AD0EX Restore line
DAT1=A A Set new top
dnyok GOSUBL ToThisWant
GOSUB NoScroll?
RTNC
GOLONG ViewDn
**********************************************************************
* Move cursor left
**********************************************************************
ltisbad GOLONG BadEdKey
EdLt D1=(2) STR
A=DAT1 A
D1=(2) CURPOS
C=DAT1 A
?C<=A A
GOYES ltisbad Already start
C=C-CON A,2
DAT1=C A
D0=C New Loc
A=DAT0 B
LCASC '\n'
?A=C B
GOYES ltwrap
LC(1) #09
?A=C B
GOYES lttab
GOSUBL SetWantX
A=A-1 A
DAT1=A A
D1=(2) CURSX
A=DAT1 B
A=A-1 B
DAT1=A B
RTNNC
A=0 B
DAT1=A B
D1=(2) XOFF
C=DAT1 A
C=C-1 A
DAT1=C A
?ST=0 sDISPOK
RTNYES
GOLONG ViewLt
ltwrap D1=(2) CURSY
A=DAT1 S
A=A-1 S
DAT1=A S
GONC ltwrap-
ST=0 sDISPOK
A=0 S
DAT1=A S
D1=(2) TOPPOS
A=DAT1 A
D0=A
GOSUB Line-
AD0EX
DAT1=A A
R0=A.F A ToThisX slower
GOLONG findnewX
ltwrap-
lttab GOTO ToThisX
**********************************************************************
* Move cursor right
**********************************************************************
rtisbad GOLONG BadEdKey
EdRt D1=(2) STREND
A=DAT1 A
D1=(2) CURPOS
C=DAT1 A
D0=C Old Pos
C=C+CON A,2
?C>A A
GOYES rtisbad Already bottom
DAT1=C A
A=DAT0 B
LCASC '\n'
?A=C B
GOYES rtwrap
LC(1) '\t'
?A=C B
GOYES rttab
GOSUBL SetWantX
A=A+1 A
DAT1=A A
D1=(2) CURSX
A=DAT1 B
A=A+1 B
DAT1=A B
LC(2) 32
?A<=C B
RTNYES
edrt+ DAT1=C B
D1=(2) XOFF
C=DAT1 A
C=C+1 A
DAT1=C A
?ST=0 sDISPOK
RTNYES
GOLONG ViewRt
rtwrap D1=(2) CURSY
A=DAT1 P
A=A+1 P
DAT1=A P
LC(1) 9
?A<=C P
GOYES rtyok
DAT1=C P
ST=0 sDISPOK
D1=(2) TOPPOS
A=DAT1 A
D0=A
GOSUB Line+
AD0EX
DAT1=A A Set new top
rtyok
rttab GOTO ToThisX
**********************************************************************
* Move cursor 1 page up
**********************************************************************
EdPgUp GOSUB GetCurPos
LC(1) 10-1
D=C A
pguplp GOSUB Line-
GOC pgupnow
D=D-1 P
GONC pguplp
GOC pgupnow
**********************************************************************
* Move cursor 1 page down
**********************************************************************
EdPgDn GOSUB GetCurPos
LC(1) 10-1
D=C A
pgdnlp GOSUB Line+
GOC pgdnnow
D=D-1 P
GONC pgdnlp
pgupnow
pgdnnow GOLONG SafeWantPos
**********************************************************************
* Move cursor 1 word left
**********************************************************************
EdWordLt GOSUBL EdStart?
GOC wordrterr
D0=D0- 2
GOSUBL StartOfPrvWrd
GOC wordrterr
CSRB.F A
- C=C-1 A
RTNC
R1=C.F A
A=R4
D1=A
GOSUB EdLt
C=R1.F A
GOTO -
**********************************************************************
* Move cursor 1 word right
**********************************************************************
EdWordRt GOSUBL EdEnd?
GOC wordrterr
D0=D0+ 2
GOSUBL EndOfNxtWrd
GOC wordrterr
CSRB.F A
C=C-1 A
- C=C-1 A
RTNC
R1=C.F A
A=R4
D1=A
GOSUB EdRt
C=R1.F A
GOTO -
wordrterr GOLONG BadEdKey
**********************************************************************
* Del all between here and start of (prev) word
**********************************************************************
EdDelWrdLt GOSUBL EdStart?
GOC wordrterr
GOSUBL StartOfPrvWrd
GOC wordrterr
ST=0 sREPEAT
ST=0 sDISPOK
D1=(2) CURPOS
A=DAT1 A
A=A-C A
DAT1=A A
* C=C+1 A To also DEL char under cursor
GOSUBL EdRemoveC
GOLONG ToThisPos
**********************************************************************
* Del all between here and end of (next) word
**********************************************************************
EdDelWrdRt GOSUBL EdEnd?
GOC wordrterr
GOSUBL EndOfNxtWrd
GOC wordrterr
ST=0 sREPEAT
ST=0 sDISPOK
GOSUBL EdRemoveC
GOLONG ToThisPos
**********************************************************************
* Move to start of text
**********************************************************************
EdFarUp D1=(2) STR
A=DAT1 A
D0=A
ST=0 sREPEAT
GOLONG ToThisD0
**********************************************************************
* Move to bottom of text
**********************************************************************
EdFarDn D1=(2) STREND
A=DAT1 A
D0=A
GOSUBL LineStart
GOLONG ToThisD0
**********************************************************************
* Move to start of row
**********************************************************************
EdFarLt GOSUB EdLineStart
AD0EX
DAT1=A A
GOTO ToThisX
**********************************************************************
* Move to end of row
**********************************************************************
EdFarRt GOSUB EdLineEnd
AD0EX
DAT1=A A
GOTO ToThisX
**********************************************************************
* Delete character under cursor
**********************************************************************
EdDel GOSUB EdEnd?
GOC cantdel
ST=1 sLINBAD
A=DAT0 B
LCASC '\n'
?A#C B
GOYES delnonNL
ST=0 sDISPOK
delnonNL
P= 1
GOTO EdRemoveP
cantdel GOLONG BadEdKey
**********************************************************************
* Delete previous character
**********************************************************************
EdBS GOSUB EdStart?
GOC cantbs
ST=1 sLINBAD
D0=D0- 2
A=DAT0 B
LCASC '\n'
?A#C B
GOYES bsnonNL
ST=0 sDISPOK
bsnonNL D1=(2) CURPOS
AD0EX
DAT1=A A
P= 1
GOSUB EdRemoveP
GOTO ToThisPos
cantbs GOLONG BadEdKey
**********************************************************************
* Insert/overwrite character C[B]=CHR
**********************************************************************
DoEdChrKey
GOSUB TogChr?
B=A B
?ST=1 sOVERWR
GOYES OverEdChr
GOTO InsEdChr
OverEdChr
GOSUB EdEnd?
GOC InsEdChr
A=DAT0 B
C=B B
DAT0=C B
LCASC '\n'
?C=B B
GOYES overNL
?A#C B
GOYES overnormal
overNL ST=0 sDISPOK
GOTO EdRt
overnormal
GOSUBL DispCurChr
GOTO EdRt
* B[B]=chr
InsEdChr
P= 1
GOSUB EdAllocP
GONC insnow
GOLONG BadEdKey
insnow ST=1 sLINBAD
A=B B
DAT0=A B
LCASC '\n'
?A#C B
GOYES insnonNL
ST=0 sDISPOK
insnonNL
GOTO EdRt
**********************************************************************
* Insert/overwrite string key
**********************************************************************
DoEdStrKey
ST=0 sDISPOK
?ST=0 sOVERWR
GOYES doeds10
GOSUB OverEdStr
GOTO doeds20
doeds10 GOSUB InsEdStr
doeds20 GOC doeds30
GOTO ToThisPos
doeds30 GOLONG BadEdKey
**********************************************************************
OverEdStr
C=DAT0 S strlen
D0=D0+ 1
CD0EX
B=C A ->str
C=R4.F A
D1=C
D1=(2) CUT
A=DAT1 A ->cut
D1=(2) CURPOS
C=DAT1 A
D0=C ->curpos
D=C A ->curpos
C=0 A
CSLC strlen
C=C+C A nibbles
D=D+C A curpos'
CDEX A curpos'
?C>A A curpos' > cut?
RTNYES Yes - no room
D1=(2) STREND Update strend if needed
A=DAT1 A
?C<=A A
GOYES +
DAT1=C A Update strend
+ C=D A nibbles
GOTO copystrnow
**********************************************************************
InsEdStr
C=DAT0 S strlen
D0=D0+ 1
CD0EX
B=C A ->str
P=C 15
GOSUB EdAllocP
RTNC no room
C=0 A
CSLC
C=C+C A nibbles
copystrnow
A=B A
AD0EX ->str
D1=A ->curpos
GOSBVL =MOVEDOWN
C=R4.F A Now update curpos according to skip index
D1=C
D1=(2) CURPOS
C=DAT1 A ->curpos
A=0 A
A=DAT0 1 skip
A=A+A A skip nibs
C=C+A A curpos'
DAT1=C A
RTNCC
**********************************************************************
* Insert list delimiters nicely
**********************************************************************
EdIndList GOSUB Ins&Ind:
ASC(1) '{}'
CON(1) 1
**********************************************************************
* Insert program delimiters nicely
**********************************************************************
EdIndPrg GOSUB Ins&Ind:
ASC(1) '\xAB\xBB'
CON(1) 1
* Insert string nicely
Ins&Ind: ST=0 sDISPOK
C=RSTK
D0=C
GOSUB InsEdStr
GOC insinderr
GOSUB IndNL
GOC insinderr
GOSUB GetCurPos
RSTK=C
GOSUB IndNL
C=RSTK
GOC insinderr
D0=C
GOSUB ToThisD0
LCASC ' '
B=C B
GOTO InsEdChr
insinderr GOLONG BadEdKey
**********************************************************************
* Insert newline character
**********************************************************************
EdIndNL ST=0 sDISPOK
GOSUB IndNL
GOC edindnlerr
GOTO ToThisPos
edindnlerr
GOLONG BadEdKey
IndNL GOSUB EdLineStart
D1=(2) CURPOS
C=DAT1 A
AD0EX
D0=A
C=C-A A
CSRB.F A
GOSBVL =ASLW5
A=C A
B=A W Max N & LineStart
D=0 A
skpwhilp
D=D+1 A
B=B-1 A
GOC gotwhiN
A=DAT0 B
D0=D0+ 2
LC(2) #1F
?A=C B
GOYES skpwhilp
LCASC ' '
?A<=C B
GOYES skpwhilp
gotwhiN C=D A
GOSUB EdAlloc D=C*2
RTNC
A=B W
GOSBVL =ASRW5
AD0EX
D1=A
LCASC '\n'
DAT1=C B
D1=D1+ 2
C=D A
C=C-CON A,2
GOSBVL =MOVEDOWN
C=R4.F A
CD1EX
D1=(2) CURPOS
DAT1=C A
RTNCC
**********************************************************************
* Toggle between lower/upper case if so requested CC: Toggled char
**********************************************************************
TogChr? A=C B
?ST=0 sLOWCS
RTNYES No request
LCASC 'A'
?A<C B
RTNYES < 'A' - not character
LCASC 'z'
?A>C B > 'z' - not character
RTNYES
LCASC 'Z'
?A>C B
GOYES +
ABIT=1 5 Convert to lower case
RTN
+ LCASC 'a'
?A<C B
RTNYES 'Z' < chr < 'a' - not character
ABIT=0 5 Convert to upper case
RTN
**********************************************************************
* At start of text?
* Uses: D1 C[A]
**********************************************************************
EdStart? GOSUB GetCurPos Special entry for cursor position
Start? C=R4.F A
D1=C
D1=(2) STR
C=DAT1 A
AD0EX
?A<=C A
GOYES +
+ AD0EX
RTN
**********************************************************************
* At end of text?
* Uses: D1 C[A]
**********************************************************************
EdEnd? GOSUB GetCurPos
End? C=R4.F A
D1=C
D1=(2) STREND
C=DAT1 A
AD0EX
?A>=C A
GOYES +
+ AD0EX
RTN
**********************************************************************
* Get end of line, CS if end of file
* Uses: A[W] C[W] D0 D1
**********************************************************************
EdLineEnd GOSUB GetCurPos
LineEnd A=R4.F A
AD0EX
D0=(2) STREND
C=DAT0 A ->end of str
D0=C
LC(N) 16
NIBASC '\n\n\n\n\n\n\n\n'
DAT0=C B Ensure a terminating newline
D0=A
-- A=DAT0 W <---------------+
P= 1 |
?A=0 P |
GOYES + --------+ |
- P= 3 <-------|--+ |
?A=0 P | | |
GOYES + --------+ | |
P= 5 | | |
?A=0 P | | |
GOYES + --------+ | |
P= 7 | | |
?A=0 P | | |
GOYES + --------+ | |
P= 9 | | |
?A=0 P | | |
GOYES + --------+ | |
P= 11 | | |
?A=0 P | | |
GOYES + --------+ | |
P= 13 | | |
?A=0 P | | |
GOYES + --------+ | |
D0=D0+ 16 | | |
P= 15 | | |
?A#0 P | | |
GOYES -- --------|-------+
D0=D0- 16 | |
+ CD0EX <-------+ |
C+P+1 |
CD0EX |
D0=D0- 2 |
A=DAT0 W |
?A#C B |
GOYES - -----------+
P= 0
A=R4.F A Now check if we found the dummy to
AD0EX indicate end-of-file fith CRY
D0=(2) STREND
C=DAT0 A
D0=A
?A=C A
RTNYES
RTNCC
**********************************************************************
* Skip line. CS if no next line
* Uses: A[W] C[W] D0 D1
**********************************************************************
EdLine+ GOSUB GetCurPos
Line+ GOSUB LineEnd
RTNC Found end
D0=D0+ 2 Skip NL
RTNCC
**********************************************************************
* Get start of line. CS if start of text
* Uses: B[A] C[A] D0 D1
**********************************************************************
EdLineStart GOSUB GetCurPos
LineStart C=R4.F A
CD0EX
D0=(2) STR
A=DAT0 A
D0=C
C=C-A A
CSRB.F A
B=C A
LCASC '\n'
linstrlp B=B-1 A
RTNC CS:Found start
D0=D0- 2
A=DAT0 B
?A#C B
GOYES linstrlp
D0=D0+ 2 Skip NL
RTNCC CC:Found chr1
**********************************************************************
* Skip to previous line. CS if no previous line
* Uses: B[A] C[A] D0 D1
**********************************************************************
EdLine- GOSUB GetCurPos
Line- GOSUB LineStart
RTNC CS:Found start
D0=D0- 2
GOSUB linstrlp
RTNCC PrevLineStart
**********************************************************************
* Alloc N chars in CURPOS
* Update nonzero ptrs >= CURPOS
* Move block up
**********************************************************************
EdAllocP C=0 A
CPEX 0
EdAlloc C=C+C A
EdAllocC D=C A Save D[A] = Need in nibbles
?D=0 A
GOYES allocok
A=R4.F A
D1=A
D1=(2) CUT
C=DAT1 A
D1=(2) STREND
A=DAT1 A
C=C-A A Free amount
?C<D A
RTNYES No memory
D1=(2) CURPOS
A=DAT1 A
D1=(2) UPDSTR
AD1EX
- AD1EX <-------+
C=DAT1 A |
?C<A A |
GOYES + ---+ |
C=C+D A | |
DAT1=C A | |
+ D1=D1+ 5 <--+ |
AD1EX |
LC(2) UPDEND |
?A<C B |
GOYES - --------+
AD1EX
D1=(2) STREND Move up
C=DAT1 A
D1=C
C=C-D A
D0=C
C=C-A A
GOSBVL =MOVEUP
allocok GOTO GetCurPos
**********************************************************************
* Delete N chars at CURPOS
* Update nonzero ptrs >= CURPOS
* Scratched locs put to CURPOS
* (DISPOK=0?)
**********************************************************************
EdRemoveP C=0 A
CPEX 0
EdRemove C=C+C A
EdRemoveC D=C A Scratch
?D=0 A
GOYES removok
GOSUBL GetCurPos
D1=(2) STREND Move down
A=DAT1 A
D1=C
C=C+D A
D0=C
C=A-C A
GOSBVL =MOVEDOWN
Update-D A=R4.F A
D1=A
D1=(2) CURPOS
A=DAT1 A
D1=(2) UPDSTR
AD1EX
- AD1EX <-------+
C=DAT1 A |
?C<A A |
GOYES ++ -----+ |
C=C-D A | |
?C>=A A | |
GOYES + ---+ | |
* ST=0 sDISPOK | | |
C=A A | | |
+ DAT1=C A <--+ | |
++ D1=D1+ 5 <----+ |
AD1EX |
LC(2) UPDEND |
?A<C B |
GOYES - --------+
removok
**********************************************************************
* Get cursor position to D0, data buffer to D1
* Uses: C[A] D0 D1
**********************************************************************
GetCurPos C=R4.F A Return CURPOS
D1=C
D1=(2) CURPOS
C=DAT1 A
D0=C
RTNCC
**********************************************************************
* Get block start & size, CS if no block
**********************************************************************
GetBlk C=R4.F A
D1=C
D1=(2) BLKEND
C=DAT1 A
D1=(2) BLK
getsub? A=DAT1 A
C=C-A A
RTNC
?C=0 A
RTNYES
?A=0 A
RTNYES
RTN
**********************************************************************
* Get clip start & size, CS if no clip
**********************************************************************
GetCut C=R4.F A
D1=C
D1=(2) MEMEND
C=DAT1 A
D1=(2) CUT
GOTO getsub?
**********************************************************************
* Get available memory if clip is ignored
**********************************************************************
GetCutFree C=R4.F A
D1=C
D1=(2) STREND
C=DAT1 A
D1=(2) MEMEND
A=DAT1 A
C=A-C A
RTN
**********************************************************************
* Get available memory
**********************************************************************
GetFree C=R4.F A
D1=C
D1=(2) CUT
C=DAT1 A
D1=(2) STREND
GOTO getsub
**********************************************************************
* Get total work memory
**********************************************************************
GetWork C=R4.F A
D1=C
D1=(2) MEMEND
GOTO getstrsub
**********************************************************************
* Get text size
**********************************************************************
GetText C=R4.F A
D1=C
D1=(2) STREND
getstrsub C=DAT1 A
D1=(2) STR
getsub A=DAT1 A
C=C-A A
RTN
**********************************************************************
* Cursor jump & calculation utilities
**********************************************************************
**********************************************************************
* In: CURPOS
* Out: XOFF CURSX WANTX
* Update only what is necessary!
* WANTX always updated
* Clears DISPOK if XOFF changes
**********************************************************************
ToThisX GOSUBL EdLineStart
AD0EX
R0=A.F A
GOTO findnewX
**********************************************************************
**********************************************************************
* Given new cursor position setup the window parameters properly
* Input: CURPOS
* Output: TOPPOS XOFF CURSX CURSY
* Notes: Updates are made only if absolutely necessary so that
* simple cursor movement in the current window might
* be enough
**********************************************************************
* Special entry which takes D0 instead of CURPOS as input
ToThisD0 C=R4.F A
D1=C
D1=(2) CURPOS
CD0EX
DAT1=C A
ToThisPos GOSUBL EdLineStart
AD0EX
R0=A.F A R0[A] = ->linestart
D=0 A
* Check whether up/down scrolling is necessary
D1=(2) TOPPOS
C=DAT1 A Current ->topline
?C=A A
GOYES topisok Same as the wanted line - skip scroll
?C>A A topline > wanted line ?
GOYES findnewtop Yes - have to scroll
D0=C ->topline
- GOSUB Line+ <-------+
D=D+1 A | lines++
CD0EX |
D0=C |
A=R0.F A | ->wantline
?C>=A A | line >= wantline ?
GOYES topisok | Yes - wantline is on screen!
LC(1) 9 |
?D<C P | Still possible to be on screen?
GOYES - --------+ Yes - continue loop
* TOPPOS is invalid, screen has to be scrolled up/down.
* Algorithm: Skip back 5 rows from wantline so the wanted line will
* be in the middle of the screen.
findnewtop ST=0 sDISPOK Display will have to be updated
A=R0.F A
D0=A ->wantline
LC(1) 5 5 rows to skip
D=C A
- D=D-1 P <-------+
GOC + ----+ |
GOSUB Line- | |
GONC - ----|---+
+ D1=(2) TOPPOS <---+
AD0EX
DAT1=A A Set new TOPPOS
D1=(2) CURSY New CURSY is of course 5-1 now
LC(1) 5-1
C=C-D P
DAT1=C P
GOTO findnewX
* TOPPOS was valid, the wanted line is on the screen. Set new CURSY
topisok D1=(2) CURSY
C=D A
DAT1=C 1
* Now TOPPOS and CURSY are valid. Calculate XOFF and CURSX
* R0[A] = ->wantline
findnewX
* 1st count visible X position
A=R0.F A
D0=A ->wantline
GOSUB Pos>Xoff D[A] = XOFF'
D1=(2) XOFF
C=DAT1 A Old XOFF
D=D-C A XOFF' - XOFF
GOC newxoffless Old XOFF is too big
LC(5) 32
?D>C A
GOYES newxoffmore
D1=(2) CURSX Can handle it with cursor X movement!
C=D A
DAT1=C B
GOTO SetWantX
newxoffmore C=DAT1 A XOFF
newxoffless ST=0 sDISPOK Have to scroll, display won't be ok
D=D+C A
LC(5) 32
D=D-C A
GONC biggerxoff
C=C+D A
D=0 A
biggerxoff D1=(2) CURSX
DAT1=C B
D1=(2) XOFF
C=D A
DAT1=C A
**********************************************************************
* Set new WANTX to be the position indicated by XOFF & CURSX
**********************************************************************
SetWantX C=R4.F A
D1=C
D1=(2) XOFF
A=DAT1 A XOFF
D1=(2) CURSX
C=0 A
C=DAT1 B CURSX
A=A+C A
D1=(2) WANTX
DAT1=A A WANTX = XOFF + CURSX
RTNCC
**********************************************************************
* Calculate XOFF for cursor position on current line
* Input: CURPOS
* Output: D[A] = XOFF
* D0 = ->curpos (?)
**********************************************************************
POS>XOFF GOSUBL EdLineStart
Pos>Xoff D1=(2) CURPOS
C=DAT1 A
AD0EX
D0=A
C=C-A A curpos - linestart
CSRB.F A
B=C A chars to curpos
D=0 A
- LCASC '\t' <-------+
B=B-1 A | chars--
RTNC |
D=D+1 A | xoff++
A=DAT0 B |
D0=D0+ 2 |
?A#C B |
GOYES - --------+
D=D-1 A | Fix back: xoff--
LC(1) 8 |
D=D&C P | Go down to even 8
D=D+CON A,8 | And then skip 8 for tab
GONC - --------+
**********************************************************************
SafeWantPos C=R4.F A
D1=C
D1=(2) WANTX
C=DAT1 A
RSTK=C
GOSUB ToThisWant
GOSUB ToThisPos
C=R4.F A
D1=C
D1=(2) WANTX
C=RSTK
DAT1=C A
RTN
**********************************************************************
* Given new cursor position on line via WANTX calculate proper new
* coordinates.
* Input: D0 = ->wantline
* WANTX (XOFF CURSX as old values)
* Output: CURPOS XOFF'
* Notes:
* Assumes WANTX>=XOFF+CURSX
**********************************************************************
ToThisWant GOSUB SkipToXOFF
GONC xofffits
* Wanted XOFF too big, have to scroll left.
* Set Cursor & XOFF to last chr
ST=0 sDISPOK Display not ok
D1=(2) XOFF
C=DAT1 A
C=C-D A
DAT1=C A
D1=(2) CURSX
A=0 B
DAT1=A B
D1=(2) CURPOS
AD0EX
DAT1=A A
RTN
* Calculate new XOFF, CURSX and CURPOS
xofffits D1=(2) WANTX
C=DAT1 A
D1=(2) XOFF
A=DAT1 A
C=C-A A
D=D+C A
GOSUB SkipAfterNth
D1=(2) CURPOS
AD0EX
DAT1=A A
D1=(2) WANTX
C=DAT1 A
D1=(2) XOFF
A=DAT1 A
C=C-A A
D1=(2) CURSX
C=C-D A
DAT1=C B
A=0 A
LA(2) 32
C=C-A A
RTNC
DAT1=A B
D1=(2) XOFF
A=DAT1 A
A=A+C A
DAT1=A A
ST=0 sDISPOK
RTN
**********************************************************************
* Seek proper place to start displaying characters given the X-scroll offset.
* Optimization of this subroutine is crucial to the speed of display
* when long lines are present. Typically long lines entail data sequences
* containing only hex chars, thus the optimization should be done that
* in mind.
* Input: D0 = ->line start
* D[A] = XOFF
* Output: CS: XOFF larger than line lenght, no chars left to show
* D0 = ->last char
* D[A] = XOFF - last
* CC: XOFF fits
* B[A] = chars until end B[S] = tab counter
* 1) D[A] = 0 D0 = ->Nth char
* 2) D[A] = unskipped D0 = ->tabulator
**********************************************************************
* Alternative entry which fetches the XOFF
SkipToXOFF C=R4.F A
D1=C
D1=(2) XOFF
C=DAT1 A
D=C A
* Skip to Nth character position
SkipToNth C=R4.F A
D1=C
D1=(2) STREND
C=DAT1 A
B=C A ->strend
AD0EX ->linestart
D0=A
B=B-A A
RTNC Just in case!
BSRB.F A B[A]=chars to end
skipx0loop B=0 S <---------+ Init tab counter
* Special entry into the loop |
SkipAfterNth LCASC '\n' |
- D=D-1 A <-------+ | xoff--
GOC skippedx ---+ | | Got Exact!
B=B-1 A | | | chars--
GOC skipunfit -+| | | No fit!
A=DAT0 B || | |
D0=D0+ 2 || | |
B=B+1 S || | | tabctr++
?A>C B || | |
GOYES - ---||---+ |
LC(1) '\t' || | |
?A=C B || | |
GOYES skipxtab --||-+ | | Skip tabulator
LC(1) '\n' || | | |
?A#C B || | | |
GOYES - ---||-|-+ |
D0=D0- 2 || | | Back to newline
skipunfit D=D+1 A <--+| | | XOFF too big, no chars left
RTNSC | | |
skippedx D=0 A <---+ | | Exact skip!
RTNCC | |
* Skip tabulator, adjusting counters accordingly
skipxtab B=B-1 S <-----+ | Fix back: tabctr--
D=D+1 A | Fix back: xoff++
C=B S | tabctr
P=C 15 | tabctr
C=0 A |
CPEX 0 | tabctr
C=-C-1 P | -tabctr
CBIT=0 3 | (-tabctr) AND 7
C=C+1 P | Width taken by tab
D=D-C A | Remove width from XOFF
GONC skipx0loop ------+ tab fits, continue
* tab doesnt fit! Return tab + unskipped amount
D=D+C A
D0=D0- 2
RTNCC
**********************************************************************
* Cursor Handling Subroutines
**********************************************************************
ClrCurs
?ST=0 sCURSOR
RTNYES
GONC TogCurs
SetCurs
?ST=1 sCURSOR
RTNYES
TogCurs
?ST=1 sCURSOR
GOYES cursoff
ST=1 sCURSOR
GONC curstog
cursoff ST=0 sCURSOR
curstog C=R4.F A
D1=C
D1=(2) CURSY
C=0 A
C=DAT1 1
P=C 0
CPEX 1 #11*
C=C+C A #22*
C=C+C A #44*
A=C A
C=C+C A #88*
A=A+C A #CC*
D1=(2) CURSX
C=0 A
C=DAT1 B
A=A+C A
D1=(5) =aADISP
C=DAT1 A
D1=C
C=DAT1 A
A=A+C A
LC(5) 20+2*34
A=A+C A
D1=A
P= 16-6
curstoglp
A=DAT1 B
A=-A-1 B
DAT1=A 1
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P=P+1
GONC curstoglp
RTNCC
**********************************************************************
* Fast Display Movement Keys
**********************************************************************
ViewDn GOSUB ScrollUp
DispLastLine
A=R4.F A
D0=A
D0=(2) TOPPOS
A=DAT0 A
D0=A
LC(1) 9-1
D=C P
shxlstlp
GOSUB Line+
GOC shwlstnox
D=D-1 P
GONC shxlstlp
shwlstnox
P= 10-1
GOTO DispEdLine
**********************************************************************
ViewUp GOSUB ScrollDn
DispFirstLine
A=R4.F A
D0=A
D0=(2) TOPPOS
A=DAT0 A
D0=A
* P= 0
GOTO DispEdLine
**********************************************************************
ViewRt GOSUB ScrollLt
A=R4.F A
D1=A
D1=(2) TOPPOS
A=DAT1 A
D0=A
D=0 S
displastlp
C=R4.F A
D1=C
D1=(2) XOFF
C=DAT1 A
D=C A
LC(5) 32
D=D+C A
GOSUB SkipToNth
LC(2) #20
GONC displast10
ST=0 sBLKINV
RSTK=C
GOC displast30
displast10
?D#0 A
GOYES displast20
?B=0 A
GOYES displast20
C=DAT0 B
displast20
RSTK=C
GOSUB BlkInv?
displast30
C=D S
P=C 15
GOSUB GetDispRow
D1=D1+ 16
D1=D1+ 16
C=RSTK
GOSUB EdDispChr! \n as space
GOSUB Line+
D=D+1 S
P= 15
LC(1) #A
P= 0
?D<C S
GOYES displastlp
RTN
**********************************************************************
ViewLt GOSUB ScrollRt
A=R4.F A
D1=A
D1=(2) TOPPOS
A=DAT1 A
D0=A
D=0 S
disp1stlp
GOSUB SkipToXOFF
LC(2) #20
GONC disp1st10
ST=0 sBLKINV
RSTK=C
GOC disp1st30
disp1st10
?D#0 A
GOYES disp1st20
?B=0 A
GOYES disp1st20
C=DAT0 B
disp1st20
RSTK=C
GOSUB BlkInv?
disp1st30
C=D S
P=C 15
GOSUB GetDispRow
C=RSTK
GOSUB EdDispChr! \n as space
GOSUB Line+
D=D+1 S
P= 15
LC(1) #A
P= 0
?D<C S
GOYES disp1stlp
RTN
**********************************************************************
* Display Scrolling Subroutines
**********************************************************************
ScrollUp GOSUB GetDispRow1
LC(5) 6*34
A=A+C A
D0=A
LC(5) 9*6*34
GOVLNG =MOVEDOWN
**********************************************************************
ScrollDn
GOSUB GetDispRow1
LC(5) 9*6*34
A=A+C A
D0=A
LC(5) 6*34
A=A+C A
D1=A
LC(5) 9*6*34
GOVLNG =MOVEUP
**********************************************************************
ScrollLt
GOSUB GetDispRow1
D0=C
D0=D0+ 1
LC(3) 10*6-1
scrltlp A=DAT0 W
DAT1=A W
D0=D0+ 16
D1=D1+ 16
A=DAT0 W
DAT1=A W
D0=D0+ 16
D1=D1+ 16
DAT1=C XS
D0=D0+ 2
D1=D1+ 2
C=C-1 B
GONC scrltlp
RTN
**********************************************************************
ScrollRt
GOSUB GetDispRow1
LC(5) 10*6*34-1
A=A+C A
D1=A
D0=A
D0=D0- 1
LC(3) 10*6-1
scrrtlp D0=D0- 16
D1=D1- 16
A=DAT0 W
DAT1=A W
D0=D0- 16
D1=D1- 16
A=DAT0 W
DAT1=A W
D0=D0- 2
D1=D1- 2
DAT0=C XS
C=C-1 B
GONC scrrtlp
RTN
**********************************************************************
* General Display Subroutines
**********************************************************************
**********************************************************************
* Clear unused display areas
**********************************************************************
InitDisp GOSUBL GetDispRow1
LC(5) 2*34
A=A-C A
D1=A
GOSBVL =WIPEOUT
P= 10
GOSUBL GetDispRow
LC(5) 2*34
GOVLNG =WIPEOUT
**********************************************************************
* Clear full display area
**********************************************************************
ClrDisp LC(5) 64*34
ClrDispC D1=(5) =aADISP Special entry to clear top C[A]
A=DAT1 A
D1=A
A=DAT1 A
D1=A
D1=D1+ 16
D1=D1+ 4
GOVLNG =WIPEOUT
**********************************************************************
GetDispRow1 P= 0
GetDispRow C=0 A
C=P 0
CPEX 1 #11
A=C X
C=C+C X #22
C=C+A X #33
C=C+C X #66
C=C+C X #CC
D1=(5) =aADISP
A=DAT1 A
D1=A
A=DAT1 A
A=A+C A
LC(5) 20+2*34
C=C+A A
A=C A
D1=C
RTN
**********************************************************************
DispCurChr
?ST=0 sDISPOK
RTNYES
C=R4.F A
D1=C
D1=(2) CURPOS
A=DAT1 A
D0=A
D1=(2) CURSY
C=DAT1 1
P=C 0
GOSUB GetDispRow
C=R4.F A
CD1EX
D1=(2) CURSX
A=0 A
A=DAT1 B
C=C+A A
D1=C
GOSUB BlkInv?
C=DAT0 B
GOSUB EdDispChr! \n as spc
C=R4.F A
D1=C
RTNCC
**********************************************************************
DispEd ?ST=0 sDISPOK
GOYES disped
?ST=0 sLINBAD
RTNYES
* Redisplay current line
GOSUBL EdLineStart
D1=(2) CURSY
C=DAT1 S
P=C 15
GOTO DispEdLine
* Redisplay entire display
disped A=R4.F A
D1=A
D1=(2) TOPPOS
A=DAT1 A
D0=A
D=0 S
dispedlp
C=D S
P=C 15
GOSUB DispEdLine
D=D+1 S
P= 15
LC(1) #A
P= 0
?D<C S
GOYES dispedlp
RTN
**********************************************************************
DispEd9 A=R4.F A
D1=A
D1=(2) TOPPOS
A=DAT1 A
D0=A
D=0 S
disped9lp C=D S
P=C 15
GOSUB DispEdLine
D=D+1 S
P= 15
LC(1) 9
P= 0
?D<C S
GOYES disped9lp
RTN
**********************************************************************
DispEdLine
GOSUB GetDispRow
RSTK=C
C=R4.F A
D1=C
GOSUB SkipToXOFF
A=C A
C=RSTK
D1=C
C=A A
GONC ExpndNow
* No BLKINV here
LC(5) 6*34
GOSBVL =WIPEOUT
GOLONG Line+
ExpndNow
?D=0 A
GOYES expskpok
C=C-D A
D=C A
GOSUB BlkInv?
C=D B
C=C-1 B
GOSUB DispSpcs
D0=D0+ 2
expskpok
LC(5) #20
CDEX A
D=D-C A
A=R4.F A
AD1EX
D1=(2) XOFF
C=DAT1 S
C=-C-1 S
D1=A
* Expand max D[B],B[A] chars
expandlp
B=B-1 A
GOC explstend
GOSUB BlkInv?
A=DAT0 B
D0=D0+ 2
LCASC '\n'
?C=A B
GOYES expnewline
LC(1) #09
?C=A B
GOYES exptab
GOSUB EdDispChrA
D=D-1 B
GONC expandlp
expandok
GOLONG Line+
exptab P=C 15
C=P 0
P= 0
C=C+D P
CBIT=0 3
C=C+1 P
D=D-C B
GOC exptabend
C=C-1 B
GOSUB DispSpcs
GOC expandlp
exptabend
C=C+D B
GOSUB DispSpcs
GOLONG Line+
explstend
ST=0 sBLKINV
expnewline
LCASC ' '
GOSUB EdDispChr
ST=0 sBLKINV
C=D B
C=C-1 B
RTNC
GOTO DispSpcs
**********************************************************************
BlkInv? A=R4.F A
AD0EX
D0=(2) BLK
C=DAT0 A
?C=0 A
GOYES noblkinv
?A<C A
GOYES noblkinv
D0=(2) BLKEND
C=DAT0 A
?A>=C A
GOYES noblkinv
AD0EX
ST=1 sBLKINV
RTN
noblkinv
AD0EX
ST=0 sBLKINV
RTN
**********************************************************************
* Write C[B]+1 spaces
* Uses: A[W] C[X] P D1
**********************************************************************
DispSpcs
P= 6-1
C=P 2
P=C 0
CSR B
A=0 W
?ST=0 sBLKINV
GOYES expspcplp
A=-A-1 W
expspcplp
DAT1=A WP
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
C=C-1 XS
GONC expspcplp
CD1EX
C+P+1
P= 0
LA(5) 6*34
C=C-A A
CD1EX
expspcslp
C=C-1 P
RTNC
P= 6-1
C=P 2
P= 0
A=0 A
?ST=0 sBLKINV
GOYES expspcwlp
A=-A-1 A
expspcwlp
DAT1=A W
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
C=C-1 XS
GONC expspcwlp
CD1EX
LA(5) 6*34-16
C=C-A A
CD1EX
GONC expspcslp
**********************************************************************
EdDispChr! LAASC '\n'
?A#C B
GOYES EdDispChr
LCASC ' '
GONC EdDispChr
EdDispChrA
C=A B
EdDispChr P= 2
LCHEX 000
P= 0
C=C+C X
A=C X
C=C+A X
C=C+A X
A=R2.F A
C=C+A A
CD1EX
A=DAT1 6
D1=C
?ST=0 sBLKINV
GOYES dspchr10
P= 6-1
A=-A-1 WP
P= 0
dspchr10
DAT1=A P
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P= 1
DAT1=A P
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P= 2
DAT1=A P
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P= 3
DAT1=A P
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P= 4
DAT1=A P
D1=D1+ 16
D1=D1+ 16
D1=D1+ 2
P= 5
DAT1=A P
P= 0
D1=C
D1=D1+ 1
RTNCC
**********************************************************************
DispRow:Ret
GOSUBL GetDispRow
Disp:Ret
ST=0 sBLKINV
C=RSTK
D0=C
dspretlp
C=DAT0 B
D0=D0+ 2
?C=0 B
GOYES dspretnow
GOSUB EdDispChr
GONC dspretlp
dspretnow
CD0EX
PC=C
**********************************************************************
Disp2Dec6B
C=B A
Disp2Dec6
CSRB.F A
DispDec6
A=0 W
A=C A
GOSUB ToDecRoll
C=0 A
CPEX 0
C=C-CON A,10
AD1EX
A=A+C A
AD1EX
C=-C-1 P
C=C-CON B,10
CSRC
ST=0 sBLKINV
dspdeclp
BSLC
LCASC '9'
BCEX P
?C<=B P
GOYES dspdec10
C=C+CON B,7
dspdec10
GOSUB EdDispChr
C=C-1 S
GONC dspdeclp
RTN
**********************************************************************
* Out: A[W]=dec A[S]=1st <>0
* P=skipped zeros
**********************************************************************
ToDecRoll
GOSBVL =HXDCW
SETHEX
P= 15
?B=0 W
RTNYES
rlleadlp
P=P+1
?B#0 S
RTNYES
BSL W
GONC rlleadlp
**********************************************************************
* ED Character Catalog
**********************************************************************
EdChrCat ST=1 sCHRMAIN Flag catalog called from main loop
* Special entry here for InputChrCat
ChrCat GOSUBL EdClrArg No repeat!
GOSUB SwapCurs2 Swap cursors
GOSUB InitCC Init catalog (current character)
GOSUB DispCC Display catalog
ST=0 sREPEAT No key repeat yet
CCLOOP GOSUB CCSetCurs Show catalog cursor
GOSUB DispCC1 Display catalog info line
ST=1 sBLINK Allow blink
GOSUBL WaitKey Wait for key
GOSUBL AdjustKey Adjust for shifts
GOSUBL ClrCurs Clear cursor
ST=1 sREPEAT Allow repeat by default
GOSUB DoCCKey Do the key
GOTO CCLOOP And loop
**********************************************************************
* Initialize character catalog
**********************************************************************
InitCC GOSUBL EdEnd? At end of text
A=0 A
GOC inicc1 Yes - init cursor to char 0
A=DAT0 B Else read current character
inicc1 D1=(2) CCCHR And init CC cursor to position
DAT1=A B
RTN
**********************************************************************
* Set CC cursor on
**********************************************************************
CCSetCurs C=R4.F A
D1=C
D1=(2) CCCHR
A=DAT1 B A[B] = character
D1=(2) CURSX
LC(2) #1F
C=C&A B
DAT1=C B Cursor X = char & #1F
D1=(2) CURSY
ASR A
ASRB.F P
DAT1=A P Cursor Y = char>>5
GOLONG SetCurs
**********************************************************************
* Swap CC and editor cursors
**********************************************************************
SwapCurs2 C=R4.F A
D1=C
D0=C
D1=(2) CURSX
D0=(2) SAVEX2
A=DAT1 A CURSX[B] and CURSY[XS]
C=DAT0 A
DAT1=C X
DAT0=A X
RTN
**********************************************************************
* This is called only once to show all the characters
**********************************************************************
DispCC LC(5) 64*34 Offset past info line
?ST=1 sCHRMAIN
GOYES +
LC(5) 56*34 When input line is active
+ GOSUBL ClrDispC
GOSUBL GetDispRow1
B=0 B
- C=B B <-------+
ST=0 sBLKINV |
GOSUBL EdDispChr |
B=B+1 B |
RTNC | OK
?B#0 P |
GOYES - --------+
C=B B |
?CBIT=1 4 |
GOYES - --------+
LC(5) 6*34-32 |
AD1EX |
A=A+C A |
AD1EX |
GONC - --------+
**********************************************************************
* This is called after every key to update catalog display on
* the part of the charater information line.
**********************************************************************
DispCC1 P= 10-1 Last line by default
?ST=1 sCHRMAIN
GOYES +
P=P-1 Unless input line is active
+ GOSUBL GetDispRow
GOSUBL Disp:Ret * Display key info
CSTRING 'Key:'
D1=D1+ 1
* Now find character from character table
C=R4.F A
D0=C
D0=(2) CCCHR
C=0 A
C=DAT0 B
?C=0 B
GOYES nonkeyed * No key for chr00
B=C A
-- A=B A <----------+
GOSUBL GetChrPlane |
D0=C | ->plane
LC(2) (=PLUSCODE)-1 |
- A=DAT0 B <-------+ |
?A=B B | |
GOYES + | |
D0=D0+ 2 | |
C=C-1 B | |
GONC - --------+ |
B=B+1 XS |
LC(3) #500 |
?B<=C XS |
GOYES -- -----------+
nonkeyed GOSUBL Disp:Ret
CSTRING ' '
GOTO dispcc1char
* Display the code for the found key. B[XS]=plane C[B]=keycode
+ LA(3) #900+(=PLUSCODE)
A=A-C B True keycode
LC(2) =MINUSCODE #2C
?A>C B
GOYES +
A=A-1 XS
LC(1) =TIMESCODE #27
?A>C B
GOYES +
A=A-1 XS
LC(1) =DIVCODE #22
?A>C B
GOYES +
A=A-1 XS
LC(2) =BACKCODE #1D
?A>C B
GOYES +
A=A-1 XS
LC(1) =INVCODE #18
?A>C B
GOYES +
A=A-1 XS
LC(1) =RIGHTCODE #12
?A>C B
GOYES +
A=A-1 XS
LC(2) =NEXTCODE #0C
?A>C B
GOYES +
A=A-1 XS
LC(1) =Sfkey6 #06
?A>C B
GOYES +
A=A-1 XS
C=0 A #00
+ A=A-C B A[XS]=row A[B]=column B[XS]=plane-1
ASL B
ASL A
BSR A
BSR A
A=B P
A=A+1 A
P= 4-1
GOSUB DispHexP
D1=D1- 2
LCASC '.'
GOSUB EdDispChr
D1=D1+ 1
dispcc1char D1=D1+ 1
GOSUBL Disp:Ret * Display char info
CSTRING 'Chr:'
D1=D1+ 1 * Display character itself
C=R4.F A
D0=C
D0=(2) CCCHR
C=DAT0 B
GOSUBL EdDispChr
D1=D1+ 1 * Display char as hex
LCASC '#'
GOSUBL EdDispChr
A=DAT0 B
P= 2-1
GOSUB DispHexP
D1=D1+ 1 * Display char as dec
A=0 W
A=DAT0 B
GOSBVL =HXDCW
SETHEX
P= 3-1
GOSUB DispHexP
D1=D1+ 1 * Display char as binary
LC(3) #700
C=DAT0 B
B=C X
- LC(2) '0'
B=B+B B
GONC +
LC(1) '1'
+ GOSUBL EdDispChr
B=B-1 XS
GONC -
RTN
**********************************************************************
DoCCKey GOSUBL DispatchKey: CC if keys are forward!
CCKeyTab EDKEY (UPCODE)+(NS),CCup
EDKEY (LEFTCODE)+(NS),CClt
EDKEY (DOWNCODE)+(NS),CCdn
EDKEY (RIGHTCODE)+(NS),CCrt
EDKEY (UPCODE)+(RS),CCfarup
EDKEY (LEFTCODE)+(RS),CCfarlt
EDKEY (DOWNCODE)+(RS),CCfardn
EDKEY (RIGHTCODE)+(RS),CCfarrt
EDKEY (ENTERCODE)+(NS),CCecho
EDKEY (ATTNCODE)+(NS),CCexit
* EDKEY (ALPHACODE),EdModA \ Not needed
* EDKEY (30)+(NS),AlphaOn Not needed
* EDKEY (30)+(ANS),AlphaOff / Not needed
* EDKEY (SHIFTCODE),EdModLS Not needed
EDKEY (ALTCODE),EdModRS
EDKEY 0,BadCCKey
**********************************************************************
BadCCKey
ST=0 sREPEAT
GOLONG ErrBeep
**********************************************************************
CCexit GOSUB SwapCurs2 Restore editor cursor
C=RSTK Was a bug ?
ST=0 sREPEAT
ST=0 sDISPOK
RTN Return to caller
**********************************************************************
* Echo CC character to text
**********************************************************************
CCecho
GOSUB SwapCurs2
D0=(2) CCCHR
?ST=1 sCHRMAIN
GOYES +
GOSUBL DoInputChr * Case 1: Echo in the input line
GOSUBL DispInput * and continue with ChrCat
GOTO SwapCurs2
* C=RSTK * Case 2: Echo in the input line
* GOLONG DoInputChr * and exit from ChrCat
+ C=DAT0 B * Case 3: Echo to text
ST=0 sDISPOK * and continue with ChrCat
GOSUBL DoEdChrKey
GOTO SwapCurs2
**********************************************************************
* CC Cursor Movement Keys
**********************************************************************
CCup LC(2) #100-#20
GONC + ---+
CCdn LC(2) #20 |
GONC + ---+
CClt LC(2) #100-1 |
GONC + ---+
CCrt LC(2) #1 |
+ D1=(2) CCCHR <--+
A=DAT1 B
A=A+C B
DAT1=A B
RTN
**********************************************************************
CCfarup LC(2) #1F
GONC + ---+
CCfarlt LC(2) #E0 |
+ D1=(2) CCCHR <--+
A=DAT1 B
A=A&C B
GONC ++ --------+
CCfardn LC(2) #E0 |
GONC + ---+ |
CCfarrt LC(2) #1F | |
+ D1=(2) CCCHR <--+ |
A=DAT1 B |
A=A!C B |
++ DAT1=A B <-------+
ST=0 sREPEAT
RTN
**********************************************************************
DispHexP B=A W
C=P 15
A=C S
CD1EX
C+P+1
CD1EX
D1=D1- 1
P= 0
dsphplp LCASC '9'
BCEX P
?C<=B P
GOYES dsphp1
C=C+CON B,7
dsphp1 GOSUBL EdDispChr
D1=D1- 2
BSR W
A=A-1 S
GONC dsphplp
P=C 15
CD1EX
C+P+1
CD1EX
P= 0
D1=D1+ 1
RTNCC
**********************************************************************
* ED Keys Using the Input Line
**********************************************************************
EdInputArg GOSUB InputDec:
CSTRING 'Arg: '
GOC Inargok Cancelled
GOSUB EdInputToHex
GOC Inarger Not valid input
?B=0 W
GOYES Inarger Zero repeat counter
B=0 A
?B#0 W
GOYES Inarger Too big repeat counter
C=R4.F A
D1=C
D1=(2) EDARG
DAT1=A A
Inargok GOLONG BackToEdMain Don't repeat EdInputArg!!
Inarger GOLONG BadEdKey
**********************************************************************
EdInputPos GOSUBL EdClrArg Don't repeat inputting!
GOSUB InputDec:
CSTRING 'Pos: '
RTNC Cancelled!
GOSUB EdInputToHex
GOC Inposer Invalid numberr
?A=0 W
GOYES Inposer
A=0 A
?A#0 W
GOYES Inposer Too big position
GOSUBL GetText
C=C+A A STREND
B=B-1 A
A=A+B A
A=A+B A WANTED
?A>C A
GOYES Inposer Over text end - Error
D0=A
GOLONG ToThisD0
Inposer GOLONG BadEdKey
**********************************************************************
EdInputRow GOSUBL EdClrArg Don't repeat inputting!
GOSUB InputDec:
CSTRING 'Row: '
RTNC Cancelled
GOSUB EdInputToHex
GOC Inrower Invalid number
?C=0 W
GOYES Inrower
D=C W
GOSUBL GetText
D0=A
inrwlp D=D-1 W
?D=0 W
GOYES inrw!
GOSUBL Line+
GONC inrwlp
Inrower GOLONG BadEdKey
inrw! GOLONG ToThisD0
**********************************************************************
EdInputChr GOSUBL EdClrArg
GOSUB InputDec:
CSTRING 'Char: '
RTNC
GOSUB EdInputToHex
GOC Inchrer
A=0 W
A=A+1 XS
?C>=A W
GOYES Inchrer
GOLONG DoEdChrKey
Inchrer GOLONG BadEdKey
**********************************************************************
EdInputToHex
C=R4.F A
D1=C
D1=(2) INPLEN
C=DAT1 B
D=C B
D1=(2) INP$
B=0 W
?D=0 B
RTNYES
A=0 W
inp>%lp A=DAT1 B
D1=D1+ 2
LCASC '0'
A=A-C B
RTNC
LC(1) '9'
?A>C P
RTNYES
?B#0 S
RTNYES
B=B+B W *2
C=B W
B=B+B W *4
B=B+B W *8
B=B+C W *10
B=B+A W +digit
D=D-1 B
?D#0 B
GOYES inp>%lp
A=B W
C=A W
RTNCC
**********************************************************************
* Input global find/replace, position restored at end
**********************************************************************
EdReplSPos GOSUBL EdClrArg No repeat
ST=1 sFIND Flag find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Find: '
GOC ReplEnd
GOSUBL EdUpdFindNext Update find position (needed!)
GOC ReplEnd
ST=0 sFIND Flag not find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Repl: '
GOC ReplEnd
GOSUBL EdFarUp
ST=0 sREPL? Flag no questions asked
GOSUBL Replace
ReplEnd D1=(2) SAVEPOS Restore to start position
C=DAT1 A
D0=C
GOLONG ToThisD0
**********************************************************************
* Input global find/replace with verification, position restored at end
**********************************************************************
EdRepl?SPos GOSUBL EdClrArg No repeat
ST=1 sFIND Flag find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Find: '
GOC ReplEnd
GOSUB EdUpdFindNext Update find position (needed!)
GOC ReplEnd
ST=0 sFIND Flag not find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Repl: '
GOC ReplEnd
GOSUBL EdFarUp
ST=1 sREPL? Flag questions asked
GOSUBL Replace
GOTO ReplEnd
**********************************************************************
* Input find/replace, position restored at end
**********************************************************************
EdRepl GOSUBL EdClrArg No repeat
ST=1 sFIND Flag find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Find: '
RTNC Aborted
GOSUB EdUpdFindNext Update find position (needed!)
RTNC No match
ST=0 sFIND Flag not find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Repl: '
RTNC Aborted
ST=0 sREPL? Flag no questions asked
GOLONG Replace
**********************************************************************
* Input find/replace with verification
**********************************************************************
EdRepl? GOSUBL EdClrArg No repeat
ST=1 sFIND Flag find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Find: '
RTNC Aborted
GOSUB EdUpdFindNext Update find position (needed!)
RTNC No match
ST=0 sFIND Flag not find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Repl: '
RTNC Aborted
ST=1 sREPL? Flag questions asked
GOLONG Replace
**********************************************************************
* Input find string
**********************************************************************
EdFind GOSUBL EdClrArg No repeat
ST=1 sFIND Flag find mode
ST=0 sINPDEC Flag any characters
GOSUB Input:
CSTRING 'Find: '
RTN
**********************************************************************
* Key press to find next match
**********************************************************************
EdFindNext ST=0 sDISPOK Display not ok
GOSUB EdUpdFind+ Update forwards
RTNNC Match
fnxterr GOLONG BadEdKey No match - error
**********************************************************************
* Key press to find previous match
**********************************************************************
EdFindPrev ST=0 sDISPOK Display not ok
GOSUB EdUpdFind- Update backwards
RTNNC Match
GOC fnxterr No match - error
**********************************************************************
* ED Input Subroutines
**********************************************************************
InputDec: ST=0 sFIND
ST=1 sINPDEC
Input: C=RSTK
D0=C
GOSUB DispPrompt
* Set return address
* B[A]=chars in prompt
CD0EX
RSTK=C
GOSUB InitInput
?ST=1 sINPDEC
GOYES inp11
GOSUBL AlphaOn
inp11
InputLoop
GOSUB UnScroll9
GOSUBL DispEd9
GOSUBL SetCurs
GOSUB SwapCurs
GOSUBL DispInput
ST=0 sCURSOR
GOSUBL SetCurs
ST=1 sBLINK
GOSUBL WaitKey
GOSUBL AdjustKey
GOSUBL ClrCurs
GOSUB SwapCurs
ST=1 sCURSOR
GOSUBL ClrCurs
ST=1 sREPEAT
ST=0 sDISPOK
GOSUB DoInputKey
GOTO InputLoop
**********************************************************************
DispInput
P= 10-1
GOSUBL GetDispRow
C=R4.F A
D0=C
D0=(2) INPOFF
A=0 A
A=DAT0 B
CD1EX
C=C+A A
CD1EX
D0=(2) INPLEN
C=DAT0 B
D0=D0+ 2
D=C B Chars
LC(2) 33 \
C=C-A B Spaces
B=C B /
ST=0 sBLKINV
dspinplp
D=D-1 B
GOC dspdinp
B=B-1 B
C=DAT0 B
D0=D0+ 2
GOSUBL EdDispChr
GONC dspinplp
dspdinp C=B B
C=C-1 B
RTNC
GOLONG DispSpcs
**********************************************************************
InitInput C=R4.F A Prompt size
D1=C
D1=(2) INPOFF
C=B A
DAT1=C B
D1=(2) SAVEX X
DAT1=C B
D1=(2) SAVEY Y (fixed)
LC(1) 10-1
DAT1=C 1
D1=(2) CURPOS Pos
C=DAT1 A
D1=(2) SAVEPOS
DAT1=C A
D1=(2) INPLEN Len
C=0 A
DAT1=C B
?ST=0 sFIND
RTNYES
D1=(2) FNDLEN
DAT1=C B
RTN
**********************************************************************
DispPrompt P= 10-1
GOSUBL GetDispRow
LC(5) 6*34
GOSBVL =WIPEOUT
LC(5) 6*34
AD1EX
A=A-C A
AD1EX
B=0 A Offset
ST=0 sBLKINV
dspprlp C=DAT0 B
D0=D0+ 2
?C=0 B
RTNYES
GOSUBL EdDispChr
B=B+1 A
GONC dspprlp
**********************************************************************
SwapCurs C=R4.F A
D1=C
D0=C
D1=(2) CURSX
D0=(2) SAVEX
A=DAT1 B
C=DAT0 B
DAT1=C B
DAT0=A B
D1=(2) CURSY
D0=(2) SAVEY
A=DAT1 1
C=DAT0 1
DAT1=C 1
DAT0=A 1
D1=(2) XOFF
RTN
**********************************************************************
UnScroll9 C=R4.F A
D1=C
D1=(2) CURSY
A=DAT1 P
LC(1) 9-1
?A<=C P
RTNYES
DAT1=C P
C=R4.F A
D1=C
D1=(2) TOPPOS
A=DAT1 A
D0=A
GOSUBL Line+
AD0EX
DAT1=A A
RTN
**********************************************************************
DoInputKey GOSUBL EdStrKey?
GONC +
GOTO DoInputStr
+ GOSUBL EdChrKey?
GONC +
GOTO DoInputChr
+ GOSUBL DispatchKey:
**********************************************************************
InputKeyTab
EDKEY (LEFTCODE)+(NS),InputLt
EDKEY (LEFTCODE)+(RS),InputFarLt
EDKEY (RIGHTCODE)+(NS),InputRt
EDKEY (RIGHTCODE)+(RS),InputFarRt
EDKEY (NEXTCODE)+(NS),InpUpdFind+
EDKEY (DOWNCODE)+(NS),InputWord
EDKEY (NEXTCODE)+(LS),InpUpdFind-
EDKEY (ENTERCODE)+(NS),InputExit
EDKEY (ENTERCODE)+(ANS),InputExit
EDKEY (ATTNCODE)+(NS),InputAbort
EDKEY (ATTNCODE)+(ANS),InputAbort
EDKEY (DELCODE)+(NS),InputDel
EDKEY (DELCODE)+(ANS),InputDel
EDKEY (BACKCODE)+(NS),InputBS
EDKEY (BACKCODE)+(ANS),InputBS
EDKEY (Sfkey3)+(NS),DoInputBlk
EDKEY (PRGCODE)+(RS),InputChrCat
* EDKEY (ALPHACODE),EdModA \
EDKEY (30)+(NS),AlphaOn By Dan
EDKEY (30)+(ANS),AlphaOff
EDKEY (30)+(ALS),TogCase /
EDKEY (SHIFTCODE),EdModLS
EDKEY (ALTCODE),EdModRS
EDKEY (EEXCODE)+(NS),TogBeep
EDKEY (EEXCODE)+(LS),TogCase
EDKEY (EEXCODE)+(RS),TogOver
EDKEY (ATTNCODE)+(RS),EdOFF
EDKEY 0,BadInputKey
**********************************************************************
BadInputKey ST=0 sREPEAT
GOLONG ErrBeep
**********************************************************************
* Abort input line
**********************************************************************
InputAbort D1=(2) INPLEN Clear input
C=0 A
DAT1=C B
C=RSTK Pop return address
GOSUBL AlphaOff Alpha mode off
ST=0 sDISPOK Display not ok
ST=0 sREPEAT Repear not ok
RTNSC Input wasn't ok
**********************************************************************
* Exit input
**********************************************************************
InputExit C=RSTK Pop return address
GOSUBL AlphaOff Alpha mode off
ST=0 sDISPOK Display not ok
ST=0 sREPEAT Repeat not ok
RTNCC Input was ok
**********************************************************************
* Call Input ChrCat if Find/Replace [i.e. ST(sINPDEC)=ST(sCHRMAIN)=0 ]
**********************************************************************
InputChrCat ?ST=1 sINPDEC
GOYES BadInputKey
GOLONG ChrCat
**********************************************************************
* Move input cursor left
**********************************************************************
InputLt D1=(2) INPOFF
C=DAT1 B prompt lenght
D1=(2) SAVEX
A=DAT1 B cursor pos
A=A-1 B
GOC badinparr cursor overflow (no prompt?)
?A<C B
GOYES badinparr start of input
DAT1=A B
RTN
badinparr GOTO BadInputKey
**********************************************************************
* Move input cursor right
**********************************************************************
InputRt D1=(2) INPLEN
C=DAT1 B input lenght
D1=(2) INPOFF
A=DAT1 B prompt lenght
C=C+A B total X
D1=(2) SAVEX
A=DAT1 B cursor position
A=A+1 B
?A>C B
GOYES + End of input, insert new char
DAT1=A B
RTN
+ ?ST=1 sINPDEC
GOYES badinparr Not find/repl
D1=(2) INPLEN
A=0 A
A=DAT1 B input lenght
D1=(2) CURPOS
C=DAT1 A
C=C+A A
C=C+A A where to get the next char
D1=(2) STREND
A=DAT1 A
?C>=A A
GOYES badinparr No more chars in text
D0=C ->char
GOTO DoInputChr And insert it
**********************************************************************
* Move input cursor to start of input
**********************************************************************
InputFarLt D1=(2) INPOFF
A=DAT1 B
D1=(2) SAVEX
DAT1=A B
RTN
**********************************************************************
* Move input cursor to end of input
**********************************************************************
InputFarRt D1=(2) INPLEN
A=DAT1 B
D1=(2) INPOFF
C=DAT1 B
A=A+C B
D1=(2) SAVEX
DAT1=A B
RTN
**********************************************************************
* Store possible current word in input line
**********************************************************************
InputWord ?ST=0 sINPDEC
GOYES +
- GOTO BadInputKey Not when inputting a number
+ GOSUBL EdThisWord Find word
GOC - No word under cursor - beep
B=C A
LC(5) INPMAX Take max INPMAX characters
?B>=C A
GOYES +
C=B A
+ D1=(2) INPOFF
A=DAT1 A
A=A+C A
D1=(2) SAVEX
DAT1=A B New cursor location
D1=(2) INPLEN
DAT1=C B
C=C+C B
D1=D1+ 2
AD0EX
D0=A
B=A A
GOSBVL =MOVEDOWN Copy new input line to place
A=B A
D0=A
GOSUBL ToThisD0 Change cursor to start of word
GOTO InpUpdFind And update
**********************************************************************
* Delete char under cursor in input line
**********************************************************************
InputDel A=0 A
D1=(2) SAVEX
A=DAT1 B
D1=(2) INPOFF
C=DAT1 B
A=A-C B True X
D1=(2) INPLEN
C=DAT1 B
?A>=C B
GOYES Ideler Nothing left
C=C-1 B
DAT1=C B Len--
D1=(2) INP$
CD1EX
C=C+A A
C=C+A A
D1=C
D0=C
D0=D0+ 2
LC(5) (INPMAX)-1
C=C-A A Chars to move
C=C+C A
GOSBVL =MOVEDOWN
GOTO InpUpdFindNew
Ideler GOTO BadInputKey
**********************************************************************
* Delete char before cursor in input line
**********************************************************************
InputBS C=0 A
D1=(2) INPOFF
C=DAT1 B
D1=(2) SAVEX
A=DAT1 B
C=A-C B True X
?C=0 B
GOYES Ibser
A=A-1 B
DAT1=A B X--
D1=(2) INPLEN
A=DAT1 B
A=A-1 B
DAT1=A B Len--
D1=(2) INP$
AD1EX
A=A+C A
A=A+C A
D0=A
D1=A
D1=D1- 2
LA(2) INPMAX
C=A-C B
C=C+C A
GOSBVL =MOVEDOWN
GOTO InpUpdFindNew
Ibser GOTO BadInputKey
**********************************************************************
* This should insert possible block into input string
**********************************************************************
DoInputBlk GOTO BadInputKey
**********************************************************************
DoInputChr C=0 A
C=C+1 A 1 char
GONC inp$key
**********************************************************************
DoInputStr C=0 A
C=DAT0 1 chars
D0=D0+ 1
* D[A]=CHARS D0=->STR + SKIP
* If CHARS = 1 SKIP=1
inp$key
D=C A chars
?ST=0 sINPDEC Check char is decimal
GOYES inp$ok
LC(1) 1
?C#D A
GOYES inp$bad
A=DAT0 B
LCASC '0'
?A<C B
GOYES inp$bad
LC(1) '9'
?A<=C B
GOYES inp$ok
inp$bad GOTO BadInputKey
inp$ok
?ST=1 sOVERWR
GOYES inpover$
GOTO inpins$
* Overwrite string into input string
inpover$ A=R4.F A
D1=A
D1=(2) SAVEX
A=DAT1 B Cursor X
D1=(2) INPOFF
C=DAT1 B Prompt lenght
A=A-C B True X
LC(2) INPMAX
C=C-A B Free chars
?D<=C B
GOYES iov$ok
GOTO BadInputKey No room for the string
iov$ok D1=(2) INP$
CD1EX
C=C+A B
C=C+A B
CD1EX ->overwrite position
C=D A
C=C+C A nibbles to write
GOSBVL =MOVEDOWN Copy string
LC(2) 1
?C=D B
GOYES inpov10 Char-key, skip 1 char only
C=DAT0 1 Skip according to string key skip index
inpov10 AD1EX
D0=A
D1=A
D1=(2) SAVEX
A=DAT1 B Cursor X
A=A+C B New X
DAT1=A B
D1=(2) INP$ Update INPLEN if necessary
CD1EX
D1=C
AD0EX
A=A-C B
ASRB.F B
D1=(2) INPLEN
C=DAT1 B
?A<C B
GOYES inpovok
DAT1=A B
inpovok GOTO InpUpdFind
* Insert string into input string
inpins$ A=R4.F A
D1=A
D1=(2) INPLEN
A=DAT1 B
LC(2) INPMAX
C=C-A B Free
?D<=C B
GOYES iins$ok
GOTO BadInputKey
iins$ok CD0EX
B=C A ->$
D1=(2) SAVEX
A=DAT1 B
D1=(2) INPOFF
C=DAT1 B
A=A-C B True X
D1=(2) (INP$)+2*(INPMAX)
CD1EX
D1=C
C=C-D A
C=C-D A
D0=C
LC(5) =INPMAX
C=C-A B
C=C-D B
C=C+C A
GOSBVL =MOVEUP D0=->$INSPOS
C=B A
CD0EX
D1=C
C=D A
C=C+C A
GOSBVL =MOVEDOWN
LC(2) 1
?C=D B
GOYES inpins5
C=DAT0 1
inpins5 D1=(2) SAVEX
A=DAT1 B
A=A+C B
DAT1=A B
D1=(2) INPLEN
C=DAT1 B
C=C+D B
DAT1=C B
GOTO InpUpdFind
**********************************************************************
* ED String Matching Code
**********************************************************************
InpToFind C=R4.F A
D0=C
D1=C
D0=(2) INPLEN
D1=(2) FNDLEN
C=0 A
LC(2) 2*(INPMAX)+2
GOVLNG =MOVEDOWN
**********************************************************************
* Update match position since find string changed
**********************************************************************
InpUpdFindNew ?ST=0 sFIND
RTNYES Not inputting a find string
GOSUB InpToFind Copy input to find storage
C=R4.F A
D0=C
D0=(2) SAVEPOS Start from the saved original
C=DAT0 A cursor position
D0=C
GOSUB UpdFindNext Update forwards
RTNNC Found match
GOTO BadInputKey No match - error
**********************************************************************
* Update match position forwards while in input line
**********************************************************************
InpUpdFind+ ?ST=0 sFIND
RTNYES Not inputting a find string
GOSUB InpToFind Copy input to find storage
GOSUB EdUpdFind+ Update forwards
RTNNC Found match
GOTO BadInputKey No match - error
**********************************************************************
* Update match position backwards while in input line
**********************************************************************
InpUpdFind- ?ST=0 sFIND
RTNYES Not inputing a find string
GOSUB InpToFind Copy input to find storage
GOSUB EdUpdFind- Update backwards
RTNNC Found match
GOTO BadInputKey No match - error
**********************************************************************
* Update match position forwards
**********************************************************************
EdUpdFind+ GOSUBL GetCurPos Start from cursor + 1
D0=D0+ 2
GOTO UpdFindNext And update from there
**********************************************************************
* Update match position backwards
**********************************************************************
EdUpdFind- GOSUBL GetCurPos Start from cursor - 1
D0=D0- 2
GOTO UpdFindPrev
**********************************************************************
* Update match position in D0 while in input line
**********************************************************************
InpUpdFind ?ST=0 sFIND
RTNYES
GOSUB InpToFind
GOSUB EdUpdFindNext
RTNNC
GOTO BadInputKey
**********************************************************************
* Update editor match position
**********************************************************************
EdUpdFindNext GOSUBL GetCurPos
UpdFindNext ST=0 sFNDCS Assume not sensitive
D1=(2) FNDLEN
C=DAT1 B
?C=0 B
RTNYES Nothing to seek
D=C B D[B] = length
D1=(2) FND$ ->find string
* Determine case sensitivity from find string
- D=D-1 B <-------+
GOC + ---+ | Tested all, not case sensitive
A=DAT1 B | |
D1=D1+ 2 | |
LCASC 'a' | |
?A<C B | |
GOYES - ---|----+
LCASC 'z' | |
?A>C B | |
GOYES - ---|----+
ST=1 sFNDCS | Found lower case ==> case sensitive
+ D1=(2) FNDLEN <--+
A=0 A
A=DAT1 B length
D1=(2) STREND
C=DAT1 A
C=C-A A
C=C-A A End Addr of seek
AD0EX
D0=A
C=C-A A
RTNC No room for a match!
CSRB.F A
D=C A Positions left to test
D=D+1 A Find matches at end of text too
* Now dispatch to separate find subroutines for speed
?ST=1 sFNDCS
GOYES FindExact+
GOTO FindInExact+
**********************************************************************
* Case dependant search forwards
**********************************************************************
FindExact+
exactlp+ D1=(2) FND$
A=DAT1 B
D=D-1 A
RTNC No positions left, no match
- C=DAT0 B <-------+
D0=D0+ 2 |
?A=C B |
GOYES + ---+ |
D=D-1 A | |
GONC - ---|----+
RTNSC | No match
* First char matched, try the rest now
+ D1=(2) FNDLEN <--+
A=DAT1 B
B=A B Setup lenght counter
D1=(2) (FND$)+2 Second char
B=B-1 B
- B=B-1 B <-------+
GOC gotexact+ -+ | No more chars to compare, match
A=DAT0 B | |
D0=D0+ 2 | |
C=DAT1 B | |
D1=D1+ 2 | |
?A=C B | |
GOYES - ---|----+ Matched char, try next one
D1=(2) FNDLEN | No match, restore search position
C=0 A |
C=DAT1 B |
C=C-B B | How many matched
AD0EX |
A=A-C A |
A=A-C A |
D0=A | Start of match
D0=D0+ 2 | And skip first char
GONC exactlp+ | And start main loop again
* Found exact match |
gotexact+ D1=(2) FNDLEN <--+
C=0 A
C=DAT1 B
AD0EX Skip back to start of match
A=A-C A
A=A-C A
D0=A
GOLONG ToThisD0 Set cursor to the match position
**********************************************************************
* Case independant search forwards
**********************************************************************
FindInExact+
inexactlp+ D1=(2) FND$
A=DAT1 B 1st char to match
LCASC 'a'
?A<C B
GOYES + ---+
LCASC 'z' |
?A>C B |
GOYES + ---+
ABIT=0 5 | Convert to upper case
+ B=A B <--+ 'char1'
-- LCASC 'a' <---------+
- D=D-1 A <-------+ |
RTNC | | No positions left, no match
A=DAT0 B | |
D0=D0+ 2 | |
?A=B B | |
GOYES + ----+ | | Matched as is, test the rest
?A<C B | | | See if chars match in upper cs
GOYES - ----|---+ | Not lower case, no match
LCASC 'z' | |
?A>C B | |
GOYES -- ----|-----+ Not lower case, no match
ABIT=0 5 | | Convert to lower case
?A#B B | |
GOYES -- ----|-----+ Still no match, try next pos
* First 'char' matched, compare the rest
+ DSL W <---+
DSL W
D1=(2) FNDLEN
C=DAT1 B
D=C B Chars to match
D1=(2) (FND$)+2 ->char2
D=D-1 B
- D=D-1 B <-------+
GOC gotinexact+ |
A=DAT0 B | Char to match
D0=D0+ 2 |
LCASC 'a' | Convert to upper case if possible
?A<C B |
GOYES + ---+ |
LCASC 'z' | |
?A>C B | |
GOYES + ---+ |
ABIT=0 5 | |
+ B=A B <--+ | charN
A=DAT1 B | Char to test
D1=D1+ 2 |
LCASC 'a' | Convert to upper case if possible
?A<C B |
GOYES + ---+ |
LCASC 'z' | |
?A>C B | |
GOYES + ---+ |
ABIT=0 5 | |
+ ?A=B B <--+ |
GOYES - --------+ Match, try next char
* No match, restore old position and start main loop again
D1=(2) FNDLEN
C=0 A
C=DAT1 B
C=C-D B
AD0EX
A=A-C A
A=A-C A
D0=A
D0=D0+ 2
DSR W
DSR W
GOTO inexactlp+
* Found inexact match, restore old position and jump there
gotinexact+ D1=(2) FNDLEN
C=0 A
C=DAT1 B
AD0EX
A=A-C A
A=A-C A
D0=A
GOLONG ToThisD0
**********************************************************************
* Update editor match position
**********************************************************************
EdUpdFindPrev GOSUBL GetCurPos
UpdFindPrev ST=0 sFNDCS Assume not sensitive
D1=(2) FNDLEN
C=DAT1 B
?C=0 B
RTNYES Nothing to seek
D=C B D[B] = length
D1=(2) FND$ ->find string
* Determine case sensitivity from find string
- D=D-1 B <-------+
GOC + ---+ | Tested all, not case sensitive
A=DAT1 B | |
D1=D1+ 2 | |
LCASC 'a' | |
?A<C B | |
GOYES - ---|----+
LCASC 'z' | |
?A>C B | |
GOYES - ---|----+
ST=1 sFNDCS | Found lower case ==> case sensitive
+ D1=(2) FNDLEN <--+
A=0 A
A=DAT1 B length
CD0EX
C=C+A A
C=C+A A ->curstail
C=C-CON A,2 Find previous!
D1=(2) STREND Check against end of text
A=DAT1 A
?C<=A A
GOYES +
C=A A
+ D0=C start scan from here
D1=(2) FNDLEN
A=0 A
A=DAT1 B
A=A-1 A
C=C-A A
C=C-A A start pos for 1st char
D1=(2) STR
A=DAT1 A
C=C-A A
RTNC No positions left!
CSRB.F A
D=C A Positions left to test
D=D+1 A Find matches at start of text too
* Now dispatch to separate find subroutines for speed
?ST=1 sFNDCS
GOYES FindExact-
GOTO FindInExact-
**********************************************************************
* Case dependant search backwards
**********************************************************************
FindExact-
A=0 A
exactlp- D1=(2) FNDLEN
A=DAT1 B
B=A B length to match
D1=(2) FND$
CD1EX
C=C+A A
C=C+A A
CD1EX
D1=D1- 2 ->last char
A=DAT1 B
D=D-1 A
RTNC No positions left, no match
- C=DAT0 B <-------+
D0=D0- 2 |
?A=C B |
GOYES + ---+ |
D=D-1 A | |
GONC - ---|----+
RTNSC | No match
* Last charmatched, try the rest now
+ D1=D1- 2 <--+ ->2nd last char
B=B-1 B
- B=B-1 B <-------+
GOC gotexact- -+ | No more chars to compare, match
A=DAT0 B | |
C=DAT1 B | |
D0=D0- 2 | |
D1=D1- 2 | |
?A=C B | |
GOYES - ---|----+ Matched char, try prev one
D1=(2) FNDLEN | No match, restore search position
C=0 A |
C=DAT1 B |
C=C-B B | How many matched
AD0EX |
A=A+C A |
A=A+C A |
AD0EX | Start of match
D0=D0- 2 | And skip back over last char
GONC exactlp- | And start main loop again
* Found exact match |
gotexact- D0=D0+ 2 <--+
GOLONG ToThisD0 Set cursor to the match position
**********************************************************************
* Case independant search backwards
**********************************************************************
FindInExact-
inexactlp- D1=(2) FNDLEN
A=0 A
A=DAT1 B
D1=(2) FND$
CD1EX
C=C+A A
C=C+A A
CD1EX
D1=D1- 2 ->Last char of FND$
A=DAT1 B 1st char to match
LCASC 'a' Convert it to upper case
?A<C B
GOYES + ---+
LCASC 'z' |
?A>C B |
GOYES + ---+
ABIT=0 5 |
+ B=A B <--+ 'charN'
- D=D-1 A <-------+
RTNC | No positions left, no match
A=DAT0 B |
D0=D0- 2 |
?A=B B |
GOYES + ----+ | Matched as is, test the rest
LCASC 'a' | | See if chars match in upper
?A<C B | | case
GOYES - ----|---+ Not lower case, no match
LCASC 'z' | |
?A>C B | |
GOYES - ----|---+ Not lower case, no match
ABIT=0 5 | | Convert to lower case
?A#B B | |
GOYES - ----|---+ Still no match, try prev pos
* Last 'char' matched, compare the rest
+ DSL W <---+
DSL W
AD1EX
D1=A
D1=(2) FNDLEN
C=DAT1 B
D=C B chars to match
D1=A
D1=D1- 2 ->2nd last char
D=D-1 B
- D=D-1 B <-------+
GOC gotinexact- |
A=DAT0 B | Char to match
D0=D0- 2 |
LCASC 'a' | Convert to upper case if possible
?A<C B |
GOYES + ---+ |
LCASC 'z' | |
?A>C B | |
GOYES + ---+ |
ABIT=0 5 | |
+ B=A B <--+ | charN
A=DAT1 B | Char to test
D1=D1- 2 |
LCASC 'a' | Convert to upper case if possible
?A<C B |
GOYES + ---+ |
LCASC 'z' | |
?A>C B | |
GOYES + ---+ |
ABIT=0 5 | |
+ ?A=B B <--+ |
GOYES - --------+ Match, try prev char
* No match, restore old position and start main loop again
D1=(2) FNDLEN
C=0 A
C=DAT1 B
C=C-D B
AD0EX
A=A+C A
A=A+C A
D0=A
D0=D0- 2
DSR W
DSR W
GOTO inexactlp-
* Found inexact match, restore old position and jump there
gotinexact- D0=D0+ 2
GOLONG ToThisD0
**********************************************************************
* Replace find string with input string
* Input: CURPOS - Replace from cursor forwards
* FND$ - Find string
* INP$ - Replace string
* sREPL? - Verify each replace? (Not implemented)
* Out: CURPOS' - Position of last replace
* Notes:
* ATTN key aborts Replace loop, this because the replace loop
* can be quite slow for long texts.
**********************************************************************
Replace ST=0 sDISPOK Display won't be ok
GOSUB EdUpdFindNext Make sure there is atleast one match
GONC ReplaceLoop There is
GOTO replerr None - error
ReplaceLoop ?ST=0 sREPL?
GOYES replnow
GOSUB ReplaceDisp First display the match
ReplaceAsk ST=0 sBLINK
ST=1 sREPEAT
GOSUBL WaitKey
A=C A
LC(2) Sfkey1 YES
?A=C A
GOYES replYES
ST=0 sREPL?
LC(1) Sfkey2 ALL
?A=C A
GOYES replYES
ST=1 sREPL?
LC(1) Sfkey6 NO
?A=C A
GOYES replNO
LC(1) Sfkey5 NONE
?A=C A
GOYES gorepldone
LC(2) ATTNCODE
?A=C A
GOYES gorepldone
GOSUBL ErrBeep
GOTO ReplaceAsk
gorepldone GOTO repldone
replNO GOSUBL GetCurPos
AD0EX
D1=A
D1=D1+ 2
GONC ReplaceNext
* Replace the match
replYES GOSUBL GetCurPos
replnow GOSBVL =chk_attn
GOC replerr Abort - ATTN pressed
C=R4 A
D1=C
D1=(2) FNDLEN
A=0 A
A=DAT1 B lenght of match
D1=(2) INPLEN
C=0 A
C=DAT1 B lenght of replace
?A<C A match < replace?
GOYES ReplaceLonger
C=A-C A Difference
GOSUBL EdRemove Delete extra chars
GOTO + And overwrite replace string
ReplaceLonger C=C-A A Allocate missing space
GOSUBL EdAlloc
GOC replerr No memory - error
* Overwrite replace string to match position
+ D1=(2) INPLEN
C=0 A
C=DAT1 B lenght to write
D1=(2) INP$ ->replace string
AD0EX
AD1EX D1 = ->match
AD0EX D0 = ->replace
C=C+C A Nibbles
GOSBVL =MOVEDOWN Overwrite
ReplaceNext C=R4 A
CD1EX
D1=(2) CURPOS
DAT1=C A Set new cursor position after replace
GOSUBL EdUpdFindNext Find next match
GOC repldone Done if none found
GOTO ReplaceLoop And replace again if found one
replerr GOSUBL ToThisPos Make sure display comes out ok
GOSUBL InitDisp Destroy traces of menu
GOSUBL SetNoBlk
GOLONG BadEdKey even if memory runs out
repldone ST=0 sDISPOK
GOSUBL ToThisPos Setup display properly
GOSUBL InitDisp And scratch menu
GOLONG SetNoBlk
* Display the match. Note that match may span several lines!
ReplaceDisp C=R4
D1=C
D1=(2) FNDLEN
C=0 A
C=DAT1 B
AD0EX
A=A+C A
A=A+C A ->matchend
D1=(2) BLKEND Set block end for highlighting
DAT1=A A
D0=A
GOSUBL ToThisD0
GOSUBL UnScroll9 Ok, last line must be on screen now
GOSUBL GetCurPos
D1=(2) FNDLEN
C=0 A
C=DAT1 B
AD0EX
A=A-C A
A=A-C A ->match
D1=(2) BLK Set block start for highlighting
DAT1=A A
D0=A
GOSUBL ToThisD0
GOSUBL DispEd9 Display the 9 lines
P= 10-1
GOSUBL GetDispRow
GOSUB +
NIBHEX 0000000000000000000000000000000000
NIBHEX FFFFFDFFFF7FFFFFDFFFF7FFFFFDFFFF70
NIBHEX F513FDF67F7FFFFFDFFFF7B54B8DF61F70
NIBHEX F5DDFD757F7FFFFFDFFFF7355AEDF45F70 YES ALL - - NONE NO
NIBHEX FB1BFD747F7FFFFFDFFFF734588DF05F70
NIBHEX FBD7FD757F7FFFFFDFFFF7B459EDF25F70
NIBHEX FB19FD754C7FFFFFDFFFF7B54B8DF61F70
NIBHEX FFFFFDFFFF7FFFFFDFFFF7FFFFFDFFFFF0
+ C=RSTK
D0=C
LC(5) 34*8
GOVLNG =MOVEDOWN
**********************************************************************
**********************************************************************
* ED Counter Variable
**********************************************************************
**********************************************************************
* Initialize ED Counter Variable
* Input: ddd..d or #hhh..h
**********************************************************************
EdInitCntr GOSUBL EdClrArg Don't repeat input!
ST=0 sFIND
ST=0 sINPDEC
GOSUBL Input:
CSTRING 'Counter: '
RTNC Aborted
GOSUB ParseInput
GOC initctrerr Invalid input - abort
C=R4.F A
D1=C
D1=(2) EDCNTR Save counter
DAT1=A 8
CSLC
D1=(2) EDCNTRWID Save counter width with type in hi bit
?ST=0 sINPDEC
GOYES +
CBIT=1 3
+ DAT1=C 1
ST=0 sDISPOK
ST=0 sREPEAT
RTN
initctrerr GOLONG BadEdKey
**********************************************************************
* Insert counter into cursor position and increment it
**********************************************************************
EdOutCntr C=R4.F A
D0=C
D0=(2) EDCNTR
D1=(2) EDCNTRWID
C=DAT1 S
C=C+C S
CSRB.F S C[S]=cntrwid
P=C 15
CD0EX
C+P+1
CD0EX
P= 0
B=C S
D1=(2) INP$ Output lenght as chars for DoEdStrKey
C=C+1 S
DAT1=C S
D1=D1+ 1
C=C-1 S
- LAASC '0'
D0=D0- 1
A=DAT0 1
LCASC '9'
?A<=C B
GOYES +
A=A+CON B,7
+ DAT1=A B
D1=D1+ 2
C=C-1 S
GONC -
C=B S And the skip amount at the end
C=C+1 S
DAT1=C S
C=R4.F A Now insert/overwrite the counter
D0=C
D0=(2) INP$
GOSUBL DoEdStrKey
?ST=0 sREPEAT If repeat is off then error occurred
RTNYES
C=R4.F A
D1=(2) EDCNTRWID
C=DAT1 S
C=C+C S
GONC +
SETDEC
+ CSRB.F S C[S]=cntrwid
D1=(2) EDCNTR
A=DAT1 8
A=A+1 W
DAT1=A 8
SETHEX
RTN
**********************************************************************
* Parse input line as a hex or a decimal number
**********************************************************************
ParseInput C=R4.F A
D1=C
D1=(2) INPLEN
C=DAT1 B
D=C B chars
D1=(2) INP$
B=0 W No digits yet
A=DAT1 B char1
ST=1 sINPDEC Assume decimal input
LCASC '#'
?A#C B
GOYES +
ST=0 sINPDEC
D1=D1+ 2
D=D-1 B
RTNC CS: No digits at all
+ D=D-1 B
RTNC CS: No digits at all
C=D P
CSRC C[S]=digits-1
LC(2) 8
?D>=C B
RTNYES CS: Over 8 decimal characters
- A=DAT1 B
D1=D1+ 2
LCASC '0'
A=A-C B
RTNC CS: Non decimal
LC(2) '9'-'0'
?A<=C B
GOYES + Is decimal
?ST=1 sINPDEC
RTNYES Wasn't decimal - error
LC(2) 'A'-'0'
A=A-C B
RTNC CS: Non hex
LC(2) 5
?A>C B
RTNYES CS: Non hex
A=A+CON B,10
+ BSL W
B=A P
D=D-1 B
GONC -
A=B W Digits
RTNCC
**********************************************************************
* Find matching delimiter
**********************************************************************
EdFindDelim ST=0 sREPEAT No repeat!
ST=0 sDISPOK Display not ok
GOSUB EdThisWord
GOC fnddelimerr No text to test
C=0 A
R1=C token counter
* Choose which scan to start
GOSUB WordProg?
GOC fndEndProg
GOSUB WordEndProg?
GOC fndProg
GOSUB WordList?
GOC fndEndList
GOSUB WordEndList?
GONC fnddelimerr
GOTO fndList
* Scan forwards for matching ">>"
- R1=A
fndEndProg GOSUB NextWord
GOC fnddelimerr
GOSUB WordEndProg?
GOC +
GOSUB WordProg?
GONC fndEndProg
A=R1 A
A=A+1 A
GONC -
+ A=R1 A
A=A-1 A
GONC -
GOTO gotdelim
* Scan backwards for matching "<<"
- R1=A
fndProg GOSUB PrevWord
GOC fnddelimerr
GOSUB WordProg?
GOC +
GOSUB WordEndProg?
GONC fndProg
A=R1 A
A=A+1 A
GONC -
+ A=R1 A
A=A-1 A
GONC -
GOC gotdelim
fnddelimerr GOLONG BadEdKey
* Scan forwards for matching "}"
- R1=A
fndEndList GOSUB NextWord
GOC fnddelimerr
GOSUB WordEndList?
GOC +
GOSUB WordList?
GONC fndEndList
A=R1 A
A=A+1 A
GONC -
+ A=R1 A
A=A-1 A
GONC -
GOC gotdelim
* Scan backwards for matching "{"
- R1=A
fndList GOSUB PrevWord
GOC fnddelimerr
GOSUB WordList?
GOC +
GOSUB WordEndList?
GONC fndList
A=R1 A
A=A+1 A
GONC -
+ A=R1 A
A=A-1 A
GONC -
gotdelim GOLONG ToThisD0
WordProg? LC(2) #AB "<<"
GOTO wordtest
WordEndProg? LC(2) #BB ">>"
GOTO wordtest
WordList? LC(2) #7B "{"
GOTO wordtest
WordEndList? LC(2) #7D "}"
wordtest A=R0
A=A-1 A
?A#0 A
GOYES wordfail
A=DAT0 B
?A=C B
RTNYES
wordfail RTNCC
* Get word under cursor, CS if none present
EdThisWord GOSUBL GetCurPos
SafeThisWord GOSUBL End?
RTNC
D1=(2) STR
A=DAT1 A
B=A A ->str
D1=(2) STREND
C=DAT1 A
D=C A ->strend
ThisWord LCASC ' '
A=DAT0 B
?A<=C B
RTNYES
- D0=D0- 2 <-------+ Scan backwards until white char
A=DAT0 B |
?A>C B |
GOYES - --------+
D0=D0+ 2 1st black char
CD0EX Check against start of str
?C>=B A
GOYES + --------+
C=B A |
+ D0=C <-------+
RSTK=C Save start of word
LCASC ' '
- A=DAT0 B <-------+ Scan forward until white
D0=D0+ 2 |
?A>C B |
GOYES - --------+
D0=D0- 2
CD0EX Check against end of text
?C<=D A
GOYES + --------+
C=D A |
+ A=C A <-------+ ->wordtail
C=RSTK
D0=C ->word
C=A-C A
CSRB.F A chars
R0=C.F A
RTNCC
* Get next word, CS if none present
EdNextWord GOSUBL GetCurPos
SafeNextWord GOSUBL End?
RTNC
D1=(2) STR
A=DAT1 A
B=A A ->str
D1=(2) STREND
C=DAT1 A
D=C A ->strend
NextWord LCASC ' '
- A=DAT0 B <-------+ Skip current word
D0=D0+ 2 |
?A>C B |
GOYES - --------+
- A=DAT0 B <-------+ Skip white
D0=D0+ 2 |
?A<=C B |
GOYES - --------+
D0=D0- 2
CD0EX
D0=C
?C>=D A
RTNYES BZZZT! No words left
RSTK=C
LCASC ' '
- A=DAT0 B <-------+ Skip black
D0=D0+ 2 |
?A>C B |
GOYES - --------+
D0=D0- 2
CD0EX
?C<=D A
GOYES + --------+ Check against strend
C=D A |
+ A=C A <-------+
C=RSTK
D0=C ->word
C=A-C A
CSRB.F A chars
R0=C.F A
RTNCC
* Get previous word, CS if none present
EdPrevWord GOSUBL GetCurPos
SafePrevWord GOSUBL Start?
RTNC
D1=(2) STR
A=DAT1 A
B=A A ->str
D1=(2) STREND
C=DAT1 A
D=C A ->strend
PrevWord LCASC ' '
- A=DAT0 B <-------+ Skip current word
D0=D0- 2 |
?A>C B |
GOYES - --------+
- A=DAT0 B <-------+ Skip white
D0=D0- 2 |
?A<=C B |
GOYES - --------+
D0=D0+ 4
CD0EX Check against start of text
D0=C
?C<=B A
RTNYES BZZZT! No words left
RSTK=C
LCASC ' '
- D0=D0- 2 <-------+
A=DAT0 B |
?A>C B |
GOYES - --------+
D0=D0+ 2
AD0EX Check against start of text
?A>=B A
GOYES + --------+
A=B A |
+ D0=A <-------+ ->word
C=RSTK
C=C-A A
CSRB.F A
R0=C.F A
RTNCC
**********************************************************************
* In : C[A] ->str D0: CURPOS
* Out : C[A] : # of nib between CURPOS and start of (prev) word
* CARRY set if no prev word
StartOfPrvWrd B=C A ->str
LCASC ' '
- A=DAT0 B <-------+ Skip white
D0=D0- 2 |
?A<=C B |
GOYES - --------+
D0=D0+ 4
AD0EX Check against start of text
D0=A
?A<=B A
RTNYES
- D0=D0- 2 <-------+
A=DAT0 B |
?A>C B |
GOYES - --------+
D0=D0+ 2
AD0EX Check against start of text
?A>=B A
GOYES + --------+
A=B A |
+ D1=(2) CURPOS <-------+
C=DAT1 A
C=C-A A
RTNCC
**********************************************************************
* IN : C[A] ->strend D0: CURPOS
* OUT : C[A] : # of nib between CURPOS and end of next word
* CARRY set if no next word
EndOfNxtWrd B=C A ->strend
LCASC ' '
- A=DAT0 B <-------+ Skip white
D0=D0+ 2 |
?A<=C B |
GOYES - --------+
D0=D0- 2
AD0EX
D0=A
?A>=B A
RTNYES
- A=DAT0 B <-------+ Skip black
D0=D0+ 2 |
?A>C B |
GOYES - --------+
D0=D0- 2
AD0EX
?A<=B A
GOYES + --------+ Check against strend
A=B A |
+ D1=(2) CURPOS <-------+
C=DAT1 A
C=A-C A
RTNCC
**********************************************************************
* Get indent for current line
* Input: D0 = ->line R0[A] = ->textend
* Output: D0 = ->line
* A[A] = white chars
* CS if input is invalid
* Uses: B[A] C[A]
**********************************************************************
GetIndent AD0EX
D0=A
C=R0.F A ->textend
?A>=C A
RTNYES
AD0EX
B=A A ->line
D0=A
- A=DAT0 B <-------+
D0=D0+ 2 |
LCASC '\n' |
?A=C B |
GOYES + ----+ |
LCASC ' ' | |
?A<=C B | |
GOYES - ----|---+
+ D0=D0- 2 <---+ ->black or ->newline
AD0EX
C=R0.F A ->textend
?A<=C A
GOYES + ----+
A=C A | Use textend instead
+ A=A-B A <---+
ASRB.F A whites
C=B A
D0=C
RTNCC
**********************************************************************
**********************************************************************
**********************************************************************
* ED Key Wait Subroutines
**********************************************************************
**********************************************************************
**********************************************************************
* Wait for a keypress.
* Entry: sREPEAT - is repeat enabled?
* sBLINK - is blink enabled?
* sDELAY - should the keypress be delayed?
* Exit: C[A] = keycode
**********************************************************************
-- GOVLNG =AllowIntr <---+ Got key, done
- GOTO TimeoutLp <----|--+ No
| |
WaitKey | |
* Interrupts disabled here so that KEYSTATE will be valid for
* key repeats. Delay loop will update KEYSTATE as needed.
ST=0 15 | |
GOSUB PopKey | |
GONC -- --------+ | Got key
?ST=0 sREPEAT | Repeat on?
GOYES - -----------+ Yes - delay, repeat
* Delay and repeat key check.
* Here, the time of the last key is used for a delay.
* Each time through the delay loop, the current keyboard state
* is checked. If Attn, or no keys are down, exit the delay loop
* skipping the repeat key check. If current keyboard is different
* from KEYSTATE, then everything is updated (SrvcKbdAB). There is
* a check for a new key. If no new key and key(s) are still down
* when delay is done, then RepKey? checks and pops a repeat key.
* If a key is found (PopKey or RepKey?), then a key is down and
* TIMER1 is set to start keyboard peeks in 31.25 to 93.75 ms.
* This will give enough time for most key functions to complete
* and return to WaitKey before an interrupt occurs. This lets
* WaitKey service the keyboard for repeating keys instead if the
* (slow) interrupt system providing fast smooth repeat keys.
* (Like scrolling!) The keyboard is disabled during the delay
* loop and repeat check for speed.
A=R4 A
LC(5) EDSPEED
A=A+C A
D1=A
A=DAT1 S Speed flag
C=0 W
LC(3) 8192*57/1000-26 Slow repeat = 0.057s
?A=0 S
GOYES +
LC(3) 8192*15/1000-26 Fast repeat = 0.015s
+ ?ST=0 sDELAY
GOYES +
LC(3) 8192*40/100-26 New repeat = 0.40s
+ A=R3 W LastKeyTime
A=A+C W
R0=A W Delay time in R0
* Disable keyboard so SrvcKbdAB does not repeat (a speedup)
D1=(5) =aDISABLE_KBD
A=DAT1 A
D1=A
LC(1) 1
DAT1=C 1
- GOSBVL =BITMAP <------+ Keys down in A
GOC ++ | Attn? - exit (CS)
?A=0 W | Any keys down?
GOYES ++ | No - exit (CS)
D1=(5) (=IRAM@)-4 |
C=DAT1 A |
D1=(5) =aKEYSTATE | Get KEYSTATE
C=DAT1 4 | (last keyboard save)
D1=C |
C=0 W |
C=DAT1 13 | in C
?A=C W | Any change in keyboard?
GOYES + -----------+ No - check delay time
B=A W | | Yes - service keyboard
GOSBVL =SrvcKbdAB | |
GOSUB PopKey | | Any new keys?
GONC ++ | | Yes - exit (CC)
+ GOSBVL =GetTimChk <------+ No - check delay time
A=R0 |
?C<A W | Delay done?
GOYES - --------+ No - do over
GOSUB RepKey? Check for repeat keys
* Exit delay and repeat check.
* No carry means we got a key (keyboard still disabled).
++ D1=(5) =aDISABLE_KBD Enable keyboard
A=DAT1 A
D1=A
A=0 P
DAT1=A 1
GOC TimeoutLp No key!
* We have a key. The keyboard has been serviced, so set
* timer1 to start keyboard peeks between 31.25 and 93.75 ms.
* This makes for fast, smooth key repeats (like scrolling).
* (Most repeat keys will get back to WaitKey before interrupt!)
RSTK=C Save key
D1=(5) =TIMERCTRL.1
LC(1) 6 Timer1 on/rupts
DAT1=C 1
D1=(2) =TIMER2 Check timer2
A=DAT1 A
LC(1) 1
?ABIT=0 8 Less than 256 ticks?
GOYES + --------+ Yes - timer1 = 1
LC(1) 0 | No - timer1 = 0
+ D1=(2) =TIMER1 <------+
DAT1=C 1 Set timer1
C=RSTK Key in C[A]
* Turn interrupts on. Keyboard has been serviced,
* so no need for RSI in AllowIntr. RSI may cause
* an interrupt and slow things down! (Yuk!)
ST=1 15
ST=0 14
RTI Got key, done
* From this point on it's pretty much the same as GETKEY
TimeoutLp GOSBVL =settimeout Set timeout
GOSBVL =Timer1On
?ST=0 sBLINK Blink enabled?
GOYES WaitNow No
D1=(5) (=NOBLINK)+7 Yes, set blink flag
C=DAT1 A
GOSBVL =setflag
ResetT1Cnt D1=(5) (=T1COUNT#0?)+7 Set cursor count
C=DAT1 A
D1=C
LC(1) 8
DAT1=C 1
WaitNow GOSBVL =clrbusy Not busy anymore
GOSBVL =setannun Update annunciators
GOSBVL =AllowIntr
* Run card detect at slow sampling rate (power saver)
D1=(5) =CARDCTL
LC(1) 8
DAT1=C 1 [ECDT RCDT SMP SWINT]=[1000]
RSI Avoid ShutDn if Key down
?ST=1 13 Interrupted?
GOYES + -----+ Yes - Skip ShutDn
SHUTDN | Light Sleep: Keys, Timers Active
|
+ ST=0 13 <---+
GOSBVL =adjkey No keys down? Clear KEYSTATE
ST=0 15 Interrupts off
GOSUB PopKey
GONC + Got key
GOSBVL =chk_timeout Timeout?
GOC gosleep
?ST=0 sBLINK Blink enabled?
GOYES WaitNow No - skip blink
D1=(5) (=T1COUNT#0?)+7 Check cursor count
C=DAT1 A
D1=C
C=DAT1 S
?C#0 S Count = zero?
GOYES WaitNow No - skip blink
GOSUBL TogCurs Blink
GOTO ResetT1Cnt Go reset blink count
gosleep GOSUB EdDeepSleep Nighty night
ST=0 15
GOTO TimeoutLp Go back and reset timeout
+ RSTK=C Save key
D1=(5) (=NOBLINK)+7 Clear blink flag
C=DAT1 A
GOSBVL =clrflag
GOSBVL =clrtimeout
GOSBVL =showbusy Busy now
C=RSTK
GOVLNG =AllowIntr Got key, done
**********************************************************************
* Initialize timers suitably for ED
**********************************************************************
InitClk GOSBVL =DisableIntr
D1=(5) =aClkOnNib No ticking clock
A=DAT1 A
D1=A
A=0 S
DAT1=A S
GOSBVL =clrtimeout Clear timeout
P= 0 HMM!
GOVLNG =AllowIntr
**********************************************************************
* DeepSleep substitute using LoPwrShutDn, which is safer with 1M cards.
**********************************************************************
EdDeepSleep C=R4.F A
D1=C
D1=(2) EDMODE Save ST flags
C=ST
DAT1=C X
A=R4.F A
LC(5) EDRSTK
P= 16-4 Save 4 RSTK levels
A=A+C A
D1=A
- C=RSTK <-------+
DAT1=C A |
D1=D1+ 5 |
P=P+1 |
GONC - --------+
GOSUB GetptrEvalC
CON(5) =DOCOL
CON(5) =TurnOff
CON(5) =COLA
CON(5) =DOCODE
REL(5) ->EDend
* I don't trust above to keep R2 and R4 intact, thus better pop the needed
* pointers again. Stack: ( $ pos fnt1 statbuf )
* Pop fnt into R2[A]
* Pop statbuf into R4[A]
OwnDeepCont GOSBVL =SAVPTR
A=DAT1 A
LC(5) #FF+10
A=A+C A
A=0 B
R4=A.F A
D1=D1+ 5
C=DAT1 A
C=C+CON A,10
R2=C.F A
* And restore return stack and status flags
LC(5) (EDRSTK)+4*5
A=A+C A
D1=A
P= 16-4 Restore RSTK levels
- D1=D1- 5 <-------+
C=DAT1 A |
RSTK=C |
P=P+1 |
GONC - --------+
C=R4.F A
D1=C
D1=(2) EDMODE
C=DAT1 X
ST=C
RTN
GetptrEvalC C=RSTK
GOVLNG =GETPTREVALC
**********************************************************************
* See any key has been pressed, if so then disable timeout
**********************************************************************
PopKey
GOSBVL =chk_attn ATTN pressed?
GONC + No ATTN key - try keybuffer
C=0 A Clear ATTN
DAT1=C A
LC(2) ATTNCODE And return [ATTN]
GOC ++
+ GOSBVL =POPKEY
RTNC CS: No regular key
++ ST=1 sDELAY Must delay next key
RSTK=C Save the keycode
B=C A
LC(2) #3F Mask out modifiers
B=B&C B
?B=0 B Modifier key?
GOYES + Yes - skip save
* Save key for repeats. Keep two keys.
A=R4.F A
LC(3) REPSTACK
A=A+C A
D0=A
gotkey A=DAT0 B Get last key saved
C=B A
DAT0=C B Save new key
D0=D0+ 2
DAT0=A B Save old key
+ GOSBVL =GetTimChk Save time of keypress in R3
R3=C for Delay?
C=RSTK
RTNCC CC: Got key
**********************************************************************
* Handle key repeat after PopKey has failed
* Interrupts disabled on entry!!
**********************************************************************
RepKey?
* Here, KEYSTATE should have valid keyboard keystate.
* Get KEYSTATE, then clear it and use to find what keys
* are down. Pop keys and use last two saved keys to
* eliminate the latest keys popped (if more than one down).
D1=(5) (=IRAM@)-4 Get KEYSTATE
C=DAT1 A
D1=(5) =aKEYSTATE
C=DAT1 4
D1=C
A=0 W
A=DAT1 13 In A
C=0 W
DAT1=C 13 Clear KEYSTATE
B=A W KEYSTATE in A, B.
GOSBVL =SrvcKbdAB Gives max 3 modified keys
GOSBVL =POPKEY Pop first down key
RTNC CS: No repeat key
B=C A Keycode in B[A]
LC(2) #C0 Save modifiers
C=C&B B
D=C A in D[B]
LC(2) #3F Mask out modifiers
B=B&C B in B[B]
?B=0 B Modifier key only?
RTNYES Yes - CS
A=R4.F A
LC(3) REPSTACK
A=A+C A Put saved keys at D0
D0=A Unused by POPKEY
- GOSBVL =POPKEY Any more keys down?
GONC + Yes
* Valid keycode (minus modifier) in B[B], modifier in D[B]
C=B A Key code (minus modifier)
C=C!D B Add modifier
ST=0 sDELAY No delay for this key
RSTK=C Save the keycode
GOTO gotkey Got key, go save
* Come here if we have more than one key down.
* One in B[B] (minus modifier) and new one in C[B].
* Mask out modifier and eliminate last key popped.
* This will help multiple key repeats to repeat in
* the correct order.
+ A=C A New keycode in A[B]
LC(2) #3F Mask out modifier
C=C&A B
A=DAT0 A Get last two saved keys
?C=A B C[B] same as last key?
GOYES - Yes - keep B[B], try again
?B=A B B[B] same as last key?
GOYES + Yes - go save to B[B]
ASR A No match for last key.
ASR X Try next to last key.
?B#A B B[B] same as next to last
GOYES - No - keep B[B], try again
+ B=C A save C[B] to B[B]
GOTO - Try again
**********************************************************************
* Move key to B[B] from C[B]
* Get plane to B[XS]
* Remove shifts B[B]
* Reset LS&RS states
**********************************************************************
AdjustKey
* Changes to plane when
* modifier is held down:
*
* Held
* Old NS LS RS A
* +----------------
* NS | NS LS RS ANS
* LS | RS ALS
* RS | LS ARS
* ANS | ALS ARS
* ALS | ARS
* ARS | ALS
* Old:
* B=C A
* A=0 A
* A=B B
* LC(2) #3F
* A=A&C B
* ?A=0 B
* RTNYES
* ABEX B
* ASR B
* New by Dan:
B=C A
A=C A
LC(2) #3F
B=B&C B
* Ignore adjust if only LS or RS down
?B#0 B Modifier only?
GOYES + No
B=A A KeyCode
LC(2) =ALPHACODE
?B#C B Alpha key?
RTNYES No
* Only alpha key down. KeyCode in B,
* clear A, and treat as non-modifier key.
LC(2) 30
B=C A
A=0 A
+ ASR B [xxMMxxxx]
* [xx00xxxx] = NS, [xx10xxxx] = LS, [xx01xxxx] = A, [xx11xxxx] = RS
* Continue old:
D0=(5) =aANNUNCIATORS
C=DAT0 A
D0=C
C=DAT0 B [xxxxLRAx]
CBIT=0 7
C=0 P
A=A!C B [xxMMLRAx]
ASRB.F B
ASRB.F B [MMLRAxxx], 0-3 = {NS LS A RS}
* Clear old LS & RS
C=DAT0 B
CBIT=0 4
CBIT=0 5
* Clear old alpha if alpha key down
?ABIT=0 1 Alpha key?
GOYES + No - skip
?ABIT=1 0 Shift key?
GOYES + Yes - skip
CBIT=0 6
+ DAT0=C B
GOSUB PassModTab
* NLAR
NIBHEX 1243 NS
NIBHEX 2253 LS
NIBHEX 3263 RS
NIBHEX 0000 LRS!
NIBHEX 4546 ANS
NIBHEX 5556 ALS
NIBHEX 6566 ARS
NIBHEX 0000 ALRS!
* NLAR
PassModTab
C=RSTK
A=A+C A
D0=A
A=DAT0 XS
B=A XS
RTN
**********************************************************************
**********************************************************************
**********************************************************************
* Default Character and String Tables
**********************************************************************
**********************************************************************
EdChrKey?
A=B XS
A=A-1 XS
GOC notchrky
GOSUB GetChrPlane
A=0 A
A=B B
A=A+A A
A=A+C A
D0=A
D0=D0- 2
C=DAT0 B
?C#0 B
RTNYES
notchrky RTNCC
GetChrPlane GOSUB PassPlane1
NIBHEX 000000000000 | |
NIBHEX 000000000000 | |
NIBHEX 720000000000 |' |
NIBHEX 00000038E500 | /^ |
NIBHEX 0000000000 | |
NIBHEX 00738393F2 | 789/|
NIBHEX 00435363A2 | 456*|
NIBHEX 00132333D2 | 123-|
NIBHEX 0003E202B2 | 0. +|
PassPlane1 C=RSTK
A=A-1 XS
RTNC
GOSUB PassPlane2
NIBHEX 000000000000 | |
NIBHEX 000000000000 | |
NIBHEX 000000000000 | |
NIBHEX 000000000000 | |
NIBHEX 0000000000 | |
NIBHEX 0000000082 | (|
NIBHEX 00000000B5 | [|
NIBHEX 00000000B7 | {|
NIBHEX 00D3C2C9D7 | =,x}|
PassPlane2 C=RSTK
A=A-1 XS
RTNC
GOSUB PassPlane3
NIBHEX 000000000000
NIBHEX 000000000000
NIBHEX 000000000000
NIBHEX 884858000000
NIBHEX 0000000000
NIBHEX 0000000032
NIBHEX 00000000F5
NIBHEX 0000000000
NIBHEX 0000A09000
PassPlane3 C=RSTK
A=A-1 XS
RTNC
GOSUB PassPlane4
NIBHEX 142434445464
NIBHEX 748494A4B4C4
NIBHEX D4E4F4051525
NIBHEX 354555657585
NIBHEX 0095A50000
NIBHEX 00738393F2
NIBHEX 00435363A2
NIBHEX 00132333D2
NIBHEX 0003E202B2
PassPlane4 C=RSTK
A=A-1 XS
RTNC
GOSUB PassPlane5
NIBHEX 162636465666
NIBHEX 768696A6B6C6
NIBHEX D6E6F6071727
NIBHEX 374757677787
NIBHEX 6297A712F3
NIBHEX 002F485892
NIBHEX 00423A4AD5
NIBHEX 0000C39800
NIBHEX 00D3B37800
PassPlane5 C=RSTK
A=A-1 XS
RTNC
GOSUB PassPlane6
NIBHEX C8FDB9293959
NIBHEX 1949F9C70969
NIBHEX 725BD9E8F879
NIBHEX 899952E7A918
NIBHEX 041BC90000
NIBHEX 00E7C7C532
NIBHEX 002A5A0BF5
NIBHEX 00B8E3A822
NIBHEX 00D8A090A3
PassPlane6 C=RSTK
RTN
**********************************************************************
EdStrKey?
A=PC
LC(5) (strkeytab)-(*)
A=A+C A
D0=A
strkylp C=DAT0 4
D0=D0+ 3
?C=0 X
GOYES retnotstr
?C=B X
GOYES retisstr
P=C 3
CD0EX
C+P+1
C+P+1
CD0EX
GONC strkylp
retnotstr P= 0
RTNCC
retisstr P= 0
RTNSC
* KEY(3) CHRS(1) CHRS SKIP(1)
EDSKEY MACRO
CON(3) $1
ASC(1) $2
CON(1) $3
EDSKEY ENDM
strkeytab
EDSKEY (=1CODE)+(ALS),'==',2
EDSKEY (tickCODE)+(NS),\''\,1
EDSKEY (DIVCODE)+(LS),'()',1
EDSKEY (DIVCODE)+(ALS),'()',1
EDSKEY (TIMESCODE)+(LS),'[]',1
EDSKEY (TIMESCODE)+(ALS),'[]',1
EDSKEY (MINUSCODE)+(LS),'\xAB\xBB',1
EDSKEY (MINUSCODE)+(RS),'""',1
EDSKEY (MINUSCODE)+(ARS),'""',1
EDSKEY (PLUSCODE)+(LS),'{}',1
EDSKEY (PLUSCODE)+(RS),'::',1
EDSKEY (EVALCODE)+(NS),'EVAL ',5
EDSKEY (SINCODE)+(NS),'SIN ',4
EDSKEY (SINCODE)+(LS),'ASIN ',5
EDSKEY (COSCODE)+(NS),'COS ',4
EDSKEY (COSCODE)+(LS),'ACOS ',5
EDSKEY (TANCODE)+(NS),'TAN ',4
EDSKEY (TANCODE)+(LS),'ATAN ',5
EDSKEY (SQRTCODE)+(LS),'SQ ',3
EDSKEY (SQRTCODE)+(RS),'XROOT ',6
EDSKEY (POWERCODE)+(LS),'ALOG ',5
EDSKEY (POWERCODE)+(RS),'LOG ',4
EDSKEY (INVCODE)+(NS),'INV ',4
EDSKEY (INVCODE)+(LS),'EXP ',4
EDSKEY (INVCODE)+(RS),'LN ',3
EDSKEY (EEXCODE)+(LS),'PURGE ',6
CON(3) 0
**********************************************************************
* Memory block swap utility for operating in low memory
* In: D0=->BLK1 D1=->BLK2 C[A]=NIBS2
* Used: A[W] C[W] B[A] D[A] D0 D1
**********************************************************************
EdBLKswap B=C A
EdBLKswaplp
?B=0 A
RTNYES
AD0EX
D0=A
CD1EX
D1=C
C=C-A A NIBS1
?C=0 A
RTNYES
?B<=C A
GOYES edblkswp1
* NIBS1<NIBS2
A=C A
A=0 P
?A=0 A
GOYES edblkswp1P
B=B-C A
GOSUB Edblkswap
GONC EdBLKswaplp
* NIBS1>=NIBS2
edblkswp1
A=B A
A=0 P
?A=0 A
GOYES edblkswp2P
C=B A
GOSUB Edblkswap
CD1EX
C=C-B A
CD1EX
GONC EdBLKswaplp
* 0 < NIBS1 < 16
edblkswp1P
CSRC C[S]=1-15
C=DAT0 15
CD0EX
CD1EX
CD0EX
CBEX A
GOSBVL =MOVEDOWN
C=B A
P=C 15
P=P-1
DAT1=C WP
P= 0
RTNCC
* 0 < NIBS2 < 16
edblkswp2P
CD1EX
D0=C
C=C+B A
CD1EX
CBEX A
CSRC
C=DAT0 15
CBEX A
GOSBVL =MOVEUP
C=B A
P=C 15
P=P-1
DAT0=C WP
P= 0
RTNCC
**********************************************************************
Edblkswap C=C-1 A
GOC Edblkswapped
P=C 0
CSR A
D=C A
D=D-1 A
GOC Edblkswapwp
Edblkswaplp
A=DAT0 W
C=DAT1 W
DAT0=C W
DAT1=A W
D0=D0+ 16
D1=D1+ 16
D=D-1 B
GONC Edblkswaplp
D=D-1 XS
GONC Edblkswaplp
D=D+1 X
D=D-1 A
GONC Edblkswaplp
Edblkswapwp
A=DAT0 WP
C=DAT1 WP
DAT0=C WP
DAT1=A WP
CD0EX
C+P+1
D0=C
CD1EX
C+P+1
D1=C
Edblkswapped P= 0
RTNCC
**********************************************************************
* Pop stack arguments and initialize all variables
* Stack: ( $ #pos fnt1 statbuf )
**********************************************************************
InitBuf
* Pop string
GOSBVL =D0=DSKTOP
D0=D0+ 15
A=DAT0 A
A=A+CON A,5
D1=A
C=DAT1 A Strlen
?CBIT=1 0 Error if odd number of nibbles
GOYES +
LC(5) =SYNTAXERR
GOVLNG =GETPTREVALC
+
C=C+A A Strend
R0=C Save it
* Expand string
GOSBVL =ROOM
A=C A
ABIT=0 0
LC(5) EDMINMEM
A=A-C A
GONC expok
GOVLNG =GPMEMERR
expok R1=A Save free
C=DAT1 A Fix $LEN
C=C+A A
DAT1=C A
C=R0 Fix $LINK
D1=C
C=DAT1 A
C=C+A A
DAT1=C A
C=A A
AD1EX
GOSBVL =MOVERSU
* Pop data buffer
GOSBVL =D1=DSKTOP
A=DAT1 A
LC(5) #FF+10
A=A+C A
A=0 B
R4=A.F A
D0=A
* Pop font
D1=D1+ 5
A=DAT1 A
A=A+CON A,10
R2=A.F A
* Pop position
D1=D1+ 5
GOSBVL =POP#
B=A A wanted pos
* Setup pointers
A=DAT1 A
A=A+CON A,10 ->$BODY
D0=(2) STR
DAT0=A A
D0=(2) CURPOS
DAT0=A A
D0=(2) TOPPOS
DAT0=A A
D0=(2) STREND
C=R0
DAT0=C A
D0=(2) CUT
A=R1
A=A+C A
DAT0=A A
D0=(2) MEMEND
DAT0=A A
?B=0 A
RTNYES Didn't want anything
D0=(2) CURPOS
A=DAT0 A
A=A+B A
GOC +
A=A+B A
GOC +
C=R0 strend
?A<=C A
GOYES ++
+ A=C A start from strend instead
++ D0=A
GOLONG ToThisD0
**********************************************************************
->EDend
ENDCODE
* Done if there are no subjobs
NOTcase 3DROP
* There is a subjob to do: ( $ #pos font data ? .. ? #subcommand )
Ed#STK #=casedrop DoEdStack
* Should not reach here!
;
**********************************************************************
* ED [STK] key was pressed
* Start SOL, exit back to ED when CONT key is pressed
* Stack: ( $ #pos font data #pos' )
**********************************************************************
NULLNAME DoEdStack
::
4UNROLL 3DROP ( $ #pos' )
( Save internal variables due to ED )
DEPTH UStackDepth #- ZERO CACHE
( Start SOL replacement )
ERRSET
::
SAVESTACK ( Save user stack regardless of mode )
BEGIN
AtUserStack ( Validate user stack )
SysMenuCheck ( Menu maintenance )
SysDisplay ( System Display )
GetKeyOb ( Wait for a key )
ERRSET DoKeyOb ( Execute the key )
ERRTRAP
::
NOP ( Validate for ASS error messages )
FixStk&Menu
ERROR@ ZERO #=casedrop SysErrFixUI
Err#Cont #=casedrop
::
HALTTempEnv? caseERRJMP
SysErrFixUI RSKIP TRUE
;
Err#Kill #=casedrop DoCont/Kill
#CAlarmErr #=case ProcessAlarm
LastRomWord@ ERROR@
SysErrFixUI ERRBEEP
TOADISP UnScroll SetDA1Temp
MakeErrMesg DISPROW1 DISPROW2
;
FALSE
UNTIL
UNDO_TOP? IT ABND ( Dump the saved stack )
;
ERRTRAP ERRJMP
( Restart )
ZERO DUMP ABND DROP TOADISP TURNMENUOFF COLA DoEd
;
**********************************************************************