2019-05-27 08:55:01 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2008-11-15 16:10:10 +01:00
/ *
* low- l e v e l f u n c t i o n s f o r t h e S W I M f l o p p y c o n t r o l l e r
*
* needs a s s e m b l y l a n g u a g e b e c a u s e i s v e r y t i m i n g d e p e n d e n t
* this c o n t r o l l e r e x i s t s o n l y o n m a c i n t o s h 6 8 0 x0 b a s e d
*
* Copyright ( C ) 2 0 0 4 ,2 0 0 8 L a u r e n t V i v i e r < L a u r e n t @lvivier.info>
*
* based o n A l a s t a i r B r i d g e w a t e r S W I M a n a l y s i s , 2 0 0 1
* based o n n e t B S D I W M d r i v e r ( c ) 1 9 9 7 , 1 9 9 8 H a u k e F a t h .
*
* 2 0 0 4 - 0 8 - 2 1 ( lv) - I n i t i a l i m p l e m e n t a t i o n
* 2 0 0 8 - 1 1 - 0 5 ( lv) - a d d g e t _ s w i m _ m o d e
* /
.equ write_ d a t a , 0 x00 0 0
.equ write_ m a r k , 0 x02 0 0
.equ write_ C R C , 0 x04 0 0
.equ write_ p a r a m e t e r ,0 x06 0 0
.equ write_ p h a s e , 0 x08 0 0
.equ write_ s e t u p , 0 x0 a00
.equ write_ m o d e 0 , 0 x0 c00
.equ write_ m o d e 1 , 0 x0 e 0 0
.equ read_ d a t a , 0 x10 0 0
.equ read_ m a r k , 0 x12 0 0
.equ read_ e r r o r , 0 x14 0 0
.equ read_ p a r a m e t e r , 0 x16 0 0
.equ read_ p h a s e , 0 x18 0 0
.equ read_ s e t u p , 0 x1 a00
.equ read_ s t a t u s , 0 x1 c00
.equ read_ h a n d s h a k e , 0 x1 e 0 0
.equ o_ s i d e , 0
.equ o_ t r a c k , 1
.equ o_ s e c t o r , 2
.equ o_ s i z e , 3
.equ o_ c r c0 , 4
.equ o_ c r c1 , 5
.equ seek_ t i m e , 3 0 0 0 0
.equ max_ r e t r y , 4 0
.equ sector_ s i z e , 5 1 2
.global swim_read_sector_header
swim_read_sector_header :
link % a6 , #0
moveml % d1 - % d5 / % a0 - % a4 ,% s p @-
movel % a6 @(0x0c), %a4
bsr m f m _ r e a d _ a d d r m a r k
moveml % s p @+, %d1-%d5/%a0-%a4
unlk % a6
rts
sector_address_mark :
.byte 0 xa1 , 0 x a1 , 0 x a1 , 0 x f e
sector_data_mark :
.byte 0 xa1 , 0 x a1 , 0 x a1 , 0 x f b
mfm_read_addrmark :
movel % a6 @(0x08), %a3
lea % a3 @(read_handshake), %a2
lea % a3 @(read_mark), %a3
moveq #- 1 , % d0
movew #s e e k _ t i m e , % d 2
wait_header_init :
tstb % a3 @(read_error - read_mark)
moveb #0x18 , % a3 @(write_mode0 - read_mark)
moveb #0x01 , % a3 @(write_mode1 - read_mark)
moveb #0x01 , % a3 @(write_mode0 - read_mark)
tstb % a3 @(read_error - read_mark)
moveb #0x08 , % a3 @(write_mode1 - read_mark)
lea s e c t o r _ a d d r e s s _ m a r k , % a0
moveq #3 , % d1
wait_addr_mark_byte :
tstb % a2 @
dbmi % d2 , w a i t _ a d d r _ m a r k _ b y t e
bpl h e a d e r _ e x i t
moveb % a3 @, %d3
cmpb % a0 @+, %d3
dbne % d1 , w a i t _ a d d r _ m a r k _ b y t e
bne w a i t _ h e a d e r _ i n i t
moveq #m a x _ r e t r y , % d 2
amark0 : tstb % a2 @
dbmi % d2 , a m a r k 0
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_track)
moveq #m a x _ r e t r y , % d 2
amark1 : tstb % a2 @
dbmi % d2 , a m a r k 1
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_side)
moveq #m a x _ r e t r y , % d 2
amark2 : tstb % a2 @
dbmi % d2 , a m a r k 2
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_sector)
moveq #m a x _ r e t r y , % d 2
amark3 : tstb % a2 @
dbmi % d2 , a m a r k 3
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_size)
moveq #m a x _ r e t r y , % d 2
crc0 : tstb % a2 @
dbmi % d2 , c r c0
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_crc0)
moveq #m a x _ r e t r y , % d 2
crc1 : tstb % a2 @
dbmi % d2 , c r c1
bpl s i g n a l _ n o n y b
moveb % a3 @, %a4@(o_crc1)
tstb % a3 @(read_error - read_mark)
header_exit :
moveq #0 , % d0
moveb #0x18 , % a3 @(write_mode0 - read_mark)
rts
signal_nonyb :
moveq #- 1 , % d0
moveb #0x18 , % a3 @(write_mode0 - read_mark)
rts
.global swim_read_sector_data
swim_read_sector_data :
link % a6 , #0
moveml % d1 - % d5 / % a0 - % a5 ,% s p @-
movel % a6 @(0x0c), %a4
bsr m f m _ r e a d _ d a t a
moveml % s p @+, %d1-%d5/%a0-%a5
unlk % a6
rts
mfm_read_data :
movel % a6 @(0x08), %a3
lea % a3 @(read_handshake), %a2
lea % a3 @(read_data), %a5
lea % a3 @(read_mark), %a3
movew #s e e k _ t i m e , % d 2
wait_data_init :
tstb % a3 @(read_error - read_mark)
moveb #0x18 , % a3 @(write_mode0 - read_mark)
moveb #0x01 , % a3 @(write_mode1 - read_mark)
moveb #0x01 , % a3 @(write_mode0 - read_mark)
tstb % a3 @(read_error - read_mark)
moveb #0x08 , % a3 @(write_mode1 - read_mark)
lea s e c t o r _ d a t a _ m a r k , % a0
moveq #3 , % d1
/* wait data address mark */
wait_data_mark_byte :
tstb % a2 @
dbmi % d2 , w a i t _ d a t a _ m a r k _ b y t e
bpl d a t a _ e x i t
moveb % a3 @, %d3
cmpb % a0 @+, %d3
dbne % d1 , w a i t _ d a t a _ m a r k _ b y t e
bne w a i t _ d a t a _ i n i t
/* read data */
tstb % a3 @(read_error - read_mark)
movel #s e c t o r _ s i z e - 1 , % d4 / * s e c t o r s i z e * /
read_new_data :
movew #m a x _ r e t r y , % d 2
read_data_loop :
moveb % a2 @, %d5
andb #0xc0 , % d5
dbne % d2 , r e a d _ d a t a _ l o o p
beq d a t a _ e x i t
moveb % a5 @, %a4@+
andb #0x40 , % d5
dbne % d4 , r e a d _ n e w _ d a t a
beq e x i t _ l o o p
moveb % a5 @, %a4@+
dbra % d4 , r e a d _ n e w _ d a t a
exit_loop :
/* read CRC */
movew #m a x _ r e t r y , % d 2
data_crc0 :
tstb % a2 @
dbmi % d2 , d a t a _ c r c0
bpl d a t a _ e x i t
moveb % a3 @, %d5
moveq #m a x _ r e t r y , % d 2
data_crc1 :
tstb % a2 @
dbmi % d2 , d a t a _ c r c1
bpl d a t a _ e x i t
moveb % a3 @, %d5
tstb % a3 @(read_error - read_mark)
moveb #0x18 , % a3 @(write_mode0 - read_mark)
/* return number of bytes read */
movel #s e c t o r _ s i z e , % d 0
addw #1 , % d4
subl % d4 , % d0
rts
data_exit :
moveb #0x18 , % a3 @(write_mode0 - read_mark)
moveq #- 1 , % d0
rts