
	list p=18f4550
	; Include file, change directory if needed
	include "p18f4550.inc"

; ******************************************************************
; Az USB-s PIC programozo program-probaja 4553-as PIC, 20MHz
; Olvassa es irja a configwordoket, memoriat, eepromot, IDwordoket
; Keszen van   2011.05.30
; a writebuffersize a bulkeras torlesnel jon at, ugyis mindig megelozi az irast
; !!! NAGYON FONTOS !!! az input buffer 128 byte hosszura allitva az USB description fileban!
; ******************************************************************
timer1ertek = 0ff00	; 1/128-ad az 100h


CONFIG WDT=OFF
CONFIG MCLRE = ON
CONFIG DEBUG = OFF
CONFIG LVP = ON
CONFIG FOSC = HSPLL_HS	;External, PLL, port function on RA6
CONFIG USBDIV = 2	;Clock source from 96MHz PLL/2
CONFIG PLLDIV = 5	;Divide by 5 (20MHz input)
CONFIG PWRT = ON	;Enabled
CONFIG BOR = OFF	;Disabled
CONFIG VREGEN = ON	;Enabled
CONFIG LPT1OSC = OFF	;Timer1 oscillator configured for high power

__idlocs _IDLOC0, 0x43
__idlocs _IDLOC1, 0x12

#define	_C	STATUS,C,A
#define	_Z	STATUS,Z,A
#define	_stack	0x300
#define	AVbit 1
#define	BANK0 0
#define	BANK1 1
#define	BANK2 2
#define	BANK3 3
#define	BANK4 4

#define sargaled LATC,2
#define zoldled LATD,0
#define pirosled LATD,1

#define MCLR LATA,0
#define PROG LATA,1
#define CLK LATA,2
#define DATA LATA,3
#define DATA_IN PORTA,3

;MAKROK

wait MACRO
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
ENDM
MCLR_HI MACRO
	bsf MCLR
ENDM
MCLR_LO MACRO
	bcf MCLR
ENDM
PGM_HI MACRO
	bsf PROG
ENDM
PGM_LO MACRO
	bcf PROG
ENDM
CLK_HI MACRO
	bsf CLK
ENDM
CLK_LO MACRO
	bcf CLK
ENDM
DATA_HI MACRO
	bsf DATA
ENDM
DATA_LO MACRO
	bcf DATA
ENDM

OUTPUTPORT MACRO
	bcf TRISA,3
ENDM
INPUTPORT MACRO
	bsf TRISA,3
ENDM

MEGSZOLIT MACRO ertek
	movlw ertek
	call Megszol
ENDM		

IDEGBETESZ MACRO ertek
	movlw HIGH ertek
	movwf ideg16hi
	movlw LOW ertek
	movwf ideg16lo
	call szolkuld
ENDM		

;BANK 0

cblock 0x00
kuldheto
tmpdatal
 tmpdatah
TEMP1
TEMP2
TEMP3
irqszamlalo
shiftcounter
ideg16lo
 ideg16hi
kezdocimlo
 kezdocimhi
  kezdocimu
idegbee
hibyte
lobyte
idegfsr1l
 idegfsr1h
confszamol
irociklus
writebuffersize
endc

read_com  	equ 'r'
reset_com 	equ 't'
write_com 	equ 'w'
bulk_com  	equ 'b'
eepromread_com  equ 'e'
eepromwrite_com	equ 'j'
configwrite_com	equ 'c'
idwrite_com	equ 'i'
semleges_com	equ 'x'


	ctrl_trf_state   	equ 0x60
	ctrl_trf_session_owner	equ 0x61
	pSrcl			equ 0x62
	 pSrch			equ 0x63
	pDstl			equ 0x64
	 pDsth			equ 0x65
	wCountl			equ 0x66
	 wCounth		equ 0x67
	short_pkt_status	equ 0x68
	UIRbits			equ 0x68
	UIEbits			equ 0x69
	UEIRbits             EQU  H'0F6A'
	UEIEbits             EQU  H'0F6B'
	USTATbits            EQU  H'0F6C'
	UCONbits             EQU  H'0F6D'
	UADDRbits            EQU  H'0F6E'
	UCFGbits             EQU  H'0F6F'
	UEP0bits             EQU  H'0F70'
	UEP1bits             EQU  H'0F71'
	UEP2bits             EQU  H'0F72'
	UEP3bits             EQU  H'0F73'
        
;BANK 1
	output_buffer 		equ 0x100
	input_buffer 		equ 0x140

	buffer_pointer 		equ 0x1d4
	tx_min	 		equ 0x1d5
	T3divLforAD 		equ 0x1d6
	 T3divHforAD 		equ 0x1d7
	flags 			equ 0x1d8
	isr_fsr0l		equ 0x1d9
	 isr_fsr0h		equ 0x1da
	parlen			equ 0x1db
	cdc_rx_len		equ 0x1dc
	cdc_trf_state		equ 0x1dd
	pCDCSrcl		equ 0x1de
	 pCDCSrch		equ 0x1df
	pCDCDstl		equ 0x1e1
	 pCDCDsth		equ 0x1e2
	cdc_tx_len		equ 0x1e3
	cdc_mem_type 		equ 0x1e4
	line_coding		equ 0x1e5
	 lncd1			equ 0x1e6
	 lncd2			equ 0x1e7
	 lncd3			equ 0x1e8
	 lncd4			equ 0x1e9
	 lncd5			equ 0x1ea
	 lncd6			equ 0x1eb
        control_signal_bitmap	equ 0x1ec
dummy_encapsulated_cmd_response equ 0x1ed
	proml			equ 0x1ee
	 promh			equ 0x1ef
	 promu			equ 0x1f0
	curr_bytel		equ 0x1f1
	 curr_byteh		equ 0x1f2
	curr_entryl		equ 0x1f3
	 curr_entryh		equ 0x1f4
	data_ptrl		equ 0x1f5
	 data_ptrh		equ 0x1f6
	 data_ptru		equ 0x1f7
	usb_device_state	equ 0x1f8
	usb_stat		equ 0x1f9
	usb_active_cfg  	equ 0x1fa
	usb_alt_intf		equ 0x1fb
	bTRNIFCount		equ 0x1fc
	delay_countl		equ 0x1fd
	 delay_counth		equ 0x1fe
	                	
;BANK 4
	ep0Bo			equ 0x400
	ep0Bi			equ 0x404
	ep1Bo			equ 0x408
	ep1Bi			equ 0x40c
	ep2Bo   		equ 0x410
	ep2Bi   		equ 0x414
	ep3Bo			equ 0x418
	ep3Bi			equ 0x41c
	SetupPkt		equ 0x420
	CtrlTrfData   		equ 0x428
	cdc_notice		equ 0x430
	cdc_data_rx		equ 0x438
	cdc_datax		equ 0x478


ORG 0x0000
	goto _startup
	return 0
org 0x0008
        goto high_isr	;low priority int
	return 0
org 0x0018
	retfie 0	;high priority int
	return 0
org 0x002a
	nop
	nop
	nop

;-----------------------------------------
USBCtrlEPService:
	MOVF      USTAT,0,ACCESS
	BNZ       @r1
	BCF       UIRbits,TRNIF,ACCESS
	MOVLB BANK4
	MOVF      ep0Bo,0,1
	ANDLW     0x3c
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	SUBLW     0xd
	BNZ       @r2
	RCALL     USBCtrlTrfSetupHandler
	BRA       @r3
@r2:
	RCALL     USBCtrlTrfOutHandler
@r3:
	BRA       @r4
@r1:
	MOVLW     4
	SUBWF     USTAT,0,0
	BNZ       @r5
	BCF       UIRbits,TRNIF,0
	RCALL     USBCtrlTrfInHandler
	BRA       @r4
@r5:
	MOVLW     0
	BRA       @r6
@r4:
	MOVLW     1
	BRA       @r6
@r6:
	RETURN    0

;-----------------------------------------

USBCtrlTrfSetupHandler:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVF      POSTINC1,1,0
	MOVLB  BANK4
	BTFSC     ep0Bi,7,1
	CLRF      ep0Bi,1
	MOVLB  BANK0
	CLRF      UIRbits,1
	CLRF      ctrl_trf_state,1
	CLRF      ctrl_trf_session_owner,1
	CLRF      wCountl,1
	CLRF      wCounth,1
	CALL      USBCheckStdRequest,0
	CLRF      INDF2,0
@s1:
	MOVF      INDF2,0,0
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     1
	SUBWF     tmpdatal,0,0
	MOVLW     0
	SUBWFB    tmpdatah,0,0
	BC        @s4
	MOVLB  BANK0
	MOVF      ctrl_trf_session_owner,0,1
	BZ        @s2
	BRA       @s4
@s2:
	CLRF      TBLPTRH,0            
	RLCF      INDF2,0,0
	ANDLW     0xfe
	RLCF      TBLPTRH,1,0
	MOVWF     TBLPTRL,0
	MOVLW     low (desccimtabla+.11) 
	ADDWF     TBLPTRL,1,0
	MOVLW     high (desccimtabla+.11)
	ADDWFC    TBLPTRH,1,0
	TBLRD*+			;POSTINC
	MOVFF     TABLAT,tmpdatal
	TBLRD*
	MOVFF     TABLAT,tmpdatah
	BRA       @s3

FAKE_hivas:
	MOVFF     tmpdatah,PCLATH
	MOVF      tmpdatal,0,0
	MOVWF     PCL,0     ; a ClassReqHandler[i]()!! -re fog ugrani!
@s3:
	RCALL     FAKE_hivas
	INCF      INDF2,1,0
	BRA       @s1
@s4:
	RCALL     USBCtrlEPServiceComplete
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

USBCtrlTrfOutHandler:
	MOVLW     0x2
	MOVLB  BANK0
	SUBWF     ctrl_trf_state,0,1
	BNZ       @t1
	RCALL     USBCtrlTrfRxService
	MOVLB  BANK4
	BTFSC     ep0Bo,6,1
	BRA       @t2
	MOVLW     0xc8
	MOVWF     ep0Bo,1
	BRA       @t3
@t2:
	MOVLW     0x88
	MOVWF     ep0Bo,1
@t3:
	BRA       @t4
@t1:
	RCALL     USBPrepareForNextSetupTrf
@t4:
	RETURN    0

;-----------------------------------------

USBCtrlTrfInHandler:
	MOVLW     4
	MOVLB  BANK1
	SUBWF     usb_device_state,0,1
	BNZ       @u1
	MOVFF     SetupPkt+2,UADDR
	MOVF      UADDR,0,0
	SUBLW     0
	BC        @u2
	MOVLW     5
	MOVWF     usb_device_state,1
	BRA       @u1
