Subversion Repositories MB01 Project

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 - 1
  Tue Jul 17 11:00:21 2018                                                                                               Page    1
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
          2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
10
          -----------------------------------------------------
11
 
12
                       Input  Filename : src\FA\string.asm
13
                       Output Filename : obj\FA\string.obj
14
                       Listing Has Been Relocated
15
 
16
 
17
 2603                        	.LIST		on
18
 2604
19
 2605
20
 2606                        	.LIST on
21
 2607
22
 2608
23
 2609                        	;---------------------------------------------------------------------------
24
 2610                        	; code segment -- bank $FA
25
 2611                        	;---------------------------------------------------------------------------
26
 2612
27
 2613                        		.CODEFA
28
 2614
29
 2615                        		.LONGA	off
30
 2616                        		.LONGI	off
31
 2617
32
 2618                        	; _strlen(src)
33
 2619                        	;
34
 2620                        	; return in C the length of the string src
35
 2621                        	; if the lenght is greater than 64k return $FFFF
36
 2622                        	;
37
 2623                        	;-------------------------------
38
 2624  FA03F7                	_strlen:
39
 2625                        		.PUBLIC _strlen
40
 2626                        	;-------------------------------
41
 2627
42
 2628                        		.LONGA	off
43
 2629                        		.LONGI	off
44
 2630  FA03F7
45
 2631          000003        	parsiz	.SET	3		; parameter stack frame size
46
 2632          000000        	locsiz	.SET	0		; locals stack frame size
47
 2633          000003        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
48
 2634          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
49
 2635          000004        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
50
 2636                        	;
51
 2637          000005        	src	.SET	entsr + 4	; <src> parameter
52
 2638                        	;
53
 2639  FA03F7  08            		php			; save SR
54
 2640  FA03F8  3B            		tsc			; stack frame
55
 2641  FA03F9  0B            		phd			; save DP reg.
56
 2642  FA03FA  5B            		tcd			; dp access to stack var's
57
 2643  FA03FB                		INDEX16			; X/Y 16 bit
58
 2644  FA03FB  C2 10         		rep	#PXFLAG
59
 2645                        		.LONGI	on
60
 2646                        		.MNLIST
61
 2647  FA03FD                		ACC08			; be sure A 8 bit
62
 2648  FA03FD  E2 20         		sep	#PMFLAG
63
  Tue Jul 17 11:00:21 2018                                                                                               Page    2
64
 
65
 
66
 
67
 
68
 2649                        		.LONGA	off
69
 2650                        		.MNLIST
70
 2651  FA03FF  A0 00 00      		ldy	#0		; pointer
71
 2652                        	;
72
 2653  FA0402  B7 05         	?loop:	lda	[src],y		; get next char
73
 2654  FA0404  F0 04         		beq	?done		; done when get a nul
74
 2655  FA0406  C8            		iny			; bump pointer
75
 2656  FA0407  D0 F9         		bne	?loop
76
 2657  FA0409  88            		dey			; max length = $FFFF
77
 2658                        	;
78
 2659  FA040A                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
79
 2660  FA040A  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
80
 2661                        		.LONGA	on
81
 2662                        		.LONGI	on
82
 2663                        		.MNLIST
83
 2664  FA040C  A5 03         		lda	<entsr+2	; move saved SR and return address
84
 2665  FA040E  85 06         		sta	<exitsr+2
85
 2666  FA0410  A5 01         		lda	<entsr
86
 2667  FA0412  85 04         		sta	<exitsr
87
 2668  FA0414  2B            		pld			; restore DP reg.
88
 2669  FA0415  3B            		tsc			; stack frame
89
 2670  FA0416  69 03 00      		adc	#skpsiz		; realign stack
90
 2671  FA0419  1B            		tcs
91
 2672  FA041A  98            		tya			; C = string length
92
 2673  FA041B  28            		plp			; restore SR
93
 2674  FA041C  6B            		rtl
94
 2675
95
 2676                        		.LONGA	off
96
 2677                        		.LONGI	off
97
 2678
98
 2679                        	; _strcpy(dst, src)
99
 2680                        	;
100
 2681                        	; copy string src to dst
101
 2682                        	; return in C the lenght of string
102
 2683                        	; dst must have sufficient room to hold the result
103
 2684                        	; if length of src > $FFFF, dst will be truncated
104
 2685                        	;
105
 2686                        	;-------------------------------
106
 2687  FA041D                	_strcpy:
107
 2688                        		.PUBLIC _strcpy
108
 2689                        	;-------------------------------
109
 2690
110
 2691                        		.LONGA	off
111
 2692                        		.LONGI	off
112
 2693  FA041D
113
 2694          000006        	parsiz	.SET	6		; parameter stack frame size
114
 2695          000000        	locsiz	.SET	0		; locals stack frame size
115
 2696          000006        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
116
 2697          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
117
 2698          000007        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
118
 2699                        	;
119
 2700          000005        	src	.SET	entsr + 4	; <src> parameter
120
 2701          000008        	dst	.SET	src + 3		; <dst> parameter
121
 2702                        	;
122
 2703  FA041D  08            		php			; save SR
123
 2704  FA041E  3B            		tsc			; stack frame
124
 2705  FA041F  0B            		phd			; save DP reg.
125
  Tue Jul 17 11:00:21 2018                                                                                               Page    3
126
 
127
 
128
 
129
 
130
 2706  FA0420  5B            		tcd			; dp access to stack var's
131
 2707  FA0421                		INDEX16			; X/Y 16 bit
132
 2708  FA0421  C2 10         		rep	#PXFLAG
133
 2709                        		.LONGI	on
134
 2710                        		.MNLIST
135
 2711  FA0423                		ACC08			; be sure A 8 bit
136
 2712  FA0423  E2 20         		sep	#PMFLAG
137
 2713                        		.LONGA	off
138
 2714                        		.MNLIST
139
 2715  FA0425  A0 00 00      		ldy	#0		; pointer
140
 2716                        	;
141
 2717  FA0428  B7 05         	?loop:	lda	[src],y		; get next char
142
 2718  FA042A  97 08         		sta	[dst],y		; store
143
 2719  FA042C  F0 07         		beq	?done		; done when get a null
144
 2720  FA042E  C8            		iny			; bump pointer
145
 2721  FA042F  D0 F7         		bne	?loop
146
 2722  FA0431  98            		tya			; A=0
147
 2723  FA0432  88            		dey			; max length = $FFFF
148
 2724  FA0433  97 08         		sta	[dst],y		; always NUL terminates dst
149
 2725                        	;
150
 2726  FA0435                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
151
 2727  FA0435  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
152
 2728                        		.LONGA	on
153
 2729                        		.LONGI	on
154
 2730                        		.MNLIST
155
 2731  FA0437  A5 03         		lda	<entsr+2	; move saved SR and return address
156
 2732  FA0439  85 09         		sta	<exitsr+2
157
 2733  FA043B  A5 01         		lda	<entsr
158
 2734  FA043D  85 07         		sta	<exitsr
159
 2735  FA043F  2B            		pld			; restore DP reg.
160
 2736  FA0440  3B            		tsc			; stack frame
161
 2737  FA0441  69 06 00      		adc	#skpsiz		; realign stack
162
 2738  FA0444  1B            		tcs
163
 2739  FA0445  98            		tya			; C = string length
164
 2740  FA0446  28            		plp			; restore SR
165
 2741  FA0447  6B            		rtl
166
 2742
167
 2743                        		.LONGA	off
168
 2744                        		.LONGI	off
169
 2745
170
 2746                        	; _strcat(str, append)
171
 2747                        	;
172
 2748                        	; append string append to string str
173
 2749                        	; return in C the lenght of string
174
 2750                        	; str must have sufficient room to hold the result
175
 2751                        	;
176
 2752                        	;-------------------------------
177
 2753  FA0448                	_strcat:
178
 2754                        		.PUBLIC _strcat
179
 2755                        	;-------------------------------
180
 2756
181
 2757                        		.LONGA	off
182
 2758                        		.LONGI	off
183
 2759  FA0448
184
 2760          000006        	parsiz	.SET	6		; parameter stack frame size
185
 2761          000002        	locsiz	.SET	2		; locals stack frame size
186
 2762          000008        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
187
  Tue Jul 17 11:00:21 2018                                                                                               Page    4
188
 
189
 
190
 
191
 
192
 2763          000003        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
193
 2764          000009        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
194
 2765                        	;
195
 2766          000007        	append	.SET	entsr + 4	; <append> parameter
196
 2767          00000A        	str	.SET	append + 3	; <str> parameter
197
 2768                        	;
198
 2769          000001        	indx	.SET	1		; <indx>: local var
199
 2770                        	;
200
 2771  FA0448  08            		php			; save SR
201
 2772  FA0449                		INDEX16			; X/Y 16 bit
202
 2773  FA0449  C2 10         		rep	#PXFLAG
203
 2774                        		.LONGI	on
204
 2775                        		.MNLIST
205
 2776  FA044B  A0 00 00      		ldy	#0		; pointer
206
 2777  FA044E  5A            		phy			; make room for local var <indx=0>
207
 2778  FA044F  3B            		tsc			; stack frame
208
 2779  FA0450  0B            		phd			; save DP reg.
209
 2780  FA0451  5B            		tcd			; dp access to stack var's
210
 2781  FA0452                		ACC08			; be sure A is 8 bit
211
 2782  FA0452  E2 20         		sep	#PMFLAG
212
 2783                        		.LONGA	off
213
 2784                        		.MNLIST
214
 2785                        	;
215
 2786  FA0454  B7 0A         	?loop:	lda	[str],y		; search end of string str
216
 2787  FA0456  F0 06         		beq	?cat		; done when get a nul
217
 2788  FA0458  C8            		iny			; bump pointer
218
 2789  FA0459  D0 F9         		bne	?loop
219
 2790  FA045B  88            		dey			; max length = $FFFF
220
 2791  FA045C  80 13         		bra	?done		; can't append more char's
221
 2792                        	;
