chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / BAS / src / s / get
1 ;
2 ; get.s
3 ;
4 ; Parsing of simple objasm header files
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's BASIC Assembler Supplement.
12 ;
13 ; BAS is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; BAS is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with BAS.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sh.aofGen
37                 GET     sh.bas
38                 GET     sh.basTalk
39                 GET     sh.flex
40                 GET     sh.string
41                 GET     sh.workspace
42
43 ;----- Main code ------------------------------------------------------------
44
45                 AREA    |BAS$$Code|,CODE,READONLY
46
47 ; --- get ---
48 ;
49 ; On entry:     R7 == pointer to workspace
50 ;               R8-R12 as set up by BASIC
51 ;
52 ; On exit:      --
53 ;
54 ; CALL syntax:  filename
55 ;
56 ; Use:          Parses a Straylight format objasm header file and sets up
57 ;               BASIC variables appropriately.
58
59                 EXPORT  get
60 get             ROUT
61
62                 STMFD   R13!,{R0-R12,R14}       ;Save some registers
63                 STR     R12,[R7,#:INDEX:be__line] ;Save BASIC's LINE value
64                 MOV     R12,R7                  ;Set up my workspace pointer
65
66                 ; --- Find out if we need to do anything ---
67
68                 BL      aof_firstPass           ;Is this the first pass?
69                 LDMCCFD R13!,{R0-R12,PC}^       ;No -- then return to caller
70
71                 ; --- Load the file into a flex block ---
72
73                 BL      str_buffer              ;Find a string buffer
74                 BL      bas_argString           ;Read a string argument
75                 MOV     R7,R1                   ;Look after this pointer
76                 MOV     R0,#17                  ;Read information about file
77                 SWI     OS_File                 ;Find out the file info
78                 TST     R0,#1                   ;Is this a file?
79                 BEQ     %80get                  ;No -- then report error
80
81                 MOV     R0,#0                   ;Clear a flags word
82                 STR     R0,[R13,#-4]!           ;Save it on the stack
83                 SUB     R13,R13,#8              ;Make a flex anchor
84                 MOV     R0,R13                  ;Point at the anchor
85                 ADD     R1,R4,#1                ;Bump file size by 1
86                 BL      flex_alloc              ;Allocate lots of memory
87                 BCS     bas_noMem               ;If it failed, complain
88
89                 MOV     R0,#16                  ;Load a file name
90                 MOV     R1,R7                   ;Point to the file name
91                 LDR     R2,[R13,#0]             ;Load the flex pointer
92                 MOV     R3,#0                   ;Load file right here
93                 SWI     XOS_File                ;Load the file
94                 BVS     %90get                  ;If it failed, tidy up
95
96                 ; --- Set up for parsing the file ---
97                 ;
98                 ; Register allocation:
99                 ;
100                 ;   R12 == workspace
101                 ;   R11 == pointer to end of file
102                 ;   R10 == pointer to current position
103                 ;   R9 == pointer to next line start
104
105                 MOV     R14,#&10                ;Put a newline at the end
106                 LDR     R9,[R13,#0]             ;Load flex block base
107                 STRB    R14,[R9,R4]             ;Save at end of the file
108                 ADD     R11,R9,R4               ;Find the end of the file
109
110                 ; --- Loop throught the lines of the file ---
111
112 10get           BL      get__nextLine           ;Get the next line
113                 BCS     %70get                  ;If now finished, return
114
115                 ; --- See if there's a comment here ---
116
117                 MOV     R8,R10                  ;Remember current position
118                 BL      get__byte               ;Read a character
119                 BCS     %10get                  ;If end of line, loop back
120                 MOVMI   R8,#0                   ;If whitespace, no label
121                 BMI     %12get                  ;And skip on a little
122                 CMP     R0,#';'                 ;Is this a line comment?
123                 BEQ     %20get                  ;Yes -- may be active comment
124
125 11get           BL      get__byte               ;Read a character
126                 BPL     %11get                  ;And wait for whitespace
127
128                 ; --- Skip whitespace and find opcode ---
129
130 12get           MOV     R7,R10                  ;Remember current position
131                 BL      get__byte               ;Read a character
132                 BCS     %10get                  ;If end of line, loop back
133                 BMI     %12get                  ;If whitespace, loop back
134
135                 ; --- Find end of opcode ---
136
137 13get           MOV     R6,R10                  ;Remember current position
138                 BL      get__byte               ;Read a character
139                 BPL     %13get                  ;And wait for whitespace
140                 MOV     R14,#0                  ;Mark end of opcode
141                 STRB    R14,[R6,#0]             ;Terminate opcode string
142
143                 ; --- Attempt to match the opcode ---
144
145                 MOV     R1,R7                   ;Point to the opcode
146                 ADR     R0,get__table           ;Point to opcode table
147                 BL      get__match              ;Try to find a match
148                 MOV     R14,PC                  ;Set up return address
149                 ADDCS   PC,PC,R0,LSL #2         ;Do dispatch table things
150                 B       %10get                  ;And get the next line
151
152                 ; --- The dispatch table ---
153
154                 B       get__hash               ;Hash (#) directive
155                 B       get__hat                ;Hat (^) directive
156                 B       get__equ                ;EQU directive
157                 B       get__equ                ;EQU directive
158                 B       get__import             ;IMPORT dirctive
159                 B       get__macro              ;MACRO directive
160                 B       get__mend               ;MEND directive
161
162                 ; --- The directive table ---
163
164 get__table      DCB     "#",0
165                 DCB     "^",0
166                 DCB     "EQU",0
167                 DCB     "*",0
168                 DCB     "IMPORT",0
169                 DCB     "MACRO",0
170                 DCB     "MEND",0
171                 DCB     0
172
173                 ; --- Found an active comment ---
174                 ;
175                 ; We use active comments to give this specific parser
176                 ; instructions, of which objasm should be blissfully
177                 ; unaware.  This is used to load BASIC macro libraries
178                 ; which we use instead of the objasm ones.
179
180 20get           BL      get__byte               ;Read the next byte
181                 BCS     %10get                  ;If end-of-line, move on
182                 CMP     R0,#'+'                 ;Is it a BAS active comment?
183                 BNE     %10get                  ;No -- ignore this line
184
185                 ; --- Find start of directive ---
186
187 21get           MOV     R7,R10                  ;Remember this position
188                 BL      get__byte               ;Get another byte
189                 BCS     %10get                  ;If end-of-line, ignore it
190                 BMI     %21get                  ;If whitespace, skip on
191
192 22get           MOV     R6,R10                  ;Remember end of directive
193                 BL      get__byte               ;Get another byte
194                 BPL     %22get                  ;If nonwhitespace, skip
195                 MOV     R14,#0                  ;Null terminate the directive
196                 STRB    R14,[R6,#0]             ;Save the null byte then
197
198                 ; --- Call the correct directive ---
199
200                 ADR     R0,get__actComm         ;Point to directive table
201                 MOV     R1,R7                   ;Point to this directive
202                 BL      get__match              ;Try to match the name
203                 MOV     R14,PC                  ;Set up a return address
204                 ADDCS   PC,PC,R0,LSL #2         ;Dispatch through the table
205                 B       %10get                  ;And get the next line
206
207                 ; --- The dispatch table ---
208
209                 B       get__lib                ;Include BASIC macro lib
210
211                 ; --- Active comment directives ---
212
213 get__actComm    DCB     "LIB",0
214                 DCB     0
215
216                 ; --- Close the file and return ---
217
218 70get           MOV     R0,R13                  ;Point to flex anchor
219                 BL      flex_free               ;Free the block
220                 BL      flex_compact            ;And reduce memory usage
221                 ADD     R13,R13,#12             ;Restore the stack pointer
222                 LDMFD   R13!,{R0-R12,PC}^       ;Return to caller
223
224 90get           MOV     R10,R0                  ;Look after error pointer
225                 MOV     R0,R13                  ;Point to flex anchor
226                 BL      flex_free               ;Free the block
227                 BL      flex_compact            ;And reduce memory usage
228                 ADD     R13,R13,#12             ;Restore the stack pointer
229                 MOV     R0,R10                  ;Get error back again
230                 SWI     OS_GenerateError        ;And raise the error
231
232 80get           MOV     R2,R0                   ;Get returned object type
233                 MOV     R0,#19                  ;Return error message
234                 SWI     OS_File                 ;Make the error
235
236                 LTORG
237
238 ; --- get__hat ---
239 ;
240 ; On entry:     R9 == pointer to end of line
241 ;               R10 == pointer to directive operands
242 ;               R11 == pointer to end of file
243 ;
244 ; On exit:      R0-R8, R10 corrupted
245 ;
246 ; Use:          Handles a hat (^) directive.
247
248 get__hat        ROUT
249
250                 STMFD   R13!,{R14}              ;Save some registers
251
252                 ; --- Find start of operands ---
253
254 00get__hat      MOV     R8,R10                  ;Remember current position
255                 BL      get__byte               ;Read another byte
256                 BMI     %00get__hat             ;If whitespace, skip on
257
258                 ; --- Now find the end ---
259
260                 MOV     R1,#32                  ;Make whitespace into spaces
261 10get__hat      MOV     R7,R10                  ;Remember current position
262                 BL      get__byte               ;Read another byte
263                 BCS     %15get__hat             ;If end-of-line, skip out
264                 STRMIB  R1,[R7,#0]              ;If whitespace, space it
265                 CMP     R0,#','                 ;Could be a comma, maybe
266                 CMPNE   R0,#';'                 ;Also stop at a comment
267                 BNE     %10get__hat             ;If not, keep going
268
269 15get__hat      MOV     R14,#0                  ;Null terminate expression
270                 STRB    R14,[R7,#0]             ;Done that then
271
272                 ; --- Evaluate the expression ---
273
274                 MOV     R1,R8                   ;Point to the expression
275                 BL      bTalk_eval              ;Evaluate the expression
276
277                 STR     R0,[R13,#8]             ;Save the new `at' value
278                 LDMFD   R13!,{PC}^              ;And return to caller
279
280                 LTORG
281
282 ; --- get__hash ---
283 ;
284 ; On entry:     R8 == pointer to label, or 0
285 ;               R9 == pointer to end of line
286 ;               R10 == pointer to directive operands
287 ;               R11 == pointer to end of file
288 ;
289 ; On exit:      R0-R8, R10 corrupted
290 ;
291 ; Use:          Handles a hash (#) directive.
292
293 get__hash       ROUT
294
295                 STMFD   R13!,{R14}              ;Save some registers
296
297                 ; --- Find start of operands ---
298
299 00get__hash     MOV     R7,R10                  ;Remember current position
300                 BL      get__byte               ;Read another byte
301                 BMI     %00get__hash            ;If whitespace, skip on
302
303                 ; --- Now find the end ---
304
305                 MOV     R1,#32                  ;Make whitespace into spaces
306 10get__hash     MOV     R6,R10                  ;Remember current position
307                 BL      get__byte               ;Read another byte
308                 BCS     %15get__hash            ;If end-of-line, skip out
309                 STRMIB  R1,[R6,#0]              ;If whitespace, space it
310                 CMP     R0,#';'                 ;Also stop at a comment
311                 BNE     %10get__hash            ;If not, keep going
312
313 15get__hash     MOV     R14,#0                  ;Null terminate expression
314                 STRB    R14,[R6,#0]             ;Done that then
315
316                 ; --- Save the current `at' value ---
317
318                 LDR     R2,[R13,#8]             ;Load current `at' value
319                 MOVS    R0,R8                   ;Point to label name
320                 BEQ     %20get__hash            ;No label -- don't assign
321
322                 BL      bTalk_create            ;Create the variable
323                 BL      bTalk_store             ;Store that in lvalue
324
325                 ; --- Evaluate the expression ---
326
327 20get__hash     MOV     R1,R7                   ;Point to the expression
328                 BL      bTalk_eval              ;Evaluate the expression
329                 ADD     R0,R0,R2                ;Increment the `at' value
330                 STR     R0,[R13,#8]             ;And store it back
331
332                 LDMFD   R13!,{PC}^              ;And return to caller
333
334                 LTORG
335
336 ; --- get__equ ---
337 ;
338 ; On entry:     R8 == pointer to label, or 0
339 ;               R9 == pointer to end of line
340 ;               R10 == pointer to directive operands
341 ;               R11 == pointer to end of file
342 ;
343 ; On exit:      R0-R8, R10 corrupted
344 ;
345 ; Use:          Handles an EQU directive.
346
347 get__equ        ROUT
348
349                 STMFD   R13!,{R14}              ;Save some registers
350                 LDR     R14,[R13,#12]           ;Load the flags word
351                 TST     R14,#1                  ;Are we in macro?
352                 LDMNEFD R13!,{PC}^              ;Yes -- return to caller
353
354                 ; --- Find start of operands ---
355
356 00get__equ      MOV     R7,R10                  ;Remember current position
357                 BL      get__byte               ;Read another byte
358                 BMI     %00get__equ             ;If whitespace, skip on
359
360                 ; --- Now find the end ---
361
362                 MOV     R1,#32                  ;Turn whitespace into spaces
363 10get__equ      MOV     R6,R10                  ;Remember current position
364                 BL      get__byte               ;Read another byte
365                 BCS     %15get__equ             ;If end-of-line, skip out
366                 STRMIB  R1,[R6,#0]              ;If whitespace, space it
367                 CMP     R0,#';'                 ;Also stop at a comment
368                 BNE     %10get__equ             ;If not, keep going
369
370 15get__equ      MOV     R14,#0                  ;Null terminate expression
371                 STRB    R14,[R6,#0]             ;Done that then
372
373                 ; --- Evaluate the expression ---
374
375                 MOV     R1,R7                   ;Point to the operand
376                 BL      bTalk_eval              ;Evaluate it nicely
377                 MOV     R2,R0                   ;This is the value to store
378
379                 MOV     R0,R8                   ;Point to label
380                 BL      bTalk_create            ;Create the variable
381                 BL      bTalk_store             ;And store the value away
382
383                 LDMFD   R13!,{PC}^              ;And return to caller
384
385                 LTORG
386
387 ; --- get__import ---
388 ;
389 ; On entry:     R9 == pointer to end of line
390 ;               R10 == pointer to directive operands
391 ;               R11 == pointer to end of file
392 ;
393 ; On exit:      R0-R8, R10 corrupted
394 ;
395 ; Use:          Handles an IMPORT directive.
396
397 get__import     ROUT
398
399                 STMFD   R13!,{R14}              ;Save some registers
400                 LDR     R14,[R13,#12]           ;Load the flags word
401                 TST     R14,#1                  ;Are we in macro?
402                 LDMNEFD R13!,{PC}^              ;Yes -- return to caller
403
404                 ; --- Find start of operands ---
405
406 00get__import   MOV     R7,R10                  ;Remember current position
407                 BL      get__byte               ;Read another byte
408                 BMI     %00get__import          ;If whitespace, skip on
409
410                 ; --- Now find the end ---
411
412                 MOV     R1,#32                  ;Turn whitespace into spaces
413 10get__import   MOV     R6,R10                  ;Remember current position
414                 BL      get__byte               ;Read another byte
415                 BCS     %15get__import          ;If end-of-line, skip out
416                 STRMIB  R1,[R6,#0]              ;If whitespace, space it
417                 CMP     R0,#';'                 ;Also stop at a comment
418                 BNE     %10get__import          ;If not, keep going
419
420 15get__import   MOV     R14,#0                  ;Null terminate expression
421                 STRB    R14,[R6,#0]             ;Done that then
422
423                 ; --- Now import the symbol ---
424
425                 MOV     R0,R7                   ;Point to operand name
426                 MOV     R1,R7                   ;Make this the alias too
427                 MOV     R3,#0                   ;No special attributes
428                 FSAVE   R9-R11                  ;Save the block pointers
429                 BL      aof_import              ;Import the symbol
430                 FLOAD   R9-R11                  ;Load them back again
431                 LDMFD   R13!,{PC}^              ;And return to caller
432
433                 LTORG
434
435 ; --- get__macro ---
436 ;
437 ; On entry:     --
438 ;
439 ; On exit:      R0-R8 corrupted
440 ;
441 ; Use:          Sets the `in a macro' flag, so that strange EQU directives
442 ;               don't get read.
443
444 get__macro      ROUT
445
446                 LDR     R0,[R13,#8]             ;Load the flags word
447                 ORR     R0,R0,#1                ;Set the flag
448                 STR     R0,[R13,#8]             ;Save the flags back
449                 MOVS    PC,R14                  ;Return to caller
450
451                 LTORG
452
453 ; --- get__mend ---
454 ;
455 ; On entry:     --
456 ;
457 ; On exit:      R0-R8 corrupted
458 ;
459 ; Use:          Clears the `in a macro' flag, so that strange EQU directives
460 ;               don't get read.
461
462 get__mend       ROUT
463
464                 LDR     R0,[R13,#8]             ;Load the flags word
465                 BIC     R0,R0,#1                ;Clear the flag
466                 STR     R0,[R13,#8]             ;Save the flags back
467                 MOVS    PC,R14                  ;Return to caller
468
469                 LTORG
470
471 ; --- get__lib ---
472 ;
473 ; On entry:     --
474 ;
475 ; On exit:      --
476 ;
477 ; Use:          Loads a macro library.  This is done so that an objasm
478 ;               header file can load BASIC macros as appropriate, since
479 ;               objasm macros are obviously not much use.  We do this by
480 ;               evaluating a call to FNlib(), which the BASIC part will
481 ;               implement as loading a library.
482
483 get__lib        ROUT
484
485                 STMFD   R13!,{R14}              ;Save the link register
486
487                 ; --- Find start of operands ---
488
489 00get__lib      MOV     R7,R10                  ;Remember current position
490                 BL      get__byte               ;Read another byte
491                 BMI     %00get__lib             ;If whitespace, skip on
492
493                 ; --- Now find the end ---
494
495 10get__lib      MOV     R6,R10                  ;Remember current position
496                 BL      get__byte               ;Read another byte
497                 BCS     %15get__lib             ;If end-of-line, skip out
498                 CMP     R0,#';'                 ;Also stop at a comment
499                 BNE     %10get__lib             ;If not, keep going
500
501 15get__lib      MOV     R14,#0                  ;Null terminate expression
502                 STRB    R14,[R6,#0]             ;Done that then
503
504                 ; --- Build the string to evaluate ---
505
506                 BL      str_buffer              ;Get a buffer
507                 ADR     R0,get__libSkel         ;Point to skeleton string
508                 BL      str_subst               ;Build the correct invocation
509                 MOV     R1,R0                   ;Point to the string built
510                 BL      bTalk_eval              ;Evaluate the expression
511
512                 LDMFD   R13!,{PC}^              ;And return to caller
513
514 get__libSkel    DCB     "FNbas_lib(""%5"")",0
515
516                 LTORG
517
518 ; --- get__nextLine ---
519 ;
520 ; On entry:     R9 == pointer to start of next line
521 ;               R11 == pointer to end of file
522 ;
523 ; On exit:      CC if more to come, and
524 ;                 R9 == pointer to start of next line line
525 ;                 R10 == pointer to next line
526 ;               else CS if end of file reached and
527 ;                 R9, R10 corrupted
528 ;               R0 always corrupted
529 ;
530 ; Use:          Finds the start address of the next line
531
532 get__nextLine   ROUT
533
534                 CMP     R9,R11                  ;Are we at end of file?
535                 ORRCSS  PC,R14,#C_flag          ;Yes -- return with C set
536
537                 MOV     R10,R9                  ;Point to the next line
538 00get__nextLine LDRB    R0,[R9],#1              ;Get next character
539                 CMP     R0,#&0A                 ;Is this a newline?
540                 BNE     %00get__nextLine        ;No -- go round for more then
541                 LDRB    R0,[R9,#0]              ;Load the next byte
542                 CMP     R0,#&0D                 ;Is this a carriage return?
543                 ADDEQ   R0,R0,#1                ;Yes -- then move along one
544                 BICS    PC,R14,#C_flag          ;And return with C clear
545
546                 LTORG
547
548 ; --- get__byte ---
549 ;
550 ; On entry:     R10 == pointer to next byte
551 ;
552 ; On exit:      CC if read a byte, and
553 ;                 R0 == byte read
554 ;                 R10 moved to byte after
555 ;                 MI if byte is whitespace, else PL
556 ;               else CS if end of line and
557 ;                 R0, R10 corrupted
558 ;
559 ; Use:          Reads a byte from the block
560
561 get__byte       ROUT
562
563                 LDRB    R0,[R10],#1             ;Load a byte
564                 CMP     R10,R9                  ;Reached end of line yet?
565                 ORRCSS  PC,R14,#C_flag + N_flag ;Yes -- set C on exit then
566                 BIC     R14,R14,#C_flag         ;Clear R14's C flag ready
567                 CMP     R0,#&9                  ;Is it a tab?
568                 CMPNE   R0,#&0C                 ;Or a form feed? (oddness)
569                 CMPNE   R0,#&0D                 ;Or a carriage return?
570                 CMPNE   R0,#&20                 ;Or a space, indeed?
571                 ORREQS  PC,R14,#N_flag          ;Yes -- set the N flag
572                 BICNES  PC,R14,#N_flag          ;Otherwise clear N
573
574                 LTORG
575
576 ; --- get__match ---
577 ;
578 ; On entry:     R0 == pointer to command line argument table
579 ;               R1 == pointer to command line word read (null terminated)
580 ;
581 ; On exit:      CS if word found in table and
582 ;                 R0 == index of item matched
583 ;               else CC and
584 ;                 R0 corrupted
585 ;
586 ; Use:          Looks up a given word in the command table given.  The
587 ;               command table consists of null-terminated strings, and is
588 ;               itself terminated by a null entry.
589 ;
590 ;               Matching is not case sensitive.  Indexing is from 0.
591
592 get__match      ROUT
593
594                 STMFD   R13!,{R1-R5,R14}        ;Save some registers
595                 MOV     R2,#0                   ;Index of the current item
596                 LDRB    R14,[R1,#0]             ;Load the first byte
597                 CMP     R14,#0                  ;Is it a null string?
598                 BEQ     %90get__match           ;Yes -- no match then
599
600                 ; --- The main loop ---
601
602 00get__match    MOV     R3,R1                   ;Point to argument start
603                 LDRB    R4,[R0],#1              ;Load a byte from the table
604                 LDRB    R5,[R3],#1              ;Load a byte from the arg
605                 CMP     R4,#0                   ;Is this an empty string?
606                 BEQ     %90get__match           ;Yes -- no match then
607
608                 ; --- Try to match a word ---
609
610 10get__match    CMP     R5,#0                   ;End of argument string?
611                 CMPEQ   R4,#0                   ;And end of match string?
612                 BEQ     %80get__match           ;Yes -- that's a match then
613                 SUB     R14,R4,#'a'             ;Subtract the bottom limit
614                 CMP     R14,#26                 ;Is it a lower case letter?
615                 BICLO   R4,R4,#&20              ;Yes -- convert to upper
616                 SUB     R14,R5,#'a'             ;Subtract the bottom limit
617                 CMP     R14,#26                 ;Is it a lower case letter?
618                 BICLO   R5,R5,#&20              ;Yes -- convert to upper
619                 CMP     R4,R5                   ;Do characters match up?
620                 LDREQB  R4,[R0],#1              ;Load a byte from the table
621                 LDREQB  R5,[R3],#1              ;Load a byte from the arg
622                 BEQ     %10get__match           ;Yes -- go round for more
623
624                 ; --- Failed -- find end of table entry ---
625
626 20get__match    CMP     R4,#0                   ;End of entry string?
627                 LDRNEB  R4,[R0],#1              ;No -- load byte from table
628                 BNE     %20get__match           ;And go round again
629                 ADD     R2,R2,#1                ;Increment item index
630                 B       %00get__match           ;Loop round for next entry
631
632                 ; --- Found a match ---
633
634 80get__match    MOV     R0,R2                   ;Get the item index
635                 LDMFD   R13!,{R1-R5,R14}        ;Unstack the registers
636                 ORRS    PC,R14,#C_flag          ;And return with C set
637
638                 ; --- No match found ---
639
640 90get__match    LDMFD   R13!,{R1-R5,R14}        ;Unstack the registers
641                 BICS    PC,R14,#C_flag          ;And return with C clear
642
643                 LTORG
644
645 ;----- That's all, folks ----------------------------------------------------
646
647                 END
648