@u2:
	MOVLW     3
	MOVWF     usb_device_state,1
@u1:
	MOVLB  BANK0
	DECF      ctrl_trf_state,0,1
	BNZ       @u3
	RCALL     USBCtrlTrfTxService
	MOVLW     0x2
	MOVLB  BANK0
	SUBWF     UIRbits,0,1
	BNZ       @u4
	MOVLB  BANK4
	MOVLW     0x84
	MOVWF     ep0Bi,1
	BRA       @u5
@u4:
	MOVLB  BANK4
	BTFSC     ep0Bi,6,1
	BRA       @u6
	MOVLW     0xc8
	MOVWF     ep0Bi,1
	BRA       @u5
@u6:
	MOVLW     0x88
	MOVWF     ep0Bi,1
@u5:
	BRA       @u7
@u3:
	RCALL     USBPrepareForNextSetupTrf
@u7:
	RETURN    0

;-----------------------------------------

USBCtrlTrfTxService:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVLW     2
	ADDWF     FSR1L,1,0
	MOVLB  BANK0
	MOVLW     8
	SUBWF     wCountl,0,1
	MOVLW     0
	SUBWFB    wCounth,0,1
	BC        @v1
	MOVFF     wCountl,POSTINC2;             byte_to_send._word = wCount._word;
	MOVFF     wCounth,POSTDEC2
	MOVF      UIRbits,0,1;           if(short_pkt_status == SHORT_PKT_NOT_USED)
	BNZ       @v2
	MOVLW     1
	MOVWF     UIRbits,1
	BRA       @v3
@v2:
	DECF      UIRbits,0,1
	BNZ       @v3
	MOVLW     2
	MOVWF     UIRbits,1
@v3:
	BRA       @v11;              else
@v1:
	MOVLW     8
	MOVWF     POSTINC2,0
	CLRF      POSTDEC2,0
@v11:
	MOVLB  BANK4
	BCF       ep0Bi,1,1
	BCF       ep0Bi,0,1;        ep0Bi.Stat.BC8 = 0;
	MOVLW     1
	MOVF      PLUSW2,0,0
	IORWF     ep0Bi,1,1
	MOVFF     INDF2,ep0Bi+1;        ep0Bi.Cnt = LSB(byte_to_send);
	MOVLW     0
	MOVF      PLUSW2,0,0
	MOVLB  BANK0
	SUBWF     wCountl,1,1
	MOVLW     1
	MOVF      PLUSW2,0,0
	SUBWFB    wCounth,1,1
	MOVLW     low CtrlTrfData           
	MOVWF     pDstl,1
	MOVLW     high CtrlTrfData
	MOVWF     pDsth,1
	MOVLB  BANK1
	BTFSS     usb_stat,1,1
	BRA       @v4
@v6:
	MOVFF     FSR2L,FSR0L;   while(byte_to_send._word)
	MOVFF     FSR2H,FSR0H
	MOVF      POSTINC0,0,0
	IORWF     POSTDEC0,0,0
	BZ        @v5
	MOVFF     pSrcl,TBLPTRL
	MOVFF     pSrch,TBLPTRH
	TBLRD*
	MOVF      TABLAT,0,0
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
	MOVLB  BANK0
	INCF      pDstl,1,1
	MOVLW     0
	ADDWFC    pDsth,1,1
	INCF      pSrcl,1,1;  pSrc.bRom++;
	ADDWFC    pSrch,1,1
	DECF      INDF2,1,0; byte_to_send._word--;
	MOVLW     1
	BC        @v7
	DECF      PLUSW2,1,0
@v7:
	BRA       @v6
@v5:
	BRA       @v8; else // RAM
@v4:
	MOVFF     FSR2L,FSR0L; while(byte_to_send._word)
	MOVFF     FSR2H,FSR0H
	MOVF      POSTINC0,0,0
	IORWF     POSTDEC0,0,0
	BZ        @v8
	MOVFF     pSrcl,FSR0L
	MOVFF     pSrch,FSR0H
	MOVF      INDF0,0,0
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
	MOVLB  BANK0
	INCF      pDstl,1,1
	MOVLW     0
	ADDWFC    pDsth,1,1
	INCF      pSrcl,1,1;               pSrc.bRam++;
	ADDWFC    pSrch,1,1
	DECF      INDF2,1,0;               byte_to_send._word--;
	MOVLW     1
	BC        @v9
	DECF      PLUSW2,1,0
@v9:
	BRA       @v4
@v8:
	MOVLW     2;            }//end USBCtrlTrfTxService
	SUBWF     FSR1L,0,0
	BC        @v10
	CLRF      FSR1L,0
	MOVF      POSTDEC1,1,0
@v10:
	MOVWF     FSR1L,0
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

USBCtrlTrfRxService:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVLW     2
	ADDWF     FSR1L,1,0
	MOVLW     3
	MOVLB  BANK4
	ANDWF     ep0Bo,0,1
	MOVWF     INDF1,0
	MOVLW     1
	MOVFF     INDF1,PLUSW2
	MOVFF     ep0Bo+1,INDF2;        LSB(byte_to_read) = ep0Bo.Cnt;
	MOVF      POSTINC2,0,0;       wCount._word = wCount._word + byte_to_read._word;
	MOVLB  BANK0
	ADDWF     wCountl,1,1
	MOVF      POSTDEC2,0,0
	ADDWFC    wCounth,1,1
	MOVLW     0x28;               pSrc.bRam = (byte*)&CtrlTrfData;
	MOVWF     pSrcl,1
	MOVLW     4
	MOVWF     pSrch,1
@w4:
	MOVFF     FSR2L,FSR0L;        while(byte_to_read._word)
	MOVFF     FSR2H,FSR0H
	MOVF      POSTINC0,0,0
	IORWF     POSTDEC0,0,0
	BZ        @w1
	MOVFF     pSrcl,FSR0L;             *pDst.bRam = *pSrc.bRam;
	MOVFF     pSrch,FSR0H
	MOVF      INDF0,0,0
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
	INCF      pDstl,1,1;           pDst.bRam++;
	MOVLW     0
	ADDWFC    pDsth,1,1
	INCF      pSrcl,1,1;           pSrc.bRam++;
	ADDWFC    pSrch,1,1
	DECF      INDF2,1,0;           byte_to_read._word--;
	MOVLW     1
	BC        @w2
	DECF      PLUSW2,1,0
@w2:
	BRA       @w4
@w1:
	MOVLW     2;            }//end USBCtrlTrfRxService
	SUBWF     FSR1L,0,0
	BC        @w3
	CLRF      FSR1L,0
	MOVF      POSTDEC1,1,0
@w3:
	MOVWF     FSR1L,0
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

USBCtrlEPServiceComplete:
	BCF       UCONbits,PKTDIS,0;       UCONbits.PKTDIS = 0;
	MOVLB  BANK0
	MOVF      ctrl_trf_session_owner,0,1
	BNZ       @x1
	MOVLB  BANK4
	MOVLW     8
	MOVWF     ep0Bo+1,1
	MOVLW     0x20
	MOVWF     ep0Bo+2,1
	MOVLW     4
	MOVWF     ep0Bo+3,1
	MOVLW     0x84
	MOVWF     ep0Bo+0,1
	MOVLB  BANK4
	MOVWF     ep0Bi,1
	BRA       @x2   
@x1:
	MOVLB  BANK4
	BTFSS     SetupPkt,7,1
	BRA       @x3
	MOVLB  BANK0
	MOVF      wCountl,0,1
	MOVLB  BANK4
	SUBWF     SetupPkt+6,0,1
	MOVLB  BANK0
	MOVF      wCounth,0,1
	MOVLB  BANK4
	SUBWFB    SetupPkt+7,0,1
	BC        @x4
	MOVFF     SetupPkt+6,wCountl
	MOVFF     SetupPkt+7,wCounth
@x4:
	RCALL     USBCtrlTrfTxService
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_state,1
	MOVLB  BANK4
	MOVLW     8
	MOVWF     ep0Bo+1,1
	MOVLW     0x20
	MOVWF     ep0Bo+2,1
	MOVLW     4
	MOVWF     ep0Bo+3,1
	MOVLW     0x80
	MOVWF     ep0Bo+0,1
	MOVLB  BANK4
	MOVLW     0x28
	MOVWF     ep0Bi+2,1
	MOVLW     4
	MOVWF     ep0Bi+3,1
	MOVLW     0xc8
	MOVWF     ep0Bi,1
	BRA       @x2
@x3:
	MOVLB  BANK0
	MOVLW     2
	MOVWF     ctrl_trf_state,1
	MOVLB  BANK4
	CLRF      ep0Bi+1,1
	MOVLW     0xc8
	MOVWF     ep0Bi,1
	MOVLB  BANK4
	MOVLW     8
	MOVWF     ep0Bo+1,1
	MOVLW     0x28
	MOVWF     ep0Bo+2,1
	MOVLW     4
	MOVWF     ep0Bo+3,1
	MOVLW     0xc8
	MOVWF     ep0Bo+0,1
@x2:
	RETURN    0

;-----------------------------------------

USBPrepareForNextSetupTrf:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVF      POSTINC1,1,0
	MOVLW     2
	MOVLB  BANK0
	SUBWF     ctrl_trf_state,0,1
	BNZ       @y1
	MOVF      UCONbits,0,0
	ANDLW     0x10
	BZ        @y1
	MOVLB  BANK4
	MOVF      ep0Bo+1,0,1
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     8
	XORWF     tmpdatal,0,0
	BNZ       @y2
	MOVF      tmpdatah,0,0
@y2:
	BNZ       @y1
	MOVF      ep0Bo,0,1;           (ep0Bo.Stat.PID == SETUP_TOKEN) &&
	ANDLW     0x3c
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	SUBLW     0xd
	BNZ       @y1
	MOVF      ep0Bo,0,1;           (ep0Bo.Stat.UOWN == 0))
	ANDLW     0x80
	BNZ       @y1
	MOVLW     0x20
	MOVWF     ep0Bo+2,1
	MOVLW     4
	MOVWF     ep0Bo+3,1
	CLRF      INDF2,0;               for(setup_cnt = 0; setup_cnt < sizeof(CTRL_TRF_SETUP); setup_cnt++)      
