;--------------------------------------------------------------------------
; Программа управляемого генератора прямоугольного сигнала
;--------------------------------------------------------------------------

        LIST P=16C63A, R=DEC
        include "p16c63a.inc"

        __CONFIG _WDT_OFF & _XT_OSC & _PWRTE_ON & _BODEN_ON
        __IDLOCS H'1200'

StartByte	EQU	0x20
Cnt0		EQU	0x21
Cnt1		EQU	0x22
Cnt2		EQU	0x23
TimeH0Loaded	EQU	0x24
TimeH1Loaded	EQU	0x25
TimeH2Loaded	EQU	0x26
TimeL0Loaded	EQU	0x27
TimeL1Loaded	EQU	0x28
TimeL2Loaded	EQU	0x29

TimeH0		EQU	0x30
TimeH1		EQU	0x31
TimeH2		EQU	0x32
TimeL0		EQU	0x33
TimeL1		EQU	0x34
TimeL2		EQU	0x35



		ORG     0
Start		;Установка начальных значений переменных и SFR ****************
		BCF	PORTC,3		; запрещение выдачи частоты синхронизации для CC 60
		CLRF	PORTB		; выключение светодиодов и питания карточки
                BSF     STATUS,RP0      ;выбор второго банка памяти
		MOVLW	0x01
                MOVWF	TRISA           ;порт A настроен на работу как выход кроме RA0 (I/O)
                MOVWF	TRISB           ;все выводы порта В настроены на работу как выходы кроме RB0
		MOVLW	0xB6
                MOVWF   TRISC		;RC2 = MCLR
		BCF	OPTION_REG,7	;разрешены Pull up резисторы на порту B (~200K)
                BCF     STATUS, RP0	;Из за того что в команде адрес регистра задается только 7 битами, а для адресации всей памяти микросхемы надо как миниум 8, старшие биты адреса хранятся отдельно в регистре STATUS, это биты RP0 и RP1. Бит RP1 используется только в микросхемах с объемом RAM больше 256 байт. Биты RP0 и RP1 определяют используемый банк регистров, а номер регисра внутри текущего банка берется из кода команды. Микросхема имеет 2 банка регисров. Некоторые управляющие регистры находятся во втором банке.
		MOVLW	0 ;0x90
                MOVWF	INTCON		;прерывания не используются
                MOVLW   0x15            ;настройка таймера 1
                MOVWF   T1CON
                MOVLW   0x0B            ;настройка модуля для сброса таймера 1
                MOVWF   CCP1CON
                MOVLW   0x64
                MOVWF   CCPR1L
                MOVLW   0x57
                MOVWF   CCPR1H
;                CLRF    TimeCardOn      ;сброс времени для вставки карточки
                MOVLW   0x90; 0xD0 - for parity
                MOVWF   RCSTA           ;настройка параметров приемника USART. Регистр RCSTA управляет настройкой приемника последовательного порта
                BSF     STATUS,RP0      ;выбор второго банка памяти
                MOVLW   0x24; 0x64 - for parity
                MOVWF   TXSTA           ;настройка параметров передатчика USART
                MOVLW	0x01		;(115200 бод)
                MOVWF   SPBRG           ;настройка скорости обмена по последовательному порту
                BCF     STATUS,RP0      ;после настройки SFR востанавливаем банк памяти
                CLRF    PORTA
		BSF	PORTC,0		; выдаем сигнал компьютеру об отсутсвии карточки
;		BSF	Flags,SlotEmpty	; слот пустой



		MOVLW	0x20
		MOVWF	FSR

		MOVLW	0xFF
		MOVWF	Cnt0
		MOVWF	Cnt1
		MOVWF	Cnt2
		MOVWF	TimeH0Loaded
		MOVWF	TimeH1Loaded
		MOVWF	TimeH2Loaded
		MOVWF	TimeL0Loaded
		MOVWF	TimeL1Loaded
		MOVWF	TimeL2Loaded
		MOVLW	10
		MOVWF	TimeH0
		MOVLW	10
		MOVWF	TimeH1
		MOVLW	10
		MOVWF	TimeH2
		MOVWF	TimeL0
		MOVWF	TimeL1
		MOVWF	TimeL2