222
 2793  FA045E  BB            	?cat:	tyx			; X = current str index
223
 2794  FA045F  A4 01         		ldy	<indx		; index to append string
224
 2795  FA0461  B7 07         		lda	[append],y	; get next char from append
225
 2796  FA0463  C8            		iny			; bump pointer to append string
226
 2797  FA0464  84 01         		sty	<indx
227
 2798  FA0466  9B            		txy
228
 2799  FA0467  97 0A         		sta	[str],y		; append char to str
229
 2800  FA0469  C9 00         		cmp	#0		; nul?
230
 2801  FA046B  F0 04         		beq	?done		; yes
231
 2802  FA046D  C8            		iny			; bump pointer
232
 2803  FA046E  D0 EE         		bne	?cat		; append next char
233
 2804  FA0470  88            		dey			; max length = $FFFF
234
 2805                        	;
235
 2806  FA0471                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
236
 2807  FA0471  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
237
 2808                        		.LONGA	on
238
 2809                        		.LONGI	on
239
 2810                        		.MNLIST
240
 2811  FA0473  A5 05         		lda	<entsr+2	; move saved SR and return address
241
 2812  FA0475  85 0B         		sta	<exitsr+2
242
 2813  FA0477  A5 03         		lda	<entsr
243
 2814  FA0479  85 09         		sta	<exitsr
244
 2815  FA047B  2B            		pld			; restore DP reg.
245
 2816  FA047C  3B            		tsc			; stack frame
246
 2817  FA047D  69 08 00      		adc	#skpsiz		; realign stack
247
 2818  FA0480  1B            		tcs
248
 2819  FA0481  98            		tya			; C = string length
249
  Tue Jul 17 11:00:21 2018                                                                                               Page    5
250
 
251
 
252
 
253
 
254
 2820  FA0482  28            		plp			; restore SR
255
 2821  FA0483  6B            		rtl
256
 2822
257
 2823                        		.LONGA	off
258
 2824                        		.LONGI	off
259
 2825
260
 2826                        	; _strncpy(dst, src, siz)
261
 2827                        	;
262
 2828                        	; copy string src to string dst of size <siz+1>
263
 2829                        	; at most siz characters will be copied
264
 2830                        	; return in C the lenght of string
265
 2831                        	; if <siz=0> src is an empty string
266
 2832                        	;
267
 2833                        	;-------------------------------
268
 2834  FA0484                	_strncpy:
269
 2835                        		.PUBLIC _strncpy
270
 2836                        	;-------------------------------
271
 2837
272
 2838                        		.LONGA	off
273
 2839                        		.LONGI	off
274
 2840  FA0484
275
 2841          000008        	parsiz	.SET	8		; parameter stack frame size
276
 2842          000000        	locsiz	.SET	0		; locals stack frame size
277
 2843          000008        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
278
 2844          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
279
 2845          000009        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
280
 2846                        	;
281
 2847          000005        	siz	.SET	entsr + 4	; <siz> parameter
282
 2848          000007        	src	.SET	siz + 2		; <src> parameter
283
 2849          00000A        	dst	.SET	src + 3		; <dst> parameter
284
 2850                        	;
285
 2851  FA0484  08            		php			; save SR
286
 2852  FA0485  3B            		tsc			; stack frame
287
 2853  FA0486  0B            		phd			; save DP reg.
288
 2854  FA0487  5B            		tcd			; dp access to stack var's
289
 2855  FA0488                		INDEX16			; X/Y 16 bit
290
 2856  FA0488  C2 10         		rep	#PXFLAG
291
 2857                        		.LONGI	on
292
 2858                        		.MNLIST
293
 2859  FA048A                		ACC08			; be sure A 8 bit
294
 2860  FA048A  E2 20         		sep	#PMFLAG
295
 2861                        		.LONGA	off
296
 2862                        		.MNLIST
297
 2863  FA048C  A4 05         		ldy	<siz
298
 2864  FA048E  F0 0E         		beq	?nul		; return an empty string
299
 2865  FA0490  A0 00 00      		ldy	#0		; pointer
300
 2866                        	;
301
 2867  FA0493  B7 07         	?loop:	lda	[src],y		; get next char
302
 2868  FA0495  97 0A         		sta	[dst],y		; store
303
 2869  FA0497  F0 09         		beq	?done		; done when get a null
304
 2870  FA0499  C8            		iny			; bump pointer
305
 2871  FA049A  C4 05         		cpy	<siz
306
 2872  FA049C  90 F5         		bcc	?loop
307
 2873                        	;
308
 2874  FA049E  A9 00         	?nul:	lda	#0		; always NUL terminates dst
309
 2875  FA04A0  97 0A         		sta	[dst],y
310
 2876                        	;
311
  Tue Jul 17 11:00:21 2018                                                                                               Page    6
312
 
313
 
314
 
315
 
316
 2877  FA04A2                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
317
 2878  FA04A2  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
318
 2879                        		.LONGA	on
319
 2880                        		.LONGI	on
320
 2881                        		.MNLIST
321
 2882  FA04A4  A5 03         		lda	<entsr+2	; move saved SR and return address
322
 2883  FA04A6  85 0B         		sta	<exitsr+2
323
 2884  FA04A8  A5 01         		lda	<entsr
324
 2885  FA04AA  85 09         		sta	<exitsr
325
 2886  FA04AC  2B            		pld			; restore DP reg.
326
 2887  FA04AD  3B            		tsc			; stack frame
327
 2888  FA04AE  69 08 00      		adc	#skpsiz		; realign stack
328
 2889  FA04B1  1B            		tcs
329
 2890  FA04B2  98            		tya			; C = string length
330
 2891  FA04B3  28            		plp			; restore SR
331
 2892  FA04B4  6B            		rtl
332
 2893
333
 2894                        		.LONGA	off
334
 2895                        		.LONGI	off
335
 2896
336
 2897                        	; _strdel(str, start, count)
337
 2898                        	;
338
 2899                        	; remove at most <count> characters from string <str>, starting
339
 2900                        	; at index <start>
340
 2901                        	;
341
 2902                        	;	stack param's:
342
 2903                        	;
343
 2904                        	;	<str>:		long pointer to string
344
 2905                        	;	<start>:	index of first character to remove (word)
345
 2906                        	;	<count>:	count of characters to remove (word)
346
 2907                        	;
347
 2908                        	;	return:		C = length of string
348
 2909                        	;
349
 2910                        	;	note:		X & Y not preserved
350
 2911                        	;
351
 2912                        	;-------------------------------
352
 2913  FA04B5                	_strdel:
353
 2914                        		.PUBLIC _strdel
354
 2915                        	;-------------------------------
355
 2916
356
 2917                        		.LONGA	off
357
 2918                        		.LONGI	off
358
 2919  FA04B5
359
 2920          000007        	parsiz	.SET	7		; parameter stack frame size
360
 2921          000000        	locsiz	.SET	0		; locals stack frame size
361
 2922          000007        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
362
 2923          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
363
 2924          000008        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
364
 2925                        	;
365
 2926          000005        	count	.SET	entsr + 4	; <count> parameter
366
 2927          000007        	start	.SET	count + 2	; <start> parameter
367
 2928          000009        	str	.SET	start + 2	; <str> parameter
368
 2929                        	;
369
 2930  FA04B5  08            		php			; save SR
370
 2931  FA04B6  3B            		tsc			; stack frame
371
 2932  FA04B7  0B            		phd			; save DP reg.
372
 2933  FA04B8  5B            		tcd			; dp access to stack var's
373
  Tue Jul 17 11:00:21 2018                                                                                               Page    7
374
 
375
 
376
 
377
 
378
 2934  FA04B9                		CPU08			; be sure A,X,Y 8 bit
379
 2935  FA04B9  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
380
 2936                        		.LONGA	off
381
 2937                        		.LONGI	off
382
 2938                        		.MNLIST
383
 2939  FA04BB  A0 00         		ldy	#0		; pointer
384
 2940  FA04BD                		INDEX16			; X/Y 16 bit
385
 2941  FA04BD  C2 10         		rep	#PXFLAG
386
 2942                        		.LONGI	on
387
 2943                        		.MNLIST
388
 2944                        	;
389
 2945  FA04BF  B7 09         	?len:	lda	[str],y		; compute string length
390
 2946  FA04C1  F0 07         		beq	?chk		; done when get a nul
391
 2947  FA04C3  C8            		iny			; bump pointer
392
 2948  FA04C4  D0 F9         		bne	?len
393
 2949  FA04C6  98            		tya
394
 2950  FA04C7  88            		dey			; max length = $FFFF
395
 2951  FA04C8  97 09         		sta	[str],y		; force string terminator
396
 2952                        	;
397
 2953  FA04CA  BB            	?chk:	tyx			; check string lenght
398
 2954  FA04CB  F0 2D         		beq	?done		; empty string
399
 2955  FA04CD  A6 05         		ldx	<count
400
 2956  FA04CF  F0 29         		beq	?done		; nothing to delete
401
 2957  FA04D1  C4 07         		cpy	<start		; if length <= start...
402
 2958  FA04D3  90 25         		bcc	?done		; ...nothing to delete
403
 2959  FA04D5  F0 23         		beq	?done
404
 2960  FA04D7                		CPU16CLC		; A 16 bit and clear carry
405
 2961  FA04D7  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
406
 2962                        		.LONGA	on
407
 2963                        		.LONGI	on
408
 2964                        		.MNLIST
409
 2965  FA04D9  8A            		txa			; <count>
410
 2966  FA04DA  65 07         		adc	<start		; index of first character to move back
411
 2967  FA04DC  85 05         		sta	<count
412
 2968  FA04DE                		ACC08			; A 8 bit
413
 2969  FA04DE  E2 20         		sep	#PMFLAG
414
 2970                        		.LONGA	off
415
 2971                        		.MNLIST
416
 2972  FA04E0  B0 06         		bcs	?mov		; beyond the string...put nul at <start> index
417
 2973  FA04E2  C4 05         		cpy	<count		; length < start + count?