@y4:
	MOVF      INDF2,0,0
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     8
	SUBWF     tmpdatal,0,0
	MOVLW     0
	SUBWFB    tmpdatah,0,0
	BC        @y3
	MOVF      INDF2,0,0;               *(((byte*)&SetupPkt)+setup_cnt) = *(((byte*)&CtrlTrfData)+setup_cnt); 
	CLRF      FSR0H,0
	ADDLW     0x28
	MOVWF     FSR0L,0
	MOVLW     4
	ADDWFC    FSR0H,1,0
	MOVF      INDF0,0,0
	MOVWF     POSTINC1,0
	MOVF      INDF2,0,0
	CLRF      FSR0H,0
	ADDLW     0x20
	MOVWF     FSR0L,0
	MOVLW     4
	ADDWFC    FSR0H,1,0
	MOVF      POSTDEC1,1,0
	MOVF      INDF1,0,0
	MOVWF     INDF0,0
	INCF      INDF2,1,0
	BRA       @y4
@y3:
	BRA       @y5;              else
@y1:
	MOVLB  BANK0
	CLRF      ctrl_trf_state,1
	MOVLB  BANK4
	MOVLW     8
	MOVWF     ep0Bo+1,1
	MOVLW     0x20
	MOVWF     ep0Bo+2,1
	MOVLW     4
	MOVWF     ep0Bo+3,1
	MOVLW     0x8c
	MOVWF     ep0Bo+0,1
	MOVLB  BANK4
	CLRF      ep0Bi,1
@y5:
	MOVF      POSTDEC1,1,0;   }//end USBPrepareForNextSetupTrf
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

USBCheckCDCRequest:
	MOVLB  BANK4
	MOVF      SetupPkt,0,1
	ANDLW     0x1f
	SUBLW     1
	BZ        @g1
	BRA       @break
@g1:
	MOVF      SetupPkt,0,1;       if(SetupPkt.RequestType != CLASS) ;
	ANDLW     0x60
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	SUBLW     1
	BZ        @h1
	BRA       @break
@h1:
	MOVF      SetupPkt+4,0,1 ;      if((SetupPkt.bIntfID != CDC_COMM_INTF_ID)&&
	BZ        @h2
	DECF      SetupPkt+4,0,1
	BZ        @h2
	BRA       @break
@h2:
	MOVF      SetupPkt+1,0,1  ;     switch(SetupPkt.bRequest)
	XORLW     0x23
	BZ        @h3
	XORLW     1
	BZ        @h4
	XORLW     3
	BZ        @h5
	XORLW     1
	BZ        @h6
	XORLW     0x24
	BZ        @h7
	XORLW     7
	BZ        @h8
	XORLW     1
	BZ        @h9
	XORLW     3
	BZ        @h10
	XORLW     1
	BZ        @h11
	BRA @break
@h11:
	MOVLB  BANK0
	MOVLW     3
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     0xe6
	MOVWF     pSrcl,1
	MOVLW     1
	MOVWF     pSrch,1
	MOVLB  BANK1
	BCF       usb_stat,1,1
	MOVLB  BANK0
	MOVLW     8
	MOVWF     wCountl,1
	BRA       @break
@h10:
	MOVLB  BANK0
	MOVLW     3
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     0xe6
	MOVWF     pDstl,1
	MOVLW     1
	MOVWF     pDsth,1
	BRA       @break
@h9:
	BRA       @break
@h8:
	BRA       @break
@h7:
	BRA       @break
@h6:
	MOVLB  BANK0
	MOVLW     3
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     0xde
	MOVWF     pDstl,1
	MOVLW     1
	MOVWF     pDsth,1
	BRA       @break
@h5:
	MOVLB  BANK0
	MOVLW     3
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     0xde
	MOVWF     pSrcl,1
	MOVLW     1
	MOVWF     pSrch,1
	MOVLB  BANK1
	BCF       usb_stat,1,1
	MOVLB  BANK0
	MOVLW     7
	MOVWF     wCountl,1
	BRA       @break
@h4:
	MOVLB  BANK0
	MOVLW     3
	MOVWF     ctrl_trf_session_owner,1
	MOVFF     SetupPkt+2,control_signal_bitmap
	BRA       @break
@h3:
	BRA       @break
@break:
	RETURN    0

;-----------------------------------------

CDCInitEP:
	MOVLB  BANK1
	CLRF      line_coding,1
	MOVLW     0xc2
	MOVWF     line_coding+1,1
	MOVLW     1
	MOVWF     line_coding+2,1
	CLRF      line_coding+3,1
	CLRF      line_coding+4,1;           line_coding.bCharFormat = 0x00;             // 1 stop bit
	CLRF      line_coding+5,1;           line_coding.bParityType = 0x00;             // None
	MOVLW     8
	MOVWF     line_coding+6,1
	CLRF      cdc_trf_state,1;           cdc_trf_state = CDC_TX_READY;
	CLRF      cdc_rx_len,1 ;          cdc_rx_len = 0;
	MOVLW     0x1a      ;         CDC_COMM_UEP = EP_IN|HSHK_EN;               // Enable 1 Comm pipe            
	MOVWF     UEP2,0
	MOVLW     0x1e       ;        CDC_DATA_UEP = EP_OUT_IN|HSHK_EN;           // Enable 2 data pipes           
	MOVWF     UEP3,0
	MOVLB  BANK4
	MOVLW     0x30
	MOVWF     ep2Bi+2,1
	MOVLW     4
	MOVWF     ep2Bi+3,1
	MOVLW     0x40        ;       CDC_INT_BD_IN.Stat._byte = _UCPU|_DAT1;     // Set status
	MOVWF     ep2Bi,0x1
	MOVLB  BANK4
	MOVWF     ep3Bo+1,1
	MOVLW     0x38        ;       CDC_BULK_BD_OUT.ADR = (byte*)&cdc_data_rx;  // Set buffer address            
	MOVWF     ep3Bo+2,1
	MOVLW     4
	MOVWF     ep3Bo+3,1
	MOVLW     0x88         ;      CDC_BULK_BD_OUT.Stat._byte = _USIE|_DAT0|_DTSEN;// Set status
	MOVWF     ep3Bo+0,1
	MOVLB  BANK4
	MOVLW     0x78
	MOVWF     ep3Bi+2,1
	MOVLW     4
	MOVWF     ep3Bi+3,1
	MOVLW     0x40          ;     CDC_BULK_BD_IN.Stat._byte = _UCPU|_DAT1;    // Set buffer address            
	MOVWF     ep3Bi+0,1
	RETURN    0

;-----------------------------------------

getsUSBUSART:
	MOVFF     FSR2L,POSTINC1;    byte getsUSBUSART(char *buffer, byte len)
	MOVFF     FSR1L,FSR2L
	MOVLB  BANK1
	CLRF      cdc_rx_len,1
	MOVLB  BANK4
	BTFSC     ep3Bo,7,1
	BRA       @i3
	MOVLW     0xfc
	MOVFF     PLUSW2,0x18
	MOVF      ep3Bo+1,0,1
	BSF       STATUS,C,0
	SUBFWB    tmpdatal,0,0
	BC        @i1
	MOVLW     0xfc
	MOVFF     ep3Bo+1,PLUSW2
@i1:
	MOVLB  BANK1
	CLRF      cdc_rx_len,1
@i4:
	MOVLW     0xfc
	MOVF      PLUSW2,0,0
	SUBWF     cdc_rx_len,0,1
	BC        @i2
	MOVF      cdc_rx_len,0,1;               buffer[cdc_rx_len] = cdc_data_rx[cdc_rx_len];
	CLRF      FSR0H,0
	ADDLW     0x38
	MOVWF     FSR0L,0
	MOVLW     4
	ADDWFC    FSR0H,1,0
	MOVF      INDF0,0,0
	MOVWF     POSTINC1,0
	MOVF      cdc_rx_len,0,1
	MOVWF     INDF1,0
	MOVLW     0xfd
	MOVFF     PLUSW2,FSR0L
	MOVLW     0xfe
	MOVFF     PLUSW2,FSR0H
	MOVF      INDF1,0,0
	ADDWF     FSR0L,1,0
	MOVLW     0
	ADDWFC    FSR0H,1,0
	MOVF      POSTDEC1,1,0
	MOVF      INDF1,0,0
	MOVWF     INDF0,0
	INCF      cdc_rx_len,1,1
	BRA       @i4
@i2:
	MOVLB  BANK4
	MOVLW     0x40
	MOVWF     ep3Bo+1,1
	ANDWF     ep3Bo,1,1;           mUSBBufferReady(CDC_BULK_BD_OUT);
	BTG       ep3Bo,6,1
	MOVLW     0x88
	IORWF     ep3Bo,1,1
@i3:
	MOVLB  BANK1
	MOVF      cdc_rx_len,0,1
	BRA       @i5
@i5:
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

putsUSBUSART:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVF      POSTINC1,1,0
	MOVLB  BANK1
	MOVF      cdc_trf_state,0,1
	BZ        @j1
	BRA       @j6
@j1:
	CLRF      INDF2,0 ;          len = 0;
@J4:
	INCF      INDF2,1,0;           len++;
	MOVF      INDF2,0,0 ;          if(len == 255) break;       // Break loop once max len is reached.       
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     0xff
	XORWF     tmpdatal,0,0
	BNZ       @j2
	MOVF      tmpdatah,0,0
@j2:
	BNZ       @j3
	BRA       @j7
@j3:
	MOVLW     0xfd          ;     }while(*data++);
	MOVFF     PLUSW2,FSR0L
	INCF      PLUSW2,1,0
	MOVLW     0xfe
	MOVFF     PLUSW2,FSR0H
	BNC       @J5
	INCF      PLUSW2,1,0
@J5:
	MOVF      INDF0,0,0
	BNZ       @J4
@j7:
	MOVF      INDF2,0,0   ;    data-=len;
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVF      FSR2L,0,0
	ADDLW     0xfd
	MOVWF     FSR0L,0
	MOVLW     0xff
	ADDWFC    FSR2H,0,0
	MOVWF     FSR0H,0
	MOVF      tmpdatal,0,0
	SUBWF     POSTINC0,1,0
	MOVF      tmpdatah,0,0
	SUBWFB    POSTDEC0,1,0
	MOVLW     0xfd            ;   mUSBUSARTTxRam((byte*)data,len);     // See cdc.h
	MOVFF     PLUSW2,pCDCSrcl
	MOVLW     0xfe
	MOVFF     PLUSW2,pCDCSrch
	MOVFF     INDF2,cdc_tx_len
	MOVLB  BANK1
	CLRF      cdc_mem_type,1
	MOVLW     1
	MOVWF     cdc_trf_state,1
@j6:
	MOVF      POSTDEC1,1,0 ;  }//end putsUSBUSART
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

