Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * low-level functions for the SWIM floppy controller
0004  *
0005  * needs assembly language because is very timing dependent
0006  * this controller exists only on macintosh 680x0 based
0007  *
0008  * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
0009  *
0010  * based on Alastair Bridgewater SWIM analysis, 2001
0011  * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
0012  *
0013  * 2004-08-21 (lv) - Initial implementation
0014  * 2008-11-05 (lv) - add get_swim_mode
0015  */
0016 
0017     .equ    write_data, 0x0000
0018     .equ    write_mark, 0x0200
0019     .equ    write_CRC,  0x0400
0020     .equ    write_parameter,0x0600
0021     .equ    write_phase,    0x0800
0022     .equ    write_setup,    0x0a00
0023     .equ    write_mode0,    0x0c00
0024     .equ    write_mode1,    0x0e00
0025     .equ    read_data,  0x1000
0026     .equ    read_mark,  0x1200
0027     .equ    read_error, 0x1400
0028     .equ    read_parameter, 0x1600
0029     .equ    read_phase, 0x1800
0030     .equ    read_setup, 0x1a00
0031     .equ    read_status,    0x1c00
0032     .equ    read_handshake, 0x1e00
0033 
0034     .equ    o_side, 0
0035     .equ    o_track, 1
0036     .equ    o_sector, 2
0037     .equ    o_size, 3
0038     .equ    o_crc0, 4
0039     .equ    o_crc1, 5
0040 
0041     .equ    seek_time, 30000
0042     .equ    max_retry, 40
0043     .equ    sector_size, 512
0044 
0045     .global swim_read_sector_header
0046 swim_read_sector_header:
0047     link    %a6, #0
0048     moveml  %d1-%d5/%a0-%a4,%sp@-
0049     movel   %a6@(0x0c), %a4
0050     bsr mfm_read_addrmark
0051     moveml  %sp@+, %d1-%d5/%a0-%a4
0052     unlk    %a6
0053     rts
0054 
0055 sector_address_mark:
0056     .byte   0xa1, 0xa1, 0xa1, 0xfe
0057 sector_data_mark:
0058     .byte   0xa1, 0xa1, 0xa1, 0xfb
0059 
0060 mfm_read_addrmark:
0061     movel   %a6@(0x08), %a3
0062     lea %a3@(read_handshake), %a2
0063     lea %a3@(read_mark), %a3
0064     moveq   #-1, %d0
0065     movew   #seek_time, %d2
0066 
0067 wait_header_init:
0068     tstb    %a3@(read_error - read_mark)
0069     moveb   #0x18, %a3@(write_mode0 - read_mark)
0070     moveb   #0x01, %a3@(write_mode1 - read_mark)
0071     moveb   #0x01, %a3@(write_mode0 - read_mark)
0072     tstb    %a3@(read_error - read_mark)
0073     moveb   #0x08, %a3@(write_mode1 - read_mark)
0074 
0075     lea sector_address_mark, %a0
0076     moveq   #3, %d1
0077 
0078 wait_addr_mark_byte:
0079 
0080     tstb    %a2@
0081     dbmi    %d2, wait_addr_mark_byte
0082     bpl header_exit
0083 
0084     moveb   %a3@, %d3
0085     cmpb    %a0@+, %d3
0086     dbne    %d1, wait_addr_mark_byte
0087     bne wait_header_init
0088 
0089     moveq   #max_retry, %d2
0090 
0091 amark0: tstb    %a2@
0092     dbmi    %d2, amark0
0093     bpl signal_nonyb
0094 
0095     moveb   %a3@, %a4@(o_track)
0096 
0097     moveq   #max_retry, %d2
0098 
0099 amark1: tstb    %a2@
0100     dbmi    %d2, amark1
0101     bpl signal_nonyb
0102 
0103     moveb   %a3@, %a4@(o_side)
0104 
0105     moveq   #max_retry, %d2
0106 
0107 amark2: tstb    %a2@
0108     dbmi    %d2, amark2
0109     bpl signal_nonyb
0110 
0111     moveb   %a3@, %a4@(o_sector)
0112 
0113     moveq   #max_retry, %d2
0114 
0115 amark3: tstb    %a2@
0116     dbmi    %d2, amark3
0117     bpl signal_nonyb
0118 
0119     moveb   %a3@, %a4@(o_size)
0120 
0121     moveq   #max_retry, %d2
0122 
0123 crc0:   tstb    %a2@
0124     dbmi    %d2, crc0
0125     bpl signal_nonyb
0126 
0127     moveb   %a3@, %a4@(o_crc0)
0128 
0129     moveq   #max_retry, %d2
0130 
0131 crc1:   tstb    %a2@
0132     dbmi    %d2, crc1
0133     bpl signal_nonyb
0134 
0135     moveb   %a3@, %a4@(o_crc1)
0136 
0137     tstb    %a3@(read_error - read_mark)
0138 
0139 header_exit:
0140     moveq   #0, %d0
0141     moveb   #0x18, %a3@(write_mode0 - read_mark)
0142     rts
0143 signal_nonyb:
0144     moveq   #-1, %d0
0145     moveb   #0x18, %a3@(write_mode0 - read_mark)
0146     rts
0147 
0148     .global swim_read_sector_data
0149 swim_read_sector_data:
0150     link    %a6, #0
0151     moveml  %d1-%d5/%a0-%a5,%sp@-
0152     movel   %a6@(0x0c), %a4
0153     bsr mfm_read_data
0154     moveml  %sp@+, %d1-%d5/%a0-%a5
0155     unlk    %a6
0156     rts
0157 
0158 mfm_read_data:
0159     movel   %a6@(0x08), %a3
0160     lea %a3@(read_handshake), %a2
0161     lea %a3@(read_data), %a5
0162     lea %a3@(read_mark), %a3
0163     movew   #seek_time, %d2
0164 
0165 wait_data_init:
0166     tstb    %a3@(read_error - read_mark)
0167     moveb   #0x18, %a3@(write_mode0 - read_mark)
0168     moveb   #0x01, %a3@(write_mode1 - read_mark)
0169     moveb   #0x01, %a3@(write_mode0 - read_mark)
0170     tstb    %a3@(read_error - read_mark)
0171     moveb   #0x08, %a3@(write_mode1 - read_mark)
0172 
0173     lea sector_data_mark, %a0
0174     moveq   #3, %d1
0175 
0176     /* wait data address mark */
0177 
0178 wait_data_mark_byte:
0179 
0180     tstb    %a2@
0181     dbmi    %d2, wait_data_mark_byte
0182     bpl data_exit
0183 
0184     moveb   %a3@, %d3
0185     cmpb    %a0@+, %d3
0186     dbne    %d1, wait_data_mark_byte
0187     bne wait_data_init
0188 
0189     /* read data */
0190 
0191     tstb    %a3@(read_error - read_mark)
0192 
0193     movel   #sector_size-1, %d4     /* sector size */
0194 read_new_data:
0195     movew   #max_retry, %d2
0196 read_data_loop:
0197     moveb   %a2@, %d5
0198     andb    #0xc0, %d5
0199     dbne    %d2, read_data_loop
0200     beq data_exit
0201     moveb   %a5@, %a4@+
0202     andb    #0x40, %d5
0203     dbne    %d4, read_new_data
0204     beq exit_loop
0205     moveb   %a5@, %a4@+
0206     dbra    %d4, read_new_data
0207 exit_loop:
0208 
0209     /* read CRC */
0210 
0211     movew   #max_retry, %d2
0212 data_crc0:
0213 
0214     tstb    %a2@
0215     dbmi    %d2, data_crc0
0216     bpl data_exit
0217 
0218     moveb   %a3@, %d5
0219 
0220     moveq   #max_retry, %d2
0221 
0222 data_crc1:
0223 
0224     tstb    %a2@
0225     dbmi    %d2, data_crc1
0226     bpl data_exit
0227 
0228     moveb   %a3@, %d5
0229 
0230     tstb    %a3@(read_error - read_mark)
0231 
0232     moveb   #0x18, %a3@(write_mode0 - read_mark)
0233 
0234     /* return number of bytes read */
0235 
0236     movel   #sector_size, %d0
0237     addw    #1, %d4
0238     subl    %d4, %d0
0239     rts
0240 data_exit:
0241     moveb   #0x18, %a3@(write_mode0 - read_mark)
0242     moveq   #-1, %d0
0243     rts