Blame | Last modification | View Log | Download | RSS feed
Tue Jul 17 11:00:20 2018 Page 1
2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
-----------------------------------------------------
Input Filename : src\F9\fatdir.asm
Output Filename : obj\F9\fatdir.obj
Listing Has Been Relocated
2603 .LIST on
2604
2605 F8FFB1 .INCLUDE inc\dirp00.inc
2606 ;----------------------------------------------------------
2607 ; DIRP00.ASM
2608 ; PROGETTO: B1601
2609 ;
2610 ; Variabili in Direct Page $00
2611 ;----------------------------------------------------------
2612
2613 ; sezione COMMON -- questo permette di includere il file in piu' file
2614
2615 .LIST on
2616
2617 DIRP00: .SECTION page0, ref_only, common ;Direct-Page 00
2618
2619 000000 .ABSOLUTE ;; inizia sempre da $00
2620 000000 .ORG 0x00
2621 000000
2622 000000 0000 JiffyClk .DW ; contatore 10ms 32 bit
2623 000002 0000 .DW
2624 000004 SysTmr .DS SYSTMRCNT ; system timer 0 (10ms)
2625 000008 SysTMF .DS SYSTMRCNT ; flag timer (80 -> start)
2626 00000C 00 Bnk0Flag .DB ; <7>: flag test RAM banco 0 ok
2627 ; <6>: flag warm reset
2628 00000D 00 RTCFlag .DB
2629
2630 00000E diskstat .DS 2 ; flag device on ata bus #0 & #1
2631 ; <7>: device ready
2632 ; <6>: compact flash device (C.F.)
2633 ; <5>: device identification ok
2634 ; <4>: MBR loaded
2635 ; <3>: valid signature in MBR
2636 ; <2>: first partition found&active
2637 ; <1>:
2638 ; <0>: valid partition flag
2639
2640 ; <7>: device ready
2641 ; <6>: USB device
2642 ; <5>: compact flash device (C.F.)
2643 ; <4>: device identification ok
2644 ; <3>: MBR loaded
2645 ; <2>: first partition found&active
2646 ; <1>: always 1
2647 ; <0>: valid partition flag
2648 000010
Tue Jul 17 11:00:20 2018 Page 2
2649
2650 00000E atadev .EQU diskstat
2651
2652 000010 usbdev .DS 2 ; flag flash disk on usb bus #0
2653 ; <7>: device plugged and ready
2654 ; <6>: always 1
2655 ; <5>: device identification ok
2656 ; <4>: MBR loaded
2657 ; <3>: valid signature in MBR
2658 ; <2>: first partition found&active
2659 ; <1>:
2660 ; <0>: valid partition flag
2661
2662 000012 diskmax .DS 16 ; disk max. sector's
2663 000012 atasec .EQU diskmax
2664 00001A usbsec .EQU diskmax+8
2665
2666
2667 000022 atambr .DS 8 ; data for first partition found in mbr
2668 ; first 3 bytes for start sector of partition
2669 ; last byte for partition type
2670 00002A usbmbr .DS 8
2671
2672 000032 ataprt .DS 8 ; total sec's of first partition
2673 00003A usbprt .DS 8 ; total sec's of first partition
2674
2675
2676 000042 00 usb0ch .DB ; usb0 (ch375/ch376) flag
2677 ; <7>: module on
2678 ; <6>: ch376 flag
2679 ; <5:0>: chip version
2680
2681 000043 00 usb0st .DB ; usb0 status
2682 ; <7>: usb0 host mode ok
2683 ; <6>: flash disk attached flag
2684 ; <5>: usb device attached
2685
2686 000044 00 fdcdrv .DB ; phisycal drive status (drive #0)
2687 ; <7>: disk format established in bit 0&1
2688 ; <6>: double step seek done
2689 ; <5>: trust format bit's (set after ok r/w)
2690 ; <4>: write protect bit (if disk in drive)
2691 ; <3>: don't care
2692 ; <2>: don't care
2693 ; <1>: HD disk if set else DD disk
2694 ; <0>: CBM format if set else IBM format
2695
2696 000045 00 vdrive .DB ; virtual drive status (ram disk, drive #1)
2697 ; <7>: disk format established in bit 0&1
2698 ; <6>: change disk simulation (after format)
2699 ; <5>: don't care
2700 ; <4>: write protect bit (under sw control)
2701 ; <3>: don't care
2702 ; <2>: don't care
2703 ; <1>: HD disk if set else DD disk
2704 ; <0>: CBM format if set else IBM format
2705
Tue Jul 17 11:00:20 2018 Page 3
2706 000046 00 fdcctl .DB ; fdc controller status
2707 ; <7>: drive is attached
2708 ; <6>: drive need recalibration (restore)
2709 ; <5>: FDC controller ok
2710 ; <4>: motor on
2711 ; <3>: dma is active
2712 ; <2>: dma chip ok (post routine)
2713 ; <1>: clock rate (1=HD,0=DD)
2714 ; <0>: disk ready
2715
2716 000047 00 fdctrk .DB ; fd: current seek track
2717 000048 00 fdcerr .DB ; fd: last error code
2718 000049 00 ataerr .DB ; ata: last error code
2719 00004A 00 ataxer .DB ; ata: last extended error code
2720
2721 00004B 00 CtrlBrk .DB ; flag CTRL+BREAK (NMI)
2722
2723 00004C 0000 MemTop .DW ; top memoria RAM
2724 00004E 00 .DB ; banco top mem
2725
2726 00004F 00 DflTxtIn .DB ; device di default text input
2727 000050 00 DflTxtOut .DB ; device di default text output
2728
2729 000051 COPPtr LP ; long pointer for COP decoding
2730 000054 00 COPIdx .DB ; COP signature/index
2731
2732 000055 00 BiosEnt .DB ; flag accesso a bios setup
2733
2734 ; variabili utilizzate da ACIA
2735 000056 spwrk .DS $30
2736
2737 ; bios mem
2738 000086 0000 nsize .DW ; dimensione blocco da allocare
2739 ;bsize .DW ; dimensione vera blocco free
2740 000088 0000 splitsz .DW ; dimensione blocco splittato
2741 00008A 0000 bfree .DW ; puntatore blocco free
2742 00008C 0000 hdrptr .DW ; puntatore header heap
2743
2744 00008E 0000 pbrklv .DW ; current break level of current process
2745 000090 0000 pbrkmin .DW ; minimum breal level of current process
2746 000092 0000 pbrkmax .DW ; maximum breal level of current process
2747 000094
2748 ; bios temp. work area
2749 000094 bwrktmp .DS $28
2750
2751 0000BC 00 coptmp .DB ; temp. used while cop
2752
2753 0000BD 00 tstser .DB ; check ser/usb test board post
2754 ; <7>: VIA2 ok
2755 ; <6>: PICRAM ok
2756 ; <1>: UART 16C550 ok
2757 ; <0>: R65C51 ok
2758
2759
2760 ;crc16 .DW
2761
2762 0000BD .RELATIVE
Tue Jul 17 11:00:20 2018 Page 4
2763
2764 .ENDS
2765
2766 [01] .IFDEF _ACIA_INC_
2767 .INCLUDE INC\SP.INC
2768 [00] .ENDIF
2769
2794 .LIST on
2795
2796 ;---------------------------------------------------------------------------
2797
2798 000020 HPLMAX .EQU 32 ; Max. subdirectory level
2799
2800 000200 BCBCNT .EQU $200 ; BCB's struct's count #
2801 000C00 BCBXBNK .EQU $0C00 ; starting BCB x-mem buffer #
2802 000040 DMACNT .EQU 64
2803
2804 0000E0 FAT0X .EQU $E0 ; x-mem bank for fat table of ata #0
2805 0000F0 FAT1X .EQU $F0 ; x-mem bank for fat table of ata #1
2806
2807 F8FFB1 .INCLUDE INC\LDT.INC
2808 ; LDT.INC
2809
2810 [01] .IFNDEF __LDT_INC__
2811 000001 __LDT_INC__ .SET 1
2812
2813 .LIST on
2814 ;---------------------------------------------------------------------------
2815 ; Logical Drive Table (LDT) -- page 0 offset's
2816 ;---------------------------------------------------------------------------
2817
2818 F8FFB1 STRUCT LDT
2819 _LDT .SECTION page0,common,ref_only,offset 0 ;LDT Struct
2820 ;.ABSOLUTE
2821 ;.ORG 0
2822 .MNLIST
2823 000000 00 ldt_fg1 .DB ; logical volume flag's
2824 ; <7>: device ready (fdc drive or ata device)
2825 ; <6>: if=1->HD/CF else->FD
2826 ; <1:0>: phisycal device number
2827
2828 000001 00 ldt_fg2 .DB ; <7>: valid volume (fat volume or cbm disk)
2829 ; <6>: if=1->FAT else->CBM (FD only)
2830 ; <5>: disk format checked
2831 ; <1:0>: disk format (fdc only)
2832
2833 000002 0000 ldt_root .DW ; lba of root dir
2834 000004 0000 ldt_fat1 .DW ; lba of fat1 table
2835 000006 0000 ldt_fat2 .DW ; lba of fat2 table
2836 000008 0000 ldt_cls .DW ; lba of first data cluster
2837 00000A 0000 ldt_max .DW ; max usable cluster + 1
2838 00000C 0000 ldt_rent .DW ; root dir. max. entries
2839 00000E 0000 ldt_cent .DW ; max. entries in dir. cluster
2840 000010 0000 ldt_eoc .DW ; end of cluster chain marker
2841 000012 0000 ldt_free .DW ; count of free cluster's
2842 000014 0000 ldt_nxt .DW ; next free cluster
2843 000016 0000 ldt_fsiz .DW ; fat table size
Tue Jul 17 11:00:20 2018 Page 5
2844
2845 000018 00 ldt_csiz .DB ; cluster size (1,2,4,8,16,32,64)
2846 000019 00 ldt_cshf .DB ; cluster shift (0,1,2,3,4,5,6)
2847 00001A 00 ldt_rsiz .DB ; root dir. size (sector's)
2848 00001B 00 ldt_mcls .DB ; mask for clust. module: 00,01,03,07,0F,1F,3F
2849 00001C 0000 ldt_cdlp .DW ; current working dir list pointer
2850 00001E 0000 ldt_cdcls .DW ; current working dir start cluster
2851 000020 00 ldt_cdlvl .DB ; current working dir level count
2852
2853 000021 00 ldt_ptype .DB
2854 000022 0000 0000 ldt_pstart .LWORD
2855 000026 0000 0000 ldt_psize .LWORD
2856
2857 000022 ldt_fp .EQU ldt_pstart ; fat table buffer long pointer
2858 000025 ldt_fbuf .EQU ldt_pstart+3 ; fat table: x-mem base bank/dma buffer
2859
2860 000026 ldt_pbr .EQU ldt_psize ; long pointer to PBR cache buffer
2861 000029 ldt_fmt .EQU ldt_psize+3
2862
2863 00002A ESTRUCT LDT
2864 00002A LDTSIZE .DS 0
2865 ;.RELATIVE
2866 .ENDS
2867 .MNLIST
2868
2869 [00] .ENDIF
2870
2871 F8FFB1
2872 ;---------------------------------------------------------------------------
2873 ; Hierarchical Path List (HPL) -- 16 bit offset's
2874 ;---------------------------------------------------------------------------
2875
2876 F8FFB1 LSTRUCT HPL
2877 _HPL .SECTION common,ref_only,offset 0 ;HPL Struct
2878 .MNLIST
2879 000000 0000 hpl_cls .DW ; parent cluster
2880 000002 0000 hpl_ix .DW ; entry index in parent cluster
2881 000004 hpl_fcb .DS 11 ; fcb name
2882 00000F 00 hpl_lst .DB ; unused
2883 000010 ESTRUCT HPL
2884 000010 HPLSIZE .DS 0
2885 ;.RELATIVE
2886 .ENDS
2887 .MNLIST
2888
2889 ;---------------------------------------------------------------------------
2890 ; Buffer Control Block (BCB) -- 16 bit offset's
2891 ;---------------------------------------------------------------------------
2892
2893 F8FFB1 LSTRUCT BCB
2894 _BCB .SECTION common,ref_only,offset 0 ;BCB Struct
2895 .MNLIST
2896 000000 0000 bcb_next .DW ; next logical linked BCB
2897 000002 00 bcb_drv .DB ; logical drive
2898 000003 00 bcb_sec .DB ; sector offset
2899 000004 0000 bcb_cls .DW ; cluster
2900 000006 0000 bcb_lba .DW ; sector lba address
Tue Jul 17 11:00:20 2018 Page 6
2901 000008 0000 bcb_lbah .DW ; lba high
2902 000008 bcb_head .EQU bcb_lbah ; floppy head
2903 00000A 0000 bcb_buf .DW ; x-mem buffer number
2904 00000A bcb_trk .EQU bcb_buf ; floppy track(low) & sector(hi)
2905 00000C 0000 bcb_ptr .DW ; buffer pointer
2906 00000E 0000 bcb_xbnk .DW ; buffer pointer hi & x-mem bank
2907 00000E bcb_dma .EQU bcb_xbnk ; buffer pointer hi & dma buffer
2908 000010 ESTRUCT BCB
2909 000010 BCBSIZE .DS 0
2910 ;.RELATIVE
2911 .ENDS
2912 .MNLIST
2913
2914 ;---------------------------------------------------------------------------
2915 ; hash Control Block (BCB) -- 16 bit offset's
2916 ;---------------------------------------------------------------------------
2917
2918 F8FFB1 LSTRUCT HCB
2919 _HCB .SECTION common,ref_only,offset 0 ;HCB Struct
2920 .MNLIST
2921 000000 0000 hcb_next .DW ; pointer to next HCB
2922 000002 0000 hcb_cls .DW ; cluster number
2923 000004 0000 hcb_seq .DW ; sequence number + logical drive number
2924 000006 0000 hcb_cnt .DW ; number of hashed entries
2925 000008 hcb_data .DS 0 ; hash buffer data
2926 000008 ESTRUCT HCB
2927 000008 HCBSIZE .DS 0
2928 ;.RELATIVE
2929 .ENDS
2930 .MNLIST
2931
2932 ;---------------------------------------------------------------------------
2933 ; TOS Working Segment
2934 ;---------------------------------------------------------------------------
2935
2936 000001 WKB .EQU .SEG.TOSSEG ; TOS working bank
2937
2938 010000 TS .SET TOSSEG
2939 01FFFF TE .SET TOSSEG + $FFFF
2940 018C00 TO0 .SET $018C00
2941 019E00 TO1 .SET TOSWKM
2942
2943 .comment @
2944 _TOS0: .SECTION ref_only, common, offset TO0, range TS TE ;FAT Struct's
2945 _TOS0_START .DS 0
2946
2947 _pbr0 .DS 512
2948 _pbr1 .DS 512
2949 _pbr2 .DS 512
2950 _pbr3 .DS 512
2951
2952 _TOS0_END .DS 0
2953 TOS0SIZ .EQU (_TOS0_END - _TOS0_START)
2954 .ENDS
2955 @
2956
2957 _TOS1: .SECTION ref_only, common, offset TO1, range TS TE ;FAT Struct's
Tue Jul 17 11:00:20 2018 Page 7
2958 019E00 _TOS1_START .DS 0
2959
2960 ; current working directory HPL
2961 019E00 cwdl0 .DS (HPLSIZE*HPLMAX)
2962 01A000 cwdl1 .DS (HPLSIZE*HPLMAX)
2963 01A200 cwdl2 .DS (HPLSIZE*HPLMAX)
2964 01A400 cwdl3 .DS (HPLSIZE*HPLMAX)
2965
2966 ; current building path HPL
2967 01A600 cbpl .DS (HPLSIZE*HPLMAX)
2968 01A600 HPL_CLS .EQU hpl_cls+cbpl
2969 01A602 HPL_IX .EQU hpl_ix+cbpl
2970 01A604 HPL_FCB .EQU hpl_fcb+cbpl
2971
2972 ; BCB list's
2973 01A800 bcbstart .DS (BCBCNT*BCBSIZE)
2974 01C800 bcbend .DS 0
2975 01C800 dmastart .DS (DMACNT*BCBSIZE)
2976 01CC00 dmaend .DS 0
2977 01CC00 dma0s .DS (17*BCBSIZE)
2978 01CD10 dma1s .DS (17*BCBSIZE)
2979
2980 01CE20 _TOS1_END .DS 0
2981 003020 TOS1SIZ .EQU (_TOS1_END - _TOS1_START)
2982 .ENDS
2983
2984 ;---------------------------------------------------------------------------
2985 ; HCB Segment
2986 ;---------------------------------------------------------------------------
2987
2988 000004 HCBBNK .EQU .SEG.HCBSEG
2989 040000 HS .SET HCBSEG
2990 04FFFF HE .SET HCBSEG + $FFFF
2991 040000 HO .SET HCBSEG
2992
2993 _HCBS: .SECTION ref_only, common, offset HO, range HS HE ;HCB's List
2994 040000 hcb_bnk .DS 8
2995 040008 hcbstart .DS 0
2996 .ENDS
2997
2998 ;.comment @
2999 ;---------------------------------------------------------------------------
3000 ; direct page for LDT var's
3001 ;---------------------------------------------------------------------------
3002
3003 ; P0OS
3004 DPOS: .SECTION page0, common, ref_only, offset 0 ;OS Main D.P.
3005
3006 ;sysbuf .DS 2 ; floppy track 0 cache buffer
3007 000000 00 defhsec .DB ; default hidden sector's in fdisk
3008 000001 00 .DB
3009 000002 0000 cmdstk .DW ; saved stack on TOS command's
3010 000004 bpath .DS 80
3011
3012 000054 bpath1 .DS 0
3013 .ENDS
3014 ;@
Tue Jul 17 11:00:20 2018 Page 8
3015
3016 ; P0LDT
3017 DPLDT: .SECTION page0, common, ref_only, offset 0 ;LDT D.P.
3018
3019 000000 ldt0 .DS LDTSIZE
3020 00002A ldt1 .DS LDTSIZE
3021 000054 ldt2 .DS LDTSIZE
3022 00007E ldt3 .DS LDTSIZE
3023 0000A8 ldt4 .DS LDTSIZE
3024
3025 0000D2 ldtp .DS 6 ; pointer to LDT's in DPLDT page
3026
3027 0000D8 sysbuf .DS 4 ; floppy track 0 cache buffer
3028
3029 .ENDS
3030
3031 ;---------------------------------------------------------------------------
3032 ; direct page for FAT var's
3033 ;---------------------------------------------------------------------------
3034
3035 ; P0FAT
3036 DPFAT: .SECTION page0, common, ref_only, offset 0 ;FAT D.P.
3037
3038 000000 0000 ostos .DW ; saved top of stack
3039 000002 00 ioerr .DB ; i/o error
3040 000003 00 ioerr2 .DB ; extended i/o error
3041 000004 0000 hcbroot .DW ; HCB struct's list
3042 000006 0000 hcblst .DW ; the last one HCB
3043 000008 00 hsiz .DB ; how many sector's an HCB can hold
3044 000009 00 hlog2 .DB ; shift count related to hsiz
3045 00000A 0000 bcbroot .DW ; BCB buffer's list
3046 00000C 0000 bcblst .DW ; the last one BCB
3047 00000E 0000 dmaroot .DW ; dma BCB buffer's list
3048 000010 0000 dmalst .DW ; the last one dma BCB
3049 000012 0000 dmabcb .DW ; BCB list for floppy root, cluster#2,#3
3050 000014 00 fspt .DB ; sector per track (floppy)
3051 000015 00 pdrive .DB ; phisycal drive number
3052 000016 00 bplvl .DB ; subdir level while build path
3053 000017 00 defdrv .DB ; default drive
3054
3055 ; the first block of ldt_ var's is copied from the LDT struct
3056 000018 00 ldtfg1 .DB ; logical volume flag's
3057 ; <7>: device ready (fdc drive or ata device)
3058 ; <6>: if=1->HD/CF else->FD
3059 ; <0>: phisycal device number
3060
3061 000019 00 ldtfg2 .DB ; <7>: valid volume (fat volume or cbm disk)
3062 ; <6>: if=1->FAT else->CBM (FD only)
3063 ; <5>: disk format checked
3064 ; <1:0>: disk format (fdc only)
3065
3066 00001A ldtfp LP ; fat table buffer long pointer
3067 00001D 00 ldtfbuf .DB ; fat table: x-mem base bank/dma buffer
3068
3069 00001E 0000 ldtroot .DW ; lba of root dir
3070 000020 0000 ldtfat1 .DW ; lba of fat1 table
3071 000022 0000 ldtfat2 .DW ; lba of fat2 table
Tue Jul 17 11:00:20 2018 Page 9
3072 000024 0000 ldtcls .DW ; lba of first data cluster
3073 000026 0000 ldtmax .DW ; max usable cluster + 1
3074 000028 00 ldtcsiz .DB ; cluster size (1,2,4,8,16,32,64)
3075 000029 00 ldtcshf .DB ; cluster shift (0,1,2,3,4,5,6)
3076 00002A 00 ldtfsiz .DB ; fat table size (if 0 -> 256)
3077 00002B 00 ldtrsiz .DB ; root dir. size (sector's)
3078 00002C 0000 ldtrent .DW ; root dir. max. entries
3079 00002E 0000 ldtcent .DW ; max. entries in dir. cluster
3080 000030 0000 ldteoc .DW ; end of cluster chain marker
3081 000032 00 ldtmcls .DB ; mask for clust. module: 00,01,03,07,0F,1F,3F
3082 000033 00 ldtfmt .DB ; floppy disk format (0,1,2, FF if ata device)
3083 000034 0000 ldtcdlp .DW ; current working dir list pointer
3084 000036 0000 ldtcdcls .DW ; current working dir start cluster
3085 000038 0000 ldtfree .DW ; count of free cluster's
3086 00003A 0000 ldtnxt .DW ; next free cluster
3087 00003C 00 ldtcdlvl .DB ; current working dir level count
3088 00003D ldtpbr LP ; long pointer to PBR cache buffer
3089
3090 000040 0000 chdcls .DW ; last accessed chained dir. cluster
3091 000042 0000 clsofs .DW ; cluster's offset from start of chain
3092
3093 ; not change order of the 2 following var's: will be accessed as 16 bit var
3094 000044 00 entofs .DB ; entry offset from start of sector
3095 000045 00 secofs .DB ; sector's offset from start of cluster
3096
3097 000046 0000 dircls .DW ; directory cluster
3098 000048 0000 dcnt .DW ; directory entry counter
3099 00004A 0000 lba .DW ; lba sector address
3100 00004C 0000 lbah .DW ; lba is 24 bit's only
3101 00004E 0000 xbuf .DW ; x-mem buffer transfer number
3102
3103 00004C fhead .EQU lbah ; fd head
3104 00004E ftrack .EQU xbuf ; fd track
3105 00004F fsec .EQU xbuf+1 ; fd sector
3106
3107 000050 00 dfcbtyp .DB ; FCB type to search
3108 000051 00 dfcbatt .DB ; attribute of found FCB
3109
3110 000052 00 curdrv .DB ; current logical drive
3111 000053 fcbs .DS 11 ; file control block name
3112
3113 ;dcmask .DW ; mask to start of cluster
3114 ; FFF0, FFE0, FFC0, FF80, FF00, FE00
3115
3116 00005E 0000 fcbp .DW ; FCB buffer long pointer
3117 000060 0000 .DW ; low=fcbp+2, high=x-mem bank or dma buffer
3118 000061 dmabuf .EQU fcbp+3 ; dma buffer #
3119 000061 xmbank .EQU fcbp+3 ; x-mem bank #
3120
3121 ; temp area
3122 000062 00 hcbseq .DB
3123 000063 00 hcbdrv .DB
3124 000064 0000 bcbcls .DW
3125 000066 00 bcbdrv .DB
3126 000067 00 bcbsec .DB
3127
3128 000068 0000 thash .DW
Tue Jul 17 11:00:20 2018 Page 10
3129 000068 hcbrec .EQU thash
3130 000068 wtmp .EQU thash
3131
3132 00006A 0000 hlast .DW
3133 00006C 0000 hcbcls .DW
3134 00006E 0000 hcbx .DW
3135 000070 0000 hcby .DW
3136 00006A tmpp .EQU hlast ; temp. long pointer
3137 00006E tmpx .EQU hcbx
3138 00006F wild .EQU hcbx+1
3139 000070 fsiz .EQU hcby
3140 000071 fptr .EQU hcby+1
3141 00006E ldrv .EQU hcbx
3142 00006F tmpldt .EQU hcbx+1
3143
3144 000072 0000 fhash .DW
3145 000074 0000 fcbofs .DW
3146 000076 00 bcbload .DB
3147 000077 00 xstart .DB
3148 000078 00 xend .DB
3149 000079 00 seccnt .DB
3150 00007A 00 maxseq .DB
3151 00007B 00 dsiz .DB
3152
3153 00007C 00 haswld .DB
3154 00007D 00 strix .DB
3155 00007E pathp LP ; long pointer to path string
3156
3157 ; TEMP
3158 000081 0000 quot .DW
3159 000083 0000 dvsor .DW
3160 000085 0000 troot .DW
3161 000087 0000 tlst .DW
3162 000089 0000 bdmask .DW
3163 00008B 0000 bcmask .DW
3164
3165 00008D 00 hcbuse .DB
3166
3167 .ENDS
3168
3172 .LIST on
3173
3174 ;---------------------------------------------------------------------------
3175 ; code segment -- bank $F9
3176 ;---------------------------------------------------------------------------
3177
3178 .CODEF9
3179 .EXTERN oserror, getldt
3180 .EXTERN mxdrv, fndhcb, fndbuf, cls2lba ; utils.asm
3181 F91CE9
3182 .PUBLIC prslbl
3183
3184 .LONGA off
3185 .LONGI off
3186
3187 ;---------------------------------------------------------------------------
3188 ; path parse & build
Tue Jul 17 11:00:20 2018 Page 11
3189 ;---------------------------------------------------------------------------
3190
3191 ; pathdrv, pathcnt & pathnxt functions
3192 ; run down the path and parse final name into fcbs
3193 ; set directory cluster to last but one path name
3194 ;
3195 ; entry: pathp = long pointer to path string
3196 ;
3197 ; exit: dircls = start cluster of the last but one path name
3198 ; if CF=0 (no error)
3199 ;
3200 ; if any error, CF=1 and A=error code
3201 ; error code: ED_FILE (invalid filename/file not found)
3202 ; ED_PATH (path not found)
3203 ; ED_ACCESS (access denied)
3204 ; ED_FORMAT (invalid format)
3205 ; ED_DRIVE (invalid drive)
3206 ; ED_NOTRDY (drive not ready)
3207 ; use: all
3208 ;
3209
3210 ;-------
3211 setpchk: ; special entry for directory handler function's
3212 ;-------
3213 F91CE9 20 F6 1C jsr setpath ; parse path string & build path
3214 F91CEC 20 69 20 jsr nodev ; devices not allowed
3215 F91CEF 20 74 20 jsr nodot ; no subdirs entries
3216 F91CF2 20 7F 20 jsr nowild ; wild cards not allowed
3217 F91CF5 60 rts
3218
3219 ;-------
3220 F91CF6 setpath:
3221 ;-------
3222 F91CF6 20 FE 1C jsr pathdrv
3223 F91CF9 90 0A bcc phx
3224 F91CFB 4C 12 24 jmp oserror
3225
3226 ;-------
3227 pathdrv: ; get drive number from path or use default drive
3228 ;-------
3229 F91CFE 20 3E 20 jsr getpdrv ; return drive number in A
3230 F91D01 90 03 bcc pathcnt
3231 F91D03 A9 0F lda #ED_DRIVE ; invalid drive error
3232 F91D05 60 phx: rts
3233 F91D06
3234 ;-------
3235 pathcnt: ; use drive in A
3236 ;-------
3237 F91D06 20 23 24 jsr mxdrv ; select drive in A
3238 F91D09 A4 7D ldy strix ; path string index
3239 F91D0B B7 7E lda [pathp],y ; get first character
3240 F91D0D C8 iny
3241 F91D0E 84 7D sty strix
3242 F91D10 20 7B 1F jsr chkslh ; if '\' or '/' then start at root...
3243 F91D13 D0 16 bne ?20 ; ...else select current working directory
3244 F91D15 20 92 1F jsr fakefcb ; fake a '.' entry for the root
3245 F91D18 86 46 stx dircls ; start at fake cluster 0
Tue Jul 17 11:00:20 2018 Page 12
3246 F91D1A 86 47 stx dircls+1
3247 F91D1C B7 7E lda [pathp],y ; get next character
3248 F91D1E F0 09 beq ?10 ; if just a '\' or '/' then stop now
3249 F91D20 20 7B 1F jsr chkslh ; detected '//' or '\\' ?
3250 F91D23 D0 0C bne pathnxt ; no, so start processing from root dir.
3251 F91D25 A9 05 lda #ED_ACCESS ; report 'access denied' error
3252 F91D27 38 sec
3253 F91D28 60 rts
3254 F91D29 18 ?10: clc ; no error
3255 F91D2A 60 rts
3256 F91D2B 88 ?20: dey ; forget about char we looked at
3257 F91D2C 84 7D sty strix
3258 F91D2E 20 A0 1F jsr mvtobp ; start processing from cur. dir.
3259
3260 ;-------
3261 pathnxt: ; parse&build path
3262 ;-------
3263 F91D31 A4 7D ldy strix
3264 F91D33 B7 7E ?10: lda [pathp],y ; can't have trailing '/' or '\'
3265 F91D35 F0 27 beq ?15 ; error
3266 F91D37 20 B2 1D jsr prspath ; parse path & set up fcb
3267 F91D3A B0 22 bcs ?15 ; error
3268 F91D3C AA tax ; A=delimiter
3269 F91D3D F0 23 beq ?20 ; we are at the end
3270 F91D3F ACC16
3271 F91D3F C2 20 rep #PMFLAG
3272 .LONGA on
3273 .MNLIST
3274 F91D41 A5 53 lda fcbs
3275 F91D43 C9 2E 20 cmp #' .' ; if chdir(".")...
3276 F91D46 ACC08
3277 F91D46 E2 20 sep #PMFLAG
3278 .LONGA off
3279 .MNLIST
3280 F91D48 F0 E9 beq ?10 ; ...stay where we are
3281 F91D4A A5 7C lda haswld ; no wilds cards in path's
3282 F91D4C D0 10 bne ?15 ; skip if wild cards found
3283 F91D4E 20 D2 20 jsr fndfcbf ; locate the directory entry
3284 F91D51 B0 0B bcs ?15 ; missing directory in path: path not found
3285 F91D53 A5 51 lda dfcbatt ; test entry attribute
3286 F91D55 89 10 bit #DA_DIR
3287 F91D57 F0 05 beq ?15 ; error: not a directory
3288 F91D59 20 D2 1E jsr setdir ; set dir. cluster
3289 F91D5C 90 D5 bcc ?10 ; next path name
3290 F91D5E A9 03 ?15: lda #ED_PATH ; 'path not found' error
3291 F91D60 38 sec
3292 F91D61 60 rts
3293 F91D62 A5 53 ?20: lda fcbs ; is it '.' or '..' ?
3294 F91D64 C9 2E cmp #'.' ; if so get its full name
3295 F91D66 D0 3F bne ?35 ; exit, no error
3296 F91D68 ACC16
3297 F91D68 C2 20 rep #PMFLAG
3298 .LONGA on
3299 .MNLIST
3300 F91D6A A5 46 lda dircls ; we are at root?
3301 F91D6C F0 37 beq ?30 ; yes, exit, no error
3302 F91D6E A4 16 ldy bplvl
Tue Jul 17 11:00:20 2018 Page 13
3303 F91D70 F0 33 beq ?30 ; no error
3304 F91D72 88 dey ; go up one level
3305 F91D73 A5 53 lda fcbs
3306 F91D75 C9 2E 2E cmp #'..' ; parent?
3307 F91D78 D0 03 bne ?25 ; no, stay here
3308 F91D7A 88 dey ; go up two level's
3309 F91D7B 30 2C bmi ?40 ; we are destined for the root
3310 F91D7D 84 16 ?25: sty bplvl
3311 F91D7F 8B phb ; save DBR
3312 F91D80 A2 01 ldx #WKB
3313 F91D82 DA phx
3314 F91D83 AB plb
3315 F91D84 A2 00 ldx #0
3316 F91D86 INDEX16
3317 F91D86 C2 10 rep #PXFLAG
3318 .LONGI on
3319 .MNLIST
3320 F91D88 98 tya
3321 F91D89 0A asl a ; get HPL pointer
3322 F91D8A 0A asl a
3323 F91D8B 0A asl a
3324 F91D8C 0A asl a ; here CF=0
3325 ;adc #cbpl
3326 F91D8D A8 tay ; HPL index access
3327 F91D8E B9 00 A6 lda HPL_CLS,y
3328 F91D91 85 46 sta dircls ; set up parent cluster
3329 F91D93 B9 02 A6 lda HPL_IX,y
3330 F91D96 85 48 sta dcnt ; set up dir. index
3331 F91D98 B9 04 A6 ?28: lda HPL_FCB,y ; copy parental name
3332 F91D9B 95 53 sta fcbs,x
3333 F91D9D C8 iny
3334 F91D9E E8 inx
3335 F91D9F E0 0B 00 cpx #11
3336 F91DA2 90 F4 bcc ?28
3337 F91DA4 AB plb
3338 F91DA5 ?30: CPU08
3339 F91DA5 E2 30 sep #(PMFLAG.OR.PXFLAG)
3340 .LONGA off
3341 .LONGI off
3342 .MNLIST
3343 F91DA7 18 ?35: clc
3344 F91DA8 60 rts
3345 F91DA9
3346 F91DA9 64 46 ?40: stz dircls ; root dir
3347 F91DAB CPU08
3348 F91DAB E2 30 sep #(PMFLAG.OR.PXFLAG)
3349 .LONGA off
3350 .LONGI off
3351 .MNLIST
3352 F91DAD 20 92 1F jsr fakefcb
3353 F91DB0 18 clc
3354 F91DB1 60 rts
3355 F91DB2
3356 ; parse path name into fcb
3357 ;
3358 ; entry: Y = pointer to current name in path
3359 ; pathp = long pointer to path
Tue Jul 17 11:00:20 2018 Page 14
3360 ;
3361 ; exit: A = last char parsed
3362 ; Y = pointer to next name in path
3363 ; CF = 1 if parsing error
3364 ;
3365 ;-------
3366 F91DB2 prspath:
3367 ;-------
3368 F91DB2 20 87 1F jsr clrfcb ; initialise fcb to blanks
3369 F91DB5 64 7C stz haswld ; clear wild cards flag
3370 F91DB7 B7 7E lda [pathp],y
3371 F91DB9 C9 2E cmp #'.' ; if name start with '.'...
3372 F91DBB D0 15 bne ?20 ; ...then we parse it differently
3373 F91DBD 85 53 sta fcbs ; move '.' to fcb
3374 F91DBF C8 iny
3375 F91DC0 B7 7E lda [pathp],y
3376 F91DC2 C8 iny
3377 F91DC3 C9 2E cmp #'.' ; if name start with '..'...
3378 F91DC5 D0 05 bne ?15 ; ...then we parse it differently
3379 F91DC7 85 54 sta fcbs+1 ; move '..' to fcb
3380 F91DC9 B7 7E ?10: lda [pathp],y
3381 F91DCB C8 iny
3382 F91DCC C9 20 ?15: cmp #' ' ; skip all subsequent blanks
3383 F91DCE F0 F9 beq ?10
3384 F91DD0 80 2F bra ?50 ; check delimiter
3385 F91DD2 20 51 1F ?20: jsr chkdlm ; filename begins with a legal char?
3386 F91DD5 F0 29 beq ?40 ; no, then only allow '/' or '\'
3387 F91DD7 64 6F stz wild ; yes, then parse it normally
3388 F91DD9 A2 00 ldx #0 ; fcb name field ptr
3389 F91DDB A9 08 lda #8 ; length of name field
3390 F91DDD 20 2F 1E jsr prsone ; parse just name field
3391 F91DE0 B0 4C bcs ?90 ; error
3392 F91DE2 A6 6F ldx wild
3393 F91DE4 85 7C sta haswld ; save name wildcard flag
3394 F91DE6 C9 2E ?30: cmp #'.'
3395 F91DE8 D0 17 bne ?50 ; skip if not extension
3396 F91DEA 64 6F stz wild
3397 F91DEC A2 08 ldx #8 ; fcb extension field ptr
3398 F91DEE A9 03 lda #3 ; length of extension field
3399 F91DF0 20 2F 1E jsr prsone ; parse just extension field
3400 F91DF3 B0 39 bcs ?90 ; error
3401 F91DF5 85 6E sta tmpx
3402 F91DF7 A5 6F lda wild ; combine wild cards flag
3403 F91DF9 05 7C ora haswld
3404 F91DFB 85 7C sta haswld
3405 F91DFD A5 6E lda tmpx
3406 F91DFF 88 dey
3407 F91E00 C8 ?40: iny ; point to next character
3408 F91E01 AA ?50: tax ; last parsed delimiter
3409 F91E02 F0 2A beq ?90 ; end of path: ok
3410 F91E04 20 7B 1F jsr chkslh ; if delimiter is not '\' nor '/'...
3411 F91E07 D0 25 bne ?90 ; ...error (CF=1)
3412 F91E09 B7 7E ?60: lda [pathp],y ; get next character
3413 F91E0B C8 iny
3414 F91E0C 20 51 1F jsr chkdlm ; here we expect a normal legal character
3415 F91E0F D0 1C bne ?80 ; exit if we've got one
3416 F91E11 20 7B 1F jsr chkslh ; swallow '\'s at this point and leave...
Tue Jul 17 11:00:20 2018 Page 15
3417 F91E14 F0 F3 beq ?60 ; ...other delimiters for next time
3418 F91E16 C9 2E cmp #'.' ; trailing '\.' ?
3419 F91E18 D0 10 bne ?75 ; no
3420 F91E1A BB tyx ; remember position of '.'
3421 F91E1B B7 7E ?70: lda [pathp],y ; get next character
3422 F91E1D F0 0F beq ?90 ; stop at ending of string
3423 F91E1F C8 iny
3424 F91E20 C9 20 cmp #' ' ; now discard trailing spaces
3425 F91E22 F0 F7 beq ?70 ; keep going until we lose all spaces
3426 F91E24 20 7B 1F jsr chkslh ; if it's a '\' or '/' try again
3427 F91E27 F0 E0 beq ?60
3428 F91E29 9B txy ; retract to the '.'
3429 F91E2A A9 2F ?75: lda #'/' ; return '/' as the delimiter...
3430 F91E2C 18 clc ; ...and exit with no problems
3431 F91E2D 88 ?80: dey ; retract a byte
3432 F91E2E 60 ?90: rts
3433
3434 ; parse a single name or extension
3435 ;
3436 ; entry: A = field size
3437 ; X = local fcb field pointer
3438 ; Y = pointer to current name in path
3439 ; pathp = long pointer to path
3440 ;
3441 ; exit: A = last char parsed
3442 ; Y = pointer to next name in path
3443 ; CF = 1 if parsing error
3444 ;
3445 ; use: A,X,Y
3446 ;
3447 ;------
3448 F91E2F prsone:
3449 ;------
3450 F91E2F 85 70 sta fsiz ; char's counter
3451 F91E31 86 71 stx fptr ; field start
3452 F91E33 B7 7E ?10: lda [pathp],y ; get next path char
3453 F91E35 C8 iny
3454 F91E36 20 51 1F jsr chkdlm
3455 F91E39 F0 1E beq ?20 ; if it is a delimiter then return
3456 F91E3B C9 2A cmp #'*'
3457 F91E3D F0 1B beq ?25 ; special case if star
3458 F91E3F C9 3F cmp #'?' ; is a wildcard?
3459 F91E41 D0 06 bne ?15 ; no
3460 F91E43 A9 80 lda #$80
3461 F91E45 04 6F tsb wild ; set wildcard flag
3462 F91E47 A9 3F lda #'?'
3463 F91E49 95 53 ?15: sta fcbs,x ; move char to fcb field
3464 F91E4B E8 inx
3465 F91E4C C6 70 dec fsiz
3466 F91E4E D0 E3 bne ?10 ; loop: next path char
3467 F91E50 B7 7E lda [pathp],y ; get next path char
3468 F91E52 C8 iny
3469 F91E53 20 51 1F jsr chkdlm ; here expected a delimiter
3470 F91E56 F0 01 beq ?20
3471 F91E58 38 sec ; error flag
3472 F91E59 60 ?20: rts
3473 F91E5A 24 6F ?25: bit wild ; already parsed a star?
Tue Jul 17 11:00:20 2018 Page 16
3474 F91E5C 70 1D bvs ?38 ; yes, so error
3475 F91E5E A9 C0 lda #$C0
3476 F91E60 04 6F tsb wild ; set wildcard+star flag
3477 F91E62 E4 71 cpx fptr ; star is first char of the field?
3478 F91E64 F0 17 beq ?40 ; yes
3479 F91E66 A9 3F ?28: lda #'?' ; if not, fill rest of field with '?'
3480 F91E68 95 53 ?30: sta fcbs,x
3481 F91E6A E8 inx
3482 F91E6B C6 70 dec fsiz
3483 F91E6D D0 F9 bne ?30
3484 F91E6F B7 7E ?35: lda [pathp],y ; get next path char
3485 F91E71 C8 iny
3486 F91E72 20 51 1F jsr chkdlm ; here expected a delimiter...
3487 F91E75 F0 E2 beq ?20
3488 F91E77 C9 2A cmp #'*' ; ...or just star...
3489 F91E79 F0 F4 beq ?35
3490 F91E7B 38 ?38: sec ; ...else error
3491 F91E7C 60 rts
3492 F91E7D B7 7E ?40: lda [pathp],y ; get next path char
3493 F91E7F C8 iny
3494 F91E80 C9 2A cmp #'*' ; skips all subsequent star's
3495 F91E82 F0 F9 beq ?40
3496 F91E84 20 51 1F jsr chkdlm ; is a delimiter?
3497 F91E87 D0 03 bne ?45 ; no
3498 F91E89 88 dey ; forgot last char
3499 F91E8A 80 DA bra ?28 ; fill rest of field with '?'
3500 F91E8C A9 2A ?45: lda #'*' ; first char of field is a star
3501 F91E8E 95 53 sta fcbs,x
3502 F91E90 E8 inx
3503 F91E91 C6 70 dec fsiz
3504 F91E93 88 dey ; forgot last char
3505 F91E94 80 9D bra ?10 ; continue normal parsing
3506
3507 ; parse a single label name (volume name)
3508 ;
3509 ; entry: pathp = long pointer to label name
3510 ;
3511 ; exit: CF = 1 if parsing error
3512 ; ZF = 1 if null string
3513 ;
3514 ; use: A,X,Y
3515 ;
3516 ;------
3517 F91E96 prslbl:
3518 ;------
3519 F91E96 20 87 1F jsr clrfcb ; set up a clean fcb
3520 F91E99 A9 0B lda #11
3521 F91E9B 85 70 sta fsiz ; char's counter
3522 F91E9D A2 00 ldx #0 ; field start
3523 F91E9F 9B txy
3524 F91EA0 18 clc
3525 F91EA1 A7 7E lda [pathp] ; get first char
3526 F91EA3 F0 2A beq ?30 ; null string
3527 F91EA5 C9 20 cmp #' ' ; reject if first char is blank
3528 F91EA7 F0 12 beq ?15
3529 F91EA9 80 02 bra ?12
3530 F91EAB B7 7E ?10: lda [pathp],y ; get next name char
Tue Jul 17 11:00:20 2018 Page 17
3531 F91EAD C8 ?12: iny
3532 F91EAE 20 51 1F jsr chkdlm
3533 F91EB1 D0 0A bne ?20 ; is not a delimiter
3534 F91EB3 C9 20 cmp #' ' ; intermediate blanks are ok
3535 F91EB5 F0 0E beq ?25
3536 F91EB7 C9 00 cmp #0 ; end of string?
3537 F91EB9 F0 11 beq ?28 ; yes
3538 F91EBB 38 ?15: sec ; reject delimiter
3539 F91EBC 60 rts
3540 F91EBD C9 2A ?20: cmp #'*'
3541 F91EBF F0 FA beq ?15 ; reject wildcard
3542 F91EC1 C9 3F cmp #'?'
3543 F91EC3 F0 F6 beq ?15
3544 F91EC5 95 53 ?25: sta fcbs,x ; move char to fcb field
3545 F91EC7 E8 inx
3546 F91EC8 C6 70 dec fsiz
3547 F91ECA D0 DF bne ?10 ; loop: next path char
3548 F91ECC C2 03 ?28: rep #PZFLAG.OR.PCFLAG
3549 F91ECE 60 rts ; exit with ZF=0,CF=0
3550 F91ECF E2 02 ?30: sep #PZFLAG ; null string: exit with ZF=1,CF=0
3551 F91ED1 60 rts
3552
3553 ; go down (or up) one level in directory
3554 ;
3555 ; entry: fcbs = local name
3556 ; fcbp = long pointer to directory entry
3557 ; bplvl = current path level
3558 ;
3559 ; exit: dircls = cluster of selected directory
3560 ; bplvl = path level
3561 ; CF = 1 if failure
3562 ;
3563 ; use: C,X
3564 ;
3565 ;------
3566 F91ED2 setdir:
3567 ;------
3568 F91ED2 84 7D sty strix ; save Y
3569 F91ED4 A0 0B ldy #11
3570 F91ED6 B7 5E lda [fcbp],y ; entry attribute
3571 F91ED8 89 10 bit #DA_DIR ; check if directory
3572 F91EDA 38 sec
3573 F91EDB F0 71 beq ?30 ; fail if this is a file
3574 F91EDD A9 01 lda #WKB
3575 F91EDF 8B phb ; save current DBR
3576 F91EE0 48 pha ; set DBR bank
3577 F91EE1 AB plb
3578 F91EE2 ACC16
3579 F91EE2 C2 20 rep #PMFLAG
3580 .LONGA on
3581 .MNLIST
3582 F91EE4 A0 1A ldy #26
3583 F91EE6 B7 5E lda [fcbp],y ; first cluster of directory
3584 F91EE8 85 68 sta wtmp
3585 F91EEA A6 16 ldx bplvl ; current path level
3586 F91EEC A5 53 lda fcbs
3587 F91EEE C9 2E 2E cmp #'..' ; watch out if going up a level
Tue Jul 17 11:00:20 2018 Page 18
3588 F91EF1 F0 3C beq ?10 ; we go up one level
3589 F91EF3 8A txa
3590 F91EF4 E8 inx ; increment level
3591 F91EF5 E0 21 cpx #HPLMAX+1 ; level overflow?
3592 F91EF7 B0 52 bcs ?25 ; yes, return failure
3593 F91EF9 86 16 stx bplvl
3594 F91EFB A0 00 ldy #0 ; fcb name pointer
3595 F91EFD CPU16
3596 F91EFD C2 30 rep #(PMFLAG.OR.PXFLAG)
3597 .LONGA on
3598 .LONGI on
3599 .MNLIST
3600 F91EFF 0A asl a ; mult. x 16 to get index
3601 F91F00 0A asl a
3602 F91F01 0A asl a
3603 F91F02 0A asl a ; here always CF=0
3604 F91F03 69 00 A6 adc #cbpl
3605 F91F06 AA tax ; point to HPL
3606 F91F07 ACC08
3607 F91F07 E2 20 sep #PMFLAG
3608 .LONGA off
3609 .MNLIST
3610 F91F09 9E 04 00 stz !hpl_fcb,x
3611 F91F0C B7 5E ?05: lda [fcbp],y ; move fcb name
3612 F91F0E 9D 04 00 sta !hpl_fcb,x
3613 F91F11 E8 inx
3614 F91F12 C8 iny
3615 F91F13 C0 0B 00 cpy #11
3616 F91F16 90 F4 bcc ?05
3617 F91F18 9E 04 00 stz !hpl_fcb,x ; last unused byte
3618 F91F1B CPU16CLC
3619 F91F1B C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3620 .LONGA on
3621 .LONGI on
3622 .MNLIST
3623 F91F1D A5 46 lda dircls ; set parent cluster
3624 F91F1F 9D 00 00 sta !hpl_cls,x
3625 F91F22 A5 68 lda wtmp
3626 F91F24 85 46 sta dircls ; set current directory cluster
3627 F91F26 A5 48 lda dcnt
3628 F91F28 9D 02 00 sta !hpl_ix,x ; set index entry on parent cluster
3629 F91F2B INDEX08
3630 F91F2B E2 10 sep #PXFLAG
3631 .LONGI off
3632 .MNLIST
3633 F91F2D 80 1C bra ?25 ; done (CF=0)
3634 F91F2F 38 ?10: sec
3635 F91F30 CA dex ; decrement level
3636 F91F31 30 18 bmi ?25 ; already at level 0 (root) so failure
3637 F91F33 86 16 stx bplvl
3638 F91F35 CPU16
3639 F91F35 C2 30 rep #(PMFLAG.OR.PXFLAG)
3640 .LONGA on
3641 .LONGI on
3642 .MNLIST
3643 F91F37 8A txa
3644 F91F38 0A asl a ; mult. x 16 to get index
Tue Jul 17 11:00:20 2018 Page 19
3645 F91F39 0A asl a
3646 F91F3A 0A asl a
3647 F91F3B 0A asl a ; here always CF=0
3648 F91F3C 69 00 A6 adc #cbpl
3649 F91F3F AA tax ; point to HPL of current dir.
3650 F91F40 A5 68 lda wtmp ; parent cluster
3651 F91F42 DD 00 00 cmp !hpl_cls,x ; will match...
3652 F91F45 38 sec
3653 F91F46 D0 03 bne ?25 ; ...otherwise return failure
3654 F91F48 85 46 sta dircls ; set cluster of selected directory
3655 F91F4A 18 clc
3656 F91F4B ?25: CPU08
3657 F91F4B E2 30 sep #(PMFLAG.OR.PXFLAG)
3658 .LONGA off
3659 .LONGI off
3660 .MNLIST
3661 F91F4D AB plb ; restore DBR
3662 F91F4E A4 7D ?30: ldy strix
3663 F91F50 60 rts
3664
3665 ; check for a path name delimiter
3666 ;
3667 ; entry: A = path character
3668 ;
3669 ; exit: A = upper case path character
3670 ; CF = 0
3671 ; ZF = 1 if character is a delimiter
3672 ; ZF = 0 if character is legal in file name
3673 ;
3674 ; use: A
3675 ;
3676 ;------
3677 F91F51 chkdlm:
3678 ;------
3679 F91F51 C9 7F cmp #$7F
3680 F91F53 B0 22 bcs ?40 ; discard if ascii code > 126 (ZF=1)
3681 F91F55 C9 21 cmp #' '+1
3682 F91F57 90 1E bcc ?40 ; discard blank & no-printable char (ZF=1)
3683 F91F59 86 6E stx tmpx ; save X
3684 F91F5B A2 0D ldx #DLMSTR-1
3685 F91F5D DF 6B 23 F9 ?10: cmp >dlmstr,x ; match A against list
3686 F91F61 F0 16 beq ?50 ; ZF=1
3687 F91F63 CA dex
3688 F91F64 10 F7 bpl ?10
3689 F91F66 A6 6E ldx tmpx ; restore X
3690 F91F68 C9 61 cmp #'a' ; make upper case
3691 F91F6A 90 06 bcc ?20
3692 F91F6C C9 7B cmp #'z'+1
3693 F91F6E B0 02 bcs ?20
3694 F91F70 29 DF and #$DF
3695 F91F72 C2 03 ?20: rep #PZFLAG.OR.PCFLAG ; ZF=0, CF=0 (no delim char)
3696 F91F74 60 rts
3697 F91F75 A6 6E ?30: ldx tmpx ; restore X
3698 F91F77 E2 02 ?40: sep #PZFLAG ; ZF=1 (delim char match)
3699 F91F79 18 ?50: clc ; always return CF=0
3700 F91F7A 60 rts
3701
Tue Jul 17 11:00:20 2018 Page 20
3702 ; check for legal delimiter: '/' or '\'
3703 ;
3704 ; entry: A = delimiter
3705 ;
3706 ; exit: A = delimiter
3707 ; ZF = 1, CF = 0 if legal delimiter '/' or '\'
3708 ; ZF = 0, CF = 1 if not
3709 ;
3710 ; use: A
3711 ;
3712 ;------
3713 F91F7B chkslh:
3714 ;------
3715 F91F7B C9 2F cmp #'/'
3716 F91F7D F0 06 beq ?10
3717 F91F7F C9 5C cmp #'\'
3718 F91F81 F0 02 beq ?10
3719 F91F83 38 sec ; error: ZF=0, CF=1
3720 F91F84 60 rts
3721 F91F85 18 ?10: clc ; ok: ZF=1, CF=0
3722 F91F86 60 rts
3723 F91F87
3724 ; sets up a clean fcb for later use
3725 ;
3726 ; entry: nothing
3727 ;
3728 ; exit: blank fcb
3729 ; X = 0
3730 ;
3731 ; use: A,X
3732 ;
3733 ;------
3734 F91F87 clrfcb:
3735 ;------
3736 F91F87 A2 0A ldx #10
3737 F91F89 A9 20 lda #' '
3738 F91F8B 95 53 ?10: sta fcbs,x
3739 F91F8D CA dex
3740 F91F8E 10 FB bpl ?10
3741 F91F90 E8 inx
3742 F91F91 60 rts
3743
3744 ; sets up a fake 'root' fcb for later use
3745 ;
3746 ; entry: nothing
3747 ;
3748 ; exit: fake '.' fcb
3749 ; X = 0
3750 ;
3751 ; use: A,X
3752 ;
3753 ;-------
3754 F91F92 fakefcb:
3755 ;-------
3756 F91F92 A9 2E lda #'.' ; start name with '.'
3757 F91F94 85 53 sta fcbs
3758 F91F96 A2 0A ldx #10 ; fill with blanks
Tue Jul 17 11:00:20 2018 Page 21
3759 F91F98 A9 20 lda #' '
3760 F91F9A 95 53 ?10: sta fcbs,x
3761 F91F9C CA dex
3762 F91F9D D0 FB bne ?10
3763 F91F9F 60 rts
3764
3765 ; move current working dir. list to build path list
3766 ;
3767 ; entry: ldtcdlp = pointer to cur. dir. list
3768 ; ldtcdcls = starting cluster of cur. dir.
3769 ; ldtcdlvl = cur. dir. level
3770 ;
3771 ; exit: dircls = starting cluster of cur. dir.
3772 ; bplvl = build path level
3773 ;
3774 ; use: C,X,Y
3775 ;
3776 ;------
3777 F91FA0 mvtobp:
3778 ;------
3779 F91FA0 A6 52 ldx curdrv
3780 F91FA2 BC D2 40 ldy !P0LDT+ldtp,x ; LDT pointer
3781 F91FA5 ACC16
3782 F91FA5 C2 20 rep #PMFLAG
3783 .LONGA on
3784 .MNLIST
3785 F91FA7 BE 20 40 ldx !P0LDT+ldt_cdlvl,y
3786 F91FAA 86 16 stx bplvl
3787 F91FAC AD 1E 40 lda !P0LDT+ldt_cdcls
3788 F91FAF 85 46 sta dircls ; starting directory to build path
3789 F91FB1 F0 13 beq ?10 ; done: ii is the root dir.
3790 F91FB3 INDEX16
3791 F91FB3 C2 10 rep #PXFLAG
3792 .LONGI on
3793 .MNLIST
3794 F91FB5 8A txa ; count of list struct's
3795 F91FB6 0A asl a ; mult. x 16 (size of HPL struct's)
3796 F91FB7 0A asl a
3797 F91FB8 0A asl a
3798 F91FB9 0A asl a
3799 F91FBA 3A dec a ; count of bytes to move - 1
3800 F91FBB BE 1C 40 ldx !P0LDT+ldt_cdlp,y
3801 ;;ldx ldtcdlp ; start source address
3802 F91FBE A0 00 A6 ldy #cbpl ; start dest address
3803 F91FC1 8B phb ; save DBR
3804 F91FC2 54 01 01 mvn #WKB,#WKB ; move
3805 F91FC5 AB plb
3806 F91FC6 ?10: CPU08
3807 F91FC6 E2 30 sep #(PMFLAG.OR.PXFLAG)
3808 .LONGA off
3809 .LONGI off
3810 .MNLIST
3811 F91FC8 60 rts
3812
3813 F91FC9 mvpath:
3814 F91FC9 ACC16
3815 F91FC9 C2 20 rep #PMFLAG
Tue Jul 17 11:00:20 2018 Page 22
3816 .LONGA on
3817 .MNLIST
3818 F91FCB A9 00 A6 lda #cbpl ; offset of build path
3819 F91FCE A4 16 ldy bplvl
3820 F91FD0 90 0B bcc ?10
3821 F91FD2 BC D2 40 ldy !P0LDT+ldtp,x ; LDT pointer
3822 F91FD5 B9 1C 40 lda !P0LDT+ldt_cdlp,y
3823 F91FD8 BE 20 40 ldx !P0LDT+ldt_cdlvl,y
3824 F91FDB 9B txy
3825 F91FDC 18 clc
3826 F91FDD 69 04 00 ?10: adc #hpl_fcb
3827 F91FE0 85 6A sta tmpp
3828 F91FE2 ACC08
3829 F91FE2 E2 20 sep #PMFLAG
3830 .LONGA off
3831 .MNLIST
3832 F91FE4 A9 01 lda #.SEG.cbpl
3833 F91FE6 85 6C sta tmpp+2 ; set HPL pointer
3834 F91FE8 84 6E sty tmpx ; subdir level
3835 F91FEA A2 00 ldx #0
3836 F91FEC 98 tya
3837 F91FED F0 1C beq ?30 ; is root
3838 F91FEF 20 10 20 ?20: jsr unparse
3839 F91FF2 C6 6E dec tmpx
3840 F91FF4 F0 14 beq ?25
3841 F91FF6 CA dex
3842 F91FF7 A9 2F lda #'/'
3843 F91FF9 9D 04 42 sta !P0OS+bpath,x
3844 F91FFC E8 inx
3845 F91FFD ACC16
3846 F91FFD C2 20 rep #PMFLAG
3847 .LONGA on
3848 .MNLIST
3849 F91FFF A5 6A lda tmpp
3850 F92001 69 10 00 adc #HPLSIZE
3851 F92004 85 6A sta tmpp
3852 F92006 ACC08
3853 F92006 E2 20 sep #PMFLAG
3854 .LONGA off
3855 .MNLIST
3856 F92008 80 E5 bra ?20
3857 F9200A CA ?25: dex
3858 F9200B 9E 04 42 ?30: stz !P0OS+bpath,x
3859 F9200E E8 inx
3860 F9200F 60 rts
3861 F92010
3862 ; unparse fcb name into canonical asciiz string
3863 F92010 unparse:
3864 F92010 A0 00 ldy #0 ; unparse name
3865 F92012 A9 08 lda #8 ; string limit
3866 F92014 20 2C 20 jsr ?20 ; unparse field
3867 F92017 B7 6A lda [tmpp],y
3868 F92019 C9 20 cmp #' '
3869 F9201B F0 0B beq ?10 ; no extension
3870 F9201D A9 2E lda #'.'
3871 F9201F 9D 04 42 sta !P0OS+bpath,x
3872 F92022 E8 inx
Tue Jul 17 11:00:20 2018 Page 23
3873 F92023 A9 0B lda #11 ; string limit
3874 F92025 20 2C 20 jsr ?20 ; unparse extension
3875 F92028 9E 04 42 ?10: stz !P0OS+bpath,x
3876 F9202B 60 rts
3877 F9202C 85 70 ?20: sta fsiz
3878 F9202E B7 6A ?25: lda [tmpp],y
3879 F92030 C9 20 cmp #' '
3880 F92032 F0 04 beq ?30
3881 F92034 9D 04 42 sta !P0OS+bpath,x
3882 F92037 E8 inx
3883 F92038 C8 ?30: iny
3884 F92039 C4 70 cpy fsiz
3885 F9203B 90 F1 bcc ?25
3886 F9203D 60 rts
3887
3888 ; get drive number from path string
3889 ;
3890 ; entry: pathp = long pointer to path string
3891 ;
3892 ; exit: A = drive number
3893 ; strix = current path string index
3894 ; CF = 1 if illegal drive name in path string
3895 ;
3896 ; use: A,X
3897 ;
3898 ;-------
3899 F9203E getpdrv:
3900 ;-------
3901 F9203E 64 7D stz strix ; clear current path string index
3902 F92040 A7 7E lda [pathp] ; check if string is empty...
3903 F92042 F0 23 beq ?30 ; ...which isn't O.K. at all
3904 F92044 AA tax
3905 F92045 A0 01 ldy #1
3906 F92047 B7 7E lda [pathp],y ; if the second char is ':'...
3907 F92049 F0 04 beq ?10 ; ...then drive is in pathname
3908 F9204B A5 17 lda defdrv ; take the default (selected) drive
3909 F9204D 80 16 bra ?25 ; return default drive
3910 F9204F 8A ?10: txa ; grab the drive designator
3911 F92050 C9 61 cmp #'a' ; make sure it is upper case
3912 F92052 90 06 bcc ?20
3913 F92054 C9 7B cmp #'z'+1
3914 F92056 B0 10 bcs ?35 ; invalid drive name
3915 F92058 29 DF and #$DF
3916 F9205A E9 40 ?20: sbc #'A'-1 ; note: here always CF=0
3917 F9205C 90 09 bcc ?30 ; invalid drive number
3918 F9205E C9 04 cmp #MAXDRV
3919 F92060 B0 06 bcs ?35 ; invalid drive number
3920 F92062 C8 iny ; bump path string pointer...
3921 F92063 84 7D sty strix ; ...past ':'
3922 F92065 18 ?25: clc
3923 F92066 60 rts
3924 F92067 38 ?30: sec ; error flag
3925 F92068 60 ?35: rts
3926
3927 ; reject devices names -- never return to the caller if error
3928 F92069 nodev:
3929 F92069 20 A0 20 jsr chkdev ; is this a device ?
Tue Jul 17 11:00:20 2018 Page 24
3930 F9206C B0 0C bcs _eaccess ; yes
3931 F9206E 60 rts
3932 F9206F
3933 ; reject if is directory or volume label
3934 ; never return to the caller if error
3935 ; A=fcb attribute
3936 F9206F nodirvol:
3937 F9206F 89 18 bit #DA_DIR+DA_VOLUME
3938 F92071 D0 07 bne _eaccess
3939 F92073 60 rts
3940
3941 ; reject "." and ".." names -- never return to the caller if error
3942 F92074 nodot:
3943 F92074 A5 53 lda fcbs
3944 F92076 C9 2E cmp #'.'
3945 F92078 F0 25 beq chkx
3946 F9207A _eaccess:
3947 F9207A A9 05 lda #ED_ACCESS ; access denied error
3948 F9207C 4C 12 24 jmp oserror
3949
3950 ; reject names with wild cards -- never return to the caller if error
3951 F9207F nowild:
3952 F9207F A5 7C lda haswld
3953 F92081 F0 1C beq chkx
3954 F92083 A9 02 lda #ED_FILE ; invalid filename
3955 F92085 4C 12 24 jmp oserror
3956
3957 ; check if fcb name = "."
3958 ; return ZF=1 if search for root (or '.' in root)
3959 F92088 chkroot:
3960 F92088 A5 46 lda dircls ; are we in the root?
3961 F9208A 05 47 ora dircls+1
3962 F9208C D0 11 bne chkx ; no, no further checks required
3963 F9208E A5 53 lda fcbs
3964 F92090 C9 2E cmp #'.' ; is it a '.' entry ?
3965 F92092 D0 0B bne chkx
3966 F92094 A2 0A ldx #10
3967 F92096 A9 20 lda #' ' ; check for 10 blanks
3968 F92098 D5 53 ?10: cmp fcbs,x
3969 F9209A D0 03 bne chkx
3970 F9209C CA dex
3971 F9209D D0 F9 bne ?10
3972 F9209F 60 chkx: rts
3973
3974 ; check if fcb name is a character device name
3975 ; return:
3976 ; CF=0 if not device name
3977 ; CF=1 if is a device name, A=index of device name
3978 ; use: A,X,Y
3979 F920A0 chkdev:
3980 F920A0 ACC16
3981 F920A0 C2 20 rep #PMFLAG
3982 .LONGA on
3983 .MNLIST
3984 F920A2 A9 79 23 lda #devlst ; set pointer to device names list
3985 F920A5 85 6A sta tmpp
3986 F920A7 ACC08
Tue Jul 17 11:00:20 2018 Page 25
3987 F920A7 E2 20 sep #PMFLAG
3988 .LONGA off
3989 .MNLIST
3990 F920A9 A9 F9 lda #^devlst
3991 F920AB 85 6C sta tmpp+2
3992 F920AD 64 6E stz tmpx ; device index
3993 F920AF A2 07 ?10: ldx #7 ; loop match name
3994 F920B1 9B txy
3995 F920B2 B5 53 ?20: lda fcbs,x ; compare fcb name...
3996 F920B4 D7 6A cmp [tmpp],y ; ...against device name
3997 F920B6 D0 08 bne ?30 ; unmatch
3998 F920B8 88 dey
3999 F920B9 CA dex
4000 F920BA 10 F6 bpl ?20
4001 F920BC 38 sec ; match
4002 F920BD A5 6E lda tmpx ; A=index
4003 F920BF 60 rts
4004 F920C0 A9 08 ?30: lda #8
4005 F920C2 65 6A adc tmpp ; next device name
4006 F920C4 85 6A sta tmpp
4007 F920C6 90 02 bcc ?32
4008 F920C8 E6 6B inc tmpp+1
4009 F920CA E6 6E ?32: inc tmpx ; increment index
4010 F920CC A7 6A lda [tmpp] ; end of list?
4011 F920CE D0 DF bne ?10 ; no, so check next name
4012 F920D0 18 clc ; unmatch
4013 F920D1 60 rts
4014
4015 ;---------------------------------------------------------------------------
4016 ; directory search
4017 ;---------------------------------------------------------------------------
4018
4019 F920D2 fndfcbf:
4020
4021 ; hashed directory search
4022 ; we try to optimize directory searches using a dynamic hash table (HCB)
4023 ;
4024 ; entry: dircls = starting cluster of directory
4025 ; curdrv = current logical drive
4026 ; fhash = hash code of searched fcb entry (=0 if search empty)
4027 ; dfcbtyp = search type (1=empty entry, 2=fcbs entry)
4028 ; fcbs = local name to search
4029 ;
4030 ; exit: CF = 1 if entry not found
4031 ; CF = 0 if entry was found
4032 ; chdcls = cluster of found entry
4033 ; entofs = entry offset number (0..15)
4034 ; secofs = sector's offset of found entry
4035 ; fcbp = long pointer to found entry
4036 ; xbuf = buffer that old sector of found entry
4037 ; lba = 24 bits address of sector
4038 ; dfcbatt = attribute of entry
4039 ;
4040 ; use: C,X,Y
4041 ;
4042 ; note: this routine should be called with 8 bit cpu mode
4043 ;
Tue Jul 17 11:00:20 2018 Page 26
4044 ;-----
4045 F920D2 hfind:
4046 ;-----
4047 F920D2 8B phb ; save current DBR
4048 F920D3 A9 00 lda #^hcb_data
4049 F920D5 48 pha
4050 F920D6 AB plb ; set DBR to HCB struct's
4051 F920D7 A6 52 ldx curdrv ; set drive
4052 F920D9 86 63 stx hcbdrv
4053 F920DB ACC16
4054 F920DB C2 20 rep #PMFLAG
4055 .LONGA on
4056 .MNLIST
4057 F920DD A6 2B ldx ldtrsiz ; root dir. size (in sec)
4058 F920DF A5 46 lda dircls ; starting directory cluster
4059 F920E1 85 40 sta chdcls ; current chainded dir. cluster
4060 F920E3 F0 02 beq ?02 ; is root
4061 F920E5 A6 28 ldx ldtcsiz ; subdir. size (in sec.)
4062 F920E7 86 7B ?02: stx dsiz ; dir. size in sector's
4063 F920E9 CPU08
4064 F920E9 E2 30 sep #(PMFLAG.OR.PXFLAG)
4065 .LONGA off
4066 .LONGI off
4067 .MNLIST
4068 F920EB 8A txa
4069 F920EC A6 09 ldx hlog2 ; shift count
4070 F920EE F0 08 beq ?06
4071 F920F0 18 clc
4072 F920F1 65 08 adc hsiz ; round up to HCB size
4073 F920F3 3A dec a
4074 F920F4 4A ?04: lsr a
4075 F920F5 CA dex
4076 F920F6 D0 FC bne ?04
4077 F920F8 85 7A ?06: sta maxseq ; how many sequnces
4078 F920FA ACC16
4079 F920FA C2 20 rep #PMFLAG
4080 .LONGA on
4081 .MNLIST
4082 F920FC A5 40 lda chdcls ; start from here
4083 F920FE 85 6C ?10: sta hcbcls ; re-entry from this cluster
4084 F92100 85 40 sta chdcls
4085 F92102 A2 00 ldx #0 ; start with sequence=0
4086 F92104 86 62 ?15: stx hcbseq ; re-entry from this sequence
4087 F92106 A0 00 ldy #0 ; current entry index
4088 F92108 CPU16
4089 F92108 C2 30 rep #(PMFLAG.OR.PXFLAG)
4090 .LONGA on
4091 .LONGI on
4092 .MNLIST
4093 F9210A 38 sec ; we want an HCB even if it's recycled
4094 F9210B 20 C9 24 jsr fndhcb ; find&fill an HCB (here return always CF=0)
4095 F9210E A6 04 ldx hcbroot ; X=HCB ptr -- start search
4096 F92110 BD 06 00 lda !hcb_cnt,x ; we have this many entries hashed
4097 F92113 29 FF 7F and #$7FFF ; strip off bit 15
4098 F92116 0A asl a
4099 F92117 65 04 adc hcbroot
4100 F92119 85 6A sta hlast ; point past to the last hash code
Tue Jul 17 11:00:20 2018 Page 27
4101 F9211B A5 72 lda fhash ; look for this hash code
4102 F9211D DD 08 00 ?20: cmp !hcb_data,x ; try to find a match
4103 F92120 F0 24 beq ?30 ; hash code match
4104 F92122 C8 ?25: iny ; re-entry after check hash code
4105 F92123 E8 inx ; bump pointer
4106 F92124 E8 inx
4107 F92125 E4 6A cpx hlast
4108 F92127 90 F4 bcc ?20 ; loop until last code
4109 F92129 A6 04 ldx hcbroot
4110 F9212B 3C 06 00 bit !hcb_cnt,x ; test sign
4111 F9212E 30 66 bmi ?40 ; no more entries: exit with CF=1 (not found)
4112 F92130 INDEX08
4113 F92130 E2 10 sep #PXFLAG
4114 .LONGI off
4115 .MNLIST
4116 F92132 A6 62 ldx hcbseq ; will check more entries
4117 F92134 E8 inx
4118 F92135 E4 7A cpx maxseq
4119 F92137 90 CB bcc ?15 ; ok, try next sequence
4120 F92139 A5 6C lda hcbcls ; we are at root dir.?
4121 F9213B F0 59 beq ?40 ; yes, exit with CF=1 (not found)
4122 F9213D 20 0D 23 jsr getncls ; C=next cluster in chain
4123 F92140 C5 30 cmp ldteoc ; have we fallen off the end of the chain?
4124 F92142 90 BA bcc ?10 ; no, try next cluster
4125 F92144 B0 50 bcs ?40 ; exit with CF=1 (not found)
4126 F92146 84 70 ?30: sty hcby ; save current index
4127 F92148 86 6E stx hcbx ; save current pointer
4128 F9214A 98 tya ; hash matching index
4129 F9214B 4A lsr a ; div. by 16
4130 F9214C 4A lsr a
4131 F9214D 4A lsr a
4132 F9214E 4A lsr a
4133 F9214F AA tax ; sector's offset
4134 F92150 98 tya
4135 F92151 29 0F 00 and #$000F
4136 F92154 A8 tay
4137 F92155 0A asl a
4138 F92156 0A asl a
4139 F92157 0A asl a
4140 F92158 0A asl a
4141 F92159 0A asl a
4142 F9215A 85 74 sta fcbofs ; entry offset
4143 F9215C CPU08
4144 F9215C E2 30 sep #(PMFLAG.OR.PXFLAG)
4145 .LONGA off
4146 .LONGI off
4147 .MNLIST
4148 F9215E 86 45 stx secofs
4149 F92160 84 44 sty entofs
4150 F92162 A5 62 lda hcbseq
4151 F92164 F0 08 beq ?34 ; offset=0
4152 F92166 A4 09 ldy hlog2 ; shift count
4153 F92168 F0 04 beq ?34 ; no shift
4154 F9216A 0A ?32: asl a
4155 F9216B 88 dey
4156 F9216C D0 FC bne ?32
4157 F9216E 18 ?34: clc
Tue Jul 17 11:00:20 2018 Page 28
4158 F9216F 65 45 adc secofs
4159 F92171 85 45 sta secofs
4160 F92173 A8 tay ; sector's offset
4161 F92174 A6 52 ldx curdrv ; current logical drive
4162 F92176 ACC16
4163 F92176 C2 20 rep #PMFLAG
4164 .LONGA on
4165 .MNLIST
4166 F92178 A5 6C lda hcbcls ; current cluster
4167 F9217A 38 sec ; preread buffer from disk
4168 F9217B 20 83 26 jsr fndbuf ; find & load buffer
4169 F9217E 18 clc
4170 F9217F A5 74 lda fcbofs
4171 F92181 65 5E adc fcbp
4172 F92183 85 5E sta fcbp
4173 F92185 CPU08
4174 F92185 E2 30 sep #(PMFLAG.OR.PXFLAG)
4175 .LONGA off
4176 .LONGI off
4177 .MNLIST
4178 F92187 20 9A 21 jsr fcbcmp ; compare entry vs. local FCB
4179 F9218A 90 0C bcc ?45 ; match!
4180 F9218C CPU16
4181 F9218C C2 30 rep #(PMFLAG.OR.PXFLAG)
4182 .LONGA on
4183 .LONGI on
4184 .MNLIST
4185 F9218E A6 6E ldx hcbx ; restore pointer&index
4186 F92190 A4 70 ldy hcby
4187 F92192 A5 72 lda fhash ; hash code to find
4188 F92194 80 8C bra ?25 ; restart search
4189 F92196 ?40: CPU08
4190 F92196 E2 30 sep #(PMFLAG.OR.PXFLAG)
4191 .LONGA off
4192 .LONGI off
4193 .MNLIST
4194 F92198 AB ?45: plb
4195 F92199 60 rts
4196
4197 .LONGA off ; for assembler
4198 .LONGI off
4199
4200 ; compare directory entry with local FCB
4201 F9219A fcbcmp:
4202 F9219A A5 50 lda dfcbtyp ; what kind of search?
4203 F9219C 3A dec a ; 1: wanted an empty entry?
4204 F9219D D0 0A bne ?20 ; no
4205 F9219F A7 5E lda [fcbp]
4206 F921A1 F0 19 beq ?30 ; ok, virgin entry
4207 F921A3 C9 E5 cmp #$E5
4208 F921A5 F0 15 beq ?30 ; ok, empty entry
4209 F921A7 38 ?10: sec ; return failure
4210 F921A8 60 rts
4211 F921A9 A2 0A ?20: ldx #10 ; match on all characters
4212 F921AB 9B txy
4213 F921AC B5 53 ?22: lda fcbs,x
4214 F921AE D7 5E cmp [fcbp],y
Tue Jul 17 11:00:20 2018 Page 29
4215 F921B0 D0 F5 bne ?10 ; unmatch
4216 F921B2 88 dey
4217 F921B3 CA dex
4218 F921B4 10 F6 bpl ?22 ; loop
4219 F921B6 A0 0B ldy #11
4220 F921B8 B7 5E lda [fcbp],y ; get file attribute
4221 F921BA 85 51 sta dfcbatt
4222 F921BC 18 ?30: clc ; return match
4223 F921BD 60 ?35: rts
4224
4225 ; compare directory entry with local FCB
4226 F921BE dfcbcmp:
4227 F921BE A5 50 lda dfcbtyp ; what kind of search?
4228 F921C0 3A dec a ; 1: wanted an empty entry?
4229 F921C1 D0 0A bne ?20 ; no
4230 F921C3 A7 5E lda [fcbp]
4231 F921C5 F0 20 beq ?30 ; ok, virgin entry
4232 F921C7 C9 E5 cmp #$E5
4233 F921C9 F0 1C beq ?30 ; ok, empty entry
4234 F921CB 38 ?10: sec ; return failure
4235 F921CC 60 rts
4236 F921CD 3A ?20: dec a ; 2: wanted match entry ('?' too)?
4237 F921CE D0 19 bne ?40 ; no
4238 F921D0 A2 0A ldx #10 ; match on all characters
4239 F921D2 9B txy
4240 F921D3 B5 53 ?22: lda fcbs,x
4241 F921D5 D7 5E cmp [fcbp],y
4242 F921D7 F0 04 beq ?24 ; match
4243 F921D9 C9 3F cmp #'?' ; this wild card match any character
4244 F921DB D0 EE bne ?10 ; failure: no match
4245 F921DD 88 ?24: dey
4246 F921DE CA dex
4247 F921DF 10 F2 bpl ?22 ; loop
4248 F921E1 A0 0B ?26: ldy #11
4249 F921E3 B7 5E lda [fcbp],y ; get file attribute
4250 F921E5 85 51 sta dfcbatt
4251 F921E7 18 ?30: clc ; return match
4252 F921E8 60 ?35: rts
4253 F921E9 A2 07 ?40: ldx #7 ; caller wish a pattern match
4254 F921EB A0 00 ldy #0 ; first time match name comnponent
4255 F921ED 20 FC 21 jsr ?60
4256 F921F0 B0 09 bcs ?50 ; no match
4257 F921F2 A2 08 ldx #8 ; 2nd time match extension component
4258 F921F4 A0 0A ldy #10
4259 F921F6 20 FC 21 jsr ?60
4260 F921F9 90 E6 bcc ?26 ; ok, pattern match
4261 F921FB 60 ?50: rts ; no match
4262 F921FC 86 77 ?60: stx xstart ; start of component
4263 F921FE 84 78 sty xend ; end of component
4264 F92200 B5 53 lda fcbs,x
4265 F92202 C9 2A cmp #'*' ; pattern start with star?
4266 F92204 F0 1D beq ?70 ; yes, so compare from end of string
4267 F92206 9B txy
4268 F92207 E6 78 inc xend ; one more for loop test
4269 F92209 80 02 bra ?64
4270 F9220B B5 53 ?62: lda fcbs,x
4271 F9220D D7 5E ?64: cmp [fcbp],y ; compare
Tue Jul 17 11:00:20 2018 Page 30
4272 F9220F F0 0A beq ?66 ; match
4273 F92211 C9 3F cmp #'?' ; wildcard match any character
4274 F92213 F0 06 beq ?66
4275 F92215 C9 2A cmp #'*' ; star match any pattern
4276 F92217 F0 08 beq ?68
4277 F92219 D0 B0 bne ?10 ; no match
4278 F9221B E8 ?66: inx
4279 F9221C C8 iny
4280 F9221D E4 78 cpx xend ; loop until end of string
4281 F9221F 90 EA bcc ?62
4282 F92221 18 ?68: clc ; match
4283 F92222 60 rts
4284 F92223 A4 78 ?70: ldy xend ; compare from end of string
4285 F92225 E6 77 inc xstart ; skip beginning star
4286 F92227 B7 5E ?72: lda [fcbp],y
4287 F92229 C9 20 cmp #' ' ; skip padding blanks
4288 F9222B D0 06 bne ?74
4289 F9222D 88 dey
4290 F9222E C4 77 cpy xstart
4291 F92230 B0 F5 bcs ?72
4292 F92232 60 rts ; here was just one star
4293 F92233 A6 78 ?74: ldx xend
4294 F92235 B5 53 ?76: lda fcbs,x
4295 F92237 C9 20 cmp #' ' ; skip padding blanks
4296 F92239 D0 06 bne ?78
4297 F9223B CA dex
4298 F9223C E4 77 cpx xstart
4299 F9223E B0 F5 bcs ?76
4300 F92240 60 rts ; here was just one star
4301 F92241 B5 53 ?78: lda fcbs,x
4302 F92243 C9 3F cmp #'?'
4303 F92245 F0 0B beq ?80
4304 F92247 D7 5E cmp [fcbp],y
4305 F92249 D0 07 bne ?80
4306 F9224B 88 dey
4307 F9224C CA dex
4308 F9224D E4 77 cpx xstart
4309 F9224F B0 F0 bcs ?78
4310 F92251 60 rts ; match
4311 F92252 38 ?80: sec
4312 F92253 60 rts
4313
4314
4315 .LONGA off ; for assembler
4316 .LONGI off
4317 F92254
4318 ; compute hash code of local FCB name (fcbs)
4319 ;
4320 ; entry: fcbs = local name to hash
4321 ; fhash = hash code of searched fcb entry (=0 if search empty)
4322 ;
4323 ; exit: fhash = hash code of local fcb name (=0 if empty)
4324 ;
4325 ; use: C,X,Y
4326 ;
4327 ; note: this routine should be called with 8 bit cpu mode
4328 ;
Tue Jul 17 11:00:20 2018 Page 31
4329 ;-----
4330 F92254 mkhsh:
4331 ;-----
4332 F92254 64 72 stz fhash
4333 F92256 64 73 stz fhash+1
4334 F92258 A5 53 lda fcbs ; first char of file name
4335 F9225A F0 2F beq ?20 ; empty entry
4336 F9225C C9 E5 cmp #$E5
4337 F9225E F0 2B beq ?20 ; deleted entry
4338 F92260 29 7F and #$7F
4339 F92262 85 73 sta fhash+1
4340 F92264 A0 0A ldy #$0A ; hash all char's
4341 F92266 A2 00 ldx #0
4342 F92268 ?10: ACC16
4343 F92268 C2 20 rep #PMFLAG
4344 .LONGA on
4345 .MNLIST
4346 F9226A A5 72 lda fhash
4347 F9226C 0A asl a
4348 F9226D 69 00 00 adc #$0000
4349 F92270 85 72 sta fhash
4350 F92272 ACC08
4351 F92272 E2 20 sep #PMFLAG
4352 .LONGA off
4353 .MNLIST
4354 F92274 E8 inx
4355 F92275 B5 53 lda fcbs,x
4356 F92277 29 7F and #$7F
4357 F92279 45 72 eor fhash
4358 F9227B 85 72 sta fhash
4359 F9227D 88 dey
4360 F9227E D0 E8 bne ?10
4361 F92280 ACC16
4362 F92280 C2 20 rep #PMFLAG
4363 .LONGA on
4364 .MNLIST
4365 F92282 A5 72 lda fhash
4366 F92284 D0 03 bne ?15 ; hash=0 reserved for empty entry
4367 F92286 1A inc a
4368 F92287 85 72 sta fhash
4369 F92289 ?15: ACC08
4370 F92289 E2 20 sep #PMFLAG
4371 .LONGA off
4372 .MNLIST
4373 F9228B 60 ?20: rts
4374
4375 ;---------------------------------------------------------------------------
4376 ; utilities
4377 ;---------------------------------------------------------------------------
4378
4379 ; in: dcnt, dircls, chdcls, curdrv
4380 F9228C getdfcb:
4381 F9228C getdbuf:
4382 F9228C CPU16
4383 F9228C C2 30 rep #(PMFLAG.OR.PXFLAG)
4384 .LONGA on
4385 .LONGI on
Tue Jul 17 11:00:20 2018 Page 32
4386 .MNLIST
4387 F9228E A5 46 lda dircls ; first cluster of directory
4388 F92290 A6 48 ldx dcnt
4389 F92292 E8 inx
4390 F92293 86 48 stx dcnt ; current directory index
4391 F92295 F0 63 beq ?18 ; first entry of dir.
4392 F92297 E0 FF FF cpx #$FFFF ; invalid next dir. index ?
4393 F9229A F0 5A beq ?16 ; yes, set end of directory condition (CF=1)
4394 F9229C 8A txa ; C=dcnt
4395 F9229D 4A lsr a ; div. by 16 (16 entries per sector)
4396 F9229E 4A lsr a
4397 F9229F 4A lsr a
4398 F922A0 4A lsr a
4399 F922A1 85 68 sta wtmp ; save sector's count
4400 F922A3 A8 tay ; Y=sector's offset
4401 F922A4 8A txa ; C=dcnt
4402 F922A5 29 0F 00 and #$000F ; entry number
4403 F922A8 AA tax ; X=entry offset
4404 F922A9 INDEX08
4405 F922A9 E2 10 sep #PXFLAG
4406 .LONGI off
4407 .MNLIST
4408 F922AB 84 45 sty secofs ; low sector's offset (valid for root dir only)
4409 F922AD 86 44 stx entofs ; entry offset
4410 F922AF CPU16
4411 F922AF C2 30 rep #(PMFLAG.OR.PXFLAG)
4412 .LONGA on
4413 .LONGI on
4414 .MNLIST
4415 F922B1 A5 46 lda dircls ; we are at root dir.?
4416 F922B3 D0 08 bne ?05 ; no
4417 F922B5 A6 48 ldx dcnt
4418 F922B7 E4 2C cpx ldtrent ; end of the root directory?
4419 F922B9 B0 36 bcs ?15 ; yes, set end of directory condition (CF=1)
4420 F922BB 80 41 bra ?20 ; get buffer
4421 F922BD ?05: INDEX08
4422 F922BD E2 10 sep #PXFLAG
4423 .LONGI off
4424 .MNLIST
4425 F922BF A5 68 lda wtmp ; sector's offset
4426 F922C1 A8 tay
4427 F922C2 A6 29 ldx ldtcshf ; sector per cluster shift count
4428 F922C4 F0 04 beq ?08 ; no shift (1 sec. per cluster)
4429 F922C6 4A ?06: lsr a
4430 F922C7 CA dex
4431 F922C8 D0 FC bne ?06
4432 F922CA 85 42 ?08: sta clsofs ; cluster's count to skip from the first
4433 F922CC ACC08
4434 F922CC E2 20 sep #PMFLAG
4435 .LONGA off
4436 .MNLIST
4437 F922CE 98 tya
4438 F922CF 25 32 and ldtmcls ; sector's offset within cluster
4439 F922D1 85 45 sta secofs
4440 F922D3 CPU16
4441 F922D3 C2 30 rep #(PMFLAG.OR.PXFLAG)
4442 .LONGA on
Tue Jul 17 11:00:20 2018 Page 33
4443 .LONGI on
4444 .MNLIST
4445 F922D5 A5 40 lda chdcls ; do we already know where we are?
4446 F922D7 F0 09 beq ?10 ; if not trace from start of chain
4447 F922D9 A4 44 ldy entofs ; entofs+secofs: null if we moved onto...
4448 ; ...next cluster
4449 F922DB D0 23 bne ?24 ; we stay at the same cluster
4450 F922DD C8 iny ; move on the next cluster in the chain...
4451 F922DE 84 42 sty clsofs ; ...starting from chdcls
4452 F922E0 80 02 bra ?12
4453 F922E2 A5 46 ?10: lda dircls ; start cluster in the chain
4454 F922E4 A6 42 ?12: ldx clsofs ; skip along chain until we arrive...
4455 F922E6 F0 16 beq ?20 ; ...at the destination cluster
4456 F922E8 C6 42 dec clsofs ; decrement cluster offset
4457 F922EA 20 0D 23 jsr getncls ; C=next cluster in chain
4458 F922ED C5 30 cmp ldteoc ; have we fallen off the end of the chain?
4459 F922EF 90 F3 bcc ?12 ; no, loop again
4460 ; here, end of cluster's chain
4461 F922F1 A9 FF FF ?15: lda #$FFFF ; set end of directory condition
4462 F922F4 85 48 sta dcnt
4463 F922F6 64 40 ?16: stz chdcls ; forget where we are
4464 F922F8 80 10 bra ?30 ; exit with CF=1
4465 F922FA 64 42 ?18: stz clsofs ; we are at first entry: clear offset's
4466 F922FC 64 44 stz entofs ; entofs+secofs
4467 F922FE 85 40 ?20: sta chdcls ; remember this cluster for next time
4468 F92300 ?24: CPU08 ; C=cluster (=0 if root)
4469 F92300 E2 30 sep #(PMFLAG.OR.PXFLAG)
4470 .LONGA off
4471 .LONGI off
4472 .MNLIST
4473 F92302 A6 52 ldx curdrv ; current logical drive
4474 F92304 A4 45 ldy secofs ; sector's offset
4475 F92306 38 sec ; preread buffer from disk
4476 F92307 20 83 26 jsr fndbuf ; find & load buffer
4477 F9230A ?30: CPU08
4478 F9230A E2 30 sep #(PMFLAG.OR.PXFLAG)
4479 .LONGA off
4480 .LONGI off
4481 .MNLIST
4482 F9230C 60 rts
4483
4484 ; get next cluster number
4485 ; in: C = cluster
4486 ; out: C = next chain cluster
4487 ; ldtfp preset to floppy fat table
4488 F9230D getncls:
4489 F9230D 08 php
4490 F9230E CPU08
4491 F9230E E2 30 sep #(PMFLAG.OR.PXFLAG)
4492 .LONGA off
4493 .LONGI off
4494 .MNLIST
4495 F92310 24 18 bit ldtfg1 ; bit 6=0 if floppy
4496 F92312 50 1C bvc ?10 ; FAT12 media
4497 F92314 EB xba ; A=sector (one sec. = 256 cluster #)
4498 F92315 AA tax
4499 F92316 4A lsr a ; divide by 16 to get x-mem buffer bank
Tue Jul 17 11:00:20 2018 Page 34
4500 F92317 4A lsr a
4501 F92318 4A lsr a
4502 F92319 4A lsr a
4503 F9231A 18 clc
4504 F9231B 65 1D adc ldtfbuf ; add fat table base base bank
4505 F9231D 8F 28 FD 00 sta >PIA0+PIAPRA ; set bank
4506 F92321 8A txa
4507 F92322 EB xba ; restore cluster number in C
4508 F92323 CPU16
4509 F92323 C2 30 rep #(PMFLAG.OR.PXFLAG)
4510 .LONGA on
4511 .LONGI on
4512 .MNLIST
4513 F92325 29 FF 0F and #$0FFF ; mask 4096 cluster's
4514 F92328 0A asl a
4515 F92329 AA tax ; index to 8k fat table in x-mem window
4516 F9232A BF 00 20 01 lda >XMWIN,x ; get chained cluster
4517 F9232E 28 plp
4518 F9232F 60 rts
4519 F92330 ?10: CPU16
4520 F92330 C2 30 rep #(PMFLAG.OR.PXFLAG)
4521 .LONGA on
4522 .LONGI on
4523 .MNLIST
4524 F92332 48 pha ; cluster #
4525 F92333 4A lsr a ; div. by 2
4526 F92334 18 clc
4527 F92335 63 01 adc $01,s ; mult. x 1.5
4528 F92337 A8 tay ; index to fat table
4529 F92338 68 pla
4530 F92339 4A lsr a ; even or odd cluster?
4531 F9233A B7 1A lda [ldtfp],y
4532 F9233C B0 05 bcs ?15 ; odd cluster
4533 F9233E 29 FF 0F and #$0FFF ; even cluster
4534 F92341 80 04 bra ?20
4535 F92343 4A ?15: lsr a ; odd cluster: 4 bit's shift
4536 F92344 4A lsr a
4537 F92345 4A lsr a
4538 F92346 4A lsr a
4539 F92347 28 ?20: plp
4540 F92348 60 rts
4541
4542 .LONGA off ; for assembler
4543 .LONGI off
4544 F92349
4545 ; get pointer to directory entry given by dcnt
4546 ; in: dcnt=directory entry counter
4547 F92349 getsec:
4548 F92349 ACC16
4549 F92349 C2 20 rep #PMFLAG
4550 .LONGA on
4551 .MNLIST
4552 F9234B A5 48 lda dcnt ; compute sector count
4553 F9234D 4A lsr a ; divide by 16 (16 entries per sector)
4554 F9234E 4A lsr a
4555 F9234F 4A lsr a
4556 F92350 4A lsr a
Tue Jul 17 11:00:20 2018 Page 35
4557 F92351 48 pha ; sector count
4558 F92352 A6 29 ldx ldtcshf ; sector per cluster shift count
4559 F92354 F0 04 beq ?06 ; no shift (1 sec. per cluster)
4560 F92356 4A ?04: lsr a
4561 F92357 CA dex
4562 F92358 D0 FC bne ?04
4563 F9235A 85 42 ?06: sta clsofs ; cluster's count to skip from the first
4564 F9235C 68 pla
4565 F9235D ACC08
4566 F9235D E2 20 sep #PMFLAG
4567 .LONGA off
4568 .MNLIST
4569 F9235F 25 32 and ldtmcls ; cluster sector offset
4570 F92361 85 45 sta secofs
4571 F92363 A5 48 lda dcnt
4572 F92365 29 0F and #$0F
4573 F92367 0A asl a
4574 F92368 85 44 sta entofs
4575 F9236A 60 rts
4576 F9236B
4577 ;---------------------------------------------------------------------------
4578 ; tables
4579 ;---------------------------------------------------------------------------
4580
4581 F9236B 3A 2E 3B 2C 3D dlmstr .DB ':.;,=+\<>|/"[]' ; path delimeters
2B 5C 3C 3E 7C
2F 22 5B 5D
4582 00000E DLMSTR .EQU $-dlmstr
4583
4584 F92379 devlst:
4585 F92379 43 4F 4E 20 20 .DB 'CON ' ; Keyboard and display
20 20 20
4586 F92381 4B 45 59 42 44 .DB 'KEYBD$ ' ; Keyboard
24 20 20
4587 F92389 53 43 52 45 45 .DB 'SCREEN$ ' ; Display
4E 24 20
4588 F92391 43 4F 4E 53 4F .DB 'CONSOLE$'
4C 45 24
4589 F92399 50 52 4E 20 20 .DB 'PRN ' ; System list device, usually a parallel port
20 20 20
4590 F923A1 4C 53 54 20 20 .DB 'LST ' ; System list device, usually a parallel port
20 20 20
4591 F923A9 4C 50 54 31 20 .DB 'LPT1 ' ; First parallel printer port
20 20 20
4592 F923B1 4C 50 54 32 20 .DB 'LPT2 ' ; Second parallel printer port
20 20 20
4593 F923B9 4C 50 54 33 20 .DB 'LPT3 ' ; Third parallel printer port
20 20 20
4594 F923C1 41 55 58 20 20 .DB 'AUX ' ; Auxiliary device, usually a serial port
20 20 20
4595 F923C9 43 4F 4D 31 20 .DB 'COM1 ' ; First serial communications port
20 20 20
4596 F923D1 43 4F 4D 32 20 .DB 'COM2 ' ; Second serial communications port
20 20 20
4597 F923D9 43 4F 4D 33 20 .DB 'COM3 ' ; Third serial communications port
20 20 20
4598 F923E1 43 4F 4D 34 20 .DB 'COM4 ' ; Fourth serial communications port
Tue Jul 17 11:00:20 2018 Page 36
20 20 20
4599 F923E9 4E 55 4C 20 20 .DB 'NUL ' ; Bit-bucket device
20 20 20
4600 F923F1 24 49 44 4C 45 .DB '$IDLE$ ' ; Bit-bucket device
24 20 20
4601 F923F9 43 4C 4F 43 4B .DB 'CLOCK$ ' ; System real-time clock
24 20 20
4602 F92401 43 4C 4F 43 4B .DB 'CLOCK ' ; System real-time clock
20 20 20
4603 F92409 43 4F 4E 46 49 .DB 'CONFIG$ '
47 24 20
4604 F92411 00 .DB 0
Lines Assembled : 4398 Errors : 0