;		GOTO	NoCarryL

		; Увеличиваем значение счетчика TimeH на единицу
NoCarryH	BTFSC   PIR1,RCIF
                CALL    GetRSData
		MOVLW	1
		ADDWF	TimeH0,W
		MOVWF	TimeH0
		BTFSS	STATUS,C
		GOTO	NoCarryH
		MOVLW	1
		ADDWF	TimeH1,W
		MOVWF	TimeH1
		BTFSS	STATUS,C
		GOTO	NoCarryH
		MOVLW	1
		ADDWF	TimeH2,W
		MOVWF	TimeH2
		BTFSS	STATUS,C
		GOTO	NoCarryH
		; Счетчик TimeH переполнился, востанавливаем его и начинаем считать TimeL
		MOVF	TimeH0Loaded,W
		MOVWF	TimeH0
		MOVF	TimeH1Loaded,W
		MOVWF	TimeH1
		MOVF	TimeH2Loaded,W
		MOVWF	TimeH2
		BSF	PORTB,7		; Вывод положительного фронта импульса
		BCF	PORTB,6
;		CALL	SetRSData
		NOP
		NOP
		NOP

NoCarryL	BTFSC   PIR1,RCIF
                CALL    GetRSData
		MOVLW	1
		ADDWF	TimeL0,W
		MOVWF	TimeL0
		BTFSS	STATUS,C
		GOTO	NoCarryL
		MOVLW	1
		ADDWF	TimeL1,W
		MOVWF	TimeL1
		BTFSS	STATUS,C
		GOTO	NoCarryL
		MOVLW	1
		ADDWF	TimeL2,W
		MOVWF	TimeL2
		BTFSS	STATUS,C
		GOTO	NoCarryL
		MOVF	TimeL0Loaded,W
		MOVWF	TimeL0
		MOVF	TimeL1Loaded,W
		MOVWF	TimeL1
		MOVF	TimeL2Loaded,W
		MOVWF	TimeL2
		BCF	PORTB,7		; Вывод отрицательного фронта импульса
		BSF	PORTB,6
;		CALL	SetRSData

		; Если количество импульсов меньше константы, считаем их
		BTFSS	Cnt2,7
		GOTO	NoCarryH
NoCarryCnt	BTFSC   PIR1,RCIF
                CALL    GetRSData
		MOVLW	1
		ADDWF	Cnt0,W
		MOVWF	Cnt0
		BTFSS	STATUS,C
		GOTO	NoCarryH
		MOVLW	1
		ADDWF	Cnt1,W
		MOVWF	Cnt1
		BTFSS	STATUS,C
		GOTO	NoCarryH
		MOVLW	1
		ADDWF	Cnt2,W
		MOVWF	Cnt2
		BTFSS	STATUS,C
		GOTO	NoCarryH
		MOVLW	0xFF
		MOVWF	Cnt0
		MOVWF	Cnt1
		MOVWF	Cnt2
		GOTO	NoCarryCnt



GetRSData
                BCF     PIR1,RCIF	; Прием и запись в память байта
                MOVF    RCREG,W
		MOVWF	INDF
;                MOVWF   TXREG

		MOVLW	0x20		; Проверка прихода стартовго байта
		SUBWF	StartByte,W
		BTFSS	STATUS,Z
		RETURN		

		INCF	FSR,F		; Увеличение адреса с
		MOVF	FSR,W		; проверкой на переполнение
		SUBLW	0x2A
		BTFSS	STATUS,Z
		RETURN
		MOVLW	0x20
		MOVWF	FSR
		GOTO	NoCarryH
		


;SetRSData
;                BTFSS   PIR1,TXIF       ;ожидание окончания передачи
;                RETURN
;		MOVF	PORTB,W
;                MOVWF   TXREG
;                BCF     PIR1,TXIF
;                RETURN


		END
