• ;****************** Start Here ******************
    ; ****************
    ; Blocker GL23 SKY + Guide Byte + Unmariner
    ;
    ; By BomAmigo
    ;
    ; Ver. 2.0
    ;
    ; 06/03/2003
    ; __________________
    ; ******************
    ;
    ;
    ; FUSE BYTE
    ; 00 - nao casado, Desativado (virgen)
    ; 05 - nao casado, ativado
    ; A5 - casado, Desativado
    ; 20 - casado, Desativado
    ; 2D - casado, cancelado
    ; 24 - casado, bloqueado
    ; 25 - casado, ativado
    ;
    ; TIME ZONE
    ; 00 - Chile / Colombia
    ; 01 - Brazil
    ; 02 - Mountain / Santiago / Caracas La Paz
    ; 03 - Mexico / Pacific / Bogotá / Lima / Quito
    ;
    ; GUIDE BYTE
    ; 0C - ?????? (Vigem)
    ; 81 - Brazil
    ; 82 - Mexico / Puerto Rico
    ; 83 - Brazil ??
    ; 84 - Chile
    ; 87 - Colombia
    ; 8F - Argentina
    ;


    .Include "2313def.inc"

    .Equ sRamStart = 0x60

    .Def Rx_Byte = r16
    .Def Temp = r17
    .Def Counter = r18
    .Def RxTxCounterBits = r19
    .Def Tx_Byte = r20
    .Def Sw1Sw2_Aux = r21 ; Garda Sw1 ou Sw2 se alterados
    .Def L_delay = r22
    .Def Compra_PPV = r23 ; Se Compra_PPV#00 é para comprar PPV na Ins40
    .Def RxTxAux = r24
    .Def Delay = r25

    ;Cad GL23 Def.
    .Equ TimeZone = 0x12 ; Brazil=01 / Chile/Colombia=00 / Mexico/Pacific=03 / Mountain = 02
    .Equ FuseByte = 0x25 ; 25h = IRD habilitado, 20h = IRD Desabilitado
    .Equ GuideByte = 0x01 ; Brasil=0Ch / Brasil=81 / Brasil=83 / Mexico=82 /
    ; Colombia=87 / Chile=84 / Argentina=8F
    ;GL23 Block Circuit Def.
    .Equ IO_IRD = 0 ; I/O IRD + SM(1) Saída e Entrada
    .Equ IO_LED = 2 ; I/O SM(2) Saída e Entrada
    .Equ IO_CARD = 4 ; I/O SM(1) Saída e Entrada
    .Equ On_Off_4066 = 5 ; Control Switch 4066 Saída

    ;Iso 7816 Def.
    .Equ Class = 0x60
    .Equ Ins = 0x61
    .Equ P1 = 0x62
    .Equ P2 = 0x63
    .Equ ByteLen = 0x64

    ; Buffers de Trabalho
    .Equ StartBuffer = 0x65 ; Buffers de trabalho
    .Equ N_CARD_Ins_2A = 0x79 ; Posição do N. do CARD nos 0x90 Bytes recebidos da Ins 2A
    ; somados a 0x65 (StartBuffer) = (0x79-0x65)+1=0x15 = 21
    .Equ N_IRD_Ins_2A = 0x7D ; Posição do N. do IRD nos 0x90 Bytes recebidos da Ins 2A
    ; somados a 0x65 (StartBuffer) = (0x7D-0x65)+1=0x19 = 25
    .Equ N_IRD_CARD = 0xCC ; Buffer para Número do IRD Enviado pelo CARD
    .Equ N_IRD_IRD = 0xD0 ; Buffer para Número do IRD Enviado pelo IRD
    .Equ N_IRD_IRD_DATA = 0xD4 ; Buffer que contem o complemento da instrução 4c Recebida do IRD

    ; #IRD que do decoder atual em uso
    ;.Equ N_IRD_atual_1 = 0x00 ; Numero do IRD atual
    ;.Equ N_IRD_atual_2 = 0x00 ; (00 00 00 00)
    ;.Equ N_IRD_atual_3 = 0x00 ;
    ;.Equ N_IRD_atual_4 = 0x00 ;

    ; #IRD que o cartao estava casado anteriormente
    ;.Equ N_IRD_antigo_1 = 0x00 ; Numero do o IRD antigamente
    ;.Equ N_IRD_antigo_2 = 0x00 ; casado com o card
    ;.Equ N_IRD_antigo_3 = 0x00 ; (00 00 00 00) Velho loopeado
    ;.Equ N_IRD_antigo_4 = 0x00 ; (00 00 00 00) Novo em uso
    ; ; (00 00 00 00) #IRD de CAM ID 0000_0000_0000
    ; ; Data da Ativacao 00/00/00 CAM ID 00_00_00_00 em HEX

    ; #CAM ID ativado
    .Equ CAMID_ativado_1 = 0x00 ; CAM_ID original do CARD (00 00 00 00)
    .Equ CAMID_ativado_2 = 0x00 ; CAM_ID de 0000_0000_0000
    .Equ CAMID_ativado_3 = 0x00 ; CAM_ID em Hexa (00_00_00_00)
    .Equ CAMID_ativado_4 = 0x00 ; CAM_ID digito Verificador (0)

    .Cseg
    .Org 0
    rjmp Start
    Start: cli
    ldi Temp, RamEnd
    out spl, Temp
    ; Imput PD,0,2,4
    cbi ddrd, IO_IRD ; (coloca o BIT no modo alta impedancia)
    cbi portd,IO_IRD ; I/O IRD + SM(1) If 4066 "On"
    cbi ddrd, IO_LED ; (coloca o BIT no modo alta impedancia)
    cbi portd,IO_LED ; I/O SM(2)
    cbi ddrd, IO_CARD ; (coloca o BIT no modo alta impedancia)
    cbi portd,IO_CARD ; I/O SM(1) If 4066 "Off"
    ; Output PD On_Off_4066 Control Switch 4066
    sbi ddrd, On_Off_4066 ; 4066 OFF (coloca o BIT no modo HIGH & LOW Digital)
    cbi portd, On_Off_4066
    ;*********************************** Clear ram atmel ***********************
    ClrRam: ldi Temp, 0x00
    ldi YH, high(sRamstart)
    ldi YL, low(sRamstart)
    CLEAR_RAM: st Y+, Temp
    cpi YL, low(RAMEND+1)
    brcs CLEAR_RAM
    cpi YH, high(RAMEND+1)
    brcs CLEAR_RAM
    ;********* Looger Stream ( Class + Ins + P1 + P2 + Byte Len ) **************
    ReadClass: sbi ddrd, On_Off_4066
    sbi portd, On_Off_4066 ; 4066 ON
    ldi XL, Class ; Buffer inicial ram atmel
    ldi Counter, 0x04 ; Seta para ler 04 Bytes do pacote
    ReadByte48: rcall RxIRD_Start ; le Um Byte do IRD.
    cpi Rx_Byte, 0x48 ; Check Byte = 48h, Class = 48h
    breq ReadByte48_L1 ;
    cpi Rx_Byte, 0xD0 ; Check Byte = D0h, Class = D0h
    breq ReadByte48_L1 ;
    rjmp ReadByte48 ; Se nao volta
    ReadByte48_L1:
    st X+, Rx_Byte ; Se é grava no buffer 48h
    ReadPacket: rcall RxIRD_Start ; Agora Recebe Ins + P1 + P2 + Byte Len
    st X+, Rx_Byte ; Grava no buffer Ins
    dec Counter ; Le + 3 Bytes (P1/P2/ByteLen)
    brne ReadPacket ; Read pacote
    ;********* Check ByteLen e zero se for le (Sw1 /Sw2) e Volta ***************
    cpi Rx_Byte, 0x00 ; Compara se ByteLen = 0x00
    breq Fim_Sw1Sw2 ; Se sim vai Monitora 90 20 se OK (Sw1/Sw2)
    ;********** Check ACK (Verifica se o CARD entendeu o comando ***************
    Check_ACK: ldi XL, Ins ; Buffer onde esta a ins
    ld Temp, X+ ; Carrega temp com a ins
    rcall RxIrd_Start ; Read Ack do SM(1)
    cp Temp, Rx_Byte ; Compara se ACK = Ins (Retorno correto)
    brne ReadClass ; Se nao volta a logear
    ldi XL, StartBuffer ; Buffer inicial para os dados
    st X+, Rx_Byte ; Grava Ack
    ;*********************************** Dispach Ins ***************************
    ;cpi Rx_Byte, 0x4C ; Check Ins 4C (Teste o IRD number)
    ;breq GotoIns4C

    cpi Rx_Byte, 0x42 ; Check Ins 42 (Reprograma CARD)
    breq GotoIns42

    ;cpi Rx_Byte, 0x54 ; Check Ins 54 (Responde com a TEN KEY)
    ;breq GotoIns54

    cpi Rx_Byte, 0x58 ; Check Ins 58 (Super Guide)
    breq GotoIns58

    ;cpi Rx_Byte, 0x40 ; Check Ins 40 (seeds decryption keys Video)
    ;breq GotoIns40

    ;***************************************************************************
    Monitora: ldi XL, ByteLen ; Monitora "ByteLen" Bytes
    ld Counter, X+
    rcall Monit_IRD ; Vai Monitorar "ByteLen" Bytes
    ;************************** Monitora Sw1 e Sw2 *****************************
    Fim_Sw1Sw2: rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK Sw1/Sw2
    rjmp ReadClass ; Logger ( Volta a Logar )
    ;********************************** Jumps Execute **************************
    ; GotoIns0C: rjmp Ins0C
    ; GotoIns20: rjmp Ins20
    ; GotoIns42: rjmp Ins42
    GotoIns42: rjmp GotoClrCARD

    GotoIns4C: rjmp Ins4C
    GotoIns54: rjmp Ins54
    GotoIns58: rjmp Ins58_
    GotoIns40: rjmp Ins40
    ; GotoIns5E: rjmp Ins5E
    ; GotoIns78: rjmp CancelInsIRD

    GotoClrIRD: rjmp CancelInsIRD
    GotoClrCARD: rjmp CancelInsCARD
    ; GotoBlock: rjmp BlockIns

    ;***************************************************************************
    ; Cancela Ins YY para IRD SKY. 48 YY KK ZZ XX
    ;***************************************************************************
    ; Transmite 00 para o IRD no lugar do comando do CARD cancelando o comando
    ;
    CancelInsIRD: ; Este comando pode ter varios comprimentos
    ldi XL, ByteLen ; Transmite "ByteLen" Bytes
    ld Counter, X+ ; para o IRD de 0x00
    CancelInsIRD_L1:
    ldi Tx_Byte, 0x00 ; 0x00
    rcall TxIRD_IF_RxCARD_start ; Transmite no lugar do CARD
    dec Counter ; decrementa o contador
    brne CancelInsIRD_L1 ; volta a transmitir
    rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK (Sw1/Sw2)
    rjmp ReadClass ; Logger ( Volta a Logar )

    ;***************************************************************************
    ; Cancela Ins YY para IRD SKY. 48 YY KK ZZ XX (Reprograma CARD)
    ;***************************************************************************
    ; Transmite 00 para o CARD no lugar do comando do IRD cancelando o comando
    ;
    CancelInsCARD: ; Este comando pode ter varios comprimentos
    ldi XL, ByteLen ; Transmite "ByteLen" Bytes
    ld Counter, X+ ; para o CARD de CMD's "NOP"
    CancelInsCARD_L1:
    ldi Tx_Byte, 0x00 ; CMD 0x00 = "NOP"
    rcall TxCARD_IF_RxIRD_start ; Transmite no lugar do IRD
    dec Counter ; decrementa o contador
    brne CancelInsCARD_L1 ; volta a ler
    rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK (Sw1/Sw2)
    rjmp ReadClass ; Logger ( Volta a Logar )

    ;***************************************************************************
    ; Intercept Ins 40 para IRD SKY 48 40 00 00 XX (seeds decryption keys Video)
    ;***************************************************************************
    ; Ins40-Command Packet-(Video Authorization Packet - seeds decryption keys that are sent by Ins54)
    ; 48 40 00 00 ??
    ;
    Ins40: ldi XL, ByteLen ; Pega LenByte do Comando 40
    ld Counter, X+
    ldi XL, StartBuffer ; Garda a resposta no Buffers
    rcall RxIRD_Buffer ; Recebe LenByte Bytes do IRD e grava no Buffer
    ;---------------------------------------------------------------------------
    sbi ddrd, On_Off_4066
    cbi portd, On_Off_4066 ; 4066 OFF
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora/Recebe o (Sw1/Sw2) do CARD sem passar para o IRD
    rcall DelayStream


    ;---------------------------------------------------------------------------
    ; compra o PPV automáticamente independente de IRD faz a compra do PPV
    ;
    ; Removido ......
    ;



    ;---------------------------------------------------------------------------
    ; Descasa o Card Permitindo pegar a TenKey para card's descasados
    ;
    ldi Tx_Byte, 0x48 ; Manda um comando 48 4C 00 00 09
    rcall TxCARD_start ; Ins4C-Marry/Check IRD
    rcall DelayStream ; Descasa o CARD com o N. do IRD diferendte do N. do CARD
    ldi Tx_Byte, 0x4C
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x09
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    rcall RxCARD_Start ; Recebe ACK do Comando 4C
    rcall DelayStream ; Da um delay Fixo
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_IRD ; Transmite o N. do IRD que nao está casado CARD (0xD0)
    ldi Counter, 0x09 ; que foi obtina da Inst. 2A
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora/Recebe o (Sw1/Sw2) do CARD sem passar para o IRD
    rcall DelayStream
    ;---------------------------------------------------------------------------
    ; Solicita autorização como se fosse um pacote do canal livre
    ;
    ; ldi XL, Class ; Pega ( Clas Ins P1 P2 LenByte ) do Comando 40
    ; ldi Counter, 0x05 ; Transmite para o CARD
    ; rcall TxCARD_Buffer ; Transmite ( Clas Ins P1 P2 LenByte ) para o CARD
    ;
    ldi Tx_Byte, 0x48 ; Manda um comando 48 40 P1 P2 ByteLen
    rcall TxCARD_start ; Ins40-Command Packet-(Video Authorization Packet -
    rcall DelayStream ; seeds decryption keys that are sent by Ins54)
    ldi Tx_Byte, 0x40 ; para obter a autorização sem casamento do card
    rcall TxCARD_start
    rcall DelayStream
    ldi XL, P1 ; Pega P1 do Comando 40
    ld Tx_Byte, X+ ; e transmite pro CARD
    rcall TxCARD_start
    rcall DelayStream
    ldi XL, P2 ; Pega P2 do Comando 40
    ld Tx_Byte, X+ ; e transmite pro CARD
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    ldi XL, ByteLen ; Pega LenByte do Comando 40
    ld Tx_Byte, X+ ; e transmite pro CARD
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    rcall RxCARD_Start ; Recebe ACK do Comando 40
    rcall DelayStream
    ;---------------------------------------------------------------------------
    ldi XL, ByteLen ; Pega LenByte do Comando 40
    ld Counter, X+ ; Transmite o Buffer para o CARD
    ldi XL, StartBuffer ; commando 48 40 20 C0
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    sbi ddrd, On_Off_4066
    sbi portd, On_Off_4066 ; 4066 ON
    ;---------------------------------------------------------------------------
    rcall RxIRD_Start ; Monitora a passagem de um byte 0x90
    ldi Tx_Byte, 0x20 ; Manda 0x20 no lugar de 0x00
    rcall TxIRD_IF_RxCARD_start ;

    rjmp ReadClass ; Logger ( Volta a Logar )

    ;***************************************************************************
    ;Intercept Ins 4C para IRD SKY. 48 4C 00 00 09
    ;***************************************************************************
    ; Ins4C-Marry/Check IRD
    ;
    Ins4C: ldi XL, ByteLen ; Pega LenByte do Comando 4C
    ld Counter, X+
    ldi XL, N_IRD_IRD ; Garda a resposta no Buffers N_IRD_IRD (0xD0)
    rcall RxIRD_Buffer ; Recebe LenByte Bytes do IRD e grava no Buffer
    ;---------------------------------------------------------------------------
    sbi ddrd, On_Off_4066
    cbi portd, On_Off_4066 ; 4066 OFF
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora/Recebe o (Sw1/Sw2) do CARD sem passar para o IRD
    rcall DelayStream
    ;---------------------------------------------------------------------------
    ldi Tx_Byte, 0x48 ; Manda um comando 48 2A 00 00 90
    rcall TxCARD_start ; Ins2A-Send More Card Info
    rcall DelayStream
    ldi Tx_Byte, 0x2A
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x90
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    rcall RxCARD_Start ; Recebe ACK do Comando 2A
    rcall DelayStream
    ;---------------------------------------------------------------------------
    ldi XL, StartBuffer ; Recebe os 0x90 Bytes do comando 2A (0x65)
    ldi Counter, 0x50 ; Grava no Buffer StartBuffer
    rcall RxCARD_Buffer ; Recebe 0x50 Bytes do CARD e grava no Buffer
    ldi Counter, 0x40 ; Monitora a passagem do resto do comando 2A
    rcall Monit_CARD ; Recebe 0x40 Bytes do CARD
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora/Recebe o (Sw1/Sw2) do CARD sem passar para o IRD
    rcall DelayStream ; Da um delay Fixo
    ;---------------------------------------------------------------------------
    ; Faz um xor entre os bytes do N. do CARD e do N. do IRD
    ; os bytes de 21 a 24 com os bytes de 25 a 28
    ; somar o End com +20 e com +24
    ;
    ldi XL, N_CARD_Ins_2A ; Calcula o N. do IRD Fazendo um Xor com o N. do CARD (0x79)
    ldi YL, N_IRD_Ins_2A ; Guarda na posição do N. do IRD Recebido da Ins 2A (0x7D)
    ldi Counter, 0x04
    StartIns4C: ld RxTxAux, X+
    ld Tx_Byte, Y
    eor RxTxAux, Tx_Byte ; Faz o XOR do N. do CARD com o do IRD
    st Y+, RxTxAux ; e guarda no N. do Card
    dec Counter
    brne StartIns4C
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_Ins_2A ; Copia o N. do IRD Recebido da Ins 2A (0x7D)
    ldi YL, N_IRD_CARD ; para N_IRD_CARD (0xCC)
    ldi Counter, 0x04
    StartIns4C_01:
    ld RxTxAux, X+
    st Y+, RxTxAux
    dec Counter
    brne StartIns4C_01
    ;---------------------------------------------------------------------------
    ldi Tx_Byte, 0x48 ; Manda um comando 48 4C 00 00 09
    rcall TxCARD_start ; Ins4C-Marry/Check IRD
    rcall DelayStream
    ldi Tx_Byte, 0x4C
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x09
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    rcall RxCARD_Start ; Recebe ACK do Comando 4C
    rcall DelayStream ; Da um delay Fixo
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_CARD ; Transmite o N. do IRD casado com o CARD (0xCC)
    ldi Counter, 0x04 ; que foi obtina da Inst. 2A
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_IRD_DATA ; Transmite o Complemento da Instrução (0xD4)
    ldi Counter, 0x05 ; 4C para o CARD, complemento recebido do IRD
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    sbi ddrd, On_Off_4066
    sbi portd, On_Off_4066 ; 4066 ON
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK (Sw1/Sw2)
    rjmp ReadClass ; Logger ( Volta a Logar )

    ;***************************************************************************
    ;Intercept Ins 54 para IRD SKY. Responde com a TEN KEY
    ;***************************************************************************
    ;
    ; Coloca apos a TEN KEY os bytes 0x00 0x03 0x00 no lugar dos 0x00 0x07 0x10
    ;
    ; Directv Message codes
    ; (711) customer account is set-up but the system has not been activated, this is called a partial activation.
    ; (721) channel is not authorized - or subscription expired.
    ; (722) a "resend" is required from DirecTV to reactivate an active subscription - ie. The receiver was off for a long period.
    ; (731) access card is full and has not reported to DirecTV.
    ; (732) PPV not setup or PPV blocked due to delinquent account.
    ; (733) due to unsuccessful attempts by the receiver to download the access card the PPV purchase ceiling has been set to 1 cent by DirecTV.
    ; (734) receiver un-sets for PPV purchases capability due to receiver malfuntion.
    ; (745) card lost, stolen or damaged.
    ; (746) possible data corruption - receiver fault.
    ; (751) access card needs to be changed out.
    ; (752) access card needs to look like an Hu card for working with a 5th generation receiver.
    ;
    ; Com Sinal de vídeo
    ;
    ; Statud do Video 00 07 00 = Inf. ou Display para Comprar PPV Em Binário (0000 0000 0000 0111 0000 0000)
    ; Statud do Video 00 07 10 = Mensagem Ext. 722 (Requerido reinicialização pela DTV) Em Binário (0000 0000 0000 0111 0001 0000)
    ; Statud do Video 02 07 13 = Em Binário (0000 0010 0000 0111 0001 0011)
    ; Statud do Video 00 07 18 = Para comprar PPV ligue p/ DTV Ext. 734 (Telefone Desligado) Em Binário (0000 0000 0000 0111 0001 1000)
    ;
    ; Sem Sinal de vídeo
    ;
    ; Statud do Video 00 04 00 = Inf. ou Display para Comprar PPV Em Binário (0000 0000 0000 0100 0000 0000)
    ; Statud do Video 00 04 04 = Mensagem Ext. 721 (Canal não Autorizado) Em Binário (0000 0000 0000 0100 0000 0100)
    ; Statud do Video 00 04 06 = Mensagem Ext. 711 (Cartão Vigem) Em Binário (0000 0000 0000 0100 0000 0110)
    ; Statud do Video 00 04 08 = <no menssage> Em Binário (0000 0000 0000 0100 0000 1000)
    ; Statud do Video 00 04 10 = Mensagem Ext. 722 (Requerido reinicialização pela DTV) Em Binário (0000 0000 0000 0100 0001 0000)
    ; Statud do Video 02 04 13 = Mensagem Ext. 732 (PPV Bloqueado ou cheio) Em Binário (0000 0010 0000 0100 0001 0011)
    ; Stat.Video 08 04 14 = Erro-14 Cartão Desconhecido Em Binário (0000 1000 0000 0100 0001 0100)
    ; Statud do Video 00 04 17 = Programa não mais disponivel para Compra Em Binário (0000 0000 0000 0100 0001 0111)
    ; Statud do Video 00 04 18 = Para comprar PPV ligue p/ DTV Ext. 734 (Telefone Desligado) Em Binário (0000 0000 0000 0100 0001 1000)
    ; Statud do Video 00 04 ?? = card lost, stolen or damaged - Ligue p/ DTV Ext. 735 Em Binário (0000 0000 0000 0100 ???? ????)
    ;
    Ins54:
    ldi Sw1Sw2_Aux,0x00 ; determina que o Sw1 e Sw2 Não devem ser alterados
    ;---------------------------------------------------------------------------
    ; Monitora a passagem da TEN KEY com 10 Bytes + 1 Byte de Status
    ldi Counter, 0x0A ; Recebe da TEN KEY 10 Bytes
    ldi XL, StartBuffer ; Garda a resposta no Buffer
    rcall RxIRD_Buffer ; Recebe LenByte Bytes do buffer para o IRD
    ;---------------------------------------------------------------------------
    Ins54_L0: sbis PIND, IO_CARD ; wait for I/O to go high - line idle
    rjmp Ins54_L0
    sbi DDRD, On_Off_4066
    cbi PORTD, On_Off_4066 ; 4066 OFF
    ;---------------------------------------------------------------------------
    ; Recebe a FLAG, da TEN KEY que já foi recebida, sem deixar passa-la para o IRD
    ldi Counter, 0x03 ; recebe 3 Bytes
    ldi XL, StartBuffer ; Garda a resposta no Buffer
    rcall RxCARD_Buffer ; Recebe 3 Bytes do CARD e grava no Buffer
    ;---------------------------------------------------------------------------
    rcall Monit_Sw1Sw2_CARD ; Monitora/Recebe o (Sw1/Sw2) do CARD
    rcall DelayStream ; sem passar para o IRD
    ;---------------------------------------------------------------------------
    ; Testa se o bit de Mensagem de erro está setado.
    ldi XL, StartBuffer
    ld Tx_Byte, X+ ; pega o primeiro byte
    ld Tx_Byte, X+ ; pega o segundo byte
    cpi Tx_Byte, 0x04 ; Verifica se a flag é XX 04 YY
    breq Ins54_L0_0
    cpi Tx_Byte, 0x07 ; Verifica se a flag é XX 07 YY
    breq Ins54_L0_1
    rjmp Ins54_L3 ; se não trans mite a flag normal
    ;---------------------------------------------------------------------------
    ; Testa o tipo de mensagem de Erro e tenta corrigilo
    ; Se não tem vídeo testa todos os erros e coloca mensagem de DISPLAY para compra
    Ins54_L0_0: ld Tx_Byte, X
    cpi Tx_Byte, 0x04 ; Verifica se a flag é XX 07 04 ou XX 04 04 (0000 0100) (Ext.721)
    breq Ins54_L1 ; se for troca por 03 ??
    cpi Tx_Byte, 0x06 ; Verifica se a flag é XX 07 06 ou XX 04 06 (0000 0110) (Ext.711)
    breq Ins54_L1 ; se for troca por 03 ??
    cpi Tx_Byte, 0x08 ; Verifica se a flag é XX 07 08 ou XX 04 08 (0000 1000)
    breq Ins54_L1 ; se for troca por 03 ??
    cpi Tx_Byte, 0x0A ; Verifica se a flag é XX 07 0A ou XX 04 0A (0000 1010) (Ext.722)
    breq Ins54_L1 ; se for troca por 03 ??
    cpi Tx_Byte, 0x10 ; Verifica se a flag é XX 07 10 ou XX 04 10 (0001 0000) (Ext.722)
    breq Ins54_L1 ; se for troca por 03 ??
    ;---------------------------------------------------------------------------
    ; Se tem vídeo testa os erro para colocar mens. DISPLAY ou para limpar as mens.
    Ins54_L0_1: ld Tx_Byte, X
    cpi Tx_Byte, 0x0C ; Verifica se a flag é XX 07 0C ou XX 04 0C (Ext.731)
    breq Ins54_L1 ; se for troca por 00 03 00
    cpi Tx_Byte, 0x12 ; Verifica se a flag é XX 07 12 ou XX 04 12 (Ext.731)
    breq Ins54_L1 ; se for troca por 00 03 00
    cpi Tx_Byte, 0x0D ; Verifica se a flag é XX 07 0D ou XX 04 0D (Ext.732)
    breq Ins54_L1 ; se for troca por 00 03 00
    cpi Tx_Byte, 0x13 ; Verifica se a flag é XX 07 13 ou XX 04 13 (Ext.732)
    breq Ins54_L1 ; se for troca por 00 03 00
    cpi Tx_Byte, 0x14 ; Verifica se a flag é XX 07 14 ou XX 04 14 (Erro-14)
    breq Ins54_L1 ; se for troca por 00 00 03 00
    cpi Tx_Byte, 0x18 ; Verifica se a flag é XX 07 18 ou XX 04 18 (Ext.734)
    breq Ins54_L1 ; se for troca por 00 03 00

    ; cpi Tx_Byte, 0x0f ; Verifica se a flag é XX 07 0F ou XX 04 0F (Ext.733)
    ; breq Ins54_L1_0 ; se for troca por 00 03 00
    ; cpi Tx_Byte, 0x15 ; Verifica se a flag é XX 15 15 ou XX 04 15 (Ext.733)
    ; breq Ins54_L1_0 ; se for troca por 00 03 00
    ; cpi Tx_Byte, 0x1c ; Verifica se a flag é XX 07 1C ou XX 04 1C (Ext.743)
    ; breq Ins54_L1_0 ; se for troca por 00 03 00
    ; cpi Tx_Byte, 0x22 ; Verifica se a flag é XX 07 22 ou XX 04 22 (Ext.743)
    ; breq Ins54_L1_0 ; se for troca por 00 03 00

    ;---------------------------------------------------------------------------
    ; Se tem vídeo e tem erro tipo 711 721 722 limpa a mensagem de erro
    cpi Tx_Byte, 0x04 ; Verifica se a flag é XX 07 04 ou XX 04 04 (0000 0100) (Ext.721)
    breq Ins54_L2 ; se for troca por 03 ??
    cpi Tx_Byte, 0x06 ; Verifica se a flag é XX 07 06 ou XX 04 06 (0000 0110) (Ext.711)
    breq Ins54_L2 ; se for troca por 03 ??
    cpi Tx_Byte, 0x08 ; Verifica se a flag é XX 07 08 ou XX 04 08 (0000 1000)
    breq Ins54_L2 ; se for troca por 03 ??
    cpi Tx_Byte, 0x0A ; Verifica se a flag é XX 07 0A ou XX 04 0A (0000 1010) (Ext.722)
    breq Ins54_L2 ; se for troca por 03 ??
    cpi Tx_Byte, 0x10 ; Verifica se a flag é XX 07 10 ou XX 04 10 (0001 0000) (Ext.722)
    breq Ins54_L2 ; se for troca por 03 ??
    ;---------------------------------------------------------------------------
    rjmp Ins54_L3 ; Transmite a flag normal
    ;---------------------------------------------------------------------------
    ; Ativa Vídeo e Zera Menssagem de Erro
    Ins54_L1: cpi Compra_PPV,0x00 ; Verifica se Compra_PPV#0x00, ou seja, se o PPV já foi
    brne Ins54_L2 ; comprado, se foi, então não solicita mais a compra, faz Flag Vídeo OK
    ;---------------------------------------------------------------------------
    ldi Sw1Sw2_Aux,0x91 ; Faz Sw1=0x91 e Sw2= 0x20
    ldi XL, StartBuffer ; Ativa vídeo na flag de vídeo
    ld Tx_Byte, X
    andi Tx_Byte,0x00 ; Zera Cod. Erro faz adn com 0000 0000
    st X+, Tx_Byte
    ld Tx_Byte, X
    ori Tx_Byte,0x03 ; Ativa vídeo faz or com 0000 0011
    st X+, Tx_Byte
    ld Tx_Byte, X
    andi Tx_Byte,0x00 ; Zera Cod. Erro faz adn com 0000 0000
    st X+, Tx_Byte
    rjmp Ins54_L3 ; se não trans mite a flag normal
    ;---------------------------------------------------------------------------
    ; Só ativa Vídeo
    Ins54_L1_0: ldi XL, StartBuffer ; Ativa vídeo na flag de vídeo
    ld Tx_Byte, X+ ; Pula o Primeiro Byte
    ld Tx_Byte, X
    ori Tx_Byte,0x03 ; Ativa vídeo faz or com 0000 0011
    st X+, Tx_Byte
    rjmp Ins54_L3 ; se não trans mite a flag normal
    ;---------------------------------------------------------------------------
    ; Transforma a Flag de Vídeo em Flag Padrão, Vídeo ativado,
    ; Bit de Mensagem Resetado, e sem Menssagem de Erro.
    Ins54_L2: ldi XL, StartBuffer ; Troca de vídeo para 00 03 00
    ldi Tx_Byte,0x00
    st X+, Tx_Byte
    ldi Tx_Byte,0x03 ; Coloca XX 03 00 no lugar
    st X+, Tx_Byte ; de XX 07 YY ou XX 04 YY
    ldi Tx_Byte,0x00
    st X+, Tx_Byte
    ;---------------------------------------------------------------------------
    ; Transmite Flag de Vídeo
    Ins54_L3:
    ldi XL, StartBuffer ; Transmite a resposta do Buffers para o IRD
    ldi Counter, 0x03 ; Transmite 3 Bytes para o IRD (Flag de Video)
    rcall TxIRD_Buffer
    ; Complemento comum
    ;---------------------------------------------------------------------------
    Ins54_L4: ldi Tx_Byte, 0x48 ; Manda um comando 48 4C 00 00 09
    rcall TxCARD_start ; Ins4C-Marry/Check IRD
    rcall DelayStream
    ldi Tx_Byte, 0x4C
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x00
    rcall TxCARD_start
    rcall DelayStream
    ldi Tx_Byte, 0x09
    rcall TxCARD_start
    rcall DelayStream
    ;---------------------------------------------------------------------------
    rcall RxCARD_Start ; Recebe ACK do Comando 4C
    rcall DelayStream ; Da um delay Fixo
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_CARD ; Transmite o N. do IRD casado com o CARD (0xCC)
    ldi Counter, 0x04 ; que foi obtina da Inst. 2A
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    ldi XL, N_IRD_IRD_DATA ; Transmite o Complemento da Instrução (0xD4)
    ldi Counter, 0x05 ; 4C para o CARD, complemento recebido do IRD
    rcall TxCARD_Buffer ; Transmite Buffer para o CARD
    ;---------------------------------------------------------------------------
    sbi DDRD, On_Off_4066
    sbi PORTD, On_Off_4066 ; 4066 ON
    ;---------------------------------------------------------------------------
    cpi Sw1Sw2_Aux, 0x91 ; Verifica se Sw1 e Sw2 devem ser trocados
    breq Ins54_L5 ; para poder comprar o PPV
    rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK (Sw1/Sw2)
    rjmp Ins54_L6 ; Logger ( Volta a Logar )
    ;---------------------------------------------------------------------------
    ; Necessário para poder comprar os PPV subestituir o 90 20 por 91 20 no (Sw1/Sw2)
    Ins54_L5: ldi Tx_Byte, 0x91 ; Manda 0x91 no lugar de 0x90
    rcall TxIRD_IF_RxCARD_start ;
    ldi Tx_Byte, 0x20 ; Manda 0x20 no lugar de 0x20
    rcall TxIRD_IF_RxCARD_start ;
    ;---------------------------------------------------------------------------
    Ins54_L6: rjmp ReadClass ; Logger ( Volta a Logar )


    ;****************************************
    ; INS 58
    ;****************************************
    Ins58_: ldi r17, 0x0C ; 0031 E01C
    avr0032: rcall Lee_Ird ; 0032 D0AD
    rcall DelayStream2 ; 0033 D137
    dec r17 ; 0034 951A
    brne avr0032 ; 0035 F7E1

    avr0036: sbis PIND, 0 ; 0036 9B80
    rjmp avr0036 ; 0037 CFFE

    avr0038: sbic PIND, 0 ; 0038 9980
    rjmp avr0038 ; 0039 CFFE
    sbi DDRD, 5 ;
    cbi PORTD, 5 ; habilita blocker
    ldi r16, 0x01 ; 003C E001
    rcall Envia_Ird ; 003D D0D2
    ldi r17, 0x1B ; 003E E11B
    rcall Timer2 ; 003F D12C
    sbi DDRD, 5 ;
    sbi PORTD, 5 ; deshabilita blocker
    rjmp ReadClass


    ;****************************************
    ;* LEE DATOS DESDE IRD PD0
    ;****************************************
    Lee_Ird: sbis PIND, 0 ; 00E0 9B80
    rjmp Lee_Ird ; 00E1 CFFE
    avr00E2: sbic PIND, 0 ; 00E2 9980
    rjmp avr00E2 ; 00E3 CFFE
    ldi r25, 0x0F ; 00E4 E09F
    avr00E5: dec r25 ; 00E5 959A
    brne avr00E5 ; 00E6 F7F1
    nop ; 00E7 0000
    ldi r16, 0x01 ; 00E8 E001
    ldi r25, 0x1F ; 00E9 E19F
    avr00EA: dec r25 ; 00EA 959A
    brne avr00EA ; 00EB F7F1
    in r24, PIND ; 00EC B380
    lsr r24 ; 00ED 9586
    rol r16 ; 00EE 1F00
    ldi r25, 0x1E ; 00EF E19E
    brsh avr00EA ; 00F0 F7C8
    com r16 ; 00F1 9500
    nop ; 00F2 0000
    ldi r25, 0x2E ; 00F3 E29E
    avr00F4: dec r25 ; 00F4 959A
    brne avr00F4 ; 00F5 F7F1
    avr00F6: sbis PIND, 0 ; 00F6 9B80
    rjmp avr00F6 ; 00F7 CFFE
    ret ; 00F8 9508
    ;****************************************

    ;****************************************
    ; Enia datos al IRD por P0
    ;****************************************
    Envia_Ird:
    sbis PIND, 0 ; 0110 9B80
    rjmp Envia_Ird ; 0111 CFFE
    sbi DDRD, 0 ; 0112 9A88
    cbi PORTD, 0 ; 0113 9890
    ldi r18, 0x08 ; 0114 E028
    clr r24 ; 0115 2788
    ldi r25, 0x14 ; 0116 E194
    avr0117: rcall Timer ; 0117 D054
    nop ; 0118 0000
    rol r16 ; 0119 1F00
    brlo avr013E ; 011A F118
    nop ; 011B 0000
    sbi PORTD, 0 ; 011C 9A90
    rjmp avr011E ; 011D C000
    avr011E: adc r24, r25 ; 011E 1F89
    andi r24, 0x01 ; 011F 7081
    dec r18 ; 0120 952A
    ldi r25, 0x18 ; 0121 E198
    nop ; 0122 0000
    brne avr0117 ; 0123 F799
    rcall Timer ; 0124 D047
    rjmp avr0126 ; 0125 C000
    avr0126: ror r24 ; 0126 9587
    brlo avr013C ; 0127 F0A0
    nop ; 0128 0000
    sbi PORTD, 0 ; 0129 9A90
    rjmp avr012B ; 012A C000
    avr012B: ldi r25, 0x1B ; 012B E19B
    rcall Timer ; 012C D03F
    nop ; 012D 0000
    sbi PORTD, 0 ; 012E 9A90
    ldi r25, 0x25 ; 012F E295
    rcall Timer ; 0130 D03B
    nop ; 0131 0000
    avr0132: sbis PIND, 4 ; 0132 9B84
    rjmp avr0132 ; 0133 CFFE
    avr0134: sbic PIND, 4 ; 0134 9984
    rjmp avr0134 ; 0135 CFFE
    sbi DDRD, 5 ; 0136 9A8D
    sbi PORTD, 5 ; 0137 9A95
    rjmp avr0139 ; 0138 C000
    avr0139: cbi DDRD, 0 ; 0139 9888
    cbi PORTD, 0 ; 013A 9890
    ret ; 013B 9508
    avr013C: cbi PORTD, 0 ; 013C 9890
    rjmp avr012B ; 013D CFED
    avr013E: cbi PORTD, 0 ; 013E 9890
    rjmp avr011E ; 013F CFDE
    avr0140: sbis PIND, 4 ; 0140 9B84
    rjmp avr0140 ; 0141 CFFE
    sbi DDRD, 4 ; 0142 9A8C
    ldi r25, 0x04 ; 0143 E094
    rcall Timer ; 0144 D027
    rjmp avr0146 ; 0145 C000
    avr0146: cbi PORTD, 4 ; 0146 9894
    rjmp avr0148 ; 0147 C000
    avr0148: rjmp avr0149 ; 0148 C000
    avr0149: nop ; 0149 0000
    ldi r18, 0x08 ; 014A E028
    clr r24 ; 014B 2788
    avr014C: ldi r25, 0x18 ; 014C E198
    rcall Timer ; 014D D01E
    nop ; 014E 0000
    rol r16 ; 014F 1F00
    brlo avr0169 ; 0150 F0C0
    nop ; 0151 0000
    sbi PORTD, 4 ; 0152 9A94
    rjmp avr0154 ; 0153 C000
    avr0154: adc r24, r25 ; 0154 1F89
    andi r24, 0x01 ; 0155 7081
    dec r18 ; 0156 952A
    brne avr014C ; 0157 F7A1
    ldi r25, 0x18 ; 0158 E198
    rcall Timer ; 0159 D012
    rjmp avr015B ; 015A C000
    avr015B: ror r24 ; 015B 9587
    brlo avr0167 ; 015C F050
    nop ; 015D 0000
    sbi PORTD, 4 ; 015E 9A94
    rjmp avr0160 ; 015F C000
    avr0160: ldi r25, 0x32 ; 0160 E392
    rcall Timer ; 0161 D00A
    nop ; 0162 0000
    rjmp avr0164 ; 0163 C000
    avr0164: sbi PORTD, 4 ; 0164 9A94
    cbi DDRD, 4 ; 0165 988C
    ret ; 0166 9508
    avr0167: cbi PORTD, 4 ; 0167 9894
    rjmp avr0160 ; 0168 CFF7
    avr0169: cbi PORTD, 4 ; 0169 9894
    rjmp avr0154 ; 016A CFE9

    DelayStream2:
    ldi r25, 0x4D ; 016B E49D
    Timer2:
    dec r25 ; 016C 959A
    brne Timer2 ; 016D F7F1
    ret ; 016E 9508
    avr016F: ldi r22, 0xFF ; 016F EF6F
    ldi r24, 0x00 ; 0170 E080
    lsr r22 ; 0171 9566
    brlo avr0173 ; 0172 F000
    avr0173: lsr r22 ; 0173 9566
    brsh avr0177 ; 0174 F410
    nop ; 0175 0000
    rjmp avr0177 ; 0176 C000
    avr0177: inc r22 ; 0177 9563
    inc r24 ; 0178 9583
    avr0179: nop ; 0179 0000
    dec r22 ; 017A 956A
    brne avr0179 ; 017B F7E9
    nop ; 017C 0000
    ldi r22, 0x3F ; 017D E36F
    dec r24 ; 017E 958A
    brne avr0179 ; 017F F7C9
    ret ; 0180 9508



    ;***************************************************************************
    ;Intercept Ins 58 para IRD SKY.
    ;***************************************************************************

    Ins58: ldi XL, ByteLen ; Verifica se o tamanho e "17"
    ld Temp, X+
    ;cpi Temp, 0x17 ; 48 58 xx xx 17
    ;breq StartIns58
    ;rjmp ReadClass ; Volta a Logar
    ;---------------------------------------------------------------------------
    StartIns58: ldi Tx_Byte, FuseByte ; Envia novo Fuse Byte para o IRD
    rcall TxIRD_IF_RxCARD_start ; Fuse Byte <<<<<<<<<<<<<<<<<<<<<
    ;---------------------------------------------------------------------------
    ldi Counter, 0x04 ; Monitora a passagem do N. do Card
    rcall Monit_IRD ; para o IRD YY + ZZ + KK + LL

    ; ldi Tx_Byte, CAMID_ativado_1 ; Envia o novo número do CARD
    ; rcall TxIRD_IF_RxCARD_start ; ativado para o IRD no lugar do
    ; ldi Tx_Byte, CAMID_ativado_2 ; número real
    ; rcall TxIRD_IF_RxCARD_start ;
    ; ldi Tx_Byte, CAMID_ativado_3 ;
    ; rcall TxIRD_IF_RxCARD_start ;
    ; ldi Tx_Byte, CAMID_ativado_4 ;
    ; rcall TxIRD_IF_RxCARD_start ;
    ;---------------------------------------------------------------------------
    ldi Counter, 0x05 ; Monitora a passagem de 5 Bytes
    rcall Monit_IRD ; para o IRD ZZ + XX + XX + XX + XX
    ;---------------------------------------------------------------------------
    ldi Tx_Byte, TimeZone ; Envia novo Time Zone para o IRD
    rcall TxIRD_IF_RxCARD_start ; Time Zone Brazil = 01
    ;---------------------------------------------------------------------------
    rcall RxIRD_Start ; Monitora a passagem de um byte
    ;---------------------------------------------------------------------------
    ldi Tx_Byte, GuideByte ; Envia um novo Guide Byte para o IRD
    rcall TxIRD_IF_RxCARD_start ; Guide Byte Brasil = 81h
    ;---------------------------------------------------------------------------
    ldi Counter, 0x0D ; Seta para Monitorar 10 Bytes
    rcall Monit_IRD ; Vai Monitorar a passagem de 10 Bytes
    rcall Monit_Sw1Sw2_CARD ; Monitora 90 20 se OK (Sw1/Sw2)
    rjmp ReadClass ; Logger ( Volta a Logar )

    ;***************************************************************************
    ; Monitora passagem de 90 20 (Sw1/Sw2) do CARD
    ;***************************************************************************
    ;
    Monit_Sw1Sw2_CARD:
    ldi Counter, 0x02 ; Seta para Monitorar 02 Bytes
    rcall Monit_CARD ; Vai Monitorar a passagem de 02 Bytes
    ret ; Retorna

    ;***************************************************************************
    ; Monitora a passagem de "conter" bytes vindos do IRD
    ;***************************************************************************
    ;
    Monit_IRD: rcall RxIRD_Start ; Monitora um Buyte
    dec Counter ; decrementa o contador
    brne Monit_IRD ; e volta a monitorar ate o final
    ret ; Retorna

    ;***************************************************************************
    ; Monitora a passagem de "conter" bytes vindos do CARD
    ;***************************************************************************
    ;
    Monit_CARD: rcall RxCARD_Start ; Monitora um Buyte
    dec Counter ; decrementa o contador
    brne Monit_CARD ; e volta a monitorar ate o final
    ret ; Retorna

    ;***************************************************************************
    ; RxIRD_Buffer => Read Data from IRD to buffer
    ;***************************************************************************
    ;
    RxIRD_Buffer: rcall RxIRD_Start ; Recebe Byte do IRD
    st X+, Rx_Byte ; Grava na posição do Buffersde X+
    dec Counter
    brne RxIRD_Buffer
    ret ; Retorna

    ;***************************************************************************
    ; RxCARD_Buffer => Read Data from CARD to buffer
    ;***************************************************************************
    ;
    RxCARD_Buffer:
    rcall RxCARD_Start ; Recebe Byte do CARD
    st X+, Rx_Byte ; Grava na posição do Buffersde X+
    dec Counter
    brne RxCARD_Buffer
    ret ; Retorna

    ;***************************************************************************
    ; TxIRD_Buffer => Write Data from buffer to IRD
    ;***************************************************************************
    ;
    TxIRD_Buffer: ld Tx_Byte, X+
    rcall TxIRD_start ; Transmite Byte para o IRD
    rcall DelayStream ; Da um delay Fixo
    rcall DelayStream ; Da um delay Fixo
    dec Counter
    brne TxIRD_Buffer
    ret ; Retorna

    ;***************************************************************************
    ; TxCARD_Buffer => Write Data from buffer to CARD
    ;***************************************************************************
    ;
    TxCARD_Buffer:
    ld Tx_Byte, X+
    rcall TxCARD_start ; Transmite Byte para o CARD
    rcall DelayStream ; Da um delay Fixo
    dec Counter
    brne TxCARD_Buffer
    ret ; Retorna

    ;***************************************************************************
    ; TxIRD_IF_RxCARD_Buffer => Write Data from buffer to IRD no lugar do CARD
    ;***************************************************************************
    ;
    TxIRD_IF_RxCARD_Buffer:
    ld Tx_Byte, X+ ; Transmite Byte para o IRD
    rcall TxIRD_IF_RxCARD_start ; Transmite no lugar do CARD
    dec Counter ; decrementa o contador
    brne TxIRD_IF_RxCARD_Buffer ; volta a Transmitir
    ret ; Retorna

    ;***************************************************************************
    ; TxCARD_IF_RxIRD_Buffer => Write Data from buffer to CARD no lugar do IRD
    ;***************************************************************************
    ;
    TxCARD_IF_RxIRD_Buffer:
    ld Tx_Byte, X+ ; Transmite Byte para o CARD
    rcall TxCARD_IF_RxIRD_start ; Transmite no lugar do IRD
    dec Counter ; decrementa o contador
    brne TxCARD_IF_RxIRD_Buffer ; volta a Transmitir
    ret ; Retorna

    ;***************************************************************************
    ; TxIRD_IF_RxCARD => Tranmite Data to PD0 If Read Data from PD4
    ;***************************************************************************

    TxIRD_IF_RxCARD_start:
    TxIRD_IF_RxCARD_L0:
    sbis PIND, IO_CARD ; wait for I/O to go high - line idle
    rjmp TxIRD_IF_RxCARD_L0 ;
    sbi ddrd, On_Off_4066 ;
    cbi portd, On_Off_4066 ; 4066 OFF
    TxIRD_IF_RxCARD_L1:
    sbic PIND, IO_CARD ; Wait Start Bit from PD4(CARD GL23)
    rjmp TxIRD_IF_RxCARD_L1
    rcall TxIRD_start ; Transmite no lugar do CARD
    TxIRD_IF_RxCARD_L2:
    sbis PIND, IO_CARD ; wait for I/O to go high - line idle
    rjmp TxIRD_IF_RxCARD_L2 ;
    sbi ddrd, On_Off_4066 ;
    sbi portd, On_Off_4066 ; 4066 ON
    ret ; Retorna

    ;***************************************************************************
    ; TxCARD_IF_RxIRD => Tranmite Data to PD4 If Read Data from PD0
    ;***************************************************************************

    TxCARD_IF_RxIRD_start:
    TxCARD_IF_RxIRD_L0:
    sbis PIND, IO_IRD ; wait for I/O to go high - line idle
    rjmp TxCARD_IF_RxIRD_L0
    sbi ddrd, On_Off_4066 ;
    cbi portd, On_Off_4066 ; 4066 OFF
    TxCARD_IF_RxIRD_L1:
    sbic PIND, IO_IRD ; Wait Start Bit from PD0(IRD)
    rjmp TxCARD_IF_RxIRD_L1 ;
    rcall TxCARD_start ; Transmite no lugar do IRD
    TxCARD_IF_RxIRD_L2:
    sbis PIND, IO_IRD ; wait for I/O to go high - line idle
    rjmp TxCARD_IF_RxIRD_L2 ;
    sbi ddrd, On_Off_4066 ;
    sbi portd, On_Off_4066 ; 4066 ON
    ret ; Retorna

    ;***************************************************************************
    ; RxIRD => Read Data from PD0 (RxP0 by 38400 BPS) => IO_IRD => IRD+Card
    ;***************************************************************************
    ; Receive 1 byte at f/93 bps. @3.579545MHz=38489 bps, @4.5MHz=48387 bps.
    ;
    RxIRD_start:
    RxIRD_start_L1:
    sbis PIND, IO_IRD ; Pula quando a linha for positiva (1 Clock) ou (2 Clock)
    rjmp RxIRD_start_L1 ; Esperando que o IRD comesse a falar (2 Clock)
    ; Inicia recebendo o Start Bit
    RxIRD_L1: sbic PIND, IO_IRD ; Espera o inicio do Start Bit (1 Clock) ou (2 Clock)
    rjmp RxIRD_L1 ; (2 Clock)
    ; Agarda (51 Clock's) pegando o inicio (1/16 Bit's)
    ldi Delay, 17 ; Prepara para esperar 48 ciclos de clock (1 Clock)
    RxIRD_L2: dec Delay ; Espera ciclos de clock (1/2 Bit's) (1 Clock)
    brne RxIRD_L2 ; (1 Clock) ou (2 Clock)
    ; Gasta (2 Clock's) preparando Byte
    ldi Rx_Byte, 1 ; (1 Clock)
    nop ; (1 Clock)
    ; Aguarda (87 Clock's) passando o Start Bit e lendo o primeiro bit
    RxIRD_L3: ldi Delay, 29 ; (1 Clock)
    RxIRD_L4: dec Delay ; Espera ciclos de clock (1 Bit) (1 Clock)
    brne RxIRD_L4 ; (1 Clock) ou (2 Clock)
    ; Gasta (6 Clock's)
    in RxTxAux, PIND ; (1 Clock)
    lsr RxTxAux ; (1 Clock)
    rol Rx_Byte ; (1 Clock)
    nop ; (1 Clock)
    brsh RxIRD_L3 ; volta para pegar os ouros Bit's (1 Clock) ou (2 Clock)
    ; Gasta (2 Clock) Inverte o Byte Recebido para o padrão normal
    com Rx_Byte ; (1 Clock)
    nop ; (1 Clock)
    ; Aguarda (86 Clock's) para completar o ultimo Bit lido
    ; Aguarda (93 Clock's) para passar o Bit de Paridade
    ; Aguarda (93 Clock's) para passar o Stop Bit
    ; Totalizando (272 Clock's)
    ldi Delay, 90 ; Espera 272 ciclos de clock ( 1+1+9/10 Bit's) (1 Clock)
    RxIRD_L5: dec Delay ; (1 Clock)
    brne RxIRD_L5 ; para passar o Bit de paridade (1 Clock) ou (2 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (33 Clock's) para compor o tempo matando o ruido do IRD para o CARD
    ldi Delay, 0x08 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 8*3+6=30 (30 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Esta rotina tem 86 clocks a mais que a original
    ; Aguarda a linha de I/O ficar em HI +5v
    RxIRD_L6: sbis PIND, IO_IRD ; Espera terminar o Stop Bit (1 Clock) ou (2 Clock)
    rjmp RxIRD_L6 ; Sai quando a linha for positiva (2 Clock)
    ret

    ;***************************************************************************
    ; TxIRD => Tranmite Data to PD0 (TxP0 By 38400 BPS) => IO_IRD => IRD+Card
    ;***************************************************************************
    ; Transmite 1 byte at f/93 bps. @3.579545MHz=38489 bps, @4.5MHz=48387 bps.
    ;
    ; ATR: 3F 7F 13 25 02 40 B0 12 69 FF 4A 50 90 47 4C 00 00 00 00 00
    ;
    ; Convention: INVERSE
    ; Protocol: T=0
    ; TA1 = 13
    ; TB1 = 25
    ; TC1 = 02
    ;
    ; Historical Bytes: 40 B0 12 69 FF 4A 50 90 47 4C 00 00 00 00 00
    ; @ ° i ÿ J P  G L
    ;
    ; Programming Voltage = 5.0 volts
    ; Programming Current = 50ma
    ; Maximum Clock Frequency = 5.0MHz
    ;
    ; Assuming a 3.5790MHz clock:
    ; Work ETU = 0.0000259849 seconds (tempo para um Bit)
    ; Guard Time = 0.0003637887 seconds (13 x o tempo de 1 Bit)
    ; Baud Rate After Reset = 38484
    ;
    ;
    TxIRD_start:
    TxIRD_start_L1:
    sbis PIND, IO_IRD ; wait for I/O to go high - line idle
    rjmp TxIRD_start_L1
    ; Inicia o Start Bit
    sbi ddrd, IO_IRD ; set I/O line as output (TX) Low (0 Volts) (2 Clock)
    cbi portd, IO_IRD ; Transmite o Start Bit (2 Clock)
    ; Aguarda (7 Clock's) para criar o Start Bit
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Aguarda (2 Clock's) Preparando os bit's dos Bytes
    ldi RxTxCounterBits, 8 ; count 8 bits (1 Clock)
    clr RxTxAux ; clear parity reg (1 Clock)
    ; Aguarda (81 Clock's) para criar o Start Bit
    TxIRD_L4: ldi Delay, 24 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 24*3+6=78 (78 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (7 Clocks) e seta o Proximo bit do Byte a ser transmitido gastando (3 Clock's) até setar o Bit e (4 Clock's) depois
    rol Tx_Byte ; put MSB into carry (1 Clock)
    brcs TxIRD_L10 ; jump if bit = 1 (1 Clock) ou (2 Clock)
    nop ; (1 Clock)
    sbi portd, IO_IRD ; bit = 0 so set TX high (inverted data) (2 Clock)
    rjmp TxIRD_L5 ; (2 Clock)
    TxIRD_L10: cbi portd, IO_IRD ; bit = 1 so set TX low (inverted) (2 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Aguarda (5 Clock's) para calcular o bit de paridade
    TxIRD_L5: adc RxTxAux, Delay ; calc parity (1 Clock)
    andi RxTxAux, 1 ; (1 Clock)
    dec RxTxCounterBits ; dec count of bits (1 Clock)
    brne TxIRD_L4 ; TX 8 bits (1 Clock) ou (2 Clock)
    ; Aguarda (82 Clock's) para criar o Start Bit
    ldi Delay,25 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 25*3+6=81 (81 Clock's)
    ; Gasta (7 Clocks) e seta bit de paridade a ser transmitido gastando (3 Clock's) até setar o Bit e (4 Clock's) depois
    ror RxTxAux ; (1 Clock)
    brcs TxIRD_L9 ; jump if parity bit = 1 (1 Clock) ou (2 Clock)
    nop ; (1 Clock)
    sbi portd, IO_IRD ; bit = 0 so set TX high (inverted data) (2 Clock)
    rjmp TxIRD_L7 ; (2 Clock)
    TxIRD_L9: cbi portd, IO_IRD ; bit = 1 so set TX low (inverted) (2 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta ( 89 Clock's) Completando o tempo do Bit de paridade transmitido (f/96 bpd)
    TxIRD_L7: ldi Delay, 27 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 27*3+6=87 (87 Clock's)
    nop ; (1 Clock)
    ; Gasta ( 93 Clock's) Transmitindo o 1 Stop Bit
    sbi portd, IO_IRD ; bit = 0 so set TX high (inverted data) (2 Clock)
    ldi Delay, 28 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 28*3+6=90 (90 Clock's)
    ; Esta rotina tem 1 clocks a mais que a original
    cbi ddrd, IO_IRD ; set I/O line to input (RX) (1 Clock)
    cbi portd, IO_IRD ; (1 Clock)
    ret

    ;***************************************************************************
    ; RxCARD => Read Data From PD4 (RxP4 by 38400 BPS)=> IO_CARD => Apenas CARD GL23
    ;***************************************************************************
    ; Receive 1 byte at f/93 bps. @3.579545MHz=38489 bps, @4.5MHz=48387 bps.
    ;
    RxCARD_Start:
    RxCARD_Start_L1:
    sbis PIND, IO_CARD ; skip if pd4 set
    rjmp RxCARD_Start_L1
    ; Inicia recebendo o Start Bit
    RxCARD_L1: sbic PIND, IO_CARD ; Wait Start Bit
    rjmp RxCARD_L1
    ; Agarda (19 Clock's) pegando o inicio (1/16 Bit's)
    ldi Delay, 4 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 4*3+6=18 (18 Clock's)
    ; Gasta (1 Clock) preparando Byte
    ldi Rx_Byte, 0x01 ; (1 Clock)

    ; Aguarda (87 Clock's) passando o Start Bit e lendo o primeiro bit
    RxCARD_L3: ldi Delay, 26 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 26*3+6=84 (84 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (3 Clock's) para ler o bit
    clc ; (1 Clock)
    sbis PIND, IO_CARD ; (1 Clock) ou (2 Clock's)
    sec ; (1 Clock)
    ; Gasta (3 Clock's) rotacionar e voltar a ler os bit's se for o ultimo gasta (2 Clock's)
    rol Rx_Byte ; (1 Clock)
    brsh RxCARD_L3 ; volta para pegar os ouros Bit's (1 Clock) ou (2 Clock's)
    ; Gasta (89 Clock's) para completar o tempo do ultimo bit
    ; Gasta (93 Clock's) para passar o bit de paridade
    ; Gasta (93 Clock's) para passar o Stop bit
    ; Totalizando (275 Clock's) na verssão anterior esperava (385 Clock's)
    ldi Delay, 89 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 89*3+6=273 (273 Clock's)
    nop ; (1 Clock)

    ; Aguarda a linha de I/O ficar em HI +5v
    RxCARD_L6: sbis PIND, IO_CARD ; Wait PD4 Hi
    rjmp RxCARD_L6 ; Sai quando a linha for positiva
    ret ; Return

    ;***************************************************************************
    ; TxCARD => Transmite Data To PD4 (RxP4 By 38400 BPS) => IO_CARD => Apenas CARD GL23
    ;***************************************************************************
    ; Transmite 1 byte at f/93 bps. @3.579545MHz=38489 bps, @4.5MHz=48387 bps.
    ;
    ; ATR: 3F 7F 13 25 02 40 B0 12 69 FF 4A 50 90 47 4C 00 00 00 00 00
    ;
    ; Convention: INVERSE
    ; Protocol: T=0
    ; TA1 = 13
    ; TB1 = 25
    ; TC1 = 02
    ;
    ; Historical Bytes: 40 B0 12 69 FF 4A 50 90 47 4C 00 00 00 00 00
    ; @ ° i ÿ J P  G L
    ;
    ; Programming Voltage = 5.0 volts
    ; Programming Current = 50ma
    ; Maximum Clock Frequency = 5.0MHz
    ;
    ; Assuming a 3.5790MHz clock:
    ; Work ETU = 0.0000259849 seconds (tempo para um Bit)
    ; Guard Time = 0.0003637887 seconds (13 x o tempo de 1 Bit)
    ; Baud Rate After Reset = 38484
    ;
    ;
    TxCARD_start:
    TxCARD_start_L1:
    sbis PIND, IO_CARD ; Espera Linha da I/O = High (skip if pd4 set)
    rjmp TxCARD_start_L1
    ; Gasta (15 Clock's) para comessar a transmitir (tempo para o cartão se preparar)
    ldi Delay, 0x02 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 2*3+6=12 (12 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Transmite o Start Bit
    sbi DDRD, IO_CARD ; Seta I/O Como Output (TX)0 (2 Clock's)
    cbi PORTD, IO_CARD ; StartBit (Start Bit) (2 Clock's)
    ; Gasta (7 Clock's) para compor o tempo do Start Bit
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (2 Clock's) Preparando os Bit's do Byte a serem transmitidos para o card
    ldi RxTxCounterBits, 8 ; Contador de 8 bits (1 Clock)
    clr RxTxAux ; Clear Registro de Paridate (1 Clock)
    ; Gasta (81 Clock's) Preparando os Bit's do Byte a serem transmitidos para o card
    TxCARD_L4: ldi Delay, 24 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 24*3+6=78 (78 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (7 Clocks) e seta o Proximo bit do Byte a ser transmitido gastando (3 Clock's) até setar o Bit e (4 Clock's) depois
    rol Tx_Byte ; put MSB into carry (1 Clock)
    brcs TxCARD_L10 ; jump if bit = 1 (1 Clock) ou (2 Clock's)
    nop ; (1 Clock)
    sbi PORTD, IO_CARD ; bit = 0 so set TX high (inverted data) (2 Clock's)
    rjmp TxCARD_L5 ; (2 Clock's)
    TxCARD_L10: cbi PORTD, IO_CARD ; bit = 1 so set TX low (inverted) (2 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta (5 Clock's) para calcular a paridade dos bit's
    TxCARD_L5: adc RxTxAux, Delay ; calc parity (1 Clock)
    andi RxTxAux, 0x01 ; (1 Clock)
    dec RxTxCounterBits ; dec count of bits (1 Clock)
    brne TxCARD_L4 ; TX 8 bits (1 Clock) ou (2 Clock's)
    ; Gasta ( 82 Clock's) Completando o ultimo Bit do Byite transmitido
    ldi Delay, 25 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 25*3+6=81 (81 Clock's)
    ; Gasta (7 Clocks) e seta o Proximo bit do Byte a ser transmitido gastando (3 Clock's) até setar o Bit e (4 Clock's) depois
    ror RxTxAux ; Transmite a paridade calculada (1 Clock)
    brlo TxCARD_L9 ; jump if parity bit = 1 (1 Clock) ou (2 Clock's)
    nop ; (1 Clock)
    sbi PORTD, IO_CARD ; bit = 0 so set TX high (inverted data) (2 Clock's)
    rjmp TxCARD_L7 ; (2 Clock's)
    TxCARD_L9: cbi PORTD, IO_CARD ; bit = 1 so set TX low (inverted) (2 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Gasta ( 89 Clock's) Completando o tempo do Bit de paridade transmitido (f/96 bpd)
    TxCARD_L7: ldi Delay, 27 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 27*3+6=87 (87 Clock's)
    nop ; (1 Clock)
    ; Gasta ( 93 Clock's) Transmitindo o 1 Stop Bit
    sbi PORTD, IO_CARD ; bit = 0 so set TX high (inverted data) (2 Clock's)
    ldi Delay, 28 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 => 28*3+6=90 (90 Clock's)
    ; Gasta (33 Clock's) para compor o tempo matando o ruido do IRD para o CARD
    ldi Delay, 0x08 ; (1 Clock)
    rcall Timer ; Timer(Clocks)=(Delay*3)+3+3 Clock's => 8*3+6=30 (30 Clock's)
    nop ; (1 Clock)
    nop ; (1 Clock)
    ; Espera a linha I/O ficar em HI +5v
    cbi DDRD, IO_CARD ; set I/O line to input (RX) (2 Clock's)
    cbi PORTD, IO_CARD ; (2 Clock's)
    ret

    ;******************************** Timer ************************************
    ; Timer para PEQUENOS Delays adrões e ajustaveis
    ;***************************************************************************
    ; DelayStream(Clocks)=1+(Delay*3)+3+3 Clock's = 1+(77*3)+3+3=238 (238 Clock's)
    ; Timer(Clocks)=(Delay*3)+3+3 Clock's
    ;
    DelayStream: ldi Delay, 0x4D ; Delay Fixo (0x4D) (1 Clock)
    ;---------------------------------------------------------------------------
    Timer: dec Delay ; Delay ajustavel (1 Clock)
    brne Timer ; (1 Clock) ou (2 Clock)
    ret ; (4 Clock)

    ;***************************************************************************
    Loop: Rjmp Loop ;Utilizado em modo programacao
    ;***************************************************************************

    Fim:

    .Exit
Responder

Volver a “Asm”