4 ; Implementation of Termite specific instructions
9 ;----- Standard header ------------------------------------------------------
16 ;----- External dependencies ------------------------------------------------
32 ;----- Main code ------------------------------------------------------------
34 AREA |TermScript$$Code|,CODE,READONLY
36 ; --- termite_beep ---
41 TCALL termite_makeBeep ;Make a beep
42 B interp_next ;And go for more
46 ; --- termite_break ---
51 TCALL termite_sendBreak ;Send the break
52 BL termite__error ;Handle possible error
53 B interp_next ;And go for more
57 ; --- termite_call ---
62 BL ctrl_setUpRegs ;Set up the regs then
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
68 MOV R14,PC ;Set up return address
69 MOV PC,R9 ;Execute the code
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
79 ; --- We have now done the SWI instr ---
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
87 ; --- termite_chain ---
92 ; --- Read a parameter ---
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
101 LDR R1,tsc_stracc ;Get the stracc address
103 ADD R1,R1,R0,LSR #8 ;Point to the string
104 AND R2,R0,#&FF ;Get the length
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
112 ; --- termite_close ---
117 MOV R0,#-1 ;Close the session
118 B tsc_end ;Do that then
122 ; --- termite_cls ---
127 TCALL termite_clearScreen ;Clear the screen
128 BL termite__error ;Handle possible error
129 B interp_next ;And go for more
133 ; --- termite_download ---
135 EXPORT termite_download
136 termite_download ROUT
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
145 ; --- Null terminate this ---
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
154 ; --- Check for another string ---
156 CMP R9,#',' ;Do we have a comma?
157 MOVNE R3,#0 ;No -- use default then
158 BNE %10termite_download ;...and jump ahead
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
168 ; --- Null terminate this ---
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
177 ; --- Do the download now ---
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
192 ; --- termite_error ---
197 CMP R9,#tok_on ;Is this an option?
199 BEQ %50termite_error ;Yes -- jump ahead
201 ; --- Read a parameter ---
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
210 LDR R1,tsc_stracc ;Get the stracc address
212 ADD R1,R1,R0,LSR #8 ;Point to the string
213 AND R2,R0,#&FF ;Get the length
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
223 ; --- There was an option ---
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
235 ; --- termite_exec ---
240 ; --- Read a parameter ---
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
249 LDR R1,tsc_stracc ;Get the stracc address
251 ADD R1,R1,R0,LSR #8 ;Point to the string
252 AND R2,R0,#&FF ;Get the length
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
266 ; --- termite_finish ---
268 EXPORT termite_finish
271 TCALL termite_finishSession ;Finish the session
272 B interp_next ;And go round for more
276 ; --- termite_hangup ---
278 EXPORT termite_hangup
281 TCALL termite_dropCarrier ;Hang up the modem
282 B interp_next ;And go for more
286 ; --- termite_lclear ---
288 EXPORT termite_lclear
291 TCALL termite_clearLocal ;Clear the buffer
292 B interp_next ;And go for more
296 ; --- termite_lecho ---
301 CMP R9,#tok_off ;Is this an option thingy?
305 BEQ %50termite_lecho ;Yes -- deal seperately
307 ; --- Just echo the result to the screen then ---
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
318 ; --- Display a string ---
320 LDR R2,tsc_stracc ;Get the stracc address
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
330 ; --- Display an integer on the screen ---
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
341 ; --- Maybe write out the return char ---
343 20termite_lecho CMP R9,#';' ;Is there a semicolon now?
344 BLEQ getToken ;Yes -- get a token
345 BEQ interp_next ;...read another instr
347 LDR R2,tsc_bucket ;Get the bucket anchor
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
359 ; --- Handle the options ---
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?
365 ORREQ R0,R0,#tscFlag_echoLL ;Yes -- set the flag
366 CMP R9,#tok_remote ;Do we require remote echos?
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
372 B interp_next ;Keep on going then!
376 ; -- termite_linput ---
378 EXPORT termite_linput
381 MOV R0,#1 ;Read an lvalue
382 BL express_read ;Read it in
384 ; --- Now enter a string reading loop ---
386 BL stracc_ensure ;Make sure that there's room
387 MOV R2,R0 ;Look after address
389 MOV R5,#0 ;The length so far
390 MOV R3,#1 ;Length of buffer to echo
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
398 ADDEQ R2,R2,R1,LSR #8
401 CMP R0,#127 ;Is this a delete?
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?
411 BLT %b00 ;No -- get some more then
412 B %f10 ;Finished -- jump ahead
414 ; --- Do a delete operation ---
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
430 ; --- We have finished reading the string ---
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
437 BL express_pop ;Get my lvalue off
438 BL ctrl_store ;Store this away
439 B interp_next ;Do another command
443 ; --- termite_lnewline ---
445 EXPORT termite_lnewline
446 termite_lnewline ROUT
448 CMP R9,#'=' ;Next char must be `='
449 MOVNE R0,#err_expEq ;If it isn't, moan
451 BL getToken ;Skip past the equals sign
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
465 ; --- termite_log ---
470 ; --- Load the first parameter ---
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
479 LDR R1,tsc_stracc ;Get the stracc address
481 ADD R1,R1,R0,LSR #8 ;Point to the string
482 AND R2,R0,#&FF ;Get the length
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
495 ; --- termite_newsession ---
497 EXPORT termite_newsession
498 termite_newsession ROUT
500 ; --- Read the base name ---
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
509 ; --- NULL terminate it ---
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.
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
523 ; --- Read the sub-style name ---
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
532 ; --- NULL terminate it ---
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
541 ; --- Now we keep on adding strings to the list ---
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
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
556 ; --- We have a string then ---
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
566 ; --- We have a string array ---
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
581 ; --- All the strings are in stracc now ---
583 ; First, we terminate the list
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
590 ; --- Now, point to the strings ---
592 LDR R5,tsc_stracc ;Load stracc anchor
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
598 TCALL termite_newSession ;Open the session
599 BL termite__error ;Handle possible error
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
607 ; --- termite_oscli ---
612 ; --- Read a parameter ---
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
621 LDR R1,tsc_stracc ;Get the stracc address
623 ADD R1,R1,R0,LSR #8 ;Point to the string
624 AND R2,R0,#&FF ;Get the length
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
636 ; --- termite_rclear ---
638 EXPORT termite_rclear
641 TCALL termite_clearRemote ;Clear the buffer
642 B interp_next ;And go for more
646 ; --- termite_recho ---
651 CMP R9,#tok_off ;Is this an option thingy?
655 BEQ %50termite_recho ;Yes -- deal seperately
657 ; --- Just echo the result to the screen then ---
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
668 ; --- Display a string ---
670 LDR R2,tsc_stracc ;Get the stracc address
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
679 ; --- Display an integer on the screen ---
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
689 ; --- Maybe write out the return char ---
691 20termite_recho CMP R9,#';' ;Is there a semicolon now?
692 BLEQ getToken ;Yes -- get a token
693 BEQ interp_next ;...read another instr
695 LDR R2,tsc_bucket ;Get the bucket anchor
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
706 ; --- Handle the options ---
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?
712 ORREQ R0,R0,#tscFlag_echoRL ;Yes -- set the flag
713 CMP R9,#tok_remote ;Do we require remote echos?
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
719 B interp_next ;Keep on going then!
723 ; --- termite_report ---
725 EXPORT termite_report
728 ; --- Read a parameter ---
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
737 LDR R1,tsc_stracc ;Get the stracc address
739 ADD R1,R1,R0,LSR #8 ;Point to the string
740 AND R2,R0,#&FF ;Get the length
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
752 ; --- termite_rinput ---
754 EXPORT termite_rinput
757 MOV R0,#1 ;Read an lvalue
758 BL express_read ;Read it in
760 ; --- Now enter a string reading loop ---
762 BL stracc_ensure ;Make sure that there's room
763 MOV R2,R0 ;Look after address
765 MOV R5,#0 ;The length so far
766 MOV R3,#1 ;Length of buffer to echo
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
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
779 ADDEQ R2,R2,R1,LSR #8
782 CMP R0,#127 ;Is this a delete?
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?
792 BLT %b00 ;No -- get some more then
793 B %f10 ;Finished -- jump ahead
795 ; --- Do a delete operation ---
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
811 ; --- We have finished reading the string ---
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
818 BL express_pop ;Get my lvalue off
819 BL ctrl_store ;Store this away
820 B interp_next ;Do another command
824 ; --- termite_rnewline ---
826 EXPORT termite_rnewline
827 termite_rnewline ROUT
829 CMP R9,#'=' ;Next char must be `='
830 MOVNE R0,#err_expEq ;If it isn't, moan
832 BL getToken ;Skip past the equals sign
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
846 ; --- termite_spool ---
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
857 ; --- Turn on spooling ---
859 ; Ooh, spooling, I really dig you.
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
868 ; --- Copy the string to the misc buffer ---
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
883 MOV R0,R2 ;Find the string rvalue
884 BL stracc_free ;Remove it from stracc
886 ; --- Make sure we're not spooling right now ---
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
893 ; --- Now open the file ---
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
902 ; --- Close the current file ---
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
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
915 ; --- termite_syscall ---
917 EXPORT termite_syscall
920 BL ctrl_setUpRegs ;Set up the regs then
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
933 TCALL termite_sysCall ;Call the call then!
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
940 ; --- Convert the string if needed ---
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
946 ; --- We have now done the SYSCALL instr ---
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
952 termite__retned DCD 0,0,0,0,0,0,0,0,0,0,0 ;For SYSCALL, CALL
956 ; --- termite_upload ---
958 EXPORT termite_upload
961 ; --- Read the protocol name ---
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
970 ; --- NULL terminate it ---
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.
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
986 ; --- Now we keep on adding strings to the list ---
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
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
1001 ; --- We have a string then ---
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
1011 ; --- We have a string array ---
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
1026 ; --- All the strings are in stracc now ---
1028 ; First, we terminate the list
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
1035 ; --- Now, point to the strings ---
1037 LDR R1,tsc_stracc ;Load stracc anchor
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
1043 TCALL termite_upLoad ;Upload the files
1044 BL termite__error ;Handle possible error
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
1052 ; --- termite_wait ---
1057 ; --- Read a parameter ---
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
1066 MOV R1,R0 ;Remember this time
1067 SWI OS_ReadMonotonicTime ;Read the current time
1068 ADD R1,R1,R0 ;Return after this time
1070 ; --- Now enter a waiting loop ---
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
1077 B interp_next ;Go round for next command
1081 ; --- termite_watchfor ---
1083 EXPORT termite_watchfor
1084 termite_watchfor ROUT
1086 ; --- See if we are ending the WATCHFOR ---
1088 CMP R9,#tok_end ;Are we ending it?
1089 BEQ %70termite_watchfor ;Yes -- jump ahead
1091 ; --- First, we must set up strings ---
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.
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
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
1106 ; --- Now read the strings one at a time ---
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
1114 ; --- We have a string array ---
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
1127 ; --- The array has finished ---
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
1133 ; --- See if it's a string then ---
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
1139 ; --- We have a string in stracc ---
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
1148 ; --- Do any more we have ---
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
1155 ; --- Now we must check the ring buffer ---
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.
1162 ADR R2,tsc_misc ;Point to the buffer
1163 MOV R3,#0 ;Number read so far
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
1175 ; --- Send on the buffer ---
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
1182 ; --- We have stopped reading bytes ---
1184 ; Either we ran out of bytes, or we got a match,
1185 ; for either case we do the same thing
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
1191 ; --- We are ending the watchfor ---
1193 70 BL getToken ;Gobble up the END
1194 BL termite__endWF ;End the WATCHFOR
1195 B interp_next ;Do the next command
1199 ; --- termite__endWF ---
1205 ; Use: Ends a WATCHFOR condition.
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
1222 05 STR R2,tsc_wForNumber ;Make that clear
1223 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
1227 ; --- termite__checkWF ---
1229 ; On entry: R0 == byte to check
1231 ; On exit: CS if that byte caused a match,
1234 ; Use: Tests all the strings in the WATCHFOR list, to see if
1235 ; the character caused a match. If it did, then WATCH
1238 termite__checkWF ROUT
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
1246 ; --- Get the information on the string ---
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
1258 ; --- Now do the comparison ---
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
1274 ; --- The characters matched ---
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
1281 ; --- Move onto the next string ---
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
1288 ; --- We found a matching string ---
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
1300 ; --- termite_remoteInput ---
1302 ; On entry: R0 == handle of script
1303 ; R2 == buffer containing bytes read
1304 ; R3 == number of bytes in buffer
1305 ; R11 == upcall block
1307 ; On exit: R2 == new buffer containing bytes to put into ring buffer
1308 ; R3 == number of bytes in this buffer
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.
1316 EXPORT termite_remoteInput
1317 termite_remoteInput ROUT
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
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
1329 ; --- Scan the buffer ---
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
1338 ; -- Send this buffer then ---
1340 BL termite_doREcho ;Send the buffer
1341 MOV R3,#0 ;Put nothing in the buffer
1342 B %90termite_remoteInput ;And return to caller
1344 ; --- We got a match ---
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
1351 90 LDMFD R13!,{R0,R4,R5,R12,PC}^ ;Return to caller
1355 ;----- Utility routines -----------------------------------------------------
1357 ; --- termite_copyString ---
1359 ; On entry: R0 == buffer to copy string to
1360 ; R1 == point to the string
1361 ; R2 == length of string to copy
1365 ; Use: Copies the string into the buffer.
1367 EXPORT termite_copyString
1368 termite_copyString ROUT
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
1382 ; --- termite_doLEcho ---
1384 ; On entry: R2 == pointer to the buffer
1385 ; R3 == number of bytes to send
1389 ; Use: Echos the buffer to local and remote according to the
1390 ; current flags, assuming the buffer came from the local input
1392 EXPORT termite_doLEcho
1393 termite_doLEcho ROUT
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
1408 ; --- termite_doREcho ---
1410 ; On entry: R2 == pointer to the buffer
1411 ; R3 == number of bytes to send
1415 ; Use: Echos the buffer to local and remote according to the
1416 ; current flags, assuming the buffer came from remote input
1418 EXPORT termite_doREcho
1419 termite_doREcho ROUT
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
1434 ; --- termite__doSpool ---
1436 ; On entry: R2 == pointer to data to spool
1437 ; R3 == size of the data
1441 ; Use: Maybe writes the data to the current spool file.
1443 termite__doSpool ROUT
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
1454 ; --- termite__storeStr ---
1456 ; On entry: R0 == rvalue of string
1458 ; On exit: R0 == offset into bucket of string
1460 ; Use: Puts the string in stracc, into the string bucket.
1462 termite__storeStr ROUT
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
1483 90 LDMFD R13!,{R1-R4,PC}^ ;Return to caller
1487 ; --- termite__enumArray ---
1489 ; On entry: R1 == offset of array definition
1490 ; R2 == item to read next
1492 ; On exit: CS if item found, and
1493 ; R0 == rvalue of item
1497 ; Use: Goes through an string array, returning each item.
1499 termite__enumArray ROUT
1501 STMFD R13!,{R1,R3,R4,R14} ;Stack registers
1502 LDR R3,tsc_varTree ;Point at the tree
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
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
1520 LDMFD R13!,{R1,R3,R4,R14} ;Load back registers
1521 ORRS PC,R14,#C_flag ;And return success
1523 95 LDMFD R13!,{R1,R3,R4,R14} ;Load back registers
1524 BICS PC,R14,#C_flag ;And return failure
1528 ; --- termite__error ---
1530 ; On entry: V flag and R0 determine error condition
1534 ; Use: This call will generate an error, if ERROR ON has been
1535 ; done, or set the ERROR$ variable otherwise.
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
1543 ; --- There was no error ---
1545 TST R1,#tscFlag_error ;Do we generate errors?
1546 BNE %90termite__error ;Yes -- just return then
1548 ; --- Put a NULL string into ERROR$ ---
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
1556 ; --- There was an error ---
1558 50 TST R1,#tscFlag_error ;Do we generate errors?
1559 BNE error_reportReal ;Yes -- report the error then
1561 ; --- Copy the string into ERROR$ ---
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
1573 ; --- Now copy over the string ---
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
1582 ; --- Return to caller ---
1584 90 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
1588 ;----- That's all, folks ----------------------------------------------------