418
 2974  FA04E4  90 02         		bcc	?mov		; yes -- terminate string at <start> index
419
 2975  FA04E6  A4 05         		ldy	<count		; index of next character to move back
420
 2976  FA04E8  B7 09         	?mov:	lda	[str],y
421
 2977  FA04EA  BB            		tyx			; save to X
422
 2978  FA04EB  A4 07         		ldy	<start		; index where put character
423
 2979  FA04ED  97 09         		sta	[str],y
424
 2980  FA04EF  C9 00         		cmp	#0		; nul byte?
425
 2981  FA04F1  F0 07         		beq	?done		; yes, done
426
 2982  FA04F3  C8            		iny
427
 2983  FA04F4  84 07         		sty	<start
428
 2984  FA04F6  9B            		txy
429
 2985  FA04F7  C8            		iny
430
 2986  FA04F8  80 EE         		bra	?mov		; move loop
431
 2987                        	;
432
 2988  FA04FA                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
433
 2989  FA04FA  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
434
 2990                        		.LONGA	on
435
  Tue Jul 17 11:00:21 2018                                                                                               Page    8
436
 
437
 
438
 
439
 
440
 2991                        		.LONGI	on
441
 2992                        		.MNLIST
442
 2993  FA04FC  A5 03         		lda	<entsr+2	; move saved SR and return address
443
 2994  FA04FE  85 0A         		sta	<exitsr+2
444
 2995  FA0500  A5 01         		lda	<entsr
445
 2996  FA0502  85 08         		sta	<exitsr
446
 2997  FA0504  2B            		pld			; restore DP reg.
447
 2998  FA0505  3B            		tsc			; stack frame
448
 2999  FA0506  69 07 00      		adc	#skpsiz		; realign stack
449
 3000  FA0509  1B            		tcs
450
 3001  FA050A  98            		tya			; C = string length
451
 3002  FA050B  28            		plp			; restore SR
452
 3003  FA050C  6B            		rtl
453
 3004
454
 3005                        		.LONGA	off
455
 3006                        		.LONGI	off
456
 3007
457
 3008                        	; _strins(str1, str2, start, maxlen)
458
 3009                        	;
459
 3010                        	; insert <str2> string into <str1> string, starting at index <start> of <str1>
460
 3011                        	; character of <str1>, starting from <start> index, are moved ahead to make
461
 3012                        	; room for characters of <str2>
462
 3013                        	; if <maxlen>=0 then string <str1> will be truncated (return an empty string)
463
 3014                        	; buffer <str1> should have a size=<maxlen>+1 to hold the nul terminator
464
 3015                        	;
465
 3016                        	;	stack param's:
466
 3017                        	;
467
 3018                        	;	<str1>:		long pointer to target string
468
 3019                        	;	<str2>:		long pointer to string to insert
469
 3020                        	;	<start>:	index of first character where start insertion (word)
470
 3021                        	;	<maxlen>:	max. length of <str1> (word)
471
 3022                        	;
472
 3023                        	;	return:		C = length of string <str1>
473
 3024                        	;
474
 3025                        	;	note:		X & Y not preserved
475
 3026                        	;
476
 3027                        	;-------------------------------
477
 3028  FA050D                	_strins:
478
 3029                        		.PUBLIC _strins
479
 3030                        	;-------------------------------
480
 3031
481
 3032                        		.LONGA	off
482
 3033                        		.LONGI	off
483
 3034  FA050D
484
 3035          00000A        	parsiz	.SET	10		; parameter stack frame size
485
 3036          00000E        	locsiz	.SET	14		; locals stack frame size
486
 3037          000018        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
487
 3038          00000F        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
488
 3039          000019        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
489
 3040                        	;
490
 3041          000013        	maxlen	.SET	entsr + 4	; <maxlen> parameter
491
 3042          000015        	start	.SET	maxlen + 2	; <start> parameter
492
 3043          000017        	str2	.SET	start + 2	; <str2> long pointer
493
 3044          00001A        	str1	.SET	str2 + 3	; <str1> long pointer
494
 3045                        	;
495
 3046          000001        	len1	.SET	1		; local: <str1> length
496
 3047          000003        	len2	.SET	3		; local: <str2> length
497
  Tue Jul 17 11:00:21 2018                                                                                               Page    9
498
 
499
 
500
 
501
 
502
 3048          000005        	iy	.SET	5		; local: temp. index
503
 3049          000007        	end	.SET	7		; local: index of last byte of <str1> to move
504
 3050          000009        	newend	.SET	9		; local: index of final <str1> ending
505
 3051          00000B        	cnt1	.SET	11		; local: count of bytes to move in <str1>
506
 3052          00000D        	cnt2	.SET	13		; local: count of bytes to copy from <str2>
507
 3053                        	;
508
 3054  FA050D  08            		php			; save SR
509
 3055  FA050E                		CPU16CLC
510
 3056  FA050E  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
511
 3057                        		.LONGA	on
512
 3058                        		.LONGI	on
513
 3059                        		.MNLIST
514
 3060  FA0510  3B            		tsc
515
 3061  FA0511  E9 0D 00      		sbc	#locsiz-1	; make room for locals var's
516
 3062  FA0514  1B            		tcs			; stack frame
517
 3063  FA0515  0B            		phd			; save DP reg.
518
 3064  FA0516  5B            		tcd			; dp access to stack var's
519
 3065  FA0517  64 05         		stz	<iy		; clear <iy>, <cnt1>, <cnt2>
520
 3066  FA0519  64 0B         		stz	<cnt1
521
 3067  FA051B  64 0D         		stz	<cnt2
522
 3068  FA051D                		ACC08			; X/Y 16 bit, A/M 8 bit
523
 3069  FA051D  E2 20         		sep	#PMFLAG
524
 3070                        		.LONGA	off
525
 3071                        		.MNLIST
526
 3072  FA051F  A4 05         		ldy	<iy		; pointer Y = 0
527
 3073  FA0521  BB            		tyx			; X = 0
528
 3074                        	;
529
 3075  FA0522  B7 17         	?len2:	lda	[str2],y	; compute string <str2> length
530
 3076  FA0524  F0 07         		beq	?stl		; done when get a nul
531
 3077  FA0526  C8            		iny			; bump pointer
532
 3078  FA0527  D0 F9         		bne	?len2
533
 3079  FA0529  98            		tya
534
 3080  FA052A  88            		dey			; max length = $FFFF
535
 3081  FA052B  97 17         		sta	[str2],y	; force string terminator
536
 3082                        	;
537
 3083  FA052D  84 03         	?stl:	sty	<len2		; store <str2> lenght
538
 3084  FA052F  9B            		txy			; Y = 0
539
 3085                        	;
540
 3086  FA0530  B7 1A         	?len1:	lda	[str1],y	; compute string <str1> length
541
 3087  FA0532  F0 07         		beq	?chk		; done when get a nul
542
 3088  FA0534  C8            		iny			; bump pointer
543
 3089  FA0535  D0 F9         		bne	?len1
544
 3090  FA0537  98            		tya
545
 3091  FA0538  88            		dey			; max length = $FFFF
546
 3092  FA0539  97 1A         		sta	[str1],y	; force string terminator
547
 3093                        	;
548
 3094  FA053B  C4 13         	?chk:	cpy	<maxlen		; fix <maxlen> if below the actual...
549
 3095  FA053D  90 02         		bcc	?chk1		; ...<str1> length
550
 3096  FA053F  84 13         		sty	<maxlen
551
 3097                        	;
552
 3098  FA0541                	?chk1:	CPU16CLC
553
 3099  FA0541  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
554
 3100                        		.LONGA	on
555
 3101                        		.LONGI	on
556
 3102                        		.MNLIST
557
 3103  FA0543  98            		tya
558
 3104  FA0544  65 03         		adc	<len2		; final string length
559
  Tue Jul 17 11:00:21 2018                                                                                               Page   10
560
 
561
 
562
 
563
 
564
 3105  FA0546  B0 06         		bcs	?chk2		; truncate to <maxlen>
565
 3106  FA0548  C5 13         		cmp	<maxlen		; can fit?
566
 3107  FA054A  B0 02         		bcs	?chk2		; no, truncate to <maxlen>
567
 3108  FA054C  85 13         		sta	<maxlen		; store final length
568
 3109                        	;
569
 3110  FA054E  84 01         	?chk2:	sty	<len1		; store <str1> length
570
 3111  FA0550  A6 03         		ldx	<len2		; if <str2> is empty...
571
 3112  FA0552  F0 6E         		beq	?done		; ...return <str1>
572
 3113  FA0554  BB            		tyx			; if <str1> is empty...
573
 3114  FA0555  F0 0B         		beq	?cat		; ...return <str1> = <str2>
574
 3115  FA0557  A6 13         		ldx	<maxlen
575
 3116  FA0559  CA            		dex
576
 3117  FA055A  86 09         		stx	<newend		; pointer to the end of final <str1>
577
 3118  FA055C  A5 15         		lda	<start
578
 3119  FA055E  C5 01         		cmp	<len1
579
 3120  FA0560  90 0B         		bcc	?chk3		; <start> is in range [1..length(str1)-1]
580
 3121                        	;
581
 3122  FA0562  84 15         	?cat:	sty	<start		; append <str2> to the end of <str1>
582
 3123  FA0564  38            		sec
583
 3124  FA0565  A5 13         		lda	<maxlen		; count of bytes to copy from <str2> to...
584
 3125  FA0567  E5 01         		sbc	<len1		; ...<str1> starting at index <start>
585
 3126  FA0569  85 0D         		sta	<cnt2
586
 3127  FA056B  80 24         		bra	?mov
587
 3128                        	;
588
 3129  FA056D  65 03         	?chk3:	adc	<len2		; <start> + length(str2)
589
 3130  FA056F  90 03         		bcc	?chk4
590
 3131  FA0571  A9 FF FF      		lda	#$FFFF		; limit max. length
591
 3132                        	;
592
 3133  FA0574  C5 13         	?chk4:	cmp	<maxlen		; can move som bytes of <str1> to make room?
