Blame | Last modification | View Log | Download | RSS feed
Tue Jul 17 11:00:16 2018 Page 1
2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
-----------------------------------------------------
Input Filename : src\F8\intp.asm
Output Filename : obj\F8\intp.obj
Listing Has Been Relocated
2588 .LIST on
2589
2590
2591 ;----------------------------------------------------------
2592 ; variabili in Direct-Page 02
2593 ;----------------------------------------------------------
2594 F8FFB1
2595 F8FFB1 .INCLUDE inc\dirp02.inc
2596 ;----------------------------------------------------------
2597 ; DIRP02.ASM
2598 ; PROGETTO: B1601
2599 ;
2600 ; Variabili in Direct Page $02
2601 ;----------------------------------------------------------
2602
2603 ; sezione COMMON -- questo permette di includere il file in piu' file
2604
2605 DIRP02: .SECTION page0, ref_only, common ;Direct-Page 02
2606
2607 000000 .ABSOLUTE ;; inizia sempre da $00
2608 000000 .ORG 0x00
2609 000000
2610 ; variabili usate nella funzione _vprintl e famiglia funzioni di formattazione
2611 000000 0000 FmtParm .DW ;; ptr array parametri banco 0
2612 000002 FmtLPFmt LP ;; long ptr stringa szFmt
2613 000005 FmtLPPut LP ;; long ptr funzione 'putter'
2614 000008 00 FmtSpec .DB ;; indice '%' corrente in szFmt
2615 000009 00 FmtWidth .DB ;; campo width
2616 00000A 00 FmtPrec .DB ;; campo precision
2617 00000B 00 FmtFlag .DB ;; flag formattazione
2618 00000C 00 FmtSgn .DB ;; segno positivo (se 0 -> no segno)
2619 00000D 00 VStoreF .DB ;; flag modo store
2620 00000E 00 FmtMod .DB ;; flag modificatori
2621 00000F 00 FmtDst .DB ;; ptr stringa szDst banco 0
2622
2623 000010 0000 FmtCnt .DW ;; contatore caratteri
2624 000012 0000 FmtGMax .DW ;; max. len stringa globale
2625 000014
2626 000014 0000 XVDec .DW ; esponente decimale (signed)
2627 000016 00 XVFlag .DB ; flag per conversioni numeriche
2628 000017
2629 000017 00 ACMCmps .DB ; flag compare segno e tipo (intero)
2630
2631 000018 ACM DQ ; accumulatore #1 integer 64 bit
2632 000020 00 ACMSize .DB ; size
2633 000021 00 ACMSgn .DB ; <7>:segno, <6>:tipo signed
Tue Jul 17 11:00:16 2018 Page 2
2634 000022 00 ACMMinSize .DB ; minima dimensione richiesta per ACM
2635 000023 00 IARGMinSize .DB
2636
2637 000024 00 FPTmp1 .DB ; byte temporaneo
2638 000025 00 FPTmp2 .DB ; byte temporaneo
2639 000026 00 FPTmp3 .DB ; byte temporaneo
2640 000027 00 FPTmp4 .DB ; byte temporaneo
2641
2642 000028 IARG DQ ; accumulatore #2 integer 64 bit
2643 000030 00 IARGSize .DB ; size
2644 000031 00 IARGSgn .DB ; <7>:segno, <6>:tipo signed
2645
2646 000032 FOP DS 9 ; temporaneo per FDIV/FMULT/integer MULT/DIV
2647 ; conversione integer -> string
2648 00003B 00 FPIndx .DB ; byte generico indice
2649 00003C 0000 FPWTmp7 .DW ; word temporanea
2650 00003E 0000 FPWTmp8 .DW ; word temporanea
2651
2652 ; variabili temporanee sovrapposte a FOP
2653 000036 FACXM .EQU FOP+4 ; byte temporaneo
2654 000037 ARGXM .EQU FOP+5 ; byte temporaneo
2655 000038 FPWTmp5 .EQU FOP+6 ; word temporanea
2656 00003A FPTmp6 .EQU FOP+8 ; byte temporaneo
2657
2658 ; Floating Point Accumulator #1 - FAC
2659 000040 00 FACSGN .DB ; FAC mantissa sign
2660 000041 00 FACEXT .DB ; FAC 8 bit extension (rounding)
2661 000042 FACM DQ ; FAC Mantissa (64 bit)
2662 00004A 0000 FACExp .DW ; FAC Exponent
2663 00004A FACEXPL .EQU FACExp ; FAC Exponent Low
2664 00004B FACEXPH .EQU FACExp+1 ; FAC Exponent Hi
2665
2666 00004C 00 FACSCMP .DB ; Sign Comparison Result: FAC vs ARG
2667 00004D 00 FACMlt .DB ; flag MULT
2668 00004E 00 FACUndf .DB ; conteggio shift per underflow
2669 00004F 00 FPDCnt .DB ; contatore per inserzione punto decimale
2670 000050
2671 ; Floating Point Accumulator #2 - ARG
2672 000050 00 ARGSGN .DB ; ARG mantissa sign
2673 000051 00 ARGEXT .DB ; ARG 8 bit extension (rounding)
2674 000052 ARGM DQ ; ARG Mantissa (64 bit)
2675 00005A 0000 ARGExp .DW ; ARG Exponent
2676 00005A ARGEXPL .EQU ARGExp ; ARG Exponent Low
2677 00005B ARGEXPH .EQU ARGExp+1 ; ARG Exponent Hi
2678
2679 ; numero bytes FAC
2680 00000A FACSIZE .EQU (FACEXPH - FACEXT)
2681 000008 MANTSIZE .EQU (FACSIZE - 2)
2682 000040 FACMBITS .EQU (MANTSIZE * 8)
2683 000041 FAC .EQU FACEXT
2684 000051 ARG .EQU ARGEXT
2685
2686 00005C 0000 FPWTmp .DW
2687 00005E 0000 FPExp .DW ; esponente conversioni str/float
2688 000060 FPLPtr LP ; long ptr operazioni move
2689 000063 00 FPFlag .DB ; flag generico operazioni FPU
2690 000064 FACTmp .DS 12 ; registro FAC temporaneo (con sgn ed ext)
Tue Jul 17 11:00:16 2018 Page 3
2691
2692 ; buffer per conversione da int/float a string (20 digit + 2)
2693 000016 FPSTRSIZE .EQU 22
2694 000070 FPUStr .DS FPSTRSIZE
2695
2696 ; buffer per formattazione int/float
2697 000030 XFSTRSIZE .EQU 48
2698 000086 XCVTStr .DS XFSTRSIZE
2699 0000B5 XCVTStrEnd .EQU ($ - 1)
2700
2701 0000B6 DUMMY100 .DS 22
2702
2703 000060 PTR1 .EQU FPLPtr ; long ptr operazioni 'move'
2704 000063 FPFLAG .EQU FPFlag
2705 00004F FPDCNT .EQU FPDCnt
2706 0000CC
2707 0000CC .RELATIVE
2708
2709 .ENDS
2710
2711 FFFFB0 MAXMANTSHIFT .EQU (-(FACMBITS + 16)) ; max. shift divisione mant.
2712 00002F XCVTMAXF .EQU (XFSTRSIZE - 1) ; max. caratteri formato F
2713 000027 XCVTMAXE .EQU (XCVTMAXF - 8) ; max. caratteri formato E
2714 00002E XCVTMAXI .EQU (XFSTRSIZE - 2) ; max. caratteri stringa int.
2715
2716 F8FFB1
2717
2718
2719 ; max. unsigned: 18446744073709551615
2720 ; max. signed : 9223372036854775807
2721 ; min. signed : -9223372036854775808
2722
2723 ;----------------------------------------------------------
2724 ; segmento codice banco $F8
2725 ;----------------------------------------------------------
2726
2727 .CODEF8
2728 .GLOBAL _iUMult8, _iUMult16, _iUMult32, _iUMult64
2729 .GLOBAL _iSMult8, _iSMult16, _iSMult32, _iSMult64
2730 .GLOBAL _iUDiv8, _iUDiv16, _iUDiv32, _iUDiv64, Byte2Hex
2731 .GLOBAL _iSDiv8, _iSDiv16, _iSDiv32, _iSDiv64
2732 .GLOBAL _Str2Hex, _Str2Int, _Int2Str, _UI2Str, _iMovACM2A
2733 .PUBLIC fidiv, fimlt
2734
2735 .LONGA off
2736 .LONGI off
2737
2738 000008 INTGSIZE .EQU 8 ; # bytes interi a 64 bytes
2739 00007F MAXINTSTR .EQU 127 ; max. lughezza stringa dec/hex
2740
2741
2742 ; _lstrtoint(lpStr, bSiz, bFlag, lpRes)
2743 ;
2744 ; convert decimal/hexadecimal string lpStr to integer
2745 ;
2746 ; entry
2747 ; lpStr = long pointer to string
Tue Jul 17 11:00:16 2018 Page 4
2748 ; bSiz = size of integer (1,2,3,4,8) - size=3 valid for hex only
2749 ; bFlag = <7>: wanted signed integer
2750 ; <6>: default to decimal string (autodetect '$' for hex)
2751 ; lpRes = long pointer to dest. buffer to store result
2752 ;
2753 ; exit
2754 ; C,X = long pointer to first invalid char. (not digit)
2755 ; Y = <7>: sign of result (only if bit 6 is set)
2756 ; <6>: set if result is signed integer
2757 ;
2758 ; P: = CF & VF flag's report any error condition
2759 ; CF = 0 & VF = 0 -> no error
2760 ; CF = 0 & VF = 1 -> mismatch type (signed/unsigned)
2761 ; CF = 1 & VF = 0 -> no conversion (invalid string)
2762 ; CF = 1 & VF = 1 -> overflow error
2763 ;
2764 ;
2765 000008 M .SET 8 ; param's bytes count
2766 00000D N .SET 13 ; bytes pushed on stack after param's
2767 00000E lpRes .SET N+1
2768 000011 bFlag .SET N+4
2769 000012 bSiz .SET N+5
2770 000013 lpStr .SET N+6
2771 000001 CReg .SET 1
2772 000003 YReg .SET 3
2773 000005 XReg .SET 5
2774 00000A PReg .SET 10
2775
2776 ;----------------------
2777 F827BB _lstrtoint:
2778 .PUBLIC _lstrtoint
2779 ;----------------------
2780
2781 .LONGA off
2782 .LONGI off
2783
2784 F827BB 08 php ; save register's size and CF&VF exit value's
2785 F827BC 8B phb ; save dbr
2786 F827BD 0B phd ; save dpr
2787 F827BE CPU16
2788 F827BE C2 30 rep #(PMFLAG.OR.PXFLAG)
2789 .LONGA on
2790 .LONGI on
2791 .MNLIST
2792 F827C0 DA phx ; X exit value
2793 F827C1 5A phy ; Y exit value
2794 F827C2 48 pha ; C exit value
2795 F827C3 A9 00 02 lda #DP02ADDR ; set working dpr
2796 F827C6 5B tcd
2797 F827C7 CPU08
2798 F827C7 E2 30 sep #(PMFLAG.OR.PXFLAG)
2799 .LONGA off
2800 .LONGI off
2801 .MNLIST
2802 F827C9 A3 0A lda PReg,s
2803 F827CB 29 BE and #~(PCFLAG+PVFLAG)
2804 F827CD 83 0A sta PReg,s ; clear CF & VF
Tue Jul 17 11:00:16 2018 Page 5
2805 F827CF A3 12 lda bSiz,s
2806 F827D1 85 24 sta FPTmp1 ; integer size
2807 F827D3 A3 11 lda bFlag,s
2808 F827D5 85 25 sta FPTmp2 ; conversion flag
2809 F827D7 AA tax
2810 F827D8 0A asl a ; test bit 6
2811 F827D9 10 30 bpl ?20 ; convert hex. string
2812 F827DB A3 15 lda lpStr+2,s
2813 F827DD 48 pha
2814 F827DE AB plb
2815 F827DF A0 00 ldy #0
2816 F827E1 B3 13 lda (lpStr,s),y ; check first char
2817 F827E3 C9 24 cmp #'$' ; hex. string?
2818 F827E5 D0 0B bne ?10 ; no
2819 F827E7 ACC16
2820 F827E7 C2 20 rep #PMFLAG
2821 .LONGA on
2822 .MNLIST
2823 F827E9 A3 13 lda lpStr,s ; bump string pointer
2824 F827EB 1A inc a
2825 F827EC 83 13 sta lpStr,s
2826 F827EE ACC08
2827 F827EE E2 20 sep #PMFLAG
2828 .LONGA off
2829 .MNLIST
2830 F827F0 80 19 bra ?20 ; convert hex. string
2831 F827F2 A4 24 ?10: ldy FPTmp1
2832 F827F4 C0 03 cpy #3 ; decimal conversion refuse pointer size
2833 F827F6 F0 13 beq ?20 ; force hex.
2834 F827F8 8A ?15: txa
2835 F827F9 29 80 and #$80 ; wanted signed flag
2836 F827FB 05 24 ora FPTmp1 ; add size
2837 F827FD AA tax
2838 F827FE A3 15 lda lpStr+2,s
2839 F82800 A8 tay
2840 F82801 A3 14 lda lpStr+1,s
2841 F82803 EB xba
2842 F82804 A3 13 lda lpStr,s
2843 F82806 20 C7 2E jsr _Str2Int ; decimal string
2844 F82809 80 0D bra ?25
2845 F8280B A6 24 ?20: ldx FPTmp1
2846 F8280D A3 15 lda lpStr+2,s
2847 F8280F A8 tay
2848 F82810 A3 14 lda lpStr+1,s
2849 F82812 EB xba
2850 F82813 A3 13 lda lpStr,s
2851 F82815 20 7E 2F jsr _Str2Hex ; hex string
2852 F82818 A3 0A ?25: lda PReg,s ; set status result
2853 F8281A 90 02 bcc ?26 ; no error
2854 F8281C 09 01 ora #PCFLAG ; set CF on exit status
2855 F8281E 50 02 ?26: bvc ?27
2856 F82820 09 40 ora #PVFLAG ; set VF on exit status
2857 F82822 83 0A ?27: sta PReg,s
2858 F82824 AA tax
2859 F82825 ACC16CLC
2860 F82825 C2 21 rep #(PMFLAG.OR.PCFLAG)
2861 .LONGA on
Tue Jul 17 11:00:16 2018 Page 6
2862 .MNLIST
2863 F82827 98 tya ; remainder string ptr
2864 F82828 63 13 adc lpStr,s
2865 F8282A 83 01 sta CReg,s
2866 F8282C ACC08
2867 F8282C E2 20 sep #PMFLAG
2868 .LONGA off
2869 .MNLIST
2870 F8282E A3 15 lda lpStr+2,s
2871 F82830 90 01 bcc ?28
2872 F82832 1A inc a
2873 F82833 83 05 ?28: sta XReg,s
2874 F82835 A9 00 lda #0
2875 F82837 83 06 sta XReg+1,s
2876 F82839 83 04 sta YReg+1,s
2877 F8283B A5 21 lda ACMSgn
2878 F8283D 83 03 sta YReg,s
2879 F8283F 8A txa ; status
2880 F82840 4A lsr a ; CF check
2881 F82841 B0 15 bcs ?40 ; error, so no store result
2882 F82843 A3 12 lda bSiz,s
2883 F82845 85 24 sta FPTmp1 ; size
2884 F82847 A3 10 lda lpRes+2,s
2885 F82849 48 pha
2886 F8284A AB plb
2887 F8284B A0 00 ldy #0
2888 F8284D BB tyx
2889 F8284E B5 18 ?30: lda ACM,x
2890 F82850 93 0E sta (lpRes,s),y
2891 F82852 C8 iny
2892 F82853 E8 inx
2893 F82854 E4 24 cpx FPTmp1
2894 F82856 90 F6 bcc ?30
2895 F82858 ?40: CPU16CLC
2896 F82858 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
2897 .LONGA on
2898 .LONGI on
2899 .MNLIST
2900 F8285A 3B tsc ; epilogue code
2901 F8285B 69 0D 00 adc #N
2902 F8285E AA tax ; source address for move
2903 F8285F 69 08 00 adc #M
2904 F82862 A8 tay ; destination address for move
2905 F82863 A9 0C 00 lda #N-1 ; bytes to move - 1
2906 F82866 44 00 00 mvp #0, #0 ; move previous
2907 F82869 98 tya ; new stack pointer
2908 F8286A 1B tcs
2909 F8286B 68 pla ; return C
2910 F8286C 7A ply ; return Y
2911 F8286D FA plx ; return X
2912 F8286E 2B pld ; restore dpr
2913 F8286F AB plb ; restore dbr
2914 F82870 28 plp ; restore status
2915 F82871 6B rtl
2916
2917 ;----------------------------------------------------------
2918 ; estensione segno accumulatori
Tue Jul 17 11:00:16 2018 Page 7
2919 ;----------------------------------------------------------
2920
2921 ; _iCWD16 - estende ACM a WORD
2922 F82872 _iCWD16:
2923 F82872 A6 20 ldx ACMSize
2924 F82874 E0 02 00 cpx #$02 ; ACM WORD ?
2925 F82877 B0 13 bcs ?06 ; si -- non deve estendere
2926 F82879 A0 00 00 ldy #0
2927 F8287C 24 21 bit ACMSgn
2928 F8287E 50 07 bvc ?04 ; unsigned => estende con 00
2929 F82880 CA dex ; indice MSB BYTE
2930 F82881 34 18 bit ACM,x
2931 F82883 10 01 bpl ?02 ; signed positivo => estende con 00
2932 F82885 88 dey ; signed negativo => estende con FF
2933 F82886 E8 ?02: inx ; indice MSB WORD
2934 F82887 94 18 ?04: sty ACM,x
2935 F82889 E8 inx ; size = 2 (WORD)
2936 F8288A 86 20 stx ACMSize ; update size
2937 F8288C 60 ?06: rts
2938
2939 ; _iCWD32 - estende ACM a LONG
2940 F8288D _iCWD32:
2941 F8288D 20 72 28 jsr _iCWD16 ; assicura ACM esteso a WORD
2942 F82890 A6 20 ldx ACMSize
2943 F82892 E0 04 00 cpx #$04 ; ACM LONG ?
2944 F82895 B0 18 bcs ?06 ; si -- non deve estendere
2945 F82897 A0 00 00 ldy #0
2946 F8289A INDEX16
2947 F8289A C2 10 rep #PXFLAG
2948 .LONGI on
2949 .MNLIST
2950 F8289C 24 21 bit ACMSgn
2951 F8289E 50 07 bvc ?04 ; unsigned => estende con 0000
2952 F828A0 CA dex ; indice MSB WORD
2953 F828A1 34 18 bit ACM,x
2954 F828A3 10 01 bpl ?02 ; signed positivo => estende con 0000
2955 F828A5 88 dey ; signed negativo => estende con FFFF
2956 F828A6 E8 ?02: inx ; indice MSB LONG
2957 F828A7 94 18 ?04: sty ACM,x ; estende
2958 F828A9 INDEX08
2959 F828A9 E2 10 sep #PXFLAG
2960 .LONGI off
2961 .MNLIST
2962 F828AB E8 inx
2963 F828AC E8 inx ; size = 4 (LONG)
2964 F828AD 86 20 stx ACMSize ; update size
2965 F828AF 60 ?06: rts
2966
2967 ; _iCWD64 - estende ACM a QUAD
2968 F828B0 _iCWD64:
2969 F828B0 20 8D 28 jsr _iCWD32 ; assicura ACM esteso a LONG
2970 F828B3 A6 20 ldx ACMSize
2971 F828B5 E0 08 cpx #$08 ; ACM QUAD ?
2972 F828B7 B0 19 bcs ?06 ; si -- non deve estendere
2973 F828B9 A0 00 ldy #0
2974 F828BB INDEX16
2975 F828BB C2 10 rep #PXFLAG
Tue Jul 17 11:00:16 2018 Page 8
2976 .LONGI on
2977 .MNLIST
2978 F828BD 24 21 bit ACMSgn
2979 F828BF 50 07 bvc ?04 ; unsigned => estende con 0000
2980 F828C1 CA dex ; indice MSB LONG
2981 F828C2 34 18 bit ACM,x
2982 F828C4 10 01 bpl ?02 ; signed positivo => estende con 0000
2983 F828C6 88 dey ; signed negativo => estende con FFFF
2984 F828C7 E8 ?02: inx ; indice MSB QUAD
2985 F828C8 94 18 ?04: sty ACM,x ; estende
2986 F828CA 94 1A sty ACM+2,x
2987 F828CC INDEX08
2988 F828CC E2 10 sep #PXFLAG
2989 .LONGI off
2990 .MNLIST
2991 F828CE A2 08 ldx #$08 ; size = 8 (QUAD)
2992 F828D0 86 20 stx ACMSize ; update size
2993 F828D2 60 ?06: rts
2994
2995 ; _iCWDARG16 - estende IARG a WORD
2996 F828D3 _iCWDARG16:
2997 F828D3 A6 30 ldx IARGSize
2998 F828D5 E0 02 cpx #$02 ; IARG WORD ?
2999 F828D7 B0 12 bcs ?06 ; si -- non deve estendere
3000 F828D9 A0 00 ldy #0
3001 F828DB 24 31 bit IARGSgn
3002 F828DD 50 07 bvc ?04 ; unsigned => estende con 00
3003 F828DF CA dex ; indice MSB BYTE
3004 F828E0 34 28 bit IARG,x
3005 F828E2 10 01 bpl ?02 ; signed positivo => estende con 00
3006 F828E4 88 dey ; signed negativo => estende con FF
3007 F828E5 E8 ?02: inx ; indice MSB WORD
3008 F828E6 94 28 ?04: sty IARG,x
3009 F828E8 E8 inx ; size = 2 (WORD)
3010 F828E9 86 30 stx IARGSize ; update size
3011 F828EB 60 ?06: rts
3012
3013 ; _iCWDARG32 - estende IARG a LONG
3014 F828EC _iCWDARG32:
3015 F828EC 20 D3 28 jsr _iCWDARG16 ; assicura IARG esteso a WORD
3016 F828EF A6 30 ldx IARGSize
3017 F828F1 E0 04 cpx #$04 ; IARG LONG ?
3018 F828F3 B0 17 bcs ?06 ; si -- non deve estendere
3019 F828F5 A0 00 ldy #0
3020 F828F7 INDEX16
3021 F828F7 C2 10 rep #PXFLAG
3022 .LONGI on
3023 .MNLIST
3024 F828F9 24 31 bit IARGSgn
3025 F828FB 50 07 bvc ?04 ; unsigned => estende con 0000
3026 F828FD CA dex ; indice MSB WORD
3027 F828FE 34 28 bit IARG,x
3028 F82900 10 01 bpl ?02 ; signed positivo => estende con 0000
3029 F82902 88 dey ; signed negativo => estende con FFFF
3030 F82903 E8 ?02: inx ; indice MSB LONG
3031 F82904 94 28 ?04: sty IARG,x ; estende
3032 F82906 INDEX08
Tue Jul 17 11:00:16 2018 Page 9
3033 F82906 E2 10 sep #PXFLAG
3034 .LONGI off
3035 .MNLIST
3036 F82908 E8 inx
3037 F82909 E8 inx ; size = 4 (LONG)
3038 F8290A 86 30 stx IARGSize ; update size
3039 F8290C 60 ?06: rts
3040
3041 ; _iCWDARG64 - estende IARG a QUAD
3042 F8290D _iCWDARG64:
3043 F8290D 20 EC 28 jsr _iCWDARG32 ; assicura IARG esteso a LONG
3044 F82910 A6 30 ldx IARGSize
3045 F82912 E0 08 cpx #$08 ; IARG QUAD ?
3046 F82914 B0 19 bcs ?06 ; si -- non deve estendere
3047 F82916 A0 00 ldy #0
3048 F82918 INDEX16
3049 F82918 C2 10 rep #PXFLAG
3050 .LONGI on
3051 .MNLIST
3052 F8291A 24 31 bit IARGSgn
3053 F8291C 50 07 bvc ?04 ; unsigned => estende con 0000
3054 F8291E CA dex ; indice MSB LONG
3055 F8291F 34 28 bit IARG,x
3056 F82921 10 01 bpl ?02 ; signed positivo => estende con 0000
3057 F82923 88 dey ; signed negativo => estende con FFFF
3058 F82924 E8 ?02: inx ; indice MSB QUAD
3059 F82925 94 28 ?04: sty IARG,x ; estende
3060 F82927 94 2A sty IARG+2,x
3061 F82929 INDEX08
3062 F82929 E2 10 sep #PXFLAG
3063 .LONGI off
3064 .MNLIST
3065 F8292B A2 08 ldx #$08 ; size = 8 (QUAD)
3066 F8292D 86 30 stx IARGSize ; update size
3067 F8292F 60 ?06: rts
3068
3069 ; _iCWD2 - estensione segno operandi ACM e IARG
3070 F82930 _iCWD2:
3071 F82930 A5 30 lda IARGSize
3072 F82932 C5 20 cmp ACMSize
3073 F82934 F0 20 beq ?10 ; no estensione
3074 F82936 B0 02 bcs ?02 ; CF = 1 => estende ACM
3075 F82938 A5 20 lda ACMSize
3076 F8293A 08 ?02: php ; salva CF
3077 F8293B A2 02 ldx #$02
3078 F8293D DF 5F 29 F8 ?04: cmp >CWDTBL,x ; X = indice CWD
3079 F82941 F0 07 beq ?06
3080 F82943 CA dex
3081 F82944 10 F7 bpl ?04
3082 F82946 28 plp ; non dovrebbe accadere
3083 F82947 B8 clv ; VF = 0
3084 F82948 38 sec ; CF = 1
3085 F82949 60 rts
3086 F8294A 8A ?06: txa
3087 F8294B 0A asl a
3088 F8294C 28 plp ; ripristina CF
3089 F8294D B0 03 bcs ?08 ; CF = 1 => CWD ACM
Tue Jul 17 11:00:16 2018 Page 10
3090 F8294F 69 06 00 adc #$06 ; CF = 0 => CWD IARG
3091 F82952 AA ?08: tax ; indice funzione
3092 F82953 FC 62 29 jsr (CWDJMP,x) ; estensione segno ACM/IARG
3093 F82956 A5 20 ?10: lda ACMSize
3094 F82958 45 30 eor IARGSize
3095 F8295A 85 17 sta ACMCmps ; set flag compare segno (7) e tipo (6)
3096 F8295C B8 clv
3097 F8295D 18 clc
3098 F8295E 60 rts
3099 F8295F
3100 ; tabella per estensione segno
3101 F8295F CWDTBL:
3102 F8295F 02 04 08 .DB $02, $04, $08
3103
3104 ; tabella funzioni CWD ACM
3105 F82962 CWDJMP:
3106 F82962 7228 8D28 B028 .DW _iCWD16, _iCWD32, _iCWD64
3107 F82968
3108 ; tabella funzioni CWD IARG
3109 F82968 CWDJMP2:
3110 F82968 D328 EC28 0D29 .DW _iCWDARG16, _iCWDARG32, _iCWDARG64
3111
3112 ;----------------------------------------------------------
3113 ; implementazione MULT unsigned integer
3114 ;----------------------------------------------------------
3115
3116 ; _iUMult8: moltiplicazione integer 8 bit unsigned
3117 ; In: ACM: unsigned integer 1
3118 ; IARG: unsigned integer 2
3119 ; Out: ACM..ACM+1 -> risultato integer unsigned (16 bit)
3120 ; X = 0
3121 ; Y = minima size
3122 ; CF = 0
3123 ; Uso: A,X,Y,ACM,IARG
3124 F8296E _iUMult8:
3125 F8296E A9 00 00 lda #0 ; azzera parte alta del risultato
3126 F82971 A2 09 LDX #9 ; ciclo 9 bit
3127 F82973 18 CLC
3128 F82974 6A ?01: ror a ; ACM + 1
3129 F82975 66 18 ROR ACM
3130 F82977 90 03 BCC ?02
3131 F82979 18 CLC
3132 F8297A 65 28 adc IARG
3133 F8297C CA ?02: DEX
3134 F8297D D0 F5 BNE ?01
3135 F8297F 85 19 sta ACM+1
3136 F82981 A0 02 ldy #$02
3137 F82983 84 20 sty ACMSize ; ACM WORD
3138 F82985 09 00 00 ora #$00
3139 F82988 D0 01 bne ?03 ; ACM+1 non ZERO
3140 F8298A 88 dey ; ACM+1 = 0 => min size = BYTE
3141 F8298B 84 22 ?03: sty ACMMinSize
3142 F8298D 18 clc
3143 F8298E 60 RTS
3144
3145 ; _iUMult16: moltiplicazione integer 16 bit unsigned
3146 ; In: ACM, ACM+1: unsigned integer 1
Tue Jul 17 11:00:16 2018 Page 11
3147 ; IARG, IARG+1: unsigned integer 2
3148 ; Out: ACM..ACM+3 -> risultato integer unsigned (32 bit)
3149 ; X = 0
3150 ; Y = minima size
3151 ; CF = 0
3152 ; Uso: A,X,Y,ACM,IARG
3153 F8298F _iUMult16:
3154 F8298F ACC16
3155 F8298F C2 20 rep #PMFLAG
3156 .LONGA on
3157 .MNLIST
3158 F82991 A9 00 00 lda #0 ; azzera parte alta del risultato
3159 F82994 A2 11 LDX #17 ; ciclo 17 bit
3160 F82996 18 CLC
3161 F82997 6A ?01: ror a : ACM + 2
3162 F82998 66 18 ROR ACM
3163 F8299A 90 03 BCC ?02
3164 F8299C 18 CLC
3165 F8299D 65 28 adc IARG
3166 F8299F CA ?02: DEX
3167 F829A0 D0 F5 BNE ?01
3168 F829A2 85 1A sta ACM+2
3169 F829A4 A0 04 ldy #$04
3170 F829A6 84 20 sty ACMSize ; ACM LONG
3171 F829A8 09 00 00 ora #$0000
3172 F829AB D0 02 bne ?03 ; WORD ACM+2 NON NULLA
3173 F829AD 88 dey
3174 F829AE 88 dey ; MIN SIZE = WORD
3175 F829AF 84 22 ?03: sty ACMMinSize
3176 F829B1 ACC08
3177 F829B1 E2 20 sep #PMFLAG
3178 .LONGA off
3179 .MNLIST
3180 F829B3 18 clc
3181 F829B4 60 RTS
3182
3183 ; _iUMult32: moltiplicazione integer 32 bit unsigned
3184 ; In: ACM..ACM+3: unsigned integer 1
3185 ; IARG..IARG+3: unsigned integer 2
3186 ; Out: ACM..ACM+7 -> risultato integer unsigned (64 bit)
3187 ; X = 0
3188 ; Y = minima size
3189 ; CF = 0
3190 ; Uso: A,X,Y,ACM,IARG
3191 F829B5 _iUMult32:
3192 F829B5 ACC16
3193 F829B5 C2 20 rep #PMFLAG
3194 .LONGA on
3195 .MNLIST
3196 F829B7 64 1C STZ ACM+4 ; azzera parte alta del risultato
3197 F829B9 64 1E STZ ACM+6
3198 F829BB A2 21 LDX #33 ; ciclo 33 bit
3199 F829BD 18 CLC
3200 F829BE 66 1E ?01: ROR ACM+6
3201 F829C0 66 1C ROR ACM+4
3202 F829C2 66 1A ROR ACM+2
3203 F829C4 66 18 ROR ACM
Tue Jul 17 11:00:16 2018 Page 12
3204 F829C6 90 0D BCC ?02
3205 F829C8 18 CLC
3206 F829C9 A5 28 LDA IARG
3207 F829CB 65 1C ADC ACM+4
3208 F829CD 85 1C STA ACM+4
3209 F829CF A5 2A LDA IARG+2
3210 F829D1 65 1E ADC ACM+6
3211 F829D3 85 1E STA ACM+6
3212 F829D5 CA ?02: DEX
3213 F829D6 D0 E6 BNE ?01
3214 F829D8 A0 08 ldy #$08
3215 F829DA 84 20 sty ACMSize ; ACM QUAD
3216 F829DC A5 1E lda ACM+6
3217 F829DE 05 1C ora ACM+4
3218 F829E0 D0 02 bne ?03 ; LONG ACM+4 NON ZERO
3219 F829E2 A0 04 ldy #$04 ; MIN SIZE = LONG
3220 F829E4 84 22 ?03: sty ACMMinSize
3221 F829E6 ACC08
3222 F829E6 E2 20 sep #PMFLAG
3223 .LONGA off
3224 .MNLIST
3225 F829E8 18 clc
3226 F829E9 60 RTS
3227
3228 ; _iUMult64: moltiplicazione integer 64 bit unsigned
3229 ; In: ACM..ACM+7: unsigned integer 1
3230 ; IARG..IARG+7: unsigned integer 2
3231 ; Out: ACM..ACM+7 -> risultato integer unsigned (128 bit LOW)
3232 ; FOP..FOP+7 -> risultato integer unsigned (128 bit HIGH) (OVERFLOW)
3233 ; X = 0
3234 ; CF = 0 -> risultato OK
3235 ; CF = 1 -> unsigned overflow
3236 ; Uso: A,X,Y,ACM,IARG,FOP
3237 F829EA _iUMult64:
3238 F829EA A0 08 ldy #$08
3239 F829EC 84 22 sty ACMMinSize
3240 F829EE 84 20 sty ACMSize
3241 F829F0 ACC16
3242 F829F0 C2 20 rep #PMFLAG
3243 .LONGA on
3244 .MNLIST
3245 F829F2 64 32 stz FOP ; azzera parte alta del risultato a 128 bit
3246 F829F4 64 34 stz FOP+2 ; la parte bassa (64 bit) in ACM
3247 F829F6 64 36 stz FOP+4
3248 F829F8 64 38 stz FOP+6
3249 F829FA A2 41 LDX #65 ; ciclo 65 bit
3250 F829FC 18 CLC
3251 F829FD 66 38 ?01: ROR FOP+6
3252 F829FF 66 36 ROR FOP+4
3253 F82A01 66 34 ROR FOP+2
3254 F82A03 66 32 ROR FOP
3255 F82A05 66 1E ROR ACM+6
3256 F82A07 66 1C ROR ACM+4
3257 F82A09 66 1A ROR ACM+2
3258 F82A0B 66 18 ROR ACM
3259 F82A0D 90 19 BCC ?02
3260 F82A0F 18 CLC
Tue Jul 17 11:00:16 2018 Page 13
3261 F82A10 A5 28 LDA IARG
3262 F82A12 65 32 ADC FOP
3263 F82A14 85 32 STA FOP
3264 F82A16 A5 2A LDA IARG+2
3265 F82A18 65 34 ADC FOP+2
3266 F82A1A 85 34 STA FOP+2
3267 F82A1C A5 2C LDA IARG+4
3268 F82A1E 65 36 ADC FOP+4
3269 F82A20 85 36 STA FOP+4
3270 F82A22 A5 2E LDA IARG+6
3271 F82A24 65 38 ADC FOP+6
3272 F82A26 85 38 STA FOP+6
3273 F82A28 CA ?02: DEX
3274 F82A29 D0 D2 BNE ?01
3275 F82A2B 38 sec ; flag overflow
3276 F82A2C A5 32 lda FOP ; test overflow
3277 F82A2E 05 34 ora FOP+2
3278 F82A30 05 36 ora FOP+4
3279 F82A32 05 38 ora FOP+6
3280 F82A34 D0 01 bne ?04 ; overflow -> CF = 1
3281 F82A36 18 clc
3282 F82A37 ?04: ACC08
3283 F82A37 E2 20 sep #PMFLAG
3284 .LONGA off
3285 .MNLIST
3286 F82A39 60 RTS
3287
3288 ;----------------------------------------------------------
3289 ; 2's complement
3290 ;----------------------------------------------------------
3291
3292 ; complento a 2 di IARG
3293 F82A3A _iNegIARG
3294 F82A3A A2 28 ldx #IARG
3295 F82A3C 80 02 bra _iNegX
3296
3297 ; complento a 2 di ACM
3298 F82A3E _iNegACM:
3299 F82A3E A2 18 ldx #ACM
3300 F82A40
3301 ; complemento a 2 accumulatore X (ACM, IARG, FOP)
3302 F82A40 _iNegX:
3303 F82A40 38 sec
3304 F82A41 _iNegXnc:
3305 F82A41 5A phy ; salva Y
3306 F82A42 A0 00 ldy #0
3307 F82A44 ACC16
3308 F82A44 C2 20 rep #PMFLAG
3309 .LONGA on
3310 .MNLIST
3311 F82A46 98 tya ; A = 0
3312 F82A47 F5 00 sbc <0,x
3313 F82A49 95 00 sta <0,x
3314 F82A4B 98 tya
3315 F82A4C F5 02 sbc <2,x
3316 F82A4E 95 02 sta <2,x
3317 F82A50 98 tya
Tue Jul 17 11:00:16 2018 Page 14
3318 F82A51 F5 04 sbc <4,x
3319 F82A53 95 04 sta <4,x
3320 F82A55 98 tya
3321 F82A56 F5 06 sbc <6,x
3322 F82A58 95 06 sta <6,x
3323 F82A5A ACC08
3324 F82A5A E2 20 sep #PMFLAG
3325 .LONGA off
3326 .MNLIST
3327 F82A5C 7A ply
3328 F82A5D 60 rts
3329 F82A5E
3330 ;----------------------------------------------------------
3331 ; implementazione SMULT signed integer
3332 ;----------------------------------------------------------
3333
3334 ; _iSMult8: moltiplicazione integer 8 bit signed
3335 ; In: ACM: signed integer 1
3336 ; IARG: signed integer 2
3337 ; Out: ACM..ACM+1 -> risultato integer signed (16 bit)
3338 ; X = 0
3339 ; CF = 0
3340 ; Uso: A,X,Y,ACM,IARG
3341 F82A5E _iSMult8:
3342 F82A5E A2 00 ldx #0
3343 F82A60 A5 18 LDA ACM
3344 F82A62 45 28 EOR IARG ; segno risultato
3345 F82A64 29 80 and #$80 ; bit 7 => segno
3346 F82A66 09 40 ora #$40 ; bit 6 => signed int
3347 F82A68 85 21 sta ACMSgn ; salva segno
3348 F82A6A 24 28 BIT IARG ; test segno IARG
3349 F82A6C 10 06 BPL ?01
3350 F82A6E 38 SEC ; complementa IARG
3351 F82A6F 8A txa
3352 F82A70 E5 28 SBC IARG
3353 F82A72 85 28 STA IARG
3354 F82A74 24 18 ?01: BIT ACM ; test segno ACM
3355 F82A76 10 06 BPL ?02
3356 F82A78 38 SEC ; complementa ACM
3357 F82A79 8A txa
3358 F82A7A E5 18 SBC ACM
3359 F82A7C 85 18 STA ACM
3360 F82A7E 20 6E 29 ?02: JSR _iUMult8 ; moltiplicazione unsigned (X = 0)
3361 F82A81 C0 02 cpy #$02 ; min size WORD ?
3362 F82A83 F0 0D beq ?02b ; si
3363 ; se ACM <= 7F allora min size = BYTE
3364 F82A85 A5 18 lda ACM
3365 F82A87 C9 80 cmp #$80
3366 F82A89 90 07 bcc ?02b
3367 F82A8B D0 04 bne ?02a ; ACM > 80 => WORD
3368 ; ACM = 80 -- se risultato negativo => BYTE
3369 F82A8D 24 21 bit ACMSgn
3370 F82A8F 30 05 bmi ?02c ; ACM BYTE negativo
3371 F82A91 C8 ?02a: iny ; ACM WORD
3372 F82A92 24 21 ?02b: bit ACMSgn ; Flag N = segno risultato
3373 F82A94 10 0A BPL ?03 ; risultato positivo
3374 F82A96 ?02c: ACC16
Tue Jul 17 11:00:16 2018 Page 15
3375 F82A96 C2 20 rep #PMFLAG
3376 .LONGA on
3377 .MNLIST
3378 F82A98 8A txa
3379 F82A99 38 sec ; risultato negativo: complementa ACM
3380 F82A9A E5 18 sbc ACM
3381 F82A9C 85 18 sta ACM
3382 F82A9E ACC08
3383 F82A9E E2 20 sep #PMFLAG
3384 .LONGA off
3385 .MNLIST
3386 F82AA0 84 22 ?03: sty ACMMinSize
3387 F82AA2 18 clc
3388 F82AA3 60 RTS
3389 F82AA4
3390 ; _iSMult16: moltiplicazione integer 16 bit signed
3391 ; In: ACM, ACM+1: signed integer 1
3392 ; IARG, IARG+1: signed integer 2
3393 ; Out: ACM..ACM+3 -> risultato integer signed (32 bit)
3394 ; X = 0
3395 ; CF = 0
3396 ; Uso: A,X,Y,ACM,IARG
3397 F82AA4 _iSMult16:
3398 F82AA4 A2 00 ldx #0
3399 F82AA6 A5 19 LDA ACM+1
3400 F82AA8 45 29 EOR IARG+1 ; segno risultato
3401 F82AAA 29 80 and #$80 ; bit 7 => segno
3402 F82AAC 09 40 ora #$40 ; bit 6 => signed int
3403 F82AAE 85 21 sta ACMSgn ; salva segno
3404 F82AB0 ACC16
3405 F82AB0 C2 20 rep #PMFLAG
3406 .LONGA on
3407 .MNLIST
3408 F82AB2 24 28 BIT IARG ; test segno IARG
3409 F82AB4 10 06 BPL ?01
3410 F82AB6 38 sec ; complementa IARG
3411 F82AB7 8A txa
3412 F82AB8 E5 28 sbc IARG
3413 F82ABA 85 28 sta IARG
3414 F82ABC 24 18 ?01: BIT ACM ; test segno ACM
3415 F82ABE 10 06 BPL ?02
3416 F82AC0 38 sec ; complementa ACM
3417 F82AC1 8A txa
3418 F82AC2 E5 18 sbc ACM
3419 F82AC4 85 18 sta ACM
3420 F82AC6 ?02: ACC08
3421 F82AC6 E2 20 sep #PMFLAG
3422 .LONGA off
3423 .MNLIST
3424 F82AC8 20 8F 29 JSR _iUMult16 ; moltiplicazione unsigned (X = 0)
3425 F82ACB C0 04 cpy #$04 ; min size LONG ?
3426 F82ACD F0 13 beq ?02b ; si
3427 ; se ACM <= 7FFF allora min size = WORD
3428 F82ACF ACC16
3429 F82ACF C2 20 rep #PMFLAG
3430 .LONGA on
3431 .MNLIST
Tue Jul 17 11:00:16 2018 Page 16
3432 F82AD1 A5 18 lda ACM
3433 F82AD3 C9 00 80 cmp #$8000
3434 F82AD6 ACC08
3435 F82AD6 E2 20 sep #PMFLAG
3436 .LONGA off
3437 .MNLIST
3438 F82AD8 90 08 bcc ?02b ; ACM < 8000 => WORD
3439 F82ADA D0 04 bne ?02a ; ACM > 8000 => LONG
3440 ; ACM = 8000 -- se risultato negativo => WORD
3441 F82ADC 24 21 bit ACMSgn
3442 F82ADE 30 06 bmi ?02c ; ACM WORD negativo
3443 F82AE0 C8 ?02a: iny ; ACM LONG
3444 F82AE1 C8 iny
3445 F82AE2 24 21 ?02b: bit ACMSgn ; Flag N = segno risultato
3446 F82AE4 10 0F BPL ?03 ; risultato positivo
3447 F82AE6 ?02c: ACC16
3448 F82AE6 C2 20 rep #PMFLAG
3449 .LONGA on
3450 .MNLIST
3451 F82AE8 8A txa
3452 F82AE9 38 sec ; risultato negativo: complementa ACM
3453 F82AEA E5 18 sbc ACM
3454 F82AEC 85 18 sta ACM
3455 F82AEE 8A TXA ; A = 0
3456 F82AEF E5 1A sbc ACM+2
3457 F82AF1 85 1A sta ACM+2
3458 F82AF3 ACC08
3459 F82AF3 E2 20 sep #PMFLAG
3460 .LONGA off
3461 .MNLIST
3462 F82AF5 84 22 ?03: sty ACMMinSize
3463 F82AF7 18 clc
3464 F82AF8 60 RTS
3465
3466 ; _iSMult32: moltiplicazione integer 32 bit signed
3467 ; In: ACM..ACM+3: signed integer 1
3468 ; IARG..IARG+3: signed integer 2
3469 ; Out: ACM..ACM+7 -> risultato integer signed (64 bit)
3470 ; X = 0
3471 ; CF = 0
3472 ; Uso: A,X,Y,ACM,IARG
3473 F82AF9 _iSMult32:
3474 F82AF9 A2 00 ldx #0
3475 F82AFB A5 1B LDA ACM+3
3476 F82AFD 45 2B EOR IARG+3 ; segno risultato
3477 F82AFF 29 80 and #$80 ; bit 7 => segno
3478 F82B01 09 40 ora #$40 ; bit 6 => signed int
3479 F82B03 85 21 sta ACMSgn ; salva segno
3480 F82B05 ACC16
3481 F82B05 C2 20 rep #PMFLAG
3482 .LONGA on
3483 .MNLIST
3484 F82B07 24 2A BIT IARG+2 ; test segno IARG
3485 F82B09 10 0B BPL ?01
3486 F82B0B 38 sec ; complementa IARG
3487 F82B0C 8A txa
3488 F82B0D E5 28 sbc IARG
Tue Jul 17 11:00:16 2018 Page 17
3489 F82B0F 85 28 sta IARG
3490 F82B11 8A txa
3491 F82B12 E5 2A sbc IARG+2
3492 F82B14 85 2A sta IARG+2
3493 F82B16 24 1A ?01: BIT ACM+2 ; test segno ACM
3494 F82B18 10 0B BPL ?02
3495 F82B1A 38 sec ; complementa ACM
3496 F82B1B 8A txa
3497 F82B1C E5 18 sbc ACM
3498 F82B1E 85 18 sta ACM
3499 F82B20 8A txa
3500 F82B21 E5 1A sbc ACM+2
3501 F82B23 85 1A sta ACM+2
3502 F82B25 ?02: ACC08
3503 F82B25 E2 20 sep #PMFLAG
3504 .LONGA off
3505 .MNLIST
3506 F82B27 20 B5 29 JSR _iUMult32 ; moltiplicazione unsigned
3507 F82B2A C0 08 cpy #$08 ; min size QUAD ?
3508 F82B2C F0 1B beq ?02b ; si
3509 ; se ACM <= 7FFFFFFF allora min size = LONG
3510 F82B2E ACC16
3511 F82B2E C2 20 rep #PMFLAG
3512 .LONGA on
3513 .MNLIST
3514 F82B30 A5 1A lda ACM+2
3515 F82B32 C9 00 80 cmp #$8000
3516 F82B35 ACC08
3517 F82B35 E2 20 sep #PMFLAG
3518 .LONGA off
3519 .MNLIST
3520 F82B37 90 10 bcc ?02b ; ACM < 80000000 => LONG
3521 F82B39 D0 0C bne ?02a ; ACM > 80000000 => QUAD
3522 F82B3B ACC16
3523 F82B3B C2 20 rep #PMFLAG
3524 .LONGA on
3525 .MNLIST
3526 F82B3D A5 18 lda ACM
3527 ;cmp #$0000
3528 F82B3F ACC08
3529 F82B3F E2 20 sep #PMFLAG
3530 .LONGA off
3531 .MNLIST
3532 F82B41 D0 04 bne ?02a ; ACM > 80000000 => QUAD
3533 ; ACM = 80000000 -- se risultato negativo => LONG
3534 F82B43 24 21 bit ACMSgn
3535 F82B45 30 06 bmi ?02c ; ACM LONG negativo
3536 F82B47 A0 08 ?02a: ldy #$08 ; ACM QUAD
3537 F82B49 24 21 ?02b: bit ACMSgn ; Flag N = segno risultato
3538 F82B4B 10 05 BPL ?03 ; risultato positivo
3539 F82B4D 20 3E 2A ?02c: JSR _iNegACM ; risultato negativo: complementa ACM
3540 F82B50 A2 00 ldx #0 ; X = 0
3541 F82B52 84 22 ?03: sty ACMMinSize
3542 F82B54 18 clc
3543 F82B55 60 rts
3544 F82B56
3545 ; _iSMult64: moltiplicazione integer 64 bit signed
Tue Jul 17 11:00:16 2018 Page 18
3546 ; In: ACM..ACM+7: signed integer 1
3547 ; IARG..IARG+7: signed integer 2
3548 ; Out: ACM..ACM+7 -> risultato integer signed (128 bit LOW)
3549 ; FOP..FOP+7 -> risultato integer signed (128 bit HIGH)
3550 ;
3551 ; CF = 0 -> risultato OK
3552 ; CF = 1 -> signed overflow
3553 ; Uso: A,X,Y,ACM,IARG,FOP
3554 F82B56 _iSMult64:
3555 F82B56 A5 1F LDA ACM+7
3556 F82B58 45 2F EOR IARG+7 ; segno risultato
3557 F82B5A 29 80 and #$80 ; bit 7 => segno
3558 F82B5C 09 40 ora #$40 ; bit 6 => signed int
3559 F82B5E 85 21 sta ACMSgn ; salva segno
3560 F82B60 24 2F BIT IARG+7 ; test segno IARG
3561 F82B62 10 03 BPL ?01
3562 F82B64 20 3A 2A JSR _iNegIARG ; complementa IARG
3563 F82B67 24 1F ?01: BIT ACM+7 ; test segno ACM
3564 F82B69 10 03 BPL ?02
3565 F82B6B 20 3E 2A JSR _iNegACM ; complementa ACM
3566 F82B6E 20 EA 29 ?02: JSR _iUMult64 ; moltiplicazione unsigned
3567 F82B71 B0 1A bcs ?10 ; overflow (risultato a 128 bit)
3568 ; risultato in 64 bit -- se MSB = 0 risultato ok -- qui CF = 0
3569 F82B73 ACC16
3570 F82B73 C2 20 rep #PMFLAG
3571 .LONGA on
3572 .MNLIST
3573 F82B75 A5 1E lda ACM+6
3574 F82B77 10 12 bpl ?08 ; OK -- CF = 0
3575 F82B79 C9 00 80 cmp #$8000 ; qui imposta CF = 1
3576 F82B7C D0 0D bne ?08 ; ACM > 8000000000000000 => overflow
3577 F82B7E A6 21 ldx ACMSgn
3578 F82B80 10 09 bpl ?08 ; positivo => overflow
3579 F82B82 A5 1C lda ACM+4
3580 F82B84 05 1A ora ACM+2
3581 F82B86 05 18 ora ACM+0
3582 F82B88 D0 01 bne ?08 ; ACM > 8000000000000000 => overflow
3583 ; ACM = 8000000000000000 negativo => OK
3584 F82B8A 18 clc
3585 F82B8B ?08: ACC08
3586 F82B8B E2 20 sep #PMFLAG
3587 .LONGA off
3588 .MNLIST
3589 F82B8D 24 21 ?10: bit ACMSgn
3590 F82B8F 10 0A bpl ?12
3591 F82B91 08 php ; salva CF
3592 F82B92 20 3E 2A jsr _iNegACM ; complementa
3593 F82B95 A2 32 ldx #FOP
3594 F82B97 20 41 2A jsr _iNegXnc
3595 F82B9A 28 plp
3596 F82B9B 60 ?12: rts
3597
3598 ;----------------------------------------------------------
3599 ; implementazione DIV unsigned integer
3600 ;----------------------------------------------------------
3601
3602 ; _iUDiv8: divisione integer 8 bit unsigned
Tue Jul 17 11:00:16 2018 Page 19
3603 ; In: ACM: unsigned integer 1
3604 ; IARG: unsigned integer 2
3605 ; Out: ACM -> integer unsigned ACM / IARG
3606 ; IARG -> integer unsigned ACM MOD IARG
3607 ; X = minima size quoziente
3608 ; Y = minima size remainder
3609 ; CF = 1 se IARG = 0 altrimenti CF = 0
3610 ; Uso: A,X,Y,ACM,IARG,FOP
3611 F82B9C _iUDiv8:
3612 F82B9C A5 28 lda IARG
3613 F82B9E D0 02 bne ?02
3614 F82BA0 38 sec ; division by sero
3615 F82BA1 60 rts
3616 F82BA2 64 32 ?02: stz FOP ; azzera rem
3617 F82BA4 A2 08 ldx #8 ; loop 8 bit
3618 F82BA6 A5 18 lda ACM ; quoziente
3619 F82BA8 2A ?04: rol a
3620 F82BA9 26 32 rol FOP
3621 F82BAB A8 tay
3622 F82BAC 38 sec
3623 F82BAD A5 32 lda FOP
3624 F82BAF E5 28 sbc IARG
3625 F82BB1 90 02 bcc ?06
3626 F82BB3 85 32 sta FOP
3627 F82BB5 98 ?06: tya
3628 F82BB6 CA dex
3629 F82BB7 D0 EF bne ?04
3630 F82BB9 2A rol a
3631 F82BBA 85 18 sta ACM ; quot
3632 F82BBC A5 32 lda FOP
3633 F82BBE 85 28 sta IARG
3634 F82BC0 A0 01 ldy #1
3635 F82BC2 BB tyx
3636 F82BC3 86 22 stx ACMMinSize
3637 F82BC5 84 23 sty IARGMinSize
3638 F82BC7 18 clc
3639 F82BC8 60 rts
3640
3641 ; _iUDiv16: divisione integer 16 bit unsigned
3642 ; In: ACM: unsigned integer 1
3643 ; IARG: unsigned integer 2
3644 ; Out: ACM -> integer unsigned ACM / IARG
3645 ; IARG -> integer unsigned ACM MOD IARG
3646 ; X = minima size quoziente
3647 ; Y = minima size remainder
3648 ; CF = 1 se IARG = 0 altrimenti CF = 0
3649 ; Uso: A,X,Y,ACM,IARG,FOP
3650 F82BC9 _iUDiv16:
3651 F82BC9 ACC16
3652 F82BC9 C2 20 rep #PMFLAG
3653 .LONGA on
3654 .MNLIST
3655 F82BCB A5 28 lda IARG
3656 F82BCD D0 04 bne ?02
3657 F82BCF ACC08
3658 F82BCF E2 20 sep #PMFLAG
3659 .LONGA off
Tue Jul 17 11:00:16 2018 Page 20
3660 .MNLIST
3661 F82BD1 38 sec ; division by sero
3662 F82BD2 60 rts
3663 F82BD3 A2 10 ?02: ldx #16 ; loop 16 bit
3664 F82BD5 CPU16
3665 F82BD5 C2 30 rep #(PMFLAG.OR.PXFLAG)
3666 .LONGA on
3667 .LONGI on
3668 .MNLIST
3669 F82BD7 64 32 stz FOP ; azzera rem
3670 F82BD9 A5 18 lda ACM ; quoziente
3671 F82BDB 2A ?04: rol a
3672 F82BDC 26 32 rol FOP
3673 F82BDE A8 tay
3674 F82BDF 38 sec
3675 F82BE0 A5 32 lda FOP
3676 F82BE2 E5 28 sbc IARG
3677 F82BE4 90 02 bcc ?06
3678 F82BE6 85 32 sta FOP
3679 F82BE8 98 ?06: tya
3680 F82BE9 CA dex
3681 F82BEA D0 EF bne ?04
3682 F82BEC 2A rol a
3683 F82BED 85 18 sta ACM ; quoziente
3684 F82BEF A5 32 lda FOP
3685 F82BF1 85 28 sta IARG ; remainder
3686 F82BF3 CPU08
3687 F82BF3 E2 30 sep #(PMFLAG.OR.PXFLAG)
3688 .LONGA off
3689 .LONGI off
3690 .MNLIST
3691 F82BF5 A0 02 ldy #2
3692 F82BF7 BB tyx
3693 F82BF8 EB xba ; A = hi rem
3694 F82BF9 D0 01 bne ?08 ; rem 16 bit
3695 F82BFB 88 dey ; rem 8 bit
3696 F82BFC A5 19 ?08: lda ACM+1 ; A = hi quot
3697 F82BFE D0 01 bne ?10 ; quot 16 bit
3698 F82C00 CA dex ; quot 8 bit
3699 F82C01 18 ?10: clc
3700 F82C02 86 22 stx ACMMinSize
3701 F82C04 84 23 sty IARGMinSize
3702 F82C06 60 rts
3703
3704 ; _iUDiv32: divisione integer 32 bit unsigned
3705 ; In: ACM: unsigned integer 1
3706 ; IARG: unsigned integer 2
3707 ; Out: ACM -> integer unsigned ACM / IARG
3708 ; IARG -> integer unsigned ACM MOD IARG
3709 ; X = minima size quoziente
3710 ; Y = minima size remainder
3711 ; CF = 1 se IARG = 0 altrimenti CF = 0
3712 ; Uso: A,X,Y,ACM,IARG,FOP
3713 F82C07 _iUDiv32:
3714 F82C07 ACC16
3715 F82C07 C2 20 rep #PMFLAG
3716 .LONGA on
Tue Jul 17 11:00:16 2018 Page 21
3717 .MNLIST
3718 F82C09 A5 28 lda IARG
3719 F82C0B 05 2A ora IARG+2
3720 F82C0D D0 04 bne ?02
3721 F82C0F ACC08
3722 F82C0F E2 20 sep #PMFLAG
3723 .LONGA off
3724 .MNLIST
3725 F82C11 38 sec ; division by sero
3726 F82C12 60 rts
3727 F82C13 A2 20 ?02: ldx #32 ; loop 32 bit
3728 F82C15 CPU16
3729 F82C15 C2 30 rep #(PMFLAG.OR.PXFLAG)
3730 .LONGA on
3731 .LONGI on
3732 .MNLIST
3733 F82C17 64 32 stz FOP ; azzera rem
3734 F82C19 64 34 stz FOP+2
3735 F82C1B 26 18 ?04: rol ACM ; quot
3736 F82C1D 26 1A rol ACM+2
3737 F82C1F 26 32 rol FOP
3738 F82C21 26 34 rol FOP+2
3739 F82C23 38 sec
3740 F82C24 A5 32 lda FOP
3741 F82C26 E5 28 sbc IARG
3742 F82C28 A8 tay
3743 F82C29 A5 34 lda FOP+2
3744 F82C2B E5 2A sbc IARG+2
3745 F82C2D 90 04 bcc ?06
3746 F82C2F 84 32 sty FOP
3747 F82C31 85 34 sta FOP+2
3748 F82C33 CA ?06: dex
3749 F82C34 D0 E5 bne ?04
3750 F82C36 INDEX08
3751 F82C36 E2 10 sep #PXFLAG
3752 .LONGI off
3753 .MNLIST
3754 F82C38 A0 04 ldy #4
3755 F82C3A BB tyx
3756 F82C3B 26 18 rol ACM
3757 F82C3D 26 1A rol ACM+2 ; quoziente
3758 F82C3F A5 32 lda FOP
3759 F82C41 85 28 sta IARG ; remainder
3760 F82C43 A5 34 lda FOP+2
3761 F82C45 85 2A sta IARG+2 ; C = hi rem
3762 F82C47 D0 02 bne ?08 ; rem 32 bit
3763 F82C49 A0 02 ldy #2 ; rem 16 bit
3764 F82C4B A5 1A ?08: lda ACM+2 ; C = hi quot
3765 F82C4D D0 02 bne ?10 ; quot 32 bit
3766 F82C4F A2 02 ldx #2 ; quot 16 bit
3767 F82C51 ?10: CPU08
3768 F82C51 E2 30 sep #(PMFLAG.OR.PXFLAG)
3769 .LONGA off
3770 .LONGI off
3771 .MNLIST
3772 F82C53 86 22 stx ACMMinSize
3773 F82C55 84 23 sty IARGMinSize
Tue Jul 17 11:00:16 2018 Page 22
3774 F82C57 18 clc
3775 F82C58 60 rts
3776
3777 ; _iUDiv64: divisione integer 64 bit unsigned
3778 ; In: ACM: unsigned integer 1
3779 ; IARG: unsigned integer 2
3780 ; Out: ACM -> integer unsigned ACM / IARG
3781 ; IARG -> integer unsigned ACM MOD IARG
3782 ; X = minima size quoziente
3783 ; Y = minima size remainder
3784 ; CF = 1 se IARG = 0 altrimenti CF = 0
3785 ; Uso: A,X,Y,ACM,IARG,FOP
3786 F82C59 _iUDiv64:
3787 F82C59 ACC16
3788 F82C59 C2 20 rep #PMFLAG
3789 .LONGA on
3790 .MNLIST
3791 F82C5B A5 28 lda IARG
3792 F82C5D 05 2A ora IARG+2
3793 F82C5F 05 2C ora IARG+4
3794 F82C61 05 2E ora IARG+6
3795 F82C63 D0 04 bne ?02
3796 F82C65 ACC08
3797 F82C65 E2 20 sep #PMFLAG
3798 .LONGA off
3799 .MNLIST
3800 F82C67 38 sec ; division by sero
3801 F82C68 60 rts
3802 F82C69 A2 40 ?02: ldx #64 ; loop 32 bit
3803 F82C6B CPU16
3804 F82C6B C2 30 rep #(PMFLAG.OR.PXFLAG)
3805 .LONGA on
3806 .LONGI on
3807 .MNLIST
3808 F82C6D 64 32 stz FOP ; azzera rem
3809 F82C6F 64 34 stz FOP+2
3810 F82C71 64 36 stz FOP+4
3811 F82C73 64 38 stz FOP+6
3812 F82C75 48 pha ; 2 word temp.
3813 F82C76 48 pha
3814 F82C77 26 18 ?04: rol ACM ; quot
3815 F82C79 26 1A rol ACM+2
3816 F82C7B 26 1C rol ACM+4
3817 F82C7D 26 1E rol ACM+6
3818 F82C7F 26 32 rol FOP
3819 F82C81 26 34 rol FOP+2
3820 F82C83 26 36 rol FOP+4
3821 F82C85 26 38 rol FOP+6
3822 F82C87 38 sec
3823 F82C88 A5 32 lda FOP
3824 F82C8A E5 28 sbc IARG
3825 F82C8C 83 01 sta $01,s
3826 F82C8E A5 34 lda FOP+2
3827 F82C90 E5 2A sbc IARG+2
3828 F82C92 83 03 sta $03,s
3829 F82C94 A5 36 lda FOP+4
3830 F82C96 E5 2C sbc IARG+4
Tue Jul 17 11:00:16 2018 Page 23
3831 F82C98 A8 tay
3832 F82C99 A5 38 lda FOP+6
3833 F82C9B E5 2E sbc IARG+6
3834 F82C9D 90 0C bcc ?06
3835 F82C9F 84 36 sty FOP+4
3836 F82CA1 85 38 sta FOP+6
3837 F82CA3 A3 01 lda $01,s
3838 F82CA5 85 32 sta FOP
3839 F82CA7 A3 03 lda $03,s
3840 F82CA9 85 34 sta FOP+2
3841 F82CAB CA ?06: dex
3842 F82CAC D0 C9 bne ?04
3843 F82CAE INDEX08
3844 F82CAE E2 10 sep #PXFLAG
3845 .LONGI off
3846 .MNLIST
3847 F82CB0 A0 08 ldy #8
3848 F82CB2 BB tyx
3849 F82CB3 26 18 rol ACM
3850 F82CB5 26 1A rol ACM+2 ; quoziente
3851 F82CB7 26 1C rol ACM+4
3852 F82CB9 26 1E rol ACM+6
3853 F82CBB A5 32 lda FOP
3854 F82CBD 85 28 sta IARG ; remainder
3855 F82CBF A5 34 lda FOP+2
3856 F82CC1 85 2A sta IARG+2
3857 F82CC3 A5 36 lda FOP+4
3858 F82CC5 85 2C sta IARG+4
3859 F82CC7 A5 38 lda FOP+6
3860 F82CC9 85 2E sta IARG+6 ; C = hi rem
3861 F82CCB 05 2C ora IARG+4
3862 F82CCD D0 02 bne ?08 ; rem 64 bit
3863 F82CCF A0 04 ldy #4 ; rem 32 bit
3864 F82CD1 A5 1E ?08: lda ACM+6 ; C = hi quot
3865 F82CD3 05 1C ora ACM+4
3866 F82CD5 D0 02 bne ?10 ; quot 64 bit
3867 F82CD7 A2 04 ldx #4 ; quot 32 bit
3868 F82CD9 68 ?10: pla ; scarta 2 word temp.
3869 F82CDA 68 pla
3870 F82CDB CPU08
3871 F82CDB E2 30 sep #(PMFLAG.OR.PXFLAG)
3872 .LONGA off
3873 .LONGI off
3874 .MNLIST
3875 F82CDD 86 22 stx ACMMinSize
3876 F82CDF 84 23 sty IARGMinSize
3877 F82CE1 18 clc
3878 F82CE2 60 rts
3879
3880 ;----------------------------------------------------------
3881 ; implementazione SDIV signed integer
3882 ;----------------------------------------------------------
3883
3884 ; _iSDiv8: divisione integer 8 bit signed
3885 ; In: ACM: signed integer 1
3886 ; IARG: signed integer 2
3887 ; Out: ACM -> integer signed ACM / IARG
Tue Jul 17 11:00:16 2018 Page 24
3888 ; IARG -> integer signed ACM MOD IARG
3889 ; X = minima size quoziente
3890 ; Y = minima size remainder
3891 ; CF = 1 se IARG = 0 altrimenti CF = 0
3892 ; VF = 1 se ACM overflow (quoziente)
3893 ; Uso: A,X,Y,ACM,IARG,FOP
3894 F82CE3 _iSDiv8:
3895 F82CE3 A5 28 lda IARG
3896 F82CE5 D0 02 bne ?02
3897 F82CE7 38 sec ; division by sero
3898 F82CE8 60 rts
3899 F82CE9 A2 00 ?02: ldx #0
3900 F82CEB 45 18 EOR ACM ; segno risultato
3901 F82CED 29 80 and #$80 ; bit 7 => segno
3902 F82CEF 09 40 ora #$40 ; bit 6 => signed int
3903 F82CF1 85 21 sta ACMSgn ; salva segno quot.
3904 F82CF3 A5 18 LDA ACM
3905 F82CF5 29 80 and #$80 ; bit 7 => segno remainder = segno dividendo
3906 F82CF7 09 40 ora #$40 ; bit 6 => signed int
3907 F82CF9 85 31 sta IARGSgn ; salva segno remainder
3908 F82CFB 24 28 BIT IARG ; test segno IARG
3909 F82CFD 10 06 BPL ?04
3910 F82CFF 38 SEC ; complementa IARG
3911 F82D00 8A txa
3912 F82D01 E5 28 SBC IARG
3913 F82D03 85 28 STA IARG
3914 F82D05 24 18 ?04: BIT ACM ; test segno ACM
3915 F82D07 10 06 BPL ?06
3916 F82D09 38 SEC ; complementa ACM
3917 F82D0A 8A txa
3918 F82D0B E5 18 SBC ACM
3919 F82D0D 85 18 STA ACM
3920 F82D0F 20 9C 2B ?06: JSR _iUDiv8
3921 F82D12 24 21 bit ACMSgn
3922 F82D14 10 07 bpl ?08
3923 F82D16 38 sec ; quot. negativo
3924 F82D17 A9 00 lda #0
3925 F82D19 E5 18 sbc ACM
3926 F82D1B 85 18 sta ACM
3927 F82D1D 24 31 ?08: bit IARGSgn
3928 F82D1F 10 07 bpl ?10
3929 F82D21 38 sec ; remainder negativo
3930 F82D22 A9 00 lda #0
3931 F82D24 E5 28 sbc IARG
3932 F82D26 85 28 sta IARG
3933 F82D28 18 ?10: clc
3934 F82D29 B8 clv ; remainder mai provoca overflow
3935 F82D2A A5 18 lda ACM ; confronta segno quoziente
3936 F82D2C 45 21 eor ACMSgn ; con segno aspettato
3937 F82D2E 10 02 bpl ?12 ; segni concordi -- OK
3938 F82D30 E2 40 sep #PVFLAG ; segnni discordi => overflow
3939 F82D32 60 ?12: RTS
3940
3941 ; _iSDiv16: divisione integer 16 bit signed
3942 ; In: ACM: signed integer 1
3943 ; IARG: signed integer 2
3944 ; Out: ACM -> integer signed ACM / IARG
Tue Jul 17 11:00:16 2018 Page 25
3945 ; IARG -> integer signed ACM MOD IARG
3946 ; X = minima size quoziente
3947 ; Y = minima size remainder
3948 ; CF = 1 se IARG = 0 altrimenti CF = 0
3949 ; VF = 1 se ACM overflow (quoziente)
3950 ; Uso: A,X,Y,ACM,IARG,FOP
3951 F82D33 _iSDiv16:
3952 F82D33 A5 28 lda IARG
3953 F82D35 05 29 ora IARG+1
3954 F82D37 D0 02 bne ?02
3955 F82D39 38 sec ; division by sero
3956 F82D3A 60 rts
3957 F82D3B A2 00 ?02: ldx #0
3958 F82D3D A5 29 lda IARG+1
3959 F82D3F 45 19 EOR ACM+1 ; segno risultato
3960 F82D41 29 80 and #$80 ; bit 7 => segno
3961 F82D43 09 40 ora #$40 ; bit 6 => signed int
3962 F82D45 85 21 sta ACMSgn ; salva segno quot.
3963 F82D47 A5 19 LDA ACM+1
3964 F82D49 29 80 and #$80 ; bit 7 => segno remainder = segno dividendo
3965 F82D4B 09 40 ora #$40 ; bit 6 => signed int
3966 F82D4D 85 31 sta IARGSgn ; salva segno remainder
3967 F82D4F 10 0A BPL ?04
3968 F82D51 ACC16
3969 F82D51 C2 20 rep #PMFLAG
3970 .LONGA on
3971 .MNLIST
3972 F82D53 38 SEC ; complementa ACM
3973 F82D54 8A txa
3974 F82D55 E5 18 SBC ACM
3975 F82D57 85 18 STA ACM
3976 F82D59 ACC08
3977 F82D59 E2 20 sep #PMFLAG
3978 .LONGA off
3979 .MNLIST
3980 F82D5B 24 29 ?04: BIT IARG+1 ; test segno IARG
3981 F82D5D 10 0A BPL ?06
3982 F82D5F ACC16
3983 F82D5F C2 20 rep #PMFLAG
3984 .LONGA on
3985 .MNLIST
3986 F82D61 38 SEC ; complementa IARG
3987 F82D62 8A txa
3988 F82D63 E5 28 SBC IARG
3989 F82D65 85 28 STA IARG
3990 F82D67 ACC08
3991 F82D67 E2 20 sep #PMFLAG
3992 .LONGA off
3993 .MNLIST
3994 F82D69 20 C9 2B ?06: JSR _iUDiv16
3995 ; Y = minima size remainder -- aggiusta IARG (remainder)
3996 F82D6C A2 28 ldx #IARG
3997 F82D6E 20 8A 2D jsr post16
3998 F82D71 84 23 sty IARGMinSize
3999 F82D73 A4 22 ldy ACMMinSize
4000 ; Y = minima size quot. -- aggiusta ACM (quot.)
4001 F82D75 A2 18 ldx #ACM
Tue Jul 17 11:00:16 2018 Page 26
4002 F82D77 20 8A 2D jsr post16
4003 F82D7A 84 22 sty ACMMinSize
4004 F82D7C BB tyx
4005 F82D7D A4 23 ldy IARGMinSize
4006 F82D7F 18 clc
4007 F82D80 B8 clv ; remainder mai provoca overflow
4008 F82D81 A5 19 lda ACM+1 ; confronta segno quoziente
4009 F82D83 45 21 eor ACMSgn ; con segno aspettato
4010 F82D85 10 02 bpl ?12 ; segni concordi -- OK
4011 F82D87 E2 40 sep #PVFLAG ; segnni discordi => overflow
4012 F82D89 60 ?12: RTS
4013
4014 ; post16 - aggiusta risultato per _iSDiv16
4015 ; In Y = minima size
4016 ; X = ptr ACM/IARG
4017 ; Out: Y = minima size
4018 ; ACM/IARG eventualmente complementato
4019 F82D8A post16:
4020 F82D8A C0 02 cpy #$02 ; min size WORD ?
4021 F82D8C F0 0D beq ?02b ; si
4022 ; se ACM/IARG <= 7F allora min size = BYTE
4023 F82D8E B5 00 lda <0,x
4024 F82D90 C9 80 cmp #$80
4025 F82D92 90 07 bcc ?02b
4026 F82D94 D0 04 bne ?02a ; ACM/IARG > 80 => WORD
4027 ; ACM/IARG = 80 -- se risultato negativo => BYTE
4028 F82D96 34 09 bit <9,x
4029 F82D98 30 05 bmi ?02c ; ACM/IARG BYTE negativo
4030 F82D9A C8 ?02a: iny ; ACM/IARG WORD
4031 F82D9B 34 09 ?02b: bit <9,x ; Flag N = segno risultato
4032 F82D9D 10 0C BPL ?03 ; risultato positivo
4033 F82D9F ?02c: ACC16
4034 F82D9F C2 20 rep #PMFLAG
4035 .LONGA on
4036 .MNLIST
4037 F82DA1 A9 00 00 lda #0
4038 F82DA4 38 sec ; risultato negativo: complementa ACM/IARG
4039 F82DA5 F5 00 sbc <0,x
4040 F82DA7 95 00 sta <0,x
4041 F82DA9 ACC08
4042 F82DA9 E2 20 sep #PMFLAG
4043 .LONGA off
4044 .MNLIST
4045 F82DAB 60 ?03: rts
4046
4047 ; _iSDiv32: divisione integer 32 bit signed
4048 ; In: ACM: signed integer 1
4049 ; IARG: signed integer 2
4050 ; Out: ACM -> integer signed ACM / IARG
4051 ; IARG -> integer signed ACM MOD IARG
4052 ; X = minima size quoziente
4053 ; Y = minima size remainder
4054 ; CF = 1 se IARG = 0 altrimenti CF = 0
4055 ; VF = 1 se ACM overflow (quoziente)
4056 ; Uso: A,X,Y,ACM,IARG,FOP
4057 F82DAC _iSDiv32:
4058 F82DAC ACC16
Tue Jul 17 11:00:16 2018 Page 27
4059 F82DAC C2 20 rep #PMFLAG
4060 .LONGA on
4061 .MNLIST
4062 F82DAE A5 28 lda IARG
4063 F82DB0 05 2A ora IARG+2
4064 F82DB2 ACC08
4065 F82DB2 E2 20 sep #PMFLAG
4066 .LONGA off
4067 .MNLIST
4068 F82DB4 D0 02 bne ?02
4069 F82DB6 38 sec ; division by sero
4070 F82DB7 60 rts
4071 F82DB8 A2 00 ?02: ldx #0
4072 F82DBA A5 2B lda IARG+3
4073 F82DBC 45 1B EOR ACM+3 ; segno risultato
4074 F82DBE 29 80 and #$80 ; bit 7 => segno
4075 F82DC0 09 40 ora #$40 ; bit 6 => signed int
4076 F82DC2 85 21 sta ACMSgn ; salva segno quot.
4077 F82DC4 A5 1B LDA ACM+3
4078 F82DC6 29 80 and #$80 ; bit 7 => segno remainder = segno dividendo
4079 F82DC8 09 40 ora #$40 ; bit 6 => signed int
4080 F82DCA 85 31 sta IARGSgn ; salva segno remainder
4081 F82DCC 10 0F BPL ?04
4082 F82DCE ACC16
4083 F82DCE C2 20 rep #PMFLAG
4084 .LONGA on
4085 .MNLIST
4086 F82DD0 38 SEC ; complementa ACM
4087 F82DD1 8A txa
4088 F82DD2 E5 18 SBC ACM
4089 F82DD4 85 18 STA ACM
4090 F82DD6 8A txa
4091 F82DD7 E5 1A SBC ACM+2
4092 F82DD9 85 1A STA ACM+2
4093 F82DDB ACC08
4094 F82DDB E2 20 sep #PMFLAG
4095 .LONGA off
4096 .MNLIST
4097 F82DDD 24 2B ?04: BIT IARG+3 ; test segno IARG
4098 F82DDF 10 0F BPL ?06
4099 F82DE1 ACC16
4100 F82DE1 C2 20 rep #PMFLAG
4101 .LONGA on
4102 .MNLIST
4103 F82DE3 38 SEC ; complementa IARG
4104 F82DE4 8A txa
4105 F82DE5 E5 28 SBC IARG
4106 F82DE7 85 28 STA IARG
4107 F82DE9 8A txa
4108 F82DEA E5 2A SBC IARG+2
4109 F82DEC 85 2A STA IARG+2
4110 F82DEE ACC08
4111 F82DEE E2 20 sep #PMFLAG
4112 .LONGA off
4113 .MNLIST
4114 F82DF0 20 07 2C ?06: JSR _iUDiv32
4115 ; Y = minima size remainder -- aggiusta IARG (remainder)
Tue Jul 17 11:00:16 2018 Page 28
4116 F82DF3 A2 28 ldx #IARG
4117 F82DF5 20 11 2E jsr post32
4118 F82DF8 84 23 sty IARGMinSize
4119 F82DFA A4 22 ldy ACMMinSize
4120 ; Y = minima size quot. -- aggiusta ACM (quot.)
4121 F82DFC A2 18 ldx #ACM
4122 F82DFE 20 11 2E jsr post32
4123 F82E01 84 22 sty ACMMinSize
4124 F82E03 BB tyx
4125 F82E04 A4 23 ldy IARGMinSize
4126 F82E06 18 clc
4127 F82E07 B8 clv ; remainder mai provoca overflow
4128 F82E08 A5 1B lda ACM+3 ; confronta segno quoziente
4129 F82E0A 45 21 eor ACMSgn ; con segno aspettato
4130 F82E0C 10 02 bpl ?12 ; segni concordi -- OK
4131 F82E0E E2 40 sep #PVFLAG ; segnni discordi => overflow
4132 F82E10 60 ?12: RTS
4133
4134 ; post32 - aggiusta risultato per _iSDiv32
4135 ; In Y = minima size
4136 ; X = ptr ACM/IARG
4137 ; Out: Y = minima size
4138 ; ACM/IARG eventualmente complementato
4139 F82E11 post32:
4140 F82E11 C0 04 cpy #$04 ; min size LONG ?
4141 F82E13 F0 13 beq ?02b ; si
4142 ; se ACM/IARG <= 7FFF allora min size = WORD
4143 F82E15 ACC16
4144 F82E15 C2 20 rep #PMFLAG
4145 .LONGA on
4146 .MNLIST
4147 F82E17 B5 00 lda <0,x
4148 F82E19 C9 00 80 cmp #$8000
4149 F82E1C ACC08
4150 F82E1C E2 20 sep #PMFLAG
4151 .LONGA off
4152 .MNLIST
4153 F82E1E 90 08 bcc ?02b
4154 F82E20 D0 04 bne ?02a ; ACM/IARG > 8000 => LONG
4155 ; ACM/IARG = 8000 -- se risultato negativo => BYTE
4156 F82E22 34 09 bit <9,x
4157 F82E24 30 06 bmi ?02c ; ACM/IARG WORD negativo
4158 F82E26 C8 ?02a: iny ; ACM/IARG LONG
4159 F82E27 C8 iny
4160 F82E28 34 09 ?02b: bit <9,x ; Flag N = segno risultato
4161 F82E2A 10 13 BPL ?03 ; risultato positivo
4162 F82E2C ?02c: ACC16
4163 F82E2C C2 20 rep #PMFLAG
4164 .LONGA on
4165 .MNLIST
4166 F82E2E A9 00 00 lda #0
4167 F82E31 38 sec ; risultato negativo: complementa ACM/IARG
4168 F82E32 F5 00 sbc <0,x
4169 F82E34 95 00 sta <0,x
4170 F82E36 A9 00 00 lda #0
4171 F82E39 F5 02 sbc <2,x
4172 F82E3B 95 02 sta <2,x
Tue Jul 17 11:00:16 2018 Page 29
4173 F82E3D ACC08
4174 F82E3D E2 20 sep #PMFLAG
4175 .LONGA off
4176 .MNLIST
4177 F82E3F 60 ?03: rts
4178
4179 ; _iSDiv64: divisione integer 64 bit signed
4180 ; In: ACM: signed integer 1
4181 ; IARG: signed integer 2
4182 ; Out: ACM -> integer signed ACM / IARG
4183 ; IARG -> integer signed ACM MOD IARG
4184 ; X = minima size quoziente
4185 ; Y = minima size remainder
4186 ; CF = 1 se IARG = 0 altrimenti CF = 0
4187 ; VF = 1 se ACM overflow (quoziente)
4188 ; Uso: A,X,Y,ACM,IARG,FOP
4189 F82E40 _iSDiv64:
4190 F82E40 ACC16
4191 F82E40 C2 20 rep #PMFLAG
4192 .LONGA on
4193 .MNLIST
4194 F82E42 A5 28 lda IARG
4195 F82E44 05 2A ora IARG+2
4196 F82E46 05 2C ora IARG+4
4197 F82E48 05 2E ora IARG+6
4198 F82E4A ACC08
4199 F82E4A E2 20 sep #PMFLAG
4200 .LONGA off
4201 .MNLIST
4202 F82E4C D0 02 bne ?02
4203 F82E4E 38 sec ; division by sero
4204 F82E4F 60 rts
4205 F82E50 A5 2F ?02: lda IARG+7
4206 F82E52 45 1F EOR ACM+7 ; segno risultato
4207 F82E54 29 80 and #$80 ; bit 7 => segno
4208 F82E56 09 40 ora #$40 ; bit 6 => signed int
4209 F82E58 85 21 sta ACMSgn ; salva segno quot.
4210 F82E5A A5 1F LDA ACM+7
4211 F82E5C 29 80 and #$80 ; bit 7 => segno remainder = segno dividendo
4212 F82E5E 09 40 ora #$40 ; bit 6 => signed int
4213 F82E60 85 31 sta IARGSgn ; salva segno remainder
4214 F82E62 10 03 BPL ?04
4215 F82E64 20 3E 2A jsr _iNegACM ; complementa ACM
4216 F82E67 24 2F ?04: BIT IARG+7 ; test segno IARG
4217 F82E69 10 03 BPL ?06
4218 F82E6B 20 3A 2A jsr _iNegIARG ; complementa IARG
4219 F82E6E 20 59 2C ?06: JSR _iUDiv64
4220 ; Y = minima size remainder -- aggiusta IARG (remainder)
4221 F82E71 A2 28 ldx #IARG
4222 F82E73 20 8F 2E jsr post64
4223 F82E76 84 23 sty IARGMinSize
4224 F82E78 A4 22 ldy ACMMinSize
4225 ; Y = minima size quot. -- aggiusta ACM (quot.)
4226 F82E7A A2 18 ldx #ACM
4227 F82E7C 20 8F 2E jsr post64
4228 F82E7F 84 22 sty ACMMinSize
4229 F82E81 BB tyx
Tue Jul 17 11:00:16 2018 Page 30
4230 F82E82 A4 23 ldy IARGMinSize
4231 F82E84 18 clc
4232 F82E85 B8 clv ; remainder mai provoca overflow
4233 F82E86 A5 1F lda ACM+7 ; confronta segno quoziente
4234 F82E88 45 21 eor ACMSgn ; con segno aspettato
4235 F82E8A 10 02 bpl ?12 ; segni concordi -- OK
4236 F82E8C E2 40 sep #PVFLAG ; segnni discordi => overflow
4237 F82E8E 60 ?12: RTS
4238
4239 ; post64 - aggiusta risultato per _iSDiv64
4240 ; In Y = minima size
4241 ; X = ptr ACM/IARG
4242 ; Out: Y = minima size
4243 ; ACM/IARG eventualmente complementato
4244 F82E8F post64:
4245 F82E8F C0 08 cpy #$08 ; min size QUAD ?
4246 F82E91 F0 1B beq ?02b ; si
4247 ; se ACM/IARG <= 7FFFFFFF allora min size = LONG
4248 F82E93 ACC16
4249 F82E93 C2 20 rep #PMFLAG
4250 .LONGA on
4251 .MNLIST
4252 F82E95 B5 02 lda <2,x
4253 F82E97 C9 00 80 cmp #$8000
4254 F82E9A ACC08
4255 F82E9A E2 20 sep #PMFLAG
4256 .LONGA off
4257 .MNLIST
4258 F82E9C 90 10 bcc ?02b ; ACM/IARG < 80000000 => LONG
4259 F82E9E D0 0C bne ?02a ; ACM/IARG > 80000000 => QUAD
4260 F82EA0 ACC16
4261 F82EA0 C2 20 rep #PMFLAG
4262 .LONGA on
4263 .MNLIST
4264 F82EA2 A5 18 lda ACM
4265 F82EA4 ACC08
4266 F82EA4 E2 20 sep #PMFLAG
4267 .LONGA off
4268 .MNLIST
4269 F82EA6 D0 04 bne ?02a ; ACM/IARG > 80000000 => QUAD
4270 ; ACM/IARG = 80000000 -- se risultato negativo => LONG
4271 F82EA8 34 09 bit <9,x
4272 F82EAA 30 06 bmi ?02c ; ACM/IARG LONG negativo
4273 F82EAC A0 08 ?02a: ldy #8 ; ACM/IARG QUAD
4274 F82EAE 34 09 ?02b: bit <9,x ; Flag N = segno risultato
4275 F82EB0 10 03 BPL ?03 ; risultato positivo
4276 F82EB2 20 40 2A ?02c: jsr _iNegX ; risultato negativo: complementa ACM/IARG
4277 F82EB5 60 ?03: rts
4278
4279 ;----------------------------------------------------------
4280 ; Funzioni 'move'
4281 ;----------------------------------------------------------
4282
4283 ; _iMovACM2A - copia ACM (in size e tipo) in IARG
4284 F82EB6 _iMovACM2A:
4285 F82EB6 A5 21 lda ACMSgn
4286 F82EB8 85 31 sta IARGSgn
Tue Jul 17 11:00:16 2018 Page 31
4287 F82EBA A6 20 ldx ACMSize
4288 F82EBC 86 30 stx IARGSize
4289 F82EBE CA dex
4290 F82EBF B5 18 ?01: lda ACM,x
4291 F82EC1 95 28 sta IARG,x
4292 F82EC3 CA dex
4293 F82EC4 10 F9 bpl ?01
4294 F82EC6 60 rts
4295 F82EC7
4296 ;----------------------------------------------------------
4297 ; Conversioni Stringa (decimale / hex) - Integer
4298 ;----------------------------------------------------------
4299
4300 ; _Str2Int - converte stringa decimale in intero
4301 ; In - C = offset stringa decimale
4302 ; Y = banco stringa
4303 ; X<7> = bit signed (richiesto signed int)
4304 ; X<6:0> = dimensione richiesta => 1,2,4,8
4305 ; DPR = DP02ADDR
4306 ;
4307 ; Out - ACM => intero 1,2,3,4,8 bytes
4308 ; ACMSgn<7> = segno (solo signed)
4309 ; ACMSgn<6> = signed int
4310 ; Y => indice dove si arresta la conversione
4311 ; CF = 0, VF = 0 OK
4312 ; CF = 0, VF = 1 mismatch type
4313 ; CF = 1, VF = 1 se overflow
4314 ; CF = 1, VF = 0 se stringa non valida
4315 F82EC7 _Str2Int:
4316 F82EC7 20 ED 2F jsr _pres2i ; prepara var. conversione
4317 F82ECA A5 20 lda ACMSize ; interi a 3 bytes non accettati
4318 F82ECC C9 03 cmp #$03
4319 F82ECE D0 02 bne ?01
4320 F82ED0 A9 04 lda #$04
4321 F82ED2 85 20 ?01: sta ACMSize
4322 F82ED4 A0 FF LDY #-1
4323 F82ED6 C8 ?02: INY
4324 F82ED7 C0 7F CPY #MAXINTSTR ; max. dimensione stringa hex/dec
4325 F82ED9 B0 51 bcs ?11 ; esce con CF = 1 e con VF = 0
4326 F82EDB B7 60 lda [FPLPtr],y ; load char
4327 F82EDD F0 4C beq ?10 ; fine stringa => esce con CF = 1 e VF = 0
4328 F82EDF C9 20 CMP #' '
4329 F82EE1 F0 F3 BEQ ?02 ; scarta spazi iniziali
4330 F82EE3 C9 08 CMP #$08
4331 F82EE5 F0 EF BEQ ?02 ; scarta TAB iniziali
4332 F82EE7 C9 2B CMP #'+' ; segno +
4333 F82EE9 F0 0C BEQ ?04 ; cerca primo digit decimale
4334 F82EEB C9 2D CMP #'-'
4335 F82EED D0 1F BNE ?08 ; test digit decimale
4336 F82EEF A9 80 LDA #$80
4337 F82EF1 04 21 TSB ACMSgn ; intero negativo
4338 F82EF3 A9 40 lda #$40
4339 F82EF5 85 63 STA FPFlag ; FPFlag<6> => intero signed
4340 F82EF7 C8 ?04: INY ; cerca digit decimale dopo '+' o '-'
4341 F82EF8 C0 7F CPY #MAXINTSTR ; max. dimensione stringa hex/dec
4342 F82EFA B0 30 bcs ?11 ; esce con CF = 1 e con VF = 0
4343 F82EFC B7 60 lda [FPLPtr],y ; load char
Tue Jul 17 11:00:16 2018 Page 32
4344 F82EFE F0 2B beq ?10 ; fine stringa => esce con CF = 1 e VF = 0
4345 F82F00 C9 20 CMP #' '
4346 F82F02 F0 F3 BEQ ?04 ; scarta spazi dopo '+' o '-'
4347 F82F04 C9 08 CMP #$08
4348 F82F06 F0 CE BEQ ?02 ; scarta TAB dopo '+' o '-'
4349 F82F08 D0 04 bne ?08 ; test digit decimale
4350 F82F0A B7 60 ?06: lda [FPLPtr],y ; loop scansione digit decimale
4351 F82F0C F0 1D beq ?10 ; fine stringa
4352 F82F0E 38 ?08: SEC ; next digit decimale
4353 F82F0F E9 3A SBC #('0'+10)
4354 F82F11 18 CLC
4355 F82F12 69 0A ADC #10
4356 F82F14 90 15 BCC ?10 ; no digit decimale => fine scansione
4357 F82F16 48 PHA
4358 F82F17 20 35 30 JSR _iUMult10 ; ACM * 10 -> ACM
4359 F82F1A 68 PLA
4360 F82F1B B0 5E bcs ?30 ; overflow => esce con CF = 1, VF = 1
4361 F82F1D 20 5A 30 JSR _iUAdd8 ; ACM + A -> ACM
4362 F82F20 B0 59 bcs ?30 ; overflow => esce con CF = 1, VF = 1
4363 F82F22 A9 80 lda #$80
4364 F82F24 04 63 tsb FPFlag ; FPFlag<7> -> flag digit decimale
4365 F82F26 C8 INY ; next char
4366 F82F27 C0 7F CPY #MAXINTSTR ; max. dimensione stringa hex/dec
4367 F82F29 90 DF bcc ?06 ; loop scansione digit decimale
4368
4369 ?10: ; a questo punto scansione terminata o per fine stringa o per
4370 ; primo carattere non digit decimale all'indice attuale
4371 F82F2B 38 sec ; assume CF = 1, VF = 0
4372 F82F2C B8 ?11: clv
4373 F82F2D A5 63 lda FPFlag
4374 F82F2F 10 4C bpl ?40 ; CF = 1 e VF = 0 => stringa vuota
4375 ; o nessun digit decimale valido
4376
4377 ; si testa se ACM contiene un numero
4378 ; compatibile con la dimensione richiesta
4379 F82F31 20 17 30 jsr _minsize ; X = minima dimensione - 1
4380 F82F34 E4 20 cpx ACMSize ; 1,2,3,4,8 => CF = 1 se overflow
4381 F82F36 B0 43 bcs ?30 ; overflow => CF = 1, VF = 1
4382 ; qui ora CF = 0
4383 F82F38 24 21 bit ACMSgn ; bit 6 => richiesto tipi signed
4384 F82F3A 70 04 bvs ?13 ; richiesto signed
4385 F82F3C 24 63 bit FPFlag ; test segno '-'
4386 F82F3E 80 3D bra ?40 ; unsigned => OK => CF = 0, VF = 0
4387 ; se VF = 1 => signed => mismatch
4388 F82F40
4389 ?13: ; richiesto tipo signed
4390 F82F40 A5 63 lda FPFlag ; FPFlag<6> = segno
4391 F82F42 0A asl a ; bit 7 = segno, CF = 1 (FPFlag<7> = 1)
4392 F82F43 04 21 tsb ACMSgn ; imposta segno
4393 F82F45 A6 20 ldx ACMSize
4394 F82F47 CA dex ; indice MSB
4395 F82F48 B5 18 lda ACM,x ; test MSB ACM
4396 F82F4A 10 10 bpl ?18 ; OK -- valore abs. < 8000...00
4397 F82F4C
4398 ; se MSB = 1 e tutti i restanti bit sono nulli il signed int
4399 ; e' valido e pari al minimo negativo. Qui ancora CF = 1
4400 F82F4C 24 21 bit ACMSgn ; signed positivo deve avere MSB = 0
Tue Jul 17 11:00:16 2018 Page 33
4401 F82F4E 10 2B bpl ?30 ; overflow => CF = 1, VF = 1
4402 ; intero negativo
4403 F82F50 C9 80 cmp #$80 ; al minimo deve essere 80 00 00 ... 00
4404 F82F52 D0 27 bne ?30 ; overflow => CF = 1, VF = 1
4405 ; qui ancora CF = 1
4406 F82F54 CA dex
4407 F82F55 B5 18 ?15: lda ACM,x
4408 F82F57 D0 22 bne ?30 ; overflow => CF = 1, VF = 1
4409 F82F59 CA dex
4410 F82F5A 10 F9 bpl ?15 ; testa tutti i bytes (= 00)
4411 F82F5C
4412 ?18: ; OK -- adesso signed int in ACM compatibile con tipo richiesto
4413 F82F5C ACC16
4414 F82F5C C2 20 rep #PMFLAG
4415 .LONGA on
4416 .MNLIST
4417 F82F5E A5 18 lda ACM ; test ACM = 0
4418 F82F60 05 1A ora ACM+2
4419 F82F62 05 1C ora ACM+4
4420 F82F64 05 1E ora ACM+6
4421 F82F66 ACC08
4422 F82F66 E2 20 sep #PMFLAG
4423 .LONGA off
4424 .MNLIST
4425 F82F68 D0 06 bne ?19 ; non nullo
4426 F82F6A A9 80 lda #$80
4427 F82F6C 14 21 trb ACMSgn ; azzera segno se nullo
4428 F82F6E 80 07 bra ?20
4429 F82F70 24 21 ?19: bit ACMSgn ; test segno
4430 F82F72 10 03 bpl ?20 ; positivo
4431 F82F74 20 3E 2A jsr _iNegACM ; complemento a 2 di ACM
4432 F82F77 B8 ?20: clv ; OK
4433 F82F78 18 clc
4434 F82F79 90 02 bcc ?40
4435 F82F7B E2 40 ?30: sep #PVFLAG ; VF = 1 => overflow
4436 F82F7D 60 ?40: rts
4437 F82F7E
4438 ; _Str2Hex - converte stringa hex. in unsigned intero
4439 ; In - C = offset stringa hex.
4440 ; Y = banco stringa
4441 ; X = dimensione richiesta => 1,2,3,4,8
4442 ; DPR = DP02ADDR
4443 ;
4444 ; Out - ACM => intero 1,2,3,4,8 bytes
4445 ; Y => indice dove si arresta la conversione
4446 ; CF = 1, VF = 1 se overflow
4447 ; CF = 1, VF = 0 se stringa non valida
4448 F82F7E _Str2Hex:
4449 F82F7E 20 ED 2F jsr _pres2i ; prepara var. conversione
4450 F82F81 64 21 stz ACMSgn ; HEX => solo unsigned
4451 F82F83 A0 00 ldy #0 ; indice stringa
4452 F82F85 B7 60 ?01: lda [FPLPtr],y ; load char
4453 F82F87 F0 53 beq ?20 ; fine stringa => esce con CF = 1 e VF = 0
4454 F82F89 C9 20 cmp #' ' ; scarta spazi iniziali
4455 F82F8B F0 04 beq ?02
4456 F82F8D C9 08 cmp #$08 ; scarta 'TAB' iniziali
4457 F82F8F D0 07 bne ?04
Tue Jul 17 11:00:16 2018 Page 34
4458 F82F91 C8 ?02: iny ; next char
4459 F82F92 C0 7F cpy #MAXINTSTR ; max. dimensione stringa hex/dec
4460 F82F94 90 EF bcc ?01
4461 F82F96 B0 54 bcs ?25 ; esce con CF = 1 e con VF = 0
4462 F82F98 C9 61 ?04: CMP #'a' ; loop test digit esadecimali
4463 F82F9A 90 02 BCC ?12
4464 F82F9C E9 20 SBC #$20 ; caps
4465 F82F9E 38 ?12: SEC
4466 F82F9F E9 3A SBC #('0'+10)
4467 F82FA1 18 CLC
4468 F82FA2 69 0A ADC #10
4469 F82FA4 B0 09 BCS ?13 ; ok, digit hex
4470 F82FA6 E9 16 SBC #(6+16)
4471 F82FA8 18 CLC
4472 F82FA9 69 06 ADC #6
4473 F82FAB 90 2F BCC ?20 ; no digit esadecimale => fine scansione
4474 F82FAD 69 09 ADC #9 ; digit hex
4475 F82FAF 29 0F ?13: and #$0F ; maschera digit hex
4476 F82FB1 48 PHA ; salva digit
4477 F82FB2 A9 80 lda #$80
4478 F82FB4 85 63 sta FPFlag ; segnala hex digit valido
4479 F82FB6 ACC16 ; ACM = ACM * 16
4480 F82FB6 C2 20 rep #PMFLAG
4481 .LONGA on
4482 .MNLIST
4483 F82FB8 A2 04 ldx #$04 ; 4 shift
4484 F82FBA A5 18 lda ACM
4485 F82FBC 0A ?15: asl a
4486 F82FBD 26 1A rol ACM+2
4487 F82FBF 26 1C rol ACM+4
4488 F82FC1 26 1E rol ACM+6
4489 F82FC3 B0 03 bcs ?17 ; overflow
4490 F82FC5 CA dex
4491 F82FC6 D0 F4 bne ?15
4492 F82FC8 85 18 ?17: sta ACM
4493 F82FCA ACC08
4494 F82FCA E2 20 sep #PMFLAG
4495 .LONGA off
4496 .MNLIST
4497 F82FCC 68 pla ; digit hex
4498 F82FCD 05 18 ora ACM ; add digit
4499 F82FCF 85 18 sta ACM
4500 F82FD1 B0 17 bcs ?24 ; CF = 1, VF = 1 => overflow su 64 bit
4501 F82FD3 C8 iny ; next char
4502 F82FD4 C0 7F cpy #MAXINTSTR ; max. dimensione stringa hex/dec
4503 F82FD6 B0 04 bcs ?20 ; fine scansione
4504 F82FD8 B7 60 lda [FPLPtr],y ; load char
4505 F82FDA D0 BC bne ?04 ; loop
4506 ?20: ; a questo punto scansione terminata o per fine stringa o per
4507 ; primo carattere non hex all'indice attuale
4508 F82FDC 38 sec ; assume CF = 1, VF = 0
4509 F82FDD B8 clv
4510 F82FDE A5 63 lda FPFlag
4511 F82FE0 F0 0A beq ?25 ; CF = 1 e VF = 0 => stringa vuota
4512 ; o nessun digit hex valido
4513 ; si testa se ACM contiene un numero
4514 ; compatibile con la dimensione richiesta
Tue Jul 17 11:00:16 2018 Page 35
4515 F82FE2 20 17 30 jsr _minsize ; X = minima dimensione - 1
4516 F82FE5 B8 clv ; assume no overflow
4517 F82FE6 E4 20 cpx ACMSize ; 1,2,3,4,8 => CF = 1 se overflow
4518 F82FE8 90 02 bcc ?25 ; OK => CF = 0, VF = 0
4519 F82FEA E2 40 ?24: sep #PVFLAG ; VF = 1 => overflow
4520 F82FEC 60 ?25: rts ; CF = 1 se errore
4521 F82FED
4522 ; routine di preparazione a conversione stringa -> intero
4523 F82FED _pres2i:
4524 F82FED 85 60 sta FPLPtr ; set long pointer
4525 F82FEF EB xba
4526 F82FF0 85 61 sta FPLPtr+1
4527 F82FF2 84 62 sty FPLPtr+2
4528 F82FF4 8A txa
4529 F82FF5 29 7F and #$7F ; maschera off tipo
4530 F82FF7 D0 01 bne ?01
4531 F82FF9 1A inc a ; minima dimensione: byte
4532 F82FFA C9 05 ?01: cmp #$05
4533 F82FFC 90 02 bcc ?02 ; valori leciti: 1,2,3,4,8
4534 F82FFE A9 08 lda #$08 ; max. dimensione: 8 bytes
4535 F83000 85 20 ?02: sta ACMSize ; tipo intero richiesto
4536 F83002 8A txa
4537 F83003 29 80 and #$80 ; bit 7: tipo signed
4538 F83005 4A lsr a ; bit 6: tipo signed
4539 F83006 85 21 sta ACMSgn
4540 F83008 ACC16 ; azzera ACM
4541 F83008 C2 20 rep #PMFLAG
4542 .LONGA on
4543 .MNLIST
4544 F8300A 64 18 stz ACM
4545 F8300C 64 1A stz ACM+2
4546 F8300E 64 1C stz ACM+4
4547 F83010 64 1E stz ACM+6
4548 F83012 ACC08
4549 F83012 E2 20 sep #PMFLAG
4550 .LONGA off
4551 .MNLIST
4552 F83014 64 63 stz FPFlag ; flag conversione
4553 F83016 60 rts
4554
4555 ; calcola minima dimensione ACM
4556 ; Out X = minima dimensione ACM - 1 (0,1,2,3,7)
4557 F83017 _minsize:
4558 F83017 ACC16
4559 F83017 C2 20 rep #PMFLAG
4560 .LONGA on
4561 .MNLIST
4562 F83019 A2 07 ldx #$07 ; si assume intero 64 bit
4563 F8301B A5 1E lda ACM+6
4564 F8301D 05 1C ora ACM+4
4565 F8301F ACC08
4566 F8301F E2 20 sep #PMFLAG
4567 .LONGA off
4568 .MNLIST
4569 F83021 D0 11 bne ?02 ; X = 07 => intero 64 bit
4570 F83023 A2 03 ldx #$03
4571 F83025 A5 1B lda ACM+3
Tue Jul 17 11:00:16 2018 Page 36
4572 F83027 D0 0B bne ?02 ; X = 03 => intero 32 bit
4573 F83029 CA dex
4574 F8302A A5 1A lda ACM+2
4575 F8302C D0 06 bne ?02 ; X = 02 => intero 24 bit
4576 F8302E CA dex
4577 F8302F A5 19 lda ACM+1
4578 F83031 D0 01 bne ?02 ; X = 01 => intero 16 bit
4579 F83033 CA dex ; X = 00 => intero 8 bit
4580 F83034 60 ?02: rts
4581 F83035
4582 ; _iUMult10 - Moltiplica unsigned ACM (64 bit) x 10
4583 ; In: ACM -> unsigned integer 64 bit
4584 ; Out: ACM <- ACM * 10 (unsigned 64 bit)
4585 ; CF -> unsigned overflow flag
4586 ; Uso: A,X,ACM,FOP
4587 F83035 _iUMult10:
4588 F83035 A2 07 LDX #INTGSIZE-1
4589 F83037 B5 18 ?01: LDA ACM,X ; copia ACM -> FOP
4590 F83039 95 32 STA FOP,X
4591 F8303B CA DEX
4592 F8303C 10 F9 BPL ?01
4593 F8303E 20 4D 30 JSR ?10 ; ACM * 2 -> ACM
4594 F83041 B0 16 bcs ?22
4595 F83043 20 4D 30 JSR ?10 ; ACM * 4 -> ACM
4596 F83046 B0 11 bcs ?22
4597 F83048 20 63 30 JSR _iUAdd64 ; ACM * 5 -> ACM
4598 F8304B B0 0C bcs ?22
4599 ; ACM * 10 -> ACM
4600
4601 ?10: ; moltiplica x 2
4602 F8304D ACC16
4603 F8304D C2 20 rep #PMFLAG
4604 .LONGA on
4605 .MNLIST
4606 F8304F 06 18 ASL ACM
4607 F83051 26 1A ROL ACM+2
4608 F83053 26 1C ROL ACM+4
4609 F83055 26 1E ROL ACM+6
4610 F83057 ?20: ACC08
4611 F83057 E2 20 sep #PMFLAG
4612 .LONGA off
4613 .MNLIST
4614 F83059 60 ?22: RTS ; CF = 1 => overflow
4615
4616 ; _iUAdd8 - Somma unsigned ACM (64 bit) e Accmulatore (8 bit)
4617 ; In: ACM -> unsigned integer 64 bit
4618 ; A -> unsigned byte
4619 ; Out: ACM <- ACM + A (unsigned 64 bit)
4620 ; CF = 1 +> overflow
4621 ; Uso: A,X,ACM,FOP
4622 F8305A _iUAdd8:
4623 F8305A LONG_OFF
4624 .LONGA off
4625 .LONGI off
4626 .MNLIST
4627 F8305A A2 07 LDX #(INTGSIZE-1) ; azzera FOP+1..FOP+7
4628 F8305C 74 32 ?01: STZ FOP,X
Tue Jul 17 11:00:16 2018 Page 37
4629 F8305E CA DEX
4630 F8305F D0 FB BNE ?01
4631 F83061 85 32 STA FOP ; byte in A
4632 F83063
4633 ; _iUAdd64 - Somma unsigned ACM e FOP (64 bit)
4634 ; In: ACM -> unsigned integer 64 bit
4635 ; FOP -> unsigned integer 64 bit
4636 ; Out: ACM <- ACM + FOP (unsigned 64 bit)
4637 ; CF = 1 => unsigned overflow
4638 ; VF = 1 +> signed overflow
4639 ; Uso: A,ACM,FOP
4640 F83063 _iUAdd64:
4641 F83063 C2 21 rep #(PMFLAG+PCFLAG) ; ACC16 + CLC
4642 F83065 A5 18 LDA ACM
4643 F83067 65 32 ADC FOP
4644 F83069 85 18 STA ACM
4645 F8306B A5 1A LDA ACM+2
4646 F8306D 65 34 ADC FOP+2
4647 F8306F 85 1A STA ACM+2
4648 F83071 A5 1C LDA ACM+4
4649 F83073 65 36 ADC FOP+4
4650 F83075 85 1C STA ACM+4
4651 F83077 A5 1E LDA ACM+6
4652 F83079 65 38 ADC FOP+6
4653 F8307B 85 1E STA ACM+6
4654 F8307D ACC08
4655 F8307D E2 20 sep #PMFLAG
4656 .LONGA off
4657 .MNLIST
4658 F8307F 60 RTS
4659
4660 ;----------------------------------------------------------
4661 ; Conversioni Integer-Stringa (decimale / hex)
4662 ;----------------------------------------------------------
4663 F83080
4664 ; _Int2Str: converte numero intero in stringa decimale/hex
4665 ; In - ACM => intero max. 64 bit
4666 ; ACMSize => dimensione intero (1, 2, 3, 4, 8 bytes)
4667 ; ACMSgn => <7>:segno, <6>:tipo signed
4668 ; X => precisione richiesta
4669 ; A => flag conversione:
4670 ; <7> 1 => DEC, 0 => HEX
4671 ; <6> 0 => LOWCAPS, 1 => HICAPS (HEX only - <7> = 0)
4672 ; <6> 1 => group thousand (DEC only - <7> = 1)
4673 ; <5> flag long pointer (forza hex a 6 digit)
4674 ; <1> => blank se positivo (DEC signed only)
4675 ; <0> => segno '+'/blank se positivo (DEC signed only)
4676 ; DPR -> impostato a DP02ADDR
4677 ; DBR -> impostato su banco 0
4678 ; CPU -> 8 bit
4679 ;
4680 ; Out: - X => puntatore stringa in pagina 02
4681 ; A = Y => lunghezza stringa
4682 F83080 _Int2Str:
4683 F83080 9B txy ; precisione minima = 1
4684 F83081 D0 01 bne ?02
4685 F83083 E8 inx
Tue Jul 17 11:00:16 2018 Page 38
4686 F83084 E0 2E ?02: cpx #XCVTMAXI ; max. numero char stringa integer
4687 F83086 90 02 bcc ?03
4688 F83088 A2 2E ldx #XCVTMAXI
4689 F8308A 89 20 ?03: bit #$20 ; test long pointer
4690 F8308C F0 08 beq ?04 ; standard integer (1,2,4,8)
4691 F8308E A2 06 ldx #6 ; precisione fissa a 6 digit
4692 F83090 A0 03 ldy #3 ; dimensione long pointer = 3 bytes
4693 F83092 29 60 and #01100000B ; maschera off bit inutilizzati - forza HEX
4694 F83094 D0 07 bne ?06
4695 F83096 A4 20 ?04: ldy ACMSize ; standard integer
4696 F83098 C0 03 cpy #3 ; se size = 3 imposta size = 4
4697 F8309A D0 01 bne ?06
4698 F8309C C8 iny
4699 F8309D 86 0A ?06: stx FmtPrec ; salva precisione
4700 F8309F 85 16 sta XVFlag ; salva flag
4701 F830A1 BB tyx ; minima dimensione = byte
4702 F830A2 D0 01 bne ?07
4703 F830A4 C8 iny
4704 F830A5 C0 05 ?07: cpy #5
4705 F830A7 90 02 bcc ?08 ; Y < 5 => OK (size = 1,2,3,4)
4706 F830A9 A0 08 ldy #8 ; MAX: 8 bytes
4707 F830AB 84 20 ?08: sty ACMSize ; salva size corretta integer
4708 F830AD AA tax ; test bit 7
4709 F830AE 30 36 bmi ?20 ; <7> = 1 => DEC
4710 F830B0
4711 ; conversione in stringa HEX -- ignora ACMSgn
4712 F830B0 A2 06 ldx #$06 ; valore da aggiungere per digit A..F
4713 F830B2 0A asl a ; NF => HI CAPS, bit 6 => long ptr
4714 F830B3 85 16 sta XVFlag ; <6> => long pointer
4715 F830B5 30 02 bmi ?10 ; HI CAPS
4716 F830B7 A2 26 ldx #$26 ; valore da aggiungere per digit a..f
4717 F830B9 86 24 ?10: stx FPTmp1
4718 F830BB BB tyx
4719 F830BC CA dex ; X = MSB integer (0,1,3,7)
4720 F830BD A0 01 LDY #1 ; indice stringa destinazione (FPUStr+1)
4721 F830BF B5 18 ?12: LDA <ACM,X ; converte MSB
4722 F830C1 20 1E 32 JSR Byte2Hex ; A = nibble H
4723 F830C4 99 70 02 STA !DP02ADDR+FPUStr,Y
4724 F830C7 C8 INY
4725 F830C8 EB xba ; nibble L
4726 F830C9 99 70 02 STA !DP02ADDR+FPUStr,Y
4727 F830CC C8 INY
4728 F830CD CA DEX
4729 F830CE 10 EF BPL ?12
4730 F830D0 BB tyx
4731 F830D1 74 70 stz FPUStr,x ; terminatore #0 stringa
4732 ; a questo punto la stringa HEX e' convertita in ACMSize * 2 digit
4733 F830D3 A2 71 ldx #FPUStr+1 ; puntatore stringa pagina 02
4734 F830D5 24 16 bit XVFlag ; test long pointer ?
4735 F830D7 50 04 bvc ?14 ; no
4736 ; long pointer => stringa completa a 6 digit
4737 F830D9 A4 0A ldy FmtPrec
4738 F830DB 98 tya ; A = Y = lunghezza stringa
4739 F830DC 60 rts ; X = inizio stringa pagina 02
4740 F830DD 20 D8 31 ?14: jsr _Int2End ; A = len -- Y = first -- X = last
4741 F830E0 64 16 stz XVFlag ; per stringa HEX ignora restanti flag
4742 F830E2 64 21 stz ACMSgn ; HEX ignora segno
Tue Jul 17 11:00:16 2018 Page 39
4743 F830E4 80 4A bra ?30 ; padding finale
4744 F830E6
4745 ?20: ; conversione in stringa decimale -- Y = size (1,2,4,8)
4746 F830E6 BB tyx
4747 F830E7 CA dex ; X = MSB integer (0,1,3,7)
4748 F830E8 A9 80 lda #$80 ; clear segno
4749 F830EA 14 21 trb ACMSgn
4750 F830EC 24 21 bit ACMSgn ; signed ?
4751 F830EE 50 06 bvc ?22 ; NO
4752 F830F0 34 18 bit <ACM,x ; test segno
4753 F830F2 10 02 bpl ?22 ; positivo
4754 F830F4 04 21 tsb ACMSgn ; imposta segno negativo
4755 F830F6 C0 08 ?22: cpy #8
4756 F830F8 F0 16 beq ?26 ; non occorre estensione
4757 F830FA 84 24 sty FPTmp1 ; calcola numero byte estensione
4758 F830FC A9 08 lda #8
4759 F830FE 38 sec
4760 F830FF E5 24 sbc FPTmp1
4761 F83101 A8 tay ; Y = numero di bytes da estendere (7,6,4)
4762 F83102 A9 00 lda #0 ; estende con $00 se positivo/unsigned
4763 F83104 24 21 bit ACMSgn
4764 F83106 10 02 bpl ?24 ; positivo
4765 F83108 A9 FF lda #$FF ; estende negativo
4766 F8310A E8 ?24: inx ; next byte da estendere
4767 F8310B 95 18 sta <ACM,x
4768 F8310D 88 dey
4769 F8310E D0 FA bne ?24
4770 F83110 ?26: ACC16 ; copia ACM in FOP (signed 64 bytes)
4771 F83110 C2 20 rep #PMFLAG
4772 .LONGA on
4773 .MNLIST
4774 F83112 A5 18 lda ACM
4775 F83114 85 32 sta FOP
4776 F83116 A5 1A lda ACM+2
4777 F83118 85 34 sta FOP+2
4778 F8311A A5 1C lda ACM+4
4779 F8311C 85 36 sta FOP+4
4780 F8311E A5 1E lda ACM+6
4781 F83120 85 38 sta FOP+6
4782 F83122 ACC08
4783 F83122 E2 20 sep #PMFLAG
4784 .LONGA off
4785 .MNLIST
4786 F83124 24 21 bit ACMSgn
4787 F83126 10 05 bpl ?28 ; positivo
4788 F83128 A2 32 ldx #FOP
4789 F8312A 20 40 2A jsr _iNegX ; negativo => complementa a 2
4790 F8312D 20 6C 31 ?28: jsr _UI2Str ; converte in stringa decimale
4791
4792 ?30: ; a questo punto la stringa convertita si trova in FPUStr+1
4793 ; A = len -- Y = ptr al primo digit non '0' -- X = ptr last digit
4794 F83130 20 F9 31 jsr _thgroup ; copia in XCVTStr/group thousand
4795 ; A = len -- Y = ptr first digit -- X = ptr last digit
4796 F83133 BB tyx ; X = puntatore stringa in pagina 02
4797 F83134 A8 tay ; Y = lunghezza attuale stringa
4798 F83135 85 27 sta FPTmp4 ; lunghezza attuale stringa
4799 F83137 A5 0A lda FmtPrec ; precisione richiesta
Tue Jul 17 11:00:16 2018 Page 40
4800 F83139 38 sec
4801 F8313A E5 27 sbc FPTmp4 ; lunghezza padding
4802 F8313C F0 0D beq ?50 ; no padding
4803 F8313E 90 0B bcc ?50 ; no padding
4804 F83140
4805 ; padding della stringa con '0' iniziali
4806 F83140 A8 tay ; counter padding
4807 F83141 A9 30 lda #'0'
4808 F83143 CA ?32: dex ; aggiorna ptr a digit precedente
4809 F83144 95 00 sta <0,x
4810 F83146 88 dey
4811 F83147 D0 FA bne ?32
4812 F83149 A4 0A ldy FmtPrec ; Y = lunghezza stringa
4813 F8314B
4814 ; memorizza eventuale segno ('+', '-', o ' ')
4815 ; X = ptr stringa -- Y = lunghezza stringa
4816 F8314B 24 21 ?50: bit ACMSgn ; signed ?
4817 F8314D 50 1B bvc ?60 ; NO -- esce
4818 F8314F 10 04 bpl ?52 ; signed positivo
4819 F83151 A9 2D lda #'-' ; signed negativo => store '-'
4820 F83153 D0 11 bne ?56
4821 F83155 A5 16 ?52: lda XVFlag ; test store segno
4822 F83157 4A lsr a ; CF -> flag segno positivo
4823 F83158 90 10 bcc ?60 ; no store segno se positivo
4824 F8315A 86 24 stx FPTmp1 ; salva ptr stringa
4825 F8315C A2 2B ldx #'+' ; assume '+'
4826 F8315E 4A lsr a ; CF -> flag blank
4827 F8315F 90 02 bcc ?54 ; store '+'
4828 F83161 A2 20 ldx #' ' ; store blank
4829 F83163 8A ?54: txa ; A = segno
4830 F83164 A6 24 ldx FPTmp1 ; X = ptr stringa
4831 F83166 CA ?56: dex ; ptr al segno
4832 F83167 95 00 sta <0,x
4833 F83169 C8 iny ; incrementa lunghezza
4834 F8316A 98 ?60: tya ; A = Y = lunghezza stringa
4835 F8316B 60 rts ; X = puntatore stringa
4836
4837 ; _UI2Str: converte intero senza segno in stringa decimale a 20 digits
4838 ; In: - FOP -> unsigned integer 64 bit
4839 ; DPR -> impostato a DP02ADDR
4840 ; CPU -> 8 bit
4841 ;
4842 ; Out: - FPUStr+1 -> stringa decimale 20 cifre
4843 ; - A -> lunghezza stringa significativa (X - Y + 1)
4844 ; - Y -> ptr in pag02 al primo digit diverso ad '0'
4845 ; - X -> ptr in pag02 ultimo digit
4846 ; NOTA il numero intero viene esteso a 9 bytes e si applica il metodo
4847 ; delle sottrazioni ripetute per determinare ciascun digit
4848 F8316C _UI2Str:
4849 F8316C A0 00 LDY #$00
4850 F8316E 84 3A STY FOP+8 ; MSB = 0 (9 bytes)
4851 F83170 84 25 STY FPTmp2 ; indice stringa
4852 F83172 A2 15 LDX #(FPSTRSIZE - 1)
4853 F83174 74 70 ?01: STZ FPUStr,X ; clear stringa destinazione
4854 F83176 CA DEX
4855 F83177 10 FB BPL ?01
4856 F83179 BB TYX
Tue Jul 17 11:00:16 2018 Page 41
4857 F8317A 8B phb ; imposta DBR al PBR corrente
4858 F8317B 4B phk ; per accedere alle costanti
4859 F8317C AB plb
4860 F8317D A0 80 LDY #$80 ; contatore SBC
4861 F8317F C2 21 ?02: rep #(PMFLAG.OR.PCFLAG)
4862 .LONGA on ; ACC16 + CLC
4863 F83181 A5 32 LDA FOP ; divisione mediante sottrazioni ripetute
4864 F83183 7D D3 32 ADC !CONSTDECTBL,x
4865 F83186 85 32 STA FOP
4866 F83188 A5 34 LDA FOP+2
4867 F8318A 7D D5 32 ADC !CONSTDECTBL+2,x
4868 F8318D 85 34 STA FOP+2
4869 F8318F A5 36 LDA FOP+4
4870 F83191 7D D7 32 ADC !CONSTDECTBL+4,x
4871 F83194 85 36 STA FOP+4
4872 F83196 A5 38 LDA FOP+6
4873 F83198 7D D9 32 ADC !CONSTDECTBL+6,x
4874 F8319B 85 38 STA FOP+6
4875 F8319D ACC08 ; ripristina acc/mem 8 bit
4876 F8319D E2 20 sep #PMFLAG
4877 .LONGA off
4878 .MNLIST
4879 F8319F A5 3A LDA FOP+8
4880 F831A1 7D DB 32 ADC !CONSTDECTBL+8,x
4881 F831A4 85 3A STA FOP+8
4882 F831A6 C8 INY ; incrementa contatore SBC
4883 F831A7 B0 04 BCS ?03 ; nuova SBC se X < 0
4884 F831A9 10 D4 BPL ?02 ; resto >= 10, nuova SBC
4885 F831AB 30 02 BMI ?04 ; resto < 10 - store digit
4886 F831AD 30 D0 ?03: BMI ?02 ; nuova SBC se X < 0
4887 F831AF 98 ?04: TYA ; fine SBC
4888 F831B0 90 04 BCC ?05 ; positivo
4889 F831B2 49 FF EOR #$FF ; negativo
4890 F831B4 69 0A ADC #10
4891 F831B6 69 2F ?05: ADC #('0' - 1) ; digit
4892 F831B8 A8 TAY
4893 F831B9 8A TXA
4894 F831BA 18 CLC
4895 F831BB 69 09 ADC #DECTBLLEN ; indice tabella divisioni
4896 F831BD 85 24 STA FPTmp1
4897 F831BF A6 25 LDX FPTmp2
4898 F831C1 E8 INX
4899 F831C2 98 TYA
4900 F831C3 29 7F AND #$7F
4901 F831C5 95 70 STA FPUStr,x ; salva digit
4902 F831C7 86 25 ?06: STX FPTmp2 ; indice stringa
4903 F831C9 A6 24 LDX FPTmp1
4904 F831CB 98 TYA
4905 F831CC 49 FF EOR #$FF ; inverte contatore SBC
4906 F831CE 29 80 AND #$80
4907 F831D0 A8 TAY
4908 F831D1 E0 B4 CPX #DECTBLSIZE
4909 F831D3 D0 AA BNE ?02 ; ricava digit successivo
4910 F831D5 AB plb ; ripristina DBR
4911 F831D6 A2 71 LDX #FPUStr+1 ; posiziona puntatori start-end
4912 F831D8
4913 F831D8 _Int2End:
Tue Jul 17 11:00:16 2018 Page 42
4914 ; posiziona X sulla prima cifra diversa da '0'
4915 ; la stringa e' terminata sicuramente con #0
4916 F831D8 86 25 stx FPTmp2
4917 F831DA B5 00 ?10: LDA <0,X ; start stringa
4918 F831DC F0 07 beq ?11 ; fine
4919 F831DE C9 30 CMP #'0'
4920 F831E0 D0 04 BNE ?12 ; primo digit non '0'
4921 F831E2 E8 INX
4922 F831E3 D0 F5 bne ?10 ; loop
4923 F831E5 CA ?11: DEX ; ultimo digit
4924 F831E6 9B ?12: txy ; Y = indice primo digit significativo
4925 F831E7 A6 25 ldx FPTmp2
4926 F831E9 B5 00 ?13: lda <0,x ; si posiziona su ultimo digit
4927 F831EB F0 03 beq ?14
4928 F831ED E8 inx
4929 F831EE D0 F9 bne ?13
4930 F831F0 CA ?14: dex ; X = last digit
4931 F831F1 8A txa
4932 F831F2 84 24 sty FPTmp1
4933 F831F4 38 sec
4934 F831F5 E5 24 sbc FPTmp1
4935 F831F7 1A inc a ; A = lunghezza stringa significativa
4936 F831F8 60 rts
4937
4938 ; formatta stringa minima raggruppando le migliaia
4939 ; i digit vengono spostati verso la fine di XCVTStr
4940 F831F9 _thgroup:
4941 F831F9 84 24 sty FPTmp1 ; indice primo digit significativo
4942 F831FB 9B txy ; Y => ptr ultimo digit
4943 F831FC A2 B5 ldx #XCVTStrEnd
4944 F831FE 74 00 stz <0,x ; terminatore #0
4945 F83200 CA dex ; indice ultimo digit
4946 F83201 A9 03 ?02: lda #3 ; counter gruppi digits
4947 F83203 EB ?04: xba ; B = counter
4948 F83204 B9 00 02 lda !DP02ADDR,y
4949 F83207 95 00 sta <0,x ; copia digit
4950 F83209 EB xba ; A = counter
4951 F8320A 88 dey
4952 F8320B C4 24 cpy FPTmp1
4953 F8320D 90 C9 bcc _Int2End ; fine loop
4954 F8320F CA dex
4955 F83210 3A dec a
4956 F83211 D0 F0 bne ?04
4957 F83213 24 16 bit XVFlag ; test group thousand
4958 F83215 50 EA bvc ?02 ; no group -- loop
4959 F83217 A9 2C lda #',' ; separatore migliaia
4960 F83219 95 00 sta <0,x
4961 F8321B CA dex
4962 F8321C 80 E3 bra ?02 ; loop
4963
4964 ; Byte2Hex: converte byte in digit HEX
4965 ; In: - A = byte
4966 ; FPTmp1 -> valore da aggiungere per digit a..f/A..F
4967 ;
4968 ; Out: - BA - Digit HEX (A->H, B->L)
4969 F8321E Byte2Hex:
4970 F8321E 48 pha ; salva byte
Tue Jul 17 11:00:16 2018 Page 43
4971 F8321F 20 28 32 JSR ?01 ; converte digit L
4972 F83222 EB xba ; B -> Digit L
4973 F83223 68 pla ; ripristina byte
4974 F83224 4A LSR A ; A/16 -> A
4975 F83225 4A LSR A
4976 F83226 4A LSR A
4977 F83227 4A LSR A
4978 F83228 29 0F ?01: AND #$0F ; maschera nibble L
4979 F8322A C9 0A CMP #10
4980 F8322C 90 02 BCC ?02
4981 F8322E 65 24 ADC FPTmp1
4982 F83230 69 30 ?02: ADC #'0'
4983 F83232 60 RTS
4984
4985 ; long fast unsigned division 16 bit
4986 ;
4987 ; entry: C = dividend 16 bit
4988 ; X = divisor low
4989 ; Y = divisor high
4990 ;
4991 ; exit: C = quotient
4992 ; X = remainder low
4993 ; Y = remainder high
4994 ;
4995 ; use: all
4996 ;
4997 ; note: no check for null divisor
4998 ; long subroutine (call with jsl)
4999 ;
5000 0000B6 dvend .EQU DUMMY100
5001 0000B8 dvsor .EQU DUMMY100+2
5002 F83233 fidiv:
5003 F83233 0B phd ; save dp
5004 F83234 F4 00 02 pea #P0MAT
5005 F83237 2B pld ; set dp
5006 F83238 86 B8 stx dvsor ; set divisor
5007 F8323A 84 B9 sty dvsor+1
5008 F8323C A2 10 ldx #16 ; bit counter
5009 F8323E A0 00 ldy #0 ; partial remainder
5010 F83240 CPU16
5011 F83240 C2 30 rep #(PMFLAG.OR.PXFLAG)
5012 .LONGA on
5013 .LONGI on
5014 .MNLIST
5015 F83242 85 B6 sta dvend ; set dividend
5016 F83244 98 tya ; C=remainder
5017 F83245 26 B6 ?10: rol dvend ; partial quotient
5018 F83247 2A rol a
5019 F83248 38 sec
5020 F83249 A8 tay ; save remainder
5021 F8324A E5 B8 sbc dvsor
5022 F8324C B0 01 bcs ?20 ; ok
5023 F8324E 98 tya ; restore old remainder
5024 F8324F CA ?20: dex
5025 F83250 D0 F3 bne ?10 ; loop
5026 F83252 26 B6 rol dvend ; adjust final quotient
5027 F83254 85 B8 sta dvsor ; save remainder
Tue Jul 17 11:00:16 2018 Page 44
5028 F83256 A5 B6 lda dvend ; C=quotient
5029 F83258 CPU08
5030 F83258 E2 30 sep #(PMFLAG.OR.PXFLAG)
5031 .LONGA off
5032 .LONGI off
5033 .MNLIST
5034 F8325A A6 B8 ldx dvsor ; X=remainder low
5035 F8325C A4 B9 ldy dvsor+1 ; Y=remainder high
5036 F8325E 2B pld ; restore dp
5037 F8325F 6B rtl
5038
5039 ; long fast unsigned division 16 bit
5040 ;
5041 ; entry: C = dividend 16 bit
5042 ; X = divisor low
5043 ; Y = divisor high
5044 ;
5045 ; exit: C = quotient
5046 ; X = remainder low
5047 ; Y = remainder high
5048 ;
5049 ; use: all
5050 ;
5051 ; note: no check for null divisor
5052 ; long subroutine (call with jsl)
5053 ;
5054 ;dvsor .EQU DUMMY100
5055 0000B6 quot .EQU DUMMY100
5056 F83260 fidiv2:
5057 F83260 0B phd ; save dp
5058 F83261 F4 00 02 pea #P0MAT
5059 F83264 2B pld ; set dp
5060 F83265 86 B8 stx dvsor ; set divisor
5061 F83267 84 B9 sty dvsor+1
5062 F83269 A2 01 ldx #1 ; bit counter
5063 F8326B CPU16
5064 F8326B C2 30 rep #(PMFLAG.OR.PXFLAG)
5065 .LONGA on
5066 .LONGI on
5067 .MNLIST
5068 F8326D A8 tay ; Y=dividend
5069 F8326E 64 B6 stz quot ; init quotient
5070 F83270 A5 B8 lda dvsor ; C=divisor
5071 F83272 0A ?10: asl a ; shift divisor: get leftmost bit
5072 F83273 B0 06 bcs ?20 ; go to division
5073 F83275 E8 inx
5074 F83276 E0 11 00 cpx #17 ; test all divisor bit's
5075 F83279 D0 F7 bne ?10
5076 F8327B 6A ?20: ror a ; put shifted-out bit back
5077 F8327C 85 B8 sta dvsor
5078 F8327E 98 ?30: tya ; get dividend
5079 F8327F 38 sec
5080 F83280 E5 B8 sbc dvsor
5081 F83282 90 01 bcc ?40 ; can't subctract, retain old dividend
5082 F83284 A8 tay ; Y=new dividend
5083 F83285 26 B6 ?40: rol quot ; shift carry into quotient (1 if division)
5084 F83287 46 B8 lsr dvsor ; shift right divisor for next subtract
Tue Jul 17 11:00:16 2018 Page 45
5085 F83289 CA dex
5086 F8328A D0 F2 bne ?30
5087 F8328C 84 B8 sty dvsor ; store remainder
5088 F8328E A5 B6 lda quot ; C=quotient
5089 F83290 CPU08
5090 F83290 E2 30 sep #(PMFLAG.OR.PXFLAG)
5091 .LONGA off
5092 .LONGI off
5093 .MNLIST
5094 F83292 A6 B8 ldx dvsor ; X=remainder low
5095 F83294 A4 B9 ldy dvsor+1 ; Y=remainder high
5096 F83296 2B pld ; restore dp
5097 F83297 6B rtl
5098
5099 ; long fast unsigned multiplication 16 bit
5100 ;
5101 ; entry: C = multiplicand 1 16 bit
5102 ; X = multiplicand 2 low byte
5103 ; Y = multiplicand 2 high byte
5104 ;
5105 ; exit: C = result
5106 ; Y = result low byte
5107 ;
5108 ; use: all
5109 ;
5110 ; note: 16 bit result only, no overflow detected
5111 ; long subroutine (call with jsl)
5112 ;
5113 0000B6 mcand2 .EQU DUMMY100
5114 F83298 fimlt:
5115 F83298 0B phd ; save dp
5116 F83299 F4 00 02 pea #P0MAT
5117 F8329C 2B pld ; set dp
5118 F8329D 86 B6 stx mcand2
5119 F8329F 84 B7 sty mcand2+1
5120 F832A1 A0 00 ldy #0 ; partial result
5121 F832A3 CPU16
5122 F832A3 C2 30 rep #(PMFLAG.OR.PXFLAG)
5123 .LONGA on
5124 .LONGI on
5125 .MNLIST
5126 F832A5 AA ?10: tax ; if mcand1 = 0...
5127 F832A6 F0 0E beq ?30 ; ...done
5128 F832A8 4A lsr a ; get right bit
5129 F832A9 90 07 bcc ?20 ; if clear, no addition to partial result...
5130 F832AB 18 clc
5131 F832AC AA tax
5132 F832AD 98 tya ; ...else add mcand2 to partial result
5133 F832AE 65 B6 adc mcand2
5134 F832B0 A8 tay ; Y=partial result
5135 F832B1 8A txa
5136 F832B2 06 B6 ?20: asl mcand2 ; shift mcand2 for next time
5137 F832B4 80 EF bra ?10
5138 F832B6 98 ?30: tya ; C=result
5139 F832B7 CPU08
5140 F832B7 E2 30 sep #(PMFLAG.OR.PXFLAG)
5141 .LONGA off
Tue Jul 17 11:00:16 2018 Page 46
5142 .LONGI off
5143 .MNLIST
5144 F832B9 2B pld ; restore dp
5145 F832BA 6B rtl
5146
5147 F832BB test1:
5148 F832BB 22 33 32 F8 jsl fidiv
5149 F832BF 00 00 brk
5150 F832C1 00 00 brk
5151 F832C3
5152 F832C3 test3:
5153 F832C3 22 98 32 F8 jsl fimlt
5154 F832C7 00 00 brk
5155 F832C9 00 00 brk
5156
5157 F832CB test2:
5158 F832CB 22 60 32 F8 jsl fidiv2
5159 F832CF 00 00 brk
5160 F832D1 00 00 brk
5161 F832D3
5162 ;----------------------------------------------------------------------------
5163 ; COSTANTI
5164 ;----------------------------------------------------------------------------
5165 F832D3
5166 ; Tabella potenze di 10 in ordine decrescente da -1E19 a 1E00,
5167 ; con segni alterni, a 9 bytes
5168 F832D3 CONSTDECTBL:
5169 F832D3 00 00 18 76 FB .DB $00, $00, $18, $76, $FB, $DC, $38, $75, $FF ; -1E19
DC 38 75 FF
5170 F832DC CONSTDECTBL1:
5171 F832DC 00 00 64 A7 B3 .DB $00, $00, $64, $A7, $B3, $B6, $E0, $0D, $00 ; +1E18
B6 E0 0D 00
5172 F832E5 00 00 76 A2 87 .DB $00, $00, $76, $A2, $87, $BA, $9C, $FE, $FF ; -1E17
BA 9C FE FF
5173 F832EE 00 00 C1 6F F2 .DB $00, $00, $C1, $6F, $F2, $86, $23, $00, $00 ; +1E16
86 23 00 00
5174 F832F7 00 80 39 5B 81 .DB $00, $80, $39, $5B, $81, $72, $FC, $FF, $FF ; -1E15
72 FC FF FF
5175 F83300 00 40 7A 10 F3 .DB $00, $40, $7A, $10, $F3, $5A, $00, $00, $00 ; +1E14
5A 00 00 00
5176 F83309 00 60 8D B1 E7 .DB $00, $60, $8D, $B1, $E7, $F6, $FF, $FF, $FF ; -1E13
F6 FF FF FF
5177 F83312 00 10 A5 D4 E8 .DB $00, $10, $A5, $D4, $E8, $00, $00, $00, $00 ; +1E12
00 00 00 00
5178 F8331B 00 18 89 B7 E8 .DB $00, $18, $89, $B7, $E8, $FF, $FF, $FF, $FF ; -1E11
FF FF FF FF
5179 F83324 00 E4 0B 54 02 .DB $00, $E4, $0B, $54, $02, $00, $00, $00, $00 ; +1E10
00 00 00 00
5180 F8332D 00 36 65 C4 FF .DB $00, $36, $65, $C4, $FF, $FF, $FF, $FF, $FF ; -1E9
FF FF FF FF
5181 F83336 00 E1 F5 05 00 .DB $00, $E1, $F5, $05, $00, $00, $00, $00, $00 ; +1E8
00 00 00 00
5182 F8333F 80 69 67 FF FF .DB $80, $69, $67, $FF, $FF, $FF, $FF, $FF, $FF ; -1E7
FF FF FF FF
5183 F83348 40 42 0F 00 00 .DB $40, $42, $0F, $00, $00, $00, $00, $00, $00 ; +1E6
00 00 00 00
5184 F83351 60 79 FE FF FF .DB $60, $79, $FE, $FF, $FF, $FF, $FF, $FF, $FF ; -1E5
Tue Jul 17 11:00:16 2018 Page 47
FF FF FF FF
5185 F8335A 10 27 00 00 00 .DB $10, $27, $00, $00, $00, $00, $00, $00, $00 ; +1E4
00 00 00 00
5186 F83363 18 FC FF FF FF .DB $18, $FC, $FF, $FF, $FF, $FF, $FF, $FF, $FF ; -1E3
FF FF FF FF
5187 F8336C 64 00 00 00 00 .DB $64, $00, $00, $00, $00, $00, $00, $00, $00 ; +1E2
00 00 00 00
5188 F83375 F6 FF FF FF FF .DB $F6, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ; -1E1
FF FF FF FF
5189 F8337E 01 00 00 00 00 .DB $01, $00, $00, $00, $00, $00, $00, $00, $00 ; +1E0
00 00 00 00
5190
5191 0000B4 DECTBLSIZE: .EQU ($ - CONSTDECTBL)
5192 000009 DECTBLLEN: .EQU (CONSTDECTBL1 - CONSTDECTBL)
Lines Assembled : 4879 Errors : 0