putrsUSBUSART:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVF      POSTINC1,1,0
	MOVLB  BANK1
	MOVF      cdc_trf_state,0,1
	BZ        @k1
	BRA       @k6
@k1:
	CLRF      INDF2,0;           len = 0;
@k5:
	INCF      INDF2,1,0;           len++;
	MOVF      INDF2,0,0 ;          if(len == 255) break;       // Break loop once max len is reached.       
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     0xff
	XORWF     tmpdatal,0,0
	BNZ       @k2
	MOVF      tmpdatah,0,0
@k2:
	BNZ       @k3
	BRA       @k7
@k3:
	MOVLW     0xfd;               }while(*data++);
	MOVFF     PLUSW2,TBLPTRL
	INCF      PLUSW2,1,0
	MOVLW     0xfe
	MOVFF     PLUSW2,TBLPTRH
	BNC       @k4
	INCF      PLUSW2,1,0
@k4:
	TBLRD*
	MOVF      TABLAT,0,0
	BNZ       @k5
@k7:
	MOVF      INDF2,0,0;       data-=len;
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVF      FSR2L,0,0
	ADDLW     0xfd
	MOVWF     FSR0L,0
	MOVLW     0xff
	ADDWFC    FSR2H,0,0
	MOVWF     FSR0H,0
	MOVF      tmpdatal,0,0
	SUBWF     POSTINC0,1,0
	MOVF      tmpdatah,0,0
	SUBWFB    POSTDEC0,1,0
	MOVLW     0xfd;               mUSBUSARTTxRom((rom byte*)data,len); // See cdc.h
	MOVFF     PLUSW2,pCDCSrcl
	MOVLW     0xfe
	MOVFF     PLUSW2,pCDCSrch
	MOVFF     INDF2,cdc_tx_len
	MOVLB  BANK1
	MOVLW     1
	MOVWF     cdc_mem_type,1
	MOVWF     cdc_trf_state,1
@k6:
	MOVF      POSTDEC1,1,0;   }//end putrsUSBUSART
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

CDCTxService:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVF      POSTINC1,1,0
	MOVLB  BANK4
	BTFSC     ep3Bi,7,1
	BRA       @l14
	MOVLW     3
	MOVLB  BANK1
	SUBWF     cdc_trf_state,0,1
	BNZ       @l0
	CLRF      cdc_trf_state,1;               cdc_trf_state = CDC_TX_READY;
@l0:
	MOVF      cdc_trf_state,0,1;       if(cdc_trf_state == CDC_TX_READY;
	BNZ       @l1
	BRA       @l14
@l1:
	MOVLW     2
	SUBWF     cdc_trf_state,0,1
	BNZ       @l2
	MOVLB  BANK4
	CLRF      ep3Bi+1,1
	MOVLB  BANK1
	MOVLW     3
	MOVWF     cdc_trf_state,1
	BRA       @l3;      else if(cdc_trf_state == CDC_TX_BUSY)
@l2:
	DECF      cdc_trf_state,0,1
	BNZ       @l3
	MOVLW     0x40          ;     	if(cdc_tx_len > sizeof(cdc_data_tx))
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVF      cdc_tx_len,0,1
	SUBWF     tmpdatal,0,0
	MOVLW     0
	SUBWFB    tmpdatah,0,0
	BC        @l4
	MOVLW     0x40           ;    	    byte_to_send = sizeof(cdc_data_tx);
	MOVWF     INDF2,0
	BRA       @l15
@l4:
	MOVFF     cdc_tx_len,INDF2      ;  	    byte_to_send = cdc_tx_len;
@l15:
	MOVFF     INDF2,ep3Bi+1       ;     CDC_BULK_BD_IN.Cnt = byte_to_send;
	MOVF      INDF2,0,0       ;	cdc_tx_len = cdc_tx_len - byte_to_send;
	SUBWF     cdc_tx_len,0,1
	MOVWF     cdc_tx_len,1
	MOVLW     0x78
	MOVWF     pCDCDstl,1
	MOVLW     4
	MOVWF     pCDCDsth,1
	DECF      cdc_mem_type,0,1        ;   if(cdc_mem_type == _ROM)            // Determine type of memory source   
	BNZ       @l5
@l16:
	MOVF      INDF2,0,0        ;       while(byte_to_send)
	BZ        @l6
	MOVFF     pCDCSrcl,TBLPTRL
	MOVFF     pCDCSrch,TBLPTRH
	TBLRD*
	MOVF      TABLAT,0,0
	MOVFF     pCDCDstl,FSR0L
	MOVFF     pCDCDsth,FSR0H
	MOVWF     INDF0,0
	INCF      pCDCDstl,1,1
	MOVLW     0
	ADDWFC    pCDCDsth,1,1
	INCF      pCDCSrcl,1,1
	ADDWFC    pCDCSrch,1,1
	DECF      INDF2,1,0
	BRA       @l16
@l6:
	BRA       @l11
@l5:
	MOVF      INDF2,0,0         ;      while(byte_to_send)
	BZ        @l11
	MOVFF     pCDCSrcl,FSR0L
	MOVFF     pCDCSrch,FSR0H
	MOVF      INDF0,0,0
	MOVFF     pCDCDstl,FSR0L
	MOVFF     pCDCDsth,FSR0H
	MOVWF     INDF0,0
	INCF      pCDCDstl,1,1
	MOVLW     0
	ADDWFC    pCDCDsth,1,1
	INCF      pCDCSrcl,1,1
	ADDWFC    pCDCSrch,1,1
	DECF      INDF2,1,0
	BRA       @l5
@l11:
	MOVF      cdc_tx_len,0,1;           if(cdc_tx_len == 0)
	BNZ       @l3
	MOVLB  BANK4
	MOVF      ep3Bi+1,0,1
	MOVWF     tmpdatal,0
	CLRF      tmpdatah,0
	MOVLW     0x40
	XORWF     tmpdatal,0,0
	BNZ       @l12
	MOVF      tmpdatah,0,0
@l12:
	BNZ       @l13
	MOVLB  BANK1
	MOVLW     2
	MOVWF     cdc_trf_state,1
	BRA       @l3
@l13:
	MOVLB  BANK1
	MOVLW     3
	MOVWF     cdc_trf_state,1
@l3:
	MOVLW     0x40;               mUSBBufferReady(CDC_BULK_BD_IN);
	MOVLB  BANK4
	ANDWF     ep3Bi,1,1
	BTG       ep3Bi,6,1
	MOVLW     0x88
	IORWF     ep3Bi,1,1
@l14:
	MOVF      POSTDEC1,1,0;   }//end CDCTxService
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------

USBCheckStdRequest:
	MOVLB  BANK4
	MOVF      SetupPkt,0,1
	ANDLW     0x60
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	RRNCF     WREG,1,0
	IORLW     0
	BZ        @m1
	BRA       @mexit
@m1:
	MOVF      SetupPkt+1,0,1  ;     switch(SetupPkt.bRequest)
	XORLW     7
	BZ        @mbreak
	XORLW     0xb
	BZ        @mbreak
	XORLW     7
	BZ        @m2
	XORLW     1
	BZ        @m3
	XORLW     0xb
	BZ        @m4
	XORLW     2
	BZ        @m4
	XORLW     3
	BZ        @m5
	XORLW     8
	BZ        @m6
	XORLW     1
	BZ        @m7
	XORLW     0xf
	BZ        @m8
	XORLW     3
	BZ        @m9
	BRA       @mbreak
@m9:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK1
	MOVLW     4
	MOVWF     usb_device_state,1
	BRA       @mexit
@m8:
	RCALL     USBStdGetDscHandler
	BRA       @mexit
@m7:
	RCALL     USBStdSetCfgHandler
	BRA       @mexit
@m6:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     0xfa
	MOVWF     pSrcl,1
	MOVLW     1
	MOVWF     pSrch,1
	MOVLB  BANK1
	BCF       usb_stat,1,1
	MOVLB  BANK0
	MOVLW     1
	MOVWF     wCountl,1
	BRA       @mexit
@m5:
	RCALL     USBStdGetStatusHandler
	BRA       @mexit
@m4:
	RCALL     USBStdFeatureReqHandler
	BRA       @mexit
@m3:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+4,0,1
	MOVLB  BANK0
	MOVWF     pSrcl,1
	CLRF      pSrch,1
	MOVLW     0xfb
	ADDWF     pSrcl,1,1
	MOVLW     1
	ADDWFC    pSrch,1,1
	MOVLB  BANK1
	BCF       usb_stat,1,1
	MOVLB  BANK0
	MOVLW     1
	MOVWF     wCountl,1
	BRA       @mexit
@m2:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+4,0,1
	CLRF      FSR0H,0
	ADDLW     0xfb
	MOVWF     FSR0L,0
	MOVLW     1
	ADDWFC    FSR0H,1,0
	MOVFF     SetupPkt+2,INDF0
	BRA       @mexit
@mbreak:
	BRA       @mexit
@mexit
	RETURN    0

;-----------------------------------------

USBStdGetDscHandler:
	MOVLW     0x80           ;    if(SetupPkt.bmRequestType == 0x80)
	MOVLB  BANK4
	SUBWF     SetupPkt,0,1
	BNZ       @n1
	MOVF      SetupPkt+3,0,1    ;       switch(SetupPkt.bDscType)
	XORLW     3
	BZ        @n2
	XORLW     1
	BZ        @n3
	XORLW     3
	BZ        @n4
	BRA       @n5
@n4:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK0
	MOVLW     low device_dsc
	MOVWF     pSrcl,1
	MOVLW     high device_dsc
	MOVWF     pSrch,1
	MOVLW     0x12	;len device_dsc struc
	MOVLB  BANK0
	MOVWF     wCountl,1
	CLRF      wCounth,1
	BRA       @n5
@n3:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+2,0,1
	MOVWF     TBLPTRL,0
	CLRF      TBLPTRH,0
	BCF       STATUS,C,0
	RLCF      TBLPTRL,1,0
	RLCF      TBLPTRH,1,0
	MOVLW     low (desccimtabla+1)
	ADDWF     TBLPTRL,1,0
	MOVLW     high (desccimtabla+1)
	ADDWFC    TBLPTRH,1,0
	TBLRD*+			;POSTINC
	MOVFF     TABLAT,pSrcl
	TBLRD*-			;POSTDEC
	MOVFF     TABLAT,pSrch
	MOVLW     2
	MOVLB  BANK0
	CLRF      TBLPTRH,0
	ADDWF     pSrcl,0,1
	MOVWF     TBLPTRL,0
	MOVF      pSrch,0,1
	ADDWFC    TBLPTRH,1,0
	TBLRD*+			;POSTINC
	MOVFF     TABLAT,wCountl
	TBLRD*-			;POSTDEC
	MOVFF     TABLAT,wCounth
	BRA       @n5
