Subversion Repositories MB01 Project

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 - 1
  Tue Jul 17 11:00:21 2018                                                                                               Page    1
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
          2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
10
          -----------------------------------------------------
11
 
12
                       Input  Filename : src\FA\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