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\printf.asm
Output Filename : obj\FA\printf.obj
Listing Has Been Relocated
2582 .LIST on
2583
2584 F8FFB1 .INCLUDE inc\dpfpu.inc
2585 ;;
2586 ;; Copyright (c) 2016 Marco Granati <mg@unet.bz>
2587 ;;
2588 ;; Permission to use, copy, modify, and distribute this software for any
2589 ;; purpose with or without fee is hereby granted, provided that the above
2590 ;; copyright notice and this permission notice appear in all copies.
2591 ;;
2592 ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2593 ;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2594 ;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2595 ;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2596 ;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2597 ;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2598 ;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2599 ;;
2600
2601 ;; name: dpfpu.inc
2602 ;; rev.: 2016/03/30
2603 ;; o.s. 65C816 version v1.0
2604
2605 .LIST on
2606
2607 ; direct page for flotaing point unit
2608 _DPFPU: .SECTION page0, common, ref_only, offset 0 ;FPU D.P.
2609
2610 000080 MNTBITS .EQU (16*8) ; significand bits + guard bits
2611 000010 MANTSIZ .EQU 16 ; significand size
2612 000014 FREGSIZ .EQU 20 ; floating point register size
2613
2614 000000 tm .DS 16 ; temp. mantissa
2615
2616 000010 00 fsubnf .DB ; subnormal flag used by fac2dec
2617 000010 atncode .EQU fsubnf ; fatanyx octant
2618
2619 000011 00 sgncmp .DB ; sign comparison: fac vs. arg
2620
2621 ; floating Point accumulator (fac)
2622 000012 facm .DS 16 ; guard bits (32 bits)+significand (80 bits)
2623 000022 0000 facexp .DW ; fac biased exponent
2624 000024 00 facsgn .DB ; fac mantissa sign
2625 000025 00 facst .DB ; fac status for floating point
2626 ; <7>: 1 if fac is invalid (nan or inf)
2627 ; <6>: 1 if fac=inf (with <7>=1)
Tue Jul 17 11:00:21 2018 Page 2
2628 ; 0 if fac=nan (with <7>=1)
2629 ; <6>: 1 if fac=0 (with <7>=0)
2630 ; <5>: always '0'
2631
2632 ; fac status for long integer
2633 ; <7>: 1 if facm will be regarded as 'signed'
2634 ; <6>: 1 if facm = 0
2635 ; <5>: always '1'
2636
2637 000026 0000 fexph .DW ; unbiased fac exponent sign extension
2638 000028 0000 facext .DW ; fac guard bits extension
2639 000028 wftmp2 .EQU facext
2640 000024 facsiz .EQU facsgn ; integer only: size in bytes
2641
2642 ; floating point operand (arg)
2643 00002A argm .DS 16 ; guard bits (32 bits)+significand (80 bits)
2644 00003A 0000 argexp .DW ; arg biased exponent
2645 00003C 00 argsgn .DB ; arg mantissa sign
2646 00003D 00 argst .DB ; arg status for floating point
2647 ; <7>: 1 if arg is invalid (nan or inf)
2648 ; <6>: 1 if arg=inf (with <7>=1)
2649 ; 0 if arg=nan (with <7>=1)
2650 ; <6>: 1 if arg=0 (with <7>=0)
2651
2652 ; arg status for long integer
2653 ; <7>: 1 if facm will be regarded as 'signed'
2654 ; <6>: 1 if facm = 0
2655 ; <5>: always '1'
2656 00003E
2657 00003E 0000 aexph .DW ; unbiased arg exponent sign extension
2658 000040 0000 argext .DW
2659
2660 00003E wftmp .EQU aexph ; temp. word (int2dec, fpadd, fpsub)
2661 00003C argsiz .EQU argsgn ; integer only: size in bytes
2662
2663 000042 fcp LP ; long pointer to flaot constants
2664 000045 00 scsgn .DB ; scaling sign
2665 000046 0000 scexp .DW ; scaling value
2666 000048 0000 dexp .DW ; decimal exponent
2667 00004A 00 dsgn .DB ; decimal float sign
2668 00004B 00 pdeg .DB ; polyn. degree
2669 00004B powfg .EQU pdeg ; flag used by fpowxy
2670
2671 00004C tlp LP ; string long pointer
2672 00004F 00 fpidx .DB ; string index
2673 000050
2674 000050 tfr0 .DS 20 ; temp. float reg. 0
2675 000064 tfr1 .DS 20 ; temp. float reg. 1
2676 000078 tfr2 .DS 20 ; temp. float reg. 2
2677 00008C tfr3 .DS 20 ; temp. float reg. 3
2678 0000A0 tfr4 .DS 20 ; temp. float reg. 4
2679 0000B4 tfr5 .DS 20 ; temp. float reg. 5
2680 0000C8 .DS 4 ; used by xcvt: doesn't change
2681
2682 0000CB XCVTEND .EQU ($ - 1) ; last byte of xcvt buffer
2683
2684 ; buffer used by decimal conversion (overlap tfr0&tfr1: 40 bytes)
Tue Jul 17 11:00:21 2018 Page 3
2685 000050 fpstr .EQU tfr0 ; 40 bytes buffer
2686 ; buffer used to format a decimal string
2687 000078 xcvt .EQU tfr2 ; 84 bytes buffer
2688
2689 0000B4 fcpc0 .EQU tfr5 ; constants pointer for exp. function
2690 0000B6 fcpc1 .EQU tfr5+2
2691 0000B8 fcpc2 .EQU tfr5+4
2692 0000BA fcpp .EQU tfr5+6
2693 0000BC fcpq .EQU tfr5+8
2694 0000BE fcpd .EQU tfr5+10
2695 0000BF fcqd .EQU tfr5+11
2696 0000C0 fcpolf .EQU tfr5+12 ; polynomial flag
2697
2698 0000B4 tmdot .EQU tfr5 ; digit count after decimal dot
2699 0000B6 tmpa .EQU tfr5+2 ; temp: save A&Y
2700 0000B7 tmpy .EQU tfr5+3
2701 0000B8 tmsgn .EQU tfr5+4 ; temp.: significand sign
2702 0000B9 tmcnt .EQU tfr5+5 ; temp.: significand digits count
2703 0000BA tesgn .EQU tfr5+6 ; temp.: exponent sign
2704 0000BB tecnt .EQU tfr5+7 ; temp.: exponent digits count
2705
2706 0000BC mcand1 .EQU tfr5+8 ; multiplicand's
2707 0000BE mcand2 .EQU tfr5+10
2708 0000C0 mcsgn .EQU tfr5+12
2709 0000C2 dvsor .EQU tfr5+14
2710 0000C4 quot .EQU tfr5+16
2711
2712 0000CC 0000 fpprec .DW ; precision
2713 0000CE 00 fpfmt .DB ; format
2714 0000CF 00 fpaltf .DB ; alternate format
2715 0000D0 00 fpcap .DB ; adding for lower case
2716 0000D1 00 fpstyle .DB ; flag 'F' style
2717 00004B fpdot .EQU pdeg ; decimal dot flag
2718 0000CE fpoct .EQU fpfmt ; octant (circular func's)
2719 0000CF fpcsgn .EQU fpaltf ; circular func's: argument sign
2720 0000D0 fpcot .EQU fpcap ; cotangent flag
2721 0000D0 fpasin .EQU fpcap ; asin flag
2722
2723 0000D2 00 dummy .DB
2724
2725 .ENDS
2734 .LIST on
2735
2736 ; save 10 bytes in stack plus 3 bytes for return address
2737 00000D PUSHED .EQU 13 ; return address + pushed register's
2738 00000F PUSHED1 .EQU 15 ; count is in top of return address
2739 000040 NLOCALS .EQU 64
2740 00004E COUNTOFS .EQU (PUSHED + NLOCALS + 1)
2741
2742 000000 FMTPARAM .EQU 0
2743
2744 ; locals in stack accessed by DPR
2745 _PRINTFDP: .SECTION page0, common, ref_only, offset 0
2746
2747 000000 0000 mvfrom .DW
2748 000002 0000 mvto .DW
2749 000004 0000 pparams .DW
Tue Jul 17 11:00:21 2018 Page 4
2750 000006 0000 fmtidx .DW ; current index to format string
2751 000008 lpfmt LP ; long pointer to format string
2752 00000B lpdest LP ; long pointer to dest. string
2753 00000E 0000 dsize .DW ; dest. string size
2754 000010 00 putopts .DB ; putter options
2755 ; <7>: 0 => file/stream - 1 => string
2756 ; <6>: if <7> = 0 => 0 => file - 1 => stream
2757 ; <6>: if <7> = 1 => 0 => alloc string - 1 => use dest
2758 000011 00 putopts2 .DB ; <7>: 0 => no store - 1 +> store
2759 000012 0000 fpusave .DW ; pointer to fpu saved direct-page
2760 000014 00 fmtflag .DB ; format flags (see F_XXX constants)
2761 000015 00 fmtmod .DB ; modifier's bit's (see F2_XXX constants)
2762 000016 00 fmtwidth .DB ; [width] field value
2763 000017 00 fmtprec .DB ; [precision] field value
2764 000018 00 fmtsgn .DB ; formattation sign
2765 000019 00 fbtmp .DB ; temp. byte
2766 00001A 00 tfloat .DB ; float conversion type (see FF_XXX constants)
2767 00001B 00 fpuuse .DB ; signal that current conversion use fpu emulator
2768
2769 00001C LOCALSIZE .DS 0
2770
2771 .ENDS
2772
2773 ; locals
2774 ;mvfrom .EQU 0
2775 ;mvto .EQU 2
2776 ;pformat .EQU 4
2777
2778 ;---------------------------------------------------------------------------
2779 ; equates
2780 ;---------------------------------------------------------------------------
2781
2782 ; spec's class
2783 000000 _dc .EQU 0 ; don't care
2784 000001 _si .EQU 1 ; sign fill +/-
2785 000002 _af .EQU 2 ; alternate form
2786 000003 _ar .EQU 3 ; format (width or precision) by argument
2787 000004 _lj .EQU 4 ; left justify
2788 000005 _pr .EQU 5 ; precision
2789 000006 _nu .EQU 6 ; numeral
2790 000007 _lo .EQU 7 ; long integer (64 bit)
2791 000008 _sh .EQU 8 ; short integer (16 bit)
2792 000009 _SH .EQU 9 ; byte (8 byte)
2793 00000A _fz .EQU 10 ; fill zeros
2794 00000B _de .EQU 11 ; signed decimal
2795 00000C _un .EQU 12 ; unsigned decimal
2796 00000D _he .EQU 13 ; hexadecimal (lower case digits)
2797 00000E _pt .EQU 14 ; long pointer (lower case digits)
2798 00000F _HE .EQU 15 ; hexadecimal (upper case digits)
2799 000010 _PT .EQU 16 ; long pointer (upper case digits)
2800 000011 _ch .EQU 17 ; char
2801 000012 _st .EQU 18 ; string (ASCIIZ)
2802 000013 _ff .EQU 19 ; float %f
2803 000014 _fe .EQU 20 ; float %e
2804 000015 _fg .EQU 21 ; float %g
2805 000016 _FE .EQU 22 ; float %E
2806 000017 _FG .EQU 23 ; float %G
Tue Jul 17 11:00:21 2018 Page 5
2807 000018 _tg .EQU 24 ; thousand group
2808 000019 _ll .EQU 25 ; long long integer (128 bits)
2809 00001A _PS .EQU 26 ; pascal/basic string
2810 00001B _xf .EQU 27 ; hex float (lower case digits)
2811 00001C _XF .EQU 28 ; hex float (upper case digits)
2812 00001D _kf .EQU 29 ; compact hex float
2813 00001E _KF .EQU 30 ; compact hex float (upper case digits)
2814 00001F _FF .EQU 31 ; float %F
2815
2816 ; fmtflag bits
2817 000080 F_ALTFMT .EQU $80 ; alternate format
2818 000040 F_LEFTJ .EQU $40 ; left justify (default: right)
2819 000020 F_FILLZ .EQU $20 ; fill with '0' digit
2820 000010 F_GROUP .EQU $10 ; thousand group
2821 000008 F_WIDTH .EQU $08 ; 'width' field is valid
2822 000004 F_PREC .EQU $04 ; 'precision' field is valid
2823
2824 ; fmtmod modifier's bits
2825 000080 F2_PSSTRING .EQU $80 ; pascal/basic string (default: ASCIIZ)
2826 000040 F2_LONGLONG .EQU $40 ; integer long long modifier
2827 000020 F2_LONG .EQU $20 ; integer long modifier
2828 000010 F2_SHORT .EQU $10 ; integer short modifier
2829 000008 F2_BYTE .EQU $08 ; integer byte modifier
2830 000004 F2_CAPS .EQU $04 ; upper case hexadecimal digits
2831 000001 F2_SIGNED .EQU $01 ; signed integer
2832
2833 ; tfloat values: float format type
2834 000045 FF_EXP .EQU 'E' ; e/E format
2835 000046 FF_STD .EQU 'F' ; f/F format
2836 000040 FF_G .EQU $40 ; g/G format
2837 000004 FF_HEX .EQU $04 ; a/A format
2838
2839 ; valid integer modifier's mask
2840 000078 MASKMOD .EQU (F2_LONG.OR.F2_SHORT.OR.F2_BYTE.OR.F2_LONGLONG)
2841
2842 ; invalid modifier mask for '%c' format
2843 0000F8 MASKCHAR .EQU (MASKMOD.OR.F2_PSSTRING)
2844
2845 ; invalid modifier mask for '%s' format
2846 000078 MASKSTR .EQU (MASKMOD)
2847
2848 ; invalid modifier mask for '%p' format
2849 0000F8 MASKPTR .EQU (MASKCHAR)
2850
2851 ; invalid modifier mask for float format
2852 0000F8 MASKFLOAT .EQU (MASKMOD.OR.F2_PSSTRING)
2853
2854 ; invalid modifier mask for integer
2855 000080 MASKINTG .EQU (F2_PSSTRING)
2856
2857 ; conversion function index
2858 000000 T_CHAR .EQU 0 ; character
2859 000002 T_STR .EQU (1 * 2) ; string
2860 000004 T_PTR .EQU (2 * 2) ; long pointer
2861 000006 T_INT .EQU (3 * 2) ; integer
2862 000008 T_HEX .EQU (4 * 2) ; hexadecimal
2863 00000A T_FLOAT .EQU (5 * 2) ; float
Tue Jul 17 11:00:21 2018 Page 6
2864
2865 ; current stage while scan format
2866 000000 FLAGSTAGE .EQU 0 ; [flag] stage
2867 000001 FILLZSTAGE .EQU 1 ; fill with '0' stage
2868 000002 WIDESTAGE .EQU 2 ; [width] stage
2869 000003 DOTSTAGE .EQU 3 ; ['.'] stage
2870 000004 PRECSTAGE .EQU 4 ; [precision] stage
2871 000005 MODSTAGE .EQU 5 ; [modifier] stage
2872
2873 ; snprintf(str, size, format, ..., count)
2874 ; str: dest string
2875 ; size: size of dest
2876 ; format: format string
2877 ; count: bytes count of variables param's
2878 ;
2879 ; P = 10 => bytes's count of know param's (str->3, size->2, format->3, count->2)
2880 ; M = byte's count of variables param's (stored in count)
2881
2882 000008 KNOWPAR .SET 8
2883
2884 ; prologue
2885 prologue .MACRO npars
2886
2887 .MLIST
2888 .LONGA off
2889 .LONGI off
2890
2891 php ; save status
2892 phb ; save DBR
2893 phd ; save DPR
2894
2895 ; CPU 16 + CLC
2896 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2897 .LONGA on
2898 .LONGI on
2899
2900 pha ; save A
2901 phx ; save X
2902 phy ; save Y
2903 tsx
2904 txa ; A = old frame stack
2905 ;sbc #NLOCALS-1
2906 sbc #LOCALSIZE-1
2907 tcs ; new stack pointer
2908 inc a
2909 tcd ; DPR point to locals base
2910 txa
2911 clc
2912 adc #PUSHED
2913 sta mvfrom ; pointer to source frame stack to move
2914 inc a
2915 inc a ; pointer to top of count param (countH)
2916 adc COUNTOFS,s ; add size of variables param's
2917 tax
2918 inx ; pointer to format param
2919 stx pparams ; pointer to top + 1 of variables param's
2920 adc #npars
Tue Jul 17 11:00:21 2018 Page 7
2921 sta mvto ; pointer to dest. frame stack to move
2922
2923 ; ACC 08
2924 sep #PMFLAG
2925 .LONGA off
2926
2927 lda #0
2928 pha
2929 phb ; DBR => bank 0
2930 ldy .ABS.FMTPARAM,x
2931 sty lpfmt
2932 lda .ABS.FMTPARAM+2,x
2933 sta lpfmt+2
2934
2935 .MNLIST
2936 .ENDM
2937
2938
2939 .CODEFA
2940
2941 ; cprintf(format, ..., count)
2942 FA07EB _cprintf:
2943
2944 ; prologue code (leave index 16 bit)
2945 FA07EB prologue 3
2946 .LONGA off
2947 .LONGI off
2948
2949 FA07EB 08 php ; save status
2950 FA07EC 8B phb ; save DBR
2951 FA07ED 0B phd ; save DPR
2952
2953 ; CPU 16 + CLC
2954 FA07EE C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2955 .LONGA on
2956 .LONGI on
2957
2958 FA07F0 48 pha ; save A
2959 FA07F1 DA phx ; save X
2960 FA07F2 5A phy ; save Y
2961 FA07F3 BA tsx
2962 FA07F4 8A txa ; A = old frame stack
2963 ;sbc #NLOCALS-1
2964 FA07F5 E9 1B 00 sbc #LOCALSIZE-1
2965 FA07F8 1B tcs ; new stack pointer
2966 FA07F9 1A inc a
2967 FA07FA 5B tcd ; DPR point to locals base
2968 FA07FB 8A txa
2969 FA07FC 18 clc
2970 FA07FD 69 0D 00 adc #PUSHED
2971 FA0800 85 00 sta mvfrom ; pointer to source frame stack to move
2972 FA0802 1A inc a
2973 FA0803 1A inc a ; pointer to top of count param (countH)
2974 FA0804 63 4E adc COUNTOFS,s ; add size of variables param's
2975 FA0806 AA tax
2976 FA0807 E8 inx ; pointer to format param
2977 FA0808 86 04 stx pparams ; pointer to top + 1 of variables param's
Tue Jul 17 11:00:21 2018 Page 8
2978 FA080A 69 03 00 adc #3
2979 FA080D 85 02 sta mvto ; pointer to dest. frame stack to move
2980 FA080F
2981 ; ACC 08
2982 FA080F E2 20 sep #PMFLAG
2983 .LONGA off
2984
2985 FA0811 A9 00 lda #0
2986 FA0813 48 pha
2987 FA0814 8B phb ; DBR => bank 0
2988 FA0815 BC 00 00 ldy .ABS.FMTPARAM,x
2989 FA0818 84 08 sty lpfmt
2990 FA081A BD 02 00 lda .ABS.FMTPARAM+2,x
2991 FA081D 85 0A sta lpfmt+2
2992
2993 .MNLIST
2994 .LONGI on
2995 FA081F
2996 FA081F CPU08
2997 FA081F E2 30 sep #(PMFLAG.OR.PXFLAG)
2998 .LONGA off
2999 .LONGI off
3000 .MNLIST
3001 FA0821
3002 ; epilogue
3003 FA0821 epilogue:
3004 FA0821 CPU16CLC
3005 FA0821 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3006 .LONGA on
3007 .LONGI on
3008 .MNLIST
3009 FA0823 A6 00 ldx mvfrom ; source pointer for data move
3010 FA0825 A4 02 ldy mvto ; dest pointer for data move
3011 FA0827 A9 0C 00 lda #PUSHED-1 ; move bytes count - 1
3012 FA082A 44 00 00 mvp #0, #0 ; cleanup stack
3013 FA082D 98 tya ; new stack pointer
3014 FA082E 1B tcs
3015 FA082F 7A ply ; restore registers
3016 FA0830 FA plx
3017 FA0831 68 pla
3018 FA0832 2B pld
3019 FA0833 AB plb
3020 FA0834 28 plp
3021 FA0835 6B rtl
3022
3023 ; common formattation routine
3024 FA0836 _vprinter:
3025 .LONGA off
3026 .LONGI off
3027
3028 FA0836 A0 00 ldy #0
3029 FA0838 INDEX16
3030 FA0838 C2 10 rep #PXFLAG
3031 .LONGI on
3032 .MNLIST
3033
3034 ; parse format string
Tue Jul 17 11:00:21 2018 Page 9
3035 FA083A B7 08 ?nxt: lda [lpfmt],y ; get next char from format string
3036 FA083C D0 03 bne $+5
3037 ;beq ?done ; end of format string (?60)
3038 FA083E 4C C3 08 jmp ?done ; end of format string (?60)
3039 FA0841 C9 25 cmp #'%'
3040 FA0843 F0 06 beq ?nxt1 ; found specifier
3041 FA0845 20 D6 08 ?put: jsr _store ; put character "as is"
3042 FA0848 C8 iny ; bump pointer
3043 FA0849 80 EF bra ?nxt ; continue parsing
3044 FA084B 84 06 ?nxt1: sty fmtidx ; save index to '%' char
3045 FA084D C8 iny
3046 FA084E B7 08 lda [lpfmt],y ; get next char after specifier
3047 FA0850 C9 25 cmp #'%'
3048 FA0852 F0 F1 beq ?put ; put literal '%' and continue
3049 FA0854
3050 ; check format after specifier '%'
3051 FA0854 A9 00 lda #0 ; A = stage = 0 (current stage)
3052 FA0856 85 18 sta fmtsgn ; clear working var's
3053 FA0858 85 14 sta fmtflag
3054 FA085A 85 15 sta fmtmod
3055 FA085C 85 16 sta fmtwidth
3056 FA085E 85 17 sta fmtprec
3057 FA0860 80 01 bra ?lpf1 ; reload current char
3058 FA0862
3059 FA0862 C8 ?lpf: iny ; loop format parsing
3060 FA0863 EB ?lpf1: xba ; B = stage
3061 FA0864 B7 08 lda [lpfmt],y ; A = next char after specifier '%'
3062 FA0866 F0 4F beq ?err ; end of format string: abandon (?50)
3063 FA0868 85 19 sta fbtmp ; save char
3064 FA086A 38 sec
3065 FA086B E9 20 sbc #' ' ; scale char to 0..5F
3066 FA086D 90 48 bcc ?err ; illegal char at this stage
3067 FA086F C9 60 cmp #(128 - ' ')
3068 FA0871 B0 44 bcs ?err ; illegal char at this stage
3069 FA0873 84 06 sty fmtidx ; save current index
3070 FA0875 CPU08 ; all registers 8 bit
3071 FA0875 E2 30 sep #(PMFLAG.OR.PXFLAG)
3072 .LONGA off
3073 .LONGI off
3074 .MNLIST
3075 FA0877 AA tax ; X = 0..5F
3076 FA0878 BF 92 0A FA lda >CLASSCHR,x ; A = class char lookup
3077 FA087C 0A asl a
3078 FA087D AA tax ; function index
3079 FA087E A5 19 lda fbtmp ; A = current char
3080 FA0880 EB xba ; B = current char, A = current stage
3081 ; ZF = 1 if current stage = 0
3082 FA0881 FC F2 0A jsr (CHKTBL,x) ; check format specifier at this stage
3083 FA0884 INDEX16 ; X/Y => 16 bits
3084 FA0884 C2 10 rep #PXFLAG
3085 .LONGI on
3086 .MNLIST
3087 FA0886 A4 06 ldy fmtidx ; Y = index to format string
3088 FA0888 B0 2D bcs ?err ; format error - abandon
3089 FA088A 50 D6 bvc ?lpf ; continue format parsing
3090 FA088C
3091 ; at this point the format specifier was recognized and we assume
Tue Jul 17 11:00:21 2018 Page 10
3092 ; that was parsed correctly and X hold the index to the right
3093 ; function that get parameter(s) from stack and convert in string.
3094 ; If the conversion function use fpu emulator we save the direct-page
3095 ; used by fp emulator to a local page in stack (for reentrancy)
3096 FA088C E0 04 00 cpx #T_PTR ; use fpu emulator?
3097 FA088F 90 1A bcc ?cvt ; no
3098 FA0891 24 1B bit fpuuse ; already saved fpu direct-page?
3099 FA0893 30 16 bmi ?cvt ; yes
3100 FA0895 DA phx ; save conversion function index
3101 FA0896 CPU16CLC
3102 FA0896 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3103 .LONGA on
3104 .LONGI on
3105 .MNLIST
3106 FA0898 3B tsc
3107 FA0899 E9 FF 00 sbc #255 ; make room for 256 bytes
3108 FA089C 1B tcs
3109 FA089D 1A inc a ; pointer to local
3110 FA089E 85 12 sta fpusave
3111 FA08A0 A8 tay ; destination for move
3112 FA08A1 A2 00 3F ldx #P0FPU ; source page for move
3113 FA08A4 A9 FF 00 lda #255 ; move 256 bytes
3114 FA08A7 54 00 00 mvn #0, #0 ; move in bank 0
3115 FA08AA FA plx ; restore function index
3116 FA08AB
3117 FA08AB ?cvt: CPU08
3118 FA08AB E2 30 sep #(PMFLAG.OR.PXFLAG)
3119 .LONGA off
3120 .LONGI off
3121 .MNLIST
3122 FA08AD FC 32 0B jsr (CVTTBL,x) ; call conversion function
3123 FA08B0 INDEX16
3124 FA08B0 C2 10 rep #PXFLAG
3125 .LONGI on
3126 .MNLIST
3127 FA08B2 A4 06 ldy fmtidx ; Y = index to format string
3128 FA08B4 C8 iny ; bump pointer
3129 FA08B5 80 83 bra ?nxt ; parse next char
3130
3131 ; ABANDON - causa errore specificatore di formato si suppone che i
3132 ; parametri non siano piu' allineati con il formato
3133 ; viene quindi copiato letteralmente il resto di szFmt a partire
3134 ; dal carattere '%' dove si e' verificato il disallineamento, fino
3135 ; alla fine della stringa szFmt
3136 FA08B7 A4 06 ?err: ldy fmtidx ; indice al carattere '%'
3137 FA08B9 B7 08 ?err1: lda [lpfmt],y ; copia da szFmt a szDst
3138 FA08BB F0 06 beq ?done ; fino a fine stringa
3139 FA08BD C8 iny
3140 FA08BE 20 D6 08 jsr _store
3141 FA08C1 80 F6 bra ?err1
3142
3143 FA08C3 24 1B ?done: bit fpuuse
3144 FA08C5 10 0F bpl ?end
3145 FA08C7 CPU16
3146 FA08C7 C2 30 rep #(PMFLAG.OR.PXFLAG)
3147 .LONGA on
3148 .LONGI on
Tue Jul 17 11:00:21 2018 Page 11
3149 .MNLIST
3150 FA08C9 A6 12 ldx fpusave ; source of move
3151 FA08CB A0 00 3F ldy #P0FPU
3152 FA08CE A9 FF 00 lda #255
3153 FA08D1 54 00 00 mvn #0, #0 ; move in bank 0
3154 FA08D4 CPU08
3155 FA08D4 E2 30 sep #(PMFLAG.OR.PXFLAG)
3156 .LONGA off
3157 .LONGI off
3158 .MNLIST
3159
3160 FA08D6 ?end:
3161
3162 FA08D6 _store:
3163 FA08D6 putter:
3164 FA08D6 A4 0E ldy dsize
3165 FA08D8 24 10 bit putopts
3166 FA08DA 10 08 bpl ?put ; put to file/stream
3167 FA08DC 50 13 bvc ?inc ; not store this byte in dest. string
3168 FA08DE C4 0E cpy dsize ; exceed dest. string size?
3169 FA08E0 B0 12 bcs ?done ; yes => no store, no increment counter
3170 FA08E2 80 0B bra ?sto ; store char in string
3171 FA08E4 C4 0E ?put: cpy dsize ; local buffer is full?
3172 FA08E6 90 07 bcc ?sto ; no, store char in local buffer
3173 FA08E8 85 19 sta fbtmp ; save current char
3174 FA08EA 20 F5 08 jsr lflush ; flush local buffer
3175 FA08ED A5 19 lda fbtmp ; restore current char
3176 FA08EF 97 0B ?sto: sta [lpdest],y ; store char in local buffer
3177 FA08F1 C8 ?inc: iny ; incremet counter
3178 FA08F2 84 0E sty dsize ; save current size of buffer
3179 FA08F4 60 ?done: rts
3180
3181 ; flush local buffer
3182 FA08F5 lflush:
3183 FA08F5 A9 00 lda #0
3184 FA08F7 97 0B sta [lpdest],y ; terminate local buffer
3185 FA08F9 BB tyx
3186 FA08FA F0 0A beq ?done ; empty buffer
3187 FA08FC A5 0C lda lpdest+1 ; C = buffer address
3188 FA08FE EB xba
3189 FA08FF A5 0B lda lpdest
3190 FA0901 A2 00 ldx #0 ; bank 0
3191 FA0903 9B txy
3192 FA0904 TXTSTROUT ; preserve A,X,Y
3193 FA0904 02 04 cop $04
3194 .MNLIST
3195 FA0906 60 ?done: rts
3196
3197 ;---------------------------------------------------------------------------
3198 ; specifier format parsing/checking - funtions that checks type and modifiers
3199 ;
3200 ; In - B = parsed char, A = current stage
3201 ; - ZF = 1 if current stage = 0
3202 ;
3203 ; Out - CF = 1 => error, unknow type or modifier not allowed
3204 ; CF = 0, VF = 1, X = conversion function index => end current parsing
3205 ; CF = 0, VF = 0 => continue parsing
Tue Jul 17 11:00:21 2018 Page 12
3206 ;---------------------------------------------------------------------------
3207
3208 .LONGA off
3209 .LONGI off
3210
3211 ; case ' ' or '+' -- only valid while stage = 0
3212 FA0907 case_si:
3213 FA0907 D0 64 bne case_dc ; error: not in stage = 0
3214 FA0909 A6 18 ldx fmtsgn
3215 FA090B E0 2B cpx #'+'
3216 FA090D F0 04 beq case_cont ; ignore ' ' if '+' already specified
3217 FA090F EB xba ; A = current char - B = stage
3218 FA0910 85 18 sta fmtsgn ; store sign byte
3219 FA0912 EB xba ; A = stage
3220 FA0913 case_cont:
3221 FA0913 18 clc ; OK
3222 FA0914 B8 clv ; continue parsing
3223 FA0915 60 rts
3224
3225 ; case digit '0' - meaning depend on current stage
3226 ; if stage = 0: left padding with digit '0' instead of blank ' '
3227 ; if stage > 0 then '0' is a digit of [width] or [precision] filkeds
3228 FA0916 case_fz:
3229 FA0916 D0 57 bne case_nu ; stage > 0 => handle width/precision
3230 FA0918 AA tax ; X = stage
3231 FA0919 A9 40 lda #F_LEFTJ
3232 FA091B 24 14 bit fmtflag ; ignore padding with '0'...
3233 FA091D F0 03 beq ?skp ; ... if not right just.
3234 FA091F 8A txa ; A = stage
3235 FA0920 D0 F1 bne case_cont ; continue parsing
3236 FA0922 A9 20 ?skp: lda #F_FILLZ ; padding with '0'
3237 FA0924 E8 inx ; X = 1 -> FILLZSTAGE
3238 FA0925 80 0C bra setflag ; after should follow width stage
3239
3240 ; case '-' -- only valid while stage = 0
3241 FA0927 case_lj:
3242 FA0927 D0 44 bne case_dc ; stop parsing
3243 FA0929 AA tax ; X = stage
3244 FA092A A9 40 lda #F_LEFTJ ; set left justify bit
3245 FA092C 80 05 bra setflag
3246 FA092E
3247 ; case '#' -- only valid while stage = 0
3248 FA092E case_af:
3249 FA092E D0 3D bne case_dc ; stop parsing
3250 FA0930 AA tax ; X = stage
3251 FA0931 A9 80 lda #F_ALTFMT ; alternate format bit
3252
3253 ; set current parsed flags
3254 FA0933 setflag:
3255 FA0933 04 14 tsb fmtflag
3256 FA0935 8A txa ; A = stage
3257 FA0936 18 clc ; OK
3258 FA0937 B8 clv ; continue parsing
3259 FA0938 60 rts
3260
3261 ; case ',' -- only valid while stage = 0
3262 FA0939 case_tg:
Tue Jul 17 11:00:21 2018 Page 13
3263 FA0939 D0 32 bne case_dc ; stop parsing
3264 FA093B AA tax ; X = stage
3265 FA093C A9 10 lda #F_GROUP ; set group thousand bit
3266 FA093E 80 F3 bra setflag
3267 FA0940
3268 ; case '*' -- [width] or [precision] field passed by argument
3269 FA0940 case_ar:
3270 FA0940 EB xba ; save stage
3271 FA0941 INDEX16
3272 FA0941 C2 10 rep #PXFLAG
3273 .LONGI on
3274 .MNLIST
3275 FA0943 A6 04 ldx pparams ; get byte parameter
3276 FA0945 CA dex ; align to next byte param
3277 FA0946 BD 00 00 lda .ABS.FMTPARAM,x
3278 FA0949 86 04 stx pparams
3279 FA094B INDEX08
3280 FA094B E2 10 sep #PXFLAG
3281 .LONGI off
3282 .MNLIST
3283 FA094D AA tax ; X = param
3284 FA094E EB xba ; A = stage
3285 FA094F C9 02 cmp #WIDESTAGE
3286 FA0951 B0 0B bcs ?nxt ; WIDESTAGE or above stage
3287 FA0953 86 16 stx fmtwidth ; store width
3288 FA0955 A9 08 lda #F_WIDTH
3289 FA0957 04 14 tsb fmtflag ; set 'width' bit
3290 FA0959 A9 03 lda #DOTSTAGE ; expected next stage: [.precision]
3291 FA095B 18 clc ; OK
3292 FA095C B8 clv ; continue parsing
3293 FA095D 60 rts
3294 FA095E C9 04 ?nxt: cmp #PRECSTAGE
3295 FA0960 D0 0B bne case_dc ; discard: unexpected stage level
3296 FA0962 86 17 stx fmtprec ; store precision
3297 FA0964 AA tax ; X = stage
3298 FA0965 A9 04 lda #F_PREC
3299 FA0967 04 14 tsb fmtflag ; set 'precision' bit
3300 FA0969 8A txa ; A = stage: keep current stage
3301 FA096A 18 clc ; OK
3302 FA096B B8 clv ; continue parsing
3303 FA096C 60 rts
3304 FA096D
3305 ; unknow chracter was parsed - sjip
3306 FA096D case_dc:
3307 FA096D 38 sec ; error flag
3308 FA096E 60 rts
3309
3310 ; case '0'..'9' - digit tht are part of [width] or [precision]
3311 ; fmtwidth and fmtprec are set to zero before enter parsing routine
3312 FA096F case_nu:
3313 FA096F AA tax ; X = stage
3314 FA0970 EB xba ; A = char '0'..'9'
3315 FA0971 38 sec
3316 FA0972 E9 30 sbc #'0' ; scale to 0..9
3317 FA0974 E0 03 cpx #WIDESTAGE+1 ; part of [width] field ?
3318 FA0976 B0 25 bcs ?nxt ; no
3319 FA0978 AA tax ; X = number 0..9
Tue Jul 17 11:00:21 2018 Page 14
3320 FA0979 A5 16 lda fmtwidth
3321 FA097B 86 16 stx fmtwidth
3322 FA097D F0 15 beq ?z ; old width = 0
3323 FA097F 0A asl a ; width * 2
3324 FA0980 B0 3E bcs ?err ; overflow
3325 FA0982 85 19 sta fbtmp
3326 FA0984 0A asl a
3327 FA0985 B0 39 bcs ?err ; overflow
3328 FA0987 0A asl a ; width * 8
3329 FA0988 B0 36 bcs ?err ; overflow
3330 FA098A 65 19 adc fbtmp ; width * 10
3331 FA098C B0 32 bcs ?err ; overflow
3332 FA098E 65 16 adc fmtwidth ; (width * 10) + number
3333 FA0990 B0 2E bcs ?err ; overflow
3334 FA0992 85 16 sta fmtwidth
3335 FA0994 A9 08 ?z: lda #F_WIDTH
3336 FA0996 04 14 tsb fmtflag ; set 'width' bit
3337 FA0998 A9 02 lda #WIDESTAGE ; set current stage: 'width'
3338 FA099A 18 clc ; OK
3339 FA099B B8 clv ; continue parsing
3340 FA099C 60 rts
3341 FA099D E0 04 ?nxt: cpx #PRECSTAGE ; precision stage ?
3342 FA099F D0 CC bne case_dc ; no -- skip
3343 FA09A1 AA tax ; X = number 0..9
3344 FA09A2 A5 17 lda fmtprec
3345 FA09A4 86 17 stx fmtprec
3346 FA09A6 F0 15 beq ?z1 ; old prec = 0
3347 FA09A8 0A asl a ; prec * 2
3348 FA09A9 B0 15 bcs ?err ; overflow
3349 FA09AB 85 19 sta fbtmp
3350 FA09AD 0A asl a
3351 FA09AE B0 10 bcs ?err ; overflow
3352 FA09B0 0A asl a ; prec * 8
3353 FA09B1 B0 0D bcs ?err ; overflow
3354 FA09B3 65 19 adc fbtmp ; prec * 10
3355 FA09B5 B0 09 bcs ?err ; overflow
3356 FA09B7 65 17 adc fmtprec ; (prec * 10) + number
3357 FA09B9 B0 05 bcs ?err ; overflow
3358 FA09BB 85 17 sta fmtprec
3359 FA09BD EB ?z1: xba ; keep current stage
3360 FA09BE 18 clc ; OK
3361 FA09BF B8 clv ; continue prsing
3362 FA09C0 60 ?err: rts
3363
3364 ; case '.' -- only valid if current stage < PRECSTAGE
3365 FA09C1 case_pr:
3366 FA09C1 C9 04 cmp #PRECSTAGE
3367 FA09C3 B0 08 bcs ?err ; skip
3368 FA09C5 A9 04 lda #F_PREC
3369 FA09C7 04 14 tsb fmtflag ; set 'precision' bit
3370 FA09C9 A9 04 lda #PRECSTAGE ; set current stage
3371 FA09CB 18 clc ; OK
3372 FA09CC B8 clv ; continue parsing
3373 FA09CD 60 ?err: rts
3374
3375 ;============================================================================
3376 ; modificatori -- impostano lo stato MODSTAGE (dopo sono ammessi solo i tipi)
Tue Jul 17 11:00:21 2018 Page 15
3377
3378 ; case 'l' -- 'long' modifier (64 bit integer)
3379 FA09CE case_lo:
3380 FA09CE A2 20 ldx #F2_LONG
3381 FA09D0 80 0E bra setmod
3382
3383 ; case 'h' -- 'short' modifier (16 bit integer)
3384 FA09D2 case_sh:
3385 FA09D2 A2 10 ldx #F2_SHORT
3386 FA09D4 80 0A bra setmod
3387
3388 ; case 'b' -- 'byte' modifier (8 bit integer)
3389 FA09D6 case_SH:
3390 FA09D6 A2 08 ldx #F2_BYTE
3391 FA09D8 80 06 bra setmod
3392
3393 ; case 'L' -- 'long long' modifier (128 bit integer)
3394 FA09DA case_ll:
3395 FA09DA A2 40 ldx #F2_LONGLONG
3396 FA09DC 80 02 bra setmod
3397 FA09DE
3398 ; case 'B' -- 'pascal/basic' string modifier
3399 FA09DE case_PS:
3400 FA09DE A2 80 ldx #F2_PSSTRING
3401
3402 FA09E0 setmod:
3403 FA09E0 C9 05 cmp #MODSTAGE
3404 FA09E2 B0 07 bcs ?err ; skip
3405 FA09E4 8A txa
3406 FA09E5 04 15 tsb fmtmod
3407 FA09E7 A9 05 lda #MODSTAGE ; set final stage
3408 FA09E9 18 clc ; OK
3409 FA09EA B8 clv ; continue parsing
3410 FA09EB 60 ?err: rts
3411
3412 ;---------------------------------------------------------------------------
3413 ; specifier format checking -- these funtions checks type and modifiers
3414 ; flags in status register are set according check result:
3415 ;
3416 ; CF = 1 => error, modifier not allowed
3417 ; CF = 0, VF = 1 => ok -- X = conversion function index
3418 ;---------------------------------------------------------------------------
3419 FA09EC
3420 ; case 'X' -- type unsigned integer hexadecimal upper case digits
3421 FA09EC case_HE:
3422 FA09EC A9 04 lda #F2_CAPS ; set CAPS bit
3423 FA09EE 04 15 tsb fmtmod
3424 FA09F0
3425 ; case 'x' -- type unsigned integer hexadecimal upper case digits
3426 FA09F0 case_he:
3427 FA09F0 A9 01 lda #F2_SIGNED
3428 FA09F2 14 15 trb fmtmod ; clear signed bit
3429 FA09F4 A5 14 lda fmtflag
3430 FA09F6 89 04 bit #F_PREC
3431 FA09F8 F0 04 beq ?skp
3432 FA09FA A9 20 lda #F_FILLZ ; ignore left '0' padding...
3433 FA09FC 14 14 trb fmtflag ; ...if specified 'precision'
Tue Jul 17 11:00:21 2018 Page 16
3434 FA09FE A2 08 ?skp: ldx #T_HEX ; conversion function index
3435 FA0A00 A9 80 lda #MASKINTG ; not allowed modifiers for integers
3436 FA0A02 80 72 bra case_end
3437
3438 ; case 'd', 'i' -- type decimal signed integer
3439 FA0A04 case_de:
3440 FA0A04 A9 01 lda #F2_SIGNED
3441 FA0A06 04 15 tsb fmtmod ; set signed bit
3442 FA0A08 80 04 bra case_i ; common code for decimal integers
3443
3444 ; case 'u' -- type decimal unsigned integer
3445 FA0A0A case_un:
3446 FA0A0A A9 01 lda #F2_SIGNED
3447 FA0A0C 14 15 trb fmtmod ; clear signed bit
3448
3449 ; common code for decimal integers
3450 FA0A0E case_i:
3451 FA0A0E A5 14 lda fmtflag
3452 FA0A10 89 04 bit #F_PREC
3453 FA0A12 F0 04 beq ?skp
3454 FA0A14 A9 20 lda #F_FILLZ ; ignore left '0' padding...
3455 FA0A16 14 14 trb fmtflag ; ...if specified 'precision'
3456 FA0A18 A9 80 ?skp: lda #F_ALTFMT
3457 FA0A1A 14 14 trb fmtflag ; ignore alternate format
3458 FA0A1C A2 06 ldx #T_INT ; conversion function index
3459 FA0A1E A9 80 lda #MASKINTG ; not allowed modifiers for integers
3460 FA0A20 80 54 bra case_end
3461
3462 ; case 'c' -- type char
3463 FA0A22 case_ch:
3464 FA0A22 A9 84 lda #(F_ALTFMT.OR.F_PREC) ; ignore precision and alternate format
3465 FA0A24 14 14 trb fmtflag
3466 FA0A26 A2 00 ldx #T_CHAR ; conversion function index
3467 FA0A28 A9 F8 lda #MASKCHAR ; not allowed modifiers for chars
3468 FA0A2A 80 4A bra case_end
3469 FA0A2C
3470 ; case 's' -- type string
3471 FA0A2C case_st:
3472 FA0A2C A9 80 lda #F_ALTFMT ; ignore alternate format
3473 FA0A2E 14 14 trb fmtflag
3474 FA0A30 A2 02 ldx #T_STR ; conversion function index
3475 FA0A32 A9 78 lda #MASKSTR ; not allowed modifiers for strings
3476 FA0A34 80 40 bra case_end
3477
3478 ; case 'E' -- type float exponential format (upper case 'E')
3479 FA0A36 case_FE:
3480 FA0A36 A9 45 lda #'E' ; format 'E'
3481 FA0A38 80 32 bra case_f
3482
3483 ; case 'e' -- type float exponential format (lower case 'e')
3484 FA0A3A case_fe:
3485 FA0A3A A9 65 lda #'e' ; format 'e'
3486 FA0A3C 80 2E bra case_f
3487 FA0A3E
3488 ; case 'G' -- type float format 'G'
3489 FA0A3E case_FG:
3490 FA0A3E A9 47 lda #'G' ; format 'G'
Tue Jul 17 11:00:21 2018 Page 17
3491 FA0A40 80 2A bra case_f
3492
3493 ; case 'g' -- type float format 'g'
3494 FA0A42 case_fg:
3495 FA0A42 A9 67 lda #'g' ; format 'g'
3496 FA0A44 80 26 bra case_f
3497 FA0A46
3498 ; case 'A' -- type float hexadecimal upper case digits
3499 FA0A46 case_XF:
3500 FA0A46 A9 20 lda #F_FILLZ ; ignore left '0' padding
3501 FA0A48 14 14 trb fmtflag
3502 FA0A4A A9 41 lda #'A' ; format 'A'
3503 FA0A4C 80 1E bra case_f
3504
3505 ; case 'a' -- type float hexadecimal lower case digits
3506 FA0A4E case_xf:
3507 FA0A4E A9 20 lda #F_FILLZ ; ignore left '0' padding
3508 FA0A50 14 14 trb fmtflag
3509 FA0A52 A9 61 lda #'a' ; format 'a'
3510 FA0A54 80 16 bra case_f
3511
3512 ; case 'K' -- type compact float hexadecimal lower case digits
3513 FA0A56 case_KF:
3514 FA0A56 A9 20 lda #F_FILLZ ; ignore left '0' padding
3515 FA0A58 14 14 trb fmtflag
3516 FA0A5A A9 4B lda #'K' ; format 'K'
3517 FA0A5C 80 0E bra case_f
3518
3519 ; case 'k' -- type compact float hexadecimal upper case digits
3520 FA0A5E case_kf:
3521 FA0A5E A9 20 lda #F_FILLZ ; ignore left '0' padding
3522 FA0A60 14 14 trb fmtflag
3523 FA0A62 A9 6B lda #'k' ; format 'K'
3524 FA0A64 80 06 bra case_f
3525
3526 ; case 'f', 'F' -- type float decimal
3527 FA0A66 case_ff:
3528 FA0A66 A9 66 lda #'f' ; format 'f'
3529 FA0A68 80 02 bra case_f
3530
3531 FA0A6A case_FF:
3532 FA0A6A A9 46 lda #'F' ; format 'F'
3533
3534 ; common code for float conversion
3535 FA0A6C case_f:
3536 ; float numbers can be left padded with '0'
3537 ; even if specified 'precision'
3538 FA0A6C 85 1A sta tfloat ; float format type
3539 FA0A6E A9 01 lda #F2_SIGNED
3540 FA0A70 04 15 tsb fmtmod ; set signed bit
3541 FA0A72 A2 0A ldx #T_FLOAT ; conversion function index
3542 FA0A74 A9 F8 lda #MASKFLOAT ; not allowed modifiers for strings
3543
3544 ; check modifier type
3545 FA0A76 case_end:
3546 FA0A76 24 15 bit fmtmod ; check not allowed modifiers
3547 FA0A78 F0 02 beq ?ok ; OK
Tue Jul 17 11:00:21 2018 Page 18
3548 FA0A7A 38 sec ; error
3549 FA0A7B 60 rts
3550 FA0A7C E2 40 ?ok: sep #PVFLAG ; set VF = 1
3551 FA0A7E 18 clc ; no error
3552 FA0A7F 60 rts
3553
3554 ; case 'P' -- type pointer hexadecimal upper case digits
3555 FA0A80 case_PT:
3556 FA0A80 A9 04 lda #F2_CAPS ; set CAPS bit
3557 FA0A82 04 15 tsb fmtmod
3558
3559 ; case 'p' -- type pointer hexadecimal lower case digits
3560 FA0A84 case_pt:
3561 FA0A84 A9 01 lda #F2_SIGNED
3562 FA0A86 14 15 trb fmtmod ; clear flag signed
3563 FA0A88 A9 20 lda #F_FILLZ ; ignore left '0' padding
3564 FA0A8A 14 14 trb fmtflag
3565 FA0A8C A2 04 ldx #T_PTR ; conversion function index
3566 FA0A8E A9 F8 lda #MASKPTR ; not allowed modifiers for pointers
3567 FA0A90 80 E4 bra case_end
3568
3569 ;---------------------------------------------------------------------------
3570 ; tables
3571 ;---------------------------------------------------------------------------
3572
3573 ; character's class lookup table (32 <= char < 128)
3574 FA0A92 CLASSCHR:
3575
3576 ; SP ! " # $ % & ' ( ) * + , - . /
3577 FA0A92 01 00 00 02 00 .DB _si,_dc,_dc,_af,_dc,_dc,_dc,_dc,_dc,_dc,_ar,_si,_tg,_lj,_pr,_dc
00 00 00 00 00
03 01 18 04 05
00
3578
3579 ; 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
3580 FA0AA2 0A 06 06 06 06 .DB _fz,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_dc,_dc,_dc,_dc,_dc,_dc
06 06 06 06 06
00 00 00 00 00
00
3581
3582 ; _ A B C D E F G H I J K L M N O
3583 FA0AB2 00 1C 1A 00 00 .DB _dc,_XF,_PS,_dc,_dc,_FE,_FF,_FG,_dc,_dc,_dc,_KF,_ll,_dc,_dc,_dc
16 1F 17 00 00
00 1E 19 00 00
00
3584
3585 ; P Q R S T U V W X Y Z [ \ ] ^ _
3586 FA0AC2 10 00 00 00 00 .DB _PT,_dc,_dc,_dc,_dc,_dc,_dc,_dc,_HE,_dc,_dc,_dc,_dc,_dc,_dc,_dc
00 00 00 0F 00
00 00 00 00 00
00
3587
3588 ; ` a b c d e f g h i j k l m n o
3589 FA0AD2 00 1B 09 11 0B .DB _dc,_xf,_SH,_ch,_de,_fe,_ff,_fg,_sh,_de,_dc,_kf,_lo,_dc,_dc,_dc
14 13 15 08 0B
00 1D 07 00 00
00
Tue Jul 17 11:00:21 2018 Page 19
3590
3591 ; p q r s t u v w x y z { | } ~ DEL
3592 FA0AE2 0E 00 00 12 00 .DB _pt,_dc,_dc,_st,_dc,_un,_dc,_dc,_he,_dc,_dc,_dc,_dc,_dc,_dc,_dc
0C 00 00 0D 00
00 00 00 00 00
00
3593
3594 ; table of specifiers checking functions
3595 FA0AF2 CHKTBL:
3596 FA0AF2 6D09 0709 2E09 .DW case_dc, case_si, case_af, case_ar
4009
3597 FA0AFA 2709 C109 6F09 .DW case_lj, case_pr, case_nu, case_lo
CE09
3598 FA0B02 D209 D609 1609 .DW case_sh, case_SH, case_fz, case_de
040A
3599 FA0B0A 0A0A F009 840A .DW case_un, case_he, case_pt, case_HE
EC09
3600 FA0B12 800A 220A 2C0A .DW case_PT, case_ch, case_st, case_ff
660A
3601 FA0B1A 3A0A 420A 360A .DW case_fe, case_fg, case_FE, case_FG
3E0A
3602 FA0B22 3909 DA09 DE09 .DW case_tg, case_ll, case_PS, case_xf
4E0A
3603 FA0B2A 460A 5E0A 560A .DW case_XF, case_kf, case_KF, case_FF
6A0A
3604 FA0B32
3605 ; tabella funzioni di conversione
3606 FA0B32 CVTTBL:
3607 ; .DW DoChar, DoStr, DoPtr, DoInt, DoHex, DoFloat
3608 FA0B32
3609 FA0B32 NULLSTR:
3610 FA0B32 28 6E 75 6C 6C .DB "(null)", 0
29 00
Lines Assembled : 3507 Errors : 0