593
 3134  FA0576  90 06         		bcc	?less		; yes
594
 3135  FA0578  E5 15         		sbc	<start		; no... compute how much bytes of <str2>...
595
 3136  FA057A  85 0D         		sta	<cnt2		; ...can be inserted
596
 3137  FA057C  80 13         		bra	?mov
597
 3138                        	;
598
 3139  FA057E  85 0B         	?less:	sta	<cnt1		; index where move bytes of <str1>
599
 3140  FA0580  38            		sec
600
 3141  FA0581  A5 13         		lda	<maxlen
601
 3142  FA0583  E5 0B         		sbc	<cnt1
602
 3143  FA0585  85 0B         		sta	<cnt1		; count of bytes to move in <str1>
603
 3144  FA0587  18            		clc
604
 3145  FA0588  65 15         		adc	<start
605
 3146  FA058A  3A            		dec	a		; pointer to the last byte of <str1>...
606
 3147  FA058B  85 07         		sta	<end		; ...that will be moved ahead
607
 3148  FA058D  A6 03         		ldx	<len2		; the whole <str2> can be inserted
608
 3149  FA058F  86 0D         		stx	<cnt2
609
 3150                        	;
610
 3151                        	; move <cnt1> bytes from the <str1> to the new end of <str1>
611
 3152  FA0591                	?mov:	ACC08			; A/M 8 bit
612
 3153  FA0591  E2 20         		sep	#PMFLAG
613
 3154                        		.LONGA	off
614
 3155                        		.MNLIST
615
 3156  FA0593  A6 0B         		ldx	<cnt1		; count of bytes to move
616
 3157  FA0595  F0 11         		beq	?cpy		; nothing to move in <str1>
617
 3158                        	;
618
 3159  FA0597  A4 07         	?lmov:	ldy	<end		; move from the end of <str1>...
619
 3160  FA0599  B7 1A         		lda	[str1],y
620
 3161  FA059B  88            		dey
621
  Tue Jul 17 11:00:21 2018                                                                                               Page   11
622
 
623
 
624
 
625
 
626
 3162  FA059C  84 07         		sty	<end
627
 3163  FA059E  A4 09         		ldy	<newend		; ...to the new end
628
 3164  FA05A0  97 1A         		sta	[str1],y
629
 3165  FA05A2  88            		dey			; decrement (move previous)
630
 3166  FA05A3  84 09         		sty	<newend
631
 3167  FA05A5  CA            		dex
632
 3168  FA05A6  D0 EF         		bne	?lmov		; move loop
633
 3169                        	;
634
 3170                        	; copy <cnt2> bytes from beginning of <str2> to <str1>, starting at index <start>
635
 3171  FA05A8  A6 0D         	?cpy:	ldx	<cnt2		; count of bytes to copy
636
 3172  FA05AA  F0 11         		beq	?nul		; nothing to copy: terminate <str1>
637
 3173                        	;
638
 3174  FA05AC  A4 05         	?lcpy:	ldy	<iy
639
 3175  FA05AE  B7 17         		lda	[str2],y
640
 3176  FA05B0  C8            		iny
641
 3177  FA05B1  84 05         		sty	<iy
642
 3178  FA05B3  A4 15         		ldy	<start		; target index
643
 3179  FA05B5  97 1A         		sta	[str1],y
644
 3180  FA05B7  C8            		iny
645
 3181  FA05B8  84 15         		sty	<start
646
 3182  FA05BA  CA            		dex
647
 3183  FA05BB  D0 EF         		bne	?lcpy		; loop copy
648
 3184                        	;
649
 3185  FA05BD  8A            	?nul:	txa			; terminate string <str1>
650
 3186  FA05BE  A4 13         		ldy	<maxlen
651
 3187  FA05C0  97 1A         		sta	[str1],y
652
 3188                        	;
653
 3189  FA05C2                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
654
 3190  FA05C2  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
655
 3191                        		.LONGA	on
656
 3192                        		.LONGI	on
657
 3193                        		.MNLIST
658
 3194  FA05C4  A5 11         		lda	<entsr+2	; move saved SR and return address
659
 3195  FA05C6  85 1B         		sta	<exitsr+2
660
 3196  FA05C8  A5 0F         		lda	<entsr
661
 3197  FA05CA  85 19         		sta	<exitsr
662
 3198  FA05CC  2B            		pld			; restore DP reg.
663
 3199  FA05CD  3B            		tsc			; stack frame
664
 3200  FA05CE  69 18 00      		adc	#skpsiz		; realign stack
665
 3201  FA05D1  1B            		tcs
666
 3202  FA05D2  98            		tya			; C = string <str1> length
667
 3203  FA05D3  28            		plp			; restore SR
668
 3204  FA05D4  6B            		rtl
669
 3205
670
 3206                        		.LONGA	off
671
 3207                        		.LONGI	off
672
 3208
673
 3209                        	;---------------------------------------------------------------------------
674
 3210                        	; strings comparison
675
 3211                        	;---------------------------------------------------------------------------
676
 3212
677
 3213                        	; _strcmp(s1, s2)
678
 3214                        	;
679
 3215                        	; lexicographically compare the null-terminated strings s1 and s2
680
 3216                        	;
681
 3217                        	;	stack param's:
682
 3218                        	;
683
  Tue Jul 17 11:00:21 2018                                                                                               Page   12
684
 
685
 
686
 
687
 
688
 3219                        	;	<s1>:		long pointer to first string
689
 3220                        	;	<s2>:		long pointer to second string
690
 3221                        	;
691
 3222                        	;	return:		status flags affected like in 'cmp' instruction
692
 3223                        	;			CF=0 & ZF=0 if s1 less than s2
693
 3224                        	;			CF=1 & ZF=1 if s1 equal to s2
694
 3225                        	;			CF=1 & ZF=0 if s1 greater than s2
695
 3226                        	;
696
 3227                        	;	note:		X & Y not preserved
697
 3228                        	;
698
 3229                        	;-------------------------------
699
 3230  FA05D5                	_strcmp:
700
 3231                        		.PUBLIC _strcmp
701
 3232                        	;-------------------------------
702
 3233
703
 3234                        		.LONGA	off
704
 3235                        		.LONGI	off
705
 3236  FA05D5
706
 3237          000006        	parsiz	.SET	6		; parameter stack frame size
707
 3238          000000        	locsiz	.SET	0		; locals stack frame size
708
 3239          000006        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
709
 3240          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
710
 3241          000007        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
711
 3242                        	;
712
 3243          000005        	s2	.SET	entsr + 4	; <s1> parameter
713
 3244          000008        	s1	.SET	s2 + 3		; <s2> parameter
714
 3245                        	;
715
 3246  FA05D5  C2 03         		rep	#PZFLAG+PCFLAG	; clear CF & ZF
716
 3247  FA05D7  08            		php			; save SR
717
 3248  FA05D8  3B            		tsc			; stack frame
718
 3249  FA05D9  0B            		phd			; save DP reg.
719
 3250  FA05DA  5B            		tcd			; dp access to stack var's
720
 3251  FA05DB                		CPU08			; A/M & X/Y 8 bit
721
 3252  FA05DB  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
722
 3253                        		.LONGA	off
723
 3254                        		.LONGI	off
724
 3255                        		.MNLIST
725
 3256  FA05DD  A0 00         		ldy	#0		; pointer
726
 3257  FA05DF                		INDEX16			; X/Y 16 bit
727
 3258  FA05DF  C2 10         		rep	#PXFLAG
728
 3259                        		.LONGI	on
729
 3260                        		.MNLIST
730
 3261                        	;
731
 3262  FA05E1  B7 08         	?cmp:	lda	[s1],y		; get next char from <s1>
732
 3263  FA05E3  D7 05         		cmp	[s2],y		; compare with byte in <s2>
733
 3264  FA05E5  D0 08         		bne	?end		; unmatch, set flags
734
 3265  FA05E7  C9 00         		cmp	#0		; end of string?
735
 3266  FA05E9  F0 04         		beq	?end		; yes, set flags
736
 3267  FA05EB  C8            		iny			; bump pointer
737
 3268  FA05EC  D0 F3         		bne	?cmp		; compare next char
738
 3269  FA05EE  38            		sec			; all match: set carry
739
 3270                        	;
740
 3271  FA05EF  08            	?end:	php			; CF & ZF affected according comparison
741
 3272  FA05F0  68            		pla
742
 3273  FA05F1  29 03         		and	#PZFLAG+PCFLAG	; mask on CF & ZF
743
 3274  FA05F3  04 01         		tsb	<entsr		; set flags on saved status reg.
744
 3275  FA05F5                		CPU16CLC		; A,X,Y 16 bit - clear carry
745
  Tue Jul 17 11:00:21 2018                                                                                               Page   13
746
 
747
 
748
 
749
 
750
 3276  FA05F5  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
751
 3277                        		.LONGA	on
752
 3278                        		.LONGI	on
753
 3279                        		.MNLIST
754
 3280  FA05F7  A5 03         		lda	<entsr+2	; move saved SR and return address
755
 3281  FA05F9  85 09         		sta	<exitsr+2
756
 3282  FA05FB  A5 01         		lda	<entsr
757
 3283  FA05FD  85 07         		sta	<exitsr
758
 3284  FA05FF  2B            		pld			; restore DP reg.
759
 3285  FA0600  3B            		tsc			; stack frame
760
 3286  FA0601  69 06 00      		adc	#skpsiz		; realign stack
761
 3287  FA0604  1B            		tcs
762
 3288  FA0605  28            		plp			; restore SR
763
 3289  FA0606  6B            		rtl
764
 3290
765
 3291                        		.LONGA	off
766
 3292                        		.LONGI	off
767
 3293
768
 3294                        	; _strncmp(s1, s2, n)
769
 3295                        	;
770
 3296                        	; lexicographically compare the null-terminated strings s1 and s2
771
 3297                        	; this function compares not more than n characters
772
 3298                        	;
773
 3299                        	;	stack param's:
774
 3300                        	;
