root/drivers/block/swim_asm.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  * low-level functions for the SWIM floppy controller
   4  *
   5  * needs assembly language because is very timing dependent
   6  * this controller exists only on macintosh 680x0 based
   7  *
   8  * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
   9  *
  10  * based on Alastair Bridgewater SWIM analysis, 2001
  11  * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
  12  *
  13  * 2004-08-21 (lv) - Initial implementation
  14  * 2008-11-05 (lv) - add get_swim_mode
  15  */
  16 
  17         .equ    write_data,     0x0000
  18         .equ    write_mark,     0x0200
  19         .equ    write_CRC,      0x0400
  20         .equ    write_parameter,0x0600
  21         .equ    write_phase,    0x0800
  22         .equ    write_setup,    0x0a00
  23         .equ    write_mode0,    0x0c00
  24         .equ    write_mode1,    0x0e00
  25         .equ    read_data,      0x1000
  26         .equ    read_mark,      0x1200
  27         .equ    read_error,     0x1400
  28         .equ    read_parameter, 0x1600
  29         .equ    read_phase,     0x1800
  30         .equ    read_setup,     0x1a00
  31         .equ    read_status,    0x1c00
  32         .equ    read_handshake, 0x1e00
  33 
  34         .equ    o_side, 0
  35         .equ    o_track, 1
  36         .equ    o_sector, 2
  37         .equ    o_size, 3
  38         .equ    o_crc0, 4
  39         .equ    o_crc1, 5
  40 
  41         .equ    seek_time, 30000
  42         .equ    max_retry, 40
  43         .equ    sector_size, 512
  44 
  45         .global swim_read_sector_header
  46 swim_read_sector_header:
  47         link    %a6, #0
  48         moveml  %d1-%d5/%a0-%a4,%sp@-
  49         movel   %a6@(0x0c), %a4
  50         bsr     mfm_read_addrmark
  51         moveml  %sp@+, %d1-%d5/%a0-%a4
  52         unlk    %a6
  53         rts
  54 
  55 sector_address_mark:
  56         .byte   0xa1, 0xa1, 0xa1, 0xfe
  57 sector_data_mark:
  58         .byte   0xa1, 0xa1, 0xa1, 0xfb
  59 
  60 mfm_read_addrmark:
  61         movel   %a6@(0x08), %a3
  62         lea     %a3@(read_handshake), %a2
  63         lea     %a3@(read_mark), %a3
  64         moveq   #-1, %d0
  65         movew   #seek_time, %d2
  66 
  67 wait_header_init:
  68         tstb    %a3@(read_error - read_mark)
  69         moveb   #0x18, %a3@(write_mode0 - read_mark)
  70         moveb   #0x01, %a3@(write_mode1 - read_mark)
  71         moveb   #0x01, %a3@(write_mode0 - read_mark)
  72         tstb    %a3@(read_error - read_mark)
  73         moveb   #0x08, %a3@(write_mode1 - read_mark)
  74 
  75         lea     sector_address_mark, %a0
  76         moveq   #3, %d1
  77 
  78 wait_addr_mark_byte:
  79 
  80         tstb    %a2@
  81         dbmi    %d2, wait_addr_mark_byte
  82         bpl     header_exit
  83 
  84         moveb   %a3@, %d3
  85         cmpb    %a0@+, %d3
  86         dbne    %d1, wait_addr_mark_byte
  87         bne     wait_header_init
  88 
  89         moveq   #max_retry, %d2
  90 
  91 amark0: tstb    %a2@
  92         dbmi    %d2, amark0
  93         bpl     signal_nonyb
  94 
  95         moveb   %a3@, %a4@(o_track)
  96 
  97         moveq   #max_retry, %d2
  98 
  99 amark1: tstb    %a2@
 100         dbmi    %d2, amark1
 101         bpl     signal_nonyb
 102 
 103         moveb   %a3@, %a4@(o_side)
 104 
 105         moveq   #max_retry, %d2
 106 
 107 amark2: tstb    %a2@
 108         dbmi    %d2, amark2
 109         bpl     signal_nonyb
 110 
 111         moveb   %a3@, %a4@(o_sector)
 112 
 113         moveq   #max_retry, %d2
 114 
 115 amark3: tstb    %a2@
 116         dbmi    %d2, amark3
 117         bpl     signal_nonyb
 118 
 119         moveb   %a3@, %a4@(o_size)
 120 
 121         moveq   #max_retry, %d2
 122 
 123 crc0:   tstb    %a2@
 124         dbmi    %d2, crc0
 125         bpl     signal_nonyb
 126 
 127         moveb   %a3@, %a4@(o_crc0)
 128 
 129         moveq   #max_retry, %d2
 130 
 131 crc1:   tstb    %a2@
 132         dbmi    %d2, crc1
 133         bpl     signal_nonyb
 134 
 135         moveb   %a3@, %a4@(o_crc1)
 136 
 137         tstb    %a3@(read_error - read_mark)
 138 
 139 header_exit:
 140         moveq   #0, %d0
 141         moveb   #0x18, %a3@(write_mode0 - read_mark)
 142         rts
 143 signal_nonyb:
 144         moveq   #-1, %d0
 145         moveb   #0x18, %a3@(write_mode0 - read_mark)
 146         rts
 147 
 148         .global swim_read_sector_data
 149 swim_read_sector_data:
 150         link    %a6, #0
 151         moveml  %d1-%d5/%a0-%a5,%sp@-
 152         movel   %a6@(0x0c), %a4
 153         bsr     mfm_read_data
 154         moveml  %sp@+, %d1-%d5/%a0-%a5
 155         unlk    %a6
 156         rts
 157 
 158 mfm_read_data:
 159         movel   %a6@(0x08), %a3
 160         lea     %a3@(read_handshake), %a2
 161         lea     %a3@(read_data), %a5
 162         lea     %a3@(read_mark), %a3
 163         movew   #seek_time, %d2
 164 
 165 wait_data_init:
 166         tstb    %a3@(read_error - read_mark)
 167         moveb   #0x18, %a3@(write_mode0 - read_mark)
 168         moveb   #0x01, %a3@(write_mode1 - read_mark)
 169         moveb   #0x01, %a3@(write_mode0 - read_mark)
 170         tstb    %a3@(read_error - read_mark)
 171         moveb   #0x08, %a3@(write_mode1 - read_mark)
 172 
 173         lea     sector_data_mark, %a0
 174         moveq   #3, %d1
 175 
 176         /* wait data address mark */
 177 
 178 wait_data_mark_byte:
 179 
 180         tstb    %a2@
 181         dbmi    %d2, wait_data_mark_byte
 182         bpl     data_exit
 183 
 184         moveb   %a3@, %d3
 185         cmpb    %a0@+, %d3
 186         dbne    %d1, wait_data_mark_byte
 187         bne     wait_data_init
 188 
 189         /* read data */
 190 
 191         tstb    %a3@(read_error - read_mark)
 192 
 193         movel   #sector_size-1, %d4             /* sector size */
 194 read_new_data:
 195         movew   #max_retry, %d2
 196 read_data_loop:
 197         moveb   %a2@, %d5
 198         andb    #0xc0, %d5
 199         dbne    %d2, read_data_loop
 200         beq     data_exit
 201         moveb   %a5@, %a4@+
 202         andb    #0x40, %d5
 203         dbne    %d4, read_new_data
 204         beq     exit_loop
 205         moveb   %a5@, %a4@+
 206         dbra    %d4, read_new_data
 207 exit_loop:
 208 
 209         /* read CRC */
 210 
 211         movew   #max_retry, %d2
 212 data_crc0:
 213 
 214         tstb    %a2@
 215         dbmi    %d2, data_crc0
 216         bpl     data_exit
 217 
 218         moveb   %a3@, %d5
 219 
 220         moveq   #max_retry, %d2
 221 
 222 data_crc1:
 223 
 224         tstb    %a2@
 225         dbmi    %d2, data_crc1
 226         bpl     data_exit
 227 
 228         moveb   %a3@, %d5
 229 
 230         tstb    %a3@(read_error - read_mark)
 231 
 232         moveb   #0x18, %a3@(write_mode0 - read_mark)
 233 
 234         /* return number of bytes read */
 235 
 236         movel   #sector_size, %d0
 237         addw    #1, %d4
 238         subl    %d4, %d0
 239         rts
 240 data_exit:
 241         moveb   #0x18, %a3@(write_mode0 - read_mark)
 242         moveq   #-1, %d0
 243         rts

/* [<][>][^][v][top][bottom][index][help] */