@n2:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+2,0,1
	MOVWF     TBLPTRL,0
	CLRF      TBLPTRH,0
	BCF       STATUS,C,0
	RLCF      TBLPTRL,1,0
	RLCF      TBLPTRH,1,0
	MOVLW     low (desccimtabla+5)
	ADDWF     TBLPTRL,1,0
	MOVLW     high (desccimtabla+5)
	ADDWFC    TBLPTRH,1,0
	TBLRD*+			;POSTINC
	MOVFF     TABLAT,pSrcl
	TBLRD*-			;POSTDEC
	MOVFF     TABLAT,pSrch
	MOVFF     pSrcl,TBLPTRL
	MOVFF     pSrch,TBLPTRH
	TBLRD*
	MOVF      TABLAT,0,0
	MOVLB  BANK0
	MOVWF     wCountl,1
	CLRF      wCounth,1
	BRA       @n5
@n5:
	MOVLB  BANK1
	BSF       usb_stat,1,1
@n1:
	RETURN    0

;-----------------------------------------

USBStdSetCfgHandler:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLW     0xf
	MOVWF     POSTINC1,0
	MOVLW     0x71
	MOVWF     POSTINC1,0
	MOVLW     0xf
	MOVWF     POSTINC1,0
	CALL      ClearArray,0
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVLW     1
	MOVWF     POSTINC1,0
	MOVLW     0xfb
	MOVWF     POSTINC1,0
	MOVLW     1
	MOVWF     POSTINC1,0
	CALL      ClearArray,0
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVFF     SetupPkt+2,usb_active_cfg     ;   usb_active_cfg = SetupPkt.bCfgValue;
	MOVLB  BANK4
	MOVF      SetupPkt+2,0,1
	BNZ       @o1
	MOVLB  BANK1
	MOVLW     5
	MOVWF     usb_device_state,1
	BRA       @o2
@o1:
	MOVLB  BANK1
	MOVLW     6
	MOVWF     usb_device_state,1
	CALL      CDCInitEP,0
@o2:
	RETURN    0

;-----------------------------------------

USBStdGetStatusHandler:
	MOVLB  BANK4
	CLRF      CtrlTrfData,1
	CLRF      CtrlTrfData+1,1    ;       CtrlTrfData._byte1 = 0;
	MOVLB  BANK4
	MOVF      SetupPkt,0,1
	ANDLW     0x1f
	XORLW     2
	BZ        @p1
	XORLW     3
	BZ        @p2
	XORLW     1
	BZ        @p3
	BRA       @p7
@p3:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	BSF       CtrlTrfData,0,1
	MOVLB  BANK1
	BTFSS     usb_stat,0,1
	BRA       @p8
	MOVLB  BANK4
	BSF       CtrlTrfData,1,1
@p8:
	BRA       @p7
@p2:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	BRA       @p7
@p1:
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+4,0,1
	ANDLW     0xf
	MULLW     8
	MOVF      PRODL,0,0
	CLRF      tmpdatah,0
	ADDLW     0
	MOVWF     tmpdatal,0
	MOVLW     4
	ADDWFC    tmpdatah,1,0
	MOVF      SetupPkt+4,0,1
	ANDLW     0x80
	BZ        @p4
	MOVLW     1
@p4:
	MULLW     4
	MOVF      PRODL,0,0
	MOVLB  BANK0
	ADDWF     tmpdatal,0,0
	MOVWF     pDstl,1
	MOVLW     0
	ADDWFC    tmpdatah,0,0
	MOVWF     pDsth,1
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVF      INDF0,0,0
	ANDLW     4
	BZ        @p5
	MOVLB  BANK4
	MOVLW     1
	MOVWF     CtrlTrfData,1
@p5:
	BRA       @p7
@p7:
	MOVLB  BANK0
	DECF      ctrl_trf_session_owner,0,1
	BNZ       @p6
	MOVLB  BANK0
	MOVLW     0x28
	MOVWF     pSrcl,1
	MOVLW     4
	MOVWF     pSrch,1
	MOVLB  BANK1
	BCF       usb_stat,1,1
	MOVLB  BANK0
	MOVLW     2
	MOVWF     wCountl,1
@p6:
	RETURN    0

;-----------------------------------------

USBStdFeatureReqHandler:
	MOVLB  BANK4
	DECF      SetupPkt+2,0,1
	BNZ       @q1
	MOVF      SetupPkt,0,1
	ANDLW     0x1f
	IORLW     0
	BNZ       @q1
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLW     3
	MOVLB  BANK4
	SUBWF     SetupPkt+1,0,1
	BNZ       @q2
	MOVLB  BANK1
	BSF       usb_stat,0,1
	BRA       @q1
@q2:
	MOVLB  BANK1
	BCF       usb_stat,0,1
@q1:
	MOVLB  BANK4
	MOVF      SetupPkt+2,0,1
	BNZ       @q3
	MOVF      SetupPkt,0,1
	ANDLW     0x1f
	SUBLW     2
	BNZ       @q3
	MOVF      SetupPkt+4,0,1 
	ANDLW     0xf
	IORLW     0
	BZ        @q3
	MOVLB  BANK0
	MOVLW     1
	MOVWF     ctrl_trf_session_owner,1
	MOVLB  BANK4
	MOVF      SetupPkt+4,0,1
	ANDLW     0xf
	MULLW     8
	MOVF      PRODL,0,0
	CLRF      tmpdatah,0
	ADDLW     0
	MOVWF     tmpdatal,0
	MOVLW     4
	ADDWFC    tmpdatah,1,0
	MOVF      SetupPkt+4,0,1
	ANDLW     0x80
	BZ        @q4
	MOVLW     1
@q4:
	MULLW     4
	MOVF      PRODL,0,0
	MOVLB  BANK0
	ADDWF     tmpdatal,0,0
	MOVWF     pDstl,1
	MOVLW     0
	ADDWFC    tmpdatah,0,0
	MOVWF     pDsth,1
	MOVLW     3
	MOVLB  BANK4
	SUBWF     SetupPkt+1,0,1
	BNZ       @q5
	MOVLW     0x84
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
	BRA       @q3
@q5:
	BTFSS     SetupPkt+4,7,1  ;             if(SetupPkt.EPDir == 1) // IN
	BRA       @q6
	MOVLW     0x40
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
	BRA       @q3
@q6:
	MOVLW     0x88
	MOVFF     pDstl,FSR0L
	MOVFF     pDsth,FSR0H
	MOVWF     INDF0,0
@q3:
	RETURN    0 



;-----------------------------------------


_startup:
	clrf PORTA
	clrf PORTB
	clrf PORTC
	clrf PORTD
	clrf PORTE

	mov TRISA,0	;mind kimenet
	mov TRISB,0ff	;mind bemenet
	mov TRISE,0ff	;mind bemenet
	mov TRISC,B'00111010'	;c2 sarga led, c6,7 kimenetek, 0/1 a clock	
	mov TRISD,B'11000000'   ;d7,6 gombok, d0,d1 led 2,3,4,5 kimenetek 
	clrf	PORTC           ; az uj nyaknak a portD7-et kiegettem, sajnos 
	clrf	PORTD
	mov ADCON1,B'00001111'  ;all DIGITAL i/o
	MCLR_HI

	call kezdvill

	clrf input_buffer
	clrf kuldheto,0
	 mov irqszamlalo,40

	mov T1CON,B'00001111' 	; 2x8 bit,1:1 prescaler
	mov TMR1H,high timer1ertek
	mov TMR1L,low timer1ertek
	bsf PIE1,TMR1IE
	bsf INTCON,PEIE
	bsf INTCON,GIE		;enable general interrupt


	LFSR 1, _stack
	LFSR 2, _stack
	CLRF      TBLPTRU, 0
	RCALL      _do_cinit

	CLRF      buffer_pointer,BANKED
;	MOVLW     0x27 		;
;	MOVWF     tx_min,1
	MOVLW     0x14		;0x14 high speed             
	MOVWF     UCFGbits,0
	MOVLB  BANK1
	CLRF      usb_device_state,1
	CLRF      usb_stat,1
	CLRF      usb_active_cfg,1

  while2:
	RCALL     USBTasks

ProcessIO:
	MOVLW     6
	MOVLB  BANK1
	SUBWF     usb_device_state,0,1
	BNC       @e1
	MOVF      UCONbits,0,0
	ANDLW     2
	BZ        @e2
@e1:
	BRA       @e3
@e2:
	RCALL     User_Process

@e3:
	BRA while2
	return 0	;csak szepseg miatt


;-----------------------------------------

USBCheckBusStatus:
	BTFSS     UCONbits,3,0 ;          if(UCONbits.USBEN == 0)
	RCALL     USBModuleEnable
	BRA       @ucbs1           ;   else
	BTFSC     UCONbits,3,0   ;        if(UCONbits.USBEN == 1)
	RCALL     USBModuleDisable
@ucbs1:
	MOVLB  BANK1
	DECF      usb_device_state,0,1
	BNZ       @ucbs2
	BTFSC     UCONbits,SE0,0     ;      if(!UCONbits.SE0)
	BRA       @ucbs2
	CLRF      UIRbits,0
	CLRF      UIEbits,0
	BSF       UIEbits,0,0      ;         UIEbits.URSTIE = 1;             // Unmask RESET interrupt            
	BSF       UIEbits,IDLEIE,0       ;        UIEbits.IDLEIE = 1;             // Unmask IDLE interrupt             
	MOVLW     2
	MOVWF     usb_device_state,1
@ucbs2:
	RETURN    0

;-----------------------------------------

USBModuleEnable:
	CLRF      UCONbits,0    ;       UCON = 0;
	CLRF      UIEbits,0     ;      UIE = 0;
	BSF       UCONbits,USBEN,0  ;     UCONbits.USBEN = 1;
	MOVLB  BANK1
	MOVLW     1
	MOVWF     usb_device_state,1
	RETURN    0

;-----------------------------------------

USBModuleDisable:
	CLRF      UCONbits,0       ;    UCON = 0;
	CLRF      UIEbits,0        ;   UIE = 0;
	MOVLB  BANK1
	CLRF      usb_device_state,1
	RETURN    0

;-----------------------------------------

USBSoftDetach:
	GOTO      USBModuleDisable  

;-----------------------------------------

USBDriverService:
	MOVLB  BANK1
	MOVF      usb_device_state,0,1
	BNZ       @uds1
	BRA       @uds2