775
 3301                        	;	<s1>:		long pointer to first string
776
 3302                        	;	<s2>:		long pointer to second string
777
 3303                        	;	<n>:		word: count of characters to compare
778
 3304                        	;
779
 3305                        	;	return:		status flags affected like in 'cmp' instruction
780
 3306                        	;			CF=0 & ZF=0 if s1 less than s2
781
 3307                        	;			CF=1 & ZF=1 if s1 equal to s2
782
 3308                        	;			CF=1 & ZF=0 if s1 greater than s2
783
 3309                        	;
784
 3310                        	;	note:		X & Y not preserved
785
 3311                        	;
786
 3312                        	;-------------------------------
787
 3313  FA0607                	_strncmp:
788
 3314                        		.PUBLIC _strncmp
789
 3315                        	;-------------------------------
790
 3316
791
 3317                        		.LONGA	off
792
 3318                        		.LONGI	off
793
 3319  FA0607
794
 3320          000008        	parsiz	.SET	8		; parameter stack frame size
795
 3321          000000        	locsiz	.SET	0		; locals stack frame size
796
 3322          000008        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
797
 3323          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
798
 3324          000009        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
799
 3325                        	;
800
 3326          000005        	n	.SET	entsr + 4	; <n> parameter
801
 3327          000007        	s2	.SET	n + 2		; <s1> parameter
802
 3328          00000A        	s1	.SET	s2 + 3		; <s2> parameter
803
 3329                        	;
804
 3330  FA0607  C2 03         		rep	#PZFLAG+PCFLAG	; clear CF & ZF
805
 3331  FA0609  08            		php			; save SR
806
 3332  FA060A  3B            		tsc			; stack frame
807
  Tue Jul 17 11:00:21 2018                                                                                               Page   14
808
 
809
 
810
 
811
 
812
 3333  FA060B  0B            		phd			; save DP reg.
813
 3334  FA060C  5B            		tcd			; dp access to stack var's
814
 3335  FA060D                		CPU08SEC		; A/M & X/Y 8 bit & set carry
815
 3336  FA060D  E2 31         		sep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
816
 3337                        		.LONGA	off
817
 3338                        		.LONGI	off
818
 3339                        		.MNLIST
819
 3340  FA060F  A0 00         		ldy	#0		; pointer
820
 3341  FA0611                		INDEX16			; X/Y 16 bit
821
 3342  FA0611  C2 10         		rep	#PXFLAG
822
 3343                        		.LONGI	on
823
 3344                        		.MNLIST
824
 3345  FA0613  A6 05         		ldx	<n		; if <n> = 0 set CF=1 & ZF=1
825
 3346  FA0615  F0 0F         		beq	?end
826
 3347                        	;
827
 3348  FA0617  B7 0A         	?cmp:	lda	[s1],y		; get next char from <s1>
828
 3349  FA0619  D7 07         		cmp	[s2],y		; compare with byte in <s2>
829
 3350  FA061B  D0 09         		bne	?end		; unmatch, set flags
830
 3351  FA061D  C9 00         		cmp	#0		; end of string?
831
 3352  FA061F  F0 05         		beq	?end		; yes, set flags
832
 3353  FA0621  C8            		iny			; bump pointer
833
 3354  FA0622  C4 05         		cpy	<n		; at most <n> characters...
834
 3355  FA0624  90 F1         		bcc	?cmp		; compare next char
835
 3356                        					; all match: set carry & zero flag
836
 3357                        	;
837
 3358  FA0626  08            	?end:	php			; CF & ZF affected according comparison
838
 3359  FA0627  68            		pla
839
 3360  FA0628  29 03         		and	#PZFLAG+PCFLAG	; mask on CF & ZF
840
 3361  FA062A  04 01         		tsb	<entsr		; set flags on saved status reg.
841
 3362  FA062C                		CPU16CLC		; A,X,Y 16 bit - clear carry
842
 3363  FA062C  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
843
 3364                        		.LONGA	on
844
 3365                        		.LONGI	on
845
 3366                        		.MNLIST
846
 3367  FA062E  A5 03         		lda	<entsr+2	; move saved SR and return address
847
 3368  FA0630  85 0B         		sta	<exitsr+2
848
 3369  FA0632  A5 01         		lda	<entsr
849
 3370  FA0634  85 09         		sta	<exitsr
850
 3371  FA0636  2B            		pld			; restore DP reg.
851
 3372  FA0637  3B            		tsc			; stack frame
852
 3373  FA0638  69 08 00      		adc	#skpsiz		; realign stack
853
 3374  FA063B  1B            		tcs
854
 3375  FA063C  28            		plp			; restore SR
855
 3376  FA063D  6B            		rtl
856
 3377
857
 3378                        		.LONGA	off
858
 3379                        		.LONGI	off
859
 3380  FA063E
860
 3381                        	; _strcasecmp(s1, s2)
861
 3382                        	;
862
 3383                        	; lexicographically compare the null-terminated strings s1 and s2,
863
 3384                        	; ignoring stings case
864
 3385                        	;
865
 3386                        	;	stack param's:
866
 3387                        	;
867
 3388                        	;	<s1>:		long pointer to first string
868
 3389                        	;	<s2>:		long pointer to second string
869
  Tue Jul 17 11:00:21 2018                                                                                               Page   15
870
 
871
 
872
 
873
 
874
 3390                        	;
875
 3391                        	;	return:		status flags affected like in 'cmp' instruction
876
 3392                        	;			CF=0 & ZF=0 if s1 less than s2
877
 3393                        	;			CF=1 & ZF=1 if s1 equal to s2
878
 3394                        	;			CF=1 & ZF=0 if s1 greater than s2
879
 3395                        	;
880
 3396                        	;	note:		X & Y not preserved
881
 3397                        	;
882
 3398                        	;-------------------------------
883
 3399  FA063E                	_strcasecmp:
884
 3400                        		.PUBLIC _strcasecmp
885
 3401                        	;-------------------------------
886
 3402
887
 3403                        		.LONGA	off
888
 3404                        		.LONGI	off
889
 3405  FA063E
890
 3406          000006        	parsiz	.SET	6		; parameter stack frame size
891
 3407          000002        	locsiz	.SET	2		; locals stack frame size
892
 3408          000008        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
893
 3409          000003        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
894
 3410          000009        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
895
 3411                        	;
896
 3412          000007        	s2	.SET	entsr + 4	; <s1> parameter
897
 3413          00000A        	s1	.SET	s2 + 3		; <s2> parameter
898
 3414                        	;
899
 3415          000001        	tmp	.SET	1		; local: temp. byte
900
 3416                        	;
901
 3417  FA063E  C2 03         		rep	#PZFLAG+PCFLAG	; clear CF & ZF
902
 3418  FA0640  08            		php			; save SR
903
 3419  FA0641  F4 00 00      		pea	#0		; local variable
904
 3420  FA0644  3B            		tsc			; stack frame
905
 3421  FA0645  0B            		phd			; save DP reg.
906
 3422  FA0646  5B            		tcd			; dp access to stack var's
907
 3423  FA0647                		CPU08			; A/M & X/Y 8 bit
908
 3424  FA0647  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
909
 3425                        		.LONGA	off
910
 3426                        		.LONGI	off
911
 3427                        		.MNLIST
912
 3428  FA0649  A0 00         		ldy	#0		; pointer
913
 3429  FA064B                		INDEX16			; X/Y 16 bit
914
 3430  FA064B  C2 10         		rep	#PXFLAG
915
 3431                        		.LONGI	on
916
 3432                        		.MNLIST
917
 3433                        	;
918
 3434  FA064D  B7 07         	?cmp:	lda	[s2],y		; get next char from <s2>
919
 3435  FA064F  C9 61         		cmp	#'a'		; translate lower case to upper case
920
 3436  FA0651  90 06         		bcc	?st
921
 3437  FA0653  C9 7B         		cmp	#'z'+1
922
 3438  FA0655  B0 02         		bcs	?st
923
 3439  FA0657  29 DF         		and	#$DF		; upper case
924
 3440  FA0659  85 01         	?st:	sta	<tmp		; store character
925
 3441  FA065B  B7 0A         		lda	[s1],y		; get next char from <s1>
926
 3442  FA065D  C9 61         		cmp	#'a'		; translate lower case to upper case
927
 3443  FA065F  90 06         		bcc	?cmp2
928
 3444  FA0661  C9 7B         		cmp	#'z'+1
929
 3445  FA0663  B0 02         		bcs	?cmp2
930
 3446  FA0665  29 DF         		and	#$DF		; upper case
931
  Tue Jul 17 11:00:21 2018                                                                                               Page   16
932
 
933
 
934
 
935
 
936
 3447  FA0667  C5 01         	?cmp2:	cmp	<tmp		; compares characters
937
 3448  FA0669  D0 08         		bne	?end		; unmatch, set flags
938
 3449  FA066B  C9 00         		cmp	#0		; end of string?
939
 3450  FA066D  F0 04         		beq	?end		; yes, set flags
940
 3451  FA066F  C8            		iny			; bump pointer
941
 3452  FA0670  D0 DB         		bne	?cmp		; compare next char
942
 3453  FA0672  38            		sec			; all match: set carry
943
 3454                        	;
944
 3455  FA0673  08            	?end:	php			; CF & ZF affected according comparison
945
 3456  FA0674  68            		pla
946
 3457  FA0675  29 03         		and	#PZFLAG+PCFLAG	; mask on CF & ZF
947
 3458  FA0677  04 03         		tsb	<entsr		; set flags on saved status reg.
948
 3459  FA0679                		CPU16CLC		; A,X,Y 16 bit - clear carry
949
 3460  FA0679  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
950
 3461                        		.LONGA	on
951
 3462                        		.LONGI	on
952
 3463                        		.MNLIST
953
 3464  FA067B  A5 05         		lda	<entsr+2	; move saved SR and return address
954
 3465  FA067D  85 0B         		sta	<exitsr+2
955
 3466  FA067F  A5 03         		lda	<entsr
