.def CONST00	=r0
.def CONSTFF	=r1
.def SREG_TEMP	=r2
; .def COUNT_IP   =r3

;.def CMD_REG	=r4
.def TR_REG		=r5
.def SECT_REG	=r6
.def DAT_REG	=r7

.def CRC_L		=r8
.def CRC_H		=r9	

.def SECT_LEN	 = r10
.def SECT_LEN_H	 = r11

.def OLD_CAPT   =r12
.def TEMP1      =r13

.def TEMP_CMD   =r15

.def TEMP		=r16 
.def CURR_CAPT  =r17 

.def SHIFT_REG	=r18 
.def S_REG		=r19

.def TEMP_D_REG =r20

.def FLAGS		 = r21
.def SHIFT_COUNT = r22
.def SHIFT_REG_S = r23

;.def TIME       = r24
;.def TEMP_ZH    =r25

.equ  DATA_BUS	= PORTB
.equ  DIR_BUS	= DDRB
.equ  PIN_BUS	= PINB
.equ  PEREHOD	= PINC

.equ	S_REG_BUSY		 = 0
.equ	S_REG_IP		 = 1
.equ    S_REG_DRQ		 = 1

.equ	S_REG_TR00		 = 2
.equ    S_REG_DATA_LOST	 = 2 

.equ	S_REG_CRC_ERR	 = 3
.equ	S_REG_SEEK_ERR	 = 4

.equ	S_REG_HLD		 = 5
.equ    S_REG_TYPE_REC	 = 5
.equ    S_REG_WRITE_ERR	 = 5

.equ	S_REG_WR_PR		 = 6
.equ	S_REG_READY		 = 7

;.equ    PMCR     = 0xF2

.equ NEW_CMD	 = 0
.equ S_D_R		 = 1
.equ BREAK_IP	 = 2
.equ CMD_1_TYPE	 = 3
.equ READ_TR	 = 4
.equ BREAK_D8	 = 5
.equ SYNC		 = 6

.macro    align
    .org    @0+PC-PC%@0
.endm
.macro STATE_M
	ldi XL, low(@0  )
	ldi XH, high(@0 ) 
.endm
.macro STATE_E
	ldi XL, low(@0  )
	ldi XH, high(@0 ) 
	rjmp _end_state
.endm

.macro CLR_S_REG
		clr S_REG
.endm
.macro SET_S_REG_BIT
		ori S_REG , ( 1 << @0 ) 
.endm

.macro RES_S_REG_BIT
		andi S_REG , ~( 1 << @0 )
.endm
.macro CHECK_S_REG_BIT
		sbrc S_REG , @0
.endm

.macro INC_SECT_LEN
		inc SECT_LEN
		brne $inc_end
		inc SECT_LEN_H
$inc_end:
.endm

.macro INI_DELAY_4
		sts TCCR2A , CONST00
		sts TCCR2B , CONST00
		sts TIMSK2 , CONST00 
.endm
.macro START_DELAY_4
		sts TCCR2B , CONST00
		ldi TEMP , 127
		sts OCR2A , TEMP
		ldi TEMP , 2 
		sts TCCR2A , TEMP
		sts TCNT2 , CONST00
		out TIFR2 , CONSTFF
		ldi TEMP , 1
		sts TCCR2B , TEMP

.endm
.macro CHECK_DELAY_4
		sbis TIFR2 ,  OCF2A
.endm
.macro STOP_DELAY_4
		sts TCCR2B , CONST00
.endm


.macro INI_DELAY_32
		sts TCCR2A , CONST00
		sts TCCR2B , CONST00
		sts TIMSK2 , CONST00 
.endm
.macro START_DELAY_32
		sts TCCR2B , CONST00
		sts OCR2A , TEMP
		ldi TEMP , 2 
		sts TCCR2A , TEMP
		sts TCNT2 , CONST00
		out TIFR2 , CONSTFF
		ldi TEMP , 6
		sts TCCR2B , TEMP

.endm
.macro CHECK_DELAY_32
		sbis TIFR2 ,  OCF2A
.endm
.macro STOP_DELAY_32
		sts TCCR2B , CONST00
.endm

.macro INI_DELAY
	sts TCCR3A , CONST00
	sts TCCR3B , CONST00
	sts TCCR3C , CONST00
	sts TIMSK3 , CONST00
