chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Sapphire / sail / _s / termite
1 ;
2 ; termite.s
3 ;
4 ; Implementation of Termite specific instructions
5 ;
6 ; © 1995 Straylight
7 ;
8
9 ;----- Standard header ------------------------------------------------------
10
11                 GET     libs:header
12                 GET     libs:swis
13
14                 GET     libs:stream
15
16 ;----- External dependencies ------------------------------------------------
17
18                 GET     sh.anchor
19                 GET     sh.ctrl
20                 GET     sh.errNum
21                 GET     sh.error
22                 GET     sh.express
23                 GET     sh.getToken
24                 GET     sh.interp
25                 GET     sh.stracc
26                 GET     sh.strBucket
27                 GET     sh.termscript
28                 GET     sh.tokens
29                 GET     sh.upcalls
30                 GET     sh.var
31
32 ;----- Main code ------------------------------------------------------------
33
34                 AREA    |TermScript$$Code|,CODE,READONLY
35
36 ; --- termite_beep ---
37
38                 EXPORT  termite_beep
39 termite_beep    ROUT
40
41                 TCALL   termite_makeBeep        ;Make a beep
42                 B       interp_next             ;And go for more
43
44                 LTORG
45
46 ; --- termite_break ---
47
48                 EXPORT  termite_break
49 termite_break   ROUT
50
51                 TCALL   termite_sendBreak       ;Send the break
52                 BL      termite__error          ;Handle possible error
53                 B       interp_next             ;And go for more
54
55                 LTORG
56
57 ; --- termite_call ---
58
59                 EXPORT  termite_call
60 termite_call    ROUT
61
62                 BL      ctrl_setUpRegs          ;Set up the regs then
63
64                 CMP     R10,#vType_integer      ;Is this an integer?
65                 MOVNE   R0,#err_numNeeded       ;No -- get error number
66                 BNE     error_report            ;...and report the error
67
68                 MOV     R14,PC                  ;Set up return address
69                 MOV     PC,R9                   ;Execute the code
70
71                 LDR     R9,=termite__retned     ;Point to some space
72                 STMIA   R9!,{R0-R8}             ;Store returned registers
73                 MOV     R14,PC,LSR #28          ;Get the flags
74                 STMIA   R9,{R14}                ;Strore the flags too
75                 LDMFD   R13!,{R7-R12}           ;Load back position info
76                 LDMFD   R13!,{R0}               ;Load stracc offset
77                 BL      stracc_free             ;Free any strings I had
78
79                 ; --- We have now done the SWI instr ---
80
81                 LDR     R0,=termite__retned     ;Point to the returned regs
82                 BL      ctrl_resolveRegs        ;Do the other half now
83                 B       interp_next             ;If flags -- return
84
85                 LTORG
86
87 ; --- termite_chain ---
88
89                 EXPORT  termite_chain
90 termite_chain   ROUT
91
92                 ; --- Read a parameter ---
93
94                 MOV     R0,#0                   ;Read an rvalue
95                 BL      express_read            ;Read it then
96                 BL      express_pop             ;And get it off the stack
97                 CMP     R1,#vType_string        ;Is this a string?
98                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
99                 BNE     error_report            ;...and report the error
100
101                 LDR     R1,tsc_stracc           ;Get the stracc address
102                 LDR     R1,[R1]
103                 ADD     R1,R1,R0,LSR #8         ;Point to the string
104                 AND     R2,R0,#&FF              ;Get the length
105
106                 ADR     R0,tsc_misc+8*4         ;Point to the misc buffer
107                 BL      termite_copyString      ;Copy the string over
108                 B       tsc_end                 ;End the script, and chain
109
110                 LTORG
111
112 ; --- termite_close ---
113
114                 EXPORT  termite_close
115 termite_close   ROUT
116
117                 MOV     R0,#-1                  ;Close the session
118                 B       tsc_end                 ;Do that then
119
120                 LTORG
121
122 ; --- termite_cls ---
123
124                 EXPORT  termite_cls
125 termite_cls     ROUT
126
127                 TCALL   termite_clearScreen     ;Clear the screen
128                 BL      termite__error          ;Handle possible error
129                 B       interp_next             ;And go for more
130
131                 LTORG
132
133 ; --- termite_download ---
134
135                 EXPORT  termite_download
136 termite_download ROUT
137
138                 MOV     R0,#0                   ;Read an rvalue
139                 BL      express_read            ;Read it then
140                 BL      express_pop             ;And get it off the stack
141                 CMP     R1,#vType_string        ;Is this a string?
142                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
143                 BNE     error_report            ;...and report the error
144
145                 ; --- Null terminate this ---
146
147                 MOV     R2,R0                   ;Look after the offset
148                 MOV     R5,#0                   ;Useful, t' be sure
149                 BL      stracc_ensure           ;Ensure we have space
150                 STRB    R5,[R0,#0]              ;Terminate the string
151                 ORR     R0,R1,#1                ;Get the rvalue
152                 BL      stracc_added            ;Tell stracc about terminator
153
154                 ; --- Check for another string ---
155
156                 CMP     R9,#','                 ;Do we have a comma?
157                 MOVNE   R3,#0                   ;No -- use default then
158                 BNE     %10termite_download     ;...and jump ahead
159
160                 BL      getToken                ;Skip over the comma
161                 MOV     R0,#0                   ;Read an rvalue
162                 BL      express_read            ;Read it then
163                 BL      express_pop             ;And get it off the stack
164                 CMP     R1,#vType_string        ;Is this a string?
165                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
166                 BNE     error_report            ;...and report the error
167
168                 ; --- Null terminate this ---
169
170                 MOV     R3,R0                   ;Look after the offset
171                 MOV     R5,#0                   ;Useful, t' be sure
172                 BL      stracc_ensure           ;Ensure we have space
173                 STRB    R5,[R0,#0]              ;Terminate the string
174                 ORR     R0,R1,#1                ;Get the rvalue
175                 BL      stracc_added            ;Tell stracc about terminator
176
177                 ; --- Do the download now ---
178
179 10              LDR     R1,tsc_stracc           ;Load stracc address
180                 MOV     R4,R2                   ;Look after the offet
181                 ADD     R2,R1,R2                ;Point to protocal name
182                 CMP     R3,#0                   ;Do we have a filename?
183                 ADDNE   R3,R1,R3                ;Yes -- point to it then
184                 TCALL   termite_downLoad        ;Do the download
185                 BL      termite__error          ;Handle possible error
186                 MOV     R0,R4                   ;Get offset of protocol name
187                 BL      stracc_free             ;Free it now
188                 B       interp_next             ;Do another instruction
189
190                 LTORG
191
192 ; --- termite_error ---
193
194                 EXPORT  termite_error
195 termite_error   ROUT
196
197                 CMP     R9,#tok_on              ;Is this an option?
198                 CMPNE   R9,#tok_off
199                 BEQ     %50termite_error        ;Yes -- jump ahead
200
201                 ; --- Read a parameter ---
202
203                 MOV     R0,#0                   ;Read an rvalue
204                 BL      express_read            ;Read it then
205                 BL      express_pop             ;And get it off the stack
206                 CMP     R1,#vType_string        ;Is this a string?
207                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
208                 BNE     error_report            ;...and report the error
209
210                 LDR     R1,tsc_stracc           ;Get the stracc address
211                 LDR     R1,[R1]
212                 ADD     R1,R1,R0,LSR #8         ;Point to the string
213                 AND     R2,R0,#&FF              ;Get the length
214
215                 MOV     R5,R0                   ;look after the rvalue
216                 ADR     R0,tsc_misc             ;Point to the misc buffer
217                 MOV     R14,#1                  ;A sillu error number
218                 STR     R14,[R0],#4             ;Store that
219                 BL      termite_copyString      ;Copy the string over
220                 ADR     R0,tsc_misc             ;Point to the misc buffer
221                 B       tsc_error               ;Return the error
222
223                 ; --- There was an option ---
224
225 50termite_error LDR     R0,tsc_flags            ;Load the flags word
226                 CMP     R9,#tok_on              ;Turn on the errors?
227                 ORREQ   R0,R0,#tscFlag_error    ;Yes -- set the bit then
228                 BICEQ   R0,R0,#tscFlag_error    ;No -- clear it then
229                 STR     R0,tsc_flags            ;Store the flags back
230                 BL      getToken                ;Skip over the token
231                 B       interp_next             ;Do the next one
232
233                 LTORG
234
235 ; --- termite_exec ---
236
237                 EXPORT  termite_exec
238 termite_exec    ROUT
239
240                 ; --- Read a parameter ---
241
242                 MOV     R0,#0                   ;Read an rvalue
243                 BL      express_read            ;Read it then
244                 BL      express_pop             ;And get it off the stack
245                 CMP     R1,#vType_string        ;Is this a string?
246                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
247                 BNE     error_report            ;...and report the error
248
249                 LDR     R1,tsc_stracc           ;Get the stracc address
250                 LDR     R1,[R1]
251                 ADD     R1,R1,R0,LSR #8         ;Point to the string
252                 AND     R2,R0,#&FF              ;Get the length
253
254                 MOV     R5,R0                   ;look after the rvalue
255                 ADR     R0,tsc_misc+8*4         ;Point to the misc buffer
256                 BL      termite_copyString      ;Copy the string over
257                 MOV     R0,R5                   ;Get the rvalue
258                 BL      stracc_free             ;Free the string from stracc
259                 ADR     R0,tsc_misc+8*4         ;Point to the misc buffer
260                 ORR     R0,R0,#(1<<30)          ;Make this into an exec
261                 BL      tsc_end                 ;Exec new script
262                 B       interp_next             ;Continue happily
263
264                 LTORG
265
266 ; --- termite_finish ---
267
268                 EXPORT  termite_finish
269 termite_finish  ROUT
270
271                 TCALL   termite_finishSession   ;Finish the session
272                 B       interp_next             ;And go round for more
273
274                 LTORG
275
276 ; --- termite_hangup ---
277
278                 EXPORT  termite_hangup
279 termite_hangup  ROUT
280
281                 TCALL   termite_dropCarrier     ;Hang up the modem
282                 B       interp_next             ;And go for more
283
284                 LTORG
285
286 ; --- termite_lclear ---
287
288                 EXPORT  termite_lclear
289 termite_lclear  ROUT
290
291                 TCALL   termite_clearLocal      ;Clear the buffer
292                 B       interp_next             ;And go for more
293
294                 LTORG
295
296 ; --- termite_lecho ---
297
298                 EXPORT  termite_lecho
299 termite_lecho   ROUT
300
301                 CMP     R9,#tok_off             ;Is this an option thingy?
302                 CMPNE   R9,#tok_local
303                 CMPNE   R9,#tok_remote
304                 CMPNE   R9,#tok_both
305                 BEQ     %50termite_lecho        ;Yes -- deal seperately
306
307                 ; --- Just echo the result to the screen then ---
308
309                 MOV     R0,#0                   ;Read an rvalue
310                 BL      express_read            ;Read the next expression
311                 BL      express_pop             ;Get the value in R0,R1
312                 CMP     R1,#vType_integer       ;Is this an integer?
313                 BEQ     %10termite_lecho        ;Yes -- jump ahead
314                 CMP     R1,#vType_string        ;Or a string?
315                 MOVNE   R0,#err_arrayBad
316                 BNE     error_report
317
318                 ; --- Display a string ---
319
320                 LDR     R2,tsc_stracc           ;Get the stracc address
321                 LDR     R2,[R2]
322                 ADD     R2,R2,R0,LSR #8         ;Point to the string
323                 AND     R3,R0,#&FF              ;Get the length
324                 BL      termite__doSpool        ;Maybe spool this lot
325                 TCALL   termite_sendLocal       ;Write out the message
326                 BL      termite__error          ;Handle possible error
327                 BL      stracc_free             ;Free the string from stracc
328                 B       %20termite_lecho        ;Jump ahead
329
330                 ; --- Display an integer on the screen ---
331
332 10termite_lecho ADR     R1,tsc_misc             ;Point to a nice buffer
333                 MOV     R2,#256                 ;The buffer is big
334                 SWI     OS_ConvertInteger4      ;Convert the number to a str
335                 SUB     R3,R1,R0                ;Get the length
336                 MOV     R2,R0                   ;Point at the block
337                 BL      termite__doSpool        ;Maybe spool this lot
338                 TCALL   termite_sendLocal       ;Write out the message
339                 BL      termite__error          ;Handle possible error
340
341                 ; --- Maybe write out the return char ---
342
343 20termite_lecho CMP     R9,#';'                 ;Is there a semicolon now?
344                 BLEQ    getToken                ;Yes -- get a token
345                 BEQ     interp_next             ;...read another instr
346
347                 LDR     R2,tsc_bucket           ;Get the bucket anchor
348                 LDR     R2,[R2]
349                 LDR     R0,tsc_lnewline         ;Load the newline offset
350                 CMP     R0,#0                   ;Is there one?
351                 BEQ     interp_next             ;No -- stop here then
352                 ADD     R2,R2,R0                ;Point to the string
353                 LDRB    R3,[R2,#-1]             ;Load out the length
354                 BL      termite__doSpool        ;Maybe spool this lot
355                 TCALL   termite_sendLocal       ;Write out the terminator
356                 BL      termite__error          ;Handle possible error
357                 B       interp_next             ;And read another instruction
358
359                 ; --- Handle the options ---
360
361 50termite_lecho LDR     R0,tsc_flags            ;Load the flags word
362                 BIC     R0,R0,#tscFlag_echoLR+tscFlag_echoLL
363                 CMP     R9,#tok_local           ;Do we require local echoing?
364                 CMPNE   R9,#tok_both
365                 ORREQ   R0,R0,#tscFlag_echoLL   ;Yes -- set the flag
366                 CMP     R9,#tok_remote          ;Do we require remote echos?
367                 CMPNE   R9,#tok_both
368                 ORREQ   R0,R0,#tscFlag_echoLR   ;Yes -- set the flag
369                 STR     R0,tsc_flags            ;Store back the flags word
370                 BL      getToken                ;Get another token
371
372                 B       interp_next             ;Keep on going then!
373
374                 LTORG
375
376 ; -- termite_linput ---
377
378                 EXPORT  termite_linput
379 termite_linput  ROUT
380
381                 MOV     R0,#1                   ;Read an lvalue
382                 BL      express_read            ;Read it in
383
384                 ; --- Now enter a string reading loop ---
385
386                 BL      stracc_ensure           ;Make sure that there's room
387                 MOV     R2,R0                   ;Look after address
388                 MOV     R4,R0                   ;Twice
389                 MOV     R5,#0                   ;The length so far
390                 MOV     R3,#1                   ;Length of buffer to echo
391
392 00
393                 TCALL   termite_readLocal       ;Read a byte from the buffer
394                 CMP     R0,#-1                  ;Was there one?
395                 BLEQ    tsc_wait                ;No -- wait for it then
396                 LDREQ   R2,tsc_stracc
397                 LDREQ   R2,[R2]
398                 ADDEQ   R2,R2,R1,LSR #8
399                 ADDEQ   R2,R2,R5
400                 BEQ     %b00
401                 CMP     R0,#127                 ;Is this a delete?
402                 CMPNE   R0,#8
403                 BEQ     %f05                    ;Yes -- deal with that then
404                 CMP     R0,#32                  ;Was it valid?
405                 STRGEB  R0,[R2,#0]              ;Yes -- store the byte
406                 BLGE    termite_doLEcho         ;Echo the buffer
407                 ADDGE   R2,R2,#1                ;Increment the pointer
408                 ADDGE   R5,R5,#1                ;Increment the length
409                 CMP     R0,#13                  ;Are we finished?
410                 CMPNE   R5,#256
411                 BLT     %b00                    ;No -- get some more then
412                 B       %f10                    ;Finished -- jump ahead
413
414                 ; --- Do a delete operation ---
415
416 05              CMP     R5,#0                   ;Is the buffer empty?
417                 BLE     %b00                    ;Yes -- do nothing
418                 MOV     R14,#8                  ;Get a backspace
419                 STRB    R14,[R2,#0]             ;Store it...
420                 STRB    R14,[R2,#2]             ;In two places
421                 MOV     R14,#32                 ;And a space too
422                 STRB    R14,[R2,#1]             ;Put that in the middle
423                 MOV     R3,#3                   ;Send 3 characters
424                 BLGE    termite_doLEcho         ;Echo the buffer
425                 SUB     R2,R2,#1                ;Reduce the address
426                 SUB     R5,R5,#1                ;And the number of chars
427                 MOV     R3,#1                   ;Put R3 back to 1
428                 B       %b00                    ;Join main loop again
429
430                 ; --- We have finished reading the string ---
431
432 10              ORR     R0,R1,R5                ;Get the rvalue
433                 MOV     R1,#vType_string        ;This is a string
434                 BL      stracc_added            ;Tell stracc about this
435                 MOV     R3,R1                   ;Move these up a little
436                 MOV     R2,R0
437                 BL      express_pop             ;Get my lvalue off
438                 BL      ctrl_store              ;Store this away
439                 B       interp_next             ;Do another command
440
441                 LTORG
442
443 ; --- termite_lnewline ---
444
445                 EXPORT  termite_lnewline
446 termite_lnewline ROUT
447
448                 CMP     R9,#'='                 ;Next char must be `='
449                 MOVNE   R0,#err_expEq           ;If it isn't, moan
450                 BNE     error_report
451                 BL      getToken                ;Skip past the equals sign
452
453                 LDR     R0,tsc_lnewline         ;Get existing offset
454                 BL      strBucket_free          ;Free it
455                 MOV     R0,#0                   ;Prepare to read rvalue
456                 BL      express_read            ;Read it then
457                 BL      express_pop             ;Pop it off the stack
458                 CMP     R1,#vType_string        ;Is it a string?
459                 MOVNE   R0,#err_strNeeded       ;No -- get error number
460                 BNE     error_report            ;And report the error
461                 BL      termite__storeStr       ;Store in the bucket
462                 STR     R0,tsc_lnewline         ;Store the new offset
463                 B       interp_next             ;And do the next instruction
464
465 ; --- termite_log ---
466
467                 EXPORT  termite_log
468 termite_log     ROUT
469
470                 ; --- Load the first parameter ---
471
472                 MOV     R0,#0                   ;Read an rvalue
473                 BL      express_read            ;Read it then
474                 BL      express_pop             ;And get it off the stack
475                 CMP     R1,#vType_string        ;Is this a string?
476                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
477                 BNE     error_report            ;...and report the error
478
479                 LDR     R1,tsc_stracc           ;Get the stracc address
480                 LDR     R1,[R1]
481                 ADD     R1,R1,R0,LSR #8         ;Point to the string
482                 AND     R2,R0,#&FF              ;Get the length
483
484                 MOV     R5,R0                   ;Look after the rvalue
485                 ADR     R0,tsc_misc             ;Point to the misc buffer
486                 BL      termite_copyString      ;Copy the string over
487                 TCALL   termite_logFileAdd      ;Add the string to the log
488                 BL      termite__error          ;Handle possible error
489                 MOV     R0,R5                   ;Get the rvalue back
490                 BL      stracc_free             ;Free it from stracc
491                 B       interp_next             ;Return to main loop
492
493                 LTORG
494
495 ; --- termite_newsession ---
496
497                 EXPORT  termite_newsession
498 termite_newsession ROUT
499
500                 ; --- Read the base name ---
501
502                 MOV     R0,#0                   ;Read an rvalue
503                 BL      express_read            ;Read it then
504                 BL      express_pop             ;Get the rvalue
505                 CMP     R1,#vType_string        ;Is it a string?
506                 MOVNE   R0,#err_numNeeded       ;No -- get the error number
507                 BNE     error_report            ;And report the error
508
509                 ; --- NULL terminate it ---
510                 ;
511                 ; We rely on the fact that there can't be anything else
512                 ; after this string.  It is also important that we remember
513                 ; the stracc offset of this string, so that all the strings
514                 ; can be removed from stracc in one go.
515
516                 MOV     R3,R1                   ;Look after the offset
517                 MOV     R5,#0                   ;Useful, t' be sure
518                 BL      stracc_ensure           ;Ensure we have space
519                 STRB    R5,[R0,#0]              ;Terminate the string
520                 ORR     R0,R1,#1                ;Get the rvalue
521                 BL      stracc_added            ;Tell stracc about terminator
522
523                 ; --- Read the sub-style name ---
524
525                 MOV     R0,#0                   ;Read an rvalue
526                 BL      express_read            ;Read it then
527                 BL      express_pop             ;Get the rvalue
528                 CMP     R1,#vType_string        ;Is it a string?
529                 MOVNE   R0,#err_numNeeded       ;No -- get the error number
530                 BNE     error_report            ;And report the error
531
532                 ; --- NULL terminate it ---
533
534                 MOV     R6,R1                   ;Look after the offset
535                 BL      stracc_ensure           ;Ensure we have space
536                 STRB    R5,[R0,#0]              ;Terminate the string
537                 ADD     R4,R1,#(1<<8)           ;The next string will go here
538                 ORR     R0,R1,#1                ;Get the rvalue
539                 BL      stracc_added            ;Tell stracc about terminator
540
541                 ; --- Now we keep on adding strings to the list ---
542
543 05              CMP     R9,#','                 ;Do we have a comma?
544                 BNE     %50termite_newsession   ;No -- do the deed then
545                 BL      getToken                ;Skip over the comma
546
547                 MOV     R0,#0                   ;Read an rvalue
548                 BL      express_read            ;Read it then
549                 BL      express_pop             ;Pop off the string
550                 CMP     R1,#vType_dimStr        ;Is this a string array?
551                 BEQ     %10termite_newsession   ;Yes -- jump ahead
552                 CMP     R1,#vType_string        ;Is it a string?
553                 MOVNE   R0,#err_strNeeded       ;No -- get the error number
554                 BNE     error_report            ;And report the error
555
556                 ; --- We have a string then ---
557
558                 CMP     R0,#0                   ;Does it have a length?
559                 BEQ     %05termite_newsession   ;No -- find another one then
560                 BL      stracc_ensure           ;Ensure we have space
561                 STRB    R5,[R0,#0]              ;Terminate the string
562                 ORR     R0,R1,#1                ;Get the rvalue
563                 BL      stracc_added            ;Tell stracc about terminator
564                 B       %05termite_newsession   ;Find another string
565
566                 ; --- We have a string array ---
567
568 10              MOV     R3,R0                   ;Look after rvalue
569                 MOV     R2,#0                   ;Start from the beginning
570 15              MOV     R1,R3                   ;Put it in R1
571                 BL      termite__enumArray      ;Get an element
572                 BCC     %05termite_newsession   ;No more, get another string
573                 ANDS    R14,R0,#&FF             ;Get the length
574                 BEQ     %15termite_newsession   ;Zero -- get another one then
575                 BL      stracc_ensure           ;Ensure we have space
576                 STRB    R5,[R0,#0]              ;Terminate the string
577                 ORR     R0,R1,#1                ;Get the rvalue
578                 BL      stracc_added            ;Tell stracc about terminator
579                 B       %15termite_newsession   ;Find another element
580
581                 ; --- All the strings are in stracc now ---
582                 ;
583                 ; First, we terminate the list
584
585 50              BL      stracc_ensure           ;Ensure we have space
586                 STRB    R5,[R0,#0]              ;Terminate the string
587                 ORR     R0,R1,#1                ;Get the rvalue
588                 BL      stracc_added            ;Tell stracc about terminator
589
590                 ; --- Now, point to the strings ---
591
592                 LDR     R5,tsc_stracc           ;Load stracc anchor
593                 LDR     R5,[R5]
594                 ADD     R0,R5,R3,LSR #8         ;Point to the base name
595                 ADD     R1,R5,R6,LSR #8         ;Point to the sub-style
596                 ADD     R2,R5,R4,LSR #8         ;Point to strings
597
598                 TCALL   termite_newSession      ;Open the session
599                 BL      termite__error          ;Handle possible error
600
601                 MOV     R0,R3                   ;Put the offset in R0
602                 BL      stracc_free             ;Free all those strings!
603                 B       interp_next             ;Do the next instruction
604
605                 LTORG
606
607 ; --- termite_oscli ---
608
609                 EXPORT  termite_oscli
610 termite_oscli   ROUT
611
612                 ; --- Read a parameter ---
613
614                 MOV     R0,#0                   ;Read an rvalue
615                 BL      express_read            ;Read it then
616                 BL      express_pop             ;And get it off the stack
617                 CMP     R1,#vType_string        ;Is this a string?
618                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
619                 BNE     error_report            ;...and report the error
620
621                 LDR     R1,tsc_stracc           ;Get the stracc address
622                 LDR     R1,[R1]
623                 ADD     R1,R1,R0,LSR #8         ;Point to the string
624                 AND     R2,R0,#&FF              ;Get the length
625
626                 MOV     R5,R0                   ;look after the rvalue
627                 ADR     R0,tsc_misc             ;Point to the misc buffer
628                 BL      termite_copyString      ;Copy the string over
629                 SWI     Wimp_StartTask          ;Do the command
630                 MOV     R0,R5                   ;Get the rvalue back
631                 BL      stracc_free             ;Free the string from stracc
632                 B       interp_next             ;Continue happily
633
634                 LTORG
635
636 ; --- termite_rclear ---
637
638                 EXPORT  termite_rclear
639 termite_rclear  ROUT
640
641                 TCALL   termite_clearRemote     ;Clear the buffer
642                 B       interp_next             ;And go for more
643
644                 LTORG
645
646 ; --- termite_recho ---
647
648                 EXPORT  termite_recho
649 termite_recho   ROUT
650
651                 CMP     R9,#tok_off             ;Is this an option thingy?
652                 CMPNE   R9,#tok_local
653                 CMPNE   R9,#tok_remote
654                 CMPNE   R9,#tok_both
655                 BEQ     %50termite_recho        ;Yes -- deal seperately
656
657                 ; --- Just echo the result to the screen then ---
658
659                 MOV     R0,#0                   ;Read an rvalue
660                 BL      express_read            ;Read the next expression
661                 BL      express_pop             ;Get the value in R0,R1
662                 CMP     R1,#vType_integer       ;Is this an integer?
663                 BEQ     %10termite_recho        ;Yes -- jump ahead
664                 CMP     R1,#vType_string        ;Or a string?
665                 MOVNE   R0,#err_arrayBad
666                 BNE     error_report
667
668                 ; --- Display a string ---
669
670                 LDR     R2,tsc_stracc           ;Get the stracc address
671                 LDR     R2,[R2]
672                 ADD     R2,R2,R0,LSR #8         ;Point to the string
673                 AND     R3,R0,#&FF              ;Get the length
674                 TCALL   termite_sendRemote      ;Write out the message
675                 BL      termite__error          ;Handle possible error
676                 BL      stracc_free             ;Free the string from stracc
677                 B       %20termite_recho        ;Maybe write out return char
678
679                 ; --- Display an integer on the screen ---
680
681 10termite_recho ADR     R1,tsc_misc             ;Point to a nice buffer
682                 MOV     R2,#256                 ;The buffer is big
683                 SWI     OS_ConvertInteger4      ;Convert the number to a str
684                 SUB     R3,R1,R0                ;Get the length
685                 MOV     R2,R0                   ;Point at the block
686                 TCALL   termite_sendRemote      ;Write out the message
687                 BL      termite__error          ;Handle possible error
688
689                 ; --- Maybe write out the return char ---
690
691 20termite_recho CMP     R9,#';'                 ;Is there a semicolon now?
692                 BLEQ    getToken                ;Yes -- get a token
693                 BEQ     interp_next             ;...read another instr
694
695                 LDR     R2,tsc_bucket           ;Get the bucket anchor
696                 LDR     R2,[R2]
697                 LDR     R0,tsc_rnewline         ;Load the newline offset
698                 CMP     R0,#0                   ;Is there one?
699                 BEQ     interp_next             ;No -- stop here then
700                 ADD     R2,R2,R0                ;Point to the string
701                 LDRB    R3,[R2,#-1]             ;Load out the length
702                 TCALL   termite_sendRemote      ;Write out the terminator
703                 BL      termite__error          ;Handle possible error
704                 B       interp_next             ;And read another instruction
705
706                 ; --- Handle the options ---
707
708 50termite_recho LDR     R0,tsc_flags            ;Load the flags word
709                 BIC     R0,R0,#tscFlag_echoRR+tscFlag_echoRL
710                 CMP     R9,#tok_local           ;Do we require local echoing?
711                 CMPNE   R9,#tok_both
712                 ORREQ   R0,R0,#tscFlag_echoRL   ;Yes -- set the flag
713                 CMP     R9,#tok_remote          ;Do we require remote echos?
714                 CMPNE   R9,#tok_both
715                 ORREQ   R0,R0,#tscFlag_echoRR   ;Yes -- set the flag
716                 STR     R0,tsc_flags            ;Store back the flags word
717                 BL      getToken                ;Get another token
718
719                 B       interp_next             ;Keep on going then!
720
721                 LTORG
722
723 ; --- termite_report ---
724
725                 EXPORT  termite_report
726 termite_report  ROUT
727
728                 ; --- Read a parameter ---
729
730                 MOV     R0,#0                   ;Read an rvalue
731                 BL      express_read            ;Read it then
732                 BL      express_pop             ;And get it off the stack
733                 CMP     R1,#vType_string        ;Is this a string?
734                 MOVNE   R0,#err_strNeeded       ;Nope -- get error number
735                 BNE     error_report            ;...and report the error
736
737                 LDR     R1,tsc_stracc           ;Get the stracc address
738                 LDR     R1,[R1]
739                 ADD     R1,R1,R0,LSR #8         ;Point to the string
740                 AND     R2,R0,#&FF              ;Get the length
741
742                 MOV     R5,R0                   ;look after the rvalue
743                 ADR     R0,tsc_misc             ;Point to the misc buffer
744                 BL      termite_copyString      ;Copy the string over
745                 TCALL   termite_printMessage    ;Report the message
746                 MOV     R0,R5                   ;Get the rvalue back
747                 BL      stracc_free             ;Free the string from stracc
748                 B       interp_next             ;Continue happily
749
750                 LTORG
751
752 ; --- termite_rinput ---
753
754                 EXPORT  termite_rinput
755 termite_rinput  ROUT
756
757                 MOV     R0,#1                   ;Read an lvalue
758                 BL      express_read            ;Read it in
759
760                 ; --- Now enter a string reading loop ---
761
762                 BL      stracc_ensure           ;Make sure that there's room
763                 MOV     R2,R0                   ;Look after address
764                 MOV     R4,R0                   ;Twice
765                 MOV     R5,#0                   ;The length so far
766                 MOV     R3,#1                   ;Length of buffer to echo
767
768 00
769                 TCALL   termite_checkCarrier    ;Get current carrier state
770                 CMP     R0,#0                   ;Is there one?
771                 MOVEQ   R0,#0                   ;No, return ""
772                 BEQ     %90termite_rinput       ;And jump ahead
773
774                 TCALL   termite_readRemote      ;Read a byte from the buffer
775                 CMP     R0,#-1                  ;Was there one?
776                 BLEQ    tsc_wait                ;No -- wait for it then
777                 LDREQ   R2,tsc_stracc
778                 LDREQ   R2,[R2]
779                 ADDEQ   R2,R2,R1,LSR #8
780                 ADDEQ   R2,R2,R5
781                 BEQ     %b00
782                 CMP     R0,#127                 ;Is this a delete?
783                 CMPNE   R0,#8
784                 BEQ     %f05                    ;Yes -- deal with that then
785                 CMP     R0,#32                  ;Was it valid?
786                 STRGEB  R0,[R2,#0]              ;Yes -- store the byte
787                 BLGE    termite_doREcho         ;Echo the buffer
788                 ADDGE   R2,R2,#1                ;Increment the pointer
789                 ADDGE   R5,R5,#1                ;Increment the length
790                 CMP     R0,#13                  ;Are we finished?
791                 CMPNE   R5,#256
792                 BLT     %b00                    ;No -- get some more then
793                 B       %f10                    ;Finished -- jump ahead
794
795                 ; --- Do a delete operation ---
796
797 05              CMP     R5,#0                   ;Is the buffer empty?
798                 BLE     %b00                    ;Yes -- do nothing
799                 MOV     R14,#8                  ;Get a backspace
800                 STRB    R14,[R2,#0]             ;Store it...
801                 STRB    R14,[R2,#2]             ;In two places
802                 MOV     R14,#32                 ;And a space too
803                 STRB    R14,[R2,#1]             ;Put that in the middle
804                 MOV     R3,#3                   ;Send 3 characters
805                 BLGE    termite_doREcho         ;Echo the buffer
806                 SUB     R2,R2,#1                ;Reduce the address
807                 SUB     R5,R5,#1                ;And the number of chars
808                 MOV     R3,#1                   ;Put R3 back to 1
809                 B       %b00                    ;Join main loop again
810
811                 ; --- We have finished reading the string ---
812
813 10              ORR     R0,R1,R5                ;Get the rvalue
814 90              MOV     R1,#vType_string        ;This is a string
815                 BL      stracc_added            ;Tell stracc about this
816                 MOV     R3,R1                   ;Move these up a little
817                 MOV     R2,R0
818                 BL      express_pop             ;Get my lvalue off
819                 BL      ctrl_store              ;Store this away
820                 B       interp_next             ;Do another command
821
822                 LTORG
823
824 ; --- termite_rnewline ---
825
826                 EXPORT  termite_rnewline
827 termite_rnewline ROUT
828
829                 CMP     R9,#'='                 ;Next char must be `='
830                 MOVNE   R0,#err_expEq           ;If it isn't, moan
831                 BNE     error_report
832                 BL      getToken                ;Skip past the equals sign
833
834                 LDR     R0,tsc_rnewline         ;Get existing offset
835                 BL      strBucket_free          ;Free it
836                 MOV     R0,#0                   ;Prepare to read rvalue
837                 BL      express_read            ;Read it then
838                 BL      express_pop             ;Pop it off the stack
839                 CMP     R1,#vType_string        ;Is it a string?
840                 MOVNE   R0,#err_strNeeded       ;No -- get error number
841                 BNE     error_report            ;And report the error
842                 BL      termite__storeStr       ;Store inthe bucket
843                 STR     R0,tsc_rnewline         ;Store the new offset
844                 B       interp_next             ;And do the next instruction
845
846 ; --- termite_spool ---
847
848                 EXPORT  termite_spool
849 termite_spool   ROUT
850
851                 CMP     R9,#10                  ;Is this a newline?
852                 CMPNE   R9,#':'                 ;Or a colon
853                 CMPNE   R9,#&FF                 ;Or the end of the file?
854                 CMPNE   R9,#tok_else            ;Or an else
855                 BEQ     %50                     ;Yes -- turn off spooling
856
857                 ; --- Turn on spooling ---
858                 ;
859                 ; Ooh, spooling, I really dig you.
860
861                 MOV     R0,#0                   ;Read an rvalue
862                 BL      express_read            ;Read the expression
863                 BL      express_pop             ;Pop the result
864                 CMP     R1,#vType_string        ;Do we have a string?
865                 MOVNE   R0,#err_strNeeded       ;No -- moan at thick user
866                 BNE     error_report            ;Do that then
867
868                 ; --- Copy the string to the misc buffer ---
869
870                 LDR     R1,tsc_stracc           ;Find the stracc buffer
871                 LDR     R1,[R1,#0]              ;Load the pointer out
872                 MOV     R2,R0                   ;Look after the rvalue
873                 ADD     R0,R1,R0,LSR #8         ;Find the string base
874                 AND     R1,R2,#&FF              ;And get the length
875                 ADR     R3,tsc_misc             ;Point to destination buffer
876 00              LDRB    R14,[R0],#1             ;Load byte from string
877                 STRB    R14,[R3],#1             ;Store in destination
878                 SUBS    R1,R1,#1                ;Decrement the counter
879                 BGT     %b00                    ;And carry on going
880                 MOV     R14,#0                  ;Terminate the string
881                 STRB    R14,[R3],#1             ;Stick that on the end
882
883                 MOV     R0,R2                   ;Find the string rvalue
884                 BL      stracc_free             ;Remove it from stracc
885
886                 ; --- Make sure we're not spooling right now ---
887
888                 LDR     R1,tsc_spool            ;Load the current handle
889                 CMP     R1,#0                   ;Are we spooling?
890                 MOVNE   R0,#0                   ;Yes -- close current file
891                 SWINE   XOS_Find                ;So do that then
892
893                 ; --- Now open the file ---
894
895                 MOV     R0,#&8F                 ;Give me lots of errors
896                 ADR     R1,tsc_misc             ;Point to the buffer
897                 SWI     XOS_Find                ;Find a file handle for it
898                 BVS     error_reportReal        ;If failed, report the error
899                 STR     R0,tsc_spool            ;Save the file handle
900                 B       interp_next             ;Now do another instruction
901
902                 ; --- Close the current file ---
903
904 50termite_spool LDR     R1,tsc_spool            ;Load the current handle
905                 CMP     R1,#0                   ;Are we spooling?
906                 MOVNE   R0,#0                   ;Yes -- close current file
907                 SWINE   XOS_Find                ;So do that then
908                 BVS     error_reportReal
909                 MOV     R14,#0                  ;Get a zero value
910                 STR     R14,tsc_spool           ;Clear the file handle
911                 B       interp_next             ;Now do another instruction
912
913                 LTORG
914
915 ; --- termite_syscall ---
916
917                 EXPORT  termite_syscall
918 termite_syscall ROUT
919
920                 BL      ctrl_setUpRegs          ;Set up the regs then
921
922                 CMP     R10,#vType_string       ;Is this a string?
923                 LDREQ   R14,tsc_stracc          ;Yes -- load the stracc addr#
924                 LDREQ   R14,[R14]               ;Grrrr...
925                 ADDEQ   R9,R14,R9,LSR #8        ;Point to the string
926                 MOVEQ   R14,PC                  ;Yes -- set up return address
927                 ADDEQ   PC,R11,#termite_sysNumString
928                 BVS     error_reportReal        ;Report possible error
929                 CMPNE   R10,#vType_integer      ;Is this an integer?
930                 MOVNE   R0,#err_arrayBad        ;No -- get error number
931                 BNE     error_report            ;...and report the error
932
933                 TCALL   termite_sysCall         ;Call the call then!
934
935                 ADR     R10,termite__retned     ;Point to some space
936                 STMIA   R10!,{R0-R8}            ;Store returned registers
937                 MOV     R14,PC,LSR #28          ;Get the flags
938                 STMIA   R10!,{R14}              ;Strore the flags too
939
940                 ; --- Convert the string if needed ---
941
942                 LDMFD   R13!,{R7-R12}           ;Load back position info
943                 LDMFD   R13!,{R0}               ;Load stracc offset
944                 BL      stracc_free             ;Free any strings I had
945
946                 ; --- We have now done the SYSCALL instr ---
947
948                 ADR     R0,termite__retned      ;Point to the returned regs
949                 BL      ctrl_resolveRegs        ;Do the other half now
950                 B       interp_next             ;No error -- happy
951
952 termite__retned DCD     0,0,0,0,0,0,0,0,0,0,0   ;For SYSCALL, CALL
953
954                 LTORG
955
956 ; --- termite_upload ---
957
958                 EXPORT  termite_upload
959 termite_upload  ROUT
960
961                 ; --- Read the protocol name ---
962
963                 MOV     R0,#0                   ;Read an rvalue
964                 BL      express_read            ;Read it then
965                 BL      express_pop             ;Get the rvalue
966                 CMP     R1,#vType_string        ;Is it a string?
967                 MOVNE   R0,#err_numNeeded       ;No -- get the error number
968                 BNE     error_report            ;And report the error
969
970                 ; --- NULL terminate it ---
971                 ;
972                 ; We rely on the fact that there can't be anything else
973                 ; after this string.  It is also important that we remember
974                 ; the stracc offset of this string, so that all the strings
975                 ; can be removed from stracc in one go.
976
977
978                 MOV     R3,R1                   ;Look after the offset
979                 MOV     R5,#0                   ;Useful, t' be sure
980                 BL      stracc_ensure           ;Ensure we have space
981                 STRB    R5,[R0,#0]              ;Terminate the string
982                 ADD     R4,R1,#(1<<8)           ;The next string will go here
983                 ORR     R0,R1,#1                ;Get the rvalue
984                 BL      stracc_added            ;Tell stracc about terminator
985
986                 ; --- Now we keep on adding strings to the list ---
987
988 05              CMP     R9,#','                 ;Do we have a comma?
989                 BNE     %50termite_upload       ;No -- do the deed then
990                 BL      getToken                ;Skip over the comma
991
992                 MOV     R0,#0                   ;Read an rvalue
993                 BL      express_read            ;Read it then
994                 BL      express_pop             ;Pop off the string
995                 CMP     R1,#vType_dimStr        ;Is this a string array?
996                 BEQ     %10termite_upload       ;Yes -- jump ahead
997                 CMP     R1,#vType_string        ;Is it a string?
998                 MOVNE   R0,#err_strNeeded       ;No -- get the error number
999                 BNE     error_report            ;And report the error
1000
1001                 ; --- We have a string then ---
1002
1003                 CMP     R0,#0                   ;Does it have a length?
1004                 BEQ     %05termite_upload       ;No -- find another one then
1005                 BL      stracc_ensure           ;Ensure we have space
1006                 STRB    R5,[R0,#0]              ;Terminate the string
1007                 ORR     R0,R1,#1                ;Get the rvalue
1008                 BL      stracc_added            ;Tell stracc about terminator
1009                 B       %05termite_upload       ;Find another string
1010
1011                 ; --- We have a string array ---
1012
1013 10              MOV     R3,R0                   ;Look after rvalue
1014                 MOV     R2,#0                   ;Start from the beginning
1015 15              MOV     R1,R3                   ;Put it in R1
1016                 BL      termite__enumArray      ;Get an element
1017                 BCC     %05termite_upload       ;No more, get another string
1018                 ANDS    R14,R0,#&FF             ;Get the length
1019                 BEQ     %15termite_upload       ;Zero -- get another one then
1020                 BL      stracc_ensure           ;Ensure we have space
1021                 STRB    R5,[R0,#0]              ;Terminate the string
1022                 ORR     R0,R1,#1                ;Get the rvalue
1023                 BL      stracc_added            ;Tell stracc about terminator
1024                 B       %15termite_upload       ;Find another element
1025
1026                 ; --- All the strings are in stracc now ---
1027                 ;
1028                 ; First, we terminate the list
1029
1030 50              BL      stracc_ensure           ;Ensure we have space
1031                 STRB    R5,[R0,#0]              ;Terminate the string
1032                 ORR     R0,R1,#1                ;Get the rvalue
1033                 BL      stracc_added            ;Tell stracc about terminator
1034
1035                 ; --- Now, point to the strings ---
1036
1037                 LDR     R1,tsc_stracc           ;Load stracc anchor
1038                 LDR     R1,[R1]
1039                 MOV     R5,R3                   ;Look after offset
1040                 ADD     R2,R1,R3,LSR #8         ;Point to the protocol name
1041                 ADD     R3,R1,R4,LSR #8         ;Point to files to upload
1042
1043                 TCALL   termite_upLoad          ;Upload the files
1044                 BL      termite__error          ;Handle possible error
1045
1046                 MOV     R0,R5                   ;Put the offset in R0
1047                 BL      stracc_free             ;Free all those strings!
1048                 B       interp_next             ;Do the next instruction
1049
1050                 LTORG
1051
1052 ; --- termite_wait ---
1053
1054                 EXPORT  termite_wait
1055 termite_wait    ROUT
1056
1057                 ; --- Read a parameter ---
1058
1059                 MOV     R0,#0                   ;Read an rvalue
1060                 BL      express_read            ;Read it then
1061                 BL      express_pop             ;And get it off the stack
1062                 CMP     R1,#vType_integer       ;Is this an integer
1063                 MOVNE   R0,#err_numNeeded       ;Nope -- get error number
1064                 BNE     error_report            ;...and report the error
1065
1066                 MOV     R1,R0                   ;Remember this time
1067                 SWI     OS_ReadMonotonicTime    ;Read the current time
1068                 ADD     R1,R1,R0                ;Return after this time
1069
1070                 ; --- Now enter a waiting loop ---
1071
1072 00              SWI     OS_ReadMonotonicTime    ;Read the current time
1073                 CMP     R0,R1                   ;Have we finished waiting?
1074                 BLCC    tsc_wait                ;No -- wait some more
1075                 BCC     %b00                    ;...and keep on looping
1076
1077                 B       interp_next             ;Go round for next command
1078
1079                 LTORG
1080
1081 ; --- termite_watchfor ---
1082
1083                 EXPORT  termite_watchfor
1084 termite_watchfor ROUT
1085
1086                 ; --- See if we are ending the WATCHFOR ---
1087
1088                 CMP     R9,#tok_end             ;Are we ending it?
1089                 BEQ     %70termite_watchfor     ;Yes -- jump ahead
1090
1091                 ; --- First, we must set up strings ---
1092                 ;
1093                 ; We actually store the strings in the strBucket.
1094                 ; In the string list, we have a word for the pointer into
1095                 ; the string list, and a byte for the match position so far.
1096
1097                 MOV     R5,#0                   ;Number so far
1098                 ADR     R3,tsc_wForStrings      ;Point to the block
1099                 MOV     R4,#0                   ;For the match position
1100                 STR     R5,tsc_wForState        ;Reset the state to 0
1101
1102 10              CMP     R5,#32                  ;Are we at the maximum?
1103                 MOVGE   R0,#err_WFTooMany       ;Yes -- get error number
1104                 BEQ     error_report            ;And report the error
1105
1106                 ; --- Now read the strings one at a time ---
1107
1108                 MOV     R0,#0                   ;Read an rvalue
1109                 BL      express_read            ;Read it then
1110                 BL      express_pop             ;Pop off this value
1111                 CMP     R1,#vType_dimStr        ;Is this a string array?
1112                 BNE     %19termite_watchfor     ;No -- jump ahead
1113
1114                 ; --- We have a string array ---
1115
1116                 MOV     R1,R0                   ;Put the array in R1
1117                 MOV     R2,#0                   ;Start from the beginning
1118 00              BL      termite__enumArray      ;Get the next string
1119                 BCC     %15termite_watchfor     ;No more -- jump ahead
1120                 BL      termite__storeStr       ;Store the string
1121                 CMP     R9,#&7e                 ;Are we case insensitive?
1122                 ORREQ   R0,R0,#(1<<31)          ;Yes -- set the flag
1123                 STMIA   R3!,{R0,R4}             ;Store information
1124                 ADD     R5,R5,#1                ;Increment the counter
1125                 B       %b00                    ;And keep doing this
1126
1127                 ; --- The array has finished ---
1128
1129 15              CMP     R9,#&7e                 ;Should we skip a token?
1130                 BLEQ    getToken                ;Yes - do that then
1131                 B       %25termite_watchfor     ;Jump ahead a little
1132
1133                 ; --- See if it's a string then ---
1134
1135 19              CMP     R1,#vType_string        ;Is it a string?
1136                 MOVNE   R0,#err_strNeeded       ;No -- get the error
1137                 BNE     error_report            ;And then report it
1138
1139                 ; --- We have a string in stracc ---
1140
1141                 CMP     R9,#&7e                 ;Case insensitive? (#'~')
1142                 BLEQ    getToken                ;Yes -- skip over it
1143 20              BL      termite__storeStr       ;Put it in the bucket
1144                 ORREQ   R0,R0,#(1<<31)          ;Set the top bit for insens
1145                 STMIA   R3!,{R0,R4}             ;Store inforamtion
1146                 ADD     R5,R5,#1                ;Increment the counter
1147
1148                 ; --- Do any more we have ---
1149
1150 25              CMP     R9,#','                 ;Do we have a comma
1151                 BLEQ    getToken                ;Yes -- skip over it
1152                 BEQ     %10termite_watchfor     ;...and then go round
1153                 STR     R5,tsc_wForNumber       ;Store the number of strings
1154
1155                 ; --- Now we must check the ring buffer ---
1156                 ;
1157                 ; We keep taking bytes off until either a match is achieved,
1158                 ; we have read 255 chars or there are no more in the
1159                 ; buffer.  In any case we then on the buffer.
1160                 ; If we have 255 chars we simply start all over again.
1161
1162                 ADR     R2,tsc_misc             ;Point to the buffer
1163                 MOV     R3,#0                   ;Number read so far
1164 00
1165                 TCALL   termite_readRemote      ;Get a byte
1166                 CMP     R0,#-1                  ;Was there a byte?
1167                 BEQ     %50termite_watchfor     ;No -- jump ahead
1168                 ADD     R3,R3,#1                ;Increment the count
1169                 STRB    R0,[R2],#1              ;Store it in the buffer
1170                 BL      termite__checkWF        ;Does this make a match?
1171                 BCS     %50termite_watchfor     ;Yes -- jump ahead
1172                 CMP     R3,#255                 ;Have we had 255 bytes now?
1173                 BNE     %b00                    ;No -- keep on going then
1174
1175                 ; --- Send on the buffer ---
1176
1177                 ADR     R2,tsc_misc             ;Point to the buffer
1178                 BL      termite_doREcho         ;Echo it appropriately
1179                 MOV     R3,#0                   ;Reset the count to 0
1180                 B       %b00                    ;And start all over again
1181
1182                 ; --- We have stopped reading bytes ---
1183                 ;
1184                 ; Either we ran out of bytes, or we got a match,
1185                 ; for either case we do the same thing
1186
1187 50              ADR     R2,tsc_misc             ;Point to the buffer
1188                 BL      termite_doREcho         ;Echo it appropriately
1189                 B       interp_next             ;Do the next instruction
1190
1191                 ; --- We are ending the watchfor ---
1192
1193 70              BL      getToken                ;Gobble up the END
1194                 BL      termite__endWF          ;End the WATCHFOR
1195                 B       interp_next             ;Do the next command
1196
1197                 LTORG
1198
1199 ; --- termite__endWF ---
1200 ;
1201 ; On entry:     --
1202 ;
1203 ; On exit:      --
1204 ;
1205 ; Use:          Ends a WATCHFOR condition.
1206
1207 termite__endWF  ROUT
1208
1209                 STMFD   R13!,{R0-R3,R14}        ;Stack some regsiters
1210                 ADR     R1,tsc_wForStrings      ;Point to the string list
1211                 LDR     R2,tsc_wForNumber       ;Get the number of strings
1212                 CMP     R2,#0                   ;Are there any?
1213                 BEQ     %f05                    ;No -- jump ahead then
1214                 MOV     R3,R2,LSL #3            ;Multiply by 8
1215                 ADD     R1,R1,R3                ;Point just past the last one
1216 00              LDR     R0,[R1,#-8]!            ;Load out an offset
1217                 BIC     R0,R0,#(1<<31)          ;Clear the flag
1218                 BL      strBucket_free          ;Remove the string
1219                 SUBS    R2,R2,#1                ;Reduce the count
1220                 BGT     %b00                    ;And free the rest
1221
1222 05              STR     R2,tsc_wForNumber       ;Make that clear
1223                 LDMFD   R13!,{R0-R3,PC}^        ;Return to caller
1224
1225                 LTORG
1226
1227 ; --- termite__checkWF ---
1228 ;
1229 ; On entry:     R0 == byte to check
1230 ;
1231 ; On exit:      CS if that byte caused a match,
1232 ;               CC otherwise
1233 ;
1234 ; Use:          Tests all the strings in the WATCHFOR list, to see if
1235 ;               the character caused a match.  If it did, then WATCH
1236 ;               is set.
1237
1238 termite__checkWF ROUT
1239
1240                 STMFD   R13!,{R0-R9,R14}        ;Stack registers
1241                 LDR     R1,tsc_bucket           ;Load the bucket anchor
1242                 LDR     R1,[R1,#0]              ;Point to it
1243                 ADR     R2,tsc_wForStrings      ;Point to the strings
1244                 LDR     R3,tsc_wForNumber       ;Load the number of strings
1245
1246                 ; --- Get the information on the string ---
1247
1248 00              LDR     R7,[R2],#4              ;Load the offset
1249                 CMP     R7,#0                   ;Is this one blank?
1250                 ADDEQ   R2,R2,#4                ;Yes -- skip over position
1251                 BEQ     %10termite__checkWF     ;Zero length -- ignore
1252                 BICS    R4,R7,#(1<<31)          ;Clear the 'insens' bit
1253                 LDR     R5,[R2],#4              ;Load position so far
1254                 ADD     R4,R1,R4                ;Point to the string
1255                 LDRB    R6,[R4,#-1]             ;Load the string length
1256                 ADD     R4,R4,R5                ;Point to the character
1257
1258                 ; --- Now do the comparison ---
1259
1260 02              LDRB    R14,[R4,#0]             ;Load the next byte
1261                 MOV     R9,R0                   ;Put byte to comapre in R8
1262                 TST     R7,#(1<<31)             ;Case insensitive?
1263                 ORRNE   R9,R9,#32               ;Yes -- make lower case
1264                 ORRNE   R14,R14,#32             ;Both of them
1265                 CMP     R9,R14                  ;Are they the same?
1266                 BEQ     %05termite__checkWF     ;Yes -- jump ahead
1267                 CMP     R5,#0                   ;Was that the first char?
1268                 SUB     R4,R4,R5                ;Point to the string start
1269                 MOV     R5,#0                   ;Put it back to 0
1270                 BNE     %02termite__checkWF     ;No --  test first char
1271                 STR     R5,[R2,#-4]             ;...store that back
1272                 B       %10termite__checkWF     ;...jump ahead
1273
1274                 ; --- The characters matched ---
1275
1276 05              ADD     R5,R5,#1                ;Increment position
1277                 CMP     R5,R6                   ;Has the string been done?
1278                 BEQ     %20termite__checkWF     ;Yes -- we jump ahead then
1279                 STR     R5,[R2,#-4]             ;Store the new position
1280
1281                 ; --- Move onto the next string ---
1282
1283 10              SUBS    R3,R3,#1                ;Decrement the string count
1284                 BGT     %00termite__checkWF     ;And keep on looking
1285                 LDMFD   R13!,{R0-R9,R14}        ;Load back registers
1286                 BICS    PC,R14,#C_flag          ;And return to caller
1287
1288                 ; --- We found a matching string ---
1289
1290 20              LDR     R14,tsc_wForNumber      ;Get teh number of strings
1291                 SUB     R14,R14,R3              ;Get index-1
1292                 ADD     R14,R14,#1              ;Get the index
1293                 STR     R14,tsc_wForState       ;Store as the state
1294                 BL      termite__endWF          ;End the current watchfor
1295                 LDMFD   R13!,{R0-R9,R14}        ;Load back registers
1296                 ORRS    PC,R14,#C_flag          ;And return to caller
1297
1298                 LTORG
1299
1300 ; --- termite_remoteInput ---
1301 ;
1302 ; On entry:     R0 == handle of script
1303 ;               R2 == buffer containing bytes read
1304 ;               R3 == number of bytes in buffer
1305 ;               R11 == upcall block
1306 ;
1307 ; On exit:      R2 == new buffer containing bytes to put into ring buffer
1308 ;               R3 == number of bytes in this buffer
1309 ;
1310 ; Use:          If we are not doing a watchfor, then this call will return
1311 ;               immediately, resulting in all the buffer being sent
1312 ;               to the ring buffer.
1313 ;               If we are in a watchfor, then all data received, up until
1314 ;               a match, is echoed immediatley, and not sent to the buffer.
1315
1316                 EXPORT  termite_remoteInput
1317 termite_remoteInput ROUT
1318
1319                 STMFD   R13!,{R14}              ;Stack the link register
1320                 LDR     R14,[R0,#:INDEX:tsc_wForNumber]
1321                 CMP     R14,#0                  ;Are we in a WATCHFOR?
1322                 LDMEQFD R13!,{PC}^              ;No -- return AQAP then
1323
1324                 STMFD   R13!,{R0,R4,R5,R12}     ;Stack some more registers
1325                 MOV     R12,R0                  ;Put workspace in R12
1326                 MOV     R4,R2                   ;Look after buffer address
1327                 MOV     R5,R3                   ;Remember number of bytes
1328
1329                 ; --- Scan the buffer ---
1330
1331 00              LDRB    R0,[R4],#1              ;Load a byte
1332                 SUB     R5,R5,#1                ;Reduce the count
1333                 BL      termite__checkWF        ;Does this cause a match
1334                 BCS     %10termite_remoteInput  ;We have a match
1335                 CMP     R5,#0                   ;Have we finished?
1336                 BGT     %b00                    ;More to go -- loop
1337
1338                 ; -- Send this buffer then ---
1339
1340                 BL      termite_doREcho         ;Send the buffer
1341                 MOV     R3,#0                   ;Put nothing in the buffer
1342                 B       %90termite_remoteInput  ;And return to caller
1343
1344                 ; --- We got a match ---
1345
1346 10              SUB     R3,R3,R5                ;Get number to send
1347                 BL      termite_doREcho         ;Send the buffer
1348                 MOV     R3,R5                   ;Get bytes left
1349                 MOV     R2,R4                   ;Point to rest of buffer
1350
1351 90              LDMFD   R13!,{R0,R4,R5,R12,PC}^ ;Return to caller
1352
1353                 LTORG
1354
1355 ;----- Utility routines -----------------------------------------------------
1356
1357 ; --- termite_copyString ---
1358 ;
1359 ; On entry:     R0 == buffer to copy string to
1360 ;               R1 == point to the string
1361 ;               R2 == length of string to copy
1362 ;
1363 ; On exit:      --
1364 ;
1365 ; Use:          Copies the string into the buffer.
1366
1367                 EXPORT  termite_copyString
1368 termite_copyString ROUT
1369
1370                 STMFD   R13!,{R0-R2,R14}        ;Stack registers
1371                 CMP     R2,#0                   ;Is this a short string?
1372 00              LDRGTB  R14,[R1],#1             ;Load a character
1373                 STRGTB  R14,[R0],#1             ;And then store it
1374                 SUBS    R2,R2,#1                ;Reduce the count
1375                 BGT     %b00                    ;And keep on goin'
1376                 MOV     R14,#0                  ;Get a terminator
1377                 STRB    R14,[R0],#1             ;Store the byte and return
1378                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1379
1380                 LTORG
1381
1382 ; --- termite_doLEcho ---
1383 ;
1384 ; On entry:     R2 == pointer to the buffer
1385 ;               R3 == number of bytes to send
1386 ;
1387 ; On exit:      --
1388 ;
1389 ; Use:          Echos the buffer to local and remote according to the
1390 ;               current flags, assuming the buffer came from the local input
1391
1392                 EXPORT  termite_doLEcho
1393 termite_doLEcho ROUT
1394
1395                 STMFD   R13!,{R0,R3,R14}        ;Stack some registers
1396                 LDR     R0,tsc_flags            ;Load the flags word
1397                 TST     R0,#tscFlag_echoLR      ;Should we echo to remote?
1398                 MOVNE   R14,PC                  ;Yes -- set up return address
1399                 ADDNE   PC,R11,#termite_sendRemote ;...and send the bytes
1400                 TST     R0,#tscFlag_echoLL      ;Should we echo to local?
1401                 BLNE    termite__doSpool        ;Yes -- check for spooling
1402                 MOVNE   R14,PC                  ;Yes -- set up return address
1403                 ADDNE   PC,R11,#termite_sendLocal ;...and send the bytes
1404                 LDMFD   R13!,{R0,R3,PC}^        ;Return to caller
1405
1406                 LTORG
1407
1408 ; --- termite_doREcho ---
1409 ;
1410 ; On entry:     R2 == pointer to the buffer
1411 ;               R3 == number of bytes to send
1412 ;
1413 ; On exit:      --
1414 ;
1415 ; Use:          Echos the buffer to local and remote according to the
1416 ;               current flags, assuming the buffer came from remote input
1417
1418                 EXPORT  termite_doREcho
1419 termite_doREcho ROUT
1420
1421                 STMFD   R13!,{R0,R3,R14}        ;Stack some registers
1422                 LDR     R0,tsc_flags            ;Load the flags word
1423                 TST     R0,#tscFlag_echoRR      ;Should we echo to remote?
1424                 MOVNE   R14,PC                  ;Yes -- set up return address
1425                 ADDNE   PC,R11,#termite_sendRemote ;...and send the bytes
1426                 TST     R0,#tscFlag_echoRL      ;Should we echo to local?
1427                 BLNE    termite__doSpool        ;Yes -- check for spooling
1428                 MOVNE   R14,PC                  ;Yes -- set up return address
1429                 ADDNE   PC,R11,#termite_sendLocal ;...and send the bytes
1430                 LDMFD   R13!,{R0,R3,PC}^        ;Return to caller
1431
1432                 LTORG
1433
1434 ; --- termite__doSpool ---
1435 ;
1436 ; On entry:     R2 == pointer to data to spool
1437 ;               R3 == size of the data
1438 ;
1439 ; On exit:      --
1440 ;
1441 ; Use:          Maybe writes the data to the current spool file.
1442
1443 termite__doSpool ROUT
1444
1445                 STMFD   R13!,{R0-R4,R14}        ;Save some registers
1446                 LDR     R1,tsc_spool            ;Load the spool handle
1447                 CMP     R1,#0                   ;Is spooling enabled?
1448                 MOVNE   R0,#2                   ;Yes -- write to the file
1449                 SWINE   XOS_GBPB                ;Do the write
1450                 LDMFD   R13!,{R0-R4,PC}^        ;And return to caller
1451
1452                 LTORG
1453
1454 ; --- termite__storeStr ---
1455 ;
1456 ; On entry:     R0 == rvalue of string
1457 ;
1458 ; On exit:      R0 == offset into bucket of string
1459 ;
1460 ; Use:          Puts the string in stracc, into the string bucket.
1461
1462 termite__storeStr ROUT
1463
1464                 STMFD   R13!,{R1-R4,R14}        ;Stack some registers
1465                 MOV     R2,R0                   ;Put the string in R2
1466                 MOV     R4,R0                   ;And in R4
1467                 ANDS    R0,R2,#&FF              ;Get the length
1468                 MOVEQ   R0,#0                   ;Zero length, get a zero
1469                 BEQ     %90termite__storeStr    ;And return to caller
1470                 BL      strBucket_alloc         ;Allocate the bucket
1471                 LDR     R3,tsc_stracc           ;Load the bucket anchor
1472                 LDR     R3,[R3]                 ;This is getting annoying
1473                 ADD     R3,R3,R2,LSR #8         ;Point to the string
1474                 AND     R2,R2,#&FF              ;Get the length
1475 00              LDRB    R14,[R3],#1             ;Load a character
1476                 STRB    R14,[R0],#1             ;Copy it over
1477                 SUBS    R2,R2,#1                ;Reduce the counter
1478                 BGT     %b00                    ;Keep on looping
1479                 MOV     R0,R4                   ;Put the rvalue in R0
1480                 BL      stracc_free             ;Remove it from stracc
1481                 MOV     R0,R1                   ;Return offset in R0
1482
1483 90              LDMFD   R13!,{R1-R4,PC}^        ;Return to caller
1484
1485                 LTORG
1486
1487 ; --- termite__enumArray ---
1488 ;
1489 ; On entry:     R1 == offset of array definition
1490 ;               R2 == item to read next
1491 ;
1492 ; On exit:      CS if item found, and
1493 ;                 R0 == rvalue of item
1494 ;                 R2 == updated
1495 ;               CC otherwise
1496 ;
1497 ; Use:          Goes through an string array, returning each item.
1498
1499 termite__enumArray ROUT
1500
1501                 STMFD   R13!,{R1,R3,R4,R14}     ;Stack registers
1502                 LDR     R3,tsc_varTree          ;Point at the tree
1503                 LDR     R3,[R3]
1504                 ADD     R0,R3,R1                ;Point at the array
1505                 MOV     R4,R2                   ;Remember the count
1506                 LDR     R14,[R0,#8]             ;Load number of items
1507                 CMP     R2,R14                  ;Have we finished?
1508                 BEQ     %95termite__enumArray   ;Yes -- return then
1509
1510                 LDR     R14,[R0,#4]             ;Load number of subscripts
1511                 ADD     R0,R0,#12               ;Point to them
1512                 ADD     R0,R0,R14,LSL #2        ;Point past them
1513                 ADD     R0,R0,R2,LSL #2         ;Point at the item
1514                 SUB     R0,R0,R3                ;Make that an offset
1515                 MOV     R1,#vType_lvString      ;The item is a string
1516                 BL      ctrl_load               ;Load it out
1517                 MOV     R0,R2                   ;Put the rvalue in R0
1518                 ADD     R2,R4,#1                ;Increment the item pos
1519
1520                 LDMFD   R13!,{R1,R3,R4,R14}     ;Load back registers
1521                 ORRS    PC,R14,#C_flag          ;And return success
1522
1523 95              LDMFD   R13!,{R1,R3,R4,R14}     ;Load back registers
1524                 BICS    PC,R14,#C_flag          ;And return failure
1525
1526                 LTORG
1527
1528 ; --- termite__error ---
1529 ;
1530 ; On entry:     V flag and R0 determine error condition
1531 ;
1532 ; On exit:      --
1533 ;
1534 ; Use:          This call will generate an error, if ERROR ON has been
1535 ;               done, or set the ERROR$ variable otherwise.
1536
1537 termite__error  ROUT
1538
1539                 STMFD   R13!,{R0-R2,R14}        ;Save regiters
1540                 LDR     R1,tsc_flags            ;Load the fags word
1541                 BVS     %50termite__error       ;Jump ahead if there's an err
1542
1543                 ; --- There was no error ---
1544
1545                 TST     R1,#tscFlag_error       ;Do we generate errors?
1546                 BNE     %90termite__error       ;Yes -- just return then
1547
1548                 ; --- Put a NULL string into ERROR$ ---
1549
1550                 LDR     R0,tsc_errorS           ;Get the exesting offset
1551                 BL      strBucket_free          ;Free it
1552                 MOV     R0,#0                   ;Get a 0 length string
1553                 STR     R0,tsc_errorS           ;Save that away
1554                 B       %90termite__error       ;Return to caller
1555
1556                 ; --- There was an error ---
1557
1558 50              TST     R1,#tscFlag_error       ;Do we generate errors?
1559                 BNE     error_reportReal        ;Yes -- report the error then
1560
1561                 ; --- Copy the string into ERROR$ ---
1562
1563                 ADD     R2,R0,#4                ;Put string pointer in R2
1564                 LDR     R0,tsc_errorS           ;Get the exesting offset
1565                 BL      strBucket_free          ;Free it
1566                 MOV     R1,R2                   ;Point to the string
1567                 MOV     R0,#0                   ;Current sting length
1568 00              LDRB    R14,[R1],#1             ;Load a byte
1569                 CMP     R14,#0                  ;Is it a NULL one?
1570                 ADDNE   R0,R0,#1                ;No -- increment the length
1571                 BNE     %b00                    ;And keep on going
1572
1573                 ; --- Now copy over the string ---
1574
1575                 BL      strBucket_alloc         ;We need this much room
1576                 STR     R1,tsc_errorS           ;Store this offset away
1577 00              LDRB    R14,[R2],#1             ;Load a byte from string
1578                 CMP     R14,#0                  ;Is this the end?
1579                 STRNE   R14,[R0],#1             ;No -- store in ERROR$
1580                 BNE     %b00                    ;And keep doing this
1581
1582                 ; --- Return to caller ---
1583
1584 90              LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
1585
1586                 LTORG
1587
1588 ;----- That's all, folks ----------------------------------------------------
1589
1590                 END