Blame | Last modification | View Log | Download | RSS feed
Tue Jul 17 11:00:21 2018 Page 1
2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
-----------------------------------------------------
Input Filename : src\F9\utils.asm
Output Filename : obj\F9\utils.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:21 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:21 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:21 2018 Page 4
2763
2764 .ENDS
2765
2766 [01] .IFDEF _ACIA_INC_
2767 .INCLUDE INC\SP.INC
2768 [00] .ENDIF
2769
2793 .LIST on
2794
2795 ;---------------------------------------------------------------------------
2796
2797 000020 HPLMAX .EQU 32 ; Max. subdirectory level
2798
2799 000200 BCBCNT .EQU $200 ; BCB's struct's count #
2800 000C00 BCBXBNK .EQU $0C00 ; starting BCB x-mem buffer #
2801 000040 DMACNT .EQU 64
2802
2803 0000E0 FAT0X .EQU $E0 ; x-mem bank for fat table of ata #0
2804 0000F0 FAT1X .EQU $F0 ; x-mem bank for fat table of ata #1
2805
2806 F8FFB1 .INCLUDE INC\LDT.INC
2807 ; LDT.INC
2808
2809 [01] .IFNDEF __LDT_INC__
2810 000001 __LDT_INC__ .SET 1
2811
2812 .LIST on
2813 ;---------------------------------------------------------------------------
2814 ; Logical Drive Table (LDT) -- page 0 offset's
2815 ;---------------------------------------------------------------------------
2816
2817 F8FFB1 STRUCT LDT
2818 _LDT .SECTION page0,common,ref_only,offset 0 ;LDT Struct
2819 ;.ABSOLUTE
2820 ;.ORG 0
2821 .MNLIST
2822 000000 00 ldt_fg1 .DB ; logical volume flag's
2823 ; <7>: device ready (fdc drive or ata device)
2824 ; <6>: if=1->HD/CF else->FD
2825 ; <1:0>: phisycal device number
2826
2827 000001 00 ldt_fg2 .DB ; <7>: valid volume (fat volume or cbm disk)
2828 ; <6>: if=1->FAT else->CBM (FD only)
2829 ; <5>: disk format checked
2830 ; <1:0>: disk format (fdc only)
2831
2832 000002 0000 ldt_root .DW ; lba of root dir
2833 000004 0000 ldt_fat1 .DW ; lba of fat1 table
2834 000006 0000 ldt_fat2 .DW ; lba of fat2 table
2835 000008 0000 ldt_cls .DW ; lba of first data cluster
2836 00000A 0000 ldt_max .DW ; max usable cluster + 1
2837 00000C 0000 ldt_rent .DW ; root dir. max. entries
2838 00000E 0000 ldt_cent .DW ; max. entries in dir. cluster
2839 000010 0000 ldt_eoc .DW ; end of cluster chain marker
2840 000012 0000 ldt_free .DW ; count of free cluster's
2841 000014 0000 ldt_nxt .DW ; next free cluster
2842 000016 0000 ldt_fsiz .DW ; fat table size
Tue Jul 17 11:00:21 2018 Page 5
2843
2844 000018 00 ldt_csiz .DB ; cluster size (1,2,4,8,16,32,64)
2845 000019 00 ldt_cshf .DB ; cluster shift (0,1,2,3,4,5,6)
2846 00001A 00 ldt_rsiz .DB ; root dir. size (sector's)
2847 00001B 00 ldt_mcls .DB ; mask for clust. module: 00,01,03,07,0F,1F,3F
2848 00001C 0000 ldt_cdlp .DW ; current working dir list pointer
2849 00001E 0000 ldt_cdcls .DW ; current working dir start cluster
2850 000020 00 ldt_cdlvl .DB ; current working dir level count
2851
2852 000021 00 ldt_ptype .DB
2853 000022 0000 0000 ldt_pstart .LWORD
2854 000026 0000 0000 ldt_psize .LWORD
2855
2856 000022 ldt_fp .EQU ldt_pstart ; fat table buffer long pointer
2857 000025 ldt_fbuf .EQU ldt_pstart+3 ; fat table: x-mem base bank/dma buffer
2858
2859 000026 ldt_pbr .EQU ldt_psize ; long pointer to PBR cache buffer
2860 000029 ldt_fmt .EQU ldt_psize+3
2861
2862 00002A ESTRUCT LDT
2863 00002A LDTSIZE .DS 0
2864 ;.RELATIVE
2865 .ENDS
2866 .MNLIST
2867
2868 [00] .ENDIF
2869
2870 F8FFB1
2871 ;---------------------------------------------------------------------------
2872 ; Hierarchical Path List (HPL) -- 16 bit offset's
2873 ;---------------------------------------------------------------------------
2874
2875 F8FFB1 LSTRUCT HPL
2876 _HPL .SECTION common,ref_only,offset 0 ;HPL Struct
2877 .MNLIST
2878 000000 0000 hpl_cls .DW ; parent cluster
2879 000002 0000 hpl_ix .DW ; entry index in parent cluster
2880 000004 hpl_fcb .DS 11 ; fcb name
2881 00000F 00 hpl_lst .DB ; unused
2882 000010 ESTRUCT HPL
2883 000010 HPLSIZE .DS 0
2884 ;.RELATIVE
2885 .ENDS
2886 .MNLIST
2887
2888 ;---------------------------------------------------------------------------
2889 ; Buffer Control Block (BCB) -- 16 bit offset's
2890 ;---------------------------------------------------------------------------
2891
2892 F8FFB1 LSTRUCT BCB
2893 _BCB .SECTION common,ref_only,offset 0 ;BCB Struct
2894 .MNLIST
2895 000000 0000 bcb_next .DW ; next logical linked BCB
2896 000002 00 bcb_drv .DB ; logical drive
2897 000003 00 bcb_sec .DB ; sector offset
2898 000004 0000 bcb_cls .DW ; cluster
2899 000006 0000 bcb_lba .DW ; sector lba address
Tue Jul 17 11:00:21 2018 Page 6
2900 000008 0000 bcb_lbah .DW ; lba high
2901 000008 bcb_head .EQU bcb_lbah ; floppy head
2902 00000A 0000 bcb_buf .DW ; x-mem buffer number
2903 00000A bcb_trk .EQU bcb_buf ; floppy track(low) & sector(hi)
2904 00000C 0000 bcb_ptr .DW ; buffer pointer
2905 00000E 0000 bcb_xbnk .DW ; buffer pointer hi & x-mem bank
2906 00000E bcb_dma .EQU bcb_xbnk ; buffer pointer hi & dma buffer
2907 000010 ESTRUCT BCB
2908 000010 BCBSIZE .DS 0
2909 ;.RELATIVE
2910 .ENDS
2911 .MNLIST
2912
2913 ;---------------------------------------------------------------------------
2914 ; hash Control Block (BCB) -- 16 bit offset's
2915 ;---------------------------------------------------------------------------
2916
2917 F8FFB1 LSTRUCT HCB
2918 _HCB .SECTION common,ref_only,offset 0 ;HCB Struct
2919 .MNLIST
2920 000000 0000 hcb_next .DW ; pointer to next HCB
2921 000002 0000 hcb_cls .DW ; cluster number
2922 000004 0000 hcb_seq .DW ; sequence number + logical drive number
2923 000006 0000 hcb_cnt .DW ; number of hashed entries
2924 000008 hcb_data .DS 0 ; hash buffer data
2925 000008 ESTRUCT HCB
2926 000008 HCBSIZE .DS 0
2927 ;.RELATIVE
2928 .ENDS
2929 .MNLIST
2930
2931 ;---------------------------------------------------------------------------
2932 ; TOS Working Segment
2933 ;---------------------------------------------------------------------------
2934
2935 000001 WKB .EQU .SEG.TOSSEG ; TOS working bank
2936
2937 010000 TS .SET TOSSEG
2938 01FFFF TE .SET TOSSEG + $FFFF
2939 018C00 TO0 .SET $018C00
2940 019E00 TO1 .SET TOSWKM
2941
2942 .comment @
2943 _TOS0: .SECTION ref_only, common, offset TO0, range TS TE ;FAT Struct's
2944 _TOS0_START .DS 0
2945
2946 _pbr0 .DS 512
2947 _pbr1 .DS 512
2948 _pbr2 .DS 512
2949 _pbr3 .DS 512
2950
2951 _TOS0_END .DS 0
2952 TOS0SIZ .EQU (_TOS0_END - _TOS0_START)
2953 .ENDS
2954 @
2955
2956 _TOS1: .SECTION ref_only, common, offset TO1, range TS TE ;FAT Struct's
Tue Jul 17 11:00:21 2018 Page 7
2957 019E00 _TOS1_START .DS 0
2958
2959 ; current working directory HPL
2960 019E00 cwdl0 .DS (HPLSIZE*HPLMAX)
2961 01A000 cwdl1 .DS (HPLSIZE*HPLMAX)
2962 01A200 cwdl2 .DS (HPLSIZE*HPLMAX)
2963 01A400 cwdl3 .DS (HPLSIZE*HPLMAX)
2964
2965 ; current building path HPL
2966 01A600 cbpl .DS (HPLSIZE*HPLMAX)
2967 01A600 HPL_CLS .EQU hpl_cls+cbpl
2968 01A602 HPL_IX .EQU hpl_ix+cbpl
2969 01A604 HPL_FCB .EQU hpl_fcb+cbpl
2970
2971 ; BCB list's
2972 01A800 bcbstart .DS (BCBCNT*BCBSIZE)
2973 01C800 bcbend .DS 0
2974 01C800 dmastart .DS (DMACNT*BCBSIZE)
2975 01CC00 dmaend .DS 0
2976 01CC00 dma0s .DS (17*BCBSIZE)
2977 01CD10 dma1s .DS (17*BCBSIZE)
2978
2979 01CE20 _TOS1_END .DS 0
2980 003020 TOS1SIZ .EQU (_TOS1_END - _TOS1_START)
2981 .ENDS
2982
2983 ;---------------------------------------------------------------------------
2984 ; HCB Segment
2985 ;---------------------------------------------------------------------------
2986
2987 000004 HCBBNK .EQU .SEG.HCBSEG
2988 040000 HS .SET HCBSEG
2989 04FFFF HE .SET HCBSEG + $FFFF
2990 040000 HO .SET HCBSEG
2991
2992 _HCBS: .SECTION ref_only, common, offset HO, range HS HE ;HCB's List
2993 040000 hcb_bnk .DS 8
2994 040008 hcbstart .DS 0
2995 .ENDS
2996
2997 ;.comment @
2998 ;---------------------------------------------------------------------------
2999 ; direct page for LDT var's
3000 ;---------------------------------------------------------------------------
3001
3002 ; P0OS
3003 DPOS: .SECTION page0, common, ref_only, offset 0 ;OS Main D.P.
3004
3005 ;sysbuf .DS 2 ; floppy track 0 cache buffer
3006 000000 00 defhsec .DB ; default hidden sector's in fdisk
3007 000001 00 .DB
3008 000002 0000 cmdstk .DW ; saved stack on TOS command's
3009 000004 bpath .DS 80
3010
3011 000054 bpath1 .DS 0
3012 .ENDS
3013 ;@
Tue Jul 17 11:00:21 2018 Page 8
3014
3015 ; P0LDT
3016 DPLDT: .SECTION page0, common, ref_only, offset 0 ;LDT D.P.
3017
3018 000000 ldt0 .DS LDTSIZE
3019 00002A ldt1 .DS LDTSIZE
3020 000054 ldt2 .DS LDTSIZE
3021 00007E ldt3 .DS LDTSIZE
3022 0000A8 ldt4 .DS LDTSIZE
3023
3024 0000D2 ldtp .DS 6 ; pointer to LDT's in DPLDT page
3025
3026 0000D8 sysbuf .DS 4 ; floppy track 0 cache buffer
3027
3028 .ENDS
3029
3030 ;---------------------------------------------------------------------------
3031 ; direct page for FAT var's
3032 ;---------------------------------------------------------------------------
3033
3034 ; P0FAT
3035 DPFAT: .SECTION page0, common, ref_only, offset 0 ;FAT D.P.
3036
3037 000000 0000 ostos .DW ; saved top of stack
3038 000002 00 ioerr .DB ; i/o error
3039 000003 00 ioerr2 .DB ; extended i/o error
3040 000004 0000 hcbroot .DW ; HCB struct's list
3041 000006 0000 hcblst .DW ; the last one HCB
3042 000008 00 hsiz .DB ; how many sector's an HCB can hold
3043 000009 00 hlog2 .DB ; shift count related to hsiz
3044 00000A 0000 bcbroot .DW ; BCB buffer's list
3045 00000C 0000 bcblst .DW ; the last one BCB
3046 00000E 0000 dmaroot .DW ; dma BCB buffer's list
3047 000010 0000 dmalst .DW ; the last one dma BCB
3048 000012 0000 dmabcb .DW ; BCB list for floppy root, cluster#2,#3
3049 000014 00 fspt .DB ; sector per track (floppy)
3050 000015 00 pdrive .DB ; phisycal drive number
3051 000016 00 bplvl .DB ; subdir level while build path
3052 000017 00 defdrv .DB ; default drive
3053
3054 ; the first block of ldt_ var's is copied from the LDT struct
3055 000018 00 ldtfg1 .DB ; logical volume flag's
3056 ; <7>: device ready (fdc drive or ata device)
3057 ; <6>: if=1->HD/CF else->FD
3058 ; <0>: phisycal device number
3059
3060 000019 00 ldtfg2 .DB ; <7>: valid volume (fat volume or cbm disk)
3061 ; <6>: if=1->FAT else->CBM (FD only)
3062 ; <5>: disk format checked
3063 ; <1:0>: disk format (fdc only)
3064
3065 00001A ldtfp LP ; fat table buffer long pointer
3066 00001D 00 ldtfbuf .DB ; fat table: x-mem base bank/dma buffer
3067
3068 00001E 0000 ldtroot .DW ; lba of root dir
3069 000020 0000 ldtfat1 .DW ; lba of fat1 table
3070 000022 0000 ldtfat2 .DW ; lba of fat2 table
Tue Jul 17 11:00:21 2018 Page 9
3071 000024 0000 ldtcls .DW ; lba of first data cluster
3072 000026 0000 ldtmax .DW ; max usable cluster + 1
3073 000028 00 ldtcsiz .DB ; cluster size (1,2,4,8,16,32,64)
3074 000029 00 ldtcshf .DB ; cluster shift (0,1,2,3,4,5,6)
3075 00002A 00 ldtfsiz .DB ; fat table size (if 0 -> 256)
3076 00002B 00 ldtrsiz .DB ; root dir. size (sector's)
3077 00002C 0000 ldtrent .DW ; root dir. max. entries
3078 00002E 0000 ldtcent .DW ; max. entries in dir. cluster
3079 000030 0000 ldteoc .DW ; end of cluster chain marker
3080 000032 00 ldtmcls .DB ; mask for clust. module: 00,01,03,07,0F,1F,3F
3081 000033 00 ldtfmt .DB ; floppy disk format (0,1,2, FF if ata device)
3082 000034 0000 ldtcdlp .DW ; current working dir list pointer
3083 000036 0000 ldtcdcls .DW ; current working dir start cluster
3084 000038 0000 ldtfree .DW ; count of free cluster's
3085 00003A 0000 ldtnxt .DW ; next free cluster
3086 00003C 00 ldtcdlvl .DB ; current working dir level count
3087 00003D ldtpbr LP ; long pointer to PBR cache buffer
3088
3089 000040 0000 chdcls .DW ; last accessed chained dir. cluster
3090 000042 0000 clsofs .DW ; cluster's offset from start of chain
3091
3092 ; not change order of the 2 following var's: will be accessed as 16 bit var
3093 000044 00 entofs .DB ; entry offset from start of sector
3094 000045 00 secofs .DB ; sector's offset from start of cluster
3095
3096 000046 0000 dircls .DW ; directory cluster
3097 000048 0000 dcnt .DW ; directory entry counter
3098 00004A 0000 lba .DW ; lba sector address
3099 00004C 0000 lbah .DW ; lba is 24 bit's only
3100 00004E 0000 xbuf .DW ; x-mem buffer transfer number
3101
3102 00004C fhead .EQU lbah ; fd head
3103 00004E ftrack .EQU xbuf ; fd track
3104 00004F fsec .EQU xbuf+1 ; fd sector
3105
3106 000050 00 dfcbtyp .DB ; FCB type to search
3107 000051 00 dfcbatt .DB ; attribute of found FCB
3108
3109 000052 00 curdrv .DB ; current logical drive
3110 000053 fcbs .DS 11 ; file control block name
3111
3112 ;dcmask .DW ; mask to start of cluster
3113 ; FFF0, FFE0, FFC0, FF80, FF00, FE00
3114
3115 00005E 0000 fcbp .DW ; FCB buffer long pointer
3116 000060 0000 .DW ; low=fcbp+2, high=x-mem bank or dma buffer
3117 000061 dmabuf .EQU fcbp+3 ; dma buffer #
3118 000061 xmbank .EQU fcbp+3 ; x-mem bank #
3119
3120 ; temp area
3121 000062 00 hcbseq .DB
3122 000063 00 hcbdrv .DB
3123 000064 0000 bcbcls .DW
3124 000066 00 bcbdrv .DB
3125 000067 00 bcbsec .DB
3126
3127 000068 0000 thash .DW
Tue Jul 17 11:00:21 2018 Page 10
3128 000068 hcbrec .EQU thash
3129 000068 wtmp .EQU thash
3130
3131 00006A 0000 hlast .DW
3132 00006C 0000 hcbcls .DW
3133 00006E 0000 hcbx .DW
3134 000070 0000 hcby .DW
3135 00006A tmpp .EQU hlast ; temp. long pointer
3136 00006E tmpx .EQU hcbx
3137 00006F wild .EQU hcbx+1
3138 000070 fsiz .EQU hcby
3139 000071 fptr .EQU hcby+1
3140 00006E ldrv .EQU hcbx
3141 00006F tmpldt .EQU hcbx+1
3142
3143 000072 0000 fhash .DW
3144 000074 0000 fcbofs .DW
3145 000076 00 bcbload .DB
3146 000077 00 xstart .DB
3147 000078 00 xend .DB
3148 000079 00 seccnt .DB
3149 00007A 00 maxseq .DB
3150 00007B 00 dsiz .DB
3151
3152 00007C 00 haswld .DB
3153 00007D 00 strix .DB
3154 00007E pathp LP ; long pointer to path string
3155
3156 ; TEMP
3157 000081 0000 quot .DW
3158 000083 0000 dvsor .DW
3159 000085 0000 troot .DW
3160 000087 0000 tlst .DW
3161 000089 0000 bdmask .DW
3162 00008B 0000 bcmask .DW
3163
3164 00008D 00 hcbuse .DB
3165
3166 .ENDS
3167
3171 .LIST on
3172
3173 ;---------------------------------------------------------------------------
3174 ; code segment -- bank $F9
3175 ;---------------------------------------------------------------------------
3176
3177 .CODEF9
3178 .EXTERN oserror
3179 .EXTERN bldldt ; fsint.sm
3180 .PUBLIC mxdrv, fndhcb, fndbuf, cls2lba
3181
3182 .LONGA off
3183 .LONGI off
3184
3185 ; switch logical drive
3186 ;
3187 ; entry: A = logical drive number
Tue Jul 17 11:00:21 2018 Page 11
3188 ;
3189 ; exit: curdrv = current logical drive number
3190 ; pdrive = current phsycal drive
3191 ; LDT struct of the drive moved in page 0
3192 ;
3193 ; use: A,X,Y
3194 ;
3195 ; note: if any error this function never return to the caller
3196 ;
3197 ;-----
3198 F92423 mxdrv:
3199 ;-----
3200 F92423 C9 04 cmp #MAXDRV
3201 F92425 90 05 bcc ?02
3202 F92427 A9 0F lda #ED_DRIVE ; invalid drive
3203 F92429 4C 12 24 jmp oserror
3204 F9242C A8 ?02: tay ; drive to select
3205 F9242D BE D2 40 ldx !P0LDT+ldtp,y ; LDT pointer
3206 F92430 3C 00 40 bit !P0LDT+ldt_fg1,x ; drive flag
3207 F92433 10 33 bpl ?05 ; drive not ready
3208 F92435 70 41 bvs ?10 ; fixed disk: we can trust...
3209 F92437 84 6E sty ldrv
3210 F92439 86 6F stx tmpldt
3211 F9243B BD 00 40 lda !P0LDT+ldt_fg1,x
3212 F9243E 29 01 and #1
3213 F92440 AA tax
3214 F92441 FDCTST ; check media inside drive
3215 F92441 02 30 cop $30
3216 F92443 03 .DB $03
3217 .MNLIST
3218 F92444 B0 0B bcs ?04 ; media changed or not ready?
3219 F92446 A6 6F ldx tmpldt
3220 F92448 BD 01 40 lda !P0LDT+ldt_fg2,x
3221 F9244B 89 20 bit #$20 ; test bit 5
3222 F9244D D0 25 bne ?08 ; ok, disk already checked
3223 F9244F F0 1C beq ?06 ; must check disk
3224 F92451 5A ?04: phy ; save error code
3225 F92452 DA phx ; save phisycal drive
3226 F92453 A6 6E ldx ldrv ; discard any HCB block for this drive
3227 F92455 20 46 25 jsr hdscdrv
3228 F92458 A6 6E ldx ldrv ; discard any buffer for this drive
3229 F9245A 20 8A 28 jsr bdscdrv
3230 F9245D FA plx ; restore phisycal drive
3231 F9245E 7A ply ; restore fdc error code
3232 F9245F C0 11 cpy #FDC_CHANGE ; check error code
3233 F92461 D0 05 bne ?05 ; disk not ready
3234 F92463 FDCTST ; check again
3235 F92463 02 30 cop $30
3236 F92465 03 .DB $03
3237 .MNLIST
3238 F92466 90 05 bcc ?06 ; ok
3239 F92468 A9 15 ?05: lda #ED_NOTRDY ; disk not ready
3240 F9246A 4C 12 24 jmp oserror
3241 F9246D A5 6E ?06: lda ldrv
3242 F9246F 20 BA 08 jsr bldldt ; build LDT table for this drive
3243 F92472 B0 44 bcs ?40
3244 F92474 A6 6F ?08: ldx tmpldt
Tue Jul 17 11:00:21 2018 Page 12
3245 F92476 A4 6E ldy ldrv
3246 F92478 BD 01 40 ?10: lda !P0LDT+ldt_fg2,x
3247 F9247B 29 A0 and #$A0 ; bit 7&5 will be set
3248 F9247D C9 A0 cmp #$A0
3249 F9247F D0 35 bne ?34 ; invalid format
3250 F92481 C4 52 cpy curdrv ; change drive?
3251 F92483 F0 30 beq ?20 ; no, use current table
3252 F92485 84 52 sty curdrv ; set up curdrv
3253 F92487 9B txy ; LDT pointer
3254 F92488 A2 29 ldx #LDTSIZE-1 ; move LDT table in current page 0
3255 F9248A B9 29 40 ?12: lda !P0LDT+ldt0+LDTSIZE-1,y
3256 F9248D 95 18 sta ldtfg1,x
3257 F9248F 88 dey
3258 F92490 CA dex
3259 F92491 10 F7 bpl ?12
3260 F92493 29 01 and #1
3261 F92495 85 15 sta pdrive
3262 F92497 A8 tay
3263 F92498 24 18 bit ldtfg1
3264 F9249A 70 19 bvs ?20 ; fixed disk
3265 F9249C A9 09 lda #9 ; 9 sec. per track
3266 F9249E A6 33 ldx ldtfmt
3267 F924A0 F0 02 beq ?14
3268 F924A2 A9 12 lda #18 ; 18 sec. per track
3269 F924A4 85 14 ?14: sta fspt
3270 F924A6 ACC16
3271 F924A6 C2 20 rep #PMFLAG
3272 .LONGA on
3273 .MNLIST
3274 F924A8 A9 00 CC lda #dma0s
3275 F924AB BB tyx
3276 F924AC F0 03 beq ?18
3277 F924AE A9 10 CD lda #dma1s
3278 F924B1 85 12 ?18: sta dmabcb
3279 F924B3 ACC08
3280 F924B3 E2 20 sep #PMFLAG
3281 .LONGA off
3282 .MNLIST
3283 F924B5 60 ?20: rts
3284
3285 F924B6 A9 0B ?34: lda #ED_FORMAT
3286 F924B8 4C 12 24 ?40: jmp oserror
3287
3288 ;---------------------------------------------------------------------------
3289 ; HCB helpers
3290 ;---------------------------------------------------------------------------
3291 F924BB
3292 F924BB fndhcb2:
3293 F924BB 8B phb ; save current DBR
3294 F924BC A9 00 lda #^hcb_data
3295 F924BE 48 pha
3296 F924BF AB plb ; set DBR to HCB struct's
3297 F924C0 CPU16
3298 F924C0 C2 30 rep #(PMFLAG.OR.PXFLAG)
3299 .LONGA on
3300 .LONGI on
3301 .MNLIST
Tue Jul 17 11:00:21 2018 Page 13
3302 F924C2 20 C9 24 jsr fndhcb
3303 F924C5 CPU08
3304 F924C5 E2 30 sep #(PMFLAG.OR.PXFLAG)
3305 .LONGA off
3306 .LONGI off
3307 .MNLIST
3308 F924C7 AB plb ; restore DBR
3309 F924C8 60 rts
3310
3311 ; find HCB for given drive,cluster and sequence
3312 ;
3313 ; entry: hcbcls = cluster (=0 if root dir.)
3314 ; hcbseq = sector offset sequence
3315 ; hcbdrv = logical drive
3316 ; DBR = bank that hold HCB struct's
3317 ; CF = 0 if exact match required
3318 ; CF = 1 if we want to recycle oldest HCB
3319 ;
3320 ; exit: CF = 0 if HCB found
3321 ; hcbroot = HCB pointer if found
3322 ; buffer loaded from disk
3323 ; CF = 1 if HCB was not found
3324 ;
3325 ; use: C,X,Y
3326 ;
3327 ; note: this routine should be called with 16 bit cpu mode
3328 ;
3329 ;------
3330 F924C9 fndhcb:
3331 ;------
3332 F924C9 64 68 stz hcbrec ; recycle flag
3333 F924CB 90 02 bcc ?05 ; no recycle
3334 F924CD C6 68 dec hcbrec ; =$FFFF, recycle
3335 F924CF A6 04 ?05: ldx hcbroot ; start from head of list
3336 F924D1 80 07 bra ?15
3337 F924D3 BD 00 00 ?10: lda !hcb_next,x ; onto the next entry
3338 F924D6 F0 15 beq ?20 ; no one there...
3339 F924D8 9B txy ; Y=previous HCB
3340 F924D9 AA tax ; X=current HCB
3341 F924DA BD 04 00 ?15: lda !hcb_seq,x ; sequence+drive
3342 F924DD 30 0E bmi ?20 ; from here start the free list
3343 F924DF C5 62 cmp hcbseq ; does seq+drive match?
3344 F924E1 D0 F0 bne ?10 ; goto next if not
3345 F924E3 BD 02 00 lda !hcb_cls,x
3346 F924E6 C5 6C cmp hcbcls ; does cluster match?
3347 F924E8 D0 E9 bne ?10 ; goto next if not
3348 F924EA 18 clc ; HCB found
3349 F924EB F0 12 beq ?30 ; we have a match: find & load buffer
3350 F924ED 38 ?20: sec ; we have been all along the chain w/no luck
3351 F924EE 24 68 bit hcbrec ; do we want to recycle oldest HCB?
3352 F924F0 10 2C bpl ?40 ; no, so HCB not found & exit with CF=1
3353 F924F2 9E 06 00 stz hcb_cnt,x ; recycle oldest HCB...
3354 F924F5 A5 62 lda hcbseq
3355 F924F7 9D 04 00 sta !hcb_seq,x ; ...so mark as us, but with nothing in it
3356 F924FA A5 6C lda hcbcls
3357 F924FC 9D 02 00 sta !hcb_cls,x
3358 F924FF 08 ?30: php ; save carry
Tue Jul 17 11:00:21 2018 Page 14
3359 F92500 E4 04 cpx hcbroot ; this HCB is the head of list?
3360 F92502 F0 0D beq ?32 ; yes, no need to move ahead
3361 F92504 BD 00 00 lda !hcb_next,x ; get link to the rest of chain
3362 F92507 99 00 00 sta !hcb_next,y ; unlink ourselves from chain
3363 F9250A A5 04 lda hcbroot
3364 F9250C 86 04 stx hcbroot ; move current entry at the head...
3365 F9250E 9D 00 00 sta !hcb_next,x ; ...and relink the rest of the chain
3366 F92511 E4 06 ?32: cpx hcblst ; this HCB was the last one of list?
3367 F92513 D0 02 bne ?35 ; no
3368 F92515 84 06 sty hcblst ; yes...so the previous become the last one
3369 F92517 28 ?35: plp ; restore carry
3370 F92518 90 04 bcc ?40 ; HCB found, not need to fill it
3371 F9251A 20 A6 25 jsr hcbfill ; fill it
3372 F9251D 18 clc
3373 F9251E 60 ?40: rts
3374
3375 .LONGA off ; for assembler
3376 .LONGI off
3377
3378 ; discard HCB for given drive, cluster and sequence
3379 ;
3380 ; entry: C = cluster
3381 ; X = logical drive
3382 ; Y = sequence #
3383 ;
3384 ; out: nothing
3385 ;
3386 ; use: all
3387 ;
3388 ; note:
3389 ;-------
3390 F9251F hdscblk:
3391 ;-------
3392 F9251F ACC16
3393 F9251F C2 20 rep #PMFLAG
3394 .LONGA on
3395 .MNLIST
3396 F92521 85 6C sta hcbcls ; cluster to discard
3397 F92523 86 63 stx hcbdrv ; drive
3398 F92525 84 62 sty hcbseq ; sequence
3399 F92527 A9 FF FF lda #$FFFF
3400 F9252A 85 89 sta bdmask ; drive+sec mask
3401 F9252C 85 8B sta bcmask ; cluster mask
3402 F9252E 80 27 bra hdscrd ; discard
3403
3404 ; discard HCB's for given drive & cluster
3405 ;
3406 ; entry: C = cluster
3407 ; X = logical drive
3408 ;
3409 ; out: nothing
3410 ;
3411 ; use: all
3412 ;
3413 ; note:
3414 ;-------
3415 F92530 hdsccls:
Tue Jul 17 11:00:21 2018 Page 15
3416 ;-------
3417 F92530 ACC16
3418 F92530 C2 20 rep #PMFLAG
3419 .LONGA on
3420 .MNLIST
3421 F92532 85 6C sta hcbcls ; cluster to discard
3422 F92534 86 63 stx hcbdrv ; drive
3423 F92536 A0 00 ldy #0
3424 F92538 84 62 sty hcbseq ; all sector's
3425 F9253A A9 FF FF lda #$FFFF
3426 F9253D 85 8B sta bcmask ; cluster mask
3427 F9253F A9 00 FF lda #$FF00
3428 F92542 85 89 sta bdmask ; drive mask (all sector's)
3429 F92544 80 11 bra hdscrd ; discard
3430
3431 ; discard HCB's for given drive
3432 ;
3433 ; entry: X = logical drive
3434 ;
3435 ; out: nothing
3436 ;
3437 ; use: all
3438 ;
3439 ; note:
3440 ;-------
3441 F92546 hdscdrv:
3442 ;-------
3443 F92546 ACC16
3444 F92546 C2 20 rep #PMFLAG
3445 .LONGA on
3446 .MNLIST
3447 F92548 64 6C stz hcbcls ; all cluster's
3448 F9254A 86 63 stx hcbdrv ; drive
3449 F9254C A0 00 ldy #0
3450 F9254E 84 62 sty hcbseq ; all sector's
3451 F92550 64 8B stz bcmask ; cluster mask (all cluster's)
3452 F92552 A9 00 FF lda #$FF00
3453 F92555 85 89 sta bdmask ; drive mask (all sector's)
3454
3455 ; discard HCB's
3456 F92557 hdscrd:
3457 F92557 8B phb ; save dbr
3458 F92558 A2 04 ldx #HCBBNK ; set working dbr
3459 F9255A DA phx
3460 F9255B AB plb
3461 F9255C CPU16
3462 F9255C C2 30 rep #(PMFLAG.OR.PXFLAG)
3463 .LONGA on
3464 .LONGI on
3465 .MNLIST
3466 F9255E A6 04 ldx hcbroot ; list root
3467 F92560 80 07 bra ?15
3468 F92562 BD 00 00 ?10: lda !hcb_next,x ; next BCB
3469 F92565 F0 3B beq ?30 ; done
3470 F92567 9B txy ; Y=previous BCB
3471 F92568 AA tax ; X=current BCB
3472 F92569 BD 04 00 ?15: lda !hcb_seq,x
Tue Jul 17 11:00:21 2018 Page 16
3473 F9256C 30 34 bmi ?30 ; no more BCB...done
3474 F9256E 25 89 and bdmask ; mask drive+sec
3475 F92570 C5 62 cmp hcbseq ; match?
3476 F92572 D0 EE bne ?10 ; no...go to next BCB
3477 F92574 BD 02 00 lda !hcb_cls,x
3478 F92577 25 8B and bcmask ; mask cluster
3479 F92579 C5 64 cmp bcbcls ; match?
3480 F9257B D0 E5 bne ?10 ; no...go to next BCB
3481 F9257D BD 00 00 lda !hcb_next,x ; get link to the rest of chain
3482 F92580 E4 04 cpx hcbroot ; is the root of the list?
3483 F92582 D0 04 bne ?20 ; no
3484 F92584 85 04 sta hcbroot ; unlink ourselves from chain
3485 F92586 80 03 bra ?25
3486 F92588 99 00 00 ?20: sta !hcb_next,y ; unlink ourselves from chain
3487 F9258B 48 ?25: pha ; next BCB to check
3488 F9258C A9 FF FF lda #$FFFF ; put this BCB in free list
3489 F9258F 9D 04 00 sta !hcb_seq,x
3490 F92592 A5 06 lda hcblst ; the actual last one
3491 F92594 86 06 stx hcblst ; this BCB become the last one
3492 F92596 9E 00 00 stz !hcb_next,x
3493 F92599 AA tax ; link the rest of list to the last one
3494 F9259A A5 06 lda hcblst
3495 F9259C 9D 00 00 sta !hcb_next,x
3496 F9259F FA plx ; next BCB to check
3497 F925A0 D0 C7 bne ?15
3498 F925A2 ?30: CPU08
3499 F925A2 E2 30 sep #(PMFLAG.OR.PXFLAG)
3500 .LONGA off
3501 .LONGI off
3502 .MNLIST
3503 F925A4 AB plb ; restore dbr
3504 F925A5 60 rts
3505
3506 ; fill an HCB with many hashed entries as much is possible
3507 ;
3508 ; entry: hcbroot = HCB pointer
3509 ; hcbcls = cluster (=0 if root dir.)
3510 ; hcbseq = sector offset sequence
3511 ; hcbdrv = logical drive
3512 ; DBR = bank that hold HCB struct's
3513 ;
3514 ; exit: HCB is filled with hashed directory entries
3515 ; hcb_cnt field is negative if no more entries
3516 ;
3517 ; use: C,X,Y
3518 ;
3519 ; note: this routine can be called in any cpu mode (8/16 bit)
3520 ;
3521 ;-------
3522 F925A6 hcbfill:
3523 ;-------
3524 F925A6 08 php
3525 F925A7 CPU08
3526 F925A7 E2 30 sep #(PMFLAG.OR.PXFLAG)
3527 .LONGA off
3528 .LONGI off
3529 .MNLIST
Tue Jul 17 11:00:21 2018 Page 17
3530 F925A9 A5 62 lda hcbseq ; what sequence number?
3531 F925AB F0 08 beq ?10 ; first...start at offset zero
3532 F925AD A6 09 ldx hlog2 ; shift count
3533 F925AF F0 04 beq ?10 ; no shift (HCB can contain 1 sector)
3534 F925B1 0A ?05: asl a
3535 F925B2 CA dex
3536 F925B3 D0 FC bne ?05
3537 F925B5 85 45 ?10: sta secofs
3538 F925B7 A8 tay ; Y=sector's offset
3539 F925B8 A5 7B lda dsiz ; directory size in sector's
3540 F925BA 38 sec
3541 F925BB E5 45 sbc secofs ; how many sector's left to hash...
3542 F925BD C5 08 cmp hsiz ; do we support this many?
3543 F925BF 90 02 bcc ?15
3544 F925C1 A5 08 lda hsiz ; ...else limit it to this many
3545 F925C3 AA ?15: tax ; X=sector's count
3546 F925C4 ACC16
3547 F925C4 C2 20 rep #PMFLAG
3548 .LONGA on
3549 .MNLIST
3550 F925C6 A5 04 lda hcbroot
3551 F925C8 85 6A sta hlast ; starting hash code pointer
3552 F925CA 84 45 ?20: sty secofs ; Y=sector offset
3553 F925CC 86 79 stx seccnt ; X=sector's count
3554 F925CE A5 6C lda hcbcls ; C=cluster
3555 F925D0 A6 63 ldx hcbdrv ; X=drive
3556 F925D2 38 sec ; preread from disk
3557 F925D3 20 83 26 jsr fndbuf ; find & fill sector buffer (can return CF=1)
3558 F925D6 20 10 26 jsr hcbblk ; hash 16 entries (preserve CF)
3559 F925D9 A6 79 ldx seccnt
3560 F925DB CA dex ; how many sector's left?
3561 F925DC F0 23 beq ?40 ; all sector's loaded&hashed
3562 F925DE B0 05 bcs ?30 ; no more entries after this sector...
3563 F925E0 A4 45 ldy secofs
3564 F925E2 C8 iny ; next sector
3565 F925E3 80 E5 bra ?20 ; load&hash next sector
3566 F925E5 ?30: CPU16
3567 F925E5 C2 30 rep #(PMFLAG.OR.PXFLAG)
3568 .LONGA on
3569 .LONGI on
3570 .MNLIST
3571 F925E7 8A txa
3572 F925E8 0A asl a
3573 F925E9 0A asl a
3574 F925EA 0A asl a
3575 F925EB 0A asl a
3576 F925EC A8 tay ; we have this many null entries
3577 F925ED A6 6A ldx hlast ; last hash code ptr
3578 F925EF 9E 08 00 ?35: stz !hcb_data,x ; zap rest of cluster
3579 F925F2 E8 inx
3580 F925F3 E8 inx
3581 F925F4 88 dey
3582 F925F5 D0 F8 bne ?35
3583 F925F7 86 6A stx hlast ; update last ptr
3584 F925F9 A4 04 ldy hcbroot
3585 F925FB 18 clc
3586 F925FC 79 06 00 adc hcb_cnt,y
Tue Jul 17 11:00:21 2018 Page 18
3587 F925FF 80 07 bra ?45 ; no more entries...
3588 F92601 90 0B ?40: bcc ?50 ; more entries...
3589 F92603 A4 04 ldy hcbroot
3590 F92605 B9 06 00 lda hcb_cnt,y
3591 F92608 09 00 80 ?45: ora #$8000 ; negative count: no more entries after...
3592 F9260B 99 06 00 sta hcb_cnt,y
3593 F9260E 28 ?50: plp
3594 F9260F 60 rts
3595
3596 .LONGA off ; for assembler
3597 .LONGI off
3598
3599 ; hash a directory block (16 entries)
3600 ;
3601 ; entry: hcbroot = HCB pointer
3602 ; hlast = start pointer where store hash codes
3603 ; fcbp = long pointer to directory block
3604 ; DBR = bank that hold HCB struct's
3605 ;
3606 ; exit: hlast=pointer to next available free entry
3607 ;
3608 ; use: C,X,Y
3609 ;
3610 ; note: this routine can be called in any cpu mode (8/16 bit)
3611 ;
3612 ;------
3613 F92610 hcbblk:
3614 ;------
3615 F92610 08 php ; save status
3616 F92611 CPU16
3617 F92611 C2 30 rep #(PMFLAG.OR.PXFLAG)
3618 .LONGA on
3619 .LONGI on
3620 .MNLIST
3621 F92613 A2 10 00 ldx #16 ; 16 entries
3622 F92616 DA ?05: phx ; save counter
3623 F92617 64 68 stz thash ; reset hash code
3624 F92619 A7 5E lda [fcbp]
3625 F9261B 29 FF 00 and #$00FF ; mask off 2nd character
3626 F9261E F0 41 beq ?15 ; empty entry so thash=0
3627 F92620 C9 E5 00 cmp #$00E5
3628 F92623 F0 3A beq ?10 ; deleted entry so thash=0
3629 F92625 AA tax ; save first character
3630 F92626 A0 0B 00 ldy #11 ; get attribute
3631 F92629 B7 5E lda [fcbp],y
3632 F9262B 29 3F 00 and #$003F ; long file name entry?
3633 F9262E C9 0F 00 cmp #$000F
3634 F92631 F0 2C beq ?10 ; yes so thash=0
3635 F92633 8A txa
3636 F92634 CPU08
3637 F92634 E2 30 sep #(PMFLAG.OR.PXFLAG)
3638 .LONGA off
3639 .LONGI off
3640 .MNLIST
3641 F92636 29 7F and #$7F
3642 F92638 85 69 sta thash+1 ; initialize hash code MSB
3643 F9263A A2 0A ldx #10 ; involve other 10 characters...
Tue Jul 17 11:00:21 2018 Page 19
3644 F9263C A0 01 ldy #1 ; ...starting from 2nd
3645 F9263E ?08: ACC16
3646 F9263E C2 20 rep #PMFLAG
3647 .LONGA on
3648 .MNLIST
3649 F92640 A5 68 lda thash ; this simulate a 17 bit rotation
3650 F92642 0A asl a ; CF=old A<15>
3651 F92643 69 00 00 adc #$0000 ; A<0>=CF=old A<15>
3652 F92646 85 68 sta thash
3653 F92648 ACC08
3654 F92648 E2 20 sep #PMFLAG
3655 .LONGA off
3656 .MNLIST
3657 F9264A B7 5E lda [fcbp],y ; get next char
3658 F9264C 29 7F and #$7F
3659 F9264E 45 68 eor thash ; xor char into the hash code
3660 F92650 85 68 sta thash
3661 F92652 C8 iny
3662 F92653 CA dex
3663 F92654 D0 E8 bne ?08 ; repeat for all characters
3664 F92656 CPU16CLC
3665 F92656 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
3666 .LONGA on
3667 .LONGI on
3668 .MNLIST
3669 F92658 A5 68 lda thash
3670 F9265A D0 05 bne ?15 ; thash=0 reserved for empty/deleted/lfn entry
3671 F9265C 1A inc a
3672 F9265D 80 02 bra ?15
3673 F9265F A5 68 ?10: lda thash ; here thash=0
3674 F92661 FA ?15: plx ; restore counter
3675 F92662 A4 6A ldy hlast ; Y=hash code data pointer
3676 F92664 99 08 00 sta hcb_data,y
3677 F92667 C8 iny ; bump ptr
3678 F92668 C8 iny
3679 F92669 84 6A sty hlast
3680 F9266B A5 5E lda fcbp ; here always CF=0
3681 F9266D 69 20 00 adc #32 ; bump fcbp pointer
3682 F92670 85 5E sta fcbp
3683 F92672 CA dex
3684 F92673 D0 A1 bne ?05 ; next entry
3685 F92675 18 clc
3686 F92676 A6 04 ldx hcbroot
3687 F92678 BD 06 00 lda !hcb_cnt,x ; update entries count
3688 F9267B 69 10 00 adc #16
3689 F9267E 9D 06 00 sta !hcb_cnt,x
3690 F92681 28 plp ; restore cpu status
3691 F92682 60 rts
3692
3693 .LONGA off ; for assembler
3694 .LONGI off
3695 F92683
3696 ;---------------------------------------------------------------------------
3697 ; disk buffer's handler
3698 ;---------------------------------------------------------------------------
3699
3700 ; find buffer for given drive,cluster§or's offset
Tue Jul 17 11:00:21 2018 Page 20
3701 ;
3702 ; entry: C = cluster (16 bit)
3703 ; X = logical drive
3704 ; Y = sector's offset from cluster start
3705 ; CF = 1 if will preread buffer
3706 ;
3707 ; exit: fcbp=long pointer to sector, x-mem bank set to right value
3708 ; xbuf=transfer buffer number
3709 ; lba&lbah=sector address
3710 ; BCB pointer moved at head of list (bcbroot)
3711 ; buffer loaded from disk sector if caller wished it
3712 ; CF=1 if this sector is the last useful sector of directory
3713 ;
3714 ; use: C,X,Y
3715 ;
3716 ; note: this routine can be called in any cpu mode (8/16 bit)
3717 ; if disk error this routine never return to the caller
3718 ;
3719 ;------
3720 F92683 fndbuf:
3721 ;------
3722 F92683 18 clc ; normal exit carry flag
3723 F92684 08 php ; save cpu status
3724 F92685 CPU08
3725 F92685 E2 30 sep #(PMFLAG.OR.PXFLAG)
3726 .LONGA off
3727 .LONGI off
3728 .MNLIST
3729 F92687 64 76 stz bcbload ; preread flag
3730 F92689 90 02 bcc ?05 ; no preread
3731 F9268B C6 76 dec bcbload ; preread
3732 F9268D 8B ?05: phb ; save current DBR
3733 F9268E 86 66 stx bcbdrv ; logical drive
3734 F92690 84 67 sty bcbsec ; sector's offset
3735 F92692 A2 01 ldx #^bcbstart
3736 F92694 DA phx
3737 F92695 AB plb ; set DBR to BCB struct's
3738 F92696 24 18 bit ldtfg1 ; ata device or floppy?
3739 F92698 CPU16
3740 F92698 C2 30 rep #(PMFLAG.OR.PXFLAG)
3741 .LONGA on
3742 .LONGI on
3743 .MNLIST
3744 F9269A 85 64 sta bcbcls ; cluster #
3745 F9269C 70 03 bvs ?08 ; ata device
3746 F9269E 4C 58 27 jmp ?50 ; floppy disk
3747 F926A1 A6 0A ?08: ldx bcbroot ; start from head of list
3748 F926A3 80 07 bra ?15 ; search BCB
3749 F926A5 BD 00 00 ?10: lda !bcb_next,x ; onto the next entry
3750 F926A8 F0 23 beq ?20 ; no one there...
3751 F926AA 9B txy ; Y=previous BCB
3752 F926AB AA tax ; X=current BCB
3753 F926AC BD 02 00 ?15: lda !bcb_drv,x
3754 F926AF 30 1C bmi ?20 ; from here start the free list
3755 F926B1 C5 66 cmp bcbdrv ; does drive+sector match?
3756 F926B3 D0 F0 bne ?10 ; goto next if not
3757 F926B5 BD 04 00 lda !bcb_cls,x
Tue Jul 17 11:00:21 2018 Page 21
3758 F926B8 C5 64 cmp bcbcls ; does cluster match?
3759 F926BA D0 E9 bne ?10 ; goto next if not
3760 F926BC BD 06 00 lda !bcb_lba,x ; we have a match...
3761 F926BF 85 4A sta lba ; ...so get lba address of sector...
3762 F926C1 BD 08 00 lda !bcb_lbah,x
3763 F926C4 85 4C sta lbah
3764 F926C6 BD 0A 00 lda !bcb_buf,x ; ...and get transfer buffer #
3765 F926C9 85 4E sta xbuf
3766 F926CB 80 52 bra ?30 ; set buffer pointer
3767 F926CD A5 66 ?20: lda bcbdrv ; or is the first one free BCB...
3768 F926CF 9D 02 00 sta !bcb_drv,x ; ...or we recycle the oldest one
3769 F926D2 A5 64 lda bcbcls ; ...and we use it
3770 F926D4 9D 04 00 sta !bcb_cls,x
3771 F926D7 BD 0A 00 lda !bcb_buf,x ; get transfer buffer #
3772 F926DA 85 4E sta xbuf
3773 F926DC DA phx ; save current BCB ptr
3774 F926DD 5A phy ; save previous BCB ptr
3775 F926DE A5 64 lda bcbcls ; ...and compute lba address of sector
3776 F926E0 CPU08
3777 F926E0 E2 30 sep #(PMFLAG.OR.PXFLAG)
3778 .LONGA off
3779 .LONGI off
3780 .MNLIST
3781 F926E2 A6 67 ldx bcbsec ; sector offset within cluster
3782 F926E4 20 2D 29 jsr cls2lba ; get lba of sector
3783 F926E7 18 clc
3784 F926E8 24 76 bit bcbload ; need to preread buffer?
3785 F926EA 10 1A bpl ?25 ; no
3786 F926EC A5 18 lda ldtfg1
3787 F926EE 29 01 and #1
3788 F926F0 48 pha ; phisycal device
3789 F926F1 A5 4C lda lbah ; 24 bit lba only
3790 F926F3 48 pha
3791 F926F4 D4 4A pei (lba) ; lba address
3792 F926F6 A9 01 lda #1
3793 F926F8 48 pha ; read one sec
3794 F926F9 A9 00 lda #0
3795 F926FB 48 pha ; x-mem buffer
3796 F926FC D4 4E pei (xbuf) ; buffer#
3797 F926FE 48 pha ; flag (ignored)
3798 F926FF ATAREAD ; read from ata device
3799 F926FF 02 40 cop $40
3800 F92701 00 .DB $00
3801 .MNLIST
3802 F92702 84 02 sty ioerr ; save i/o error if any
3803 F92704 86 03 stx ioerr2 ; save bit error if any
3804 F92706 ?25: CPU16
3805 F92706 C2 30 rep #(PMFLAG.OR.PXFLAG)
3806 .LONGA on
3807 .LONGI on
3808 .MNLIST
3809 F92708 7A ply ; restore previous BCB
3810 F92709 FA plx ; restore current BCB ptr
3811 F9270A 90 09 bcc ?27 ; no i/o error
3812 F9270C A9 FF FF lda #$FFFF ; invalidate buffer
3813 F9270F 9D 02 00 sta !bcb_drv,x
3814 F92712 4C 5D 28 jmp ?200
Tue Jul 17 11:00:21 2018 Page 22
3815 F92715 A5 4A ?27: lda lba ; save lba address onto current BCB
3816 F92717 9D 06 00 sta !bcb_lba,x
3817 F9271A A5 4C lda lbah
3818 F9271C 9D 08 00 sta !bcb_lbah,x
3819 F9271F BD 0C 00 ?30: lda !bcb_ptr,x ; set buffer pointer
3820 F92722 85 5E sta fcbp
3821 F92724 BD 0E 00 lda !bcb_xbnk,x
3822 F92727 85 60 sta fcbp+2 ; set hi ptr & x-mem bank
3823 F92729 E4 0A cpx bcbroot ; this BCB is at the head of list?
3824 F9272B F0 13 beq ?35 ; yes, not need to move
3825 F9272D BD 00 00 lda !bcb_next,x ; get link to the rest of chain
3826 F92730 99 00 00 sta !bcb_next,y ; unlink ourselves from chain
3827 F92733 A5 0A lda bcbroot
3828 F92735 86 0A stx bcbroot ; move current entry at the head...
3829 F92737 9D 00 00 sta !bcb_next,x ; ...and relink the rest of the chain
3830 F9273A E4 0C cpx bcblst ; this BCB was the last one of list?
3831 F9273C D0 02 bne ?35 ; no
3832 F9273E 84 0C sty bcblst ; yes...so the previous become the last one
3833 F92740 A0 FE 01 ?35: ldy #$01FE ; pointer to last directory entry
3834 F92743 ACC08
3835 F92743 E2 20 sep #PMFLAG
3836 .LONGA off
3837 .MNLIST
3838 F92745 A5 61 lda fcbp+3
3839 F92747 8F 28 FD 00 sta >PIA0+PIAPRA ; set x-mem bank
3840 F9274B AB plb ; restore DBR
3841 F9274C B7 5E lda [fcbp],y ; get first name character
3842 F9274E D0 06 bne ?38 ; not null entry, exit with CF=0
3843 F92750 A3 01 lda $01,s ; no more entry after this sector...
3844 F92752 09 01 ora #PCFLAG ; ...so set CF in saved status
3845 F92754 83 01 sta $01,s
3846 F92756 28 ?38: plp
3847 F92757 60 rts
3848
3849 ?50: ; find dma buffer (C=cluster)
3850
3851 .LONGA off ; remember... here cpu mode 16 bit
3852 .LONGI off
3853
3854 F92758 C9 05 cmp #5 ; root dir, cluser #2,#3 ijn separate list
3855 F9275A B0 03 bcs ?55
3856 F9275C 4C 24 28 jmp ?100
3857 F9275F A6 0E ?55: ldx dmaroot ; start from head of list
3858 F92761 80 07 bra ?65 ; search BCB
3859 F92763 BD 00 00 ?60: lda !bcb_next,x ; onto the next entry
3860 F92766 F0 31 beq ?70 ; no one there...
3861 F92768 9B txy ; Y=previous BCB
3862 F92769 AA tax ; X=current BCB
3863 F9276A BD 02 00 ?65: lda !bcb_drv,x
3864 F9276D 30 2A bmi ?70 ; from here start the free list
3865 F9276F C5 66 cmp bcbdrv ; does drive+sector match?
3866 F92771 D0 F0 bne ?60 ; goto next if not
3867 F92773 BD 04 00 lda !bcb_cls,x
3868 F92776 C5 64 cmp bcbcls ; does cluster match?
3869 F92778 D0 E9 bne ?60 ; goto next if not
3870 F9277A BD 06 00 lda !bcb_lba,x ; we have a match...
3871 F9277D 85 4A sta lba ; ...so get lba address of sector...
Tue Jul 17 11:00:21 2018 Page 23
3872 F9277F ACC08
3873 F9277F E2 20 sep #PMFLAG
3874 .LONGA off
3875 .MNLIST
3876 F92781 BD 08 00 lda !bcb_head,x
3877 F92784 85 4C sta fhead ; ...and head...
3878 F92786 ACC16
3879 F92786 C2 20 rep #PMFLAG
3880 .LONGA on
3881 .MNLIST
3882 F92788 BD 0A 00 lda !bcb_trk,x
3883 F9278B 85 4E sta ftrack ; ...and track & sector
3884 F9278D BD 0C 00 lda !bcb_ptr,x ; set buffer pointer
3885 F92790 85 5E sta fcbp
3886 F92792 BD 0E 00 lda !bcb_dma,x
3887 F92795 85 60 sta fcbp+2 ; set hi ptr & dma buffer
3888 F92797 80 62 bra ?80 ; done
3889 F92799 A5 66 ?70: lda bcbdrv ; or is the first one free BCB...
3890 F9279B 9D 02 00 sta !bcb_drv,x ; ...or we recycle the oldest one
3891 F9279E A5 64 lda bcbcls ; ...and we use it
3892 F927A0 9D 04 00 sta !bcb_cls,x
3893 F927A3 BD 0C 00 lda !bcb_ptr,x ; set buffer pointer
3894 F927A6 85 5E sta fcbp
3895 F927A8 BD 0E 00 lda !bcb_dma,x
3896 F927AB 85 60 sta fcbp+2 ; set hi ptr & dma buffer
3897 F927AD DA phx ; save current BCB ptr
3898 F927AE 5A phy ; save previous BCB ptr
3899 F927AF A5 64 lda bcbcls ; ...and compute lba address of sector
3900 F927B1 CPU08
3901 F927B1 E2 30 sep #(PMFLAG.OR.PXFLAG)
3902 .LONGA off
3903 .LONGI off
3904 .MNLIST
3905 F927B3 A6 67 ldx bcbsec ; sector offset within cluster
3906 F927B5 20 2D 29 jsr cls2lba ; get lba of sector
3907 F927B8 20 5E 29 jsr lba2hts ; get floppy tuplet H,T,S
3908 F927BB 18 clc
3909 F927BC 24 76 bit bcbload ; need to preread buffer?
3910 F927BE 10 1E bpl ?75 ; no
3911 F927C0 A5 18 lda ldtfg1 ; read sector from floppy disk
3912 F927C2 29 01 and #1
3913 F927C4 48 pha ; phisycal device
3914 F927C5 A5 4E lda ftrack
3915 F927C7 A6 4C ldx fhead
3916 F927C9 A4 4F ldy fsec
3917 F927CB 48 pha ; track
3918 F927CC DA phx ; head
3919 F927CD 5A phy ; sector
3920 F927CE A9 01 lda #1 ; read one sector
3921 F927D0 48 pha
3922 F927D1 A5 61 lda dmabuf
3923 F927D3 48 pha ; dma buffer #
3924 F927D4 A5 33 lda ldtfmt
3925 F927D6 48 pha ; format
3926 F927D7 FDCREAD ; fdc read
3927 F927D7 02 31 cop $31
3928 F927D9 00 .DB $00
Tue Jul 17 11:00:21 2018 Page 24
3929 .MNLIST
3930 F927DA 84 02 sty ioerr ; save i/o error if any
3931 F927DC 64 03 stz ioerr2 ; no extended i/o error for fdc
3932 F927DE ?75: CPU16
3933 F927DE C2 30 rep #(PMFLAG.OR.PXFLAG)
3934 .LONGA on
3935 .LONGI on
3936 .MNLIST
3937 F927E0 7A ply ; restore previous BCB
3938 F927E1 FA plx ; restore current BCB ptr
3939 F927E2 90 08 bcc ?77 ; ok, no read errror
3940 F927E4 A9 FF FF lda #$FFFF ; invalidate buffer
3941 F927E7 9D 02 00 sta !bcb_drv,x
3942 F927EA 80 71 bra ?200 ; i/o error
3943 F927EC A5 4A ?77: lda lba ; store lba address onto current BCB
3944 F927EE 9D 06 00 sta !bcb_lba,x
3945 F927F1 A5 4C lda fhead ; store head
3946 F927F3 9D 08 00 sta !bcb_head,x
3947 F927F6 A5 4E lda ftrack ; store track§or
3948 F927F8 9D 0A 00 sta !bcb_trk,x
3949 F927FB E4 0E ?80: cpx dmaroot ; this BCB is at the head of list?
3950 F927FD F0 13 beq ?85 ; yes, not need to move
3951 F927FF BD 00 00 lda !bcb_next,x ; get link to the rest of chain
3952 F92802 99 00 00 sta !bcb_next,y ; unlink ourselves from chain
3953 F92805 A5 0E lda dmaroot
3954 F92807 86 0E stx dmaroot ; move current entry at the head...
3955 F92809 9D 00 00 sta !bcb_next,x ; ...and relink the rest of the chain
3956 F9280C E4 10 cpx dmalst ; this BCB was the last one of list?
3957 F9280E D0 02 bne ?85 ; no
3958 F92810 84 10 sty dmalst ; yes...so the previous become the last one
3959 F92812 A0 FE 01 ?85: ldy #$01FE ; pointer to last directory entry
3960 F92815 ACC08
3961 F92815 E2 20 sep #PMFLAG
3962 .LONGA off
3963 .MNLIST
3964 F92817 AB plb ; restore DBR
3965 F92818 B7 5E lda [fcbp],y ; get first name character
3966 F9281A D0 06 bne ?90 ; not null entry, exit with CF=0
3967 F9281C A3 01 lda $01,s ; no more entry after this sector...
3968 F9281E 09 01 ora #PCFLAG ; ...so set CF in saved status
3969 F92820 83 01 sta $01,s
3970 F92822 28 ?90: plp
3971 F92823 60 rts
3972
3973 ; floppy disk root dir, cluster #2,#3,#4
3974 F92824 A6 12 ?100: ldx dmabcb ; BCB list in systerm track (track 0)
3975 F92826 80 06 bra ?115
3976 F92828 BD 00 00 ?110: lda !bcb_next,x ; onto the next entry
3977 F9282B F0 30 beq ?120 ; no one there...
3978 F9282D AA tax ; X=current BCB
3979 F9282E BD 02 00 ?115: lda !bcb_drv,x
3980 F92831 30 2A bmi ?120 ; from here start the free list
3981 F92833 C5 66 cmp bcbdrv ; does drive+sector match?
3982 F92835 D0 F1 bne ?110 ; goto next if not
3983 F92837 BD 04 00 lda !bcb_cls,x
3984 F9283A C5 64 cmp bcbcls ; does cluster match?
3985 F9283C D0 EA bne ?110 ; goto next if not
Tue Jul 17 11:00:21 2018 Page 25
3986 F9283E BD 06 00 lda !bcb_lba,x ; we have a match...
3987 F92841 85 4A sta lba ; ...so get lba address of sector...
3988 F92843 ACC08
3989 F92843 E2 20 sep #PMFLAG
3990 .LONGA off
3991 .MNLIST
3992 F92845 BD 08 00 lda !bcb_head,x
3993 F92848 85 4C sta fhead ; ...and head...
3994 F9284A ACC16
3995 F9284A C2 20 rep #PMFLAG
3996 .LONGA on
3997 .MNLIST
3998 F9284C BD 0A 00 lda !bcb_trk,x
3999 F9284F 85 4E sta ftrack ; ...and track & sector
4000 F92851 BD 0C 00 lda !bcb_ptr,x ; set buffer pointer
4001 F92854 85 5E sta fcbp
4002 F92856 BD 0E 00 lda !bcb_dma,x
4003 F92859 85 60 sta fcbp+2 ; set hi ptr & dma buffer
4004 F9285B 80 B5 bra ?85 ; done
4005 ?120: ; no BCB...should'nt happen this
4006
4007 ;
4008 F9285D
4009 ?200: ; i/o error
4010 ; load from disk error
4011 F9285D CPU08
4012 F9285D E2 30 sep #(PMFLAG.OR.PXFLAG)
4013 .LONGA off
4014 .LONGI off
4015 .MNLIST
4016 F9285F AB plb ; restore DBR
4017 F92860 28 plp
4018 F92861 38 sec ; error
4019 F92862 60 rts
4020
4021 ; discard buffer for given drive, cluster & sector offset
4022 ;
4023 ; mode: A/M/X/Y 8 bit
4024 ;
4025 ; entry: C = cluster
4026 ; X = logical drive
4027 ; Y = sector offset within cluster
4028 ;
4029 ; out: BCB's list affected
4030 ;
4031 ; use: all
4032 ;
4033 ; note:
4034 ;-------
4035 F92863 bdscsec:
4036 ;-------
4037 F92863 ACC16
4038 F92863 C2 20 rep #PMFLAG
4039 .LONGA on
4040 .MNLIST
4041 F92865 85 64 sta bcbcls ; cluster to discard
4042 F92867 86 66 stx bcbdrv ; drive
Tue Jul 17 11:00:21 2018 Page 26
4043 F92869 84 67 sty bcbsec ; sector
4044 F9286B A9 FF FF lda #$FFFF
4045 F9286E 85 89 sta bdmask ; drive+sec mask
4046 F92870 85 8B sta bcmask ; cluster mask
4047 F92872 80 27 bra bdscrd ; discard
4048
4049 ; discard buffer's of given drive & cluster
4050 ;
4051 ; mode: A/M/X/Y 8 bit
4052 ;
4053 ; entry: C = cluster
4054 ; X = logical drive
4055 ;
4056 ; out: BCB's list affected
4057 ;
4058 ; use: all
4059 ;
4060 ; note:
4061 ;-------
4062 F92874 bdsccls:
4063 ;-------
4064 F92874 ACC16
4065 F92874 C2 20 rep #PMFLAG
4066 .LONGA on
4067 .MNLIST
4068 F92876 85 64 sta bcbcls ; cluster to discard
4069 F92878 86 66 stx bcbdrv ; drive
4070 F9287A A0 00 ldy #0
4071 F9287C 84 67 sty bcbsec ; all sector's
4072 F9287E A9 FF FF lda #$FFFF
4073 F92881 85 8B sta bcmask ; cluster mask
4074 F92883 A9 FF 00 lda #$00FF
4075 F92886 85 89 sta bdmask ; drive mask (all sector's)
4076 F92888 80 11 bra bdscrd ; discard
4077
4078 ; discard buffer's of given drive
4079 ;
4080 ; mode: A/M/X/Y 8 bit
4081 ;
4082 ; entry: X = logical drive
4083 ;
4084 ; out: BCB's list affected
4085 ;
4086 ; use: all
4087 ;
4088 ; note:
4089 ;-------
4090 F9288A bdscdrv:
4091 ;-------
4092 F9288A ACC16
4093 F9288A C2 20 rep #PMFLAG
4094 .LONGA on
4095 .MNLIST
4096 F9288C 64 64 stz bcbcls ; all cluster's
4097 F9288E 86 66 stx bcbdrv ; drive
4098 F92890 A0 00 ldy #0
4099 F92892 84 67 sty bcbsec ; all sector's
Tue Jul 17 11:00:21 2018 Page 27
4100 F92894 64 8B stz bcmask ; cluster mask (all cluster's)
4101 F92896 A9 FF 00 lda #$00FF
4102 F92899 85 89 sta bdmask ; drive mask (all sector's)
4103
4104 ; discard buffer's
4105 F9289B bdscrd:
4106 F9289B A0 00 ldy #0
4107 F9289D E0 02 cpx #ATADRV
4108 F9289F 90 01 bcc ?02
4109 F928A1 88 dey
4110 F928A2 84 6F ?02: sty ldrv+1 ; flag fdc/ata
4111 F928A4 8B phb ; save dbr
4112 F928A5 A2 01 ldx #WKB ; set working dbr
4113 F928A7 DA phx
4114 F928A8 AB plb
4115 F928A9 CPU16
4116 F928A9 C2 30 rep #(PMFLAG.OR.PXFLAG)
4117 .LONGA on
4118 .LONGI on
4119 .MNLIST
4120 F928AB A6 0A ldx bcbroot ; fixed disk list
4121 F928AD A4 0C ldy bcblst
4122 F928AF 24 6E bit ldrv
4123 F928B1 30 04 bmi ?05
4124 F928B3 A6 0E ldx dmaroot ; fd list
4125 F928B5 A4 10 ldy dmalst
4126 F928B7 86 85 ?05: stx troot ; head of list
4127 F928B9 84 87 sty tlst ; end of list
4128 F928BB 80 07 bra ?15
4129 F928BD BD 00 00 ?10: lda !bcb_next,x ; next BCB
4130 F928C0 F0 3B beq ?30 ; done
4131 F928C2 9B txy ; Y=previous BCB
4132 F928C3 AA tax ; X=current BCB
4133 F928C4 BD 02 00 ?15: lda !bcb_drv,x
4134 F928C7 30 34 bmi ?30 ; no more BCB...done
4135 F928C9 25 89 and bdmask ; mask drive+sec
4136 F928CB C5 66 cmp bcbdrv ; match?
4137 F928CD D0 EE bne ?10 ; no...go to next BCB
4138 F928CF BD 04 00 lda !bcb_cls,x
4139 F928D2 25 8B and bcmask ; mask cluster
4140 F928D4 C5 64 cmp bcbcls ; match?
4141 F928D6 D0 E5 bne ?10 ; no...go to next BCB
4142 F928D8 BD 00 00 lda !bcb_next,x ; get link to the rest of chain
4143 F928DB E4 85 cpx troot ; is the root of the list?
4144 F928DD D0 04 bne ?20 ; no
4145 F928DF 85 85 sta troot ; unlink ourselves from chain
4146 F928E1 80 03 bra ?25
4147 F928E3 99 00 00 ?20: sta !bcb_next,y ; unlink ourselves from chain
4148 F928E6 48 ?25: pha ; next BCB to check
4149 F928E7 A9 FF FF lda #$FFFF ; put this BCB in free list
4150 F928EA 9D 02 00 sta !bcb_drv,x
4151 F928ED A5 87 lda tlst ; the actual last one
4152 F928EF 86 87 stx tlst ; this BCB become the last one
4153 F928F1 9E 00 00 stz !bcb_next,x
4154 F928F4 AA tax ; link the rest of list to the last one
4155 F928F5 A5 87 lda tlst
4156 F928F7 9D 00 00 sta !bcb_next,x
Tue Jul 17 11:00:21 2018 Page 28
4157 F928FA FA plx ; next BCB to check
4158 F928FB D0 C7 bne ?15
4159 F928FD A6 85 ?30: ldx troot
4160 F928FF A4 85 ldy troot
4161 F92901 24 6E bit ldrv
4162 F92903 30 20 bmi ?35
4163 F92905 86 0E stx dmaroot ; update fd list
4164 F92907 84 10 sty dmalst
4165 F92909 A5 8B lda bcmask ; discard drive?
4166 F9290B D0 1C bne ?40 ; no
4167 F9290D A2 00 CC ldx #dma0s
4168 F92910 A5 66 lda bcbdrv
4169 F92912 29 FF 00 and #$00FF
4170 F92915 F0 03 beq ?32 ; drive #0
4171 F92917 A2 10 CD ldx #dma1s
4172 F9291A A9 FF FF ?32: lda #$FFFF
4173 F9291D 9D 02 00 sta !bcb_drv,x ; empty list
4174 F92920 9E 00 00 stz !bcb_next,x
4175 F92923 80 04 bra ?40
4176 F92925 86 0A ?35: stx bcbroot ; update fixed disk list
4177 F92927 84 0C sty bcblst
4178 F92929 ?40: CPU08
4179 F92929 E2 30 sep #(PMFLAG.OR.PXFLAG)
4180 .LONGA off
4181 .LONGI off
4182 .MNLIST
4183 F9292B AB plb ; restore dbr
4184 F9292C 60 rts
4185
4186 ;---------------------------------------------------------------------------
4187 ; utilities
4188 ;---------------------------------------------------------------------------
4189
4190 ; compute lba address from a given cluster
4191 ;
4192 ; entry: C = cluster (16 bit) -- if C = 0 return lba of root directory
4193 ; X = sector offset (8 bit)
4194 ;
4195 ; exit: lba and lbah filled with lba address
4196 ;
4197 ; use: C,X,Y
4198 ;
4199 ; note: this routine should be called in 8 bit cpu mode
4200 ;
4201 ;-------
4202 F9292D cls2lba:
4203 ;-------
4204 F9292D 86 68 stx wtmp ; sector's offset...
4205 F9292F 64 69 stz wtmp+1 ;...extended to 16 bit
4206 F92931 A6 29 ldx ldtcshf ; shift count#
4207 F92933 CPU16
4208 F92933 C2 30 rep #(PMFLAG.OR.PXFLAG)
4209 .LONGA on
4210 .LONGI on
4211 .MNLIST
4212 F92935 64 4C stz lbah
4213 F92937 A8 tay ; compute lba for root dir.?
Tue Jul 17 11:00:21 2018 Page 29
4214 F92938 F0 15 beq ?20 ; yes
4215 F9293A 3A dec a ; skip fake cluster#0
4216 F9293B 3A dec a
4217 F9293C 9B txy
4218 F9293D F0 06 beq ?10 ; no shift
4219 F9293F 0A ?05: asl a ; compute lba base
4220 F92940 26 4C rol lbah
4221 F92942 CA dex
4222 F92943 D0 FA bne ?05
4223 F92945 18 ?10: clc
4224 F92946 A4 4C ldy lbah ; Y=lbah
4225 F92948 65 24 adc ldtcls ; add offset of first data sector
4226 F9294A 90 06 bcc ?32
4227 F9294C C8 iny
4228 F9294D 80 02 bra ?30
4229 F9294F A5 1E ?20: lda ldtroot ; lba address of root dir. (here Y=0)
4230 F92951 18 ?30: clc
4231 F92952 65 68 ?32: adc wtmp ; add sector's offset
4232 F92954 85 4A sta lba
4233 F92956 90 01 bcc ?40
4234 F92958 C8 iny ; update lbah
4235 F92959 84 4C ?40: sty lbah
4236 F9295B CPU08
4237 F9295B E2 30 sep #(PMFLAG.OR.PXFLAG)
4238 .LONGA off
4239 .LONGI off
4240 .MNLIST
4241 F9295D 60 rts
4242
4243 .LONGA off ; for assembler
4244 .LONGI off
4245
4246 ; translate lba address into tuplet (H,T,S) for floppy disk operation
4247 ;
4248 ; remind:
4249 ; H = head number (0..1)
4250 ; T = track number (0..79)
4251 ; S = sector number (1..max) where max=9 or 18
4252 ; SPT = sector per tack (18 or 36)
4253 ;
4254 ; LBA = (H + 2*T)*SPT + (S - 1)
4255 ;
4256 ; T = LBA / (2 * SPT)
4257 ; L = LBA MOD (2 * SPT)
4258 ; H = L / P
4259 ; S = (L MOD P) + 1
4260 ;
4261 ; entry: lba = lba address
4262 ; fspt = sector per track
4263 ;
4264 ; exit: fhead, ftrack, fsec
4265 ;
4266 ; use: all
4267 ;
4268 ;-------
4269 F9295E lba2hts:
4270 ;-------
Tue Jul 17 11:00:21 2018 Page 30
4271 F9295E A5 14 lda fspt
4272 F92960 0A asl a ; 2*SPT
4273 F92961 85 83 sta dvsor
4274 F92963 64 84 stz dvsor+1 ; divisor=2*SPT
4275 F92965 A5 4B lda lba+1
4276 F92967 EB xba
4277 F92968 A5 4A lda lba ; C=lba
4278 F9296A 20 81 29 jsr fudiv ; return C=quotient
4279 F9296D 85 4E sta ftrack ; store track, ignore B (should be null)
4280 F9296F A0 00 ldy #0 ; Y=head
4281 F92971 A6 83 ldx dvsor ; remainder (L)
4282 F92973 8A txa
4283 F92974 38 sec
4284 F92975 E5 14 sbc fspt ; get sector & head
4285 F92977 90 02 bcc ?10 ; L < SPT so head=0, sec=L+1
4286 F92979 C8 iny ; head=1
4287 F9297A AA tax ; L >= SPT so head=1, sec=L-SPT+1
4288 F9297B E8 ?10: inx ; X=sector
4289 F9297C 84 4C sty fhead
4290 F9297E 86 4F stx fsec
4291 F92980 60 rts
4292
4293 ; fast unsigned division 16 bit
4294 ;
4295 ; entry: C = 16 bit dividend
4296 ; dvsor = 16 bit divisor
4297 ;
4298 ; exit: C = quot = 16 bit quotient
4299 ; dvsor = 16 bit remainder
4300 ;
4301 ; use: all
4302 ;
4303 ; note: no check for null divisor
4304 ;
4305 ;-----
4306 F92981 fudiv:
4307 ;-----
4308 F92981 A2 01 ldx #1 ; bit counter
4309 F92983 CPU16
4310 F92983 C2 30 rep #(PMFLAG.OR.PXFLAG)
4311 .LONGA on
4312 .LONGI on
4313 .MNLIST
4314 ;ldy lba ; Y=dividend
4315 F92985 A8 tay
4316 F92986 64 81 stz quot ; init quotient
4317 F92988 A5 83 lda dvsor ; C=divisor
4318 F9298A 0A ?10: asl a ; shift divisor: get leftmost bit
4319 F9298B B0 06 bcs ?20 ; go to division
4320 F9298D E8 inx
4321 F9298E E0 11 00 cpx #17 ; test all divisor bit's
4322 F92991 D0 F7 bne ?10
4323 F92993 6A ?20: ror a ; put shifted-out bit back
4324 F92994 85 83 sta dvsor
4325 F92996 98 ?30: tya ; get dividend
4326 F92997 38 sec
4327 F92998 E5 83 sbc dvsor
Tue Jul 17 11:00:21 2018 Page 31
4328 F9299A 90 01 bcc ?40 ; can't subctract, retain old dividend
4329 F9299C A8 tay ; Y=new dividend
4330 F9299D 26 81 ?40: rol quot ; shift carry into quotient (1 if division)
4331 F9299F 46 83 lsr dvsor ; shift right divisor for next subtract
4332 F929A1 CA dex
4333 F929A2 D0 F2 bne ?30
4334 F929A4 84 83 sty dvsor ; store remainder
4335 F929A6 A5 81 lda quot ; C=quotient
4336 F929A8 CPU08
4337 F929A8 E2 30 sep #(PMFLAG.OR.PXFLAG)
4338 .LONGA off
4339 .LONGI off
4340 .MNLIST
4341 F929AA 60 rts
4342
4343 F929AB ftest:
4344 F929AB 0B phd
4345 F929AC F4 00 41 pea #P0FAT
4346 F929AF 2B pld
4347 F929B0 86 14 stx fspt
4348 F929B2 85 4A sta lba
4349 F929B4 EB xba
4350 F929B5 85 4B sta lba+1
4351 F929B7 20 5E 29 jsr lba2hts
4352 F929BA A9 00 lda #0
4353 F929BC EB xba
4354 F929BD A5 4E lda ftrack
4355 F929BF A6 4F ldx fsec
4356 F929C1 A4 4C ldy fhead
4357 F929C3 2B pld
4358 F929C4 00 00 brk
4359 F929C6 00 00 brk
4360 F929C8
4361 ;---------------------------------------------------------------------------
4362 ; tables
4363 ;---------------------------------------------------------------------------
4364
4365 F929C8 3A 2E 3B 2C 3D dlmstr .DB ':.;,=+\<>|/"[]' ; path delimeters
2B 5C 3C 3E 7C
2F 22 5B 5D
4366 00000E DLMSTR .EQU $-dlmstr
4367
4368 F929D6 devlst:
4369 F929D6 43 4F 4E 20 20 .DB 'CON ' ; Keyboard and display
20 20 20
4370 F929DE 4B 45 59 42 44 .DB 'KEYBD$ ' ; Keyboard
24 20 20
4371 F929E6 53 43 52 45 45 .DB 'SCREEN$ ' ; Display
4E 24 20
4372 F929EE 43 4F 4E 53 4F .DB 'CONSOLE$'
4C 45 24
4373 F929F6 50 52 4E 20 20 .DB 'PRN ' ; System list device, usually a parallel port
20 20 20
4374 F929FE 4C 53 54 20 20 .DB 'LST ' ; System list device, usually a parallel port
20 20 20
4375 F92A06 4C 50 54 31 20 .DB 'LPT1 ' ; First parallel printer port
20 20 20
Tue Jul 17 11:00:21 2018 Page 32
4376 F92A0E 4C 50 54 32 20 .DB 'LPT2 ' ; Second parallel printer port
20 20 20
4377 F92A16 4C 50 54 33 20 .DB 'LPT3 ' ; Third parallel printer port
20 20 20
4378 F92A1E 41 55 58 20 20 .DB 'AUX ' ; Auxiliary device, usually a serial port
20 20 20
4379 F92A26 43 4F 4D 31 20 .DB 'COM1 ' ; First serial communications port
20 20 20
4380 F92A2E 43 4F 4D 32 20 .DB 'COM2 ' ; Second serial communications port
20 20 20
4381 F92A36 43 4F 4D 33 20 .DB 'COM3 ' ; Third serial communications port
20 20 20
4382 F92A3E 43 4F 4D 34 20 .DB 'COM4 ' ; Fourth serial communications port
20 20 20
4383 F92A46 4E 55 4C 20 20 .DB 'NUL ' ; Bit-bucket device
20 20 20
4384 F92A4E 24 49 44 4C 45 .DB '$IDLE$ ' ; Bit-bucket device
24 20 20
4385 F92A56 43 4C 4F 43 4B .DB 'CLOCK$ ' ; System real-time clock
24 20 20
4386 F92A5E 43 4C 4F 43 4B .DB 'CLOCK ' ; System real-time clock
20 20 20
4387 F92A66 43 4F 4E 46 49 .DB 'CONFIG$ '
47 24 20
4388 F92A6E 00 .DB 0
Lines Assembled : 4199 Errors : 0