.endm

.macro START_DELAY 
	out TIFR3 , CONSTFF
	sts TCNT3H , CONST00
	sts TCNT3L , CONST00
	cpi TEMP , 0
	brne $ma1 
	ldi TEMP , 6*KOEFF
	rjmp $mae	
$ma1:
	cpi TEMP , 1
	brne $ma2 
	ldi TEMP , 12*KOEFF
	rjmp $mae	
$ma2:
   	cpi TEMP , 2
	brne $ma3 
	ldi TEMP , 20*KOEFF
	rjmp $mae	
$ma3:
	ldi TEMP , 30*KOEFF
$mae:	
	sts OCR3AH , TEMP
	sts OCR3AL , CONST00
	ldi TEMP , ( 1 << WGM12 ) | ( 1 << CS11 ) | ( 1 << CS10 )  
	sts TCCR3B , TEMP
.endm
.macro CHECK_DELAY
	sbis TIFR3 , OCF3A
.endm
.macro STOP_DELAY
	sts TCCR3B , CONST00
.endm

.macro INI_CAPTURE
		ldi TEMP , 0x80
		out ACSR , TEMP
		out C1SR , TEMP
		sts  TCCR3A , CONST00
		sts  TCCR3B , CONST00
		sts  TCCR3C , CONST00
		sts  TIMSK3 , CONST00 
.endm

.macro START_CAPTURE
		ldi TEMP , 0x02
		sts TCCR3B , TEMP
.endm

.macro STOP_CAPTURE
		sts TCCR3B , CONST00
.endm

.macro START_IP
	sts TCCR1B , CONST00
	sts TCCR1A , CONST00
	sts TCNT1H , CONSTFF
	sts TCNT1L , TEMP
	out TIFR1 , CONSTFF
	ldi TEMP , ( 1 << CS12 ) | ( 1 << CS11 ) 
	sts TCCR1B , TEMP

.endm
.macro CHECK_IP
		sbis TIFR1 , TOV1
.endm
.macro STOP_IP
	sts TCCR1B , CONST00
.endm

.equ PULSE =  8
.equ MED_PULSE = PULSE * 5 / 2
.equ LONG_PULSE = PULSE * 7 / 2 
.equ KOEFF = 2          ; скорость перемещения головки пир коеф 2 обычная 

.listmac

;.macro READPULSE 
;$m1:  
;	   sbis   TIFR3, ICF3     // (1/2) skip next instruction if timer input capture seen
;      rjmp   $m1           // (2)   wait more 
; 	   lds     TEMP , ICR3L     // (2)   get time of input capture (ICR1L, lower 8 bits only)
; 	   sbi     TIFR3, ICF3    // (2)   clear input capture flag
;  	   mov     CURR_CAPT, TEMP     // (1)   calculate time since previous capture...
;       sub     CURR_CAPT, OLD_CAPT      // (1)   ...into r22
;       mov     OLD_CAPT, TEMP      // (1)   set r18 to time of current capture
;.endm



.macro WAIT_SHIFT_R
				ldi XL, low(@0  )
				ldi XH, high(@0 ) 
				sbrs FLAGS , S_D_R
					rjmp _start_state	
				andi  FLAGS , ~( 1 << S_D_R )
.endm

.macro WAIT_SYNC_A1
				ldi XL, low(@0  )
				ldi XH, high(@0 )
				sbrs FLAGS , SYNC
				rjmp _start_state	
				andi  FLAGS , ~(( 1 << SYNC ) | (1 << S_D_R ))
;				ldi TEMP , 0xA1
;				cpse TEMP_D_REG ,  TEMP 
;				rjmp _start_state

.endm


.macro STORE  ;   
		lsl     @1          // (1)   shift received data
.if @0 != 0
		ori     @1 , 1        // (1)   store "1" bit

 		cpi @1 ,  0xA1
		brne $sm5
		cpi @2 ,  0x0A 
		brne $sm6
		ori FLAGS , ( 1 << SYNC )
		rjmp $sm7
