Blame | Last modification | View Log | Download | RSS feed
Tue Jul 17 11:00:21 2018 Page 1
2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
-----------------------------------------------------
Input Filename : src\FA\string.asm
Output Filename : obj\FA\string.obj
Listing Has Been Relocated
2603 .LIST on
2604
2605
2606 .LIST on
2607
2608
2609 ;---------------------------------------------------------------------------
2610 ; code segment -- bank $FA
2611 ;---------------------------------------------------------------------------
2612
2613 .CODEFA
2614
2615 .LONGA off
2616 .LONGI off
2617
2618 ; _strlen(src)
2619 ;
2620 ; return in C the length of the string src
2621 ; if the lenght is greater than 64k return $FFFF
2622 ;
2623 ;-------------------------------
2624 FA03F7 _strlen:
2625 .PUBLIC _strlen
2626 ;-------------------------------
2627
2628 .LONGA off
2629 .LONGI off
2630 FA03F7
2631 000003 parsiz .SET 3 ; parameter stack frame size
2632 000000 locsiz .SET 0 ; locals stack frame size
2633 000003 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
2634 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
2635 000004 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
2636 ;
2637 000005 src .SET entsr + 4 ; <src> parameter
2638 ;
2639 FA03F7 08 php ; save SR
2640 FA03F8 3B tsc ; stack frame
2641 FA03F9 0B phd ; save DP reg.
2642 FA03FA 5B tcd ; dp access to stack var's
2643 FA03FB INDEX16 ; X/Y 16 bit
2644 FA03FB C2 10 rep #PXFLAG
2645 .LONGI on
2646 .MNLIST
2647 FA03FD ACC08 ; be sure A 8 bit
2648 FA03FD E2 20 sep #PMFLAG
Tue Jul 17 11:00:21 2018 Page 2
2649 .LONGA off
2650 .MNLIST
2651 FA03FF A0 00 00 ldy #0 ; pointer
2652 ;
2653 FA0402 B7 05 ?loop: lda [src],y ; get next char
2654 FA0404 F0 04 beq ?done ; done when get a nul
2655 FA0406 C8 iny ; bump pointer
2656 FA0407 D0 F9 bne ?loop
2657 FA0409 88 dey ; max length = $FFFF
2658 ;
2659 FA040A ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
2660 FA040A C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2661 .LONGA on
2662 .LONGI on
2663 .MNLIST
2664 FA040C A5 03 lda <entsr+2 ; move saved SR and return address
2665 FA040E 85 06 sta <exitsr+2
2666 FA0410 A5 01 lda <entsr
2667 FA0412 85 04 sta <exitsr
2668 FA0414 2B pld ; restore DP reg.
2669 FA0415 3B tsc ; stack frame
2670 FA0416 69 03 00 adc #skpsiz ; realign stack
2671 FA0419 1B tcs
2672 FA041A 98 tya ; C = string length
2673 FA041B 28 plp ; restore SR
2674 FA041C 6B rtl
2675
2676 .LONGA off
2677 .LONGI off
2678
2679 ; _strcpy(dst, src)
2680 ;
2681 ; copy string src to dst
2682 ; return in C the lenght of string
2683 ; dst must have sufficient room to hold the result
2684 ; if length of src > $FFFF, dst will be truncated
2685 ;
2686 ;-------------------------------
2687 FA041D _strcpy:
2688 .PUBLIC _strcpy
2689 ;-------------------------------
2690
2691 .LONGA off
2692 .LONGI off
2693 FA041D
2694 000006 parsiz .SET 6 ; parameter stack frame size
2695 000000 locsiz .SET 0 ; locals stack frame size
2696 000006 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
2697 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
2698 000007 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
2699 ;
2700 000005 src .SET entsr + 4 ; <src> parameter
2701 000008 dst .SET src + 3 ; <dst> parameter
2702 ;
2703 FA041D 08 php ; save SR
2704 FA041E 3B tsc ; stack frame
2705 FA041F 0B phd ; save DP reg.
Tue Jul 17 11:00:21 2018 Page 3
2706 FA0420 5B tcd ; dp access to stack var's
2707 FA0421 INDEX16 ; X/Y 16 bit
2708 FA0421 C2 10 rep #PXFLAG
2709 .LONGI on
2710 .MNLIST
2711 FA0423 ACC08 ; be sure A 8 bit
2712 FA0423 E2 20 sep #PMFLAG
2713 .LONGA off
2714 .MNLIST
2715 FA0425 A0 00 00 ldy #0 ; pointer
2716 ;
2717 FA0428 B7 05 ?loop: lda [src],y ; get next char
2718 FA042A 97 08 sta [dst],y ; store
2719 FA042C F0 07 beq ?done ; done when get a null
2720 FA042E C8 iny ; bump pointer
2721 FA042F D0 F7 bne ?loop
2722 FA0431 98 tya ; A=0
2723 FA0432 88 dey ; max length = $FFFF
2724 FA0433 97 08 sta [dst],y ; always NUL terminates dst
2725 ;
2726 FA0435 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
2727 FA0435 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2728 .LONGA on
2729 .LONGI on
2730 .MNLIST
2731 FA0437 A5 03 lda <entsr+2 ; move saved SR and return address
2732 FA0439 85 09 sta <exitsr+2
2733 FA043B A5 01 lda <entsr
2734 FA043D 85 07 sta <exitsr
2735 FA043F 2B pld ; restore DP reg.
2736 FA0440 3B tsc ; stack frame
2737 FA0441 69 06 00 adc #skpsiz ; realign stack
2738 FA0444 1B tcs
2739 FA0445 98 tya ; C = string length
2740 FA0446 28 plp ; restore SR
2741 FA0447 6B rtl
2742
2743 .LONGA off
2744 .LONGI off
2745
2746 ; _strcat(str, append)
2747 ;
2748 ; append string append to string str
2749 ; return in C the lenght of string
2750 ; str must have sufficient room to hold the result
2751 ;
2752 ;-------------------------------
2753 FA0448 _strcat:
2754 .PUBLIC _strcat
2755 ;-------------------------------
2756
2757 .LONGA off
2758 .LONGI off
2759 FA0448
2760 000006 parsiz .SET 6 ; parameter stack frame size
2761 000002 locsiz .SET 2 ; locals stack frame size
2762 000008 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
Tue Jul 17 11:00:21 2018 Page 4
2763 000003 entsr .SET locsiz + 1 ; pointer to saved status reg.
2764 000009 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
2765 ;
2766 000007 append .SET entsr + 4 ; <append> parameter
2767 00000A str .SET append + 3 ; <str> parameter
2768 ;
2769 000001 indx .SET 1 ; <indx>: local var
2770 ;
2771 FA0448 08 php ; save SR
2772 FA0449 INDEX16 ; X/Y 16 bit
2773 FA0449 C2 10 rep #PXFLAG
2774 .LONGI on
2775 .MNLIST
2776 FA044B A0 00 00 ldy #0 ; pointer
2777 FA044E 5A phy ; make room for local var <indx=0>
2778 FA044F 3B tsc ; stack frame
2779 FA0450 0B phd ; save DP reg.
2780 FA0451 5B tcd ; dp access to stack var's
2781 FA0452 ACC08 ; be sure A is 8 bit
2782 FA0452 E2 20 sep #PMFLAG
2783 .LONGA off
2784 .MNLIST
2785 ;
2786 FA0454 B7 0A ?loop: lda [str],y ; search end of string str
2787 FA0456 F0 06 beq ?cat ; done when get a nul
2788 FA0458 C8 iny ; bump pointer
2789 FA0459 D0 F9 bne ?loop
2790 FA045B 88 dey ; max length = $FFFF
2791 FA045C 80 13 bra ?done ; can't append more char's
2792 ;
2793 FA045E BB ?cat: tyx ; X = current str index
2794 FA045F A4 01 ldy <indx ; index to append string
2795 FA0461 B7 07 lda [append],y ; get next char from append
2796 FA0463 C8 iny ; bump pointer to append string
2797 FA0464 84 01 sty <indx
2798 FA0466 9B txy
2799 FA0467 97 0A sta [str],y ; append char to str
2800 FA0469 C9 00 cmp #0 ; nul?
2801 FA046B F0 04 beq ?done ; yes
2802 FA046D C8 iny ; bump pointer
2803 FA046E D0 EE bne ?cat ; append next char
2804 FA0470 88 dey ; max length = $FFFF
2805 ;
2806 FA0471 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
2807 FA0471 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2808 .LONGA on
2809 .LONGI on
2810 .MNLIST
2811 FA0473 A5 05 lda <entsr+2 ; move saved SR and return address
2812 FA0475 85 0B sta <exitsr+2
2813 FA0477 A5 03 lda <entsr
2814 FA0479 85 09 sta <exitsr
2815 FA047B 2B pld ; restore DP reg.
2816 FA047C 3B tsc ; stack frame
2817 FA047D 69 08 00 adc #skpsiz ; realign stack
2818 FA0480 1B tcs
2819 FA0481 98 tya ; C = string length
Tue Jul 17 11:00:21 2018 Page 5
2820 FA0482 28 plp ; restore SR
2821 FA0483 6B rtl
2822
2823 .LONGA off
2824 .LONGI off
2825
2826 ; _strncpy(dst, src, siz)
2827 ;
2828 ; copy string src to string dst of size <siz+1>
2829 ; at most siz characters will be copied
2830 ; return in C the lenght of string
2831 ; if <siz=0> src is an empty string
2832 ;
2833 ;-------------------------------
2834 FA0484 _strncpy:
2835 .PUBLIC _strncpy
2836 ;-------------------------------
2837
2838 .LONGA off
2839 .LONGI off
2840 FA0484
2841 000008 parsiz .SET 8 ; parameter stack frame size
2842 000000 locsiz .SET 0 ; locals stack frame size
2843 000008 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
2844 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
2845 000009 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
2846 ;
2847 000005 siz .SET entsr + 4 ; <siz> parameter
2848 000007 src .SET siz + 2 ; <src> parameter
2849 00000A dst .SET src + 3 ; <dst> parameter
2850 ;
2851 FA0484 08 php ; save SR
2852 FA0485 3B tsc ; stack frame
2853 FA0486 0B phd ; save DP reg.
2854 FA0487 5B tcd ; dp access to stack var's
2855 FA0488 INDEX16 ; X/Y 16 bit
2856 FA0488 C2 10 rep #PXFLAG
2857 .LONGI on
2858 .MNLIST
2859 FA048A ACC08 ; be sure A 8 bit
2860 FA048A E2 20 sep #PMFLAG
2861 .LONGA off
2862 .MNLIST
2863 FA048C A4 05 ldy <siz
2864 FA048E F0 0E beq ?nul ; return an empty string
2865 FA0490 A0 00 00 ldy #0 ; pointer
2866 ;
2867 FA0493 B7 07 ?loop: lda [src],y ; get next char
2868 FA0495 97 0A sta [dst],y ; store
2869 FA0497 F0 09 beq ?done ; done when get a null
2870 FA0499 C8 iny ; bump pointer
2871 FA049A C4 05 cpy <siz
2872 FA049C 90 F5 bcc ?loop
2873 ;
2874 FA049E A9 00 ?nul: lda #0 ; always NUL terminates dst
2875 FA04A0 97 0A sta [dst],y
2876 ;
Tue Jul 17 11:00:21 2018 Page 6
2877 FA04A2 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
2878 FA04A2 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2879 .LONGA on
2880 .LONGI on
2881 .MNLIST
2882 FA04A4 A5 03 lda <entsr+2 ; move saved SR and return address
2883 FA04A6 85 0B sta <exitsr+2
2884 FA04A8 A5 01 lda <entsr
2885 FA04AA 85 09 sta <exitsr
2886 FA04AC 2B pld ; restore DP reg.
2887 FA04AD 3B tsc ; stack frame
2888 FA04AE 69 08 00 adc #skpsiz ; realign stack
2889 FA04B1 1B tcs
2890 FA04B2 98 tya ; C = string length
2891 FA04B3 28 plp ; restore SR
2892 FA04B4 6B rtl
2893
2894 .LONGA off
2895 .LONGI off
2896
2897 ; _strdel(str, start, count)
2898 ;
2899 ; remove at most <count> characters from string <str>, starting
2900 ; at index <start>
2901 ;
2902 ; stack param's:
2903 ;
2904 ; <str>: long pointer to string
2905 ; <start>: index of first character to remove (word)
2906 ; <count>: count of characters to remove (word)
2907 ;
2908 ; return: C = length of string
2909 ;
2910 ; note: X & Y not preserved
2911 ;
2912 ;-------------------------------
2913 FA04B5 _strdel:
2914 .PUBLIC _strdel
2915 ;-------------------------------
2916
2917 .LONGA off
2918 .LONGI off
2919 FA04B5
2920 000007 parsiz .SET 7 ; parameter stack frame size
2921 000000 locsiz .SET 0 ; locals stack frame size
2922 000007 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
2923 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
2924 000008 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
2925 ;
2926 000005 count .SET entsr + 4 ; <count> parameter
2927 000007 start .SET count + 2 ; <start> parameter
2928 000009 str .SET start + 2 ; <str> parameter
2929 ;
2930 FA04B5 08 php ; save SR
2931 FA04B6 3B tsc ; stack frame
2932 FA04B7 0B phd ; save DP reg.
2933 FA04B8 5B tcd ; dp access to stack var's
Tue Jul 17 11:00:21 2018 Page 7
2934 FA04B9 CPU08 ; be sure A,X,Y 8 bit
2935 FA04B9 E2 30 sep #(PMFLAG.OR.PXFLAG)
2936 .LONGA off
2937 .LONGI off
2938 .MNLIST
2939 FA04BB A0 00 ldy #0 ; pointer
2940 FA04BD INDEX16 ; X/Y 16 bit
2941 FA04BD C2 10 rep #PXFLAG
2942 .LONGI on
2943 .MNLIST
2944 ;
2945 FA04BF B7 09 ?len: lda [str],y ; compute string length
2946 FA04C1 F0 07 beq ?chk ; done when get a nul
2947 FA04C3 C8 iny ; bump pointer
2948 FA04C4 D0 F9 bne ?len
2949 FA04C6 98 tya
2950 FA04C7 88 dey ; max length = $FFFF
2951 FA04C8 97 09 sta [str],y ; force string terminator
2952 ;
2953 FA04CA BB ?chk: tyx ; check string lenght
2954 FA04CB F0 2D beq ?done ; empty string
2955 FA04CD A6 05 ldx <count
2956 FA04CF F0 29 beq ?done ; nothing to delete
2957 FA04D1 C4 07 cpy <start ; if length <= start...
2958 FA04D3 90 25 bcc ?done ; ...nothing to delete
2959 FA04D5 F0 23 beq ?done
2960 FA04D7 CPU16CLC ; A 16 bit and clear carry
2961 FA04D7 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2962 .LONGA on
2963 .LONGI on
2964 .MNLIST
2965 FA04D9 8A txa ; <count>
2966 FA04DA 65 07 adc <start ; index of first character to move back
2967 FA04DC 85 05 sta <count
2968 FA04DE ACC08 ; A 8 bit
2969 FA04DE E2 20 sep #PMFLAG
2970 .LONGA off
2971 .MNLIST
2972 FA04E0 B0 06 bcs ?mov ; beyond the string...put nul at <start> index
2973 FA04E2 C4 05 cpy <count ; length < start + count?
2974 FA04E4 90 02 bcc ?mov ; yes -- terminate string at <start> index
2975 FA04E6 A4 05 ldy <count ; index of next character to move back
2976 FA04E8 B7 09 ?mov: lda [str],y
2977 FA04EA BB tyx ; save to X
2978 FA04EB A4 07 ldy <start ; index where put character
2979 FA04ED 97 09 sta [str],y
2980 FA04EF C9 00 cmp #0 ; nul byte?
2981 FA04F1 F0 07 beq ?done ; yes, done
2982 FA04F3 C8 iny
2983 FA04F4 84 07 sty <start
2984 FA04F6 9B txy
2985 FA04F7 C8 iny
2986 FA04F8 80 EE bra ?mov ; move loop
2987 ;
2988 FA04FA ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
2989 FA04FA C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2990 .LONGA on
Tue Jul 17 11:00:21 2018 Page 8
2991 .LONGI on
2992 .MNLIST
2993 FA04FC A5 03 lda <entsr+2 ; move saved SR and return address
2994 FA04FE 85 0A sta <exitsr+2
2995 FA0500 A5 01 lda <entsr
2996 FA0502 85 08 sta <exitsr
2997 FA0504 2B pld ; restore DP reg.
2998 FA0505 3B tsc ; stack frame
2999 FA0506 69 07 00 adc #skpsiz ; realign stack
3000 FA0509 1B tcs
3001 FA050A 98 tya ; C = string length
3002 FA050B 28 plp ; restore SR
3003 FA050C 6B rtl
3004
3005 .LONGA off
3006 .LONGI off
3007
3008 ; _strins(str1, str2, start, maxlen)
3009 ;
3010 ; insert <str2> string into <str1> string, starting at index <start> of <str1>
3011 ; character of <str1>, starting from <start> index, are moved ahead to make
3012 ; room for characters of <str2>
3013 ; if <maxlen>=0 then string <str1> will be truncated (return an empty string)
3014 ; buffer <str1> should have a size=<maxlen>+1 to hold the nul terminator
3015 ;
3016 ; stack param's:
3017 ;
3018 ; <str1>: long pointer to target string
3019 ; <str2>: long pointer to string to insert
3020 ; <start>: index of first character where start insertion (word)
3021 ; <maxlen>: max. length of <str1> (word)
3022 ;
3023 ; return: C = length of string <str1>
3024 ;
3025 ; note: X & Y not preserved
3026 ;
3027 ;-------------------------------
3028 FA050D _strins:
3029 .PUBLIC _strins
3030 ;-------------------------------
3031
3032 .LONGA off
3033 .LONGI off
3034 FA050D
3035 00000A parsiz .SET 10 ; parameter stack frame size
3036 00000E locsiz .SET 14 ; locals stack frame size
3037 000018 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3038 00000F entsr .SET locsiz + 1 ; pointer to saved status reg.
3039 000019 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3040 ;
3041 000013 maxlen .SET entsr + 4 ; <maxlen> parameter
3042 000015 start .SET maxlen + 2 ; <start> parameter
3043 000017 str2 .SET start + 2 ; <str2> long pointer
3044 00001A str1 .SET str2 + 3 ; <str1> long pointer
3045 ;
3046 000001 len1 .SET 1 ; local: <str1> length
3047 000003 len2 .SET 3 ; local: <str2> length
Tue Jul 17 11:00:21 2018 Page 9
3048 000005 iy .SET 5 ; local: temp. index
3049 000007 end .SET 7 ; local: index of last byte of <str1> to move
3050 000009 newend .SET 9 ; local: index of final <str1> ending
3051 00000B cnt1 .SET 11 ; local: count of bytes to move in <str1>
3052 00000D cnt2 .SET 13 ; local: count of bytes to copy from <str2>
3053 ;
3054 FA050D 08 php ; save SR
3055 FA050E CPU16CLC
3056 FA050E C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3057 .LONGA on
3058 .LONGI on
3059 .MNLIST
3060 FA0510 3B tsc
3061 FA0511 E9 0D 00 sbc #locsiz-1 ; make room for locals var's
3062 FA0514 1B tcs ; stack frame
3063 FA0515 0B phd ; save DP reg.
3064 FA0516 5B tcd ; dp access to stack var's
3065 FA0517 64 05 stz <iy ; clear <iy>, <cnt1>, <cnt2>
3066 FA0519 64 0B stz <cnt1
3067 FA051B 64 0D stz <cnt2
3068 FA051D ACC08 ; X/Y 16 bit, A/M 8 bit
3069 FA051D E2 20 sep #PMFLAG
3070 .LONGA off
3071 .MNLIST
3072 FA051F A4 05 ldy <iy ; pointer Y = 0
3073 FA0521 BB tyx ; X = 0
3074 ;
3075 FA0522 B7 17 ?len2: lda [str2],y ; compute string <str2> length
3076 FA0524 F0 07 beq ?stl ; done when get a nul
3077 FA0526 C8 iny ; bump pointer
3078 FA0527 D0 F9 bne ?len2
3079 FA0529 98 tya
3080 FA052A 88 dey ; max length = $FFFF
3081 FA052B 97 17 sta [str2],y ; force string terminator
3082 ;
3083 FA052D 84 03 ?stl: sty <len2 ; store <str2> lenght
3084 FA052F 9B txy ; Y = 0
3085 ;
3086 FA0530 B7 1A ?len1: lda [str1],y ; compute string <str1> length
3087 FA0532 F0 07 beq ?chk ; done when get a nul
3088 FA0534 C8 iny ; bump pointer
3089 FA0535 D0 F9 bne ?len1
3090 FA0537 98 tya
3091 FA0538 88 dey ; max length = $FFFF
3092 FA0539 97 1A sta [str1],y ; force string terminator
3093 ;
3094 FA053B C4 13 ?chk: cpy <maxlen ; fix <maxlen> if below the actual...
3095 FA053D 90 02 bcc ?chk1 ; ...<str1> length
3096 FA053F 84 13 sty <maxlen
3097 ;
3098 FA0541 ?chk1: CPU16CLC
3099 FA0541 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3100 .LONGA on
3101 .LONGI on
3102 .MNLIST
3103 FA0543 98 tya
3104 FA0544 65 03 adc <len2 ; final string length
Tue Jul 17 11:00:21 2018 Page 10
3105 FA0546 B0 06 bcs ?chk2 ; truncate to <maxlen>
3106 FA0548 C5 13 cmp <maxlen ; can fit?
3107 FA054A B0 02 bcs ?chk2 ; no, truncate to <maxlen>
3108 FA054C 85 13 sta <maxlen ; store final length
3109 ;
3110 FA054E 84 01 ?chk2: sty <len1 ; store <str1> length
3111 FA0550 A6 03 ldx <len2 ; if <str2> is empty...
3112 FA0552 F0 6E beq ?done ; ...return <str1>
3113 FA0554 BB tyx ; if <str1> is empty...
3114 FA0555 F0 0B beq ?cat ; ...return <str1> = <str2>
3115 FA0557 A6 13 ldx <maxlen
3116 FA0559 CA dex
3117 FA055A 86 09 stx <newend ; pointer to the end of final <str1>
3118 FA055C A5 15 lda <start
3119 FA055E C5 01 cmp <len1
3120 FA0560 90 0B bcc ?chk3 ; <start> is in range [1..length(str1)-1]
3121 ;
3122 FA0562 84 15 ?cat: sty <start ; append <str2> to the end of <str1>
3123 FA0564 38 sec
3124 FA0565 A5 13 lda <maxlen ; count of bytes to copy from <str2> to...
3125 FA0567 E5 01 sbc <len1 ; ...<str1> starting at index <start>
3126 FA0569 85 0D sta <cnt2
3127 FA056B 80 24 bra ?mov
3128 ;
3129 FA056D 65 03 ?chk3: adc <len2 ; <start> + length(str2)
3130 FA056F 90 03 bcc ?chk4
3131 FA0571 A9 FF FF lda #$FFFF ; limit max. length
3132 ;
3133 FA0574 C5 13 ?chk4: cmp <maxlen ; can move som bytes of <str1> to make room?
3134 FA0576 90 06 bcc ?less ; yes
3135 FA0578 E5 15 sbc <start ; no... compute how much bytes of <str2>...
3136 FA057A 85 0D sta <cnt2 ; ...can be inserted
3137 FA057C 80 13 bra ?mov
3138 ;
3139 FA057E 85 0B ?less: sta <cnt1 ; index where move bytes of <str1>
3140 FA0580 38 sec
3141 FA0581 A5 13 lda <maxlen
3142 FA0583 E5 0B sbc <cnt1
3143 FA0585 85 0B sta <cnt1 ; count of bytes to move in <str1>
3144 FA0587 18 clc
3145 FA0588 65 15 adc <start
3146 FA058A 3A dec a ; pointer to the last byte of <str1>...
3147 FA058B 85 07 sta <end ; ...that will be moved ahead
3148 FA058D A6 03 ldx <len2 ; the whole <str2> can be inserted
3149 FA058F 86 0D stx <cnt2
3150 ;
3151 ; move <cnt1> bytes from the <str1> to the new end of <str1>
3152 FA0591 ?mov: ACC08 ; A/M 8 bit
3153 FA0591 E2 20 sep #PMFLAG
3154 .LONGA off
3155 .MNLIST
3156 FA0593 A6 0B ldx <cnt1 ; count of bytes to move
3157 FA0595 F0 11 beq ?cpy ; nothing to move in <str1>
3158 ;
3159 FA0597 A4 07 ?lmov: ldy <end ; move from the end of <str1>...
3160 FA0599 B7 1A lda [str1],y
3161 FA059B 88 dey
Tue Jul 17 11:00:21 2018 Page 11
3162 FA059C 84 07 sty <end
3163 FA059E A4 09 ldy <newend ; ...to the new end
3164 FA05A0 97 1A sta [str1],y
3165 FA05A2 88 dey ; decrement (move previous)
3166 FA05A3 84 09 sty <newend
3167 FA05A5 CA dex
3168 FA05A6 D0 EF bne ?lmov ; move loop
3169 ;
3170 ; copy <cnt2> bytes from beginning of <str2> to <str1>, starting at index <start>
3171 FA05A8 A6 0D ?cpy: ldx <cnt2 ; count of bytes to copy
3172 FA05AA F0 11 beq ?nul ; nothing to copy: terminate <str1>
3173 ;
3174 FA05AC A4 05 ?lcpy: ldy <iy
3175 FA05AE B7 17 lda [str2],y
3176 FA05B0 C8 iny
3177 FA05B1 84 05 sty <iy
3178 FA05B3 A4 15 ldy <start ; target index
3179 FA05B5 97 1A sta [str1],y
3180 FA05B7 C8 iny
3181 FA05B8 84 15 sty <start
3182 FA05BA CA dex
3183 FA05BB D0 EF bne ?lcpy ; loop copy
3184 ;
3185 FA05BD 8A ?nul: txa ; terminate string <str1>
3186 FA05BE A4 13 ldy <maxlen
3187 FA05C0 97 1A sta [str1],y
3188 ;
3189 FA05C2 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
3190 FA05C2 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3191 .LONGA on
3192 .LONGI on
3193 .MNLIST
3194 FA05C4 A5 11 lda <entsr+2 ; move saved SR and return address
3195 FA05C6 85 1B sta <exitsr+2
3196 FA05C8 A5 0F lda <entsr
3197 FA05CA 85 19 sta <exitsr
3198 FA05CC 2B pld ; restore DP reg.
3199 FA05CD 3B tsc ; stack frame
3200 FA05CE 69 18 00 adc #skpsiz ; realign stack
3201 FA05D1 1B tcs
3202 FA05D2 98 tya ; C = string <str1> length
3203 FA05D3 28 plp ; restore SR
3204 FA05D4 6B rtl
3205
3206 .LONGA off
3207 .LONGI off
3208
3209 ;---------------------------------------------------------------------------
3210 ; strings comparison
3211 ;---------------------------------------------------------------------------
3212
3213 ; _strcmp(s1, s2)
3214 ;
3215 ; lexicographically compare the null-terminated strings s1 and s2
3216 ;
3217 ; stack param's:
3218 ;
Tue Jul 17 11:00:21 2018 Page 12
3219 ; <s1>: long pointer to first string
3220 ; <s2>: long pointer to second string
3221 ;
3222 ; return: status flags affected like in 'cmp' instruction
3223 ; CF=0 & ZF=0 if s1 less than s2
3224 ; CF=1 & ZF=1 if s1 equal to s2
3225 ; CF=1 & ZF=0 if s1 greater than s2
3226 ;
3227 ; note: X & Y not preserved
3228 ;
3229 ;-------------------------------
3230 FA05D5 _strcmp:
3231 .PUBLIC _strcmp
3232 ;-------------------------------
3233
3234 .LONGA off
3235 .LONGI off
3236 FA05D5
3237 000006 parsiz .SET 6 ; parameter stack frame size
3238 000000 locsiz .SET 0 ; locals stack frame size
3239 000006 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3240 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
3241 000007 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3242 ;
3243 000005 s2 .SET entsr + 4 ; <s1> parameter
3244 000008 s1 .SET s2 + 3 ; <s2> parameter
3245 ;
3246 FA05D5 C2 03 rep #PZFLAG+PCFLAG ; clear CF & ZF
3247 FA05D7 08 php ; save SR
3248 FA05D8 3B tsc ; stack frame
3249 FA05D9 0B phd ; save DP reg.
3250 FA05DA 5B tcd ; dp access to stack var's
3251 FA05DB CPU08 ; A/M & X/Y 8 bit
3252 FA05DB E2 30 sep #(PMFLAG.OR.PXFLAG)
3253 .LONGA off
3254 .LONGI off
3255 .MNLIST
3256 FA05DD A0 00 ldy #0 ; pointer
3257 FA05DF INDEX16 ; X/Y 16 bit
3258 FA05DF C2 10 rep #PXFLAG
3259 .LONGI on
3260 .MNLIST
3261 ;
3262 FA05E1 B7 08 ?cmp: lda [s1],y ; get next char from <s1>
3263 FA05E3 D7 05 cmp [s2],y ; compare with byte in <s2>
3264 FA05E5 D0 08 bne ?end ; unmatch, set flags
3265 FA05E7 C9 00 cmp #0 ; end of string?
3266 FA05E9 F0 04 beq ?end ; yes, set flags
3267 FA05EB C8 iny ; bump pointer
3268 FA05EC D0 F3 bne ?cmp ; compare next char
3269 FA05EE 38 sec ; all match: set carry
3270 ;
3271 FA05EF 08 ?end: php ; CF & ZF affected according comparison
3272 FA05F0 68 pla
3273 FA05F1 29 03 and #PZFLAG+PCFLAG ; mask on CF & ZF
3274 FA05F3 04 01 tsb <entsr ; set flags on saved status reg.
3275 FA05F5 CPU16CLC ; A,X,Y 16 bit - clear carry
Tue Jul 17 11:00:21 2018 Page 13
3276 FA05F5 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3277 .LONGA on
3278 .LONGI on
3279 .MNLIST
3280 FA05F7 A5 03 lda <entsr+2 ; move saved SR and return address
3281 FA05F9 85 09 sta <exitsr+2
3282 FA05FB A5 01 lda <entsr
3283 FA05FD 85 07 sta <exitsr
3284 FA05FF 2B pld ; restore DP reg.
3285 FA0600 3B tsc ; stack frame
3286 FA0601 69 06 00 adc #skpsiz ; realign stack
3287 FA0604 1B tcs
3288 FA0605 28 plp ; restore SR
3289 FA0606 6B rtl
3290
3291 .LONGA off
3292 .LONGI off
3293
3294 ; _strncmp(s1, s2, n)
3295 ;
3296 ; lexicographically compare the null-terminated strings s1 and s2
3297 ; this function compares not more than n characters
3298 ;
3299 ; stack param's:
3300 ;
3301 ; <s1>: long pointer to first string
3302 ; <s2>: long pointer to second string
3303 ; <n>: word: count of characters to compare
3304 ;
3305 ; return: status flags affected like in 'cmp' instruction
3306 ; CF=0 & ZF=0 if s1 less than s2
3307 ; CF=1 & ZF=1 if s1 equal to s2
3308 ; CF=1 & ZF=0 if s1 greater than s2
3309 ;
3310 ; note: X & Y not preserved
3311 ;
3312 ;-------------------------------
3313 FA0607 _strncmp:
3314 .PUBLIC _strncmp
3315 ;-------------------------------
3316
3317 .LONGA off
3318 .LONGI off
3319 FA0607
3320 000008 parsiz .SET 8 ; parameter stack frame size
3321 000000 locsiz .SET 0 ; locals stack frame size
3322 000008 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3323 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
3324 000009 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3325 ;
3326 000005 n .SET entsr + 4 ; <n> parameter
3327 000007 s2 .SET n + 2 ; <s1> parameter
3328 00000A s1 .SET s2 + 3 ; <s2> parameter
3329 ;
3330 FA0607 C2 03 rep #PZFLAG+PCFLAG ; clear CF & ZF
3331 FA0609 08 php ; save SR
3332 FA060A 3B tsc ; stack frame
Tue Jul 17 11:00:21 2018 Page 14
3333 FA060B 0B phd ; save DP reg.
3334 FA060C 5B tcd ; dp access to stack var's
3335 FA060D CPU08SEC ; A/M & X/Y 8 bit & set carry
3336 FA060D E2 31 sep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3337 .LONGA off
3338 .LONGI off
3339 .MNLIST
3340 FA060F A0 00 ldy #0 ; pointer
3341 FA0611 INDEX16 ; X/Y 16 bit
3342 FA0611 C2 10 rep #PXFLAG
3343 .LONGI on
3344 .MNLIST
3345 FA0613 A6 05 ldx <n ; if <n> = 0 set CF=1 & ZF=1
3346 FA0615 F0 0F beq ?end
3347 ;
3348 FA0617 B7 0A ?cmp: lda [s1],y ; get next char from <s1>
3349 FA0619 D7 07 cmp [s2],y ; compare with byte in <s2>
3350 FA061B D0 09 bne ?end ; unmatch, set flags
3351 FA061D C9 00 cmp #0 ; end of string?
3352 FA061F F0 05 beq ?end ; yes, set flags
3353 FA0621 C8 iny ; bump pointer
3354 FA0622 C4 05 cpy <n ; at most <n> characters...
3355 FA0624 90 F1 bcc ?cmp ; compare next char
3356 ; all match: set carry & zero flag
3357 ;
3358 FA0626 08 ?end: php ; CF & ZF affected according comparison
3359 FA0627 68 pla
3360 FA0628 29 03 and #PZFLAG+PCFLAG ; mask on CF & ZF
3361 FA062A 04 01 tsb <entsr ; set flags on saved status reg.
3362 FA062C CPU16CLC ; A,X,Y 16 bit - clear carry
3363 FA062C C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3364 .LONGA on
3365 .LONGI on
3366 .MNLIST
3367 FA062E A5 03 lda <entsr+2 ; move saved SR and return address
3368 FA0630 85 0B sta <exitsr+2
3369 FA0632 A5 01 lda <entsr
3370 FA0634 85 09 sta <exitsr
3371 FA0636 2B pld ; restore DP reg.
3372 FA0637 3B tsc ; stack frame
3373 FA0638 69 08 00 adc #skpsiz ; realign stack
3374 FA063B 1B tcs
3375 FA063C 28 plp ; restore SR
3376 FA063D 6B rtl
3377
3378 .LONGA off
3379 .LONGI off
3380 FA063E
3381 ; _strcasecmp(s1, s2)
3382 ;
3383 ; lexicographically compare the null-terminated strings s1 and s2,
3384 ; ignoring stings case
3385 ;
3386 ; stack param's:
3387 ;
3388 ; <s1>: long pointer to first string
3389 ; <s2>: long pointer to second string
Tue Jul 17 11:00:21 2018 Page 15
3390 ;
3391 ; return: status flags affected like in 'cmp' instruction
3392 ; CF=0 & ZF=0 if s1 less than s2
3393 ; CF=1 & ZF=1 if s1 equal to s2
3394 ; CF=1 & ZF=0 if s1 greater than s2
3395 ;
3396 ; note: X & Y not preserved
3397 ;
3398 ;-------------------------------
3399 FA063E _strcasecmp:
3400 .PUBLIC _strcasecmp
3401 ;-------------------------------
3402
3403 .LONGA off
3404 .LONGI off
3405 FA063E
3406 000006 parsiz .SET 6 ; parameter stack frame size
3407 000002 locsiz .SET 2 ; locals stack frame size
3408 000008 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3409 000003 entsr .SET locsiz + 1 ; pointer to saved status reg.
3410 000009 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3411 ;
3412 000007 s2 .SET entsr + 4 ; <s1> parameter
3413 00000A s1 .SET s2 + 3 ; <s2> parameter
3414 ;
3415 000001 tmp .SET 1 ; local: temp. byte
3416 ;
3417 FA063E C2 03 rep #PZFLAG+PCFLAG ; clear CF & ZF
3418 FA0640 08 php ; save SR
3419 FA0641 F4 00 00 pea #0 ; local variable
3420 FA0644 3B tsc ; stack frame
3421 FA0645 0B phd ; save DP reg.
3422 FA0646 5B tcd ; dp access to stack var's
3423 FA0647 CPU08 ; A/M & X/Y 8 bit
3424 FA0647 E2 30 sep #(PMFLAG.OR.PXFLAG)
3425 .LONGA off
3426 .LONGI off
3427 .MNLIST
3428 FA0649 A0 00 ldy #0 ; pointer
3429 FA064B INDEX16 ; X/Y 16 bit
3430 FA064B C2 10 rep #PXFLAG
3431 .LONGI on
3432 .MNLIST
3433 ;
3434 FA064D B7 07 ?cmp: lda [s2],y ; get next char from <s2>
3435 FA064F C9 61 cmp #'a' ; translate lower case to upper case
3436 FA0651 90 06 bcc ?st
3437 FA0653 C9 7B cmp #'z'+1
3438 FA0655 B0 02 bcs ?st
3439 FA0657 29 DF and #$DF ; upper case
3440 FA0659 85 01 ?st: sta <tmp ; store character
3441 FA065B B7 0A lda [s1],y ; get next char from <s1>
3442 FA065D C9 61 cmp #'a' ; translate lower case to upper case
3443 FA065F 90 06 bcc ?cmp2
3444 FA0661 C9 7B cmp #'z'+1
3445 FA0663 B0 02 bcs ?cmp2
3446 FA0665 29 DF and #$DF ; upper case
Tue Jul 17 11:00:21 2018 Page 16
3447 FA0667 C5 01 ?cmp2: cmp <tmp ; compares characters
3448 FA0669 D0 08 bne ?end ; unmatch, set flags
3449 FA066B C9 00 cmp #0 ; end of string?
3450 FA066D F0 04 beq ?end ; yes, set flags
3451 FA066F C8 iny ; bump pointer
3452 FA0670 D0 DB bne ?cmp ; compare next char
3453 FA0672 38 sec ; all match: set carry
3454 ;
3455 FA0673 08 ?end: php ; CF & ZF affected according comparison
3456 FA0674 68 pla
3457 FA0675 29 03 and #PZFLAG+PCFLAG ; mask on CF & ZF
3458 FA0677 04 03 tsb <entsr ; set flags on saved status reg.
3459 FA0679 CPU16CLC ; A,X,Y 16 bit - clear carry
3460 FA0679 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3461 .LONGA on
3462 .LONGI on
3463 .MNLIST
3464 FA067B A5 05 lda <entsr+2 ; move saved SR and return address
3465 FA067D 85 0B sta <exitsr+2
3466 FA067F A5 03 lda <entsr
3467 FA0681 85 09 sta <exitsr
3468 FA0683 2B pld ; restore DP reg.
3469 FA0684 3B tsc ; stack frame
3470 FA0685 69 08 00 adc #skpsiz ; realign stack
3471 FA0688 1B tcs
3472 FA0689 28 plp ; restore SR
3473 FA068A 6B rtl
3474
3475 .LONGA off
3476 .LONGI off
3477
3478 ; _strncasecmp(s1, s2, n)
3479 ;
3480 ; lexicographically compare the null-terminated strings s1 and s2,
3481 ; ignoring strings case; this function compares not more than n characters
3482 ;
3483 ; stack param's:
3484 ;
3485 ; <s1>: long pointer to first string
3486 ; <s2>: long pointer to second string
3487 ; <n>: word: count of characters to compare
3488 ;
3489 ; return: status flags affected like in 'cmp' instruction
3490 ; CF=0 & ZF=0 if s1 less than s2
3491 ; CF=1 & ZF=1 if s1 equal to s2
3492 ; CF=1 & ZF=0 if s1 greater than s2
3493 ;
3494 ; note: X & Y not preserved
3495 ;
3496 ;-------------------------------
3497 FA068B _strncasecmp:
3498 .PUBLIC _strncasecmp
3499 ;-------------------------------
3500
3501 .LONGA off
3502 .LONGI off
3503 FA068B
Tue Jul 17 11:00:21 2018 Page 17
3504 000008 parsiz .SET 8 ; parameter stack frame size
3505 000002 locsiz .SET 2 ; locals stack frame size
3506 00000A skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3507 000003 entsr .SET locsiz + 1 ; pointer to saved status reg.
3508 00000B exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3509 ;
3510 000007 n .SET entsr + 4 ; <n> parameter
3511 000009 s2 .SET n + 2 ; <s1> parameter
3512 00000C s1 .SET s2 + 3 ; <s2> parameter
3513 ;
3514 000001 tmp .SET 1 ; local: temp. byte
3515 ;
3516 FA068B C2 03 rep #PZFLAG+PCFLAG ; clear CF & ZF
3517 FA068D 08 php ; save SR
3518 FA068E F4 00 00 pea #0 ; local variable
3519 FA0691 3B tsc ; stack frame
3520 FA0692 0B phd ; save DP reg.
3521 FA0693 5B tcd ; dp access to stack var's
3522 FA0694 CPU08SEC ; A/M & X/Y 8 bit & set carry
3523 FA0694 E2 31 sep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3524 .LONGA off
3525 .LONGI off
3526 .MNLIST
3527 FA0696 A0 00 ldy #0 ; pointer
3528 FA0698 INDEX16 ; X/Y 16 bit
3529 FA0698 C2 10 rep #PXFLAG
3530 .LONGI on
3531 .MNLIST
3532 FA069A A6 07 ldx <n ; if <n> = 0 set CF=1 & ZF=1
3533 FA069C F0 27 beq ?end
3534 ;
3535 FA069E B7 09 ?cmp: lda [s2],y ; get next char from <s2>
3536 FA06A0 C9 61 cmp #'a' ; translate lower case to upper case
3537 FA06A2 90 06 bcc ?st
3538 FA06A4 C9 7B cmp #'z'+1
3539 FA06A6 B0 02 bcs ?st
3540 FA06A8 29 DF and #$DF ; upper case
3541 FA06AA 85 01 ?st: sta <tmp ; store character
3542 FA06AC B7 0C lda [s1],y ; get next char from <s1>
3543 FA06AE C9 61 cmp #'a' ; translate lower case to upper case
3544 FA06B0 90 06 bcc ?cmp2
3545 FA06B2 C9 7B cmp #'z'+1
3546 FA06B4 B0 02 bcs ?cmp2
3547 FA06B6 29 DF and #$DF ; upper case
3548 FA06B8 C5 01 ?cmp2: cmp <tmp ; compares characters
3549 FA06BA D0 09 bne ?end ; unmatch, set flags
3550 FA06BC C9 00 cmp #0 ; end of string?
3551 FA06BE F0 05 beq ?end ; yes, set flags
3552 FA06C0 C8 iny ; bump pointer
3553 FA06C1 C4 07 cpy <n ; at most <n> characters...
3554 FA06C3 90 D9 bcc ?cmp ; compare next char
3555 ; all match: set carry & zero flag
3556 ;
3557 FA06C5 08 ?end: php ; CF & ZF affected according comparison
3558 FA06C6 68 pla
3559 FA06C7 29 03 and #PZFLAG+PCFLAG ; mask on CF & ZF
3560 FA06C9 04 03 tsb <entsr ; set flags on saved status reg.
Tue Jul 17 11:00:21 2018 Page 18
3561 FA06CB CPU16CLC ; A,X,Y 16 bit - clear carry
3562 FA06CB C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3563 .LONGA on
3564 .LONGI on
3565 .MNLIST
3566 FA06CD A5 05 lda <entsr+2 ; move saved SR and return address
3567 FA06CF 85 0D sta <exitsr+2
3568 FA06D1 A5 03 lda <entsr
3569 FA06D3 85 0B sta <exitsr
3570 FA06D5 2B pld ; restore DP reg.
3571 FA06D6 3B tsc ; stack frame
3572 FA06D7 69 0A 00 adc #skpsiz ; realign stack
3573 FA06DA 1B tcs
3574 FA06DB 28 plp ; restore SR
3575 FA06DC 6B rtl
3576
3577 .LONGA off
3578 .LONGI off
3579
3580 ;---------------------------------------------------------------------------
3581 ; find character & substring
3582 ;---------------------------------------------------------------------------
3583
3584 ; _strchr(s, c)
3585 ;
3586 ; locates the first occurrence of character <c> in string pointed to by <s>
3587 ;
3588 ; stack param's:
3589 ;
3590 ; <s>: long pointer to string
3591 ; <c>: character to find (byte)
3592 ;
3593 ; return: CF=0 & C = index of character in string, if found
3594 ; CF=1 & C = index of the nul terminator if not found
3595 ; (string length in fact)
3596 ;
3597 ; note: X & Y not preserved
3598 ;
3599 ;-------------------------------
3600 FA06DD _strchr:
3601 .PUBLIC _strchr
3602 ;-------------------------------
3603
3604 .LONGA off
3605 .LONGI off
3606 FA06DD
3607 000004 parsiz .SET 4 ; parameter stack frame size
3608 000000 locsiz .SET 0 ; locals stack frame size
3609 000004 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3610 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
3611 000005 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3612 ;
3613 000005 c .SET entsr + 4 ; <c> parameter
3614 000006 s .SET c + 1 ; <s> parameter
3615 ;
3616 FA06DD 38 sec ; assume not found
3617 FA06DE 08 php ; save SR
Tue Jul 17 11:00:21 2018 Page 19
3618 FA06DF 3B tsc ; stack frame
3619 FA06E0 0B phd ; save DP reg.
3620 FA06E1 5B tcd ; dp access to stack var's
3621 FA06E2 CPU08 ; A/M & X/Y 8 bit
3622 FA06E2 E2 30 sep #(PMFLAG.OR.PXFLAG)
3623 .LONGA off
3624 .LONGI off
3625 .MNLIST
3626 FA06E4 A0 00 ldy #0 ; pointer
3627 FA06E6 INDEX16 ; X/Y 16 bit
3628 FA06E6 C2 10 rep #PXFLAG
3629 .LONGI on
3630 .MNLIST
3631 ;
3632 FA06E8 B7 06 ?cmp: lda [s],y ; get next char from <s>
3633 FA06EA C5 05 cmp <c ; compare with character <c>
3634 FA06EC F0 0A beq ?end ; match, reset carry flag
3635 FA06EE C9 00 cmp #0 ; end of string?
3636 FA06F0 F0 0A beq ?done ; yes, return index of terminator
3637 FA06F2 C8 iny ; bump pointer
3638 FA06F3 D0 F3 bne ?cmp ; compare next char
3639 FA06F5 88 dey
3640 FA06F6 80 04 bra ?done
3641 ;
3642 FA06F8 A9 01 ?end: lda #PCFLAG ; clear CF
3643 FA06FA 14 01 trb <entsr
3644 ;
3645 FA06FC ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
3646 FA06FC C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3647 .LONGA on
3648 .LONGI on
3649 .MNLIST
3650 FA06FE A5 03 lda <entsr+2 ; move saved SR and return address
3651 FA0700 85 07 sta <exitsr+2
3652 FA0702 A5 01 lda <entsr
3653 FA0704 85 05 sta <exitsr
3654 FA0706 2B pld ; restore DP reg.
3655 FA0707 3B tsc ; stack frame
3656 FA0708 69 04 00 adc #skpsiz ; realign stack
3657 FA070B 1B tcs
3658 FA070C 98 tya ; C = index
3659 FA070D 28 plp ; restore SR
3660 FA070E 6B rtl
3661
3662 .LONGA off
3663 .LONGI off
3664
3665 ; _strrchr(s, c)
3666 ;
3667 ; locates the last occurrence of character <c> in string pointed to by <s>
3668 ;
3669 ; stack param's:
3670 ;
3671 ; <s>: long pointer to string
3672 ; <c>: character to find (byte)
3673 ;
3674 ; return: CF=0 & C = index of character in string, if found
Tue Jul 17 11:00:21 2018 Page 20
3675 ; CF=1 & C = index of the nul terminator if not found
3676 ; (string length in fact)
3677 ;
3678 ; note: X & Y not preserved
3679 ;
3680 ;-------------------------------
3681 FA070F _strrchr:
3682 .PUBLIC _strrchr
3683 ;-------------------------------
3684
3685 .LONGA off
3686 .LONGI off
3687 FA070F
3688 000004 parsiz .SET 4 ; parameter stack frame size
3689 000000 locsiz .SET 0 ; locals stack frame size
3690 000004 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3691 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
3692 000005 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3693 ;
3694 000005 c .SET entsr + 4 ; <c> parameter
3695 000006 s .SET c + 1 ; <s> parameter
3696 ;
3697 FA070F 38 sec ; assume not found
3698 FA0710 08 php ; save SR
3699 FA0711 3B tsc ; stack frame
3700 FA0712 0B phd ; save DP reg.
3701 FA0713 5B tcd ; dp access to stack var's
3702 FA0714 CPU08 ; A/M & X/Y 8 bit
3703 FA0714 E2 30 sep #(PMFLAG.OR.PXFLAG)
3704 .LONGA off
3705 .LONGI off
3706 .MNLIST
3707 FA0716 A0 00 ldy #0 ; pointer
3708 FA0718 INDEX16 ; X/Y 16 bit
3709 FA0718 C2 10 rep #PXFLAG
3710 .LONGI on
3711 .MNLIST
3712 ;
3713 FA071A B7 06 ?len: lda [s],y ; find end of string
3714 FA071C F0 07 beq ?ok ; done when get a nul
3715 FA071E C8 iny ; bump pointer
3716 FA071F D0 F9 bne ?len
3717 FA0721 98 tya
3718 FA0722 88 dey ; max length = $FFFF
3719 FA0723 97 06 sta [s],y ; force string terminator
3720 ;
3721 FA0725 BB ?ok: tyx ; save pointer to the end of string
3722 FA0726 A5 05 lda <c
3723 FA0728 D7 06 ?cmp: cmp [s],y ; compare
3724 FA072A F0 07 beq ?end ; match, reset carry flag
3725 FA072C 88 dey ; update pointer
3726 FA072D D0 F9 bne ?cmp ; compare previous char
3727 FA072F C7 06 cmp [s] ; compare character at index 0
3728 FA0731 D0 05 bne ?done ; unmatch
3729 ;
3730 FA0733 A9 01 ?end: lda #PCFLAG ; clear CF
3731 FA0735 14 01 trb <entsr
Tue Jul 17 11:00:21 2018 Page 21
3732 FA0737 BB tyx ; index where found character
3733 ;
3734 FA0738 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
3735 FA0738 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3736 .LONGA on
3737 .LONGI on
3738 .MNLIST
3739 FA073A A5 03 lda <entsr+2 ; move saved SR and return address
3740 FA073C 85 07 sta <exitsr+2
3741 FA073E A5 01 lda <entsr
3742 FA0740 85 05 sta <exitsr
3743 FA0742 2B pld ; restore DP reg.
3744 FA0743 3B tsc ; stack frame
3745 FA0744 69 04 00 adc #skpsiz ; realign stack
3746 FA0747 1B tcs
3747 FA0748 8A txa ; C = index
3748 FA0749 28 plp ; restore SR
3749 FA074A 6B rtl
3750
3751 .LONGA off
3752 .LONGI off
3753
3754 ; _strlchr(s, c, i)
3755 ;
3756 ; locates the first occurrence of character <c> in string pointed to by <s>,
3757 ; starting from the character at index <i>
3758 ;
3759 ; stack param's:
3760 ;
3761 ; <s>: long pointer to string
3762 ; <c>: character to find (byte)
3763 ; <i>: index where start searching (word)
3764 ;
3765 ; return: CF=0 & C = index of character in string, if found
3766 ; CF=1 & C = index of the nul terminator if not found
3767 ; (string length in fact)
3768 ;
3769 ; note: X & Y not preserved
3770 ;
3771 ;-------------------------------
3772 FA074B _strlchr:
3773 .PUBLIC _strlchr
3774 ;-------------------------------
3775
3776 .LONGA off
3777 .LONGI off
3778 FA074B
3779 000006 parsiz .SET 6 ; parameter stack frame size
3780 000000 locsiz .SET 0 ; locals stack frame size
3781 000006 skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3782 000001 entsr .SET locsiz + 1 ; pointer to saved status reg.
3783 000007 exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3784 ;
3785 000005 i .SET entsr + 4 ; <i> parameter
3786 000007 c .SET i + 2 ; <c> parameter
3787 000008 s .SET c + 1 ; <s> parameter
3788 ;
Tue Jul 17 11:00:21 2018 Page 22
3789 FA074B 38 sec ; assume not found
3790 FA074C 08 php ; save SR
3791 FA074D 3B tsc ; stack frame
3792 FA074E 0B phd ; save DP reg.
3793 FA074F 5B tcd ; dp access to stack var's
3794 FA0750 CPU08 ; A/M & X/Y 8 bit
3795 FA0750 E2 30 sep #(PMFLAG.OR.PXFLAG)
3796 .LONGA off
3797 .LONGI off
3798 .MNLIST
3799 FA0752 A0 00 ldy #0 ; pointer
3800 FA0754 INDEX16 ; X/Y 16 bit
3801 FA0754 C2 10 rep #PXFLAG
3802 .LONGI on
3803 .MNLIST
3804 ;
3805 FA0756 B7 08 ?cmp: lda [s],y ; get next char from <s>
3806 FA0758 C5 07 cmp <c ; compare with character <c>
3807 FA075A F0 0A beq ?fnd ; match, test index
3808 FA075C C9 00 ?tst: cmp #0 ; end of string?
3809 FA075E F0 0E beq ?done ; yes, return index of terminator
3810 FA0760 C8 iny ; bump pointer
3811 FA0761 D0 F3 bne ?cmp ; compare next char
3812 FA0763 88 dey
3813 FA0764 80 08 bra ?done
3814 ;
3815 FA0766 C4 05 ?fnd: cpy <i ; at right starting index?
3816 FA0768 90 F2 bcc ?tst ; no, search again
3817 FA076A A9 01 lda #PCFLAG ; clear CF
3818 FA076C 14 01 trb <entsr
3819 ;
3820 FA076E ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
3821 FA076E C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3822 .LONGA on
3823 .LONGI on
3824 .MNLIST
3825 FA0770 A5 03 lda <entsr+2 ; move saved SR and return address
3826 FA0772 85 09 sta <exitsr+2
3827 FA0774 A5 01 lda <entsr
3828 FA0776 85 07 sta <exitsr
3829 FA0778 2B pld ; restore DP reg.
3830 FA0779 3B tsc ; stack frame
3831 FA077A 69 06 00 adc #skpsiz ; realign stack
3832 FA077D 1B tcs
3833 FA077E 98 tya ; C = index
3834 FA077F 28 plp ; restore SR
3835 FA0780 6B rtl
3836
3837 .LONGA off
3838 .LONGI off
3839
3840 ; _strstr(s, find)
3841 ; locates the first occurrence of string <find> in string <s>
3842 ;
3843 ; stack param's:
3844 ;
3845 ; <s>: long pointer to string <s>
Tue Jul 17 11:00:21 2018 Page 23
3846 ; <find>: long pointer to string <find>
3847 ;
3848 ; return: CF=0 & C=index of first character of first occurrence
3849 ; CF=1 & C=length of <s> if <find> occur nowhere in <s>
3850 ; if <find> is empty return CF=0 & C=0
3851 ;
3852 ; note: X & Y not preserved
3853 ;
3854 ;-------------------------------
3855 FA0781 _strstr:
3856 .PUBLIC _strstr
3857 ;-------------------------------
3858
3859 .LONGA off
3860 .LONGI off
3861 FA0781
3862 000006 parsiz .SET 6 ; parameter stack frame size
3863 000004 locsiz .SET 4 ; locals stack frame size
3864 00000A skpsiz .SET parsiz + locsiz ; bytes to skip to realign stack
3865 000005 entsr .SET locsiz + 1 ; pointer to saved status reg.
3866 00000B exitsr .SET skpsiz + 1 ; pointer to moved status reg.
3867 ;
3868 000009 find .SET entsr + 4 ; <find> parameter
3869 00000C s .SET find + 3 ; <s> parameter
3870 ;
3871 000001 len .SET 1 ; local: string <find> length
3872 000003 c .SET 3 ; local: firs character of <find>
3873 ;
3874 FA0781 38 sec ; assume not found
3875 FA0782 08 php ; save SR
3876 FA0783 CPU08 ; A/M & X/Y 8 bit
3877 FA0783 E2 30 sep #(PMFLAG.OR.PXFLAG)
3878 .LONGA off
3879 .LONGI off
3880 .MNLIST
3881 FA0785 A2 00 ldx #0 ; index
3882 FA0787 INDEX16 ; X/Y 16
3883 FA0787 C2 10 rep #PXFLAG
3884 .LONGI on
3885 .MNLIST
3886 FA0789 DA phx ; local: <c>
3887 FA078A DA phx ; local: <len>
3888 FA078B 3B tsc ; stack frame
3889 FA078C 0B phd ; save DP reg.
3890 FA078D 5B tcd ; dp access to stack var's
3891 FA078E A7 09 lda [find] ; if string <find> is empty...
3892 FA0790 F0 42 beq ?end2 ; ...exit with index = 0 & CF = 0
3893 FA0792 85 03 sta <c ; <c> = first character of <find>
3894 FA0794 A4 09 ldy <find ; bump pointer to <find>
3895 FA0796 C8 iny
3896 FA0797 84 09 sty <find ; <find1> = pointer to 2nd character of <find>
3897 FA0799 D0 02 bne ?go
3898 FA079B E6 0B inc <find+2
3899 ;
3900 FA079D 9B ?go txy ; Y = 0
3901 ;
3902 FA079E B7 09 ?len: lda [find],y ; compute string <find1> length
Tue Jul 17 11:00:21 2018 Page 24
3903 FA07A0 F0 07 beq ?do ; done when get a nul
3904 FA07A2 C8 iny ; bump pointer
3905 FA07A3 D0 F9 bne ?len
3906 FA07A5 98 tya
3907 FA07A6 88 dey ; max length = $FFFF
3908 FA07A7 97 09 sta [find],y ; force string terminator
3909 ;
3910 FA07A9 84 01 ?do: sty <len ; <len> = <find1> length
3911 ;
3912 FA07AB A4 0C ?do1: ldy <s ; scan string <s>
3913 ;
3914 FA07AD A7 0C ?do2: lda [s] ; next char of string <s>
3915 FA07AF F0 27 beq ?done ; end of string <s>: exit with CF=1
3916 FA07B1 E8 inx ; update <s> scan index
3917 FA07B2 C8 iny
3918 FA07B3 84 0C sty <s ; bump <s> pointer
3919 FA07B5 D0 02 bne ?do3
3920 FA07B7 E6 0E inc <s+2
3921 ;
3922 FA07B9 C5 03 ?do3: cmp <c ; match first character of <find>?
3923 FA07BB D0 F0 bne ?do2 ; no, so check next character of <s>
3924 FA07BD A4 01 ldy <len ; now compute _strncmp(s, find1, len)
3925 FA07BF F0 12 beq ?end ; if <len> = 0 match first character
3926 FA07C1 A0 00 00 ldy #0
3927 ;
3928 FA07C4 B7 0C ?cmp: lda [s],y ; get next char from <s>
3929 FA07C6 D7 09 cmp [find],y ; compare with byte in <find1>
3930 FA07C8 D0 E1 bne ?do1 ; unmatch, try next char of <s>
3931 FA07CA C9 00 cmp #0 ; end of string?
3932 FA07CC F0 05 beq ?end ; yes, reset carry flag
3933 FA07CE C8 iny ; bump pointer
3934 FA07CF C4 01 cpy <len ; at most <len> characters...
3935 FA07D1 90 F1 bcc ?cmp ; compare next char
3936 ;
3937 FA07D3 CA ?end: dex ; all match: update index & reset carry flag
3938 ;
3939 FA07D4 ?end2:
3940 FA07D4 A9 01 lda #PCFLAG ; reset CF...
3941 FA07D6 14 05 trb <entsr ; ...on saved status reg.
3942 ;
3943 FA07D8 ?done: CPU16CLC ; A,X,Y 16 bit - clear carry
3944 FA07D8 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3945 .LONGA on
3946 .LONGI on
3947 .MNLIST
3948 FA07DA A5 07 lda <entsr+2 ; move saved SR and return address
3949 FA07DC 85 0D sta <exitsr+2
3950 FA07DE A5 05 lda <entsr
3951 FA07E0 85 0B sta <exitsr
3952 FA07E2 2B pld ; restore DP reg.
3953 FA07E3 3B tsc ; stack frame
3954 FA07E4 69 0A 00 adc #skpsiz ; realign stack
3955 FA07E7 1B tcs
3956 FA07E8 8A txa ; C = index
3957 FA07E9 28 plp ; restore SR
3958 FA07EA 6B rtl
3959
Tue Jul 17 11:00:21 2018 Page 25
3960 .LONGA off
3961 .LONGI off
Lines Assembled : 3788 Errors : 0