Blame | Last modification | View Log | Download | RSS feed
Tue Jul 17 11:00:16 2018 Page 1
2500 A.D. 65816 Macro Assembler #26960 - Version 5.02g
-----------------------------------------------------
Input Filename : src\F8\fdc.asm
Output Filename : obj\F8\fdc.obj
Listing Has Been Relocated
2591 .LIST on
2592
2593 F8FFB1 .INCLUDE inc\dirp00.inc
2594 ;----------------------------------------------------------
2595 ; DIRP00.ASM
2596 ; PROGETTO: B1601
2597 ;
2598 ; Variabili in Direct Page $00
2599 ;----------------------------------------------------------
2600
2601 ; sezione COMMON -- questo permette di includere il file in piu' file
2602
2603 .LIST on
2604
2605 DIRP00: .SECTION page0, ref_only, common ;Direct-Page 00
2606
2607 000000 .ABSOLUTE ;; inizia sempre da $00
2608 000000 .ORG 0x00
2609 000000
2610 000000 0000 JiffyClk .DW ; contatore 10ms 32 bit
2611 000002 0000 .DW
2612 000004 SysTmr .DS SYSTMRCNT ; system timer 0 (10ms)
2613 000008 SysTMF .DS SYSTMRCNT ; flag timer (80 -> start)
2614 00000C 00 Bnk0Flag .DB ; <7>: flag test RAM banco 0 ok
2615 ; <6>: flag warm reset
2616 00000D 00 RTCFlag .DB
2617
2618 00000E diskstat .DS 2 ; flag device on ata bus #0 & #1
2619 ; <7>: device ready
2620 ; <6>: compact flash device (C.F.)
2621 ; <5>: device identification ok
2622 ; <4>: MBR loaded
2623 ; <3>: valid signature in MBR
2624 ; <2>: first partition found&active
2625 ; <1>:
2626 ; <0>: valid partition flag
2627
2628 ; <7>: device ready
2629 ; <6>: USB device
2630 ; <5>: compact flash device (C.F.)
2631 ; <4>: device identification ok
2632 ; <3>: MBR loaded
2633 ; <2>: first partition found&active
2634 ; <1>: always 1
2635 ; <0>: valid partition flag
2636 000010
Tue Jul 17 11:00:16 2018 Page 2
2637
2638 00000E atadev .EQU diskstat
2639
2640 000010 usbdev .DS 2 ; flag flash disk on usb bus #0
2641 ; <7>: device plugged and ready
2642 ; <6>: always 1
2643 ; <5>: device identification ok
2644 ; <4>: MBR loaded
2645 ; <3>: valid signature in MBR
2646 ; <2>: first partition found&active
2647 ; <1>:
2648 ; <0>: valid partition flag
2649
2650 000012 diskmax .DS 16 ; disk max. sector's
2651 000012 atasec .EQU diskmax
2652 00001A usbsec .EQU diskmax+8
2653
2654
2655 000022 atambr .DS 8 ; data for first partition found in mbr
2656 ; first 3 bytes for start sector of partition
2657 ; last byte for partition type
2658 00002A usbmbr .DS 8
2659
2660 000032 ataprt .DS 8 ; total sec's of first partition
2661 00003A usbprt .DS 8 ; total sec's of first partition
2662
2663
2664 000042 00 usb0ch .DB ; usb0 (ch375/ch376) flag
2665 ; <7>: module on
2666 ; <6>: ch376 flag
2667 ; <5:0>: chip version
2668
2669 000043 00 usb0st .DB ; usb0 status
2670 ; <7>: usb0 host mode ok
2671 ; <6>: flash disk attached flag
2672 ; <5>: usb device attached
2673
2674 000044 00 fdcdrv .DB ; phisycal drive status (drive #0)
2675 ; <7>: disk format established in bit 0&1
2676 ; <6>: double step seek done
2677 ; <5>: trust format bit's (set after ok r/w)
2678 ; <4>: write protect bit (if disk in drive)
2679 ; <3>: don't care
2680 ; <2>: don't care
2681 ; <1>: HD disk if set else DD disk
2682 ; <0>: CBM format if set else IBM format
2683
2684 000045 00 vdrive .DB ; virtual drive status (ram disk, drive #1)
2685 ; <7>: disk format established in bit 0&1
2686 ; <6>: change disk simulation (after format)
2687 ; <5>: don't care
2688 ; <4>: write protect bit (under sw control)
2689 ; <3>: don't care
2690 ; <2>: don't care
2691 ; <1>: HD disk if set else DD disk
2692 ; <0>: CBM format if set else IBM format
2693
Tue Jul 17 11:00:16 2018 Page 3
2694 000046 00 fdcctl .DB ; fdc controller status
2695 ; <7>: drive is attached
2696 ; <6>: drive need recalibration (restore)
2697 ; <5>: FDC controller ok
2698 ; <4>: motor on
2699 ; <3>: dma is active
2700 ; <2>: dma chip ok (post routine)
2701 ; <1>: clock rate (1=HD,0=DD)
2702 ; <0>: disk ready
2703
2704 000047 00 fdctrk .DB ; fd: current seek track
2705 000048 00 fdcerr .DB ; fd: last error code
2706 000049 00 ataerr .DB ; ata: last error code
2707 00004A 00 ataxer .DB ; ata: last extended error code
2708
2709 00004B 00 CtrlBrk .DB ; flag CTRL+BREAK (NMI)
2710
2711 00004C 0000 MemTop .DW ; top memoria RAM
2712 00004E 00 .DB ; banco top mem
2713
2714 00004F 00 DflTxtIn .DB ; device di default text input
2715 000050 00 DflTxtOut .DB ; device di default text output
2716
2717 000051 COPPtr LP ; long pointer for COP decoding
2718 000054 00 COPIdx .DB ; COP signature/index
2719
2720 000055 00 BiosEnt .DB ; flag accesso a bios setup
2721
2722 ; variabili utilizzate da ACIA
2723 000056 spwrk .DS $30
2724
2725 ; bios mem
2726 000086 0000 nsize .DW ; dimensione blocco da allocare
2727 ;bsize .DW ; dimensione vera blocco free
2728 000088 0000 splitsz .DW ; dimensione blocco splittato
2729 00008A 0000 bfree .DW ; puntatore blocco free
2730 00008C 0000 hdrptr .DW ; puntatore header heap
2731
2732 00008E 0000 pbrklv .DW ; current break level of current process
2733 000090 0000 pbrkmin .DW ; minimum breal level of current process
2734 000092 0000 pbrkmax .DW ; maximum breal level of current process
2735 000094
2736 ; bios temp. work area
2737 000094 bwrktmp .DS $28
2738
2739 0000BC 00 coptmp .DB ; temp. used while cop
2740
2741 0000BD 00 tstser .DB ; check ser/usb test board post
2742 ; <7>: VIA2 ok
2743 ; <6>: PICRAM ok
2744 ; <1>: UART 16C550 ok
2745 ; <0>: R65C51 ok
2746
2747
2748 ;crc16 .DW
2749
2750 0000BD .RELATIVE
Tue Jul 17 11:00:16 2018 Page 4
2751
2752 .ENDS
2753
2754 [01] .IFDEF _ACIA_INC_
2755 .INCLUDE INC\SP.INC
2756 [00] .ENDIF
2757
2761 .LIST on
2762
2763 F8FFB1 .INCLUDE inc\BIOSSEG.INC
2764
2765 ;---------------------------------------------------------------------------
2766 ; BIOS Working Segment
2767 ;---------------------------------------------------------------------------
2768
2769 010000 BIOSSEG .EQU $010000
2770 000001 BIOSWKB .EQU .SEG.TOSSEG ; BIOS working bank
2771 010000 _BS .SET BIOSSEG
2772 01FFFF _BE .SET BIOSSEG + $FFFF
2773 ;;TO .SET TOSWKM
2774
2775 _BIOS: .SECTION ref_only, common, offset _BS, range _BS _BE ;BIOS working area
2776 010000 _BIOS_START .DS 0
2777
2778 010000 _vram .DS $0800
2779 010800 _vattr .DS $0800
2780 011000 _vpal .DS $0400
2781 011400 _ioram .DS $0400
2782 011800 _ioram2 .DS $0800
2783
2784 012000 _xram .DS $2000
2785
2786 014000 _dmasave .DS $4800 ; save 36 fdc sec. ($4800)
2787
2788 ;_atamod0 .DS 41 ; model string device ata #0
2789 ;_ataser0 .DS 21 ; serial string device ata #0
2790 ;_atarev0 .DS 9 ; revision string device ata #0
2791
2792 ;_atamod1 .DS 41 ; model string device ata #1
2793 ;_ataser1 .DS 21 ; serial string device ata #1
2794 ;_atarev1 .DS 9 ; revision string device ata #1
2795
2796 ;_usbdsc0 .DS 32 ; identification string device usb #0
2797 ;_usbdsc1 .DS 32 ; identification string device usb #1
2798
2799 018800 _BIOS_END .DS 0
2800 008800 BIOSSIZ .EQU (_BIOS_END - _BIOS_START)
2801 .ENDS
2802
2803 ;DMASEG .EQU $020000
2804 ;DMASWKB .EQU .SEG.DMASEG ; DMA working bank
2805 ;_DS .SET DMASEG
2806 ;_DE .SET DMASEG + $FFFF
2807
2808 ;_DMAS1: .SECTION ref_only, common, offset _DS, range _DS _DE ;DMA segment
2809 ;_clscache .DS $8000
2810 ;.ENDS
Tue Jul 17 11:00:16 2018 Page 5
2811
2812
2813 000002 BUFDSK1 .EQU $02
2814 000003 BUFDSK2 .EQU $03
2815
2816 ; costanti di temporizzazione
2817 000010 T1MS .EQU (4 * PHI2) ; costante 1ms (timer PHI2)
2818 009C40 T10MS .EQU (10 * 1000 * PHI2)
2819 000014 T20MS .EQU 20
2820 0007D0 SNDTMO .EQU 2000 ; 2000ms (timer PB6) - timeout SendTo
2821
2822 0009C4 INTTMO .EQU 2500 ; 2000ms (timer PB6) - timeout INT
2823 0009C4 RESTMO .EQU 2500 ; 2500ms (timer PB6) - timeout res
2824
2825 0003B6 MOTACL .EQU 950 ; ritardo spin-up (ms)
2826 000A28 MOTDCL .EQU 2600 ; ritardo spin-down (ms)
2827
2828 ; GAP 3 read/write
2829 00001B RWGPL3DD .EQU $1B ; GPL3 -> D.D. standard
2830 000010 RWGPL3DDA .EQU $10 ; GPL3 -> D.D. 10 tracce
2831 000036 RWGPL3HD .EQU $36 ; GPL3 -> H.D.
2832 000014 RWGPL3HDA .EQU $14 ; GPL3 -> D.D. 10 tracce
2833
2834 ; GAP 3 format
2835 000054 FMGPL3DD .EQU $54 ; GPL3 -> D.D. standard
2836 000024 FMGPL3DDA .EQU $24 ; GPL3 -> D.D. 10 tracce
2837 00006C FMGPL3HD .EQU $6C ; GPL3 -> H.D.
2838 000032 FMGPL3HDA .EQU $32 ; GPL3 -> H.D.
2839
2840 ; comandi per UM8388
2841 000003 CMDSPECIFY .EQU $03
2842 000004 CMDSENSEST .EQU $04
2843 000007 CMDRECAL .EQU $07
2844 000008 CMDSENSEINT .EQU $08
2845 00000F CMDSEEK .EQU $0F
2846 000045 CMDWRITE .EQU $45
2847 00004A CMDREADID .EQU $4A
2848 00004D CMDFMT .EQU $4D
2849 000066 CMDREAD .EQU $66
2850
2851 0000DF UM_SRTHUT .EQU $DF ; SRT = 3ms, HUT = 240ms
2852 ;UM_SRTHUT .EQU $0F ; SRT = 3ms, HUT = 240ms
2853
2854 000002 UM_HLTND .EQU $02 ; HLT = 2ms, ND = 0 (DMA MODE)
2855 ;UM_HLTND .EQU $FE ; HLT = 2ms, ND = 0 (DMA MODE)
2856
2857 ; costanti per modo DMA (no autoinc, address inc, single mode)
2858 000042 VERFTRASF .EQU $42 ; verfy transfer: read FDC, dummy MEM
2859 000046 WRITETRASF .EQU $46 ; write transfer: read FDC, write MEM
2860 00004A READTRASF .EQU $4A ; read transfer: read MEM, write FDC
2861
2862 000005 maxret .EQU 5 ; retries #
2863
2864 ; page 0 local var's (declared in bios temp. work area)
2865 _P0BTMP: .SECTION page0, ref_only, offset bwrktmp ; DP Tmp. BIOS
2866
2867 000094 FDCTMP_START .EQU $
Tue Jul 17 11:00:16 2018 Page 6
2868
2869 000094 0000 ncnt .DW ; number of bytes for dma
2870 000096 0000 ntrsf .DW ; number of trasferred bytes
2871 000098 0000 ptmp .DW ; temp. pointer used by format
2872 00009A 0000 bufstart .DW ; used by ram disk
2873 00009C 0000 bufend .DW ; used by ram disk
2874 00009E bufp LP ; buffer pointer
2875 0000A1 verfp LP ; verify buffer pointer
2876
2877 000098 xmstart .EQU ptmp ; ram disk start address
2878 00009C dmabuf .EQU bufend ; dma buffer # & needs dma buffers #
2879 00009D bufcnt .EQU bufend+1
2880 00009A drvhead .EQU bufstart
2881 00009B dtlstp .EQU bufstart+1
2882 0000A1 lpfn .EQU verfp ; callback function pointer
2883
2884 0000A4 fdcres .DS 7 ; store phase reult bytes
2885 0000AB 00 drive .DB ; current drive #
2886 0000AC 00 track .DB ; current track
2887 0000AD 00 head .DB ; current side
2888 0000AE 00 sector .DB ; start sector
2889 0000AF 00 sectnum .DB ; sector's number/track
2890 0000B0 00 maxsect .DB ; max. number of sects/track + 1
2891 0000B1 00 eot .DB ; end of track
2892 0000B2 00 gap3 .DB ; gap 3 length
2893 0000B3 00 dmast .DB ; save dma status reg.
2894 0000B4 00 fdop .DB ; fdc function index
2895 0000B5 00 vdop .DB ; ram disk operation
2896 0000B6 00 opfg .DB ; flag param's
2897
2898 0000B6 fmtfg .EQU opfg
2899 0000B2 buftst .EQU gap3 ; used by ram disk
2900
2901 0000B7 00 dskfmt .DB ; disk format
2902 0000B8 00 fmtfill .DB ; fill byte while format
2903 0000B9 00 tmpa .DB
2904 0000BA 00 tmpx .DB
2905 0000BB 00 retries .DB ; retries #
2906
2907 0000BB xmbank .EQU retries ; bank that hold ram disk
2908 0000B9 mcand1 .EQU tmpa ; used by ram disk
2909 0000BA mcand2 .EQU tmpx
2910
2911 000028 FDCTMP_SIZ .EQU ($-FDCTMP_START)
2912
2913 .ENDS
2914
2915 .CODEF8
2916 .GLOBAL fdinit, vdinit
2917 ;.EXTERN LF8Tst, getctime
2918 F8921B
2919 .LONGA off
2920 .LONGI off
2921 F8921B
2922 F8921B .DS 37
2923
2924 ;---------------------------------------------------------------------------
Tue Jul 17 11:00:16 2018 Page 7
2925 ; System interface
2926 ;---------------------------------------------------------------------------
2927
2928 ;---------------------------------------------------------------------------
2929 ; sys_fdrw - read/write/verify sectors in floppy disk
2930 ;
2931 ; prototype: sys_fdrw(bDrive, bTrak, bHead, bSect, bNum, bBuf, bFlag)
2932 ;
2933 ; Params (7 bytes):
2934 ; bDrive = drive number (0..1)
2935 ; bTrak = track number ($00..$4F)
2936 ; bHead = head number ($00..$01)
2937 ; bSect = sector number ($01...)
2938 ; bNum = number of sectors to be read/write ($01...)
2939 ; bBuf = buffer number ($00..$FF)
2940 ; bFlag = flag
2941 ; <7>: verify data after writing
2942 ; <0>: CBM format (otherwise DOS format)
2943 ;
2944 ; Out:
2945 ; CF = 0 if operation completed successfully
2946 ; C = number of bytes effectively transferred
2947 ; X = disk format ($00, $01, $02, $03)
2948 ; Y = unchanged
2949 ; CF = 1 if error
2950 ; C = number of bytes effectively transferred
2951 ; X = disk format ($00, $01, $02, $03, $FF)
2952 ; Y = error code
2953 ; Status register always preserved except carry
2954
2955 ; params offset
2956 000013 bFlag .SET STKPRMS
2957 000014 bBuf .SET STKPRMS + 1
2958 000015 bNum .SET STKPRMS + 2
2959 000016 bSect .SET STKPRMS + 3
2960 000017 bHead .SET STKPRMS + 4
2961 000018 bTrak .SET STKPRMS + 5
2962 000019 bDrive .SET STKPRMS + 6
2963
2964 F89240 sys_fdrw:
2965 .GLOBAL sys_fdrw
2966
2967 F89240 ACC16 ; retrieve function number
2968 F89240 C2 20 rep #PMFLAG
2969 .LONGA on
2970 .MNLIST
2971 F89242 A3 10 lda STKPCL,s ; pointer to byte after signature
2972 F89244 85 51 sta COPPtr
2973 F89246 1A inc a ; update return address
2974 F89247 83 10 sta STKPCL,s
2975 F89249 64 96 stz ntrsf ; clear bytes transferred
2976 F8924B ACC08 ; A,M -> 8 bit
2977 F8924B E2 20 sep #PMFLAG
2978 .LONGA off
2979 .MNLIST
2980 F8924D 64 48 stz fdcerr
2981 F8924F 64 B3 stz dmast
Tue Jul 17 11:00:16 2018 Page 8
2982 F89251 A9 FF lda #$FF ; invalid format
2983 F89253 85 B7 sta dskfmt
2984 F89255 A3 12 lda STKPBR,s ; bank where was executed cop instruction
2985 F89257 85 53 sta COPPtr+2
2986 F89259 A7 51 lda [COPPtr] ; byte after signature
2987 F8925B C9 03 cmp #$03 ; right value: 0,1,2
2988 F8925D B0 50 bcs ?12 ; error
2989 F8925F 85 B4 sta fdop
2990 F89261 A3 19 lda bDrive,s ; drive number
2991 F89263 AA tax
2992 F89264 E0 02 cpx #FDMAXDRIVE
2993 F89266 B0 4B bcs ?14 ; error
2994 F89268 85 AB sta drive
2995 F8926A A3 18 lda bTrak,s ; track number
2996 F8926C C9 50 cmp #$50 ; max track number $4F
2997 F8926E B0 47 bcs ?16 ; error
2998 F89270 85 AC sta track
2999 F89272 A3 17 lda bHead,s ; head number
3000 F89274 C9 02 cmp #$02
3001 F89276 B0 3F bcs ?16
3002 F89278 85 AD sta head
3003 F8927A 38 sec
3004 F8927B A3 16 lda bSect,s ; starting sector
3005 F8927D F0 38 beq ?16
3006 F8927F 85 AE sta sector
3007 F89281 A3 15 lda bNum,s ; number of sector
3008 F89283 F0 32 beq ?16
3009 F89285 85 AF sta sectnum
3010 F89287 A3 14 lda bBuf,s ; buffer number
3011 F89289 85 9C sta dmabuf
3012 F8928B A3 13 lda bFlag,s ; flag
3013 F8928D 29 81 and #$81 ; mask bit 7 and bit 0
3014 F8928F 85 B6 sta opfg
3015 F89291 8A txa ; phisycal drive?
3016 F89292 F0 11 beq ?08 ; yes
3017 F89294 A5 45 lda vdrive ; ram disk formatted?
3018 F89296 10 13 bpl ?10 ; no
3019 F89298 29 03 and #$03
3020 F8929A C9 03 cmp #$03 ; format $03?
3021 F8929C F0 0D beq ?10 ; yes, invalid format
3022 F8929E 85 B7 sta dskfmt ; current ram disk format
3023 F892A0 20 99 9E jsr vdrw ; ram disk operation
3024 F892A3 80 1C bra ?24
3025 F892A5 24 46 ?08: bit fdcctl ; drive attached?
3026 F892A7 30 15 bmi ?22 ; yes
3027 F892A9 80 08 bra ?14
3028 F892AB A9 0D ?10: lda #FDC_BADFMT
3029 F892AD 80 0A bra ?20
3030 F892AF A9 15 ?12: lda #FDC_BADOP
3031 F892B1 80 06 bra ?20
3032 F892B3 A9 0E ?14: lda #FDC_NODRIVE ; invalid drive
3033 F892B5 80 02 bra ?20
3034 F892B7 A9 14 ?16: lda #FDC_PARAMS
3035 F892B9 85 48 ?20: sta fdcerr
3036 F892BB 38 sec
3037 F892BC 80 03 bra ?24
3038 F892BE 20 E1 94 ?22: jsr fdrw ; fd operation
Tue Jul 17 11:00:16 2018 Page 9
3039 F892C1 ?24: ACC16 ; report out data
3040 F892C1 C2 20 rep #PMFLAG
3041 .LONGA on
3042 .MNLIST
3043 F892C3 A5 96 lda ntrsf
3044 F892C5 83 0D sta STKCR,s
3045 F892C7 ACC08
3046 F892C7 E2 20 sep #PMFLAG
3047 .LONGA off
3048 .MNLIST
3049 F892C9 A5 B7 lda dskfmt
3050 F892CB 83 0B sta STKXR,s
3051 F892CD A9 00 lda #0
3052 F892CF 83 0C sta STKXR+1,s
3053 F892D1 A5 48 lda fdcerr ; error code if CF=1
3054 F892D3 6B rtl
3055 F892D4
3056 ;---------------------------------------------------------------------------
3057 ; sys_fdtrack - read/write/verify whole track (both side) on floppy disk
3058 ;
3059 ; prototype: sys_fdtrack(bDrive, bTrak, bBuf, bFlag)
3060 ;
3061 ; Params (4 bytes):
3062 ; bDrive = drive number
3063 ; bTrak = track number ($00..$4F)
3064 ; bBuf = buffer number ($00..$FF)
3065 ; bFlag = flag
3066 ; <7>: verify data after writing
3067 ; <0>: CBM format (otherwise DOS format)
3068 ;
3069 ; Out:
3070 ; CF = 0 if operation completed successfully
3071 ; C = number of bytes effectively transferred
3072 ; X = disk format ($00, $01, $02, $03)
3073 ; Y = unchanged
3074 ; CF = 1 if error
3075 ; C = number of bytes effectively transferred
3076 ; X = disk format ($00, $01, $02, $03, $FF)
3077 ; Y = error code
3078 ; Status register always preserved except carry
3079
3080 ; params offset
3081 000013 bFlag .SET STKPRMS
3082 000014 bBuf .SET STKPRMS + 1
3083 000015 bTrak .SET STKPRMS + 2
3084 000016 bDrive .SET STKPRMS + 3
3085
3086 F892D4 sys_fdtrack:
3087 .GLOBAL sys_fdtrack
3088
3089 F892D4 ACC16 ; retrieve function number
3090 F892D4 C2 20 rep #PMFLAG
3091 .LONGA on
3092 .MNLIST
3093 F892D6 A3 10 lda STKPCL,s ; pointer to byte after signature
3094 F892D8 85 51 sta COPPtr
3095 F892DA 1A inc a ; update return address
Tue Jul 17 11:00:16 2018 Page 10
3096 F892DB 83 10 sta STKPCL,s
3097 F892DD 64 96 stz ntrsf ; clear bytes transferred
3098 F892DF ACC08 ; A,M -> 8 bit
3099 F892DF E2 20 sep #PMFLAG
3100 .LONGA off
3101 .MNLIST
3102 F892E1 64 48 stz fdcerr
3103 F892E3 64 B3 stz dmast
3104 F892E5 A9 FF lda #$FF
3105 F892E7 85 B7 sta dskfmt
3106 F892E9 A3 12 lda STKPBR,s ; bank where was executed cop instruction
3107 F892EB 85 53 sta COPPtr+2
3108 F892ED A7 51 lda [COPPtr] ; byte after signature
3109 F892EF C9 03 cmp #$03 ; right value: 0,1,2
3110 F892F1 B0 43 bcs ?12 ; error
3111 F892F3 85 B4 sta fdop
3112 F892F5 A3 16 lda bDrive,s ; drive number
3113 F892F7 AA tax
3114 F892F8 E0 02 cpx #FDMAXDRIVE
3115 F892FA B0 3E bcs ?14 ; error
3116 F892FC 85 AB sta drive
3117 F892FE A3 15 lda bTrak,s ; track number
3118 F89300 C9 50 cmp #$50 ; max track number $4F
3119 F89302 B0 3A bcs ?16 ; error
3120 F89304 85 AC sta track
3121 F89306 64 AD stz head
3122 F89308 A9 01 lda #1
3123 F8930A 85 AE sta sector
3124 F8930C A3 14 lda bBuf,s ; buffer number
3125 F8930E 85 9C sta dmabuf
3126 F89310 A3 13 lda bFlag,s ; flag
3127 F89312 29 81 and #$81 ; mask bit 7 and bit 0
3128 F89314 09 40 ora #$40 ; flag MT
3129 F89316 85 B6 sta opfg
3130 F89318 8A txa ; phisycal drive?
3131 F89319 F0 11 beq ?08 ; yes
3132 F8931B A5 45 lda vdrive ; ram disk formatted?
3133 F8931D 10 13 bpl ?10 ; no
3134 F8931F 29 03 and #$03
3135 F89321 C9 03 cmp #$03 ; format $03?
3136 F89323 F0 0D beq ?10 ; yes, invalid format
3137 F89325 85 B7 sta dskfmt ; current ram disk format
3138 F89327 20 99 9E jsr vdrw ; ram disk operation
3139 F8932A 80 1C bra ?24
3140 F8932C 24 46 ?08: bit fdcctl ; drive attached?
3141 F8932E 30 15 bmi ?22 ; yes
3142 F89330 80 08 bra ?14
3143 F89332 A9 0D ?10: lda #FDC_BADFMT
3144 F89334 80 0A bra ?20
3145 F89336 A9 15 ?12: lda #FDC_BADOP
3146 F89338 80 06 bra ?20
3147 F8933A A9 0E ?14: lda #FDC_NODRIVE
3148 F8933C 80 02 bra ?20
3149 F8933E A9 14 ?16: lda #FDC_PARAMS
3150 F89340 85 48 ?20: sta fdcerr
3151 F89342 38 sec
3152 F89343 80 03 bra ?24
Tue Jul 17 11:00:16 2018 Page 11
3153 F89345 20 E1 94 ?22: jsr fdrw ; fd drive operation
3154 F89348 ?24: ACC16 ; report out data
3155 F89348 C2 20 rep #PMFLAG
3156 .LONGA on
3157 .MNLIST
3158 F8934A A5 96 lda ntrsf
3159 F8934C 83 0D sta STKCR,s
3160 F8934E ACC08
3161 F8934E E2 20 sep #PMFLAG
3162 .LONGA off
3163 .MNLIST
3164 F89350 A5 B7 lda dskfmt
3165 F89352 83 0B sta STKXR,s
3166 F89354 A9 00 lda #0
3167 F89356 83 0C sta STKXR+1,s
3168 F89358 A5 48 lda fdcerr ; error code if CF=1
3169 F8935A 6B rtl
3170
3171 ;---------------------------------------------------------------------------
3172 ; sys_fdfmt - low level format whole floppy disk
3173 ;
3174 ; prototype: sys_fdfmt(bDrive, bFlag, bFill, lpCall)
3175 ;
3176 ; Params (6 bytes):
3177 ; bDrive = drive number
3178 ; bFlag = format flag
3179 ; <7>: valid callback function in lpCall
3180 ; <6>: verify track after format one
3181 ; <1>: select H.D. format (otherwise D.D. format)
3182 ; <0>: select CBM format (otherwise standard DOS format)
3183 ; bFill = fill byte for all sectors
3184 ; lpCall = long pointer to callback user function while formatting
3185 ;
3186 ; Out:
3187 ; CF = 0 if operation completed successfully
3188 ; A,X,Y preserved
3189 ; CF = 1 if error
3190 ; A, X preserved
3191 ; Y = error code
3192 ; Status register always preserved except carry
3193
3194 ; params offset
3195 000013 lpCall .SET STKPRMS
3196 000016 bFill .SET STKPRMS + 3
3197 000017 bFlag .SET STKPRMS + 4
3198 000018 bDrive .SET STKPRMS + 5
3199
3200 F8935B sys_fdfmt:
3201 .GLOBAL sys_fdfmt
3202
3203 F8935B A3 18 lda bDrive,s ; recover params from stack
3204 F8935D 85 AB sta drive ; drive number
3205 F8935F A8 tay
3206 F89360 A3 17 lda bFlag,s
3207 F89362 85 B6 sta fmtfg ; format flag
3208 F89364 AA tax
3209 F89365 29 03 and #00000011B
Tue Jul 17 11:00:16 2018 Page 12
3210 F89367 85 B7 sta dskfmt ; required format
3211 F89369 C9 03 cmp #00000011B ; format 3 is invalid
3212 F8936B D0 05 bne ?01
3213 F8936D A9 0D lda #FDC_BADFMT
3214 F8936F 38 sec
3215 F89370 80 45 bra ?05 ; error
3216 F89372 A3 16 ?01: lda bFill,s
3217 F89374 85 B8 sta fmtfill ; fill byte
3218 F89376 8A txa
3219 F89377 10 14 bpl ?04 ; no callback
3220 F89379 A3 15 lda lpCall+2,s ; bank that hold callback function
3221 F8937B 85 A3 sta lpfn+2
3222 F8937D D0 06 bne ?02 ; callback function cannot stay in bank $00
3223 F8937F A9 80 lda #$80 ; invalid callback
3224 F89381 14 B6 trb fmtfg ; no callback
3225 F89383 80 08 bra ?04
3226 F89385 ?02: CPU16
3227 F89385 C2 30 rep #(PMFLAG.OR.PXFLAG)
3228 .LONGA on
3229 .LONGI on
3230 .MNLIST
3231 F89387 A3 13 lda lpCall,s ; address of callback function
3232 F89389 85 A1 sta lpfn
3233 F8938B CPU08
3234 F8938B E2 30 sep #(PMFLAG.OR.PXFLAG)
3235 .LONGA off
3236 .LONGI off
3237 .MNLIST
3238 F8938D A9 00 ?04: lda #0
3239 F8938F AA tax
3240 F89390 85 48 sta fdcerr ; clear error
3241 F89392 85 AC sta track
3242 F89394 85 AD sta head
3243 F89396 85 9E sta bufp ; set dma buffer at $030000
3244 F89398 85 9F sta bufp+1
3245 F8939A 1A inc a
3246 F8939B 85 AE sta sector ; sector = 1
3247 F8939D 1A inc a
3248 F8939E 1A inc a
3249 F8939F 85 A0 sta bufp+2
3250 F893A1 CA dex
3251 F893A2 86 9B stx dtlstp ; DTL/STP = $FF
3252 F893A4 A6 B7 ldx dskfmt
3253 F893A6 BF A1 A0 F8 lda >MAXSECT,x
3254 F893AA 85 B0 sta maxsect ; max. numbers of sectors/track + 1
3255 F893AC 3A dec a
3256 F893AD 85 AF sta sectnum ; sectors/track
3257 F893AF 85 B1 sta eot ; end of track
3258 F893B1 C0 02 cpy #FDMAXDRIVE
3259 F893B3 90 05 bcc ?06
3260 F893B5 A9 0E lda #FDC_NODRIVE
3261 F893B7 85 48 ?05: sta fdcerr
3262 F893B9 6B rtl
3263 F893BA BB ?06: tyx ; phisycal drive?
3264 F893BB F0 05 beq ?08 ; yes
3265 F893BD 20 F1 9D jsr vdfmt ; ram disk formattation
3266 F893C0 80 03 bra ?10
Tue Jul 17 11:00:16 2018 Page 13
3267 F893C2 20 7E 95 ?08: jsr fdfmt ; format floppy disk
3268 F893C5 A5 48 ?10: lda fdcerr ; report error if one
3269 F893C7 6B rtl
3270
3271 ;---------------------------------------------------------------------------
3272 ; sys_fdverf - verify integrity of low level format of whole floppy disk
3273 ;
3274 ; prototype: sys_fdverf(bDrive, lpCall)
3275 ;
3276 ; Params (4 bytes):
3277 ; bDrive = drive number
3278 ; lpCall = long pointer to callback user function while verify
3279 ; if lpCall = null the callback function is not called
3280 ; callback function ignored for ram disk
3281 ;
3282 ; Out:
3283 ; CF = 0 if operation completed successfully
3284 ; A,X preserved
3285 ; Y = disk format
3286 ; CF = 1 if error
3287 ; A, X preserved
3288 ; Y = error code
3289 ; Status register always preserved except carry
3290
3291 ; params offset
3292 000013 lpCall .SET STKPRMS
3293 000016 bDrive .SET STKPRMS + 3
3294
3295 F893C8 sys_fdverf:
3296 .GLOBAL sys_fdverf
3297
3298 F893C8 64 B6 stz fmtfg ; no callback
3299 F893CA 64 48 stz fdcerr
3300 F893CC A3 16 lda bDrive,s ; recover params from stack
3301 F893CE 85 AB sta drive ; drive number
3302 F893D0 A8 tay
3303 F893D1 A3 15 lda lpCall+2,s ; bank that hold callback function
3304 F893D3 85 A3 sta lpfn+2
3305 F893D5 F0 0C beq ?02 ; callback function cannot stay in bank $00
3306 F893D7 CPU16
3307 F893D7 C2 30 rep #(PMFLAG.OR.PXFLAG)
3308 .LONGA on
3309 .LONGI on
3310 .MNLIST
3311 F893D9 A3 13 lda lpCall,s ; address of callback function
3312 F893DB 85 A1 sta lpfn
3313 F893DD CPU08
3314 F893DD E2 30 sep #(PMFLAG.OR.PXFLAG)
3315 .LONGA off
3316 .LONGI off
3317 .MNLIST
3318 F893DF A9 80 lda #$80 ; call callback function
3319 F893E1 04 B6 tsb fmtfg
3320 F893E3 C0 02 ?02: cpy #FDMAXDRIVE
3321 F893E5 90 05 bcc ?06
3322 F893E7 A9 0E lda #FDC_NODRIVE ; error
3323 F893E9 85 48 ?04: sta fdcerr
Tue Jul 17 11:00:16 2018 Page 14
3324 F893EB 6B rtl
3325 F893EC BB ?06: tyx ; phisycal drive?
3326 F893ED F0 0E beq ?10 ; yes
3327 F893EF A5 45 lda vdrive ; ram disk formatted?
3328 F893F1 30 05 bmi ?08 ; yes
3329 F893F3 A9 0D lda #FDC_BADFMT
3330 F893F5 38 sec
3331 F893F6 80 F1 bra ?04
3332 F893F8 29 0B ?08: and #00000011
3333 F893FA 18 clc
3334 F893FB 80 07 bra ?12
3335 F893FD 20 67 96 ?10: jsr fdverf ; verify floppy disk format
3336 F89400 B0 08 bcs ?14
3337 F89402 A5 B7 lda dskfmt ; get format
3338 F89404 83 09 ?12: sta STKYR,s
3339 F89406 A9 00 lda #0
3340 F89408 83 0A sta STKYR+1,s
3341 F8940A A5 48 ?14: lda fdcerr ; report error if one
3342 F8940C 6B rtl
3343
3344 ;---------------------------------------------------------------------------
3345 ; sys_fdctl - control function
3346 ;
3347 ; prototype: sys_fdctl(X=drive number if required)
3348 ;
3349 ; Functions:
3350 ; $00: reset FDC controller
3351 ; input reg.: none
3352 ; output reg.: unchanged
3353 ; $01: POST routine (init FDC controller)
3354 ; input reg.: none
3355 ; output reg.: unchanged
3356 ; $02: get drive status
3357 ; input reg.: X = drive number
3358 ; output reg.: Y = drive status (ST3), A,X unchanged
3359 ; output reg.: A,X,Y unchanged
3360 ; $03: check if disk inserted into drive
3361 ; input reg.: X = drive number
3362 ; output reg.: unchanged
3363 ; $04: get format diskette if inserted into drive
3364 ; input reg.: X = drive number
3365 ; output reg.: Y = diskette format, A,X unchanged
3366 ; $05: set write protect bit on ram disk (no effect for phis. drive)
3367 ; input reg.: X = drive number
3368 ; output reg.: unchanged
3369 ; $06: reset write protect bit on ram disk (no effect for phis. drive)
3370 ; input reg.: X = drive number
3371 ; output reg.: unchanged
3372 ; Out:
3373 ; CF = 0 if operation completed successfully
3374 ; CF = 1 if error
3375 ; A, X preserved
3376 ; Y = error code
3377 ; Status register always preserved except carry
3378 F8940D sys_fdctl:
3379 .GLOBAL sys_fdctl
3380
Tue Jul 17 11:00:16 2018 Page 15
3381 F8940D ACC16 ; retrieve function number
3382 F8940D C2 20 rep #PMFLAG
3383 .LONGA on
3384 .MNLIST
3385 F8940F A3 10 lda STKPCL,s ; pointer to byte after signature
3386 F89411 85 51 sta COPPtr
3387 F89413 1A inc a ; update return address
3388 F89414 83 10 sta STKPCL,s
3389 F89416 ACC08 ; A,M -> 8 bit
3390 F89416 E2 20 sep #PMFLAG
3391 .LONGA off
3392 .MNLIST
3393 F89418 A3 12 lda STKPBR,s ; bank where was executed cop instruction
3394 F8941A 85 53 sta COPPtr+2
3395 F8941C A3 0B lda STKXR,s
3396 F8941E 85 AB sta drive ; get drive # (X reg.)
3397 F89420 A7 51 lda [COPPtr] ; byte after signature
3398 F89422 C9 07 cmp #MXCTLFN
3399 F89424 90 05 bcc ?04
3400 F89426 A9 15 lda #FDC_BADOP
3401 F89428 85 48 sta fdcerr
3402 F8942A 60 rts
3403 F8942B 64 48 ?04: stz fdcerr
3404 F8942D 0A asl a
3405 F8942E AA tax ; function index
3406 F8942F FC 93 A0 jsr (CTLFN,x)
3407 F89432 A5 48 lda fdcerr ; return error code if any
3408 F89434 6B rtl
3409
3410 ; ctl function 0: reset controller
3411 F89435 ctl_fn0:
3412 F89435 20 3A 9B jsr fdcrst
3413 F89438 85 48 sta fdcerr
3414 F8943A 60 rts
3415
3416 ; ctl function 1: POST routine (init)
3417 F8943B ctl_fn1:
3418 F8943B 4C B6 9F jmp fdinit
3419
3420 ; ctl function 2: get drive status
3421 F8943E ctl_fn2:
3422 F8943E 20 C9 94 jsr ctl_tst ; check drive #
3423 F89441 AA tax ; phisycal drive?
3424 F89442 F0 10 beq ?10 ; yes
3425 F89444 A5 45 lda vdrive ; bit 4: wp on bit
3426 F89446 0A asl a
3427 F89447 0A asl a ; shift to bit 6
3428 F89448 29 40 and #01000000B
3429 F8944A 09 20 ora #00100000B ; ready bit
3430 F8944C 18 clc
3431 F8944D 83 0B ?05: sta STKYR+2,s ; report status
3432 F8944F A9 00 lda #0
3433 F89451 83 0C sta STKYR+3,s
3434 F89453 60 rts
3435 F89454 20 D6 94 ?10: jsr ctl_dr ; check drive attached
3436 F89457 20 2E 99 jsr drvst
3437 F8945A 90 F1 bcc ?05
Tue Jul 17 11:00:16 2018 Page 16
3438 F8945C 60 rts
3439 F8945D
3440 ; ctl function 3: check disk ready
3441 F8945D ctl_fn3:
3442 F8945D 20 C9 94 jsr ctl_tst ; check drive #
3443 F89460 AA tax ; phisycal drive?
3444 F89461 F0 0F beq ?10 ; yes
3445 F89463 24 45 bit vdrive ; test bit 6: change disk bit
3446 F89465 18 clc
3447 F89466 50 09 bvc ?05 ; disk not changed
3448 F89468 A9 40 lda #$40
3449 F8946A 14 45 trb vdrive ; reset change disk bit
3450 F8946C A9 11 lda #FDC_CHANGE
3451 F8946E 85 48 sta fdcerr
3452 F89470 38 sec
3453 F89471 60 ?05: rts
3454 F89472 20 D6 94 ?10: jsr ctl_dr ; check drive attached
3455 F89475 20 D7 98 jsr chkdsk ; change disk line test
3456 F89478 4C 77 95 jmp stop
3457
3458 ; ctl function 4: get disk format
3459 F8947B ctl_fn4:
3460 F8947B 20 C9 94 jsr ctl_tst ; check drive #
3461 F8947E AA tax ; phisycal drive?
3462 F8947F F0 14 beq ?10 ; yes
3463 F89481 A5 45 lda vdrive ; test bit 7: ram disk formatted?
3464 F89483 30 06 bmi ?02 ; yes
3465 F89485 A9 0D lda #FDC_BADFMT
3466 F89487 85 48 sta fdcerr
3467 F89489 38 sec
3468 F8948A 60 rts
3469 F8948B 29 03 ?02: and #00000011B ; report current format
3470 F8948D 83 0B sta STKYR+2,s
3471 F8948F A9 00 lda #0
3472 F89491 83 0C sta STKYR+3,s
3473 F89493 18 clc
3474 F89494 60 rts
3475 F89495 64 44 ?10: stz fdcdrv ; get disk format - invalidate current format
3476 F89497 20 3F 98 jsr chkfmt ; try to check format
3477 F8949A B0 12 bcs ?20 ; error
3478 F8949C A5 44 lda fdcdrv ; update format
3479 F8949E 29 7C and #01111100B
3480 F894A0 05 B7 ora dskfmt
3481 F894A2 09 80 ora #$80 ; recognized format
3482 F894A4 85 44 sta fdcdrv
3483 F894A6 A5 B7 lda dskfmt ; report format in Y reg.
3484 F894A8 83 0B sta STKYR+2,s
3485 F894AA A9 00 lda #0
3486 F894AC 83 0C sta STKYR+3,s
3487 F894AE 4C 77 95 ?20: jmp stop
3488
3489 ; ctl function 5: set write protect bit on ram disk
3490 F894B1 ctl_fn5:
3491 F894B1 20 C9 94 jsr ctl_tst ; check drive #
3492 F894B4 AA tax ; phisycal drive?
3493 F894B5 F0 04 beq ?10 ; yes, done
3494 F894B7 A9 10 lda #$10 ; set bit 4
Tue Jul 17 11:00:16 2018 Page 17
3495 F894B9 04 45 tsb vdrive
3496 F894BB 18 ?10: clc
3497 F894BC 60 rts
3498
3499 ; ctl function 6: reset write protect bit on ram disk
3500 F894BD ctl_fn6:
3501 F894BD 20 C9 94 jsr ctl_tst ; check drive #
3502 F894C0 AA tax ; phisycal drive?
3503 F894C1 F0 04 beq ?10 ; yes, done
3504 F894C3 A9 10 lda #$10 ; reset bit 4
3505 F894C5 14 45 trb vdrive
3506 F894C7 18 ?10: clc
3507 F894C8 60 rts
3508
3509 ; test drive number
3510 F894C9 ctl_tst:
3511 F894C9 A5 AB lda drive
3512 F894CB C9 02 cmp #FDMAXDRIVE
3513 F894CD 90 06 bcc ?10
3514 F894CF A9 0E lda #FDC_NODRIVE ; error: invalid drive
3515 F894D1 85 48 sta fdcerr
3516 F894D3 68 pla ; skip return address
3517 F894D4 68 pla
3518 F894D5 60 ?10: rts
3519
3520 ; test if drive is attached to controller
3521 F894D6 ctl_dr:
3522 F894D6 24 46 bit fdcctl
3523 F894D8 30 06 bmi ?10
3524 F894DA A9 0E lda #FDC_NODRIVE ; error: invalid drive
3525 F894DC 85 48 sta fdcerr
3526 F894DE 68 pla ; skip return address
3527 F894DF 68 pla
3528 F894E0 60 ?10: rts
3529
3530 ;---------------------------------------------------------------------------
3531 ; fdc read/write & format routines
3532 ;---------------------------------------------------------------------------
3533
3534 ; execute read/verf/write track/sector's on floppy disk
3535 ; param's:
3536 ; fdop=fdc operation (0=read,1=fake verify,2=write)
3537 ; track=fd track
3538 ; sector=fd first sector
3539 ; head=fd side
3540 ; eot=fd last sector
3541 ; gap3=gap3 length for read/write
3542 ; dtlstp=fd DTL/STP param
3543 ; ncnt=bytes # to transfer
3544 ; opfg<7>=verify buffer with disk
3545 ; opfg<6>=MT command (multi track)
3546 ; bufp=buffer pointer
3547 ; verfp=verify buffer pointer
3548 ;
3549 ; out: CF=1 if error, fdcerr hold error code
3550 F894E1 fdrw:
3551 F894E1 20 3F 98 jsr chkfmt ; start motor and test disk format
Tue Jul 17 11:00:16 2018 Page 18
3552 F894E4 90 03 bcc ?00
3553 F894E6 4C 77 95 jmp stop ; stop motor
3554 F894E9 20 60 9D ?00: jsr chkparms ; check params
3555 F894EC 90 03 bcc ?01
3556 F894EE 4C 77 95 jmp stop ; stop motor
3557 F894F1 A9 05 ?01: lda #maxret ; retries count
3558 F894F3 85 BB sta retries
3559 F894F5 24 B6 bit opfg ; will verify buffer?
3560 F894F7 10 03 bpl ?02 ; no
3561 F894F9 20 2C 9D jsr savebuf ; save dma buffer for verify
3562 F894FC A4 AC ?02: ldy track ; seek track
3563 F894FE 20 C6 99 jsr seek
3564 F89501 B0 55 bcs ?14 ; error: retry?
3565 F89503 A6 B4 ldx fdop
3566 F89505 BF B1 A0 F8 lda >CMDTAB,x ; FDC command
3567 F89509 48 pha
3568 F8950A BF B4 A0 F8 lda >DMATAB,x ; DMA mode
3569 F8950E EB xba ; B=dma mode
3570 F8950F A6 9E ldx bufp
3571 F89511 A4 9F ldy bufp+1
3572 F89513 A5 A0 lda bufp+2
3573 F89515 20 7C 9A jsr dmaset ; dma setup
3574 F89518 68 pla ; FDC command
3575 F89519 24 B6 bit opfg
3576 F8951B 50 02 bvc ?04 ; no MT
3577 F8951D 09 80 ora #$80 ; MT operation
3578 F8951F 20 6F 97 ?04: jsr fdcmd ; execute command
3579 F89522 B0 34 bcs ?14 ; error: retry?
3580 F89524 24 B6 bit opfg ; will verify data?
3581 F89526 10 36 bpl ?16 ; no -- no error
3582 F89528 A9 46 lda #WRITETRASF ; read disk into verify buffer
3583 F8952A EB xba ; dma mode (read data)
3584 F8952B A6 A1 ldx verfp
3585 F8952D A4 A2 ldy verfp+1
3586 F8952F A5 A3 lda verfp+2
3587 F89531 20 7C 9A jsr dmaset ; dma setup
3588 F89534 A9 66 lda #CMDREAD
3589 F89536 24 B6 bit opfg
3590 F89538 50 02 bvc ?06 ; no MT
3591 F8953A 09 80 ora #$80 ; MT operation
3592 F8953C 20 6F 97 ?06: jsr fdcmd ; execute command
3593 F8953F B0 17 bcs ?14 ; error: retry?
3594 F89541 A0 00 ldy #0
3595 F89543 INDEX16 ; verify buffer's
3596 F89543 C2 10 rep #PXFLAG
3597 .LONGI on
3598 .MNLIST
3599 F89545 B7 9E ?08: lda [bufp],y
3600 F89547 D7 A1 cmp [verfp],y
3601 F89549 D0 05 bne ?10 ; unmatch (ZF=0)
3602 F8954B C8 iny
3603 F8954C C4 94 cpy ncnt
3604 F8954E 90 F5 bcc ?08
3605 F89550 ?10: INDEX08 ; here ZF=1 if match, ZF=0 if not
3606 F89550 E2 10 sep #PXFLAG
3607 .LONGI off
3608 .MNLIST
Tue Jul 17 11:00:16 2018 Page 19
3609 F89552 18 clc ; assume no error
3610 F89553 F0 09 beq ?16 ; match
3611 F89555 A9 12 lda #FDC_VER ; verify error
3612 F89557 38 sec
3613 F89558 C6 BB ?14: dec retries ; try again?
3614 F8955A D0 A0 bne ?02 ; yes
3615 F8955C 80 0A bra ?18 ; CF=1, A=error code
3616 F8955E A5 44 ?16: lda fdcdrv ; set valid format
3617 F89560 29 7C and #01111100B
3618 F89562 05 B7 ora dskfmt ; update format in drive
3619 F89564 09 A0 ora #$A0 ; current valid format&trust bit
3620 F89566 85 44 sta fdcdrv
3621 F89568 24 B6 ?18: bit opfg ; will restore dma buffer after verify?
3622 F8956A 10 03 bpl done ; no
3623 F8956C 20 44 9D jsr restbuf ; restore dma buffer
3624
3625 ; end fdc operation: reset controller if any error
3626 ; stop motor & set fdcerr if error
3627 ; in: CF=1 if error, A=error code
3628 F8956F done:
3629 F8956F 90 0A bcc stop2
3630 F89571 48 pha ; save error code
3631 F89572 20 3A 9B jsr fdcrst ; reset controller after error
3632 F89575 68 pla ; restore error code
3633 F89576 38 sec
3634
3635 ; stop motor & set error code if any
3636 ; in: CF=1 if error, A=error code
3637 F89577 stop:
3638 F89577 90 02 bcc stop2
3639 F89579 85 48 sta fdcerr ; set error code
3640 F8957B stop2:
3641 F8957B 4C 07 9D jmp stopmtr
3642
3643 ; format whole floppy disk
3644 ; out: CF=1 if error, fdcerr hold error code
3645 F8957E fdfmt:
3646 F8957E 24 46 bit fdcctl ; drive attached?
3647 F89580 30 06 bmi ?02 ; yes
3648 F89582 A9 0E lda #FDC_NODRIVE
3649 F89584 85 48 sta fdcerr
3650 F89586 38 sec
3651 F89587 60 rts
3652 F89588 20 D7 98 ?02: jsr chkdsk ; start motor and check if disk in drive
3653 F8958B 90 02 bcc ?04 ; ok - ready
3654 F8958D 50 E8 bvc stop ; not ready, stop motor&exit
3655 F8958F A9 10 ?04: lda #$10 ; test disk write protect on
3656 F89591 24 44 bit fdcdrv
3657 F89593 F0 04 beq ?06
3658 F89595 A9 0B lda #FDC_WP ; wp on error
3659 F89597 80 DE bra stop ; stop motor&exit
3660 F89599 64 48 ?06: stz fdcerr ; clear error
3661 F8959B A5 44 lda fdcdrv ; reset format
3662 F8959D 29 5C and #01011100B
3663 F8959F 85 44 sta fdcdrv
3664 F895A1 24 44 bit fdcdrv ; need to call seek0 double step?
3665 F895A3 70 05 bvs ?08 ; no
Tue Jul 17 11:00:16 2018 Page 20
3666 F895A5 20 95 99 jsr seek0 ; double step seek track 0
3667 F895A8 B0 CD bcs stop ; error
3668 F895AA A5 B7 ?08: lda dskfmt ; set FDC rate
3669 F895AC 20 BB 9C jsr setrate
3670 F895AF A9 01 lda #$01 ; reset bit 0...
3671 F895B1 14 B6 trb fmtfg ; ...for first call to callback
3672 F895B3 ACC16
3673 F895B3 C2 20 rep #PMFLAG
3674 .LONGA on
3675 .MNLIST
3676 F895B5 3B tsc ; make room for a local buffer in stack
3677 F895B6 38 sec
3678 F895B7 E9 50 00 sbc #80
3679 F895BA 1B tcs
3680 F895BB 1A inc a ; pointer to temp. buffer
3681 F895BC 85 98 sta ptmp
3682 F895BE ACC08
3683 F895BE E2 20 sep #PMFLAG
3684 .LONGA off
3685 .MNLIST
3686 F895C0 A0 4F ldy #79 ; save buffer dma in temp. buffer
3687 F895C2 B7 9E ?09: lda [bufp],y
3688 F895C4 91 98 sta (ptmp),y
3689 F895C6 88 dey
3690 F895C7 10 F9 bpl ?09
3691 F895C9 C8 iny ; Y=0
3692 F895CA BB tyx ; X=0
3693 F895CB 84 AC ?10: sty track ; format this track...
3694 F895CD 86 AD ?11: stx head ; ...in this side
3695 F895CF A9 05 lda #maxret
3696 F895D1 85 BB sta retries ; retries count
3697 F895D3 A0 00 ?12: ldy #0 ; fill buffer with data for current track/head
3698 F895D5 A2 01 ldx #1 ; X=sector
3699 F895D7 A5 AC ?14: lda track
3700 F895D9 97 9E sta [bufp],y ; C=track
3701 F895DB C8 iny
3702 F895DC A5 AD lda head
3703 F895DE 97 9E sta [bufp],y ; H=head
3704 F895E0 C8 iny
3705 F895E1 8A txa
3706 F895E2 97 9E sta [bufp],y ; R=sector
3707 F895E4 C8 iny
3708 F895E5 A9 02 lda #2
3709 F895E7 97 9E sta [bufp],y ; N=size of sector
3710 F895E9 C8 iny
3711 F895EA E8 inx
3712 F895EB E4 B0 cpx maxsect ; loop
3713 F895ED 90 E8 bcc ?14
3714 F895EF 84 94 sty ncnt ; DMA count of bytes
3715 F895F1 64 95 stz ncnt+1
3716 F895F3 20 32 98 jsr tstrdy ; test disk ready
3717 F895F6 B0 4A bcs ?20 ; error - no disk or disk changed
3718 F895F8 A9 4A lda #READTRASF ; read transfer
3719 F895FA EB xba ; B=dma mode
3720 F895FB A6 9E ldx bufp
3721 F895FD A4 9F ldy bufp+1
3722 F895FF A5 A0 lda bufp+2
Tue Jul 17 11:00:16 2018 Page 21
3723 F89601 20 7C 9A jsr dmaset
3724 F89604 24 B6 bit fmtfg
3725 F89606 10 13 bpl ?16 ; no callback
3726 F89608 4B phk ; JSL simulation
3727 F89609 F4 1A 96 pea #?16-1 ; return address
3728 F8960C A5 B1 lda eot ; params for callback
3729 F8960E EB xba ; B = sector/track
3730 F8960F A5 B6 lda fmtfg
3731 F89611 4A lsr a ; bit 0 -> carry -> 0 if first call
3732 F89612 A5 AB lda drive ; A = drive
3733 F89614 A4 AC ldy track ; Y = track
3734 F89616 A6 AD ldx head ; X = head
3735 F89618 DC A1 00 jmp [lpfn]
3736 ?16: ; return from notify callback
3737 F8961B A4 AC ldy track ; track seek
3738 F8961D 20 C6 99 jsr seek
3739 F89620 B0 20 bcs ?20 ; seek error
3740 F89622 20 07 97 jsr fdftcmd ; format track
3741 F89625 90 06 bcc ?18 ; no error
3742 F89627 C6 BB dec retries
3743 F89629 D0 A8 bne ?12 ; try again
3744 F8962B 80 15 bra ?20
3745 F8962D A9 01 ?18: lda #$01
3746 F8962F 04 B6 tsb fmtfg ; bit 0 = 1 -> for callback
3747 F89631 A6 AD ldx head ; next side
3748 F89633 E8 inx
3749 F89634 E0 02 cpx #2
3750 F89636 90 95 bcc ?11 ; format same track in next side
3751 F89638 A2 00 ldx #0 ; restart side=0
3752 F8963A A4 AC ldy track ; next track
3753 F8963C C8 iny
3754 F8963D C0 50 cpy #80
3755 F8963F 90 8A bcc ?10 ; format next track
3756 F89641 18 clc ; format end without error
3757 F89642 08 ?20: php ; save carry
3758 F89643 FA plx ; save carry in X bit 0
3759 F89644 A0 4F ldy #79 ; restore buffer dma
3760 F89646 B1 98 ?22: lda (ptmp),y
3761 F89648 97 9E sta [bufp],y
3762 F8964A 88 dey
3763 F8964B 10 F9 bpl ?22
3764 F8964D ACC16CLC
3765 F8964D C2 21 rep #(PMFLAG.OR.PCFLAG)
3766 .LONGA on
3767 .MNLIST
3768 F8964F 3B tsc ; restore stack frame
3769 F89650 69 50 00 adc #80
3770 F89653 1B tcs
3771 F89654 ACC08
3772 F89654 E2 20 sep #PMFLAG
3773 .LONGA off
3774 .MNLIST
3775 F89656 8A txa ; A = saved status
3776 F89657 4A lsr a ; CF=1 if error
3777 F89658 B0 0A bcs ?24 ; error
3778 F8965A A5 44 lda fdcdrv ; set valid format
3779 F8965C 29 7C and #01111100B
Tue Jul 17 11:00:16 2018 Page 22
3780 F8965E 05 B7 ora dskfmt ; update format in selected drive
3781 F89660 09 80 ora #$80 ; current valid format (but not trust bit)
3782 F89662 85 44 sta fdcdrv
3783 F89664 4C 6F 95 ?24: jmp done ; stop motor - reset controller if error
3784
3785 ; verify low level format of floppy disk
3786 ; out: CF=1 if error, fdcerr hold error code
3787 F89667 fdverf:
3788 F89667 24 46 bit fdcctl ; drive attached?
3789 F89669 30 06 bmi ?02 ; yes
3790 F8966B A9 0E lda #FDC_NODRIVE
3791 F8966D 85 48 sta fdcerr
3792 F8966F 38 sec
3793 F89670 60 rts
3794 F89671 64 44 ?02: stz fdcdrv ; get disk format - invalidate current format
3795 F89673 20 3F 98 jsr chkfmt ; try to check format
3796 F89676 90 03 bcc ?06
3797 F89678 4C 77 95 ?04: jmp stop ; error
3798 F8967B A9 00 ?06: lda #0
3799 F8967D AA tax
3800 F8967E 85 9E sta bufp ; set dma buffer at $030000
3801 F89680 85 9F sta bufp+1 ; fake transfer
3802 F89682 1A inc a
3803 F89683 85 AE sta sector ; sector = 1
3804 F89685 1A inc a
3805 F89686 1A inc a
3806 F89687 85 A0 sta bufp+2
3807 F89689 CA dex
3808 F8968A 86 9B stx dtlstp ; DTL/STP = $FF
3809 F8968C A6 B7 ldx dskfmt
3810 F8968E BF A1 A0 F8 lda >MAXSECT,x
3811 F89692 85 B0 sta maxsect ; max. numbers of sectors/track + 1
3812 F89694 3A dec a
3813 F89695 85 AF sta sectnum ; sectors/track
3814 F89697 85 B1 sta eot ; end of track
3815 F89699 0A asl a ; num. of bytes
3816 F8969A 85 95 sta ncnt+1
3817 F8969C 64 94 stz ncnt
3818 F8969E A0 00 ldy #0 ; Y=0
3819 F896A0 BB tyx ; X=0
3820 F896A1 84 AC ?10: sty track ; check this track...
3821 F896A3 86 AD ?11: stx head ; ...in this side
3822 F896A5 A9 05 lda #maxret
3823 F896A7 85 BB sta retries ; retries count
3824 F896A9 20 32 98 ?12: jsr tstrdy ; test disk
3825 F896AC B0 CA bcs ?04 ; error - no disk or disk changed
3826 F896AE A9 42 lda #VERFTRASF ; fake transfer, only check track
3827 F896B0 EB xba ; B=dma mode
3828 F896B1 A6 9E ldx bufp ; buffer pointer
3829 F896B3 A4 9F ldy bufp+1
3830 F896B5 A5 A0 lda bufp+2
3831 F896B7 20 7C 9A jsr dmaset
3832 F896BA 24 B6 bit fmtfg
3833 F896BC 10 13 bpl ?14 ; no callback
3834 F896BE 4B phk ; JSL simulation
3835 F896BF F4 D0 96 pea #?14-1 ; return address
3836 F896C2 A5 B7 lda dskfmt
Tue Jul 17 11:00:16 2018 Page 23
3837 F896C4 EB xba ; B = sector/track
3838 F896C5 A5 B6 lda fmtfg
3839 F896C7 4A lsr a ; bit 0 -> carry -> 0 if first call
3840 F896C8 A5 AB lda drive ; A = drive
3841 F896CA A4 AC ldy track ; Y = track
3842 F896CC A6 AD ldx head
3843 F896CE DC A1 00 jmp [lpfn]
3844 ?14: ; return from notify callback
3845 F896D1 A4 AC ldy track ; track seek
3846 F896D3 20 C6 99 jsr seek
3847 F896D6 B0 A0 bcs ?04 ; seek error
3848 F896D8 A9 66 lda #CMDREAD ; fake read whole track in current side
3849 F896DA 20 6F 97 jsr fdcmd
3850 F896DD 90 06 bcc ?18
3851 F896DF C6 BB dec retries
3852 F896E1 D0 C6 bne ?12
3853 F896E3 80 1F bra ?20
3854 F896E5 A9 01 ?18: lda #$01
3855 F896E7 04 B6 tsb fmtfg ; bit 0 = 1 -> for callback
3856 F896E9 A6 AD ldx head ; next side
3857 F896EB E8 inx
3858 F896EC E0 02 cpx #2
3859 F896EE 90 B3 bcc ?11 ; same track, side=1
3860 F896F0 A2 00 ldx #0 ; clear head
3861 F896F2 A4 AC ldy track ; next track
3862 F896F4 C8 iny
3863 F896F5 C0 50 cpy #80
3864 F896F7 90 A8 bcc ?10 ; next track, side=0
3865 F896F9 A5 44 lda fdcdrv ; set valid format
3866 F896FB 29 7C and #01111100B
3867 F896FD 05 B7 ora dskfmt ; update format (but not trut bit)
3868 F896FF 09 80 ora #$80 ; current valid format
3869 F89701 85 44 sta fdcdrv
3870 F89703 18 clc
3871 F89704 4C 6F 95 ?20: jmp done
3872
3873 ;---------------------------------------------------------------------------
3874 ; fdc basic read/write/format command's
3875 ;---------------------------------------------------------------------------
3876
3877 ; fd format track command
3878 ; out: CF=1 if error, A=error code
3879 ; A,X,Y destroyed
3880 F89707 fdftcmd:
3881 F89707 64 96 stz ntrsf ; clear numbers of transferred bytes
3882 F89709 64 97 stz ntrsf+1
3883 F8970B A5 B7 lda dskfmt
3884 F8970D 29 03 and #$03 ; disk format [0..2]
3885 F8970F AA tax ; X=format
3886 F89710 BF A9 A0 F8 lda >FGPLTBL,x ; GAP 3 length
3887 F89714 85 B2 sta gap3
3888 F89716 BF AD A0 F8 lda >HEADTBL,x ; head inversion for CBM format
3889 F8971A 45 AD eor head
3890 F8971C 0A asl a ; head -> bit 2
3891 F8971D 0A asl a
3892 F8971E 85 9A sta drvhead ; head + drive (=0)
3893 F89720 A9 4D lda #CMDFMT ; format track command
Tue Jul 17 11:00:16 2018 Page 24
3894 F89722 20 9A 9B jsr sendto
3895 F89725 A5 9A lda drvhead ; head + drive
3896 F89727 20 9A 9B jsr sendto
3897 F8972A A9 02 lda #2 ; sector size = 512 bytes
3898 F8972C 20 9A 9B jsr sendto
3899 F8972F A5 B1 lda eot ; SC = sector/track
3900 F89731 20 9A 9B jsr sendto
3901 F89734 A5 B2 lda gap3 ; GPL 3 length
3902 F89736 20 9A 9B jsr sendto
3903 F89739 A5 B8 lda fmtfill ; D = fill byte
3904 F8973B 20 9A 9B jsr sendto
3905 F8973E 2C 00 FD bit VIA0+VIAPRB ; clear CB1 flag
3906 F89741 A9 02 lda #$02 ; enable DMA bus
3907 F89743 1C 0F FD trb VIA0+VIAPRANH ; PA1 -> /DME = 0
3908 F89746 20 5F 99 jsr chkres ; wait result
3909 F89749 20 BC 97 jsr chkdma
3910 F8974C B0 20 bcs ?10 ; error in phase result
3911 F8974E 24 B6 bit fmtfg ; verf track ?
3912 F89750 50 1C bvc ?10 ; no
3913 F89752 A5 B1 lda eot
3914 F89754 0A asl a ; number of bytes
3915 F89755 85 95 sta ncnt+1
3916 F89757 64 94 stz ncnt
3917 F89759 64 96 stz ntrsf ; clear numbers of transferred bytes
3918 F8975B 64 97 stz ntrsf+1
3919 F8975D A9 42 lda #VERFTRASF ; fake transfer, just check track
3920 F8975F EB xba ; B=dma mode
3921 F89760 A6 9E ldx bufp ; buffer pointer
3922 F89762 A4 9F ldy bufp+1
3923 F89764 A5 A0 lda bufp+2
3924 F89766 20 7C 9A jsr dmaset
3925 F89769 A9 66 lda #CMDREAD ; fake read whole track in current side
3926 F8976B 20 6F 97 jsr fdcmd
3927 F8976E 60 ?10: rts
3928
3929 ; fd read/write/verf command
3930 ; in: A=command
3931 ; out: CF=1 if error, A=error code
3932 ; A,X,Y destroyed
3933 F8976F fdcmd:
3934 ;stz ntrsf ; clear numbers of transferred bytes
3935 ;stz ntrsf+1
3936 F8976F A8 tay ; Y=command
3937 F89770 A5 B7 lda dskfmt
3938 F89772 29 03 and #$03 ; disk format [0..2]
3939 F89774 AA tax ; X=format
3940 F89775 BF A5 A0 F8 lda >RWGPLTBL,x ; GAP 3 length for required format
3941 F89779 85 B2 sta gap3
3942 F8977B BF AD A0 F8 lda >HEADTBL,x ; head inversion for CBM format
3943 F8977F 45 AD eor head
3944 F89781 0A asl a ; head -> bit 2
3945 F89782 0A asl a
3946 F89783 85 9A sta drvhead ; head + drive (=0)
3947 F89785 98 tya ; A=command
3948 F89786 20 9A 9B jsr sendto
3949 F89789 A5 9A lda drvhead ; head + drive
3950 F8978B 20 9A 9B jsr sendto
Tue Jul 17 11:00:16 2018 Page 25
3951 F8978E A5 AC lda track ; track
3952 F89790 20 9A 9B jsr sendto
3953 F89793 A5 AD lda head ; head
3954 F89795 20 9A 9B jsr sendto
3955 F89798 A5 AE lda sector ; sector
3956 F8979A 20 9A 9B jsr sendto
3957 F8979D A9 02 lda #2 ; sector size = 512 bytes
3958 F8979F 20 9A 9B jsr sendto
3959 F897A2 A5 B1 lda eot ; EOT (last sector)
3960 F897A4 20 9A 9B jsr sendto
3961 F897A7 A5 B2 lda gap3 ; GPL 3 length
3962 F897A9 20 9A 9B jsr sendto
3963 F897AC A5 9B lda dtlstp ; DTL/STP
3964 F897AE 20 9A 9B jsr sendto
3965 F897B1 2C 00 FD bit VIA0+VIAPRB ; clear CB1 flag (FDC interrupt)
3966 F897B4 A9 02 lda #$02 ; enable DMA bus control
3967 F897B6 1C 0F FD trb VIA0+VIAPRANH ; PA1 -> /DME = 0
3968 ;jsr chkres3 ; wait for transfer ending and CPU bus enable
3969 F897B9
3970 F897B9 20 5F 99 jsr chkres ; wait for transfer ending and CPU bus enable
3971
3972 ; read from dma count the effective transferred bytes count
3973 F897BC chkdma:
3974 F897BC 48 pha ; save error code if any
3975 F897BD 08 php ; save carry for pending error
3976 F897BE AF 98 FD 00 lda >DMASR ; save DMA status & clear status reg
3977 F897C2 85 B3 sta dmast
3978 F897C4 85 EE sta <$ee
3979
3980 F897C6 8E 9C FD stx .ABS.DMAWCLRFF
3981 F897C9 AE 95 FD ldx .ABS.DMAC+DMACNT2
3982 F897CC 86 E8 stx <$e8
3983 F897CE AE 95 FD ldx .ABS.DMAC+DMACNT2
3984 F897D1 86 E9 stx <$e9
3985 F897D3 8E 9C FD stx .ABS.DMAWCLRFF
3986 F897D6 AE 94 FD ldx .ABS.DMAC+DMAADDR2
3987 F897D9 86 EA stx <$ea
3988 F897DB EA nop
3989 F897DC EA nop
3990 F897DD EA nop
3991 F897DE EA nop
3992 F897DF AE 94 FD ldx .ABS.DMAC+DMAADDR2
3993 F897E2 86 EB stx <$eb
3994 F897E4 64 EF stz <$ef
3995 F897E6 90 04 bcc ?10
3996 F897E8 C6 EF dec <$ef
3997 F897EA B0 43 bcs ?30 ; error pending
3998 F897EC 8D 9C FD ?10: sta !DMAWCLRFF ; loop for read dma reg.
3999 F897EF EA nop
4000 F897F0 EA nop
4001 F897F1 AD 95 FD lda !DMAC+DMACNT2 ; low count DMA residue
4002 F897F4 EB xba
4003 F897F5 EA nop
4004 F897F6 AD 95 FD lda !DMAC+DMACNT2 ; high count DMA residue
4005 F897F9 EB xba
4006 F897FA EA nop
4007 F897FB 8D 9C FD sta !DMAWCLRFF
Tue Jul 17 11:00:16 2018 Page 26
4008 F897FE CD 95 FD cmp !DMAC+DMACNT2
4009 F89801 EA nop
4010 F89802 D0 E8 bne ?10
4011 F89804 EB xba
4012 F89805 EA nop
4013 F89806 CD 95 FD cmp !DMAC+DMACNT2
4014 F89809 EA nop
4015 F8980A D0 E0 bne ?10
4016 F8980C EB xba ; C = residual bytes #
4017 F8980D ACC16
4018 F8980D C2 20 rep #PMFLAG
4019 .LONGA on
4020 .MNLIST
4021 F8980F 1A inc a ; DMA count residue
4022 F89810 85 96 sta ntrsf
4023 F89812 38 sec
4024 F89813 A5 94 lda ncnt ; # transferred bytes
4025 F89815 E5 96 sbc ntrsf
4026 ;sta ntrsf
4027 F89817 C5 94 cmp ncnt
4028 F89819 ACC08
4029 F89819 E2 20 sep #PMFLAG
4030 .LONGA off
4031 .MNLIST
4032 F8981B D0 06 bne ?20 ; error: no match
4033 F8981D A5 B3 lda dmast ; check dma status
4034 F8981F 89 04 bit #$04 ; premature cycle ending?
4035 F89821 D0 0C bne ?30 ; no
4036 F89823 A3 01 ?20: lda $01,s ; set CF in saved status
4037 F89825 09 01 ora #PCFLAG ; set error flag
4038 F89827 83 01 sta $01,s
4039 F89829 A9 08 lda #FDC_DLOSS ; data loss error
4040 F8982B
4041 F8982B 09 80 ora #$80
4042
4043 F8982D 83 02 sta $02,s ; report error
4044 F8982F 28 ?30: plp ; return CF
4045 F89830 68 pla ; return error code
4046 F89831 60 rts
4047
4048 ;---------------------------------------------------------------------------
4049 ; disk check routines
4050 ;---------------------------------------------------------------------------
4051
4052 ; test if disk ready while motor is spinning
4053 ; out: CF=0 if disk ready
4054 ; CF=1 if disk not ready or changed, A=FDC_NOTREADY
4055 ; A destroyed, X&Y preserved
4056 F89832 tstrdy:
4057 F89832 18 clc
4058 F89833 AF DF FD 00 lda >FDCDIR ; read disk change line
4059 F89837 29 80 and #$80 ; bit 7 will be 0
4060 F89839 F0 03 beq ?10 ; ready - exit with CF = 0
4061 F8983B A9 10 lda #FDC_NOTREADY ; not ready
4062 F8983D 38 sec ; error
4063 F8983E 60 ?10: rts
4064
Tue Jul 17 11:00:16 2018 Page 27
4065 ; check disk format - if the actual disk was not never checked it will be
4066 ; tested for the format
4067 ; out: CF=1 if error, A=error code
4068 ; A&Y destroyed, X preserved
4069 F8983F chkfmt:
4070 F8983F 20 D7 98 jsr chkdsk ; start motor and check if disk ready
4071 F89842 90 04 bcc ?06 ; disk ready and not changed
4072 F89844 50 3F bvc ?20 ; not ready - exit with CF = 1
4073 F89846 64 48 stz fdcerr ; disk changed
4074 F89848 24 44 ?06: bit fdcdrv ; need to call seek0 double step?
4075 F8984A 70 05 bvs ?08 ; no
4076 F8984C 20 95 99 jsr seek0 ; double step seek track 0
4077 F8984F B0 34 bcs ?20 ; error
4078 F89851 A5 44 ?08: lda fdcdrv ; bit 7 -> know format ?
4079 F89853 30 31 bmi ?30 ; yes, so check and compare
4080 F89855 A9 02 lda #$02 ; start with H.D.
4081 F89857 85 B7 ?10: sta dskfmt
4082 F89859 20 BB 9C jsr setrate ; setup rate
4083 F8985C 20 C2 98 jsr ?50 ; little delay
4084 F8985F 20 48 99 jsr readid ; read ID track=0 head=0
4085 F89862 90 08 bcc ?12 ; ok
4086 F89864 A5 B7 lda dskfmt
4087 F89866 F0 14 beq ?16 ; error - unrecognized format
4088 F89868 A9 00 lda #0 ; try D.D. rate
4089 F8986A 80 EB bra ?10
4090 F8986C 20 76 98 ?12: jsr ?14 ; check track & head
4091 F8986F B0 14 bcs ?20
4092 F89871 A9 80 lda #$80
4093 F89873 04 44 tsb fdcdrv ; set know format bit
4094 F89875 60 rts
4095 F89876 A5 A7 ?14: lda fdcres+3 ; check track
4096 F89878 C5 47 cmp fdctrk
4097 F8987A F0 04 beq ?18 ; will be the same
4098 F8987C A9 0D ?16: lda #FDC_BADFMT ; unknow format
4099 F8987E 38 ?17: sec
4100 F8987F 60 rts
4101 F89880 A5 A8 ?18: lda fdcres+4 ; head is inverted if CBM format
4102 F89882 04 B7 tsb dskfmt ; this set eventually bit 0 for CBM format
4103 F89884 18 clc
4104 F89885 60 ?20: rts
4105 F89886 89 20 ?30: bit #$20 ; trust format?
4106 F89888 D0 32 bne ?34 ; yes
4107 F8988A 29 02 and #$02 ; mask rate
4108 F8988C 85 B7 sta dskfmt ; here bit 0 = 0
4109 F8988E A8 tay
4110 F8988F 45 46 eor fdcctl ; compare with current rate
4111 F89891 29 02 and #$02
4112 F89893 F0 07 beq ?31 ; same rate
4113 F89895 98 tya
4114 F89896 20 BB 9C jsr setrate
4115 F89899 20 C2 98 jsr ?50 ; little delay
4116 F8989C A9 80 ?31: lda #$80
4117 F8989E 14 44 trb fdcdrv ; clear know format bit
4118 F898A0 20 48 99 jsr readid ; read first ID in current track
4119 F898A3 B0 E0 bcs ?20 ; error
4120 F898A5 20 76 98 jsr ?14 ; check track & head
4121 F898A8 B0 DB bcs ?20 ; error
Tue Jul 17 11:00:16 2018 Page 28
4122 F898AA A5 44 lda fdcdrv
4123 F898AC 45 B7 eor dskfmt ; compare computed format with the stored one
4124 F898AE 29 03 and #$03 ; will be 0
4125 F898B0 F0 04 beq ?32
4126 F898B2 A9 0F lda #FDC_FMT ; mismatch format
4127 F898B4 80 C8 bra ?17
4128 F898B6 A9 80 ?32: lda #$80
4129 F898B8 04 44 tsb fdcdrv ; set know format bit
4130 F898BA 18 clc
4131 F898BB 60 rts
4132 F898BC 29 03 ?34: and #$03 ; trust format
4133 F898BE 85 B7 sta dskfmt
4134 F898C0 18 clc
4135 F898C1 60 rts
4136
4137 ; 1ms delay
4138 F898C2 A9 20 ?50: lda #$20 ; T2 count PHI2 pulses
4139 F898C4 1C 0B FD trb VIA0+VIAACR
4140 F898C7 A9 10 lda #T1MS
4141 F898C9 9C 08 FD stz VIA0+VIAT2CL
4142 F898CC 8D 09 FD sta VIA0+VIAT2CH
4143 F898CF AD 0D FD ?55: lda VIA0+VIAIFR
4144 F898D2 89 20 bit #T2IFRB
4145 F898D4 F0 F9 beq ?55
4146 F898D6 60 rts
4147
4148 ; check disk in drive - if disk is changed reset controller and recalibrate
4149 ; drive & move head in track 0 & aquire wp status on disk
4150 ; out: CF=0 if disk ready
4151 ; CF=1 if disk not ready or changed
4152 ; VF=1 if disk changed else VF=0 if not ready
4153 ; A=error code FDC_NOTREADY or FDC_CHANGE or others
4154 ; A destroyed, X&Y preserved
4155 F898D7 chkdsk:
4156 F898D7 5A phy
4157 F898D8 64 48 stz fdcerr
4158 F898DA 20 CE 9C jsr startmtr ; start motor
4159 F898DD 18 clc
4160 F898DE AF DF FD 00 lda >FDCDIR ; read disk change line
4161 F898E2 29 80 and #$80 ; bit 7 will be 0
4162 F898E4 F0 21 beq ?20 ; ready so aquire wp status
4163 F898E6 A9 01 lda #$01 ; clear ready bit
4164 F898E8 14 46 trb fdcctl
4165 F898EA 20 3A 9B jsr fdcrst ; aquire new disk change line status
4166 F898ED B0 1F bcs ?30 ; error
4167 F898EF 20 95 99 jsr seek0 ; recalibrate after reset and seek track 0
4168 F898F2 B0 1A bcs ?30 ; error
4169 F898F4 A0 11 ldy #FDC_CHANGE ; disk change?
4170 F898F6 E2 40 sep #PVFLAG ; VF = 1 if disk change
4171 F898F8 AF DF FD 00 lda >FDCDIR ; read line
4172 F898FC 29 80 and #$80 ; bit 7 = 0 if disk inserted into drive
4173 F898FE F0 03 beq ?10 ; so disk changed
4174 F89900 A0 10 ldy #FDC_NOTREADY ; not ready
4175 F89902 B8 clv ; VF flag = 0 if not ready
4176 F89903 38 ?10: sec ; error
4177 F89904 98 tya ; A=error code
4178 F89905 50 07 bvc ?30 ; not ready
Tue Jul 17 11:00:16 2018 Page 29
4179 F89907 08 ?20: php ; save CF&VF
4180 F89908 48 pha ; save error code if any
4181 F89909 20 10 99 jsr chkwp ; aquire wp disk status
4182 F8990C 68 pla
4183 F8990D 28 plp
4184 F8990E 7A ?30: ply
4185 F8990F 60 rts
4186
4187 ; set write protect on bit and disk ready bit
4188 F89910 chkwp:
4189 F89910 A9 10 lda #$10
4190 F89912 14 44 trb fdcdrv ; clear wp on bit
4191 F89914 A9 01 lda #$01 ; set ready bit
4192 F89916 04 46 tsb fdcctl
4193 F89918 A9 04 lda #CMDSENSEST ; sense status
4194 F8991A 20 9A 9B jsr sendto
4195 F8991D A9 00 lda #0 ; drive
4196 F8991F 20 9A 9B jsr sendto
4197 F89922 20 D0 9B jsr waitres ; get result
4198 F89925 24 A4 bit fdcres ; ST3 bit 6 is wp on bit
4199 F89927 50 04 bvc ?10 ; no wp
4200 F89929 A9 10 lda #$10
4201 F8992B 04 44 tsb fdcdrv ; set bit 4: wp on
4202 F8992D 60 ?10: rts
4203
4204 ; sense phisycal drive #0 status
4205 ; out: A=ST3 status if no error
4206 ; CF=1 if error, fdcerr=error code
4207 F8992E drvst:
4208 F8992E 20 CE 9C jsr startmtr
4209 F89931 20 37 99 jsr ?20
4210 F89934 4C 77 95 jmp stop
4211
4212 F89937 A9 04 ?20: lda #CMDSENSEST ; sense status
4213 F89939 20 9A 9B jsr sendto
4214 F8993C A9 00 lda #0 ; drive
4215 F8993E 20 9A 9B jsr sendto
4216 F89941 20 D0 9B jsr waitres ; get result
4217 F89944 A5 A4 lda fdcres ; get ST3
4218 F89946 18 clc
4219 F89947 60 rts
4220
4221 ; read first valid ID in current track, head = 0
4222 ; if current track is not valid ($FF) seek to track 0
4223 ; out: CF=1 if error, A=error code
4224 ; A&Y destroyed, X preserved
4225 F89948 readid:
4226 F89948 A5 47 lda fdctrk
4227 F8994A C9 FF cmp #$FF
4228 F8994C D0 07 bne ?02
4229 F8994E A0 00 ldy #0
4230 F89950 20 C6 99 jsr seek
4231 F89953 B0 3F bcs chk
4232 F89955 A9 4A ?02: lda #CMDREADID
4233 F89957 20 9A 9B jsr sendto
4234 F8995A A9 00 lda #0 ; head + drive (head = 0)
4235 F8995C 20 9A 9B jsr sendto
Tue Jul 17 11:00:16 2018 Page 30
4236 F8995F
4237 ; wait phase result after read/write/format/read ID and check result
4238 ; out: CF=1 if error, A=error code
4239 ; A&Y destroyed, X preserved
4240 F8995F chkres:
4241 F8995F 20 20 9C jsr waitint ; wait interrupt
4242 F89962 chkres2:
4243 F89962 20 D0 9B jsr waitres ; get result
4244 F89965 A5 A4 lda fdcres ; test ST0
4245 F89967 29 C0 and #11000000B
4246 F89969 F0 29 beq chk ; here CF = 0 - result ok
4247 F8996B C9 40 cmp #01000000B
4248 F8996D D0 21 bne ?10 ; bad controller
4249 F8996F 18 clc ; no error
4250 F89970 A5 A5 lda fdcres+1 ; test ST1
4251 F89972 30 20 bmi chk ; 7 -> end of track, no error
4252 F89974 0A asl a ; skip bit 7
4253 F89975 0A asl a ; 6 -> skip
4254 F89976 0A asl a
4255 F89977 A0 09 ldy #FDC_DATACRC
4256 F89979 B0 18 bcs ?20 ; 5 -> CRC error
4257 F8997B 0A asl a
4258 F8997C A0 08 ldy #FDC_DLOSS
4259 F8997E B0 13 bcs ?20 ; 4 -> data loss
4260 F89980 0A asl a
4261 F89981 0A asl a
4262 F89982 A0 0A ldy #FDC_NOID
4263 F89984 B0 0D bcs ?20 ; 2 -> ID not found
4264 F89986 0A asl a
4265 F89987 A0 0B ldy #FDC_WP
4266 F89989 B0 08 bcs ?20 ; 1 -> write protect
4267 F8998B 0A asl a
4268 F8998C A0 0C ldy #FDC_MARK
4269 F8998E B0 03 bcs ?20 ; 0 -> mark address
4270 F89990 A0 01 ?10: ldy #FDC_BAD ; bad controller
4271 F89992 38 sec
4272 F89993 98 ?20: tya ; A=error code
4273 F89994 60 chk: rts
4274
4275 ;---------------------------------------------------------------------------
4276 ; drive seek routines
4277 ;---------------------------------------------------------------------------
4278
4279 ; recalibrate drive if need and move head in track 0 with a double step seek
4280 ; this routine should be called if bit 6 of fdcdrv is 0 as after a reset
4281 ; out: CF=1 if error, A=error code
4282 ; A&Y destroyed, X preserved
4283 F89995 seek0:
4284 ;jsr restore
4285 ;bcs ?20
4286 ;stz fdctrk ; store current track (=0)
4287 ;lda #$40
4288 ;trb fdcctl ; reset flag restore: done
4289 F89995 A0 01 ldy #1 ; seek track 1
4290 F89997 20 C6 99 jsr seek ; and recalibrate if need
4291 F8999A B0 0B bcs ?10 ; error
4292 F8999C A0 00 ldy #0 ; seek track 0
Tue Jul 17 11:00:16 2018 Page 31
4293 F8999E 20 C6 99 jsr seek
4294 F899A1 B0 04 bcs ?10
4295 F899A3 A9 40 lda #$40 ; set bit 6 of fdcdrv
4296 F899A5 04 44 tsb fdcdrv
4297 F899A7 60 ?10: rts
4298 F899A8 A2 00 ?20: ldx #0
4299 F899AA A4 47 ldy fdctrk
4300 F899AC A5 FF lda $ff
4301 F899AE 00 00 brk
4302 F899B0 EA nop
4303 F899B1 EA nop
4304 F899B2 A2 01 ?30: ldx #1
4305 F899B4 A4 47 ldy fdctrk
4306 F899B6 A5 FF lda $ff
4307 F899B8 00 00 brk
4308 F899BA EA nop
4309 F899BB EA nop
4310 F899BC A2 02 ?40: ldx #2
4311 F899BE A4 47 ldy fdctrk
4312 F899C0 A5 FF lda $ff
4313 F899C2 00 00 brk
4314 F899C4 EA nop
4315 F899C5 EA nop
4316 F899C6
4317 ; move head in track Y & recalibrate drive if need
4318 ; in: Y=track
4319 ; A destroyed, X&Y preserved
4320 F899C6 seek:
4321 ;bit $FD2a
4322 ;bpl ?00
4323 ;lda !FDCDATA
4324
4325 F899C6 ?00:
4326
4327 F899C6 24 46 bit fdcctl ; test bit 6: need restore?
4328 F899C8 50 0F bvc ?04 ; no
4329 F899CA 20 31 9A jsr restore ; recalibrate drive
4330 F899CD B0 31 bcs ?10 ; error - exit
4331 F899CF 64 47 stz fdctrk ; store current track (=0)
4332 F899D1 A9 40 lda #$40
4333 F899D3 14 46 trb fdcctl ; reset flag restore: done
4334 F899D5 C0 00 cpy #0 ; requested track=0 ?
4335 F899D7 F0 21 beq ?06 ; yes, exit after a while
4336 F899D9 C4 47 ?04: cpy fdctrk ; already in the desidered track ?
4337 F899DB F0 1D beq ?06 ; yes, exit
4338 F899DD A9 0F lda #CMDSEEK ; send seek command
4339 F899DF 20 96 9B jsr sndto2
4340 F899E2 B0 17 bcs ?08
4341 F899E4 A9 00 lda #0 ; drive
4342 F899E6 20 96 9B jsr sndto2
4343 F899E9 B0 10 bcs ?08
4344 F899EB 98 tya ; track
4345 F899EC 85 47 sta fdctrk
4346 F899EE 20 96 9B jsr sndto2
4347 F899F1 B0 08 bcs ?08
4348 F899F3 A9 07 lda #FDC_SEEK ; error seek ?
4349 F899F5 20 46 9A jsr wseek ; wait result
Tue Jul 17 11:00:16 2018 Page 32
4350 F899F8 B0 01 bcs ?08
4351 F899FA 18 ?06: clc
4352 F899FB 20 09 9A ?08: jsr ?20
4353 F899FE 90 08 bcc ?12
4354 F89A00 85 B9 ?10: sta tmpa
4355 F89A02 A9 FF lda #$FF ; invalidate current track
4356 F89A04 85 47 sta fdctrk
4357 F89A06 A5 B9 lda tmpa
4358 F89A08 60 ?12: rts
4359
4360 ; 10ms delay
4361 F89A09 08 ?20: php
4362 F89A0A 48 pha
4363 F89A0B A9 20 lda #$20 ; T2 count PHI2 pulses
4364 F89A0D 1C 0B FD trb VIA0+VIAACR
4365 F89A10 A9 40 lda #<T10MS
4366 F89A12 8D 08 FD sta VIA0+VIAT2CL
4367 F89A15 A9 9C lda #>T10MS
4368 F89A17 8D 09 FD sta VIA0+VIAT2CH
4369 F89A1A ?22: TASKSW
4370 F89A1A 02 00 cop FN_TASKSW
4371 F89A1C 00 .DB $00
4372 .MNLIST
4373 F89A1D AD 0D FD lda VIA0+VIAIFR
4374 F89A20 89 20 bit #T2IFRB
4375 F89A22 F0 F6 beq ?22
4376 F89A24 68 pla
4377 F89A25 28 plp
4378 F89A26 60 rts
4379
4380 F89A27 A2 FF ?40: ldx #$FF
4381 F89A29 A5 FF lda $ff
4382 F89A2B A4 47 ldy fdctrk
4383 F89A2D 00 00 brk
4384 F89A2F EA nop
4385 F89A30 EA nop
4386 F89A31
4387 ; causes the read/write head within the FDD to retract in the track 0 position
4388 ; out: CF=1 if error, A=error code
4389 ; A destroyed, X&Y preserved
4390 F89A31 restore:
4391 F89A31 20 36 9A jsr ?10 ; ricalibrate: first step
4392 F89A34 90 45 bcc wsk ; no double step need
4393 ; if error, need one step more
4394 F89A36 A9 07 ?10: lda #CMDRECAL ; ricalibrate command
4395 F89A38 20 96 9B jsr sndto2
4396 F89A3B B0 3E bcs wsk ; error
4397 F89A3D A9 00 lda #0 ; drive
4398 F89A3F 20 96 9B jsr sndto2
4399 F89A42 B0 37 bcs wsk ; error
4400 F89A44 A9 06 lda #FDC_FAULT ; restore error ?
4401
4402 ; wait result phase after seek/recalibrate command
4403 ; in: A=error code FDC_FAULT or FDC_SEEK
4404 ; out: CF=1 if error, A=error code
4405 ; A,X,Y preserved
4406 F89A46 wseek:
Tue Jul 17 11:00:16 2018 Page 33
4407 F89A46 85 B9 sta tmpa ; save error code
4408 F89A48 20 6E 9A jsr ?20 ; sense interrupt
4409 F89A4B B0 2E bcs wsk ; return pending error
4410 F89A4D A5 A4 ?01: lda fdcres ; test result status
4411 F89A4F 85 FF sta $FF
4412 F89A51 C9 80 cmp #$80
4413 F89A53 F0 0B beq ?30
4414 F89A55 29 60 and #01100000B
4415 F89A57 C9 60 cmp #01100000B
4416 F89A59 38 sec
4417 F89A5A F0 01 beq ?10 ; restore/seek error
4418 F89A5C 18 clc ; no error
4419 F89A5D A5 B9 ?10: lda tmpa
4420 F89A5F 60 rts
4421
4422 F89A60 AD 2A FD ?30: lda !$FD2A
4423 F89A63 85 FD sta $fd
4424 F89A65 10 F9 bpl ?30
4425 F89A67 20 71 9A jsr ?21
4426 F89A6A B0 0F bcs wsk
4427 ;lda !VIA0+VIAPRB
4428 F89A6C 80 DF bra ?01
4429 F89A6E
4430 ; wait result phase after sensing interrupt
4431 F89A6E 20 20 9C ?20: jsr waitint ; wait interrupt within timeout
4432 F89A71 A9 08 ?21: lda #CMDSENSEINT ; sense interrupt
4433 F89A73 20 9A 9B jsr sendto
4434 F89A76 64 A4 stz fdcres
4435 F89A78 20 D0 9B jsr waitres ; wait result phase
4436 F89A7B 60 wsk: rts
4437
4438 ;---------------------------------------------------------------------------
4439 ; low level controller routines
4440 ;---------------------------------------------------------------------------
4441
4442 ; dma setup on channel 2 for a transfer cycle
4443 ; in: X=transfer buffer low pointer
4444 ; Y=transfer buffer high pointer
4445 ; A=transfer buffer bank
4446 ; B=dma mode transfer
4447 ; ncnt=bytes to transfer count #
4448 F89A7C dmaset:
4449 F89A7C 48 pha
4450 F89A7D 64 F0 stz <$f0
4451 F89A7F 64 F1 stz <$f1
4452 F89A81 A9 01 lda #$01
4453 F89A83 1C 0F FD trb VIA0+VIAPRANH ; DMA X16=0 (bank 2)
4454 F89A86 A9 02 lda #2
4455 F89A88 0C 00 FD tsb VIA0+VIAPRB
4456 F89A8B 68 pla
4457 F89A8C 29 01 and #$01 ; mask bit 0
4458 F89A8E F0 05 beq ?02 ; transfer buffer is in bank 2
4459 F89A90 A9 01 lda #$01
4460 F89A92 0C 0F FD tsb VIA0+VIAPRANH ; DMA X16=1 (bank 3)
4461 F89A95 ?02:
4462 F89A95 A9 07 lda #$07
4463 F89A97 1C CF FD trb VIA3+VIAPRANH
Tue Jul 17 11:00:16 2018 Page 34
4464 F89A9A
4465 ;lda #01011000B
4466 F89A9A A9 00 lda #0
4467 F89A9C 8D C0 FD sta !VIA3+VIAPRB
4468
4469 F89A9F 78 sei
4470 F89AA0 8F 9D FD 00 sta >DMAWMCLR
4471 F89AA4 EA nop
4472 F89AA5 EA nop
4473 F89AA6 EA nop
4474 F89AA7 EA nop
4475 F89AA8 AF 98 FD 00 lda >DMASR ; clear status flag
4476 F89AAC EA nop
4477 F89AAD EA nop
4478 F89AAE A9 00 lda #$00
4479 F89AB0 8F 98 FD 00 sta >DMAWCMD
4480 F89AB4 EA nop
4481 F89AB5 EA nop
4482 F89AB6 8F 9D FD 00 sta >DMAWMCLR
4483 F89ABA EA nop
4484 F89ABB EA nop
4485 F89ABC A9 06 lda #$06
4486 F89ABE EA nop
4487 F89ABF 8F 9A FD 00 sta >DMAWMSKB ; mask off bit channel 2
4488 F89AC3 EA nop
4489 F89AC4 EB xba ; A=transfer mode
4490 F89AC5 8F 9B FD 00 sta >DMAMODE ; set DMA transfer mode
4491 F89AC9 85 F2 sta <$f2
4492 F89ACB
4493 F89ACB EA nop
4494 F89ACC 8F 9C FD 00 ?06: sta >DMAWCLRFF ; clear F/F
4495 F89AD0 E6 F0 inc <$f0
4496 F89AD2 EA nop
4497 F89AD3 EA nop
4498 F89AD4 8A txa
4499 F89AD5 8F 94 FD 00 sta >DMAC+DMAADDR2 ; store low buffer address
4500 F89AD9 EA nop
4501 F89ADA EA nop
4502 F89ADB 98 tya
4503 F89ADC 8F 94 FD 00 sta >DMAC+DMAADDR2 ; store high buffer address
4504 F89AE0 EA nop
4505 F89AE1 8F 9C FD 00 sta >DMAWCLRFF ; clear F/F
4506 F89AE5 EA nop
4507 F89AE6 EA nop
4508 F89AE7 8A txa
4509 F89AE8 CF 94 FD 00 cmp >DMAC+DMAADDR2 ; cmp low buffer address
4510 F89AEC D0 DE bne ?06
4511 F89AEE 98 tya
4512 F89AEF CF 94 FD 00 cmp >DMAC+DMAADDR2 ; cmp high buffer address
4513 F89AF3 D0 D7 bne ?06
4514 F89AF5 ACC16
4515 F89AF5 C2 20 rep #PMFLAG
4516 .LONGA on
4517 .MNLIST
4518 F89AF7 A5 94 lda ncnt
4519 F89AF9 3A dec a ; DMA count=ncnt-1
4520 F89AFA 48 pha
Tue Jul 17 11:00:16 2018 Page 35
4521 F89AFB ACC08
4522 F89AFB E2 20 sep #PMFLAG
4523 .LONGA off
4524 .MNLIST
4525 F89AFD FA plx ; X=low count
4526 F89AFE 7A ply ; Y=high count
4527 F89AFF 8F 9C FD 00 ?08: sta >DMAWCLRFF ; clear F/F
4528 F89B03 E6 F1 inc <$f1
4529 F89B05 EA nop
4530 F89B06 EA nop
4531 F89B07 8A txa
4532 F89B08 8F 95 FD 00 sta >DMAC+DMACNT2 ; store low count
4533 F89B0C EA nop
4534 F89B0D EA nop
4535 F89B0E 98 tya
4536 F89B0F 8F 95 FD 00 sta >DMAC+DMACNT2 ; store high count
4537 F89B13 EA nop
4538 F89B14 8F 9C FD 00 sta >DMAWCLRFF ; clear F/F
4539 F89B18 EA nop
4540 F89B19 EA nop
4541 F89B1A 8A txa
4542 F89B1B CF 95 FD 00 cmp >DMAC+DMACNT2 ; cmp low count
4543 F89B1F D0 DE bne ?08
4544 F89B21 98 tya
4545 F89B22 CF 95 FD 00 cmp >DMAC+DMACNT2 ; cmp high count
4546 F89B26 D0 D7 bne ?08
4547 F89B28 8F 9C FD 00 sta >DMAWCLRFF ; clear F/F
4548 F89B2C A9 02 lda #$02
4549 F89B2E EA nop
4550 F89B2F EA nop
4551 F89B30 8F 9A FD 00 sta >DMAWMSKB ; un-mask bit channel 2
4552 F89B34 A9 08 lda #$08
4553 F89B36 04 46 tsb fdcctl ; set bit 3
4554 F89B38 58 cli
4555 F89B39 60 rts
4556
4557 ; reset controller FDC after boot or for recovering after error
4558 ; motor status as in current fdcctl bit 4
4559 ; after reset restore flag (bit 6) in fdcctl are set
4560 ; and drive status will be cleared
4561 ; out: CF=1 if error, A=error code
4562 ; fdcctl<6:5> set/reset
4563 ; registers: A&Y destroyed, X preserved
4564 F89B3A fdcrst:
4565 F89B3A 08 php ; save I status
4566 F89B3B 78 sei ; disable interrupt
4567 F89B3C 2C 00 FD bit VIA0+VIAPRB ; reset flag CB1
4568 F89B3F 64 48 stz fdcerr
4569 F89B41 A9 20 lda #$20
4570 F89B43 14 46 trb fdcctl ; reset flag FDC
4571 F89B45 A9 40 lda #$40
4572 F89B47 04 46 tsb fdcctl ; force restore
4573 F89B49 64 44 stz fdcdrv ; invalidate drive
4574 F89B4B A5 46 lda fdcctl
4575 F89B4D 29 10 and #00010000B ; mask on motor bit
4576 F89B4F 09 08 ora #00001000B ; enable FDC interrupt&dma, reset FDC
4577 F89B51 8F DA FD 00 sta >FDCDOR ; reset controller
Tue Jul 17 11:00:16 2018 Page 36
4578 F89B55 EA nop
4579 F89B56 EA nop
4580 F89B57 EA nop
4581 F89B58 EA nop
4582 F89B59 2C 00 FD bit VIA0+VIAPRB ; reset flag CB1
4583 F89B5C EA nop
4584 F89B5D EA nop
4585 F89B5E EA nop
4586 F89B5F EA nop
4587 F89B60 09 0C ora #00001100B ; enable controller
4588 F89B62 8F DA FD 00 sta >FDCDOR ; this write cause interrupt from FDC
4589 F89B66 28 plp ; restore I flag
4590 F89B67 20 20 9C jsr waitint ; wait interrupt within timeout
4591 F89B6A
4592 ; controller reply to sense interrupt command
4593 ; with 4 status bytes: $C0, $C1, $C2, $C3
4594 F89B6A
4595 F89B6A A0 C0 ldy #$C0 ; first expected status
4596 F89B6C A9 08 ?01: lda #CMDSENSEINT
4597 F89B6E 20 9A 9B jsr sendto ; sense interrupt
4598 F89B71 20 D0 9B jsr waitres ; result phase (normally 2 bytes)
4599 F89B74 C4 A4 cpy fdcres ; check first byte result
4600 F89B76 F0 04 beq ?03 ; ok, as expected
4601 F89B78 38 sec ; controller error
4602 F89B79 A9 01 lda #FDC_BAD ; bad controller error
4603 F89B7B 60 rts
4604 F89B7C C8 ?03: iny
4605 F89B7D C0 C4 cpy #$C4 ; last expected result is $C3
4606 F89B7F 90 EB bcc ?01 ; loop
4607 F89B81 A9 20 lda #$20
4608 F89B83 04 46 tsb fdcctl ; flag controller FDC OK
4609 F89B85 A5 46 lda fdcctl
4610 F89B87 20 BB 9C jsr setrate ; select current rate
4611 F89B8A A9 03 lda #CMDSPECIFY
4612 F89B8C 20 9A 9B jsr sendto ; setup standard controller
4613 F89B8F A9 DF lda #UM_SRTHUT
4614 F89B91 20 9A 9B jsr sendto
4615 F89B94 A9 02 lda #UM_HLTND ; send command to FDC
4616
4617 ; like sendto but always return to the caller, even if error
4618 F89B96 sndto2:
4619 F89B96 20 9A 9B jsr sendto
4620 F89B99 60 rts
4621
4622 ; send command to controller within SNDTMO timeout
4623 ; in: A=command
4624 ; out: CF=1 if error, A=error code
4625 ; A,X,Y preserved (if error A will be destroyed)
4626 ; if error, return address from stack will be pulled out and discarded
4627 F89B9A sendto:
4628 F89B9A 85 B9 sta tmpa
4629 F89B9C 20 E8 9D jsr wait16us ; 16uS delay safety
4630 F89B9F A9 20 lda #$20 ; T2 count PB6 pulses (1ms)
4631 F89BA1 0C 0B FD tsb VIA0+VIAACR
4632 F89BA4 A9 D0 lda #<SNDTMO ; timeout send byte
4633 F89BA6 8D 08 FD sta !VIA0+VIAT2CL
4634 F89BA9 A9 07 lda #>SNDTMO
Tue Jul 17 11:00:16 2018 Page 37
4635 F89BAB 8D 09 FD sta !VIA0+VIAT2CH
4636 F89BAE AF DC FD 00 ?02: lda >FDCMSR ; read FDC status
4637 F89BB2 29 C0 and #$C0 ; mask bit 7,6
4638 F89BB4 C9 80 cmp #$80 ; bit 6 will be 0
4639 F89BB6 F0 0D beq ?03 ; FDCcan accept data within timeout
4640 F89BB8 A9 20 lda #T2IFRB
4641 F89BBA 2C 0D FD bit VIA0+VIAIFR ; test timeout
4642 F89BBD F0 EF beq ?02 ; no timeout
4643 F89BBF 68 pla ; pull out return address...
4644 F89BC0 68 pla ; ...and discard it
4645 F89BC1 A9 02 lda #FDC_SNDTOUT ; timeout error
4646 F89BC3 38 sec ; error
4647 F89BC4 60 rts
4648 F89BC5 20 E8 9D ?03: jsr wait16us ; 16uS delay before to access data register
4649 F89BC8 A5 B9 lda tmpa
4650 F89BCA 8F DD FD 00 sta >FDCDATA ; send byte to controller
4651 F89BCE 18 clc
4652 F89BCF 60 rts
4653 F89BD0
4654 ; wait result phase from FDC within RESTMO timeout
4655 ; out: CF=1 if result phase error, A=error code
4656 ; A destroyed, X&Y preserved
4657 ; if error, return address from stack will be pulled out and discarded
4658 F89BD0 waitres:
4659 F89BD0 86 BA stx tmpx ; save X
4660 F89BD2 20 E8 9D jsr wait16us ; safety delay of 16uS
4661 F89BD5 A2 00 ldx #0 ; index for store 7 bytes of result
4662 F89BD7 A9 20 lda #$20 ; T2 count PB6 pulses (1ms)
4663 F89BD9 0C 0B FD tsb VIA0+VIAACR
4664 F89BDC A9 C4 ?00: lda #<RESTMO ; setup result phase timeout
4665 F89BDE 8D 08 FD sta !VIA0+VIAT2CL
4666 F89BE1 A9 09 lda #>RESTMO
4667 F89BE3 8D 09 FD sta !VIA0+VIAT2CH
4668 F89BE6 AF DC FD 00 ?01: lda >FDCMSR ; read status reg. of FDC
4669 F89BEA 29 C0 and #$C0 ; mask bit 7,6
4670 F89BEC C9 C0 cmp #$C0 ; bit 6 will be 1 when CPU can read FDC
4671 F89BEE F0 0F beq ?03 ; data ready within timeout
4672 F89BF0 A9 20 lda #T2IFRB
4673 F89BF2 2C 0D FD bit VIA0+VIAIFR ; test timeout
4674 F89BF5 F0 EF beq ?01 ; no timeout
4675 F89BF7 A9 03 lda #FDC_RESTOUT ; set timeout result phase error
4676 F89BF9 FA ?02: plx ; pull out return address...
4677 F89BFA FA plx ; ...and discard it
4678 F89BFB A6 BA ldx tmpx ; restore X
4679 F89BFD 38 sec ; error
4680 F89BFE 60 rts ; exit
4681 F89BFF 20 E8 9D ?03: jsr wait16us ; 16uS delay before to read data register
4682 F89C02 AF DD FD 00 lda >FDCDATA ; read FDC data register
4683 F89C06 95 A4 sta fdcres,x ; store byte
4684 F89C08 20 E8 9D jsr wait16us ; 16uS delay before to read status register
4685 F89C0B AF DC FD 00 lda >FDCMSR ; test bit 4 (busy)
4686 F89C0F 89 10 bit #00010000B
4687 F89C11 F0 09 beq ?05 ; no more bytes
4688 F89C13 E8 inx
4689 F89C14 E0 07 cpx #7 ; max. 7 bytes in result phase
4690 F89C16 90 C4 bcc ?00 ; loop next byte
4691 F89C18 A9 05 lda #FDC_BADRES ; too many bytes
Tue Jul 17 11:00:16 2018 Page 38
4692 F89C1A D0 DD bne ?02 ; error
4693 F89C1C A6 BA ?05: ldx tmpx
4694 F89C1E 18 clc ; OK
4695 F89C1F 60 rts
4696
4697 ; wait interrupt from UM8388 within INTTMO timeout
4698 ; out: CF=1 if timeout error, A=error code
4699 ; A destroyed, X&Y preserved
4700 ; if error, return address from stack will be pulled out and discarded
4701 F89C20 waitint:
4702 F89C20 A9 20 lda #$20 ; T2 count PB6 pulses (1ms)
4703 F89C22 0C 0B FD tsb VIA0+VIAACR
4704 F89C25 A9 C4 lda #<INTTMO ; interrupt timeout
4705 F89C27 8D 08 FD sta !VIA0+VIAT2CL
4706 F89C2A A9 09 lda #>INTTMO
4707 F89C2C 8D 09 FD sta !VIA0+VIAT2CH
4708 F89C2F AF 0D FD 00 ?02: lda >VIA0+VIAIFR
4709 F89C33 89 10 bit #CB1IFRB ; CB1 -> positive edge INT from FDC
4710 F89C35 D0 0C bne ?04 ; INT within timeout
4711
4712 F89C37 89 20 bit #T2IFRB ; test timeout
4713 F89C39 F0 F4 beq ?02 ; no timeout
4714 F89C3B 38 sec ; error
4715 F89C3C 68 pla ; pull out return address...
4716 F89C3D 68 pla ; ...and discard it
4717 F89C3E A9 04 lda #FDC_INTTOUT ; set timeout error
4718 F89C40 85 FE sta $fe
4719 F89C42
4720 F89C42 60 rts
4721 F89C43 2C 00 FD ?04: bit VIA0+VIAPRB ; clear flag CB1
4722 F89C46 A9 02 lda #$02 ; enable CPU bus
4723 F89C48 0C 0F FD tsb VIA0+VIAPRANH ; PA1 -> /DME = 1
4724 F89C4B A9 08 lda #$08
4725 F89C4D 14 46 trb fdcctl ; reset dma active bit
4726 F89C4F 18 clc ; no error
4727 F89C50
4728 F89C50 60 rts
4729
4730 F89C51 chkres3:
4731 F89C51 20 57 9C jsr waitint3
4732 F89C54 4C 62 99 jmp chkres2
4733
4734 F89C57 waitint3:
4735 F89C57 A9 10 lda #CB1IFRB
4736 F89C59 8D CD FD sta !VIA3+VIAIFR
4737 F89C5C 64 F4 stz <$f4
4738 F89C5E 64 F5 stz <$f5
4739 F89C60 64 F6 stz <$f6
4740 F89C62 64 F7 stz <$f7
4741 F89C64 A2 00 ldx #0
4742 F89C66 9B txy
4743 F89C67 A9 10 lda #$10
4744 F89C69 0C CC FD tsb VIA3+VIAPCR
4745 F89C6C 78 sei
4746 F89C6D INDEX16
4747 F89C6D C2 10 rep #PXFLAG
4748 .LONGI on
Tue Jul 17 11:00:16 2018 Page 39
4749 .MNLIST
4750 F89C6F ?02:
4751 F89C6F A9 10 lda #CB1IFRB
4752 F89C71 ?03:
4753 F89C71 2C CD FD bit !VIA3+VIAIFR
4754 F89C74 F0 04 beq ?04
4755 F89C76 2C C0 FD bit !VIA3+VIAPRB
4756 F89C79 C8 iny
4757
4758 F89C7A ?04:
4759 F89C7A 2C 0D FD bit !VIA0+VIAIFR
4760 ;bit #CB1IFRB ; CB1 -> positive edge INT from FDC
4761 F89C7D F0 F2 beq ?03
4762
4763 ;bne ?10 ; INT within timeout
4764
4765 ;bit !VIA3+VIAIFR
4766 ;beq ?03
4767 ;bit !VIA3+VIAPRB
4768 ;iny
4769 ;bra ?03
4770
4771 F89C7F 2C 00 FD ?10: bit VIA0+VIAPRB ; clear flag CB1
4772
4773 F89C82 A2 00 00 ldx #$00
4774 F89C85 ?11:
4775 F89C85 2C CD FD bit !VIA3+VIAIFR
4776 F89C88 F0 04 beq ?11a
4777 F89C8A 2C C0 FD bit !VIA3+VIAPRB
4778 F89C8D C8 iny
4779
4780 F89C8E ?11a:
4781 F89C8E CA dex
4782 F89C8F D0 F4 bne ?11
4783
4784 F89C91 A2 00 00 ldx #$00
4785 F89C94 ?11c:
4786 F89C94 2C CD FD bit !VIA3+VIAIFR
4787 F89C97 F0 04 beq ?11d
4788 F89C99 2C C0 FD bit !VIA3+VIAPRB
4789 F89C9C C8 iny
4790
4791 F89C9D ?11d:
4792 F89C9D CA dex
4793 F89C9E D0 F4 bne ?11c
4794 F89CA0
4795 F89CA0 A9 02 lda #$02 ; enable CPU bus
4796 F89CA2 0C 0F FD tsb VIA0+VIAPRANH ; PA1 -> /DME = 1
4797 F89CA5 A9 08 lda #$08
4798 F89CA7 14 46 trb fdcctl ; reset dma active bit
4799 F89CA9 18 clc ; no error
4800
4801 F89CAA 2C CD FD bit !VIA3+VIAIFR
4802 F89CAD F0 04 beq ?12
4803 F89CAF 2C C0 FD bit !VIA3+VIAPRB
4804 F89CB2 C8 iny
4805 F89CB3 ?12:
Tue Jul 17 11:00:16 2018 Page 40
4806 F89CB3
4807 F89CB3 86 F4 stx <$f4
4808 F89CB5 84 F6 sty <$f6
4809 F89CB7 INDEX08
4810 F89CB7 E2 10 sep #PXFLAG
4811 .LONGI off
4812 .MNLIST
4813 F89CB9 58 cli
4814 F89CBA 60 rts
4815
4816 ; setup clock rate in controller
4817 ; in: A=$00(DD),=$02(HD)
4818 ; A destroyed, X&Y preserved
4819 F89CBB setrate:
4820 F89CBB 29 02 and #00000010B ; mask bit 1
4821 F89CBD F0 06 beq ?02 ; select DD
4822 F89CBF 04 46 tsb fdcctl ; select HD
4823 F89CC1 A9 00 lda #0 ; rate 500Kb/s
4824 F89CC3 F0 04 beq ?04 ; set rate
4825 F89CC5 A9 02 ?02: lda #00000010B ; rate 250Kb/s
4826 F89CC7 14 46 trb fdcctl
4827 F89CC9 8F DF FD 00 ?04: sta >FDCCCR ; set rate
4828 F89CCD 60 rts
4829
4830 ; enable motor and wait for spin-up timer expiration
4831 ; A destroyed, X&Y preserved
4832 F89CCE startmtr:
4833 F89CCE 78 sei ; disable IRQ
4834 F89CCF A9 30 lda #00110000B ; CNT0 mode 0 - 2 bytes
4835 F89CD1 8D 4B FD sta !CTC0+CTCCTRL ; CTC 0 stopped
4836 F89CD4 A9 08 lda #CB2IFRB ; spin-down timer stopped
4837 F89CD6 8D 0E FD sta VIA0+VIAIER ; clear IRQ CB2 (TMF0) from CNT0 CTC
4838 F89CD9 8D 0D FD sta VIA0+VIAIFR ; clear flag CB2
4839 F89CDC A9 10 lda #00010000B ; motor already on?
4840 F89CDE 24 46 bit fdcctl
4841 F89CE0 F0 02 beq ?04 ; no, put on
4842 F89CE2 58 cli ; yes - exit
4843 F89CE3 60 rts
4844 F89CE4 04 46 ?04: tsb fdcctl ; flag motor on
4845 F89CE6 09 0C ora #00001100B ; enable controller,IRQ,DMA,drive0
4846 F89CE8 8F DA FD 00 sta >FDCDOR ; select drive and motor
4847 F89CEC 58 cli
4848 F89CED A9 20 lda #$20 ; T2 count PB6 pulses (1ms)
4849 F89CEF 0C 0B FD tsb VIA0+VIAACR
4850 F89CF2 A9 B6 lda #<MOTACL ; spin-up delay
4851 F89CF4 8D 08 FD sta !VIA0+VIAT2CL
4852 F89CF7 A9 03 lda #>MOTACL
4853 F89CF9 8D 09 FD sta !VIA0+VIAT2CH
4854 F89CFC ?06: TASKSW ; task switch while wait timer expiration
4855 F89CFC 02 00 cop FN_TASKSW
4856 F89CFE 00 .DB $00
4857 .MNLIST
4858 F89CFF AD 0D FD lda !VIA0+VIAIFR ; loop spin-up
4859 F89D02 89 20 bit #T2IFRB
4860 F89D04 F0 F6 beq ?06
4861 F89D06 60 rts
4862 F89D07
Tue Jul 17 11:00:16 2018 Page 41
4863 ; set up motor spin-down timer
4864 ; this routine preserve CF
4865 ; A&X&Y preserved
4866 F89D07 stopmtr:
4867 F89D07 78 sei ; disable IRQ
4868 F89D08 A5 46 lda fdcctl
4869 F89D0A 89 10 bit #00010000B ; motor bit
4870 F89D0C F0 1C beq ?10 ; motor already off
4871 ; motor on -> setup spin-down timer
4872 F89D0E A9 30 lda #00110000B ; CNT0 mode 0 - 2 bytes
4873 F89D10 8D 4B FD sta !CTC0+CTCCTRL ; CTC 0 stopped
4874 F89D13 A9 08 lda #CB2IFRB
4875 F89D15 8D 0E FD sta !VIA0+VIAIER ; clear IRQ CB2 (TMF0) from CNT0
4876 F89D18 8D 0D FD sta !VIA0+VIAIFR ; clear flag CB2
4877 F89D1B A9 28 lda #<MOTDCL ; setup spin-down timer
4878 F89D1D 8D 48 FD sta !CTC0 ; CNT0
4879 F89D20 A9 0A lda #>MOTDCL
4880 F89D22 8D 48 FD sta !CTC0
4881 F89D25 A9 88 lda #(CB2IFRB.OR.$80)
4882 F89D27 8D 0E FD sta !VIA0+VIAIER ; enable interrupt on CB2
4883 F89D2A 58 ?10: cli
4884 F89D2B 60 rts
4885
4886 ; move dma buffer to safe area while verify data
4887 F89D2C savebuf:
4888 F89D2C A5 A3 lda verfp+2 ; the source bank
4889 F89D2E 8F 3F 9D F8 sta ?10+2 ; store source bank for mvn istruction
4890 F89D32 8B phb ; save data bank
4891 F89D33 CPU16
4892 F89D33 C2 30 rep #(PMFLAG.OR.PXFLAG)
4893 .LONGA on
4894 .LONGI on
4895 .MNLIST
4896 F89D35 A5 94 lda ncnt
4897 F89D37 3A dec a ; count #
4898 F89D38 A6 A1 ldx verfp ; source address
4899 F89D3A A0 00 40 ldy #!DMASAVE ; dest address
4900 F89D3D 54 01 00 ?10: mvn #0,#1 ; move to bank 1
4901 F89D40 CPU08
4902 F89D40 E2 30 sep #(PMFLAG.OR.PXFLAG)
4903 .LONGA off
4904 .LONGI off
4905 .MNLIST
4906 F89D42 AB plb ; restore data bank
4907 F89D43 60 rts
4908
4909 ; restore dma buffer from safe area
4910 F89D44 restbuf:
4911 F89D44 08 php ; save carry
4912 F89D45 48 pha ; save error code if any
4913 F89D46 A5 A3 lda verfp+2 ; the source bank
4914 F89D48 8F 58 9D F8 sta ?10+1 ; store dest bank for mvn istruction
4915 F89D4C 8B phb ; save data bank
4916 F89D4D CPU16
4917 F89D4D C2 30 rep #(PMFLAG.OR.PXFLAG)
4918 .LONGA on
4919 .LONGI on
Tue Jul 17 11:00:16 2018 Page 42
4920 .MNLIST
4921 F89D4F A5 94 lda ncnt
4922 F89D51 3A dec a ; count #
4923 F89D52 A2 00 40 ldx #!DMASAVE ; source address
4924 F89D55 A4 A1 ldy verfp ; dest address
4925 F89D57 54 00 01 ?10: mvn #1,#0 ; move from bank 1
4926 F89D5A CPU08
4927 F89D5A E2 30 sep #(PMFLAG.OR.PXFLAG)
4928 .LONGA off
4929 .LONGI off
4930 .MNLIST
4931 F89D5C AB plb ; restore data bank
4932 F89D5D 68 pla
4933 F89D5E 28 plp
4934 F89D5F 60 rts
4935
4936 ; check params for read/write
4937 ; out: CF=1 if error, A=error code
4938 F89D60 chkparms:
4939 F89D60 64 9E stz bufp ; always aligned at 512 bytes
4940 F89D62 64 A1 stz verfp
4941 F89D64 A9 FF lda #$FF
4942 F89D66 85 9B sta dtlstp ; standard for disk r/w
4943 F89D68 A6 B4 ldx fdop ; operation index
4944 F89D6A BF B7 A0 F8 lda >VDOPTAB,x
4945 F89D6E 85 B5 sta vdop ; ram disk operation
4946 F89D70 30 04 bmi ?02 ; write operation
4947 F89D72 A9 80 lda #$80
4948 F89D74 14 B6 trb opfg ; no verify for read
4949 F89D76 A6 B7 ?02: ldx dskfmt
4950 F89D78 BF A1 A0 F8 lda >MAXSECT,x
4951 F89D7C 85 B0 sta maxsect ; max. number of sectors/track + 1
4952 F89D7E A5 B6 lda opfg ; test required format
4953 F89D80 45 B7 eor dskfmt ; compare bit 0
4954 F89D82 29 01 and #$01 ; they will be the same
4955 F89D84 D0 56 bne ?20 ; mismatch format
4956 F89D86 24 B6 bit opfg ; test MT operation
4957 F89D88 50 0B bvc ?04 ; no MT
4958 F89D8A 64 AD stz head ; MT -> start head = 0
4959 F89D8C A2 01 ldx #1 ; MT -> start sector = 1
4960 F89D8E 86 AE stx sector
4961 F89D90 A6 B0 ldx maxsect ; MT -> SectNum = max. sectors
4962 F89D92 CA dex
4963 F89D93 86 AF stx sectnum
4964 F89D95 A5 AE ?04: lda sector ; start sector will be < MaxSect
4965 F89D97 C5 B0 cmp maxsect
4966 F89D99 B0 45 bcs ?22
4967 F89D9B A5 AF lda sectnum ; here CF = 0
4968 F89D9D A8 tay
4969 F89D9E 3A dec a ; SectNum - 1
4970 F89D9F 65 AE adc sector ; EOT = end of track
4971 F89DA1 B0 3D bcs ?22 ; overflow
4972 F89DA3 C5 B0 cmp maxsect
4973 F89DA5 B0 39 bcs ?22 ; EOT > (MaxSect - 1)
4974 F89DA7 85 B1 sta eot ; end of track
4975 F89DA9 98 tya ; number of sectors
4976 F89DAA 24 B6 bit opfg
Tue Jul 17 11:00:16 2018 Page 43
4977 F89DAC 50 02 bvc ?08 ; no MT
4978 F89DAE 0A asl a ; MT -> double number of sectors
4979 F89DAF A8 tay
4980 F89DB0 0A ?08: asl a ; number of pages of 256 bytes - here CF = 0
4981 F89DB1 85 95 sta ncnt+1 ; number of bytes to be trasferred
4982 F89DB3 64 94 stz ncnt
4983 F89DB5 84 9D sty bufcnt ; number of required dma buffers
4984 F89DB7 A5 9C lda dmabuf ; test buffer dma
4985 F89DB9 A8 tay
4986 F89DBA 29 7F and #$7F ; mask off bit 7
4987 F89DBC AA tax
4988 F89DBD 65 9D adc bufcnt ; here never carry
4989 F89DBF C9 81 cmp #$81 ; over the limit of the bank?
4990 F89DC1 B0 21 bcs ?24 ; yes
4991 F89DC3 8A txa
4992 F89DC4 0A asl a ; high byte of address of the buffer
4993 F89DC5 85 9F sta bufp+1 ; verfp and bufp equal but in opposite bank
4994 F89DC7 85 A2 sta verfp+1
4995 F89DC9 A2 02 ldx #BUFDSK1 ; bank of buffer #0..#127
4996 F89DCB 98 tya
4997 F89DCC 10 01 bpl ?12
4998 F89DCE E8 inx ; bank of buffer #128..#255
4999 F89DCF 86 A0 ?12: stx bufp+2
5000 F89DD1 A0 02 ldy #BUFDSK1 ; bank of verify buffer
5001 F89DD3 E0 03 cpx #BUFDSK2 ; always different from other buffer
5002 F89DD5 F0 01 beq ?16
5003 F89DD7 C8 iny
5004 F89DD8 84 A3 ?16: sty verfp+2
5005 F89DDA 18 clc
5006 F89DDB 60 rts
5007 F89DDC A9 0F ?20: lda #FDC_FMT ; format mismatch
5008 F89DDE 38 sec
5009 F89DDF 60 rts
5010 F89DE0 A9 14 ?22: lda #FDC_PARAMS ; invalid params
5011 F89DE2 38 sec
5012 F89DE3 60 rts
5013 F89DE4 A9 13 ?24: lda #FDC_BADBUF ; invalid buffer
5014 F89DE6 38 sec
5015 F89DE7 60 rts
5016
5017 ; 16us delay for safe access to FDC register's
5018 F89DE8 wait16us:
5019
5020 [01] .IF PHI2 = 4
5021 000009 ??CNT .EQU 9
5022 [01] .ELSE
5023 ??CNT .EQU 5
5024 [00] .ENDIF
5025
5026 ; #cycles = 5*N + 13 + M(2 * nop) = 64/32 cycles
5027 ; 4MHz -> N = 9, M = 6
5028 ; 2MHz -> N = 5, M = 4
5029
5030 F89DE8 A9 09 lda #??CNT
5031 F89DEA 3A ?01: dec a
5032 F89DEB D0 FD bne ?01
5033 [01] .IF PHI2 = 4
Tue Jul 17 11:00:16 2018 Page 44
5034 F89DED EA nop
5035 [00] .ENDIF
5036 F89DEE EA nop
5037 F89DEF EA nop
5038 F89DF0 60 rts
5039
5040 ;---------------------------------------------------------------------------
5041 ; ram disk managment
5042 ;---------------------------------------------------------------------------
5043
5044 ; ram disk format whole disk (X = drive)
5045 ; always return CF=0
5046 ; any time ram disk is formatted, change disk bit (bit 6) is set
5047 F89DF1 vdfmt:
5048 F89DF1 A5 45 lda vdrive
5049 F89DF3 89 10 bit #$10 ; ram disk write protect on?
5050 F89DF5 F0 06 beq ?01 ; no
5051 F89DF7 A9 0B lda #FDC_WP ; wp on error
5052 F89DF9 85 48 sta fdcerr
5053 F89DFB 38 sec
5054 F89DFC 60 rts
5055 F89DFD 29 7C ?01: and #01111100B ; reset format
5056 F89DFF 85 45 sta vdrive
5057 F89E01 A9 01 lda #$01 ; reset bit 0
5058 F89E03 14 B6 trb fmtfg ; for first call to callback
5059 F89E05 A9 01 lda #XMBANK ; bank that old X mem
5060 F89E07 85 A0 sta bufp+2
5061 F89E09 AE 0A FC ldx CRXME ; save X mem setting
5062 F89E0C DA phx
5063 F89E0D 8D 0B FC sta !CRXMEON ; enable X mem in window $012000 - $013FFF
5064 F89E10 A0 00 ldy #0 ; start track
5065 F89E12 BB tyx ; start head
5066 F89E13 84 AC ?02: sty track ; format this track...
5067 F89E15 86 AD ?04: stx head ; ...in this side
5068 F89E17 20 72 9F jsr getlba ; set ram disk address
5069 F89E1A 8D 28 FD sta !PIA0+PIAPRA ; set ram disk bank
5070 F89E1D 24 B6 bit fmtfg
5071 F89E1F 10 13 bpl ?06 ; no callback
5072 F89E21 4B phk ; JSL simulation
5073 F89E22 F4 33 9E pea #?06-1 ; return address
5074 F89E25 A5 B1 lda eot ; params for callback
5075 F89E27 EB xba ; B = sector/track
5076 F89E28 A5 B6 lda fmtfg
5077 F89E2A 4A lsr a ; bit 0 -> carry -> 0 if first call
5078 F89E2B A9 01 lda #1 ; A = drive
5079 F89E2D A4 AC ldy track ; Y = track
5080 F89E2F A6 AD ldx head ; X = head
5081 F89E31 DC A1 00 jmp [lpfn]
5082 ?06: ; return from callback
5083 F89E34 A6 AF ldx sectnum ; number of sector per track
5084 F89E36 INDEX16
5085 F89E36 C2 10 rep #PXFLAG
5086 .LONGI on
5087 .MNLIST
5088 F89E38 A4 98 ldy xmstart ; start address of X mem
5089 F89E3A 84 9E ?08: sty bufp ; sector's loop
5090 F89E3C A5 B8 lda fmtfill ; fill byte
Tue Jul 17 11:00:16 2018 Page 45
5091 F89E3E A0 FF 01 ldy #$01FF ; size of sector
5092 F89E41 97 9E ?10: sta [bufp],y ; fill one sector
5093 F89E43 88 dey
5094 F89E44 10 FB bpl ?10
5095 F89E46 CA dex
5096 F89E47 F0 17 beq ?12 ; end sector's loop
5097 F89E49 CPU16CLC
5098 F89E49 C2 31 rep #(PMFLAG.OR.PXFLAG.OR.PCFLAG)
5099 .LONGA on
5100 .LONGI on
5101 .MNLIST
5102 F89E4B A5 9E lda bufp
5103 F89E4D 69 00 02 adc #$0200 ; next sector pointer
5104 F89E50 A8 tay
5105 F89E51 ACC08
5106 F89E51 E2 20 sep #PMFLAG
5107 .LONGA off
5108 .MNLIST
5109 F89E53 C0 00 40 cpy #XMSTOP ; end of X mem
5110 F89E56 90 E2 bcc ?08 ; fill next block
5111 F89E58 EE 28 FD inc !PIA0+PIAPRA ; increment X mem bank
5112 F89E5B A0 00 20 ldy #XMSTART ; start address of X mem
5113 F89E5E 80 DA bra ?08 ; fill next block
5114 F89E60 ?12: INDEX08
5115 F89E60 E2 10 sep #PXFLAG
5116 .LONGI off
5117 .MNLIST
5118 F89E62 A9 01 lda #$01
5119 F89E64 04 B6 tsb fmtfg ; bit 0 = 1 -> for callback
5120 F89E66 A6 AD ldx head ; next side
5121 F89E68 E8 inx
5122 F89E69 E0 02 cpx #2
5123 F89E6B 90 A8 bcc ?04 ; same track, next side
5124 F89E6D A2 00 ldx #0 ; clear head
5125 F89E6F A4 AC ldy track ; next track
5126 F89E71 C8 iny
5127 F89E72 C0 50 cpy #80
5128 F89E74 90 9D bcc ?02 ; next track, side=0
5129 F89E76 A5 45 lda vdrive ; set valid format
5130 F89E78 29 7C and #01111100B
5131 F89E7A 05 B7 ora dskfmt ; update format in selected drive
5132 F89E7C 09 C0 ora #$C0 ; current valid format
5133 F89E7E 85 45 sta vdrive ; set bit 6: change disk
5134 F89E80 FA plx ; restore X mem setting
5135 F89E81 9D 0A FC sta !CRXME,x
5136 F89E84 A2 3E ldx #RTCRDFG ; validate ram disk configuration
5137 F89E86 8E 4C FD stx RTCALE
5138 F89E89 A9 55 lda #$55
5139 F89E8B 8D 4D FD sta RTCDATA
5140 F89E8E E8 inx ; save configuration in RTC ram
5141 F89E8F 8E 4C FD stx RTCALE
5142 F89E92 A5 45 lda vdrive
5143 F89E94 8D 4D FD sta RTCDATA ; save ram disk
5144 F89E97 18 clc
5145 F89E98 60 rts
5146
5147 ; execute read/write on ram disk
Tue Jul 17 11:00:16 2018 Page 46
5148 ; in: vdop=command ($00=read, $80=write, $40=fake verify)
5149 ; opfg<7>=1 if read verify buffer
5150 ; out: CF=1 if error (just verify error in ram disk)
5151 ; A,X,Y destroyed
5152 F89E99 vdrw:
5153 F89E99 20 60 9D jsr chkparms ; check params
5154 F89E9C 90 03 bcc ?02 ; ok
5155 F89E9E 85 48 ?01: sta fdcerr
5156 F89EA0 60 rts ; return error
5157 F89EA1 24 B5 ?02: bit vdop ; write operation?
5158 F89EA3 10 0B bpl ?04 ; no
5159 F89EA5 A9 10 lda #$10
5160 F89EA7 24 45 bit vdrive ; write protect?
5161 F89EA9 F0 05 beq ?04 ; no
5162 F89EAB A9 0B lda #FDC_WP ; yes...
5163 F89EAD 38 sec ; ...error
5164 F89EAE 80 EE bra ?01
5165 F89EB0 24 B6 ?04: bit opfg ; verify buffer?
5166 F89EB2 10 03 bpl ?06 ; no
5167 F89EB4 20 2C 9D jsr savebuf ; save verify buffer
5168 F89EB7 20 72 9F ?06: jsr getlba ; set ram disk address
5169 F89EBA 8D 28 FD sta !PIA0+PIAPRA ; set ram disk bank
5170 F89EBD 64 B2 stz buftst ; now using bufp buffer
5171 F89EBF 20 EE 9E jsr vdcmd ; execute command (here always CF = 0)
5172 F89EC2 A5 B6 lda opfg
5173 F89EC4 10 27 bpl ?20 ; no verify, exit
5174 F89EC6 85 B2 sta buftst ; now using verfp buffer
5175 F89EC8 64 B5 stz vdop ; read for verify
5176 F89ECA A5 BB lda xmbank
5177 F89ECC 8D 28 FD sta !PIA0+PIAPRA ; set ram disk bank
5178 F89ECF 20 EE 9E jsr vdcmd ; execute command
5179 F89ED2 A0 00 ldy #0 ; verify data
5180 F89ED4 INDEX16
5181 F89ED4 C2 10 rep #PXFLAG
5182 .LONGI on
5183 .MNLIST
5184 F89ED6 B7 9E ?08: lda [bufp],y
5185 F89ED8 D7 A1 cmp [verfp],y
5186 F89EDA D0 05 bne ?10 ; unmatch: ZF=0
5187 F89EDC C8 iny
5188 F89EDD C4 94 cpy ncnt
5189 F89EDF 90 F5 bcc ?08 ; when finish ZF=1
5190 F89EE1 ?10: INDEX08 ; here ZF=1 if match
5191 F89EE1 E2 10 sep #PXFLAG
5192 .LONGI off
5193 .MNLIST
5194 F89EE3 18 clc ; assume no error
5195 F89EE4 F0 04 beq ?12
5196 F89EE6 A9 12 lda #FDC_VER ; verify error
5197 F89EE8 85 48 sta fdcerr
5198 F89EEA 20 44 9D ?12: jsr restbuf ; restore verify buffer
5199 F89EED 60 ?20: rts
5200
5201 ; ram disk read/write command
5202 ; in: vdop=command ($00=read, $80=write, $40=fake verify)
5203 ; buftst=0 if using bufp, =$80 if using verfp
5204 ; out: CF=0 always
Tue Jul 17 11:00:16 2018 Page 47
5205 ; A,X,Y destroyed
5206 F89EEE vdcmd:
5207 F89EEE AE 0A FC ldx .ABS.CRXME ; save X mem setting
5208 F89EF1 DA phx
5209 F89EF2 8D 0B FC sta !CRXMEON ; enable X mem in window $012000 - $013FFF
5210 F89EF5 INDEX16
5211 F89EF5 C2 10 rep #PXFLAG
5212 .LONGI on
5213 .MNLIST
5214 F89EF7 A4 94 ldy ncnt
5215 F89EF9 24 B5 bit vdop ; fake verify operation?
5216 F89EFB 70 6B bvs ?24 ; yes, no operation in ram disk
5217 F89EFD A6 9E ldx bufp ; buffer start for read/write
5218 F89EFF A5 A0 lda bufp+2
5219 F89F01 24 B2 bit buftst ; read verify buffer?
5220 F89F03 10 04 bpl ?02 ; no, so use bufp buffer
5221 F89F05 A6 A1 ldx verfp ; yes, so use verfp verify buffer
5222 F89F07 A5 A3 lda verfp+2
5223 F89F09 86 9A ?02: stx bufstart ; set start buffer for ram disk access
5224 F89F0B 85 B9 sta tmpa ; source or dest bank
5225 F89F0D ACC16CLC ; calc end of transfer buffer
5226 F89F0D C2 21 rep #(PMFLAG.OR.PCFLAG)
5227 .LONGA on
5228 .MNLIST
5229 F89F0F 98 tya ; count #
5230 F89F10 65 9A adc bufstart
5231 F89F12 85 9C sta bufend ; end address of transfer
5232 F89F14 ACC08
5233 F89F14 E2 20 sep #PMFLAG
5234 .LONGA off
5235 .MNLIST
5236 F89F16 A9 FF lda #$FF
5237 F89F18 EB xba ; B = $FF
5238 F89F19 24 B5 bit vdop ; check read/write flag
5239 F89F1B 10 24 bpl ?14 ; read operation
5240 ; write operation
5241 F89F1D A5 B9 lda tmpa ; the source bank
5242 F89F1F 8F 2D 9F F8 sta ?10+2 ; store source bank for mvn istruction
5243 F89F23 A6 9A ldx bufstart ; start address of source block
5244 F89F25 8B phb ; save current danta bank
5245 F89F26 A4 98 ldy xmstart ; start address of current h&t&&s
5246 F89F28 A9 01 ?08: lda #$01 ; size of block - 1 (512 bytes)
5247 F89F2A EB xba ; before B = $FF, A = $01 -> C = $01FF
5248 F89F2B 54 01 00 ?10: mvn #0,#1 ; move sector from bank 2 or 3 to bank 1
5249 F89F2E E4 9C cpx bufend ; X point past the last moved byte
5250 F89F30 B0 33 bcs ?22 ; end of move
5251 F89F32 C0 00 40 cpy #XMSTOP ; end of X mem?
5252 F89F35 90 F1 bcc ?08 ; no, move next block
5253 F89F37 AB plb ; restore data bank
5254 F89F38 EE 28 FD inc PIA0+PIAPRA ; increment X mem bank
5255 F89F3B 8B phb ; save current danta bank
5256 F89F3C A0 00 20 ldy #XMSTART ; start address from beginning of X mem
5257 F89F3F 80 E7 bra ?08 ; move next block
5258 ?14: ; read operation
5259 F89F41 A5 B9 lda tmpa ; dest bank
5260 F89F43 A4 9A ldy bufstart ; start address of dest. block
5261 F89F45 8F 50 9F F8 sta ?20+1 ; store dest. bank for mvn istruction
Tue Jul 17 11:00:16 2018 Page 48
5262 F89F49 8B phb ; save current danta bank
5263 F89F4A A6 98 ldx xmstart ; start address of current h&t&s
5264 F89F4C A9 01 ?18: lda #$01 ; size of block - 1 (512 bytes)
5265 F89F4E EB xba ; before B = $FF, A = $01 -> C = $01FF
5266 F89F4F 54 00 01 ?20: mvn #1,#0 ; move sector from bank 1 to bank 2 or 3
5267 F89F52 C4 9C cpy bufend ; Y point past the last moved byte
5268 F89F54 B0 0F bcs ?22 ; end of move
5269 F89F56 E0 00 40 cpx #XMSTOP ; end of X mem?
5270 F89F59 90 F1 bcc ?18 ; no, move next block
5271 F89F5B AB plb ; restore data bank
5272 F89F5C EE 28 FD inc PIA0+PIAPRA ; increment X mem bank
5273 F89F5F 8B phb
5274 F89F60 A2 00 20 ldx #XMSTART ; start address from beginning of X mem
5275 F89F63 80 E7 bra ?18 ; move next block
5276 F89F65 AB ?22: plb ; restore data bank
5277 F89F66 A4 94 ldy ncnt
5278 F89F68 84 96 ?24: sty ntrsf ; store numbers of moved bytes
5279 F89F6A INDEX08
5280 F89F6A E2 10 sep #PXFLAG
5281 .LONGI off
5282 .MNLIST
5283 F89F6C FA plx ; restore X mem setting
5284 F89F6D 9D 0A FC sta !CRXME,x
5285 F89F70 18 clc
5286 F89F71 60 rts
5287 F89F72
5288 ; translate the tuplet (T,H,S) into LBA (Linear Block Address)
5289 ; LBA = [(2*track + head)]*P + sector - 1
5290 ; where P = sectors/track
5291 F89F72 getlba:
5292 F89F72 20 96 9F jsr lbabase ; get LBA base
5293 F89F75 A6 AE ldx sector
5294 F89F77 86 B9 stx mcand1 ; store S in word
5295 F89F79 64 BA stz mcand2
5296 F89F7B ACC16CLC ; A/M 16 bit + CLC
5297 F89F7B C2 21 rep #(PMFLAG.OR.PCFLAG)
5298 .LONGA on
5299 .MNLIST
5300 F89F7D 65 B9 adc mcand1
5301 F89F7F 3A dec a ; LBA
5302 F89F80 6A ror a ; divide by 16 to get xmem bank
5303 F89F81 6A ror a
5304 F89F82 6A ror a
5305 F89F83 6A ror a
5306 F89F84 ACC08
5307 F89F84 E2 20 sep #PMFLAG
5308 .LONGA off
5309 .MNLIST
5310 F89F86 85 BB sta xmbank ; ram disk bank
5311 F89F88 EB xba ; B = bank, A = modulus
5312 F89F89 6A ror a ; shift in last carry
5313 F89F8A 4A lsr a ; calc the modulo
5314 F89F8B 4A lsr a
5315 F89F8C 4A lsr a ; MSB of xmem
5316 F89F8D 18 clc
5317 F89F8E 69 20 adc #>XMSTART ; add the physical start of xmem
5318 F89F90 85 99 sta xmstart+1
Tue Jul 17 11:00:16 2018 Page 49
5319 F89F92 64 98 stz xmstart
5320 F89F94 EB xba ; return in A the ram disk bank
5321 F89F95 60 rts
5322 F89F96
5323 ; get base of Linear Block Address (LBA)
5324 ; LBA = [(2*track + head)]*P + sector - 1
5325 ; where P = sectors/track
5326 ; this function calc the LBA base = [(2*track + head)]*P
5327 ; the result is stored in C
5328 F89F96 lbabase:
5329 F89F96 A5 B0 lda maxsect
5330 F89F98 3A dec a
5331 F89F99 85 B9 sta mcand1 ; multiplicand #1
5332 F89F9B A5 AC lda track
5333 F89F9D 0A asl a ; 2*track (here always CF = 0)
5334 F89F9E 65 AD adc head
5335 F89FA0 85 BA sta mcand2 ; 2*track + head
5336 F89FA2 A9 00 lda #0 ; MSB result of (macnd1 * mcand2)
5337 F89FA4 A2 09 ldx #9 ; loop 9 bit
5338 F89FA6 18 clc
5339 F89FA7 6A ?02: ror a
5340 F89FA8 66 B9 ror mcand1 ; LSB result of multiplication
5341 F89FAA 90 03 bcc ?04
5342 F89FAC 18 clc
5343 F89FAD 65 BA adc mcand2
5344 F89FAF CA ?04: dex
5345 F89FB0 D0 F5 bne ?02
5346 F89FB2 EB xba ; B = MSB of result
5347 F89FB3 A5 B9 lda mcand1 ; A = LSB of result
5348 F89FB5 60 rts ; C = 16 bit result
5349
5350 ;---------------------------------------------------------------------------
5351 ; POST routine
5352 ;---------------------------------------------------------------------------
5353
5354 ; this routine is invoked within boot phase
5355 F89FB6 fdinit:
5356 F89FB6 A9 FB lda #11111011B
5357 F89FB8 14 46 trb fdcctl ; reset all bit's but not dma flag
5358 F89FBA A9 02 lda #00000010B
5359 F89FBC 04 46 tsb fdcctl ; select HD rte at beginning
5360 F89FBE 20 CE 9C jsr startmtr ; start motor
5361 F89FC1 20 3A 9B jsr fdcrst ; reset FDC controller
5362 F89FC4 A9 20 lda #$20 ; test bit 5
5363 F89FC6 24 46 bit fdcctl
5364 F89FC8 F0 37 beq ?100 ; FDC controller fault
5365 F89FCA 20 31 A0 jsr ?110
5366 F89FCD 64 48 stz fdcerr
5367 F89FCF 20 CE 9C jsr startmtr ; start motor
5368 F89FD2 20 95 99 jsr seek0 ; recalibrate after reset and seek track 0
5369 F89FD5 B0 1B bcs ?30 ; fail
5370 F89FD7 A9 80 lda #$80 ; set flag drive ok
5371 F89FD9 04 46 tsb fdcctl
5372 F89FDB
5373 F89FDB SCNPRINT
5374 F89FDB 02 01 cop $01
5375 .MNLIST
Tue Jul 17 11:00:16 2018 Page 50
5376 F89FDD 70 61 73 73 2E .DB 'pass.', $0D, $00
0D 00
5377 F89FE4
5378 F89FE4 AF DF FD 00 lda >FDCDIR ; read disk change line
5379 F89FE8 29 80 and #$80 ; bit 7 will be 0 if disk ready
5380 F89FEA D0 03 bne ?20 ; not ready
5381 F89FEC 20 10 99 jsr chkwp ; aquire wp status
5382 F89FEF 18 ?20: clc
5383 F89FF0 80 0C bra ?32
5384 F89FF2 ?30: SCNPRINT
5385 F89FF2 02 01 cop $01
5386 .MNLIST
5387 F89FF4 66 61 69 6C 2E .DB 'fail.', $0D, $00
0D 00
5388 F89FFB 38 sec
5389 F89FFC 85 48 sta fdcerr
5390 F89FFE 4C 07 9D ?32: jmp stopmtr
5391 F8A001
5392 F8A001 ?100: SCNPRINT
5393 F8A001 02 01 cop $01
5394 .MNLIST
5395 F8A003 45 52 52 4F 52 .DB 'ERROR: diskette controller UM8388 fail', $0D, $00
3A 20 64 69 73
6B 65 74 74 65
20 63 6F 6E 74
72 6F 6C 6C 65
72 20 55 4D 38
33 38 38 20 66
61 69 6C 0D 00
5396 F8A02B TASKSW
5397 F8A02B 02 00 cop FN_TASKSW
5398 F8A02D 00 .DB $00
5399 .MNLIST
5400 F8A02E 4C 07 9D jmp stopmtr ; exit
5401 F8A031
5402 F8A031 ?110: SCNPRINT
5403 F8A031 02 01 cop $01
5404 .MNLIST
5405 F8A033 64 72 69 76 65 .DB 'drive #0...', $00
20 23 30 2E 2E
2E 00
5406 F8A03F 60 rts
5407 F8A040
5408 ; POST routine for initial ram disk configuration
5409 F8A040 vdinit:
5410 F8A040 20 66 A0 jsr ?100
5411 F8A043 A9 40 lda #$40
5412 F8A045 85 45 sta vdrive ; reset unformatted ram disk (disk changed)
5413 F8A047 20 75 A0 jsr ?110
5414 F8A04A 24 0C bit Bnk0Flag ; <6> -> warm reset flag
5415 F8A04C 50 17 bvc ?10 ; cold reset - unformatted
5416 F8A04E A2 3E ldx #RTCRDFG ; resume saved configuration
5417 F8A050 8E 4C FD stx RTCALE ; from RTC RAM in bank 0 & 1
5418 F8A053 AD 4D FD lda RTCDATA ; valid ram disk configuration?
5419 F8A056 C9 55 cmp #$55
5420 F8A058 D0 0B bne ?10 ; no -- make default ram disk
5421 F8A05A E8 inx
Tue Jul 17 11:00:16 2018 Page 51
5422 F8A05B 8E 4C FD stx RTCALE
5423 F8A05E AD 4D FD lda RTCDATA ; get ram disk 0 configuration
5424 F8A061 09 40 ora #$40 ; always disk ghanged at startup
5425 F8A063 85 45 sta vdrive
5426 F8A065 60 ?10: rts
5427
5428 F8A066 ?100: SCNPRINT
5429 F8A066 02 01 cop $01
5430 .MNLIST
5431 F8A068 64 72 69 76 65 .DB 'drive #1...', $00
20 23 31 2E 2E
2E 00
5432 F8A074 60 rts
5433
5434 F8A075 ?110: SCNPRINT
5435 F8A075 02 01 cop $01
5436 .MNLIST
5437 F8A077 76 69 72 74 75 .DB 'virtual drive (ram disk).', $0D, $00
61 6C 20 64 72
69 76 65 20 28
72 61 6D 20 64
69 73 6B 29 2E
0D 00
5438 F8A092 60 rts
5439
5440 ;---------------------------------------------------------------------------
5441 ; Tables
5442 ;---------------------------------------------------------------------------
5443
5444 ; ctl function's table
5445 F8A093 CTLFN:
5446 F8A093 3594 3B94 3E94 .DW ctl_fn0, ctl_fn1, ctl_fn2, ctl_fn3, ctl_fn4
5D94 7B94
5447 F8A09D B194 BD94 .DW ctl_fn5, ctl_fn6
5448
5449 000007 MXCTLFN .EQU ($-CTLFN)/2
5450
5451 ; max. number of secors/track
5452 F8A0A1 MAXSECT
5453 F8A0A1 0A 0B 13 15 .DB 10, 11, 19, 21
5454
5455 ; GAP 3 lenght for rd/wr command
5456 F8A0A5 RWGPLTBL:
5457 F8A0A5 1B 10 36 14 .DB RWGPL3DD, RWGPL3DDA, RWGPL3HD, RWGPL3HDA
5458
5459 ; GAP 3 lenght while format track
5460 F8A0A9 FGPLTBL:
5461 F8A0A9 54 24 6C 32 .DB FMGPL3DD, FMGPL3DDA, FMGPL3HD, FMGPL3HDA
5462 F8A0AD
5463 ; head inversion for MSDOS/CBM format
5464 F8A0AD HEADTBL:
5465 F8A0AD 00 01 00 01 .DB $00, $01, $00, $01
5466
5467 ; commands for UM8388
5468 F8A0B1 CMDTAB:
5469 F8A0B1 66 66 45 .DB CMDREAD, CMDREAD, CMDWRITE
5470 F8A0B4
Tue Jul 17 11:00:16 2018 Page 52
5471 ; transfer command for DMA
5472 F8A0B4 DMATAB:
5473 F8A0B4 46 42 4A .DB WRITETRASF, VERFTRASF, READTRASF
5474 F8A0B7
5475 ; disk operation flag (read, verify, write)
5476 F8A0B7 VDOPTAB:
5477 F8A0B7 00 40 80 .DB $00, $40, $80
5478
5479
5480 F8A0BA testdma:
5481 F8A0BA A2 44 ldx #$44
5482 F8A0BC A0 CC ldy #$CC
5483 F8A0BE 64 F0 stz <$f0
5484 F8A0C0 64 F1 stz <$f1
5485 F8A0C2 64 F2 stz <$f2
5486 F8A0C4 64 F3 stz <$f3
5487 F8A0C6 64 F4 stz <$f4
5488 F8A0C8 64 F5 stz <$f5
5489 F8A0CA 64 F6 stz <$f6
5490 F8A0CC 64 F7 stz <$f7
5491 F8A0CE
5492 F8A0CE 8D 9C FD ?06: sta !DMAWCLRFF ; clear F/F
5493 F8A0D1 E6 F0 inc <$f0
5494 F8A0D3 EA nop
5495 F8A0D4 EA nop
5496 F8A0D5 8A txa
5497 F8A0D6 8D 90 FD sta !DMAC+DMAADDR0 ; store low buffer address
5498 F8A0D9 EA nop
5499 F8A0DA EA nop
5500 F8A0DB 98 tya
5501 F8A0DC 8D 90 FD sta !DMAC+DMAADDR0 ; store high buffer address
5502 F8A0DF EA nop
5503 F8A0E0 8D 9C FD sta !DMAWCLRFF ; clear F/F
5504 F8A0E3 EA nop
5505 F8A0E4 EA nop
5506 F8A0E5 8A txa
5507 F8A0E6 CD 90 FD cmp !DMAC+DMAADDR0 ; cmp low buffer address
5508 F8A0E9 D0 E3 bne ?06
5509 F8A0EB 98 tya
5510 F8A0EC CD 90 FD cmp !DMAC+DMAADDR0 ; cmp high buffer address
5511 F8A0EF D0 DD bne ?06
5512 F8A0F1 A2 5D ldx #$5D ; X=low count
5513 F8A0F3 A0 BF ldy #$BF ; Y=high count
5514 F8A0F5 8D 9C FD ?08: sta !DMAWCLRFF ; clear F/F
5515 F8A0F8 E6 F1 inc <$f1
5516 F8A0FA EA nop
5517 F8A0FB EA nop
5518 F8A0FC 8A txa
5519 F8A0FD 8D 91 FD sta !DMAC+DMACNT0 ; store low count
5520 F8A100 EA nop
5521 F8A101 EA nop
5522 F8A102 98 tya
5523 F8A103 8D 91 FD sta !DMAC+DMACNT0 ; store high count
5524 F8A106 EA nop
5525 F8A107 8D 9C FD sta !DMAWCLRFF ; clear F/F
5526 F8A10A EA nop
5527 F8A10B EA nop
Tue Jul 17 11:00:16 2018 Page 53
5528 F8A10C 8A txa
5529 F8A10D CD 91 FD cmp !DMAC+DMACNT0 ; cmp low count
5530 F8A110 D0 E3 bne ?08
5531 F8A112 98 tya
5532 F8A113 CD 91 FD cmp !DMAC+DMACNT0 ; cmp high count
5533 F8A116 D0 DD bne ?08
5534 F8A118 8D 9C FD sta !DMAWCLRFF ; clear F/F
5535
5536 F8A11B 8D 9C FD ?06a: sta !DMAWCLRFF ; clear F/F
5537 F8A11E E6 F2 inc <$f2
5538 F8A120 EA nop
5539 F8A121 EA nop
5540 F8A122 8A txa
5541 F8A123 8D 92 FD sta !DMAC+DMAADDR1 ; store low buffer address
5542 F8A126 EA nop
5543 F8A127 EA nop
5544 F8A128 98 tya
5545 F8A129 8D 92 FD sta !DMAC+DMAADDR1 ; store high buffer address
5546 F8A12C EA nop
5547 F8A12D 8D 9C FD sta !DMAWCLRFF ; clear F/F
5548 F8A130 EA nop
5549 F8A131 EA nop
5550 F8A132 8A txa
5551 F8A133 CD 92 FD cmp !DMAC+DMAADDR1 ; cmp low buffer address
5552 F8A136 D0 E3 bne ?06a
5553 F8A138 98 tya
5554 F8A139 CD 92 FD cmp !DMAC+DMAADDR1 ; cmp high buffer address
5555 F8A13C D0 DD bne ?06a
5556 F8A13E A2 5D ldx #$5D ; X=low count
5557 F8A140 A0 BF ldy #$BF ; Y=high count
5558 F8A142 8D 9C FD ?08a: sta !DMAWCLRFF ; clear F/F
5559 F8A145 E6 F3 inc <$f3
5560 F8A147 EA nop
5561 F8A148 EA nop
5562 F8A149 8A txa
5563 F8A14A 8D 93 FD sta !DMAC+DMACNT1 ; store low count
5564 F8A14D EA nop
5565 F8A14E EA nop
5566 F8A14F 98 tya
5567 F8A150 8D 93 FD sta !DMAC+DMACNT1 ; store high count
5568 F8A153 EA nop
5569 F8A154 8D 9C FD sta !DMAWCLRFF ; clear F/F
5570 F8A157 EA nop
5571 F8A158 EA nop
5572 F8A159 8A txa
5573 F8A15A CD 93 FD cmp !DMAC+DMACNT1 ; cmp low count
5574 F8A15D D0 E3 bne ?08a
5575 F8A15F 98 tya
5576 F8A160 CD 93 FD cmp !DMAC+DMACNT1 ; cmp high count
5577 F8A163 D0 DD bne ?08a
5578 F8A165 8D 9C FD sta !DMAWCLRFF ; clear F/F
5579
5580 F8A168 8D 9C FD ?06b: sta !DMAWCLRFF ; clear F/F
5581 F8A16B E6 F4 inc <$f4
5582 F8A16D EA nop
5583 F8A16E EA nop
5584 F8A16F 8A txa
Tue Jul 17 11:00:16 2018 Page 54
5585 F8A170 8D 94 FD sta !DMAC+DMAADDR2 ; store low buffer address
5586 F8A173 EA nop
5587 F8A174 EA nop
5588 F8A175 98 tya
5589 F8A176 8D 94 FD sta !DMAC+DMAADDR2 ; store high buffer address
5590 F8A179 EA nop
5591 F8A17A 8D 9C FD sta !DMAWCLRFF ; clear F/F
5592 F8A17D EA nop
5593 F8A17E EA nop
5594 F8A17F 8A txa
5595 F8A180 CD 94 FD cmp !DMAC+DMAADDR2 ; cmp low buffer address
5596 F8A183 D0 E3 bne ?06b
5597 F8A185 98 tya
5598 F8A186 CD 94 FD cmp !DMAC+DMAADDR2 ; cmp high buffer address
5599 F8A189 D0 DD bne ?06b
5600 F8A18B A2 5D ldx #$5D ; X=low count
5601 F8A18D A0 BF ldy #$BF ; Y=high count
5602 F8A18F 8D 9C FD ?08b: sta !DMAWCLRFF ; clear F/F
5603 F8A192 E6 F5 inc <$f5
5604 F8A194 EA nop
5605 F8A195 EA nop
5606 F8A196 8A txa
5607 F8A197 8D 95 FD sta !DMAC+DMACNT2 ; store low count
5608 F8A19A EA nop
5609 F8A19B EA nop
5610 F8A19C 98 tya
5611 F8A19D 8D 95 FD sta !DMAC+DMACNT2 ; store high count
5612 F8A1A0 EA nop
5613 F8A1A1 8D 9C FD sta !DMAWCLRFF ; clear F/F
5614 F8A1A4 EA nop
5615 F8A1A5 EA nop
5616 F8A1A6 8A txa
5617 F8A1A7 CD 95 FD cmp !DMAC+DMACNT2 ; cmp low count
5618 F8A1AA D0 E3 bne ?08b
5619 F8A1AC 98 tya
5620 F8A1AD CD 95 FD cmp !DMAC+DMACNT2 ; cmp high count
5621 F8A1B0 D0 DD bne ?08b
5622 F8A1B2 8D 9C FD sta !DMAWCLRFF ; clear F/F
5623
5624 F8A1B5 8D 9C FD ?06c: sta !DMAWCLRFF ; clear F/F
5625 F8A1B8 E6 F6 inc <$f6
5626 F8A1BA EA nop
5627 F8A1BB EA nop
5628 F8A1BC 8A txa
5629 F8A1BD 8D 96 FD sta !DMAC+DMAADDR3 ; store low buffer address
5630 F8A1C0 EA nop
5631 F8A1C1 EA nop
5632 F8A1C2 98 tya
5633 F8A1C3 8D 96 FD sta !DMAC+DMAADDR3 ; store high buffer address
5634 F8A1C6 EA nop
5635 F8A1C7 8D 9C FD sta !DMAWCLRFF ; clear F/F
5636 F8A1CA EA nop
5637 F8A1CB EA nop
5638 F8A1CC 8A txa
5639 F8A1CD CD 96 FD cmp !DMAC+DMAADDR3 ; cmp low buffer address
5640 F8A1D0 D0 E3 bne ?06c
5641 F8A1D2 98 tya
Tue Jul 17 11:00:16 2018 Page 55
5642 F8A1D3 CD 96 FD cmp !DMAC+DMAADDR3 ; cmp high buffer address
5643 F8A1D6 D0 DD bne ?06c
5644 F8A1D8 A2 5D ldx #$5D ; X=low count
5645 F8A1DA A0 BF ldy #$BF ; Y=high count
5646 F8A1DC 8D 9C FD ?08c: sta !DMAWCLRFF ; clear F/F
5647 F8A1DF E6 F7 inc <$f7
5648 F8A1E1 EA nop
5649 F8A1E2 EA nop
5650 F8A1E3 8A txa
5651 F8A1E4 8D 97 FD sta !DMAC+DMACNT3 ; store low count
5652 F8A1E7 EA nop
5653 F8A1E8 EA nop
5654 F8A1E9 98 tya
5655 F8A1EA 8D 97 FD sta !DMAC+DMACNT3 ; store high count
5656 F8A1ED EA nop
5657 F8A1EE 8D 9C FD sta !DMAWCLRFF ; clear F/F
5658 F8A1F1 EA nop
5659 F8A1F2 EA nop
5660 F8A1F3 8A txa
5661 F8A1F4 CD 97 FD cmp !DMAC+DMACNT3 ; cmp low count
5662 F8A1F7 D0 E3 bne ?08c
5663 F8A1F9 98 tya
5664 F8A1FA CD 97 FD cmp !DMAC+DMACNT3 ; cmp high count
5665 F8A1FD D0 DD bne ?08c
5666 F8A1FF 8D 9C FD sta !DMAWCLRFF ; clear F/F
5667 F8A202 EA nop
5668 F8A203 00 00 brk
5669 F8A205 00 00 brk
5670 F8A207
5671 ;---------------------------------------------------------------------------
5672 ; end of file
5673 ;---------------------------------------------------------------------------
Lines Assembled : 5506 Errors : 0