$sm5:	  
.else
;		sbrs FLAGS , READ_TR
;			rjmp $sm6
;		cpi @1 ,  0xC2
;		brne $sm6
;		cpi @2 ,  0x14 
;		brne $sm6
;		ori FLAGS , ( 1 << SYNC )
;		rjmp $sm7
.endif
$sm6:	  
		dec    SHIFT_COUNT    // (1)   decrement bit counter
		brne    $sm8          // (1/2) skip if bit counter >0
$sm7:      
		ldi SHIFT_COUNT , 16
		mov TEMP_D_REG  , @1  // (2)   store received data byte
		ori FLAGS , (1 << S_D_R )
		CALC_CRC TEMP_D_REG
$sm8:
	
.endm

.macro  READ_BYTE 
		sbis   TIFR3, ICF3     // (1/2) skip next instruction if timer input capture seen
			rjmp   $rdend           // (2)   wait more 
		lds     TEMP , ICR3L     // (2)   get time of input capture (ICR1L, lower 8 bits only)
 		sbi     TIFR3, ICF3    // (2)   clear input capture flag
 		mov     CURR_CAPT, TEMP     // (1)   calculate time since previous capture...
		sub     CURR_CAPT, OLD_CAPT      // (1)   ...into r22
		mov     OLD_CAPT, TEMP      // (1)   set r18 to time of current capture
	
  	    cpi     CURR_CAPT, LONG_PULSE		
        brsh    $rdl				
        cpi     CURR_CAPT, MED_PULSE	
        brlo    $rds				
		mov		TEMP , SHIFT_REG
		mov		SHIFT_REG , SHIFT_REG_S
		mov		SHIFT_REG_S , TEMP
		rjmp    $rdm
$rdl:		
		STORE 0 , SHIFT_REG , SHIFT_REG_S
$rdm:	    
		STORE 0 , SHIFT_REG_S , SHIFT_REG	
$rds:
        STORE 0 , SHIFT_REG , SHIFT_REG_S
		STORE 1	, SHIFT_REG_S , SHIFT_REG			
$rdend:
.endm   


 .macro INI_CRC
	ldi TEMP , low(0xCDB4)
	mov CRC_L , TEMP
	ldi TEMP , high(0xCDB4)
	mov CRC_H , TEMP 
.endm 
.macro CALC_CRC
	mov YL , @0
	eor YL , CRC_H
	ldi YH , high( 2 * crchi ) + 0x40
    ld CRC_H , Y
	eor CRC_H , CRC_L
	dec YH
    ld CRC_L , Y
.endm


.if OLD_WRITE == 1
.equ BIT_COUNT = 8
.else
.equ BIT_COUNT = 4
.endif


;.macro OUT_BIT
;$ms0:	
;		lds TEMP1 , UCSRA 
;		sbrs TEMP1 ,  UDRE
;			rjmp $ms0 
;		sts UDR , @0
;.endm

.macro OUT_BIT_
$ms0:	
		lds TEMP1 , UCSRA 
		sbrs TEMP1 ,  UDRE
			rjmp _end_state 
		sts UDR , @0
		dec SHIFT_COUNT 
		brne @1		 
.endm


;.macro PREV_WRITE_DATA
;.if OLD_WRITE == 1
;		ldi SHIFT_COUNT , 8
;.else
;		ldi SHIFT_COUNT , 4
;.endif
;.endm

.macro WRITE_DATA
.if OLD_WRITE == 1
mw0:	
		lsl TEMP_D_REG
		brcc mw1
		
		ori SHIFT_REG_S ,  1 
		ldi SHIFT_REG , ( 1 )
		rjmp mw2
mw1:
		ldi SHIFT_REG , 0x0
		sbrs SHIFT_REG_S , 0
		ldi SHIFT_REG , (1 << 4 )
		andi SHIFT_REG_S , ~( 1 )       
mw2:
.else
mw0:		
		lsl TEMP_D_REG
		rol SHIFT_REG_S
		lsl TEMP_D_REG
		rol SHIFT_REG_S
		andi SHIFT_REG_S , 0b00000111
		ldi YH , high( MFM_table * 2 ) + 0x40
		ldi YL , low( MFM_table  * 2 )
		add YL , SHIFT_REG_S
		adc YH , CONST00
		ld  SHIFT_REG , Y
.endif
.endm


;.macro WRITE_SYNC
;		ld  SHIFT_REG , Y+
;.endm