@uds1:
	MOVF      UIRbits,0,0;       if(UIRbits.ACTVIF && UIEbits.ACTVIE)    USBWakeFromSuspend();
	ANDLW     4
	BZ        @uds3
	MOVF      UIEbits,0,0
	ANDLW     4
	BZ        @uds3
	RCALL     USBWakeFromSuspend
@uds3:
	BTFSC     UCONbits,SUSPND,0;       if(UCONbits.SUSPND==1) return;
	BRA       @uds2
	MOVF      UIRbits,0,0;       if(UIRbits.URSTIF && UIEbits.URSTIE)    USBProtocolResetHandler();           
	ANDLW     1
	BZ        @uds4
	MOVF      UIEbits,0,0
	ANDLW     1
	BZ        @uds4
	RCALL     USBProtocolResetHandler
@uds4:
	MOVF      UIRbits,0,0 ;      if(UIRbits.IDLEIF && UIEbits.IDLEIE)    USBSuspend();
	ANDLW     0x10
	BZ        @uds5
	MOVF      UIEbits,0,0
	ANDLW     0x10
	BZ        @uds5
	RCALL     USBSuspend
@uds5:
	MOVF      UIRbits,0,0;       if(UIRbits.SOFIF && UIEbits.SOFIE)      USB_SOF_Handler();
	ANDLW     0x40
	BZ        @uds6
	MOVF      UIEbits,0,0
	ANDLW     0x40
	BZ        @uds6
	RCALL     USB_SOF_Handler
@uds6:
	MOVF      UIRbits,0,0 ;      if(UIRbits.STALLIF && UIEbits.STALLIE)  USBStallHandler();
	ANDLW     0x20
	BZ        @uds7
	MOVF      UIEbits,0,0
	ANDLW     0x20
	BZ        @uds7
	RCALL     USBStallHandler
@uds7:
	MOVF      UIRbits,0,0  ;     if(UIRbits.UERRIF && UIEbits.UERRIE)    USBErrorHandler();
	ANDLW     2
	BZ        @uds8
	MOVF      UIEbits,0,0
	ANDLW     2
	BZ        @uds8
	RCALL     USBErrorHandler
@uds8:
	MOVLW     3
	MOVLB  BANK1
	SUBWF     usb_device_state,0,1
	BC        @uds9
	BRA       @uds2
@uds9:
	MOVLB  BANK1
	CLRF      bTRNIFCount,1
@uds12:
	MOVLW     4
	SUBWF     bTRNIFCount,0,1
	BC        @uds2
	MOVF      UIRbits,0,0   ;        if(UIRbits.TRNIF && UIEbits.TRNIE)
	ANDLW     8
	BZ        @uds10
	MOVF      UIEbits,0,0
	ANDLW     8
	BZ        @uds10
	CALL      USBCtrlEPService,0
	IORLW     0
	BNZ       @uds11
	BCF       UIRbits,TRNIF,0;   		        UIRbits.TRNIF = 0;
@uds11:
	MOVLB  BANK1
	INCF      bTRNIFCount,1,1
	BRA       @uds12
@uds10:
	BRA       @uds2
@uds2:
	RETURN    0

;-----------------------------------------

USBSuspend:
	BSF       UIEbits,ACTVIE,0;       UIEbits.ACTVIE = 1;
	BCF       UIRbits,IDLEIF,0;       UIRbits.IDLEIF = 0;
	BSF       UCONbits,SUSPND,0;       UCONbits.SUSPND = 1;
	BCF       PIR2,USBIF,0;       PIR2bits.USBIF = 0;
	BSF       PIE2,USBIE,0;       PIE2bits.USBIE = 1;
	SLEEP
	BCF       PIE2,USBIE,0;       PIE2bits.USBIE = 0;
	RETURN    0

;-----------------------------------------

USBWakeFromSuspend:
	BCF       UCONbits,SUSPND,0;       UCONbits.SUSPND = 0;
	BCF       UIEbits,ACTVIE,0;       UIEbits.ACTVIE = 0;
@uwfs2:
	BTFSS     UIRbits,ACTVIF,0;       while(UIRbits.ACTVIF){UIRbits.ACTVIF = 0;}  // Added
	BRA       @uwfs1
	BCF       UIRbits,ACTVIF,0
	BRA       @uwfs2
@uwfs1:
	RETURN    0

;-----------------------------------------

USBRemoteWakeup:
	MOVLB  BANK1
	BTFSS     usb_stat,0,1
	BRA       @urw1
	BCF       UCONbits,SUSPND,0 ;          UCONbits.SUSPND = 0;
	BSF       UCONbits,RESUME,0  ;         UCONbits.RESUME = 1;
	MOVLB  BANK1
	MOVLW     8
	MOVWF     delay_countl,1
	MOVLW     7
	MOVWF     delay_counth,1
@urw2:
	DECF      delay_countl,1,1 ;              delay_count--;
	MOVLW     0
	SUBWFB    delay_counth,1,1
	MOVF      delay_countl,0,1  ;         }while(delay_count);
	IORWF     delay_counth,0,1
	BNZ       @urw2
	BCF       UCONbits,RESUME,0   ;        UCONbits.RESUME = 0;
@urw1:
	RETURN    0

;-----------------------------------------

USB_SOF_Handler:
	BCF       UIRbits,SOFIF,0    ;   UIRbits.SOFIF = 0;
	RETURN    0

;-----------------------------------------

USBStallHandler:
	BTFSS     UEP0bits,EPSTALL,0     ;  if(UEP0bits.EPSTALL == 1)
	BRA       @ush1
	MOVLW     0x80
	MOVLB  BANK4
	SUBWF     ep0Bo,0,1
	BNZ       @ush2
	MOVLW     0x84
	MOVLB  BANK4
	SUBWF     ep0Bi,0,1
	BNZ       @ush2
	MOVLB  BANK4
	MOVLW     0x8c
	MOVWF     ep0Bo,1
@ush2:
	BCF       UEP0bits,EPSTALL,0;           UEP0bits.EPSTALL = 0;         	    // Clear STALL status
@ush1:
	BCF       UIRbits,STALLIF,0 ;      UIRbits.STALLIF = 0;
	RETURN    0

;-----------------------------------------

USBErrorHandler:
	CLRF      UEIRbits,0      ;      UEIR = 0;
	RETURN    0

;-----------------------------------------

USBProtocolResetHandler:
	CLRF      UEIRbits,0 ;          UEIR = 0;
	CLRF      UIRbits,0  ;         UIR = 0;
	MOVLW     0x9f       ;        UEIE = 0b10011111;              // Unmask all USB error interrupts           
	MOVWF     UEIEbits,0
	MOVLW     0x7b        ;       UIE = 0b01111011;               // Enable all interrupts except ACTVIE       
	MOVWF     UIEbits,0
	CLRF      UADDR,0     ;      UADDR = 0x00;
	MOVLW     0xf
	MOVWF     POSTINC1,0
	MOVLW     0x71
	MOVWF     POSTINC1,0
	MOVLW     0xf
	MOVWF     POSTINC1,0
	RCALL     ClearArray
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVF      POSTDEC1,1,0
	MOVLW     0x16          ;     UEP0 = EP_CTRL|HSHK_EN;         // Init EP0 as a Ctrl EP, see usbdrv.h       
	MOVWF     UEP0bits,0
@uprh2:
	BTFSS     UIRbits,TRNIF,0   ;    while(UIRbits.TRNIF == 1)       // Flush any pending transactions            
	BRA       @uprh1
	BCF       UIRbits,TRNIF,0    ;       UIRbits.TRNIF = 0;
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	BRA       @uprh2
@uprh1:
	BCF       UCONbits,PKTDIS,0     ;  UCONbits.PKTDIS = 0;            // Make sure packet processing is enabled    
	CALL      USBPrepareForNextSetupTrf,0	;    // Declared in usbctrltrf.c
	MOVLB  BANK1
	BCF       usb_stat,0,1
	MOVLB  BANK1
	CLRF      usb_active_cfg,1
	MOVLB  BANK1
	MOVLW     3
	MOVWF     usb_device_state,1
	RETURN    0

;-----------------------------------------

ClearArray:
	MOVFF     FSR2L,POSTINC1
	MOVFF     FSR1L,FSR2L
	MOVLW     0xfd       ;        *startAdr;
	MOVFF     PLUSW2,FSR0L
	MOVLW     0xfe
	MOVFF     PLUSW2,FSR0H
@ca2:
	MOVLW     0xfc        ;       while(count)
	MOVF      PLUSW2,0,0
	BZ        @ca1
	CLRF      POSTINC0,0
	MOVLW     0xfc
	DECF      PLUSW2,1,0
	BRA       @ca2
@ca1:
	MOVF      POSTDEC1,1,0
	MOVFF     INDF1,FSR2L
	RETURN    0

;-----------------------------------------
_do_cinit:
	MOVLW     0x2a           ;  TBLPTR = (short long)&_cinit;
	MOVWF     TBLPTRL,0
	MOVLW     0
	MOVWF     TBLPTRH,0
	MOVLW     0
	MOVWF     TBLPTRU,0
	MOVLB  BANK1
	TBLRD*+			;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     curr_entryl, 1
	TBLRD*+			;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     curr_entryh, 1
test:
	BNZ       tovab
	TSTFSZ    curr_entryl, 1
	BRA       tovab
	BRA	 done;
 tovab:
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     proml, 1
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     promh, 1
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     promu, 1
	TBLRD*+ 		;tblrdpostinc
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     FSR0L, 0
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     FSR0H, 0
	TBLRD*+ 		;tblrdpostinc
	TBLRD*+ 		;tblrdpostinc
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     curr_bytel, 1
	TBLRD*+ 		;tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     curr_byteh, 1
	TBLRD*+ 		;tblrdpostinc
	TBLRD*+ 		;tblrdpostinc
	MOVFF     TBLPTRL,data_ptrl    ;      data_ptr = TBLPTR;
	MOVFF     TBLPTRH,data_ptrh
	MOVFF     TBLPTRU,data_ptru
	MOVFF     proml,TBLPTRL     ;     TBLPTR = prom;
	MOVFF     promh,TBLPTRH
	MOVFF     promu,TBLPTRU
	MOVLB  BANK1
	MOVF      curr_bytel, 1, 1
copy_loop:
	BNZ       copy_one_byte
	MOVF      curr_byteh, 1, 1
	BZ        done_copying
copy_one_byte:
	TBLRD*+ 		;	tblrdpostinc
	MOVF      TABLAT, 0, 0
	MOVWF     POSTINC0, 0
	DECF      curr_bytel, 1, 1
	BC        copy_loop
	DECF      curr_byteh, 1, 1
	BRA       copy_one_byte