956
 3467  FA0681  85 09         		sta	<exitsr
957
 3468  FA0683  2B            		pld			; restore DP reg.
958
 3469  FA0684  3B            		tsc			; stack frame
959
 3470  FA0685  69 08 00      		adc	#skpsiz		; realign stack
960
 3471  FA0688  1B            		tcs
961
 3472  FA0689  28            		plp			; restore SR
962
 3473  FA068A  6B            		rtl
963
 3474
964
 3475                        		.LONGA	off
965
 3476                        		.LONGI	off
966
 3477
967
 3478                        	; _strncasecmp(s1, s2, n)
968
 3479                        	;
969
 3480                        	; lexicographically compare the null-terminated strings s1 and s2,
970
 3481                        	; ignoring strings case; this function compares not more than n characters
971
 3482                        	;
972
 3483                        	;	stack param's:
973
 3484                        	;
974
 3485                        	;	<s1>:		long pointer to first string
975
 3486                        	;	<s2>:		long pointer to second string
976
 3487                        	;	<n>:		word: count of characters to compare
977
 3488                        	;
978
 3489                        	;	return:		status flags affected like in 'cmp' instruction
979
 3490                        	;			CF=0 & ZF=0 if s1 less than s2
980
 3491                        	;			CF=1 & ZF=1 if s1 equal to s2
981
 3492                        	;			CF=1 & ZF=0 if s1 greater than s2
982
 3493                        	;
983
 3494                        	;	note:		X & Y not preserved
984
 3495                        	;
985
 3496                        	;-------------------------------
986
 3497  FA068B                	_strncasecmp:
987
 3498                        		.PUBLIC _strncasecmp
988
 3499                        	;-------------------------------
989
 3500
990
 3501                        		.LONGA	off
991
 3502                        		.LONGI	off
992
 3503  FA068B
993
  Tue Jul 17 11:00:21 2018                                                                                               Page   17
994
 
995
 
996
 
997
 
998
 3504          000008        	parsiz	.SET	8		; parameter stack frame size
999
 3505          000002        	locsiz	.SET	2		; locals stack frame size
1000
 3506          00000A        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
1001
 3507          000003        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
1002
 3508          00000B        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
1003
 3509                        	;
1004
 3510          000007        	n	.SET	entsr + 4	; <n> parameter
1005
 3511          000009        	s2	.SET	n + 2		; <s1> parameter
1006
 3512          00000C        	s1	.SET	s2 + 3		; <s2> parameter
1007
 3513                        	;
1008
 3514          000001        	tmp	.SET	1		; local: temp. byte
1009
 3515                        	;
1010
 3516  FA068B  C2 03         		rep	#PZFLAG+PCFLAG	; clear CF & ZF
1011
 3517  FA068D  08            		php			; save SR
1012
 3518  FA068E  F4 00 00      		pea	#0		; local variable
1013
 3519  FA0691  3B            		tsc			; stack frame
1014
 3520  FA0692  0B            		phd			; save DP reg.
1015
 3521  FA0693  5B            		tcd			; dp access to stack var's
1016
 3522  FA0694                		CPU08SEC		; A/M & X/Y 8 bit & set carry
1017
 3523  FA0694  E2 31         		sep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1018
 3524                        		.LONGA	off
1019
 3525                        		.LONGI	off
1020
 3526                        		.MNLIST
1021
 3527  FA0696  A0 00         		ldy	#0		; pointer
1022
 3528  FA0698                		INDEX16			; X/Y 16 bit
1023
 3529  FA0698  C2 10         		rep	#PXFLAG
1024
 3530                        		.LONGI	on
1025
 3531                        		.MNLIST
1026
 3532  FA069A  A6 07         		ldx	<n		; if <n> = 0 set CF=1 & ZF=1
1027
 3533  FA069C  F0 27         		beq	?end
1028
 3534                        	;
1029
 3535  FA069E  B7 09         	?cmp:	lda	[s2],y		; get next char from <s2>
1030
 3536  FA06A0  C9 61         		cmp	#'a'		; translate lower case to upper case
1031
 3537  FA06A2  90 06         		bcc	?st
1032
 3538  FA06A4  C9 7B         		cmp	#'z'+1
1033
 3539  FA06A6  B0 02         		bcs	?st
1034
 3540  FA06A8  29 DF         		and	#$DF		; upper case
1035
 3541  FA06AA  85 01         	?st:	sta	<tmp		; store character
1036
 3542  FA06AC  B7 0C         		lda	[s1],y		; get next char from <s1>
1037
 3543  FA06AE  C9 61         		cmp	#'a'		; translate lower case to upper case
1038
 3544  FA06B0  90 06         		bcc	?cmp2
1039
 3545  FA06B2  C9 7B         		cmp	#'z'+1
1040
 3546  FA06B4  B0 02         		bcs	?cmp2
1041
 3547  FA06B6  29 DF         		and	#$DF		; upper case
1042
 3548  FA06B8  C5 01         	?cmp2:	cmp	<tmp		; compares characters
1043
 3549  FA06BA  D0 09         		bne	?end		; unmatch, set flags
1044
 3550  FA06BC  C9 00         		cmp	#0		; end of string?
1045
 3551  FA06BE  F0 05         		beq	?end		; yes, set flags
1046
 3552  FA06C0  C8            		iny			; bump pointer
1047
 3553  FA06C1  C4 07         		cpy	<n		; at most <n> characters...
1048
 3554  FA06C3  90 D9         		bcc	?cmp		; compare next char
1049
 3555                        					; all match: set carry & zero flag
1050
 3556                        	;
1051
 3557  FA06C5  08            	?end:	php			; CF & ZF affected according comparison
1052
 3558  FA06C6  68            		pla
1053
 3559  FA06C7  29 03         		and	#PZFLAG+PCFLAG	; mask on CF & ZF
1054
 3560  FA06C9  04 03         		tsb	<entsr		; set flags on saved status reg.
1055
  Tue Jul 17 11:00:21 2018                                                                                               Page   18
1056
 
1057
 
1058
 
1059
 
1060
 3561  FA06CB                		CPU16CLC		; A,X,Y 16 bit - clear carry
1061
 3562  FA06CB  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1062
 3563                        		.LONGA	on
1063
 3564                        		.LONGI	on
1064
 3565                        		.MNLIST
1065
 3566  FA06CD  A5 05         		lda	<entsr+2	; move saved SR and return address
1066
 3567  FA06CF  85 0D         		sta	<exitsr+2
1067
 3568  FA06D1  A5 03         		lda	<entsr
1068
 3569  FA06D3  85 0B         		sta	<exitsr
1069
 3570  FA06D5  2B            		pld			; restore DP reg.
1070
 3571  FA06D6  3B            		tsc			; stack frame
1071
 3572  FA06D7  69 0A 00      		adc	#skpsiz		; realign stack
1072
 3573  FA06DA  1B            		tcs
1073
 3574  FA06DB  28            		plp			; restore SR
1074
 3575  FA06DC  6B            		rtl
1075
 3576
1076
 3577                        		.LONGA	off
1077
 3578                        		.LONGI	off
1078
 3579
1079
 3580                        	;---------------------------------------------------------------------------
1080
 3581                        	; find character & substring
1081
 3582                        	;---------------------------------------------------------------------------
1082
 3583
1083
 3584                        	; _strchr(s, c)
1084
 3585                        	;
1085
 3586                        	; locates the first occurrence of character <c> in string pointed to by <s>
1086
 3587                        	;
1087
 3588                        	;	stack param's:
1088
 3589                        	;
1089
 3590                        	;	<s>:		long pointer to string
1090
 3591                        	;	<c>:		character to find (byte)
1091
 3592                        	;
1092
 3593                        	;	return:		CF=0 & C = index of character in string, if found
1093
 3594                        	;			CF=1 & C = index of the nul terminator if not found
1094
 3595                        	;			           (string length in fact)
1095
 3596                        	;
1096
 3597                        	;	note:		X & Y not preserved
1097
 3598                        	;
1098
 3599                        	;-------------------------------
1099
 3600  FA06DD                	_strchr:
1100
 3601                        		.PUBLIC _strchr
1101
 3602                        	;-------------------------------
1102
 3603
1103
 3604                        		.LONGA	off
1104
 3605                        		.LONGI	off
1105
 3606  FA06DD
1106
 3607          000004        	parsiz	.SET	4		; parameter stack frame size
1107
 3608          000000        	locsiz	.SET	0		; locals stack frame size
1108
 3609          000004        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
1109
 3610          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
1110
 3611          000005        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
1111
 3612                        	;
1112
 3613          000005        	c	.SET	entsr + 4	; <c> parameter
1113
 3614          000006        	s	.SET	c + 1		; <s> parameter
1114
 3615                        	;
1115
 3616  FA06DD  38            		sec			; assume not found
1116
 3617  FA06DE  08            		php			; save SR
1117
  Tue Jul 17 11:00:21 2018                                                                                               Page   19
1118
 
1119
 
1120
 
1121
 
1122
 3618  FA06DF  3B            		tsc			; stack frame
1123
 3619  FA06E0  0B            		phd			; save DP reg.
1124
 3620  FA06E1  5B            		tcd			; dp access to stack var's
1125
 3621  FA06E2                		CPU08			; A/M & X/Y 8 bit
1126
 3622  FA06E2  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
1127
 3623                        		.LONGA	off
1128
 3624                        		.LONGI	off
1129
 3625                        		.MNLIST
1130
 3626  FA06E4  A0 00         		ldy	#0		; pointer
1131
 3627  FA06E6                		INDEX16			; X/Y 16 bit
1132
 3628  FA06E6  C2 10         		rep	#PXFLAG
1133
 3629                        		.LONGI	on
1134
 3630                        		.MNLIST
1135
 3631                        	;
1136
 3632  FA06E8  B7 06         	?cmp:	lda	[s],y		; get next char from <s>
1137
 3633  FA06EA  C5 05         		cmp	<c		; compare with character <c>
1138
 3634  FA06EC  F0 0A         		beq	?end		; match, reset carry flag
