-
Notifications
You must be signed in to change notification settings - Fork 0
/
EDITOR.inc
225 lines (179 loc) · 7.09 KB
/
EDITOR.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
;-----------------------------------------------------------------------------
.proc Editor
;-----------------------------------------------------------------------------
@t: .data 0 ; Temporary hold variable
@s: .data 0 ; Source for moving
@d: .data 0 ; Destination for moving
@p: .data 0 ; Pointer for moving
@ch: .data 0 ; Character for moving
@len: .data 0 ; Length of the line to be inserted
@arraylen: .data 0 ; Length of the array
@blocklen: .data 0 ; Length of the block to be manipulated
@msgAtLine: .data $+1,"\r\nAt line\r\n",0
@msgReplace: .data $+1,"\r\nReplace line\r\n",0
@msgAtEnd: .data $+1,"\r\nInsert at end\r\n",0
CalculateArrayLength:
PUSH CONST_MAXINT ; Calculate the length of the program array in use by searching for the last
CALL FindLine ; possible line number resulting in a pointer to the final "zero" line number
MOV pFound @arraylen ; The length is the found location minus the start location plus 1
program_ @arraylen
INC @arraylen
RET
CalculateLineLength:
POP @t ; Pop off the return address and parameters
CALL FindLine ; Here I still have the target line number on the stack
PUSH @t ; Push the return address back onto the stack
MOV pFound @t ; Calculate the length of the line.
INC @t ; Do this by taking the offset to the next line and add two
INDEXEDRD @t @blocklen ; ... to ajust for the line number and the offset itself
ADD CONST_2 @blocklen
RET
CalculateBufLength:
MOV pCode @t
CLR @blocklen
@loopBL:
INDEXEDRD @t @ch
CMPEQ @ch CONST_0 @doneBL
INC @t
INC @blocklen
JMP @loopBL
@doneBL:
RET
;-----------------------------------------------------------------------------
; Editor
;-----------------------------------------------------------------------------
Editor:
; PRINTCRLF
PUSH tokenValue ; Check if the specified line number already exists
CALL FindLine
INDEXEDRD pFound lineNo ; The FindLine can get the next larger number if the exact
; number is not found so we need to load the actual found number
CMPNE tokenValue lineNo @insert ; If the line number is not found, the user wants insert a new line
; If the line number is found, the user wants to replace or delete it.
; Start by deleting the line and then insert the new line if the user wants to replace it.
CALL CalculateArrayLength
PUSH lineNo
CALL CalculateLineLength
MOV pFound @t
SUB program_ @t
PUSH program ; Point to start of the array to manipulate
PUSH @arraylen ; Total length of the array
PUSH @t ; Offset into the array where the manipulated block starts
PUSH @blocklen ; Length of the manipulated block
CALL DeleteBlock
; The old line is now deleted. So now we can insert the new line if the user wants to replace it.
; But we first check if the new line is empty, we then just return to the prompt.
@insert:
CALL CalculateArrayLength
CALL CalculateBufLength
CMPEQ @blocklen CONST_0 @done
PUSH tokenValue ; Check if the specified line number already exists
CALL FindLine
ADD CONST_3 @blocklen ; Add three to the length to make room for the line number and the offset to the next line
MOV pFound @t
SUB program_ @t
PUSH program ; Point to start of the array to manipulate
PUSH @arraylen ; Total length of the array
PUSH @t ; Offset into the array where the manipulated block starts
PUSH @blocklen ; Length of the manipulated block
CALL InsertBlock
INDEXEDWR tokenValue pFound ; Write the line number
INC pFound
DEC @blocklen ; Adjust the length/offset
DEC @blocklen
INDEXEDWR @blocklen pFound ; Write the offset to the next line
INC pFound
MOV pCode @t
DEC @blocklen
@loopIB:
INDEXEDRD @t @ch
INDEXEDWR @ch pFound
INC @t
INC pFound
JMPN0 @ch @loopIB
@done:
JMP Prompt
.endp
;-----------------------------------------------------------------------------
.proc DeleteBlock
;-----------------------------------------------------------------------------
@t: .data 0 ; Temporary hold variable
@arrayStart: .data 0
@arraySize: .data 0
@delStartOffset:.data 0
@delLen: .data 0
@ch: .data 0
@pD: .data 0
@pS: .data 0
@cnt: .data 0
DeleteBlock:
POP @t ; Pop off the return address and parameters
POP @delLen
POP @delStartOffset
POP @arraySize
POP @arrayStart
PUSH @t ; Push the return address back onto the stack
MOV program_ @pD
ADD @delStartOffset @pD
MOV @pD @pS
ADD @delLen @pS
MOV @arraySize @cnt
@delStartOffset @cnt
@delLen @cnt
@delLoop:
INDEXEDRD @pS @ch
INDEXEDWR @ch @pD
INC @pS
INC @pD
DEC @cnt
JMPN0 @cnt @delLoop
MOV @delLen @cnt
@fill0Loop:
INDEXEDWR CONST_0 @pD
INC @pD
DEC @cnt
JMPN0 @cnt @fill0Loop
RET
.endp
;-----------------------------------------------------------------------------
.proc InsertBlock
;-----------------------------------------------------------------------------
@t: .data 0 ; Temporary hold variable
@arrayStart: .data 0
@arraySize: .data 0
@insStartOffset:.data 0
@insLen: .data 0
@ch: .data 0
@pD: .data 0
@pS: .data 0
@cnt: .data 0
InsertBlock:
POP @t ; Pop off the return address and parameters
POP @insLen
POP @insStartOffset
POP @arraySize
POP @arrayStart
PUSH @t ; Push the return address back onto the stack
MOV program_ @pD ; destination = startOfArray + lengthOfArray + lengthOfInsert
ADD @arraySize @pD
ADD @insLen @pD
MOV program_ @pS ; source = startOfArray + lengthOfArray
ADD @arraySize @pS
MOV @arraySize @cnt ; length = lengthOfArray - startOfInsert + 1
@insStartOffset @cnt
INC @cnt
@insLoop:
INDEXEDRD @pS @ch
INDEXEDWR @ch @pD
DEC @pS
DEC @pD
DEC @cnt
JMPN0 @cnt @insLoop
MOV @insLen @cnt
@fill0Loop:
INDEXEDWR CONST_0 @pD
DEC @pD
DEC @cnt
JMPN0 @cnt @fill0Loop
RET
.endp