done_copying:
	MOVFF     data_ptrl,TBLPTRL     ;     TBLPTR = data_ptr;
	MOVFF     data_ptrh,TBLPTRH
	MOVFF     data_ptru,TBLPTRU
	MOVLB  BANK1
	DECF      curr_entryl,1,1
	MOVLW     0
	SUBWFB    curr_entryh,1,1
	BRA test;
done:
	RETURN    0

;-----------------------------------------

InitializeSystem:
	MOVLW     0xf
	IORWF     ADCON1,1,0
	MOVLW     0x14            ;   mInitializeUSBDriver();         // See usbdrv.h
	MOVWF     UCFGbits,0
	MOVLB  BANK1
	CLRF      usb_device_state,1
	MOVLB  BANK1
	CLRF      usb_stat,1
	MOVLB  BANK1
	CLRF      usb_active_cfg,1
	RETURN 0

;-----------------------------------------


USBTasks:
	CALL      USBCheckBusStatus,0
	BTFSC     UCFGbits,UTEYE,0   ;    if(UCFGbits.UTEYE!=1)
	BRA       @ut1
	CALL      USBDriverService,0
@ut1:
	GOTO      CDCTxService

;-----------------------------------------




;-----------------------------------------

User_Process:
	MOVLW     44		;a blokk merete
	MOVWF     POSTINC1
	MOVLW     low input_buffer
	MOVWF     POSTINC1
	MOVLW     high input_buffer
	MOVWF     POSTINC1
	CALL      getsUSBUSART	;bekerjuk a blokkot
	MOVF      POSTDEC1
	MOVF      POSTDEC1
	MOVF      POSTDEC1
	MOVLB  BANK1
	MOVWF     parlen,BANKED

	OUPUTPORT	;csak itt az elejen csinaljuk

	movf input_buffer,w
	sublw read_com
	 bnz @tova1
	call beolvaso
@tova1:
	movf input_buffer,w
	sublw bulk_com
	 bnz @tova2
	call bulkeras
@tova2:
	movf input_buffer,w
	sublw reset_com
	 bnz @tova3
	call resetel
	mov input_buffer,semleges_com
@tova3:
	movf input_buffer,w
	sublw eepromread_com
	 bnz @tova4
	call eepromolvas
@tova4:
	movf input_buffer,w
	sublw write_com
	 bnz @tova5
	call writeprogi
@tova5:
	movf input_buffer,w
	sublw eepromwrite_com
	 bnz @tova6
	call eepromiro
@tova6:
	movf input_buffer,w
	sublw configwrite_com
	 bnz @tova7
	call configiro
@tova7:
	movf input_buffer,w
	sublw idwrite_com
	 bnz @tova8
	call IDiro
@tova8:
	movf input_buffer,w	;ha ki akarjuk kapcsolni, kuldjuk az
	sublw 'k'		;elore megbeszelt kodu jelet
	bnz @SendADC
	bcf zoldled
@SendADC:
	btfss kuldheto,0	;kell-e kuldeni a blokkot?
	jmp @b_exit

	MOVLB  BANK1
	MOVF      cdc_trf_state,0,BANKED
	BNZ       @b_exiterror			;sajnos, nem tudjuk meg kuldeni

blokkelkuld:
	movlw D'64'
	MOVWF cdc_tx_len,BANKED
	MOVLW     low output_buffer
	MOVWF     pCDCSrcl,BANKED
	MOVLW     high output_buffer
	MOVWF     pCDCSrch,BANKED
akkorkulddmar:
	CLRF      cdc_mem_type,BANKED
	MOVLW     1
	MOVWF     cdc_trf_state,BANKED
	mov kuldheto,0
	
@b_exit:
	RETURN    0

@b_exiterror:
	btfsc zoldled
	BSF pirosled
	RETURN    0

;-----------------------------------

;-----------------------------------

                                      
;/* Device Descriptor */               

device_dsc:           
db    0x12, 0x01; 	sizeof(USB_DEV_DSC), DSC_DEV                  
dw    0x0200;		USB Spec Release Number in BCD format             
db    0x02, 0x00; 	Class Code, subclass code                                        
db    0x00, 0x08;	Protocol code,EP0_BUFF_SIZE                                     
dw    0x04D8;		Vendor ID                                         
dw    0x000A;		Product ID: CDC RS-232 Emulation Demo             
dw    0x0001;		Device release number in BCD format               
db    0x01, 0x02;	Manufacturer string index, product string index                         
db    0x00, 0x01;	Device serial number string index, number of poss. conf                 
                                    
                                      
CFG01:
; /* Configuration Descriptor */    
db    0x09,0x02;	sizeof(USB_CFG_DSC),DSC_CFG
dw    0x0043;		sizeof(cfg01) 67byte, // Total length of data for this cfg                 
db    0x02,0x01;	Number of interfaces in this cfg,Index value of this configuration
db    0x00,0xc0;	Configuration string index,_DEFAULT | _SELF// Attributes

db    0x32,0x09;	;50 Max power consumption (2X mA) ,sizeof(USB_INTF_DSC)
                                      
db    0x04,0x00;	;DSC_INTF, interface number
db    0x00,0x01;	Alternate Setting Number ,Number of endpoints
db    0x02,0x02;	COMM_INTF Class code, ABSTRACT_CONTROL_MODELSubclass code
db    0x01,0x00;	V25TER Protocol code,Interface string index

                                      
; /* CDC Class-Specific Descriptors */                                         
db    0x05,0x24; 	sizeof(USB_CDC_HEADER_FN_DSC),CS_INTERFACE
db	0x00,0x10;	DSC_FN_HEADER,
db	0x01,0x04;	sizeof(USB_CDC_ACM_FN_DSC)

db	0x24,0x02;	CS_INTERFACE,DSC_FN_ACM
db	0x02,0x05;	sizeof(USB_CDC_UNION_FN_DSC)

db	0x24,0x06;	CS_INTERFACE,DSC_FN_UNION
db	0x00,0x01;	CDC_COMM_INTF_ID,CDC_DATA_INTF_ID
 
db    0x05,0x24; sizeof(USB_CDC_CALL_MGT_FN_DSC),CS_INTERFACE
db	0x01,0x00;	DSC_FN_CALL_MGT,

db	0x01,0x07;	CDC_DATA_INTF_ID, sizeof(USB_EP_DSC)

db	0x05,0x82;	DSC_EP,_EP02_IN
db	0x03,0x08;	_INT
dw	0x0200;		CDC_INT_EP_SIZE

db 	0x09,0x04;	sizeof(USB_INTF_DSC),DSC_INTF INTERFACE descriptor type

db	0x01,0x00;	Interface Number,Alternate Setting Number
db	0x02,0x0a;	Number of endpoints in this intf,DATA_INTF Class code
db	0x00,0x00;	subclass code,NO_PROTOCOL Protocol code
db	0x00,0x07;	interface string index,sizeof(USB_EP_DSC)
                                             
; /* Endpoint Descriptors */        
db	0x05,0x03	; ,DSC_EP,_EP03_OUT
db	0x02,0x80	;,_BULK,64 CDC_BULK_OUT_EP_SIZE input_puffer merete!
db	0x00;0x00


db    0x07,0x05		; sizeof(USB_EP_DSC),DSC_EP
db	0x83,0x02	; _EP03_IN,_BULK
db	0x40,0x00	; 64 CDC_BULK_IN_EP_SIZE output_puffer merete!
                                      