1139
 3635  FA06EE  C9 00         		cmp	#0		; end of string?
1140
 3636  FA06F0  F0 0A         		beq	?done		; yes, return index of terminator
1141
 3637  FA06F2  C8            		iny			; bump pointer
1142
 3638  FA06F3  D0 F3         		bne	?cmp		; compare next char
1143
 3639  FA06F5  88            		dey
1144
 3640  FA06F6  80 04         		bra	?done
1145
 3641                        	;
1146
 3642  FA06F8  A9 01         	?end:	lda	#PCFLAG		; clear CF
1147
 3643  FA06FA  14 01         		trb	<entsr
1148
 3644                        	;
1149
 3645  FA06FC                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
1150
 3646  FA06FC  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1151
 3647                        		.LONGA	on
1152
 3648                        		.LONGI	on
1153
 3649                        		.MNLIST
1154
 3650  FA06FE  A5 03         		lda	<entsr+2	; move saved SR and return address
1155
 3651  FA0700  85 07         		sta	<exitsr+2
1156
 3652  FA0702  A5 01         		lda	<entsr
1157
 3653  FA0704  85 05         		sta	<exitsr
1158
 3654  FA0706  2B            		pld			; restore DP reg.
1159
 3655  FA0707  3B            		tsc			; stack frame
1160
 3656  FA0708  69 04 00      		adc	#skpsiz		; realign stack
1161
 3657  FA070B  1B            		tcs
1162
 3658  FA070C  98            		tya			; C = index
1163
 3659  FA070D  28            		plp			; restore SR
1164
 3660  FA070E  6B            		rtl
1165
 3661
1166
 3662                        		.LONGA	off
1167
 3663                        		.LONGI	off
1168
 3664
1169
 3665                        	; _strrchr(s, c)
1170
 3666                        	;
1171
 3667                        	; locates the last occurrence of character <c> in string pointed to by <s>
1172
 3668                        	;
1173
 3669                        	;	stack param's:
1174
 3670                        	;
1175
 3671                        	;	<s>:		long pointer to string
1176
 3672                        	;	<c>:		character to find (byte)
1177
 3673                        	;
1178
 3674                        	;	return:		CF=0 & C = index of character in string, if found
1179
  Tue Jul 17 11:00:21 2018                                                                                               Page   20
1180
 
1181
 
1182
 
1183
 
1184
 3675                        	;			CF=1 & C = index of the nul terminator if not found
1185
 3676                        	;			           (string length in fact)
1186
 3677                        	;
1187
 3678                        	;	note:		X & Y not preserved
1188
 3679                        	;
1189
 3680                        	;-------------------------------
1190
 3681  FA070F                	_strrchr:
1191
 3682                        		.PUBLIC _strrchr
1192
 3683                        	;-------------------------------
1193
 3684
1194
 3685                        		.LONGA	off
1195
 3686                        		.LONGI	off
1196
 3687  FA070F
1197
 3688          000004        	parsiz	.SET	4		; parameter stack frame size
1198
 3689          000000        	locsiz	.SET	0		; locals stack frame size
1199
 3690          000004        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
1200
 3691          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
1201
 3692          000005        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
1202
 3693                        	;
1203
 3694          000005        	c	.SET	entsr + 4	; <c> parameter
1204
 3695          000006        	s	.SET	c + 1		; <s> parameter
1205
 3696                        	;
1206
 3697  FA070F  38            		sec			; assume not found
1207
 3698  FA0710  08            		php			; save SR
1208
 3699  FA0711  3B            		tsc			; stack frame
1209
 3700  FA0712  0B            		phd			; save DP reg.
1210
 3701  FA0713  5B            		tcd			; dp access to stack var's
1211
 3702  FA0714                		CPU08			; A/M & X/Y 8 bit
1212
 3703  FA0714  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
1213
 3704                        		.LONGA	off
1214
 3705                        		.LONGI	off
1215
 3706                        		.MNLIST
1216
 3707  FA0716  A0 00         		ldy	#0		; pointer
1217
 3708  FA0718                		INDEX16			; X/Y 16 bit
1218
 3709  FA0718  C2 10         		rep	#PXFLAG
1219
 3710                        		.LONGI	on
1220
 3711                        		.MNLIST
1221
 3712                        	;
1222
 3713  FA071A  B7 06         	?len:	lda	[s],y		; find end of string
1223
 3714  FA071C  F0 07         		beq	?ok		; done when get a nul
1224
 3715  FA071E  C8            		iny			; bump pointer
1225
 3716  FA071F  D0 F9         		bne	?len
1226
 3717  FA0721  98            		tya
1227
 3718  FA0722  88            		dey			; max length = $FFFF
1228
 3719  FA0723  97 06         		sta	[s],y		; force string terminator
1229
 3720                        	;
1230
 3721  FA0725  BB            	?ok:	tyx			; save pointer to the end of string
1231
 3722  FA0726  A5 05         		lda	<c
1232
 3723  FA0728  D7 06         	?cmp:	cmp	[s],y		; compare
1233
 3724  FA072A  F0 07         		beq	?end		; match, reset carry flag
1234
 3725  FA072C  88            		dey			; update pointer
1235
 3726  FA072D  D0 F9         		bne	?cmp		; compare previous char
1236
 3727  FA072F  C7 06         		cmp	[s]		; compare character at index 0
1237
 3728  FA0731  D0 05         		bne	?done		; unmatch
1238
 3729                        	;
1239
 3730  FA0733  A9 01         	?end:	lda	#PCFLAG		; clear CF
1240
 3731  FA0735  14 01         		trb	<entsr
1241
  Tue Jul 17 11:00:21 2018                                                                                               Page   21
1242
 
1243
 
1244
 
1245
 
1246
 3732  FA0737  BB            		tyx			; index where found character
1247
 3733                        	;
1248
 3734  FA0738                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
1249
 3735  FA0738  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1250
 3736                        		.LONGA	on
1251
 3737                        		.LONGI	on
1252
 3738                        		.MNLIST
1253
 3739  FA073A  A5 03         		lda	<entsr+2	; move saved SR and return address
1254
 3740  FA073C  85 07         		sta	<exitsr+2
1255
 3741  FA073E  A5 01         		lda	<entsr
1256
 3742  FA0740  85 05         		sta	<exitsr
1257
 3743  FA0742  2B            		pld			; restore DP reg.
1258
 3744  FA0743  3B            		tsc			; stack frame
1259
 3745  FA0744  69 04 00      		adc	#skpsiz		; realign stack
1260
 3746  FA0747  1B            		tcs
1261
 3747  FA0748  8A            		txa			; C = index
1262
 3748  FA0749  28            		plp			; restore SR
1263
 3749  FA074A  6B            		rtl
1264
 3750
1265
 3751                        		.LONGA	off
1266
 3752                        		.LONGI	off
1267
 3753
1268
 3754                        	; _strlchr(s, c, i)
1269
 3755                        	;
1270
 3756                        	; locates the first occurrence of character <c> in string pointed to by <s>,
1271
 3757                        	; starting from the character at index <i>
1272
 3758                        	;
1273
 3759                        	;	stack param's:
1274
 3760                        	;
1275
 3761                        	;	<s>:		long pointer to string
1276
 3762                        	;	<c>:		character to find (byte)
1277
 3763                        	;	<i>:		index where start searching (word)
1278
 3764                        	;
1279
 3765                        	;	return:		CF=0 & C = index of character in string, if found
1280
 3766                        	;			CF=1 & C = index of the nul terminator if not found
1281
 3767                        	;			           (string length in fact)
1282
 3768                        	;
1283
 3769                        	;	note:		X & Y not preserved
1284
 3770                        	;
1285
 3771                        	;-------------------------------
1286
 3772  FA074B                	_strlchr:
1287
 3773                        		.PUBLIC _strlchr
1288
 3774                        	;-------------------------------
1289
 3775
1290
 3776                        		.LONGA	off
1291
 3777                        		.LONGI	off
1292
 3778  FA074B
1293
 3779          000006        	parsiz	.SET	6		; parameter stack frame size
1294
 3780          000000        	locsiz	.SET	0		; locals stack frame size
1295
 3781          000006        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
1296
 3782          000001        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
1297
 3783          000007        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
1298
 3784                        	;
1299
 3785          000005        	i	.SET	entsr + 4	; <i> parameter
1300
 3786          000007        	c	.SET	i + 2		; <c> parameter
1301
 3787          000008        	s	.SET	c + 1		; <s> parameter
1302
 3788                        	;
1303
  Tue Jul 17 11:00:21 2018                                                                                               Page   22
1304
 
1305
 
1306
 
1307
 
1308
 3789  FA074B  38            		sec			; assume not found
1309
 3790  FA074C  08            		php			; save SR
1310
 3791  FA074D  3B            		tsc			; stack frame
1311
 3792  FA074E  0B            		phd			; save DP reg.
1312
 3793  FA074F  5B            		tcd			; dp access to stack var's
1313
 3794  FA0750                		CPU08			; A/M & X/Y 8 bit
1314
 3795  FA0750  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
1315
 3796                        		.LONGA	off
1316
 3797                        		.LONGI	off
1317
 3798                        		.MNLIST
1318
 3799  FA0752  A0 00         		ldy	#0		; pointer
1319
 3800  FA0754                		INDEX16			; X/Y 16 bit
1320
 3801  FA0754  C2 10         		rep	#PXFLAG
1321
 3802                        		.LONGI	on
1322
 3803                        		.MNLIST
1323
 3804                        	;
1324
 3805  FA0756  B7 08         	?cmp:	lda	[s],y		; get next char from <s>
1325
 3806  FA0758  C5 07         		cmp	<c		; compare with character <c>
1326
 3807  FA075A  F0 0A         		beq	?fnd		; match, test index
1327
 3808  FA075C  C9 00         	?tst:	cmp	#0		; end of string?
1328
 3809  FA075E  F0 0E         		beq	?done		; yes, return index of terminator
1329
 3810  FA0760  C8            		iny			; bump pointer
