Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | - | 1 | Tue Jul 17 11:00:21 2018 Page 1 |
2 | |||
3 | |||
4 | |||
5 | |||
6 | |||
7 | |||
8 | |||
9 | 2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g |
||
10 | ----------------------------------------------------- |
||
11 | |||
12 | Input Filename : src\FA\printf.asm |
||
13 | Output Filename : obj\FA\printf.obj |
||
14 | Listing Has Been Relocated |
||
15 | |||
16 | |||
17 | 2582 .LIST on |
||
18 | 2583 |
||
19 | 2584 F8FFB1 .INCLUDE inc\dpfpu.inc |
||
20 | 2585 ;; |
||
21 | 2586 ;; Copyright (c) 2016 Marco Granati <mg@unet.bz> |
||
22 | 2587 ;; |
||
23 | 2588 ;; Permission to use, copy, modify, and distribute this software for any |
||
24 | 2589 ;; purpose with or without fee is hereby granted, provided that the above |
||
25 | 2590 ;; copyright notice and this permission notice appear in all copies. |
||
26 | 2591 ;; |
||
27 | 2592 ;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||
28 | 2593 ;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||
29 | 2594 ;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||
30 | 2595 ;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||
31 | 2596 ;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||
32 | 2597 ;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||
33 | 2598 ;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||
34 | 2599 ;; |
||
35 | 2600 |
||
36 | 2601 ;; name: dpfpu.inc |
||
37 | 2602 ;; rev.: 2016/03/30 |
||
38 | 2603 ;; o.s. 65C816 version v1.0 |
||
39 | 2604 |
||
40 | 2605 .LIST on |
||
41 | 2606 |
||
42 | 2607 ; direct page for flotaing point unit |
||
43 | 2608 _DPFPU: .SECTION page0, common, ref_only, offset 0 ;FPU D.P. |
||
44 | 2609 |
||
45 | 2610 000080 MNTBITS .EQU (16*8) ; significand bits + guard bits |
||
46 | 2611 000010 MANTSIZ .EQU 16 ; significand size |
||
47 | 2612 000014 FREGSIZ .EQU 20 ; floating point register size |
||
48 | 2613 |
||
49 | 2614 000000 tm .DS 16 ; temp. mantissa |
||
50 | 2615 |
||
51 | 2616 000010 00 fsubnf .DB ; subnormal flag used by fac2dec |
||
52 | 2617 000010 atncode .EQU fsubnf ; fatanyx octant |
||
53 | 2618 |
||
54 | 2619 000011 00 sgncmp .DB ; sign comparison: fac vs. arg |
||
55 | 2620 |
||
56 | 2621 ; floating Point accumulator (fac) |
||
57 | 2622 000012 facm .DS 16 ; guard bits (32 bits)+significand (80 bits) |
||
58 | 2623 000022 0000 facexp .DW ; fac biased exponent |
||
59 | 2624 000024 00 facsgn .DB ; fac mantissa sign |
||
60 | 2625 000025 00 facst .DB ; fac status for floating point |
||
61 | 2626 ; <7>: 1 if fac is invalid (nan or inf) |
||
62 | 2627 ; <6>: 1 if fac=inf (with <7>=1) |
||
63 | Tue Jul 17 11:00:21 2018 Page 2 |
||
64 | |||
65 | |||
66 | |||
67 | |||
68 | 2628 ; 0 if fac=nan (with <7>=1) |
||
69 | 2629 ; <6>: 1 if fac=0 (with <7>=0) |
||
70 | 2630 ; <5>: always '0' |
||
71 | 2631 |
||
72 | 2632 ; fac status for long integer |
||
73 | 2633 ; <7>: 1 if facm will be regarded as 'signed' |
||
74 | 2634 ; <6>: 1 if facm = 0 |
||
75 | 2635 ; <5>: always '1' |
||
76 | 2636 |
||
77 | 2637 000026 0000 fexph .DW ; unbiased fac exponent sign extension |
||
78 | 2638 000028 0000 facext .DW ; fac guard bits extension |
||
79 | 2639 000028 wftmp2 .EQU facext |
||
80 | 2640 000024 facsiz .EQU facsgn ; integer only: size in bytes |
||
81 | 2641 |
||
82 | 2642 ; floating point operand (arg) |
||
83 | 2643 00002A argm .DS 16 ; guard bits (32 bits)+significand (80 bits) |
||
84 | 2644 00003A 0000 argexp .DW ; arg biased exponent |
||
85 | 2645 00003C 00 argsgn .DB ; arg mantissa sign |
||
86 | 2646 00003D 00 argst .DB ; arg status for floating point |
||
87 | 2647 ; <7>: 1 if arg is invalid (nan or inf) |
||
88 | 2648 ; <6>: 1 if arg=inf (with <7>=1) |
||
89 | 2649 ; 0 if arg=nan (with <7>=1) |
||
90 | 2650 ; <6>: 1 if arg=0 (with <7>=0) |
||
91 | 2651 |
||
92 | 2652 ; arg status for long integer |
||
93 | 2653 ; <7>: 1 if facm will be regarded as 'signed' |
||
94 | 2654 ; <6>: 1 if facm = 0 |
||
95 | 2655 ; <5>: always '1' |
||
96 | 2656 00003E |
||
97 | 2657 00003E 0000 aexph .DW ; unbiased arg exponent sign extension |
||
98 | 2658 000040 0000 argext .DW |
||
99 | 2659 |
||
100 | 2660 00003E wftmp .EQU aexph ; temp. word (int2dec, fpadd, fpsub) |
||
101 | 2661 00003C argsiz .EQU argsgn ; integer only: size in bytes |
||
102 | 2662 |
||
103 | 2663 000042 fcp LP ; long pointer to flaot constants |
||
104 | 2664 000045 00 scsgn .DB ; scaling sign |
||
105 | 2665 000046 0000 scexp .DW ; scaling value |
||
106 | 2666 000048 0000 dexp .DW ; decimal exponent |
||
107 | 2667 00004A 00 dsgn .DB ; decimal float sign |
||
108 | 2668 00004B 00 pdeg .DB ; polyn. degree |
||
109 | 2669 00004B powfg .EQU pdeg ; flag used by fpowxy |
||
110 | 2670 |
||
111 | 2671 00004C tlp LP ; string long pointer |
||
112 | 2672 00004F 00 fpidx .DB ; string index |
||
113 | 2673 000050 |
||
114 | 2674 000050 tfr0 .DS 20 ; temp. float reg. 0 |
||
115 | 2675 000064 tfr1 .DS 20 ; temp. float reg. 1 |
||
116 | 2676 000078 tfr2 .DS 20 ; temp. float reg. 2 |
||
117 | 2677 00008C tfr3 .DS 20 ; temp. float reg. 3 |
||
118 | 2678 0000A0 tfr4 .DS 20 ; temp. float reg. 4 |
||
119 | 2679 0000B4 tfr5 .DS 20 ; temp. float reg. 5 |
||
120 | 2680 0000C8 .DS 4 ; used by xcvt: doesn't change |
||
121 | 2681 |
||
122 | 2682 0000CB XCVTEND .EQU ($ - 1) ; last byte of xcvt buffer |
||
123 | 2683 |
||
124 | 2684 ; buffer used by decimal conversion (overlap tfr0&tfr1: 40 bytes) |
||
125 | Tue Jul 17 11:00:21 2018 Page 3 |
||
126 | |||
127 | |||
128 | |||
129 | |||
130 | 2685 000050 fpstr .EQU tfr0 ; 40 bytes buffer |
||
131 | 2686 ; buffer used to format a decimal string |
||
132 | 2687 000078 xcvt .EQU tfr2 ; 84 bytes buffer |
||
133 | 2688 |
||
134 | 2689 0000B4 fcpc0 .EQU tfr5 ; constants pointer for exp. function |
||
135 | 2690 0000B6 fcpc1 .EQU tfr5+2 |
||
136 | 2691 0000B8 fcpc2 .EQU tfr5+4 |
||
137 | 2692 0000BA fcpp .EQU tfr5+6 |
||
138 | 2693 0000BC fcpq .EQU tfr5+8 |
||
139 | 2694 0000BE fcpd .EQU tfr5+10 |
||
140 | 2695 0000BF fcqd .EQU tfr5+11 |
||
141 | 2696 0000C0 fcpolf .EQU tfr5+12 ; polynomial flag |
||
142 | 2697 |
||
143 | 2698 0000B4 tmdot .EQU tfr5 ; digit count after decimal dot |
||
144 | 2699 0000B6 tmpa .EQU tfr5+2 ; temp: save A&Y |
||
145 | 2700 0000B7 tmpy .EQU tfr5+3 |
||
146 | 2701 0000B8 tmsgn .EQU tfr5+4 ; temp.: significand sign |
||
147 | 2702 0000B9 tmcnt .EQU tfr5+5 ; temp.: significand digits count |
||
148 | 2703 0000BA tesgn .EQU tfr5+6 ; temp.: exponent sign |
||
149 | 2704 0000BB tecnt .EQU tfr5+7 ; temp.: exponent digits count |
||
150 | 2705 |
||
151 | 2706 0000BC mcand1 .EQU tfr5+8 ; multiplicand's |
||
152 | 2707 0000BE mcand2 .EQU tfr5+10 |
||
153 | 2708 0000C0 mcsgn .EQU tfr5+12 |
||
154 | 2709 0000C2 dvsor .EQU tfr5+14 |
||
155 | 2710 0000C4 quot .EQU tfr5+16 |
||
156 | 2711 |
||
157 | 2712 0000CC 0000 fpprec .DW ; precision |
||
158 | 2713 0000CE 00 fpfmt .DB ; format |
||
159 | 2714 0000CF 00 fpaltf .DB ; alternate format |
||
160 | 2715 0000D0 00 fpcap .DB ; adding for lower case |
||
161 | 2716 0000D1 00 fpstyle .DB ; flag 'F' style |
||
162 | 2717 00004B fpdot .EQU pdeg ; decimal dot flag |
||
163 | 2718 0000CE fpoct .EQU fpfmt ; octant (circular func's) |
||
164 | 2719 0000CF fpcsgn .EQU fpaltf ; circular func's: argument sign |
||
165 | 2720 0000D0 fpcot .EQU fpcap ; cotangent flag |
||
166 | 2721 0000D0 fpasin .EQU fpcap ; asin flag |
||
167 | 2722 |
||
168 | 2723 0000D2 00 dummy .DB |
||
169 | 2724 |
||
170 | 2725 .ENDS |
||
171 | 2734 .LIST on |
||
172 | 2735 |
||
173 | 2736 ; save 10 bytes in stack plus 3 bytes for return address |
||
174 | 2737 00000D PUSHED .EQU 13 ; return address + pushed register's |
||
175 | 2738 00000F PUSHED1 .EQU 15 ; count is in top of return address |
||
176 | 2739 000040 NLOCALS .EQU 64 |
||
177 | 2740 00004E COUNTOFS .EQU (PUSHED + NLOCALS + 1) |
||
178 | 2741 |
||
179 | 2742 000000 FMTPARAM .EQU 0 |
||
180 | 2743 |
||
181 | 2744 ; locals in stack accessed by DPR |
||
182 | 2745 _PRINTFDP: .SECTION page0, common, ref_only, offset 0 |
||
183 | 2746 |
||
184 | 2747 000000 0000 mvfrom .DW |
||
185 | 2748 000002 0000 mvto .DW |
||
186 | 2749 000004 0000 pparams .DW |
||
187 | Tue Jul 17 11:00:21 2018 Page 4 |
||
188 | |||
189 | |||
190 | |||
191 | |||
192 | 2750 000006 0000 fmtidx .DW ; current index to format string |
||
193 | 2751 000008 lpfmt LP ; long pointer to format string |
||
194 | 2752 00000B lpdest LP ; long pointer to dest. string |
||
195 | 2753 00000E 0000 dsize .DW ; dest. string size |
||
196 | 2754 000010 00 putopts .DB ; putter options |
||
197 | 2755 ; <7>: 0 => file/stream - 1 => string |
||
198 | 2756 ; <6>: if <7> = 0 => 0 => file - 1 => stream |
||
199 | 2757 ; <6>: if <7> = 1 => 0 => alloc string - 1 => use dest |
||
200 | 2758 000011 00 putopts2 .DB ; <7>: 0 => no store - 1 +> store |
||
201 | 2759 000012 0000 fpusave .DW ; pointer to fpu saved direct-page |
||
202 | 2760 000014 00 fmtflag .DB ; format flags (see F_XXX constants) |
||
203 | 2761 000015 00 fmtmod .DB ; modifier's bit's (see F2_XXX constants) |
||
204 | 2762 000016 00 fmtwidth .DB ; [width] field value |
||
205 | 2763 000017 00 fmtprec .DB ; [precision] field value |
||
206 | 2764 000018 00 fmtsgn .DB ; formattation sign |
||
207 | 2765 000019 00 fbtmp .DB ; temp. byte |
||
208 | 2766 00001A 00 tfloat .DB ; float conversion type (see FF_XXX constants) |
||
209 | 2767 00001B 00 fpuuse .DB ; signal that current conversion use fpu emulator |
||
210 | 2768 |
||
211 | 2769 00001C LOCALSIZE .DS 0 |
||
212 | 2770 |
||
213 | 2771 .ENDS |
||
214 | 2772 |
||
215 | 2773 ; locals |
||
216 | 2774 ;mvfrom .EQU 0 |
||
217 | 2775 ;mvto .EQU 2 |
||
218 | 2776 ;pformat .EQU 4 |
||
219 | 2777 |
||
220 | 2778 ;--------------------------------------------------------------------------- |
||
221 | 2779 ; equates |
||
222 | 2780 ;--------------------------------------------------------------------------- |
||
223 | 2781 |
||
224 | 2782 ; spec's class |
||
225 | 2783 000000 _dc .EQU 0 ; don't care |
||
226 | 2784 000001 _si .EQU 1 ; sign fill +/- |
||
227 | 2785 000002 _af .EQU 2 ; alternate form |
||
228 | 2786 000003 _ar .EQU 3 ; format (width or precision) by argument |
||
229 | 2787 000004 _lj .EQU 4 ; left justify |
||
230 | 2788 000005 _pr .EQU 5 ; precision |
||
231 | 2789 000006 _nu .EQU 6 ; numeral |
||
232 | 2790 000007 _lo .EQU 7 ; long integer (64 bit) |
||
233 | 2791 000008 _sh .EQU 8 ; short integer (16 bit) |
||
234 | 2792 000009 _SH .EQU 9 ; byte (8 byte) |
||
235 | 2793 00000A _fz .EQU 10 ; fill zeros |
||
236 | 2794 00000B _de .EQU 11 ; signed decimal |
||
237 | 2795 00000C _un .EQU 12 ; unsigned decimal |
||
238 | 2796 00000D _he .EQU 13 ; hexadecimal (lower case digits) |
||
239 | 2797 00000E _pt .EQU 14 ; long pointer (lower case digits) |
||
240 | 2798 00000F _HE .EQU 15 ; hexadecimal (upper case digits) |
||
241 | 2799 000010 _PT .EQU 16 ; long pointer (upper case digits) |
||
242 | 2800 000011 _ch .EQU 17 ; char |
||
243 | 2801 000012 _st .EQU 18 ; string (ASCIIZ) |
||
244 | 2802 000013 _ff .EQU 19 ; float %f |
||
245 | 2803 000014 _fe .EQU 20 ; float %e |
||
246 | 2804 000015 _fg .EQU 21 ; float %g |
||
247 | 2805 000016 _FE .EQU 22 ; float %E |
||
248 | 2806 000017 _FG .EQU 23 ; float %G |
||
249 | Tue Jul 17 11:00:21 2018 Page 5 |
||
250 | |||
251 | |||
252 | |||
253 | |||
254 | 2807 000018 _tg .EQU 24 ; thousand group |
||
255 | 2808 000019 _ll .EQU 25 ; long long integer (128 bits) |
||
256 | 2809 00001A _PS .EQU 26 ; pascal/basic string |
||
257 | 2810 00001B _xf .EQU 27 ; hex float (lower case digits) |
||
258 | 2811 00001C _XF .EQU 28 ; hex float (upper case digits) |
||
259 | 2812 00001D _kf .EQU 29 ; compact hex float |
||
260 | 2813 00001E _KF .EQU 30 ; compact hex float (upper case digits) |
||
261 | 2814 00001F _FF .EQU 31 ; float %F |
||
262 | 2815 |
||
263 | 2816 ; fmtflag bits |
||
264 | 2817 000080 F_ALTFMT .EQU $80 ; alternate format |
||
265 | 2818 000040 F_LEFTJ .EQU $40 ; left justify (default: right) |
||
266 | 2819 000020 F_FILLZ .EQU $20 ; fill with '0' digit |
||
267 | 2820 000010 F_GROUP .EQU $10 ; thousand group |
||
268 | 2821 000008 F_WIDTH .EQU $08 ; 'width' field is valid |
||
269 | 2822 000004 F_PREC .EQU $04 ; 'precision' field is valid |
||
270 | 2823 |
||
271 | 2824 ; fmtmod modifier's bits |
||
272 | 2825 000080 F2_PSSTRING .EQU $80 ; pascal/basic string (default: ASCIIZ) |
||
273 | 2826 000040 F2_LONGLONG .EQU $40 ; integer long long modifier |
||
274 | 2827 000020 F2_LONG .EQU $20 ; integer long modifier |
||
275 | 2828 000010 F2_SHORT .EQU $10 ; integer short modifier |
||
276 | 2829 000008 F2_BYTE .EQU $08 ; integer byte modifier |
||
277 | 2830 000004 F2_CAPS .EQU $04 ; upper case hexadecimal digits |
||
278 | 2831 000001 F2_SIGNED .EQU $01 ; signed integer |
||
279 | 2832 |
||
280 | 2833 ; tfloat values: float format type |
||
281 | 2834 000045 FF_EXP .EQU 'E' ; e/E format |
||
282 | 2835 000046 FF_STD .EQU 'F' ; f/F format |
||
283 | 2836 000040 FF_G .EQU $40 ; g/G format |
||
284 | 2837 000004 FF_HEX .EQU $04 ; a/A format |
||
285 | 2838 |
||
286 | 2839 ; valid integer modifier's mask |
||
287 | 2840 000078 MASKMOD .EQU (F2_LONG.OR.F2_SHORT.OR.F2_BYTE.OR.F2_LONGLONG) |
||
288 | 2841 |
||
289 | 2842 ; invalid modifier mask for '%c' format |
||
290 | 2843 0000F8 MASKCHAR .EQU (MASKMOD.OR.F2_PSSTRING) |
||
291 | 2844 |
||
292 | 2845 ; invalid modifier mask for '%s' format |
||
293 | 2846 000078 MASKSTR .EQU (MASKMOD) |
||
294 | 2847 |
||
295 | 2848 ; invalid modifier mask for '%p' format |
||
296 | 2849 0000F8 MASKPTR .EQU (MASKCHAR) |
||
297 | 2850 |
||
298 | 2851 ; invalid modifier mask for float format |
||
299 | 2852 0000F8 MASKFLOAT .EQU (MASKMOD.OR.F2_PSSTRING) |
||
300 | 2853 |
||
301 | 2854 ; invalid modifier mask for integer |
||
302 | 2855 000080 MASKINTG .EQU (F2_PSSTRING) |
||
303 | 2856 |
||
304 | 2857 ; conversion function index |
||
305 | 2858 000000 T_CHAR .EQU 0 ; character |
||
306 | 2859 000002 T_STR .EQU (1 * 2) ; string |
||
307 | 2860 000004 T_PTR .EQU (2 * 2) ; long pointer |
||
308 | 2861 000006 T_INT .EQU (3 * 2) ; integer |
||
309 | 2862 000008 T_HEX .EQU (4 * 2) ; hexadecimal |
||
310 | 2863 00000A T_FLOAT .EQU (5 * 2) ; float |
||
311 | Tue Jul 17 11:00:21 2018 Page 6 |
||
312 | |||
313 | |||
314 | |||
315 | |||
316 | 2864 |
||
317 | 2865 ; current stage while scan format |
||
318 | 2866 000000 FLAGSTAGE .EQU 0 ; [flag] stage |
||
319 | 2867 000001 FILLZSTAGE .EQU 1 ; fill with '0' stage |
||
320 | 2868 000002 WIDESTAGE .EQU 2 ; [width] stage |
||
321 | 2869 000003 DOTSTAGE .EQU 3 ; ['.'] stage |
||
322 | 2870 000004 PRECSTAGE .EQU 4 ; [precision] stage |
||
323 | 2871 000005 MODSTAGE .EQU 5 ; [modifier] stage |
||
324 | 2872 |
||
325 | 2873 ; snprintf(str, size, format, ..., count) |
||
326 | 2874 ; str: dest string |
||
327 | 2875 ; size: size of dest |
||
328 | 2876 ; format: format string |
||
329 | 2877 ; count: bytes count of variables param's |
||
330 | 2878 ; |
||
331 | 2879 ; P = 10 => bytes's count of know param's (str->3, size->2, format->3, count->2) |
||
332 | 2880 ; M = byte's count of variables param's (stored in count) |
||
333 | 2881 |
||
334 | 2882 000008 KNOWPAR .SET 8 |
||
335 | 2883 |
||
336 | 2884 ; prologue |
||
337 | 2885 prologue .MACRO npars |
||
338 | 2886 |
||
339 | 2887 .MLIST |
||
340 | 2888 .LONGA off |
||
341 | 2889 .LONGI off |
||
342 | 2890 |
||
343 | 2891 php ; save status |
||
344 | 2892 phb ; save DBR |
||
345 | 2893 phd ; save DPR |
||
346 | 2894 |
||
347 | 2895 ; CPU 16 + CLC |
||
348 | 2896 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
349 | 2897 .LONGA on |
||
350 | 2898 .LONGI on |
||
351 | 2899 |
||
352 | 2900 pha ; save A |
||
353 | 2901 phx ; save X |
||
354 | 2902 phy ; save Y |
||
355 | 2903 tsx |
||
356 | 2904 txa ; A = old frame stack |
||
357 | 2905 ;sbc #NLOCALS-1 |
||
358 | 2906 sbc #LOCALSIZE-1 |
||
359 | 2907 tcs ; new stack pointer |
||
360 | 2908 inc a |
||
361 | 2909 tcd ; DPR point to locals base |
||
362 | 2910 txa |
||
363 | 2911 clc |
||
364 | 2912 adc #PUSHED |
||
365 | 2913 sta mvfrom ; pointer to source frame stack to move |
||
366 | 2914 inc a |
||
367 | 2915 inc a ; pointer to top of count param (countH) |
||
368 | 2916 adc COUNTOFS,s ; add size of variables param's |
||
369 | 2917 tax |
||
370 | 2918 inx ; pointer to format param |
||
371 | 2919 stx pparams ; pointer to top + 1 of variables param's |
||
372 | 2920 adc #npars |
||
373 | Tue Jul 17 11:00:21 2018 Page 7 |
||
374 | |||
375 | |||
376 | |||
377 | |||
378 | 2921 sta mvto ; pointer to dest. frame stack to move |
||
379 | 2922 |
||
380 | 2923 ; ACC 08 |
||
381 | 2924 sep #PMFLAG |
||
382 | 2925 .LONGA off |
||
383 | 2926 |
||
384 | 2927 lda #0 |
||
385 | 2928 pha |
||
386 | 2929 phb ; DBR => bank 0 |
||
387 | 2930 ldy .ABS.FMTPARAM,x |
||
388 | 2931 sty lpfmt |
||
389 | 2932 lda .ABS.FMTPARAM+2,x |
||
390 | 2933 sta lpfmt+2 |
||
391 | 2934 |
||
392 | 2935 .MNLIST |
||
393 | 2936 .ENDM |
||
394 | 2937 |
||
395 | 2938 |
||
396 | 2939 .CODEFA |
||
397 | 2940 |
||
398 | 2941 ; cprintf(format, ..., count) |
||
399 | 2942 FA07EB _cprintf: |
||
400 | 2943 |
||
401 | 2944 ; prologue code (leave index 16 bit) |
||
402 | 2945 FA07EB prologue 3 |
||
403 | 2946 .LONGA off |
||
404 | 2947 .LONGI off |
||
405 | 2948 |
||
406 | 2949 FA07EB 08 php ; save status |
||
407 | 2950 FA07EC 8B phb ; save DBR |
||
408 | 2951 FA07ED 0B phd ; save DPR |
||
409 | 2952 |
||
410 | 2953 ; CPU 16 + CLC |
||
411 | 2954 FA07EE C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
412 | 2955 .LONGA on |
||
413 | 2956 .LONGI on |
||
414 | 2957 |
||
415 | 2958 FA07F0 48 pha ; save A |
||
416 | 2959 FA07F1 DA phx ; save X |
||
417 | 2960 FA07F2 5A phy ; save Y |
||
418 | 2961 FA07F3 BA tsx |
||
419 | 2962 FA07F4 8A txa ; A = old frame stack |
||
420 | 2963 ;sbc #NLOCALS-1 |
||
421 | 2964 FA07F5 E9 1B 00 sbc #LOCALSIZE-1 |
||
422 | 2965 FA07F8 1B tcs ; new stack pointer |
||
423 | 2966 FA07F9 1A inc a |
||
424 | 2967 FA07FA 5B tcd ; DPR point to locals base |
||
425 | 2968 FA07FB 8A txa |
||
426 | 2969 FA07FC 18 clc |
||
427 | 2970 FA07FD 69 0D 00 adc #PUSHED |
||
428 | 2971 FA0800 85 00 sta mvfrom ; pointer to source frame stack to move |
||
429 | 2972 FA0802 1A inc a |
||
430 | 2973 FA0803 1A inc a ; pointer to top of count param (countH) |
||
431 | 2974 FA0804 63 4E adc COUNTOFS,s ; add size of variables param's |
||
432 | 2975 FA0806 AA tax |
||
433 | 2976 FA0807 E8 inx ; pointer to format param |
||
434 | 2977 FA0808 86 04 stx pparams ; pointer to top + 1 of variables param's |
||
435 | Tue Jul 17 11:00:21 2018 Page 8 |
||
436 | |||
437 | |||
438 | |||
439 | |||
440 | 2978 FA080A 69 03 00 adc #3 |
||
441 | 2979 FA080D 85 02 sta mvto ; pointer to dest. frame stack to move |
||
442 | 2980 FA080F |
||
443 | 2981 ; ACC 08 |
||
444 | 2982 FA080F E2 20 sep #PMFLAG |
||
445 | 2983 .LONGA off |
||
446 | 2984 |
||
447 | 2985 FA0811 A9 00 lda #0 |
||
448 | 2986 FA0813 48 pha |
||
449 | 2987 FA0814 8B phb ; DBR => bank 0 |
||
450 | 2988 FA0815 BC 00 00 ldy .ABS.FMTPARAM,x |
||
451 | 2989 FA0818 84 08 sty lpfmt |
||
452 | 2990 FA081A BD 02 00 lda .ABS.FMTPARAM+2,x |
||
453 | 2991 FA081D 85 0A sta lpfmt+2 |
||
454 | 2992 |
||
455 | 2993 .MNLIST |
||
456 | 2994 .LONGI on |
||
457 | 2995 FA081F |
||
458 | 2996 FA081F CPU08 |
||
459 | 2997 FA081F E2 30 sep #(PMFLAG.OR.PXFLAG) |
||
460 | 2998 .LONGA off |
||
461 | 2999 .LONGI off |
||
462 | 3000 .MNLIST |
||
463 | 3001 FA0821 |
||
464 | 3002 ; epilogue |
||
465 | 3003 FA0821 epilogue: |
||
466 | 3004 FA0821 CPU16CLC |
||
467 | 3005 FA0821 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
468 | 3006 .LONGA on |
||
469 | 3007 .LONGI on |
||
470 | 3008 .MNLIST |
||
471 | 3009 FA0823 A6 00 ldx mvfrom ; source pointer for data move |
||
472 | 3010 FA0825 A4 02 ldy mvto ; dest pointer for data move |
||
473 | 3011 FA0827 A9 0C 00 lda #PUSHED-1 ; move bytes count - 1 |
||
474 | 3012 FA082A 44 00 00 mvp #0, #0 ; cleanup stack |
||
475 | 3013 FA082D 98 tya ; new stack pointer |
||
476 | 3014 FA082E 1B tcs |
||
477 | 3015 FA082F 7A ply ; restore registers |
||
478 | 3016 FA0830 FA plx |
||
479 | 3017 FA0831 68 pla |
||
480 | 3018 FA0832 2B pld |
||
481 | 3019 FA0833 AB plb |
||
482 | 3020 FA0834 28 plp |
||
483 | 3021 FA0835 6B rtl |
||
484 | 3022 |
||
485 | 3023 ; common formattation routine |
||
486 | 3024 FA0836 _vprinter: |
||
487 | 3025 .LONGA off |
||
488 | 3026 .LONGI off |
||
489 | 3027 |
||
490 | 3028 FA0836 A0 00 ldy #0 |
||
491 | 3029 FA0838 INDEX16 |
||
492 | 3030 FA0838 C2 10 rep #PXFLAG |
||
493 | 3031 .LONGI on |
||
494 | 3032 .MNLIST |
||
495 | 3033 |
||
496 | 3034 ; parse format string |
||
497 | Tue Jul 17 11:00:21 2018 Page 9 |
||
498 | |||
499 | |||
500 | |||
501 | |||
502 | 3035 FA083A B7 08 ?nxt: lda [lpfmt],y ; get next char from format string |
||
503 | 3036 FA083C D0 03 bne $+5 |
||
504 | 3037 ;beq ?done ; end of format string (?60) |
||
505 | 3038 FA083E 4C C3 08 jmp ?done ; end of format string (?60) |
||
506 | 3039 FA0841 C9 25 cmp #'%' |
||
507 | 3040 FA0843 F0 06 beq ?nxt1 ; found specifier |
||
508 | 3041 FA0845 20 D6 08 ?put: jsr _store ; put character "as is" |
||
509 | 3042 FA0848 C8 iny ; bump pointer |
||
510 | 3043 FA0849 80 EF bra ?nxt ; continue parsing |
||
511 | 3044 FA084B 84 06 ?nxt1: sty fmtidx ; save index to '%' char |
||
512 | 3045 FA084D C8 iny |
||
513 | 3046 FA084E B7 08 lda [lpfmt],y ; get next char after specifier |
||
514 | 3047 FA0850 C9 25 cmp #'%' |
||
515 | 3048 FA0852 F0 F1 beq ?put ; put literal '%' and continue |
||
516 | 3049 FA0854 |
||
517 | 3050 ; check format after specifier '%' |
||
518 | 3051 FA0854 A9 00 lda #0 ; A = stage = 0 (current stage) |
||
519 | 3052 FA0856 85 18 sta fmtsgn ; clear working var's |
||
520 | 3053 FA0858 85 14 sta fmtflag |
||
521 | 3054 FA085A 85 15 sta fmtmod |
||
522 | 3055 FA085C 85 16 sta fmtwidth |
||
523 | 3056 FA085E 85 17 sta fmtprec |
||
524 | 3057 FA0860 80 01 bra ?lpf1 ; reload current char |
||
525 | 3058 FA0862 |
||
526 | 3059 FA0862 C8 ?lpf: iny ; loop format parsing |
||
527 | 3060 FA0863 EB ?lpf1: xba ; B = stage |
||
528 | 3061 FA0864 B7 08 lda [lpfmt],y ; A = next char after specifier '%' |
||
529 | 3062 FA0866 F0 4F beq ?err ; end of format string: abandon (?50) |
||
530 | 3063 FA0868 85 19 sta fbtmp ; save char |
||
531 | 3064 FA086A 38 sec |
||
532 | 3065 FA086B E9 20 sbc #' ' ; scale char to 0..5F |
||
533 | 3066 FA086D 90 48 bcc ?err ; illegal char at this stage |
||
534 | 3067 FA086F C9 60 cmp #(128 - ' ') |
||
535 | 3068 FA0871 B0 44 bcs ?err ; illegal char at this stage |
||
536 | 3069 FA0873 84 06 sty fmtidx ; save current index |
||
537 | 3070 FA0875 CPU08 ; all registers 8 bit |
||
538 | 3071 FA0875 E2 30 sep #(PMFLAG.OR.PXFLAG) |
||
539 | 3072 .LONGA off |
||
540 | 3073 .LONGI off |
||
541 | 3074 .MNLIST |
||
542 | 3075 FA0877 AA tax ; X = 0..5F |
||
543 | 3076 FA0878 BF 92 0A FA lda >CLASSCHR,x ; A = class char lookup |
||
544 | 3077 FA087C 0A asl a |
||
545 | 3078 FA087D AA tax ; function index |
||
546 | 3079 FA087E A5 19 lda fbtmp ; A = current char |
||
547 | 3080 FA0880 EB xba ; B = current char, A = current stage |
||
548 | 3081 ; ZF = 1 if current stage = 0 |
||
549 | 3082 FA0881 FC F2 0A jsr (CHKTBL,x) ; check format specifier at this stage |
||
550 | 3083 FA0884 INDEX16 ; X/Y => 16 bits |
||
551 | 3084 FA0884 C2 10 rep #PXFLAG |
||
552 | 3085 .LONGI on |
||
553 | 3086 .MNLIST |
||
554 | 3087 FA0886 A4 06 ldy fmtidx ; Y = index to format string |
||
555 | 3088 FA0888 B0 2D bcs ?err ; format error - abandon |
||
556 | 3089 FA088A 50 D6 bvc ?lpf ; continue format parsing |
||
557 | 3090 FA088C |
||
558 | 3091 ; at this point the format specifier was recognized and we assume |
||
559 | Tue Jul 17 11:00:21 2018 Page 10 |
||
560 | |||
561 | |||
562 | |||
563 | |||
564 | 3092 ; that was parsed correctly and X hold the index to the right |
||
565 | 3093 ; function that get parameter(s) from stack and convert in string. |
||
566 | 3094 ; If the conversion function use fpu emulator we save the direct-page |
||
567 | 3095 ; used by fp emulator to a local page in stack (for reentrancy) |
||
568 | 3096 FA088C E0 04 00 cpx #T_PTR ; use fpu emulator? |
||
569 | 3097 FA088F 90 1A bcc ?cvt ; no |
||
570 | 3098 FA0891 24 1B bit fpuuse ; already saved fpu direct-page? |
||
571 | 3099 FA0893 30 16 bmi ?cvt ; yes |
||
572 | 3100 FA0895 DA phx ; save conversion function index |
||
573 | 3101 FA0896 CPU16CLC |
||
574 | 3102 FA0896 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG) |
||
575 | 3103 .LONGA on |
||
576 | 3104 .LONGI on |
||
577 | 3105 .MNLIST |
||
578 | 3106 FA0898 3B tsc |
||
579 | 3107 FA0899 E9 FF 00 sbc #255 ; make room for 256 bytes |
||
580 | 3108 FA089C 1B tcs |
||
581 | 3109 FA089D 1A inc a ; pointer to local |
||
582 | 3110 FA089E 85 12 sta fpusave |
||
583 | 3111 FA08A0 A8 tay ; destination for move |
||
584 | 3112 FA08A1 A2 00 3F ldx #P0FPU ; source page for move |
||
585 | 3113 FA08A4 A9 FF 00 lda #255 ; move 256 bytes |
||
586 | 3114 FA08A7 54 00 00 mvn #0, #0 ; move in bank 0 |
||
587 | 3115 FA08AA FA plx ; restore function index |
||
588 | 3116 FA08AB |
||
589 | 3117 FA08AB ?cvt: CPU08 |
||
590 | 3118 FA08AB E2 30 sep #(PMFLAG.OR.PXFLAG) |
||
591 | 3119 .LONGA off |
||
592 | 3120 .LONGI off |
||
593 | 3121 .MNLIST |
||
594 | 3122 FA08AD FC 32 0B jsr (CVTTBL,x) ; call conversion function |
||
595 | 3123 FA08B0 INDEX16 |
||
596 | 3124 FA08B0 C2 10 rep #PXFLAG |
||
597 | 3125 .LONGI on |
||
598 | 3126 .MNLIST |
||
599 | 3127 FA08B2 A4 06 ldy fmtidx ; Y = index to format string |
||
600 | 3128 FA08B4 C8 iny ; bump pointer |
||
601 | 3129 FA08B5 80 83 bra ?nxt ; parse next char |
||
602 | 3130 |
||
603 | 3131 ; ABANDON - causa errore specificatore di formato si suppone che i |
||
604 | 3132 ; parametri non siano piu' allineati con il formato |
||
605 | 3133 ; viene quindi copiato letteralmente il resto di szFmt a partire |
||
606 | 3134 ; dal carattere '%' dove si e' verificato il disallineamento, fino |
||
607 | 3135 ; alla fine della stringa szFmt |
||
608 | 3136 FA08B7 A4 06 ?err: ldy fmtidx ; indice al carattere '%' |
||
609 | 3137 FA08B9 B7 08 ?err1: lda [lpfmt],y ; copia da szFmt a szDst |
||
610 | 3138 FA08BB F0 06 beq ?done ; fino a fine stringa |
||
611 | 3139 FA08BD C8 iny |
||
612 | 3140 FA08BE 20 D6 08 jsr _store |
||
613 | 3141 FA08C1 80 F6 bra ?err1 |
||
614 | 3142 |
||
615 | 3143 FA08C3 24 1B ?done: bit fpuuse |
||
616 | 3144 FA08C5 10 0F bpl ?end |
||
617 | 3145 FA08C7 CPU16 |
||
618 | 3146 FA08C7 C2 30 rep #(PMFLAG.OR.PXFLAG) |
||
619 | 3147 .LONGA on |
||
620 | 3148 .LONGI on |
||
621 | Tue Jul 17 11:00:21 2018 Page 11 |
||
622 | |||
623 | |||
624 | |||
625 | |||
626 | 3149 .MNLIST |
||
627 | 3150 FA08C9 A6 12 ldx fpusave ; source of move |
||
628 | 3151 FA08CB A0 00 3F ldy #P0FPU |
||
629 | 3152 FA08CE A9 FF 00 lda #255 |
||
630 | 3153 FA08D1 54 00 00 mvn #0, #0 ; move in bank 0 |
||
631 | 3154 FA08D4 CPU08 |
||
632 | 3155 FA08D4 E2 30 sep #(PMFLAG.OR.PXFLAG) |
||
633 | 3156 .LONGA off |
||
634 | 3157 .LONGI off |
||
635 | 3158 .MNLIST |
||
636 | 3159 |
||
637 | 3160 FA08D6 ?end: |
||
638 | 3161 |
||
639 | 3162 FA08D6 _store: |
||
640 | 3163 FA08D6 putter: |
||
641 | 3164 FA08D6 A4 0E ldy dsize |
||
642 | 3165 FA08D8 24 10 bit putopts |
||
643 | 3166 FA08DA 10 08 bpl ?put ; put to file/stream |
||
644 | 3167 FA08DC 50 13 bvc ?inc ; not store this byte in dest. string |
||
645 | 3168 FA08DE C4 0E cpy dsize ; exceed dest. string size? |
||
646 | 3169 FA08E0 B0 12 bcs ?done ; yes => no store, no increment counter |
||
647 | 3170 FA08E2 80 0B bra ?sto ; store char in string |
||
648 | 3171 FA08E4 C4 0E ?put: cpy dsize ; local buffer is full? |
||
649 | 3172 FA08E6 90 07 bcc ?sto ; no, store char in local buffer |
||
650 | 3173 FA08E8 85 19 sta fbtmp ; save current char |
||
651 | 3174 FA08EA 20 F5 08 jsr lflush ; flush local buffer |
||
652 | 3175 FA08ED A5 19 lda fbtmp ; restore current char |
||
653 | 3176 FA08EF 97 0B ?sto: sta [lpdest],y ; store char in local buffer |
||
654 | 3177 FA08F1 C8 ?inc: iny ; incremet counter |
||
655 | 3178 FA08F2 84 0E sty dsize ; save current size of buffer |
||
656 | 3179 FA08F4 60 ?done: rts |
||
657 | 3180 |
||
658 | 3181 ; flush local buffer |
||
659 | 3182 FA08F5 lflush: |
||
660 | 3183 FA08F5 A9 00 lda #0 |
||
661 | 3184 FA08F7 97 0B sta [lpdest],y ; terminate local buffer |
||
662 | 3185 FA08F9 BB tyx |
||
663 | 3186 FA08FA F0 0A beq ?done ; empty buffer |
||
664 | 3187 FA08FC A5 0C lda lpdest+1 ; C = buffer address |
||
665 | 3188 FA08FE EB xba |
||
666 | 3189 FA08FF A5 0B lda lpdest |
||
667 | 3190 FA0901 A2 00 ldx #0 ; bank 0 |
||
668 | 3191 FA0903 9B txy |
||
669 | 3192 FA0904 TXTSTROUT ; preserve A,X,Y |
||
670 | 3193 FA0904 02 04 cop $04 |
||
671 | 3194 .MNLIST |
||
672 | 3195 FA0906 60 ?done: rts |
||
673 | 3196 |
||
674 | 3197 ;--------------------------------------------------------------------------- |
||
675 | 3198 ; specifier format parsing/checking - funtions that checks type and modifiers |
||
676 | 3199 ; |
||
677 | 3200 ; In - B = parsed char, A = current stage |
||
678 | 3201 ; - ZF = 1 if current stage = 0 |
||
679 | 3202 ; |
||
680 | 3203 ; Out - CF = 1 => error, unknow type or modifier not allowed |
||
681 | 3204 ; CF = 0, VF = 1, X = conversion function index => end current parsing |
||
682 | 3205 ; CF = 0, VF = 0 => continue parsing |
||
683 | Tue Jul 17 11:00:21 2018 Page 12 |
||
684 | |||
685 | |||
686 | |||
687 | |||
688 | 3206 ;--------------------------------------------------------------------------- |
||
689 | 3207 |
||
690 | 3208 .LONGA off |
||
691 | 3209 .LONGI off |
||
692 | 3210 |
||
693 | 3211 ; case ' ' or '+' -- only valid while stage = 0 |
||
694 | 3212 FA0907 case_si: |
||
695 | 3213 FA0907 D0 64 bne case_dc ; error: not in stage = 0 |
||
696 | 3214 FA0909 A6 18 ldx fmtsgn |
||
697 | 3215 FA090B E0 2B cpx #'+' |
||
698 | 3216 FA090D F0 04 beq case_cont ; ignore ' ' if '+' already specified |
||
699 | 3217 FA090F EB xba ; A = current char - B = stage |
||
700 | 3218 FA0910 85 18 sta fmtsgn ; store sign byte |
||
701 | 3219 FA0912 EB xba ; A = stage |
||
702 | 3220 FA0913 case_cont: |
||
703 | 3221 FA0913 18 clc ; OK |
||
704 | 3222 FA0914 B8 clv ; continue parsing |
||
705 | 3223 FA0915 60 rts |
||
706 | 3224 |
||
707 | 3225 ; case digit '0' - meaning depend on current stage |
||
708 | 3226 ; if stage = 0: left padding with digit '0' instead of blank ' ' |
||
709 | 3227 ; if stage > 0 then '0' is a digit of [width] or [precision] filkeds |
||
710 | 3228 FA0916 case_fz: |
||
711 | 3229 FA0916 D0 57 bne case_nu ; stage > 0 => handle width/precision |
||
712 | 3230 FA0918 AA tax ; X = stage |
||
713 | 3231 FA0919 A9 40 lda #F_LEFTJ |
||
714 | 3232 FA091B 24 14 bit fmtflag ; ignore padding with '0'... |
||
715 | 3233 FA091D F0 03 beq ?skp ; ... if not right just. |
||
716 | 3234 FA091F 8A txa ; A = stage |
||
717 | 3235 FA0920 D0 F1 bne case_cont ; continue parsing |
||
718 | 3236 FA0922 A9 20 ?skp: lda #F_FILLZ ; padding with '0' |
||
719 | 3237 FA0924 E8 inx ; X = 1 -> FILLZSTAGE |
||
720 | 3238 FA0925 80 0C bra setflag ; after should follow width stage |
||
721 | 3239 |
||
722 | 3240 ; case '-' -- only valid while stage = 0 |
||
723 | 3241 FA0927 case_lj: |
||
724 | 3242 FA0927 D0 44 bne case_dc ; stop parsing |
||
725 | 3243 FA0929 AA tax ; X = stage |
||
726 | 3244 FA092A A9 40 lda #F_LEFTJ ; set left justify bit |
||
727 | 3245 FA092C 80 05 bra setflag |
||
728 | 3246 FA092E |
||
729 | 3247 ; case '#' -- only valid while stage = 0 |
||
730 | 3248 FA092E case_af: |
||
731 | 3249 FA092E D0 3D bne case_dc ; stop parsing |
||
732 | 3250 FA0930 AA tax ; X = stage |
||
733 | 3251 FA0931 A9 80 lda #F_ALTFMT ; alternate format bit |
||
734 | 3252 |
||
735 | 3253 ; set current parsed flags |
||
736 | 3254 FA0933 setflag: |
||
737 | 3255 FA0933 04 14 tsb fmtflag |
||
738 | 3256 FA0935 8A txa ; A = stage |
||
739 | 3257 FA0936 18 clc ; OK |
||
740 | 3258 FA0937 B8 clv ; continue parsing |
||
741 | 3259 FA0938 60 rts |
||
742 | 3260 |
||
743 | 3261 ; case ',' -- only valid while stage = 0 |
||
744 | 3262 FA0939 case_tg: |
||
745 | Tue Jul 17 11:00:21 2018 Page 13 |
||
746 | |||
747 | |||
748 | |||
749 | |||
750 | 3263 FA0939 D0 32 bne case_dc ; stop parsing |
||
751 | 3264 FA093B AA tax ; X = stage |
||
752 | 3265 FA093C A9 10 lda #F_GROUP ; set group thousand bit |
||
753 | 3266 FA093E 80 F3 bra setflag |
||
754 | 3267 FA0940 |
||
755 | 3268 ; case '*' -- [width] or [precision] field passed by argument |
||
756 | 3269 FA0940 case_ar: |
||
757 | 3270 FA0940 EB xba ; save stage |
||
758 | 3271 FA0941 INDEX16 |
||
759 | 3272 FA0941 C2 10 rep #PXFLAG |
||
760 | 3273 .LONGI on |
||
761 | 3274 .MNLIST |
||
762 | 3275 FA0943 A6 04 ldx pparams ; get byte parameter |
||
763 | 3276 FA0945 CA dex ; align to next byte param |
||
764 | 3277 FA0946 BD 00 00 lda .ABS.FMTPARAM,x |
||
765 | 3278 FA0949 86 04 stx pparams |
||
766 | 3279 FA094B INDEX08 |
||
767 | 3280 FA094B E2 10 sep #PXFLAG |
||
768 | 3281 .LONGI off |
||
769 | 3282 .MNLIST |
||
770 | 3283 FA094D AA tax ; X = param |
||
771 | 3284 FA094E EB xba ; A = stage |
||
772 | 3285 FA094F C9 02 cmp #WIDESTAGE |
||
773 | 3286 FA0951 B0 0B bcs ?nxt ; WIDESTAGE or above stage |
||
774 | 3287 FA0953 86 16 stx fmtwidth ; store width |
||
775 | 3288 FA0955 A9 08 lda #F_WIDTH |
||
776 | 3289 FA0957 04 14 tsb fmtflag ; set 'width' bit |
||
777 | 3290 FA0959 A9 03 lda #DOTSTAGE ; expected next stage: [.precision] |
||
778 | 3291 FA095B 18 clc ; OK |
||
779 | 3292 FA095C B8 clv ; continue parsing |
||
780 | 3293 FA095D 60 rts |
||
781 | 3294 FA095E C9 04 ?nxt: cmp #PRECSTAGE |
||
782 | 3295 FA0960 D0 0B bne case_dc ; discard: unexpected stage level |
||
783 | 3296 FA0962 86 17 stx fmtprec ; store precision |
||
784 | 3297 FA0964 AA tax ; X = stage |
||
785 | 3298 FA0965 A9 04 lda #F_PREC |
||
786 | 3299 FA0967 04 14 tsb fmtflag ; set 'precision' bit |
||
787 | 3300 FA0969 8A txa ; A = stage: keep current stage |
||
788 | 3301 FA096A 18 clc ; OK |
||
789 | 3302 FA096B B8 clv ; continue parsing |
||
790 | 3303 FA096C 60 rts |
||
791 | 3304 FA096D |
||
792 | 3305 ; unknow chracter was parsed - sjip |
||
793 | 3306 FA096D case_dc: |
||
794 | 3307 FA096D 38 sec ; error flag |
||
795 | 3308 FA096E 60 rts |
||
796 | 3309 |
||
797 | 3310 ; case '0'..'9' - digit tht are part of [width] or [precision] |
||
798 | 3311 ; fmtwidth and fmtprec are set to zero before enter parsing routine |
||
799 | 3312 FA096F case_nu: |
||
800 | 3313 FA096F AA tax ; X = stage |
||
801 | 3314 FA0970 EB xba ; A = char '0'..'9' |
||
802 | 3315 FA0971 38 sec |
||
803 | 3316 FA0972 E9 30 sbc #'0' ; scale to 0..9 |
||
804 | 3317 FA0974 E0 03 cpx #WIDESTAGE+1 ; part of [width] field ? |
||
805 | 3318 FA0976 B0 25 bcs ?nxt ; no |
||
806 | 3319 FA0978 AA tax ; X = number 0..9 |
||
807 | Tue Jul 17 11:00:21 2018 Page 14 |
||
808 | |||
809 | |||
810 | |||
811 | |||
812 | 3320 FA0979 A5 16 lda fmtwidth |
||
813 | 3321 FA097B 86 16 stx fmtwidth |
||
814 | 3322 FA097D F0 15 beq ?z ; old width = 0 |
||
815 | 3323 FA097F 0A asl a ; width * 2 |
||
816 | 3324 FA0980 B0 3E bcs ?err ; overflow |
||
817 | 3325 FA0982 85 19 sta fbtmp |
||
818 | 3326 FA0984 0A asl a |
||
819 | 3327 FA0985 B0 39 bcs ?err ; overflow |
||
820 | 3328 FA0987 0A asl a ; width * 8 |
||
821 | 3329 FA0988 B0 36 bcs ?err ; overflow |
||
822 | 3330 FA098A 65 19 adc fbtmp ; width * 10 |
||
823 | 3331 FA098C B0 32 bcs ?err ; overflow |
||
824 | 3332 FA098E 65 16 adc fmtwidth ; (width * 10) + number |
||
825 | 3333 FA0990 B0 2E bcs ?err ; overflow |
||
826 | 3334 FA0992 85 16 sta fmtwidth |
||
827 | 3335 FA0994 A9 08 ?z: lda #F_WIDTH |
||
828 | 3336 FA0996 04 14 tsb fmtflag ; set 'width' bit |
||
829 | 3337 FA0998 A9 02 lda #WIDESTAGE ; set current stage: 'width' |
||
830 | 3338 FA099A 18 clc ; OK |
||
831 | 3339 FA099B B8 clv ; continue parsing |
||
832 | 3340 FA099C 60 rts |
||
833 | 3341 FA099D E0 04 ?nxt: cpx #PRECSTAGE ; precision stage ? |
||
834 | 3342 FA099F D0 CC bne case_dc ; no -- skip |
||
835 | 3343 FA09A1 AA tax ; X = number 0..9 |
||
836 | 3344 FA09A2 A5 17 lda fmtprec |
||
837 | 3345 FA09A4 86 17 stx fmtprec |
||
838 | 3346 FA09A6 F0 15 beq ?z1 ; old prec = 0 |
||
839 | 3347 FA09A8 0A asl a ; prec * 2 |
||
840 | 3348 FA09A9 B0 15 bcs ?err ; overflow |
||
841 | 3349 FA09AB 85 19 sta fbtmp |
||
842 | 3350 FA09AD 0A asl a |
||
843 | 3351 FA09AE B0 10 bcs ?err ; overflow |
||
844 | 3352 FA09B0 0A asl a ; prec * 8 |
||
845 | 3353 FA09B1 B0 0D bcs ?err ; overflow |
||
846 | 3354 FA09B3 65 19 adc fbtmp ; prec * 10 |
||
847 | 3355 FA09B5 B0 09 bcs ?err ; overflow |
||
848 | 3356 FA09B7 65 17 adc fmtprec ; (prec * 10) + number |
||
849 | 3357 FA09B9 B0 05 bcs ?err ; overflow |
||
850 | 3358 FA09BB 85 17 sta fmtprec |
||
851 | 3359 FA09BD EB ?z1: xba ; keep current stage |
||
852 | 3360 FA09BE 18 clc ; OK |
||
853 | 3361 FA09BF B8 clv ; continue prsing |
||
854 | 3362 FA09C0 60 ?err: rts |
||
855 | 3363 |
||
856 | 3364 ; case '.' -- only valid if current stage < PRECSTAGE |
||
857 | 3365 FA09C1 case_pr: |
||
858 | 3366 FA09C1 C9 04 cmp #PRECSTAGE |
||
859 | 3367 FA09C3 B0 08 bcs ?err ; skip |
||
860 | 3368 FA09C5 A9 04 lda #F_PREC |
||
861 | 3369 FA09C7 04 14 tsb fmtflag ; set 'precision' bit |
||
862 | 3370 FA09C9 A9 04 lda #PRECSTAGE ; set current stage |
||
863 | 3371 FA09CB 18 clc ; OK |
||
864 | 3372 FA09CC B8 clv ; continue parsing |
||
865 | 3373 FA09CD 60 ?err: rts |
||
866 | 3374 |
||
867 | 3375 ;============================================================================ |
||
868 | 3376 ; modificatori -- impostano lo stato MODSTAGE (dopo sono ammessi solo i tipi) |
||
869 | Tue Jul 17 11:00:21 2018 Page 15 |
||
870 | |||
871 | |||
872 | |||
873 | |||
874 | 3377 |
||
875 | 3378 ; case 'l' -- 'long' modifier (64 bit integer) |
||
876 | 3379 FA09CE case_lo: |
||
877 | 3380 FA09CE A2 20 ldx #F2_LONG |
||
878 | 3381 FA09D0 80 0E bra setmod |
||
879 | 3382 |
||
880 | 3383 ; case 'h' -- 'short' modifier (16 bit integer) |
||
881 | 3384 FA09D2 case_sh: |
||
882 | 3385 FA09D2 A2 10 ldx #F2_SHORT |
||
883 | 3386 FA09D4 80 0A bra setmod |
||
884 | 3387 |
||
885 | 3388 ; case 'b' -- 'byte' modifier (8 bit integer) |
||
886 | 3389 FA09D6 case_SH: |
||
887 | 3390 FA09D6 A2 08 ldx #F2_BYTE |
||
888 | 3391 FA09D8 80 06 bra setmod |
||
889 | 3392 |
||
890 | 3393 ; case 'L' -- 'long long' modifier (128 bit integer) |
||
891 | 3394 FA09DA case_ll: |
||
892 | 3395 FA09DA A2 40 ldx #F2_LONGLONG |
||
893 | 3396 FA09DC 80 02 bra setmod |
||
894 | 3397 FA09DE |
||
895 | 3398 ; case 'B' -- 'pascal/basic' string modifier |
||
896 | 3399 FA09DE case_PS: |
||
897 | 3400 FA09DE A2 80 ldx #F2_PSSTRING |
||
898 | 3401 |
||
899 | 3402 FA09E0 setmod: |
||
900 | 3403 FA09E0 C9 05 cmp #MODSTAGE |
||
901 | 3404 FA09E2 B0 07 bcs ?err ; skip |
||
902 | 3405 FA09E4 8A txa |
||
903 | 3406 FA09E5 04 15 tsb fmtmod |
||
904 | 3407 FA09E7 A9 05 lda #MODSTAGE ; set final stage |
||
905 | 3408 FA09E9 18 clc ; OK |
||
906 | 3409 FA09EA B8 clv ; continue parsing |
||
907 | 3410 FA09EB 60 ?err: rts |
||
908 | 3411 |
||
909 | 3412 ;--------------------------------------------------------------------------- |
||
910 | 3413 ; specifier format checking -- these funtions checks type and modifiers |
||
911 | 3414 ; flags in status register are set according check result: |
||
912 | 3415 ; |
||
913 | 3416 ; CF = 1 => error, modifier not allowed |
||
914 | 3417 ; CF = 0, VF = 1 => ok -- X = conversion function index |
||
915 | 3418 ;--------------------------------------------------------------------------- |
||
916 | 3419 FA09EC |
||
917 | 3420 ; case 'X' -- type unsigned integer hexadecimal upper case digits |
||
918 | 3421 FA09EC case_HE: |
||
919 | 3422 FA09EC A9 04 lda #F2_CAPS ; set CAPS bit |
||
920 | 3423 FA09EE 04 15 tsb fmtmod |
||
921 | 3424 FA09F0 |
||
922 | 3425 ; case 'x' -- type unsigned integer hexadecimal upper case digits |
||
923 | 3426 FA09F0 case_he: |
||
924 | 3427 FA09F0 A9 01 lda #F2_SIGNED |
||
925 | 3428 FA09F2 14 15 trb fmtmod ; clear signed bit |
||
926 | 3429 FA09F4 A5 14 lda fmtflag |
||
927 | 3430 FA09F6 89 04 bit #F_PREC |
||
928 | 3431 FA09F8 F0 04 beq ?skp |
||
929 | 3432 FA09FA A9 20 lda #F_FILLZ ; ignore left '0' padding... |
||
930 | 3433 FA09FC 14 14 trb fmtflag ; ...if specified 'precision' |
||
931 | Tue Jul 17 11:00:21 2018 Page 16 |
||
932 | |||
933 | |||
934 | |||
935 | |||
936 | 3434 FA09FE A2 08 ?skp: ldx #T_HEX ; conversion function index |
||
937 | 3435 FA0A00 A9 80 lda #MASKINTG ; not allowed modifiers for integers |
||
938 | 3436 FA0A02 80 72 bra case_end |
||
939 | 3437 |
||
940 | 3438 ; case 'd', 'i' -- type decimal signed integer |
||
941 | 3439 FA0A04 case_de: |
||
942 | 3440 FA0A04 A9 01 lda #F2_SIGNED |
||
943 | 3441 FA0A06 04 15 tsb fmtmod ; set signed bit |
||
944 | 3442 FA0A08 80 04 bra case_i ; common code for decimal integers |
||
945 | 3443 |
||
946 | 3444 ; case 'u' -- type decimal unsigned integer |
||
947 | 3445 FA0A0A case_un: |
||
948 | 3446 FA0A0A A9 01 lda #F2_SIGNED |
||
949 | 3447 FA0A0C 14 15 trb fmtmod ; clear signed bit |
||
950 | 3448 |
||
951 | 3449 ; common code for decimal integers |
||
952 | 3450 FA0A0E case_i: |
||
953 | 3451 FA0A0E A5 14 lda fmtflag |
||
954 | 3452 FA0A10 89 04 bit #F_PREC |
||
955 | 3453 FA0A12 F0 04 beq ?skp |
||
956 | 3454 FA0A14 A9 20 lda #F_FILLZ ; ignore left '0' padding... |
||
957 | 3455 FA0A16 14 14 trb fmtflag ; ...if specified 'precision' |
||
958 | 3456 FA0A18 A9 80 ?skp: lda #F_ALTFMT |
||
959 | 3457 FA0A1A 14 14 trb fmtflag ; ignore alternate format |
||
960 | 3458 FA0A1C A2 06 ldx #T_INT ; conversion function index |
||
961 | 3459 FA0A1E A9 80 lda #MASKINTG ; not allowed modifiers for integers |
||
962 | 3460 FA0A20 80 54 bra case_end |
||
963 | 3461 |
||
964 | 3462 ; case 'c' -- type char |
||
965 | 3463 FA0A22 case_ch: |
||
966 | 3464 FA0A22 A9 84 lda #(F_ALTFMT.OR.F_PREC) ; ignore precision and alternate format |
||
967 | 3465 FA0A24 14 14 trb fmtflag |
||
968 | 3466 FA0A26 A2 00 ldx #T_CHAR ; conversion function index |
||
969 | 3467 FA0A28 A9 F8 lda #MASKCHAR ; not allowed modifiers for chars |
||
970 | 3468 FA0A2A 80 4A bra case_end |
||
971 | 3469 FA0A2C |
||
972 | 3470 ; case 's' -- type string |
||
973 | 3471 FA0A2C case_st: |
||
974 | 3472 FA0A2C A9 80 lda #F_ALTFMT ; ignore alternate format |
||
975 | 3473 FA0A2E 14 14 trb fmtflag |
||
976 | 3474 FA0A30 A2 02 ldx #T_STR ; conversion function index |
||
977 | 3475 FA0A32 A9 78 lda #MASKSTR ; not allowed modifiers for strings |
||
978 | 3476 FA0A34 80 40 bra case_end |
||
979 | 3477 |
||
980 | 3478 ; case 'E' -- type float exponential format (upper case 'E') |
||
981 | 3479 FA0A36 case_FE: |
||
982 | 3480 FA0A36 A9 45 lda #'E' ; format 'E' |
||
983 | 3481 FA0A38 80 32 bra case_f |
||
984 | 3482 |
||
985 | 3483 ; case 'e' -- type float exponential format (lower case 'e') |
||
986 | 3484 FA0A3A case_fe: |
||
987 | 3485 FA0A3A A9 65 lda #'e' ; format 'e' |
||
988 | 3486 FA0A3C 80 2E bra case_f |
||
989 | 3487 FA0A3E |
||
990 | 3488 ; case 'G' -- type float format 'G' |
||
991 | 3489 FA0A3E case_FG: |
||
992 | 3490 FA0A3E A9 47 lda #'G' ; format 'G' |
||
993 | Tue Jul 17 11:00:21 2018 Page 17 |
||
994 | |||
995 | |||
996 | |||
997 | |||
998 | 3491 FA0A40 80 2A bra case_f |
||
999 | 3492 |
||
1000 | 3493 ; case 'g' -- type float format 'g' |
||
1001 | 3494 FA0A42 case_fg: |
||
1002 | 3495 FA0A42 A9 67 lda #'g' ; format 'g' |
||
1003 | 3496 FA0A44 80 26 bra case_f |
||
1004 | 3497 FA0A46 |
||
1005 | 3498 ; case 'A' -- type float hexadecimal upper case digits |
||
1006 | 3499 FA0A46 case_XF: |
||
1007 | 3500 FA0A46 A9 20 lda #F_FILLZ ; ignore left '0' padding |
||
1008 | 3501 FA0A48 14 14 trb fmtflag |
||
1009 | 3502 FA0A4A A9 41 lda #'A' ; format 'A' |
||
1010 | 3503 FA0A4C 80 1E bra case_f |
||
1011 | 3504 |
||
1012 | 3505 ; case 'a' -- type float hexadecimal lower case digits |
||
1013 | 3506 FA0A4E case_xf: |
||
1014 | 3507 FA0A4E A9 20 lda #F_FILLZ ; ignore left '0' padding |
||
1015 | 3508 FA0A50 14 14 trb fmtflag |
||
1016 | 3509 FA0A52 A9 61 lda #'a' ; format 'a' |
||
1017 | 3510 FA0A54 80 16 bra case_f |
||
1018 | 3511 |
||
1019 | 3512 ; case 'K' -- type compact float hexadecimal lower case digits |
||
1020 | 3513 FA0A56 case_KF: |
||
1021 | 3514 FA0A56 A9 20 lda #F_FILLZ ; ignore left '0' padding |
||
1022 | 3515 FA0A58 14 14 trb fmtflag |
||
1023 | 3516 FA0A5A A9 4B lda #'K' ; format 'K' |
||
1024 | 3517 FA0A5C 80 0E bra case_f |
||
1025 | 3518 |
||
1026 | 3519 ; case 'k' -- type compact float hexadecimal upper case digits |
||
1027 | 3520 FA0A5E case_kf: |
||
1028 | 3521 FA0A5E A9 20 lda #F_FILLZ ; ignore left '0' padding |
||
1029 | 3522 FA0A60 14 14 trb fmtflag |
||
1030 | 3523 FA0A62 A9 6B lda #'k' ; format 'K' |
||
1031 | 3524 FA0A64 80 06 bra case_f |
||
1032 | 3525 |
||
1033 | 3526 ; case 'f', 'F' -- type float decimal |
||
1034 | 3527 FA0A66 case_ff: |
||
1035 | 3528 FA0A66 A9 66 lda #'f' ; format 'f' |
||
1036 | 3529 FA0A68 80 02 bra case_f |
||
1037 | 3530 |
||
1038 | 3531 FA0A6A case_FF: |
||
1039 | 3532 FA0A6A A9 46 lda #'F' ; format 'F' |
||
1040 | 3533 |
||
1041 | 3534 ; common code for float conversion |
||
1042 | 3535 FA0A6C case_f: |
||
1043 | 3536 ; float numbers can be left padded with '0' |
||
1044 | 3537 ; even if specified 'precision' |
||
1045 | 3538 FA0A6C 85 1A sta tfloat ; float format type |
||
1046 | 3539 FA0A6E A9 01 lda #F2_SIGNED |
||
1047 | 3540 FA0A70 04 15 tsb fmtmod ; set signed bit |
||
1048 | 3541 FA0A72 A2 0A ldx #T_FLOAT ; conversion function index |
||
1049 | 3542 FA0A74 A9 F8 lda #MASKFLOAT ; not allowed modifiers for strings |
||
1050 | 3543 |
||
1051 | 3544 ; check modifier type |
||
1052 | 3545 FA0A76 case_end: |
||
1053 | 3546 FA0A76 24 15 bit fmtmod ; check not allowed modifiers |
||
1054 | 3547 FA0A78 F0 02 beq ?ok ; OK |
||
1055 | Tue Jul 17 11:00:21 2018 Page 18 |
||
1056 | |||
1057 | |||
1058 | |||
1059 | |||
1060 | 3548 FA0A7A 38 sec ; error |
||
1061 | 3549 FA0A7B 60 rts |
||
1062 | 3550 FA0A7C E2 40 ?ok: sep #PVFLAG ; set VF = 1 |
||
1063 | 3551 FA0A7E 18 clc ; no error |
||
1064 | 3552 FA0A7F 60 rts |
||
1065 | 3553 |
||
1066 | 3554 ; case 'P' -- type pointer hexadecimal upper case digits |
||
1067 | 3555 FA0A80 case_PT: |
||
1068 | 3556 FA0A80 A9 04 lda #F2_CAPS ; set CAPS bit |
||
1069 | 3557 FA0A82 04 15 tsb fmtmod |
||
1070 | 3558 |
||
1071 | 3559 ; case 'p' -- type pointer hexadecimal lower case digits |
||
1072 | 3560 FA0A84 case_pt: |
||
1073 | 3561 FA0A84 A9 01 lda #F2_SIGNED |
||
1074 | 3562 FA0A86 14 15 trb fmtmod ; clear flag signed |
||
1075 | 3563 FA0A88 A9 20 lda #F_FILLZ ; ignore left '0' padding |
||
1076 | 3564 FA0A8A 14 14 trb fmtflag |
||
1077 | 3565 FA0A8C A2 04 ldx #T_PTR ; conversion function index |
||
1078 | 3566 FA0A8E A9 F8 lda #MASKPTR ; not allowed modifiers for pointers |
||
1079 | 3567 FA0A90 80 E4 bra case_end |
||
1080 | 3568 |
||
1081 | 3569 ;--------------------------------------------------------------------------- |
||
1082 | 3570 ; tables |
||
1083 | 3571 ;--------------------------------------------------------------------------- |
||
1084 | 3572 |
||
1085 | 3573 ; character's class lookup table (32 <= char < 128) |
||
1086 | 3574 FA0A92 CLASSCHR: |
||
1087 | 3575 |
||
1088 | 3576 ; SP ! " # $ % & ' ( ) * + , - . / |
||
1089 | 3577 FA0A92 01 00 00 02 00 .DB _si,_dc,_dc,_af,_dc,_dc,_dc,_dc,_dc,_dc,_ar,_si,_tg,_lj,_pr,_dc |
||
1090 | 00 00 00 00 00 |
||
1091 | 03 01 18 04 05 |
||
1092 | 00 |
||
1093 | 3578 |
||
1094 | 3579 ; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
||
1095 | 3580 FA0AA2 0A 06 06 06 06 .DB _fz,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_nu,_dc,_dc,_dc,_dc,_dc,_dc |
||
1096 | 06 06 06 06 06 |
||
1097 | 00 00 00 00 00 |
||
1098 | 00 |
||
1099 | 3581 |
||
1100 | 3582 ; _ A B C D E F G H I J K L M N O |
||
1101 | 3583 FA0AB2 00 1C 1A 00 00 .DB _dc,_XF,_PS,_dc,_dc,_FE,_FF,_FG,_dc,_dc,_dc,_KF,_ll,_dc,_dc,_dc |
||
1102 | 16 1F 17 00 00 |
||
1103 | 00 1E 19 00 00 |
||
1104 | 00 |
||
1105 | 3584 |
||
1106 | 3585 ; P Q R S T U V W X Y Z [ \ ] ^ _ |
||
1107 | 3586 FA0AC2 10 00 00 00 00 .DB _PT,_dc,_dc,_dc,_dc,_dc,_dc,_dc,_HE,_dc,_dc,_dc,_dc,_dc,_dc,_dc |
||
1108 | 00 00 00 0F 00 |
||
1109 | 00 00 00 00 00 |
||
1110 | 00 |
||
1111 | 3587 |
||
1112 | 3588 ; ` a b c d e f g h i j k l m n o |
||
1113 | 3589 FA0AD2 00 1B 09 11 0B .DB _dc,_xf,_SH,_ch,_de,_fe,_ff,_fg,_sh,_de,_dc,_kf,_lo,_dc,_dc,_dc |
||
1114 | 14 13 15 08 0B |
||
1115 | 00 1D 07 00 00 |
||
1116 | 00 |
||
1117 | Tue Jul 17 11:00:21 2018 Page 19 |
||
1118 | |||
1119 | |||
1120 | |||
1121 | |||
1122 | 3590 |
||
1123 | 3591 ; p q r s t u v w x y z { | } ~ DEL |
||
1124 | 3592 FA0AE2 0E 00 00 12 00 .DB _pt,_dc,_dc,_st,_dc,_un,_dc,_dc,_he,_dc,_dc,_dc,_dc,_dc,_dc,_dc |
||
1125 | 0C 00 00 0D 00 |
||
1126 | 00 00 00 00 00 |
||
1127 | 00 |
||
1128 | 3593 |
||
1129 | 3594 ; table of specifiers checking functions |
||
1130 | 3595 FA0AF2 CHKTBL: |
||
1131 | 3596 FA0AF2 6D09 0709 2E09 .DW case_dc, case_si, case_af, case_ar |
||
1132 | 4009 |
||
1133 | 3597 FA0AFA 2709 C109 6F09 .DW case_lj, case_pr, case_nu, case_lo |
||
1134 | CE09 |
||
1135 | 3598 FA0B02 D209 D609 1609 .DW case_sh, case_SH, case_fz, case_de |
||
1136 | 040A |
||
1137 | 3599 FA0B0A 0A0A F009 840A .DW case_un, case_he, case_pt, case_HE |
||
1138 | EC09 |
||
1139 | 3600 FA0B12 800A 220A 2C0A .DW case_PT, case_ch, case_st, case_ff |
||
1140 | 660A |
||
1141 | 3601 FA0B1A 3A0A 420A 360A .DW case_fe, case_fg, case_FE, case_FG |
||
1142 | 3E0A |
||
1143 | 3602 FA0B22 3909 DA09 DE09 .DW case_tg, case_ll, case_PS, case_xf |
||
1144 | 4E0A |
||
1145 | 3603 FA0B2A 460A 5E0A 560A .DW case_XF, case_kf, case_KF, case_FF |
||
1146 | 6A0A |
||
1147 | 3604 FA0B32 |
||
1148 | 3605 ; tabella funzioni di conversione |
||
1149 | 3606 FA0B32 CVTTBL: |
||
1150 | 3607 ; .DW DoChar, DoStr, DoPtr, DoInt, DoHex, DoFloat |
||
1151 | 3608 FA0B32 |
||
1152 | 3609 FA0B32 NULLSTR: |
||
1153 | 3610 FA0B32 28 6E 75 6C 6C .DB "(null)", 0 |
||
1154 | 29 00 |
||
1155 | |||
1156 | |||
1157 | Lines Assembled : 3507 Errors : 0 |
||
1158 | |||
1159 | |||
1160 |