;rom struct{byte bLength;byte bDscType;word string[1];}sd000={                    

DSCONF:
dw     0x0400,
db	0x03,0x09; sizeof(sd000)

DS001:                                     
;rom struct{byte bLength;byte bDscType;word string[25];}sd001={                   
db    0x04,0x34;	52 sizeof(sd001),DSC_STR
db 0x03,'M'
db 0,'i'
db 0,'c'
db 0,'r'
db 0,'o'
db 0,'c'
db 0,'h'

db 0,'i'
db 0,'p'
db 0,' '
db 0,'T'
db 0,'e'
db 0,'c'
db 0,'h'
db 0,'n'
db 0,'o'
db 0,'l'
db 0,'o'
db 0,'g'
db 0,'y'
db 0,' '
db 0,'I'
db 0,'n'
db 0,'c'
db 0,'.'                    
        
DS002:                              
;rom struct{byte bLength;byte bDscType;word string[25];}sd002={                   
db	0x00, 0x0034		;52 sizeof(sd002),DSC_STR
db 0x03,'C'
db 0,'D'
db 0,'C'
db 0,' '
db 0,'S'
db 0,'e'
db 0,'r'
db 0,'i'
db 0,'a'
db 0,'l'
db 0,' '                   
db 0,'E'
db 0,'m'
db 0,'u'
db 0,'l'
db 0,'a'
db 0,'t'
db 0,'i'
db 0,'o'
db 0,'n'
db 0,' '
db 0,'V'
db 0,'1'
db 0,'.'
db 0,'0'         


DSCONFK = DSCONF+1
DS001K = DS001+1
DS002K = DS002+1

desccimtabla:
db 0,low CFG01, high CFG01,low CFG01, high CFG01, low DSCONFK, high DSCONFK,low DS001K, high DS001K,low DS002K, high DS002K,low USBCheckCDCRequest,high USBCheckCDCRequest,0ffh


;----------------------------------------- INTERRUPT HANDLER

high_isr:

 	btfsc PIR1,TMR1IF
	bra timer1thread
	jmp irq_exit	

timer1thread:
	bcf PIR1,TMR1IF
	mov TMR1H,high timer1ertek
	mov TMR1L,low timer1ertek
	 decfsz irqszamlalo		;minden 64. megszakitaskor a sarga led valtozik 
	 jmp nemvillant
	 mov irqszamlalo,40
	 btg sargaled
    nemvillant:
irq_exit:
	retfie FAST


kezdvill:
	btg pirosled

	mov TEMP3,10

  kedv2:
	btg pirosled
	btg sargaled

	mov TEMP1,0

    kedv4:
	mov TEMP2,0
    kedv3:
        nop
	nop
	nop
	decfsz TEMP2
	bra kedv3
	decfsz TEMP1
	bra kedv4                              

	btg pirosled
	btg sargaled

	mov TEMP1,0
    kedv5:
	mov TEMP2,0
    kedv6:
        nop
	nop
	nop
	decfsz TEMP2
	bra kedv6
	decfsz TEMP1
	bra kedv5                              

	decfsz TEMP3
	bra kedv2

	bcf pirosled
	bcf sargaled
	ret

;-----------------------------------------



resetel:
	DATA_LO
	nop
	CLK_LO
	nop
	PGM_HI
	nop
	MCLR_LO
	call x10ms
	call x10ms
	MCLR_HI
	PGM_LO
	ret

x10ms:
	mov TEMP1,40h
	jmp edvna

x4ms:
	mov TEMP1,20h

    edvna:
	mov TEMP2,0
    edvki:
        nop
	nop
	nop
	nop
	decfsz TEMP2
	bra edvki
	decfsz TEMP1
	bra edvna                              
	ret

bevezeto:
	DATA_LO
	nop
	CLK_LO
	nop
	PGM_LO
	nop
	MCLR_LO
	nop
	PGM_HI
	nop
	call x4ms
	MCLR_HI
	nop
	call x4ms
	movff input_buffer+1,kezdocimu
	movff input_buffer+2,kezdocimhi
	movff input_buffer+3,kezdocimlo
	bsf zoldled
	movff FSR1L,idegfsr1l	;elmentjuk az eredeti FSR1-t
	movff FSR1H,idegfsr1h
	movlw     low input_buffer 	;beallitjuk a bejovo+4-re
	addlw 4
	movwf FSR1L
	movlw     high input_buffer
	movwf FSR1H
	ret

kivezeto:	
	DATA_LO
	nop
	CLK_LO
	nop
	call x4ms
	MCLR_LO
	call x4ms
	PGM_LO
	call x4ms
	MCLR_HI
      	movff	idegfsr1l,FSR1L
	movff	idegfsr1h,FSR1H
	mov input_buffer, semleges_com
	ret

Megszol:
	movwf idegbee
	mov shiftcounter,4
	jmp toldi
  toldki:
	movwf idegbee
    toldi:
	DATA_LO
	rrcf idegbee,f
	jnc atug
	DATA_HI
	nop
       atug:
	CLK_HI
	wait
	CLK_LO
	wait
	decfsz shiftcounter
	bra toldi
	clc
	ret	

szolkuld:
	MEGSZOLIT 0
	mov shiftcounter,8
	movf ideg16lo,W
	call toldki
	mov shiftcounter,8
	movf ideg16hi,W
	call toldki    
	ret

kezdocimez:
	mov ideg16hi,0eh
	movff kezdocimu,ideg16lo
	call szolkuld
	IDEGBETESZ 06ef8h
	mov ideg16hi,0eh
	movff kezdocimhi,ideg16lo
	call szolkuld
	IDEGBETESZ 06ef7h
	mov ideg16hi,0eh
	movff kezdocimlo,ideg16lo
	call szolkuld
	IDEGBETESZ 06ef6h
	ret

olvabe:
	MEGSZOLIT 9
	mov shiftcounter,8
	movlw 0
	call toldki
	INPUTPORT
	wait
	mov shiftcounter,8
	clrf idegbee
  toldbe:
	CLK_HI
	wait
	CLK_LO
	wait
	clc
	btfsc DATA_IN
	stc
	rrcf idegbee,f
	decfsz shiftcounter
	bra toldbe
	clc
	OUTPUTPORT
	ret	


beolvaso:
	call bevezeto
	movlw     low output_buffer
	movwf FSR1L
	movlw     high output_buffer
	movwf FSR1H
	call kezdocimez

	mov confszamol,40	;64db
     readbe:
	call olvabe
	movff idegbee,POSTINC1
	decfsz confszamol
	bra readbe
	mov kuldheto,1
	call kivezeto
	ret

eepromolvas:
	call bevezeto
	movlw     low output_buffer
	movwf FSR1L
	movlw     high output_buffer
	movwf FSR1H

	mov confszamol,40	;64db
     eereadbe:

	IDEGBETESZ 09ea6h
	IDEGBETESZ 09ca6h
	mov ideg16hi,0eh
	movff kezdocimlo,ideg16lo
	call szolkuld
	IDEGBETESZ 06ea9h
	mov ideg16hi,0eh
	movff kezdocimhi,ideg16lo
	call szolkuld
	IDEGBETESZ 06eaah
	IDEGBETESZ 080a6h

	IDEGBETESZ 050a8h
	IDEGBETESZ 06ef5h
	IDEGBETESZ 00000h

	MEGSZOLIT 2		;eepromra jellemzo ertek
	call sifteljbe
	call sifteljbe		;16 bit jon be, de csak a masodik az ertekes
	movff idegbee,POSTINC1

	clc
	movlw 1
	addwf kezdocimlo,f
	movlw 0
	addwfc kezdocimhi,f

	decfsz confszamol
	bra eereadbe

	mov kuldheto,1
	call kivezeto
	ret

sifteljbe:
	INPUTPORT
	mov shiftcounter,8
	clrf idegbee
  siftbe:
	CLK_HI
	wait
	CLK_LO
	wait
	clc
	btfsc DATA_IN
	stc
	rrcf idegbee,f
	decfsz shiftcounter
	bra siftbe
	clc
	OUTPUTPORT
	ret	


bulkeras:
	call bevezeto
	movff kezdocimu,TEMP1	;a kezdocimu nem hordoz a bulkerasnak infot, ezert hasznalhatom itt
	clc
	rrcf TEMP1               ;elosztja kettovel
	decf TEMP1                  ;es levon egyet igy 64-bol 31, 32-bol 15 lesz
	movff TEMP1,writebuffersize

	IDEGBETESZ 00e3ch
	IDEGBETESZ 06ef8h
	IDEGBETESZ 00e00h
	IDEGBETESZ 06ef7h
	IDEGBETESZ 00e05h
	IDEGBETESZ 06ef6h
	movff kezdocimhi,ideg16lo
	movff ideg16lo,ideg16hi
	call Wbszolkuld
	IDEGBETESZ 00e3ch
	IDEGBETESZ 06ef8h
	IDEGBETESZ 00e00h
	IDEGBETESZ 06ef7h
	IDEGBETESZ 00e04h
	IDEGBETESZ 06ef6h
	movff kezdocimlo,ideg16lo
	movff ideg16lo,ideg16hi
	call Wbszolkuld
	IDEGBETESZ 0
	IDEGBETESZ 0
	call x10ms
	call x10ms
	call x10ms
	call kivezeto
	ret

Wbszolkuld:
	MEGSZOLIT 0ch
	mov shiftcounter,8
	movf ideg16lo,W
	call toldki
	mov shiftcounter,8
	movf ideg16hi,W
	call toldki    
	ret

eepromiro:
	call bevezeto

	mov confszamol,20	;32db

	IDEGBETESZ 09ea6h
	IDEGBETESZ 09ca6h
	wait

     eewrite:
        wait
	mov ideg16hi,0eh
	movff kezdocimlo,ideg16lo
	call szolkuld
	IDEGBETESZ 06ea9h
	mov ideg16hi,0eh
	movff kezdocimhi,ideg16lo
	call szolkuld

	IDEGBETESZ 06eaah

	mov ideg16hi,0eh
	movff POSTINC1,ideg16lo
	nop
	call szolkuld
	IDEGBETESZ 06ea8h	;beirjuk
 
	IDEGBETESZ 084a6h	;enab memwrite
	IDEGBETESZ 082a6h	;init write

	IDEGBETESZ 050a6h	;poll wr bit
	IDEGBETESZ 06ef5h
	IDEGBETESZ 0000h

	MEGSZOLIT 2		;eepromra jellemzo ertek
	mov shiftcounter,8
	movlw 0
	call toldki
	wait
	mov shiftcounter,8
	movlw 0
	call toldki
	call x4ms
	IDEGBETESZ 094a6h	;disable write

	incf kezdocimu

	clc
	movlw 1
	addwf kezdocimlo,f
	movlw 0
	addwfc kezdocimhi,f

	decfsz confszamol
	bra eewrite

	call kivezeto
	ret


writeprogi:
	call bevezeto 
	IDEGBETESZ 08ea6h
	IDEGBETESZ 09ca6h
	call kezdocimez

	movff writebuffersize,irociklus	    ;31db word vagy 15db, attol fugg...
   irolup:
	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi

	call Wszolkuld		;sima iras
	decfsz irociklus
	bra irolup

	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi

	call Wprogkuld		;iras es programozas a 32. word
	call Wbeiras
	call kivezeto
	ret

Wszolkuld:
	MEGSZOLIT 0dh		;1101b iras+2 increment
	mov shiftcounter,8
	movf ideg16lo,W
	call toldki
	mov shiftcounter,8
	movf ideg16hi,W
	call toldki    
	ret

Wprogkuld:
	MEGSZOLIT 0fh		;1111b iras+programozas
	mov shiftcounter,8
	movf ideg16lo,W
	call toldki
	mov shiftcounter,8
	movf ideg16hi,W
	call toldki    
	ret

Wbeiras:
	mov shiftcounter,3
	movlw 0
	call toldki

	CLK_HI
	call x10ms
	CLK_LO
	call x10ms

			;16 0 bit kisiftelese
	mov shiftcounter,8
	movlw 0
	call toldki
	mov shiftcounter,8
	movlw 0
	call toldki
	ret


configiro:
	call bevezeto

	IDEGBETESZ 08ea6h
	IDEGBETESZ 08ca6h
	IDEGBETESZ 00e30h
	IDEGBETESZ 06ef8h
	IDEGBETESZ 00e00h
	IDEGBETESZ 06ef7h

	mov irociklus,0

  konfiro:
	mov ideg16hi,0eh		;300000h legalso byte cimzese
	movff irociklus,ideg16lo
	call szolkuld
	IDEGBETESZ 06ef6h

	movff POSTINC1,ideg16lo
	movff ideg16lo,ideg16hi		;csak az also ertek a fontos ugyis itt	
	call Wprogkuld
	call Wbeiras
	IDEGBETESZ 0000h

	incf irociklus
	movlw 0eh       	;dec 14
	cpfseq irociklus
	bra konfiro

	call x10ms
	call kivezeto
	ret

IDiro:
	call bevezeto

	IDEGBETESZ 08ea6h
	IDEGBETESZ 09ca6h

	IDEGBETESZ 00e20h
	IDEGBETESZ 06ef8h
	IDEGBETESZ 00e00h
	IDEGBETESZ 06ef7h
	IDEGBETESZ 00e00h
	IDEGBETESZ 06ef6h

	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi		
	call Wszolkuld
	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi		
	call Wszolkuld
	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi		
	call Wszolkuld
	movff POSTINC1,ideg16lo
	movff POSTINC1,ideg16hi		
	call Wprogkuld
	call Wbeiras
	call x10ms
	call kivezeto
	ret

END