1330
 3811  FA0761  D0 F3         		bne	?cmp		; compare next char
1331
 3812  FA0763  88            		dey
1332
 3813  FA0764  80 08         		bra	?done
1333
 3814                        	;
1334
 3815  FA0766  C4 05         	?fnd:	cpy	<i		; at right starting index?
1335
 3816  FA0768  90 F2         		bcc	?tst		; no, search again
1336
 3817  FA076A  A9 01         		lda	#PCFLAG		; clear CF
1337
 3818  FA076C  14 01         		trb	<entsr
1338
 3819                        	;
1339
 3820  FA076E                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
1340
 3821  FA076E  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1341
 3822                        		.LONGA	on
1342
 3823                        		.LONGI	on
1343
 3824                        		.MNLIST
1344
 3825  FA0770  A5 03         		lda	<entsr+2	; move saved SR and return address
1345
 3826  FA0772  85 09         		sta	<exitsr+2
1346
 3827  FA0774  A5 01         		lda	<entsr
1347
 3828  FA0776  85 07         		sta	<exitsr
1348
 3829  FA0778  2B            		pld			; restore DP reg.
1349
 3830  FA0779  3B            		tsc			; stack frame
1350
 3831  FA077A  69 06 00      		adc	#skpsiz		; realign stack
1351
 3832  FA077D  1B            		tcs
1352
 3833  FA077E  98            		tya			; C = index
1353
 3834  FA077F  28            		plp			; restore SR
1354
 3835  FA0780  6B            		rtl
1355
 3836
1356
 3837                        		.LONGA	off
1357
 3838                        		.LONGI	off
1358
 3839
1359
 3840                        	; _strstr(s, find)
1360
 3841                        	; locates the first occurrence of string <find> in string <s>
1361
 3842                        	;
1362
 3843                        	;	stack param's:
1363
 3844                        	;
1364
 3845                        	;	<s>:		long pointer to string <s>
1365
  Tue Jul 17 11:00:21 2018                                                                                               Page   23
1366
 
1367
 
1368
 
1369
 
1370
 3846                        	;	<find>:		long pointer to string <find>
1371
 3847                        	;
1372
 3848                        	;	return:		CF=0 & C=index of first character of first occurrence
1373
 3849                        	;			CF=1 & C=length of <s> if <find> occur nowhere in <s>
1374
 3850                        	;			if <find> is empty return CF=0 & C=0
1375
 3851                        	;
1376
 3852                        	;	note:		X & Y not preserved
1377
 3853                        	;
1378
 3854                        	;-------------------------------
1379
 3855  FA0781                	_strstr:
1380
 3856                        		.PUBLIC _strstr
1381
 3857                        	;-------------------------------
1382
 3858
1383
 3859                        		.LONGA	off
1384
 3860                        		.LONGI	off
1385
 3861  FA0781
1386
 3862          000006        	parsiz	.SET	6		; parameter stack frame size
1387
 3863          000004        	locsiz	.SET	4		; locals stack frame size
1388
 3864          00000A        	skpsiz	.SET	parsiz + locsiz	; bytes to skip to realign stack
1389
 3865          000005        	entsr	.SET	locsiz + 1	; pointer to saved status reg.
1390
 3866          00000B        	exitsr	.SET	skpsiz + 1	; pointer to moved status reg.
1391
 3867                        	;
1392
 3868          000009        	find	.SET	entsr + 4	; <find> parameter
1393
 3869          00000C        	s	.SET	find + 3	; <s> parameter
1394
 3870                        	;
1395
 3871          000001        	len	.SET	1		; local: string <find> length
1396
 3872          000003        	c	.SET	3		; local: firs character of <find>
1397
 3873                        	;
1398
 3874  FA0781  38            		sec			; assume not found
1399
 3875  FA0782  08            		php			; save SR
1400
 3876  FA0783                		CPU08			; A/M & X/Y 8 bit
1401
 3877  FA0783  E2 30         		sep	#(PMFLAG.OR.PXFLAG)
1402
 3878                        		.LONGA	off
1403
 3879                        		.LONGI	off
1404
 3880                        		.MNLIST
1405
 3881  FA0785  A2 00         		ldx	#0		; index
1406
 3882  FA0787                		INDEX16			; X/Y 16
1407
 3883  FA0787  C2 10         		rep	#PXFLAG
1408
 3884                        		.LONGI	on
1409
 3885                        		.MNLIST
1410
 3886  FA0789  DA            		phx			; local: <c>
1411
 3887  FA078A  DA            		phx			; local: <len>
1412
 3888  FA078B  3B            		tsc			; stack frame
1413
 3889  FA078C  0B            		phd			; save DP reg.
1414
 3890  FA078D  5B            		tcd			; dp access to stack var's
1415
 3891  FA078E  A7 09         		lda	[find]		; if string <find> is empty...
1416
 3892  FA0790  F0 42         		beq	?end2		; ...exit with index = 0 & CF = 0
1417
 3893  FA0792  85 03         		sta	<c		; <c> = first character of <find>
1418
 3894  FA0794  A4 09         		ldy	<find		; bump pointer to <find>
1419
 3895  FA0796  C8            		iny
1420
 3896  FA0797  84 09         		sty	<find		; <find1> = pointer to 2nd character of <find>
1421
 3897  FA0799  D0 02         		bne	?go
1422
 3898  FA079B  E6 0B         		inc	<find+2
1423
 3899                        	;
1424
 3900  FA079D  9B            	?go	txy			; Y = 0
1425
 3901                        	;
1426
 3902  FA079E  B7 09         	?len:	lda	[find],y	; compute string <find1> length
1427
  Tue Jul 17 11:00:21 2018                                                                                               Page   24
1428
 
1429
 
1430
 
1431
 
1432
 3903  FA07A0  F0 07         		beq	?do		; done when get a nul
1433
 3904  FA07A2  C8            		iny			; bump pointer
1434
 3905  FA07A3  D0 F9         		bne	?len
1435
 3906  FA07A5  98            		tya
1436
 3907  FA07A6  88            		dey			; max length = $FFFF
1437
 3908  FA07A7  97 09         		sta	[find],y	; force string terminator
1438
 3909                        	;
1439
 3910  FA07A9  84 01         	?do:	sty	<len		; <len> = <find1> length
1440
 3911                        	;
1441
 3912  FA07AB  A4 0C         	?do1:	ldy	<s		; scan string <s>
1442
 3913                        	;
1443
 3914  FA07AD  A7 0C         	?do2:	lda	[s]		; next char of string <s>
1444
 3915  FA07AF  F0 27         		beq	?done		; end of string <s>: exit with CF=1
1445
 3916  FA07B1  E8            		inx			; update <s> scan index
1446
 3917  FA07B2  C8            		iny
1447
 3918  FA07B3  84 0C         		sty	<s		; bump <s> pointer
1448
 3919  FA07B5  D0 02         		bne	?do3
1449
 3920  FA07B7  E6 0E         		inc	<s+2
1450
 3921                        	;
1451
 3922  FA07B9  C5 03         	?do3:	cmp	<c		; match first character of <find>?
1452
 3923  FA07BB  D0 F0         		bne	?do2		; no, so check next character of <s>
1453
 3924  FA07BD  A4 01         		ldy	<len		; now compute _strncmp(s, find1, len)
1454
 3925  FA07BF  F0 12         		beq	?end		; if <len> = 0 match first character
1455
 3926  FA07C1  A0 00 00      		ldy	#0
1456
 3927                        	;
1457
 3928  FA07C4  B7 0C         	?cmp:	lda	[s],y		; get next char from <s>
1458
 3929  FA07C6  D7 09         		cmp	[find],y	; compare with byte in <find1>
1459
 3930  FA07C8  D0 E1         		bne	?do1		; unmatch, try next char of <s>
1460
 3931  FA07CA  C9 00         		cmp	#0		; end of string?
1461
 3932  FA07CC  F0 05         		beq	?end		; yes, reset carry flag
1462
 3933  FA07CE  C8            		iny			; bump pointer
1463
 3934  FA07CF  C4 01         		cpy	<len		; at most <len> characters...
1464
 3935  FA07D1  90 F1         		bcc	?cmp		; compare next char
1465
 3936                        	;
1466
 3937  FA07D3  CA            	?end:	dex			; all match: update index & reset carry flag
1467
 3938                        	;
1468
 3939  FA07D4                	?end2:
1469
 3940  FA07D4  A9 01         		lda	#PCFLAG		; reset CF...
1470
 3941  FA07D6  14 05         		trb	<entsr		; ...on saved status reg.
1471
 3942                        	;
1472
 3943  FA07D8                	?done:	CPU16CLC		; A,X,Y 16 bit - clear carry
1473
 3944  FA07D8  C2 31         		rep	#(PMFLAG.OR.PXFLAG.OR.PCFLAG)
1474
 3945                        		.LONGA	on
1475
 3946                        		.LONGI	on
1476
 3947                        		.MNLIST
1477
 3948  FA07DA  A5 07         		lda	<entsr+2	; move saved SR and return address
1478
 3949  FA07DC  85 0D         		sta	<exitsr+2
1479
 3950  FA07DE  A5 05         		lda	<entsr
1480
 3951  FA07E0  85 0B         		sta	<exitsr
1481
 3952  FA07E2  2B            		pld			; restore DP reg.
1482
 3953  FA07E3  3B            		tsc			; stack frame
1483
 3954  FA07E4  69 0A 00      		adc	#skpsiz		; realign stack
1484
 3955  FA07E7  1B            		tcs
1485
 3956  FA07E8  8A            		txa			; C = index
1486
 3957  FA07E9  28            		plp			; restore SR
1487
 3958  FA07EA  6B            		rtl
1488
 3959
1489
  Tue Jul 17 11:00:21 2018                                                                                               Page   25
1490
 
1491
 
1492
 
1493
 
1494
 3960                        		.LONGA	off
1495
 3961                        		.LONGI	off
1496
 
1497
 
1498
             Lines Assembled : 3788                  Errors : 0
1499
 
1500
 
1501