Subversion Repositories MB01 Project

Rev

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