mirror of
https://github.com/lampmerchant/tashtwenty.git
synced 2024-11-24 19:33:51 +00:00
4688 lines
156 KiB
NASM
4688 lines
156 KiB
NASM
;;; 80 characters wide please ;;;;;;;;;;;;;;;;;;;;;;;;;; 8-space tabs please ;;;
|
|
|
|
|
|
;
|
|
;;;
|
|
;;;;; TashTwenty: Single-Chip DCD Interface
|
|
;;;
|
|
;
|
|
|
|
|
|
;;; License ;;;
|
|
|
|
; This program is free software: you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation, either version 3 of the License, or
|
|
; (at your option) any later version.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
;
|
|
; You should have received a copy of the GNU General Public License
|
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
;;; Connections ;;;
|
|
|
|
;;; ;;;
|
|
; .--------. ;
|
|
; Supply -|01 \/ 14|- Ground ;
|
|
; !ENBL ---> RA5 -|02 13|- RA0 ---> Next !ENBL ;
|
|
; PH3 ---> RA4 -|03 12|- RA1 <--- PH0 ;
|
|
; PH2 ---> RA3 -|04 11|- RA2 <--- PH1 ;
|
|
; WR ---> RC5 -|05 10|- RC0 ---> MMC SCK ;
|
|
; RD <--- RC4 -|06 09|- RC1 <--- MMC MISO ;
|
|
; MMC !CS <--- RC3 -|07 08|- RC2 ---> MMC MOSI ;
|
|
; '--------' ;
|
|
;;; ;;;
|
|
|
|
|
|
;;; Assembler Directives ;;;
|
|
|
|
list P=PIC16F1825, F=INHX32, ST=OFF, MM=OFF, R=DEC, X=ON
|
|
#include P16F1825.inc
|
|
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
|
|
;_FOSC_INTOSC Internal oscillator, I/O on RA5
|
|
;_WDTE_OFF Watchdog timer disabled
|
|
;_PWRTE_ON Keep in reset for 64 ms on start
|
|
;_MCLRE_OFF RA3/!MCLR is RA3
|
|
;_CP_OFF Code protection off
|
|
;_CPD_OFF Data memory protection off
|
|
;_BOREN_OFF Brownout reset off
|
|
;_CLKOUTEN_OFF CLKOUT disabled, I/O on RA4
|
|
;_IESO_OFF Internal/External switch not needed
|
|
;_FCMEN_OFF Fail-safe clock monitor not needed
|
|
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _LVP_OFF
|
|
;_WRT_OFF Write protection off
|
|
;_PLLEN_ON 4x PLL on
|
|
;_STVREN_ON Stack over/underflow causes reset
|
|
;_LVP_OFF High-voltage on Vpp to program
|
|
|
|
|
|
;;; Macros ;;;
|
|
|
|
DELAY macro value ;Delay 3*W cycles, set W to 0
|
|
movlw value
|
|
decfsz WREG,F
|
|
bra $-1
|
|
endm
|
|
|
|
DNOP macro
|
|
bra $+1
|
|
endm
|
|
|
|
|
|
;;; Constants ;;;
|
|
|
|
;FLAGS:
|
|
ABORTED equ 7 ;Set if a transmit or receive operation was aborted
|
|
RNFERR equ 6 ;Set if host tries to access a too-high block address
|
|
DEVSEL1 equ 1 ;MSB of which device is selected
|
|
DEVSEL0 equ 0 ;LSB of which device is selected
|
|
|
|
;M_FLAGS:
|
|
M_FAIL equ 7 ;Set when there's been a failure on the MMC interface
|
|
M_CMDLR equ 6 ;Set when R3 or R7 is expected (5 bytes), not R1
|
|
M_CMDRB equ 5 ;Set when an R1b is expected (busy signal after reply)
|
|
M_MBRD equ 4 ;Set when a multiblock read is in progress
|
|
M_MBWR equ 3 ;Set when a multiblock write is in progress
|
|
M_BKADR equ 2 ;Set when block (rather than byte) addressing is in use
|
|
M_CDVER equ 1 ;Set when dealing with a V2.0+ card, clear for 1.0
|
|
|
|
;DVxFLAG:
|
|
DV_EXST equ 7 ;Set when device exists
|
|
|
|
;Firmware version
|
|
FWVER_3 equ 0x20
|
|
FWVER_2 equ 0x21
|
|
FWVER_1 equ 0x11
|
|
FWVER_0 equ 0x28
|
|
|
|
|
|
;;; Variable Storage ;;;
|
|
|
|
cblock 0x70 ;Bank-common registers
|
|
|
|
FLAGS ;You've got to have flags
|
|
GROUPS ;Count of groups to transmit, count of groups received
|
|
CRC16H ;High byte of the CRC16 register
|
|
CRC16L ;Low byte of the CRC16 register
|
|
M_FLAGS ;MMC flags
|
|
M_CMDN ;The MMC command to be sent, later the R1 response byte
|
|
M_ADR3 ;First (high) byte of the address, first byte of R3/R7 response
|
|
M_ADR2 ;Second byte of the address, second byte of R3/R7 response
|
|
M_ADR1 ;Third byte of the address, third byte of R3/R7 response
|
|
M_ADR0 ;Fourth (low) byte of the address, last byte of R3/R7 response
|
|
TEMP ;Various purposes
|
|
TEMP2 ;Various purposes
|
|
D3
|
|
D2
|
|
D1
|
|
D0
|
|
|
|
endc
|
|
|
|
cblock 0x20 ;Bank 0 registers
|
|
|
|
;Partition struct
|
|
DV0FLAG ;Device 0 flags
|
|
DV0LN_2 ;Device 0 LBA length
|
|
DV0LN_1 ; "
|
|
DV0LN_0 ; "
|
|
DV0ST_3 ;Device 0 start LBA
|
|
DV0ST_2 ; "
|
|
DV0ST_1 ; "
|
|
DV0ST_0 ; "
|
|
DV1FLAG ;Device 1 flags
|
|
DV1LN_2 ;Device 1 LBA length
|
|
DV1LN_1 ; "
|
|
DV1LN_0 ; "
|
|
DV1ST_3 ;Device 1 start LBA
|
|
DV1ST_2 ; "
|
|
DV1ST_1 ; "
|
|
DV1ST_0 ; "
|
|
DV2FLAG ;Device 2 flags
|
|
DV2LN_2 ;Device 2 LBA length
|
|
DV2LN_1 ; "
|
|
DV2LN_0 ; "
|
|
DV2ST_3 ;Device 2 start LBA
|
|
DV2ST_2 ; "
|
|
DV2ST_1 ; "
|
|
DV2ST_0 ; "
|
|
DV3FLAG ;Device 3 flags
|
|
DV3LN_2 ;Device 3 LBA length
|
|
DV3LN_1 ; "
|
|
DV3LN_0 ; "
|
|
DV3ST_3 ;Device 3 start LBA
|
|
DV3ST_2 ; "
|
|
DV3ST_1 ; "
|
|
DV3ST_0 ; "
|
|
|
|
;Error (high nibble) and unknown command (low nibble) log
|
|
LOG_00
|
|
LOG_01
|
|
LOG_02
|
|
LOG_03
|
|
LOG_04
|
|
LOG_05
|
|
LOG_06
|
|
LOG_07
|
|
LOG_08
|
|
LOG_09
|
|
LOG_0A
|
|
LOG_0B
|
|
LOG_0C
|
|
LOG_0D
|
|
LOG_0E
|
|
LOG_0F
|
|
LOG_10
|
|
LOG_11
|
|
LOG_12
|
|
LOG_13
|
|
LOG_14
|
|
LOG_15
|
|
LOG_16
|
|
LOG_17
|
|
LOG_18
|
|
LOG_19
|
|
LOG_1A
|
|
LOG_1B
|
|
LOG_1C
|
|
LOG_1D
|
|
LOG_1E
|
|
LOG_1F
|
|
|
|
;Card info
|
|
CARDINF
|
|
|
|
;TODO Unused 7 bytes
|
|
UNUSED6
|
|
UNUSED5
|
|
UNUSED4
|
|
UNUSED3
|
|
UNUSED2
|
|
UNUSED1
|
|
UNUSED0
|
|
|
|
endc
|
|
|
|
cblock 0x68 ;Top of data buffer (receive shorthand)
|
|
|
|
RC_SYNC ;Sync byte
|
|
RC_CMDG ;Command groups + 0x80
|
|
RC_RSPG ;Response groups + 0x80
|
|
RC_CMDN ;Command number
|
|
RC_BLKS ;Block count
|
|
RC_ADRH ;Block address high
|
|
RC_ADRM ;Block address middle
|
|
RC_ADRL ;Block address low
|
|
|
|
endc
|
|
|
|
cblock 0x68 ;Top of data buffer (transmit shorthand)
|
|
|
|
TX_CMDN ;Command number
|
|
TX_BLKS ;Block count
|
|
TX_STAT ;Status
|
|
TX_PAD1 ;Pad byte
|
|
TX_PAD2 ;Pad byte
|
|
TX_PAD3 ;Pad byte
|
|
TX_CSUM ;Checksum, if reply is only one group long
|
|
|
|
endc
|
|
|
|
|
|
;;; Vectors ;;;
|
|
|
|
org 0x0 ;Reset vector
|
|
bra Init
|
|
|
|
org 0x4 ;Interrupt vector
|
|
|
|
|
|
;;; Interrupt Handler ;;;
|
|
|
|
;BSR must always be at 0 when interrupts are on
|
|
|
|
Interrupt
|
|
lslf PORTA,W ;32 entries in the jump table, each has four
|
|
brw ; instructions; jump to the one matching state
|
|
nop ;We expect RA0 to be high
|
|
nop ; "
|
|
|
|
IntEn0 movlb 7 ;This is the suspend state, so we should never
|
|
clrf IOCAF ; get here unless it's a blip on one of the
|
|
retfie ; state lines - if it is, clear and return and
|
|
nop ; just hope timing isn't too badly wrecked
|
|
IntEn1 movlb 7 ;This is the communication state, so we should
|
|
clrf IOCAF ; never get here unless it's a blip on one of
|
|
retfie ; the state lines - if it is, clear and return
|
|
nop ; and just hope timing isn't too badly wrecked
|
|
IntEn2 bsf PORTC,RC4 ;Being in state 2 (idle) without first going to
|
|
bra IntAbort ; state 3 means mac wants to abort the
|
|
nop ; operation in progress
|
|
nop ; "
|
|
IntEn3 bra IntDoneReceive ;This means mac is done and is waiting for
|
|
nop ; !HSHK to be deasserted
|
|
nop ; "
|
|
nop ; "
|
|
IntEn4 bsf PORTC,RC4 ;This state (reset) is two states away from the
|
|
bra IntAbort ; communication state, which is strange, but
|
|
nop ; assume that it means mac wants to abort the
|
|
nop ; operation in progress
|
|
IntEn5 bcf PORTC,RC4 ;Now this is really weird; why would mac go to
|
|
bra Interrupt ; this state (drive RD low) in the middle of
|
|
nop ; communication? Whatever, drive RD low and
|
|
nop ; immediately circle back until state changes
|
|
IntEn6 bsf PORTC,RC4 ;Now this is really weird; why would mac go to
|
|
bra Interrupt ; this state (drive RD high) in the middle of
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; immediately circle back until state changes
|
|
IntEn7 bsf PORTC,RC4 ;Now this is really weird; why would mac go to
|
|
bra Interrupt ; this state (drive RD high) in the middle of
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; immediately circle back until state changes
|
|
IntEnNx bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to talk to the next device in mid-
|
|
nop ; communication? Whatever, drive RD high and
|
|
nop ; force an unexplained return to the idle state
|
|
IntNEn bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
bsf PORTC,RC4 ;Now this is really REALLY weird; why would mac
|
|
bra IntAbort ; decide to deassert !ENBL mid-communication?
|
|
nop ; Whatever, drive RD high and force an
|
|
nop ; unexplained return to the idle state
|
|
|
|
IntDoneReceive
|
|
movlp high RecvDecode ;Decode the data we've received
|
|
call RecvDecode ; "
|
|
bsf PORTC,RC4 ;Deassert !HSHK to acknowledge receive is done
|
|
IntDRc0 decf PORTA,W ;Check the current state
|
|
xorlw B'00000110' ;If it's still 3, mac hasn't acknowledged our
|
|
btfsc STATUS,Z ; acknowledgment of the end of received data
|
|
bra IntDRc0 ; yet, so loop again
|
|
xorlw B'00000010' ;If it's anything else but 2 (idle), something
|
|
btfss STATUS,Z ; weird's going on, so abort
|
|
bra IntAbort ; "
|
|
movlb 7 ;Clear the interrupt that got us here and any
|
|
clrf IOCAF ; we received after that
|
|
movlb 31 ;Swallow the interrupt return address and
|
|
decf STKPTR,F ; instead return to who called receiver
|
|
movlb 0 ; without reenabling interrupts
|
|
movlp 0 ;Reset PCLATH to where we're returning
|
|
return ; "
|
|
|
|
IntAbort
|
|
movlb 7 ;Clear the interrupt that got us here and any
|
|
clrf IOCAF ; we received after that
|
|
movlb 31 ;Swallow the return address where the PC was
|
|
decf STKPTR,F ; when the interrupt happened
|
|
movlb 0 ; "
|
|
bsf FLAGS,ABORTED ;Raise the aborted flag
|
|
movlp 0 ;Reset PCLATH to where we're returning
|
|
return ;Return to caller without reenabling interrupts
|
|
|
|
|
|
;;; Init ;;;
|
|
|
|
Init
|
|
banksel OSCCON ;32 MHz (w/PLL) high-freq internal oscillator
|
|
movlw B'11110000'
|
|
movwf OSCCON
|
|
|
|
banksel IOCAP ;When interrupts are on, any change on !ENBL,
|
|
movlw B'00111100' ; PH3, PH2, or PH1 triggers one; this is what
|
|
movwf IOCAP ; gets us out of the endless receive loop
|
|
movwf IOCAN
|
|
|
|
banksel SSPCON1 ;SSP SPI master mode, clock set by baud rate
|
|
movlw B'00101010' ; generator to 400 kHz, clock idles low, data
|
|
movwf SSPCON1 ; lines change on falling edge, data sampled on
|
|
movlw B'01000000' ; rising edge (CKP=0, CKE=1, SMP=0)
|
|
movwf SSP1STAT
|
|
movlw 19
|
|
movwf SSP1ADD
|
|
|
|
banksel ANSELA ;All pins digital, not analog
|
|
clrf ANSELA
|
|
clrf ANSELC
|
|
|
|
banksel LATA ;Next !ENBL off, RD and !CS high to start
|
|
movlw B'00111111'
|
|
movwf LATA
|
|
movwf LATC
|
|
|
|
banksel TRISA ;State pins inputs, RA0 output, WR input, RD
|
|
movlw B'00111110' ; tristated to start, MISO input, !CS, MOSI,
|
|
movwf TRISA ; and SCK output
|
|
movlw B'00110010'
|
|
movwf TRISC
|
|
|
|
movlw B'00001000' ;Interrupt on PORTA pin change enabled, but
|
|
movwf INTCON ; interrupt subsystem off for now
|
|
|
|
movlw 0x20 ;Zero all bank 0 registers
|
|
movwf FSR0H
|
|
clrf FSR0L
|
|
movlw 72
|
|
movwf TEMP
|
|
movlw 0
|
|
ClrLoop movwi FSR0++
|
|
decfsz TEMP,F
|
|
bra ClrLoop
|
|
|
|
movlb 0 ;Start BSR at 0
|
|
|
|
movlw 11 ;Delay approximately 1 ms to allow the MMC card
|
|
movwf TEMP ; to come up - do not call MmcInit before this
|
|
DelayMs DELAY 242 ; has been done
|
|
decfsz TEMP,F ; "
|
|
bra DelayMs ; "
|
|
call MmcInit ;Initialize!
|
|
btfsc M_FLAGS,M_FAIL ;If we couldn't initialize the card, give up
|
|
goto NoDevices ; and pass !ENBL through to next device
|
|
movlb 4 ;Now that we're initialized, crank the speed
|
|
movlw B'00100001' ; of the SPI interface up to 2 MHz
|
|
movwf SSPCON1 ; "
|
|
movlb 0 ; "
|
|
|
|
movlw 0x51 ;Set up a read command for the MMC card (R1-
|
|
movwf M_CMDN ; type response)
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
clrf M_ADR3 ;Point the card address to the master boot
|
|
clrf M_ADR2 ; record
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf PORTC,RC3 ;Assert !CS
|
|
call MmcCmd ;Send the MMC command
|
|
btfsc M_FLAGS,M_FAIL ;If the operation failed, give up and just pass
|
|
goto NoDevices ; !ENBL through to the next device
|
|
movlw 0x20 ;Point FSR0 to the top of the data buffer
|
|
movwf FSR0H ; "
|
|
movlw 0x48 ; "
|
|
movwf FSR0L ; "
|
|
call MmcReadData ;Read data from the MMC card
|
|
btfsc M_FLAGS,M_FAIL ;If the operation failed, give up and just pass
|
|
goto NoDevices ; !ENBL through to the next device
|
|
bsf PORTC,RC3 ;Deassert !CS
|
|
|
|
movlw 0x22 ;Point FSR0 to the MBR partition table
|
|
movwf FSR0H ; "
|
|
movlw 0x06 ; "
|
|
movwf FSR0L ; "
|
|
movlw 0x20 ;Point FSR1 to the device structs
|
|
movwf FSR1H ; "
|
|
clrf FSR1L ; "
|
|
movlw 4 ;Loop through all four MBR partition entries
|
|
movwf TEMP ; "
|
|
MbrLoop moviw 4[FSR0] ;Check whether the partition type is 0xAF,
|
|
xorlw 0xAF ; which is the type code for HFS; if it isn't,
|
|
btfss STATUS,Z ; then move ahead to the next one
|
|
bra MbrNext ; "
|
|
moviw 15[FSR0] ;Check whether the partition size > 0xFFFFFF;
|
|
btfss STATUS,Z ; if it is, it's too big, move ahead to the
|
|
bra MbrNext ; next one
|
|
moviw 11[FSR0] ;Copy the partition start LBA, converting the
|
|
movwi 4[FSR1] ; little-endian number to big-endian as we go
|
|
moviw 10[FSR0] ; "
|
|
movwi 5[FSR1] ; "
|
|
moviw 9[FSR0] ; "
|
|
movwi 6[FSR1] ; "
|
|
moviw 8[FSR0] ; "
|
|
movwi 7[FSR1] ; "
|
|
moviw 14[FSR0] ;Copy the partition LBA size, converting the
|
|
movwi 1[FSR1] ; little-endian number to big-endian as we go
|
|
moviw 13[FSR0] ; "
|
|
movwi 2[FSR1] ; "
|
|
moviw 12[FSR0] ; "
|
|
movwi 3[FSR1] ; "
|
|
movlw 1 << DV_EXST ;Set the device-exists flag for this partition
|
|
movwi 0[FSR1] ; "
|
|
addfsr FSR1,8 ;Advance device struct pointer to next entry
|
|
MbrNext addfsr FSR0,16 ;Advance the MBR pointer to the next entry
|
|
decfsz TEMP,F ;If we have partition entries left to scan,
|
|
bra MbrLoop ; loop for the next one
|
|
moviw 0[FSR0] ;After all that, check whether the 0xAA55 (LE)
|
|
xorlw 0x55 ; MBR signature is present; if it isn't, then
|
|
btfss STATUS,Z ; all we did above was for nothing because this
|
|
goto NoDevices ; isn't a valid MBR, so just pass !ENBL through
|
|
moviw 1[FSR0] ; "
|
|
xorlw 0xAA ; "
|
|
btfss STATUS,Z ; "
|
|
goto NoDevices ; "
|
|
btfss DV0FLAG,DV_EXST ;If we didn't detect any valid partitions, just
|
|
goto NoDevices ; pass !ENBL through; if we have at least one,
|
|
goto WaitEnbl ; enter the normal idle loop and wait for !ENBL
|
|
|
|
|
|
;;; Mainline Code ;;;
|
|
|
|
GetCommand
|
|
bsf PORTC,RC4 ;Deassert !HSHK and prepare to receive
|
|
movlp high Receive ;Initiate receive
|
|
call Receive ; "
|
|
btfsc FLAGS,ABORTED ;If it was aborted, return to idle loop
|
|
return ; "
|
|
call CheckChecksum ;Calculate the checksum of the received block
|
|
btfss STATUS,Z ;If the checksum was bad, send a NAK
|
|
bra NakCommand ; "
|
|
movf RC_CMDN,W ;If the command number is 0x00, do a read
|
|
btfsc STATUS,Z ; "
|
|
bra CmdRead ; "
|
|
addlw -1 ;If the command number is 0x01, do a write
|
|
btfsc STATUS,Z ; "
|
|
bra CmdWrite ; "
|
|
addlw -2 ;If the command number is 0x03, get controller
|
|
btfsc STATUS,Z ; status (identify device)
|
|
bra CmdStatus ; "
|
|
addlw -62 ;If the command number is 0x41, do a continued
|
|
btfsc STATUS,Z ; write (write routine will tell this apart)
|
|
bra CmdWrite ; "
|
|
bra CmdUnknown ;If none of the above, fake a response
|
|
|
|
CmdUnknown
|
|
movf RC_CMDN,W ;Save the unknown command's number since it's
|
|
movwf TEMP2 ; about to be overwritten
|
|
call ClearResponse ;Clear the buffer according to expectations
|
|
movf TEMP2,W ;Our reply is going to be the command number
|
|
movwf TX_CMDN ; with its MSB set, by convention, but data
|
|
bsf TX_CMDN,7 ; will be all zeroes
|
|
clrf FSR0H ;Point FSR0 at error/unknown command log
|
|
bsf FSR0H,5 ; "
|
|
clrf FSR0L ; "
|
|
bsf FSR0L,5 ; "
|
|
andlw B'0011111' ;Mask off the low 5 bits of the command code
|
|
addwf FSR0L,F ; "
|
|
movf INDF0,W ;If the count (low nibble) is already at 15,
|
|
andlw B'00001111' ; keep it there; if it's below 15, increment it
|
|
xorlw B'00001111' ; "
|
|
btfss STATUS,Z ; "
|
|
incf INDF0,F ; "
|
|
call CalcChecksum ;Calculate the checksum of placeholder reply
|
|
movlp high Transmit ;Initiate transmission; if it's aborted, we
|
|
call Transmit ; don't actually do anything differently
|
|
return ;Done, hope the host doesn't mind
|
|
|
|
NakCommand
|
|
movlw 1 ;A NAK is a blank one-group command buffer with
|
|
movwf GROUPS ; a command number of 0x7F
|
|
movlw 0x7F ; "
|
|
movwf TX_CMDN ; "
|
|
clrf TX_BLKS ; "
|
|
clrf TX_STAT ; "
|
|
clrf TX_PAD1 ; "
|
|
clrf TX_PAD2 ; "
|
|
clrf TX_PAD3 ; "
|
|
movlw 0x81 ;We know what the checksum will be, so just
|
|
movwf TX_CSUM ; hardcode it
|
|
movlp high Transmit ;Initiate transmission; if it's aborted, we
|
|
call Transmit ; don't actually do anything differently
|
|
return ;Done
|
|
|
|
ErrorSetup
|
|
movlb 31 ;Insert the latter half of this function into
|
|
movf TOSH,W ; the call stack, then return to the caller so
|
|
movwf TEMP ; the caller can retlw a status code that we
|
|
movf TOSL,W ; can act on
|
|
movwf TEMP2 ; "
|
|
movlw high ErrSet0 ; "
|
|
movwf TOSH ; "
|
|
movlw low ErrSet0 ; "
|
|
movwf TOSL ; "
|
|
incf STKPTR,F ; "
|
|
movf TEMP,W ; "
|
|
movwf TOSH ; "
|
|
movf TEMP2,W ; "
|
|
movwf TOSL ; "
|
|
movlb 0 ; "
|
|
return ; "
|
|
ErrSet0 movf WREG,W ;If the caller returned status 0, just return
|
|
btfsc STATUS,Z ; to idle loop
|
|
return ; "
|
|
movwf TX_PAD1 ;Store error code in first transmitter pad byte
|
|
clrf FSR0H ;Point FSR0 at error/unknown command log
|
|
bsf FSR0H,5 ; "
|
|
clrf FSR0L ; "
|
|
bsf FSR0L,5 ; "
|
|
andlw B'0011111' ;Mask off the low 5 bits of the error code (we
|
|
addwf FSR0L,F ; need to keep to 32 or fewer errors)
|
|
movf INDF0,W ;If the error count (high nibble) is already at
|
|
andlw B'11110000' ; 15, keep it there; if it's below 15,
|
|
xorlw B'11110000' ; increment it
|
|
movlw 0x10 ; "
|
|
btfsc STATUS,Z ; "
|
|
addwf INDF0,F ; "
|
|
bsf PORTC,RC3 ;Deassert !CS
|
|
movlw 1 ;Communicate failure to the host by setting the
|
|
movwf GROUPS ; MSB of the status byte and sending only the
|
|
bsf TX_STAT,7 ; header group
|
|
call CalcChecksum ;Calculate the checksum
|
|
movlp high Transmit ;Initiate transmission; if it's aborted, we
|
|
call Transmit ; don't actually do anything differently
|
|
return ;Done
|
|
|
|
CmdRead
|
|
call ErrorSetup ;Set up error handling
|
|
movf RC_BLKS,W ;Move the block count from receiver position to
|
|
movwf TX_BLKS ; transmitter position
|
|
movlw 0x80 ;Command number is the read command with the
|
|
movwf TX_CMDN ; MSB set
|
|
clrf TX_STAT ;A zero status means all is well
|
|
call MmcStopOngoing ;Stop any multiblock read or write
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x01 ; "
|
|
call TranslateAddr ;Translate block address to MMC block address
|
|
btfsc FLAGS,RNFERR ;If we couldn't translate this block address to
|
|
retlw 0x02 ; an MMC address, report the error
|
|
call MmcConvAddr ;Convert the address if necessary
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x03 ; "
|
|
clrf TX_PAD1 ;Clear the padding bytes (don't do this before
|
|
clrf TX_PAD2 ; we convert the address since they overlap
|
|
clrf TX_PAD3 ; with the address bytes)
|
|
;TODO clear 20 tag bytes too?
|
|
movlw 0x52 ;Set up a read command for the MMC card (R1-
|
|
movwf M_CMDN ; type response)
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
bcf PORTC,RC3 ;Assert !CS
|
|
call MmcCmd ;Send the MMC command
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x04 ; "
|
|
bsf M_FLAGS,M_MBRD ;Set the flag for an ongoing multiblock read
|
|
CmdRea0 movlw 0x20 ;Point FSR0 past the six header bytes and the
|
|
movwf FSR0H ; 20 'tag' bytes to where the real data starts
|
|
movlw 0x62 ; "
|
|
movwf FSR0L ; "
|
|
call MmcReadData ;Read data from the MMC card
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x05 ; "
|
|
decf TX_BLKS,W ;If the blocks-remaining counter is at one,
|
|
btfsc STATUS,Z ; stop the multiblock read here before sending
|
|
call MmcStopOngoing ; our response to the mac
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x06 ; "
|
|
movlw 77 ;Set the group count to 77 (512 bytes of data,
|
|
movwf GROUPS ; 20 'tag' bytes, 6 byte header, checksum byte)
|
|
call CalcChecksum ;Calculate the checksum on our response
|
|
movlp high Transmit ;Initiate transmission
|
|
call Transmit ; "
|
|
btfsc FLAGS,ABORTED ;If the command was aborted, return to idle
|
|
retlw 0x00 ; loop
|
|
call MmcIncAddr ;Increment address for next read
|
|
decfsz TX_BLKS,F ;Decrement the block count; if it hits zero,
|
|
bra CmdRea0 ; that's all the reading we were requested to
|
|
retlw 0x00 ; do, so call it done
|
|
|
|
CmdWrite
|
|
call ErrorSetup ;Set up error handling
|
|
movf RC_BLKS,W ;Move the block count from receiver position to
|
|
movwf TX_BLKS ; transmitter position
|
|
movlw 0x81 ;Command number is the write command with the
|
|
movwf TX_CMDN ; MSB set
|
|
clrf TX_STAT ;A zero status means all is well
|
|
movf RC_CMDN,W ;If this is a continued write, we don't want to
|
|
xorlw 0x41 ; set up the write anew, so skip ahead
|
|
btfsc STATUS,Z ; "
|
|
bra CmdWriteCont ; "
|
|
call MmcStopOngoing ;Stop any multiblock read or write
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x07 ; "
|
|
call TranslateAddr ;Translate block address to MMC block address
|
|
btfsc FLAGS,RNFERR ;If we couldn't translate this block address to
|
|
retlw 0x08 ; an MMC address, report the error
|
|
call MmcConvAddr ;Convert the address if necessary
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x09 ; "
|
|
movlw 0x59 ;Set up a write command for the MMC card (R1-
|
|
movwf M_CMDN ; type reply)
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
bcf PORTC,RC3 ;Assert !CS
|
|
call MmcCmd ;Send the MMC command
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x0A ; "
|
|
bsf M_FLAGS,M_MBWR ;Set the flag for an ongoing multiblock write
|
|
CmdWriteCont
|
|
btfss M_FLAGS,M_MBWR ;If for some reason we got here without there
|
|
retlw 0x0B ; being a multiblock write going on, error
|
|
movlw 0x20 ;Point FSR0 past the sync, length, header, and
|
|
movwf FSR0H ; tag bytes, and to the data we'll be writing
|
|
movlw 0x65 ; "
|
|
movwf FSR0L ; "
|
|
call MmcWriteData ;Write data to the MMC card
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x0C ; "
|
|
decf RC_BLKS,W ;If the blocks-remaining counter is at one,
|
|
btfsc STATUS,Z ; stop the multiblock write here before sending
|
|
call MmcStopOngoing ; our response to the mac
|
|
btfsc M_FLAGS,M_FAIL ;If MMC operation failed, report the error
|
|
retlw 0x0D ; "
|
|
clrf TX_PAD1 ;Clear the padding bytes (don't do this before
|
|
clrf TX_PAD2 ; we convert the address since they overlap
|
|
clrf TX_PAD3 ; with the address bytes)
|
|
movlw 1 ;Acknowledgment is one group in length
|
|
movwf GROUPS ; "
|
|
call CalcChecksum ;Calculate the checksum on our response
|
|
movlp high Transmit ;Initiate transmission; if it's aborted, we
|
|
call Transmit ; don't actually do anything differently
|
|
retlw 0x00 ;Done
|
|
|
|
CmdStatus
|
|
call ClearResponse ;Clear the buffer for our response
|
|
movlw 0x83 ;Command number is the status command with the
|
|
movwf TX_CMDN ; MSB set
|
|
clrf TX_STAT ;A zero status means all is well
|
|
clrf TX_BLKS ;Clear the block count as it's not relevant
|
|
clrf TX_PAD1 ;Clear the padding bytes
|
|
clrf TX_PAD2 ; "
|
|
clrf TX_PAD3 ; "
|
|
movlw 0x20 ;Point FSR0 at the appropriate struct for the
|
|
movwf FSR0H ; selected device
|
|
clrf FSR0L ; "
|
|
btfsc FLAGS,DEVSEL1 ; "
|
|
addfsr FSR0,16 ; "
|
|
btfsc FLAGS,DEVSEL0 ; "
|
|
addfsr FSR0,8 ; "
|
|
movlw 0x20 ;Point FSR1 past the six header bytes to where
|
|
movwf FSR1H ; the real data starts
|
|
movlw 0x4E ; "
|
|
movwf FSR1L ; "
|
|
movlw 0x01 ;Device manufacturer is 0x0100, not sure if
|
|
movwi 2[FSR1] ; anybody cares
|
|
movlw 0xF6 ;Device is mountable, readable, writeable,
|
|
movwi 4[FSR1] ; ejectable (?), icon_included, & disk_in_place
|
|
moviw 3[FSR0] ;Copy the LBA length of the partition into the
|
|
movwi 7[FSR1] ; block size of the drive
|
|
moviw 2[FSR0] ; "
|
|
movwi 6[FSR1] ; "
|
|
moviw 1[FSR0] ; "
|
|
movwi 5[FSR1] ; "
|
|
addfsr FSR1,7 ;Decrement the block size of the drive because
|
|
movlw 0xFF ; it appears that the block size of the drive
|
|
addwf INDF1,F ; is actually the maximum block on the drive
|
|
addfsr FSR1,-1 ; TODO look into this further
|
|
addwfc INDF1,F ; "
|
|
addfsr FSR1,-1 ; "
|
|
addwfc INDF1,F ; "
|
|
addfsr FSR1,7 ;Point FSR1 to manufacturer info field
|
|
moviw 0[FSR0] ;Copy the partition information for this device
|
|
movwi FSR1++ ; into the first 8 bytes
|
|
moviw 1[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 2[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 3[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 4[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 5[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 6[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
moviw 7[FSR0] ; "
|
|
movwi FSR1++ ; "
|
|
movlw 0x20 ;Point FSR0 to remaining 40 bytes in bank 0
|
|
movwf FSR0L ; "
|
|
movlw 40 ;Copy 40 bytes to the manufacturer info field
|
|
movwf TEMP ; "
|
|
CmdSta0 moviw FSR0++ ; "
|
|
movwi FSR1++ ; "
|
|
decfsz TEMP,F ; "
|
|
bra CmdSta0 ; "
|
|
movlw FWVER_3 ;Copy firmware version into last four bytes of
|
|
movwi FSR1++ ; manufacturer info field and leave FSR1
|
|
movlw FWVER_2 ; pointing to icon field
|
|
movwi FSR1++ ; "
|
|
movlw FWVER_1 ; "
|
|
movwi FSR1++ ; "
|
|
movlw FWVER_0 ; "
|
|
movwi FSR1++ ; "
|
|
movlw high Icon | 0x80;Point FSR0 to the icon table
|
|
movwf FSR0H ; "
|
|
movlw low Icon ; "
|
|
movwf FSR0L ; "
|
|
clrf TEMP ;Copy 256 bytes to the icon field
|
|
CmdSta1 moviw FSR0++ ; "
|
|
movwi FSR1++ ; "
|
|
decfsz TEMP,F ; "
|
|
bra CmdSta1 ; "
|
|
movlw 0x0A ;The credits
|
|
movwi FSR1++ ; "
|
|
movlw 'T' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'a' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 's' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'h' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'T' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'w' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'e' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'n' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 't' ; "
|
|
movwi FSR1++ ; "
|
|
movlw 'y' ; "
|
|
movwi FSR1++ ; "
|
|
call CalcChecksum ;Calculate the checksum on our response
|
|
movlp high Transmit ;Initiate transmission; if it's aborted, we
|
|
call Transmit ; don't actually do anything differently
|
|
return ;Done
|
|
|
|
|
|
;;; Subprograms ;;;
|
|
|
|
;Calculate the checksum of the block about to be transmitted, containing
|
|
; GROUPS * 7 bytes. Trashes TEMP, TEMP2, and FSR0.
|
|
CalcChecksum
|
|
movlw 0x20 ;Point FSR0 at the top of the data buffer
|
|
movwf FSR0H ; "
|
|
movlw 0x48 ; "
|
|
movwf FSR0L ; "
|
|
movf GROUPS,W ;Copy the group count into TEMP
|
|
movwf TEMP ; "
|
|
clrf TEMP2 ;Zero the running sum (mod 256)
|
|
bra CalcCh1 ;Jump the first add so we sum one less than the
|
|
CalcCh0 moviw FSR0++ ; total bytes in the block and can write the
|
|
addwf TEMP2,F ; checksum to the very last byte position
|
|
CalcCh1 moviw FSR0++ ;Add the bytes in this group to the running sum
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
decfsz TEMP,F ;Loop until we've summed the last group
|
|
bra CalcCh0 ; "
|
|
comf TEMP2,W ;Two's complement the sum so the whole block
|
|
addlw 1 ; adds up to zero and write it to the block's
|
|
movwi FSR0++ ; last byte
|
|
return
|
|
|
|
;Calculate the checksum of the block just received, starting at the third byte
|
|
; of the data buffer and containing GROUPS * 7 bytes. Trashes TEMP, TEMP2, and
|
|
; FSR0.
|
|
CheckChecksum
|
|
movlw 0x20 ;Point FSR0 to the third byte of the data
|
|
movwf FSR0H ; buffer
|
|
movlw 0x4B ; "
|
|
movwf FSR0L ; "
|
|
movf GROUPS,W ;Copy the group count into TEMP
|
|
movwf TEMP ; "
|
|
clrf TEMP2 ;Zero the running sum (mod 256)
|
|
CheckC0 moviw FSR0++ ;Add the next seven bytes to the running sum
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
moviw FSR0++ ; "
|
|
addwf TEMP2,F ; "
|
|
decfsz TEMP,F ;Loop until we've summed the last group
|
|
bra CheckC0 ; "
|
|
movf TEMP2,F ;Set Z if block sum is 0 and checksum is good
|
|
return
|
|
|
|
;Clear the data buffer for the response to a command according to the expected
|
|
; response length according to mac, setting GROUPS to the number of groups to
|
|
; be sent. Trashes TEMP and FSR0.
|
|
ClearResponse
|
|
movlw 0x20 ;Point FSR0 at the top of the data buffer
|
|
movwf FSR0H ; "
|
|
movlw 0x48 ; "
|
|
movwf FSR0L ; "
|
|
movf RC_RSPG,W ;Snuff the top bit of the number of groups in
|
|
andlw B'01111111' ; the expected response and copy this into
|
|
movwf GROUPS ; the group count as well as a temporary
|
|
movwf TEMP ; counter
|
|
movlw 0 ;Zero is what we're setting the buffer to
|
|
ClearR0 movwi FSR0++ ;Write seven zeroes to the buffer
|
|
movwi FSR0++ ; "
|
|
movwi FSR0++ ; "
|
|
movwi FSR0++ ; "
|
|
movwi FSR0++ ; "
|
|
movwi FSR0++ ; "
|
|
movwi FSR0++ ; "
|
|
decfsz TEMP,F ;Loop until we've zeroed the last group
|
|
bra ClearR0 ; "
|
|
return
|
|
|
|
;Translate the address from a command into an address on the MMC card. Sets
|
|
; RNFERR if (considering the block count) the command would address memory that
|
|
; is beyond the boundary of the drive.
|
|
TranslateAddr
|
|
bcf FLAGS,RNFERR ;Assume no error to start with
|
|
movlw 0x20 ;Point FSR0 at the appropriate struct for the
|
|
movwf FSR0H ; selected device
|
|
clrf FSR0L ; "
|
|
btfsc FLAGS,DEVSEL1 ; "
|
|
addfsr FSR0,16 ; "
|
|
btfsc FLAGS,DEVSEL0 ; "
|
|
addfsr FSR0,8 ; "
|
|
decf RC_BLKS,W ;Add the block count (less one because it's
|
|
addwf RC_ADRL,F ; one-relative) to the block address so we can
|
|
movlw 0 ; do a full boundary check
|
|
addwfc RC_ADRM,F ; "
|
|
addwfc RC_ADRH,F ; "
|
|
moviw 3[FSR0] ;Compare the maximum block address that would
|
|
subwf RC_ADRL,W ; be accessed by this command to the LBA length
|
|
moviw 2[FSR0] ; of the partition; if the maximum block
|
|
subwfb RC_ADRM,W ; address is greater than or equal to the LBA
|
|
moviw 1[FSR0] ; length of the partition, this is an invalid
|
|
subwfb RC_ADRH,W ; access and must be rejected; set the record-
|
|
btfsc STATUS,C ; not-found flag
|
|
bsf FLAGS,RNFERR ; "
|
|
decf RC_BLKS,W ;Restore the block address as before
|
|
subwf RC_ADRL,F ; "
|
|
movlw 0 ; "
|
|
subwfb RC_ADRM,F ; "
|
|
subwfb RC_ADRH,F ; "
|
|
btfsc FLAGS,RNFERR ;If we had a record-not-found error, we're done
|
|
return ; "
|
|
moviw 7[FSR0] ;Add the block address to the start address for
|
|
addwf RC_ADRL,W ; the partition and store the result in the
|
|
movwf M_ADR0 ; MMC address registers
|
|
moviw 6[FSR0] ; "
|
|
addwfc RC_ADRM,W ; "
|
|
movwf M_ADR1 ; "
|
|
moviw 5[FSR0] ; "
|
|
addwfc RC_ADRH,W ; "
|
|
movwf M_ADR2 ; "
|
|
clrf M_ADR3 ; "
|
|
moviw 4[FSR0] ; "
|
|
addwfc M_ADR3,F ; "
|
|
return
|
|
|
|
|
|
;;; MMC Subprograms ;;;
|
|
|
|
;Initialize MMC card. Sets M_FAIL on fail. Trashes TEMP and TEMP2.
|
|
MmcInit
|
|
clrf M_FLAGS ;Make sure flags are all clear to begin with
|
|
movlb 4 ;This is where all the SSP registers are
|
|
movlw 10 ;Send 80 clocks on SPI interface to ensure MMC
|
|
movwf TEMP ; card is started up and in native command mode
|
|
MmcIni0 movlw 0xFF ; "
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
decfsz TEMP,F ; "
|
|
bra MmcIni0 ; "
|
|
movlb 0 ;Assert !CS
|
|
bcf PORTC,RC3 ; "
|
|
movlw 0x40 ;Send command 0 (expect R1-type response)
|
|
movwf M_CMDN ; which, with !CS asserted, signals to the card
|
|
clrf M_ADR3 ; that we want to enter SPI mode
|
|
clrf M_ADR2 ; "
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
btfsc M_FLAGS,M_FAIL ;If this command failed, unrecognized or
|
|
return ; missing MMC card, fail the init operation
|
|
movf M_CMDN,W ;If this command returned any response other
|
|
xorlw 0x01 ; than 0x01 ('in idle state'), unrecognized MMC
|
|
btfss STATUS,Z ; card, fail the init operation
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfss STATUS,Z ; "
|
|
return ; "
|
|
bsf M_FLAGS,M_CDVER ;Assume version 2.0+ to begin with
|
|
clrf TEMP ;Set retry counter to 0 (65536) for later use
|
|
clrf TEMP2 ; "
|
|
movlw 0x48 ;Send command 8 (expect R7-type response) to
|
|
movwf M_CMDN ; check if we're dealing with a V2.0+ card
|
|
clrf M_ADR3 ; "
|
|
clrf M_ADR2 ; "
|
|
movlw 0x01 ; "
|
|
movwf M_ADR1 ; "
|
|
movlw 0xAA ; "
|
|
movwf M_ADR0 ; "
|
|
bsf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If the command set any error flags or there
|
|
andlw B'11111110' ; was no response, switch assumptions and guess
|
|
btfsc STATUS,Z ; that we're dealing with a Version 1 card and
|
|
btfsc M_FLAGS,M_FAIL ; jump ahead to initialize it
|
|
bcf M_FLAGS,M_CDVER ; "
|
|
btfss M_FLAGS,M_CDVER ; "
|
|
bra MmcIni1 ; "
|
|
movf M_ADR1,W ;If the command didn't error, but the lower 12
|
|
andlw B'00001111' ; bits of the R7 response are something besides
|
|
xorlw 0x01 ; 0x1AA, we're dealing with an unknown card, so
|
|
btfss STATUS,Z ; raise the fail flag and return to caller
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
movf M_ADR0,W ; "
|
|
xorlw 0xAA ; "
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfsc M_FLAGS,M_FAIL ; "
|
|
return ; "
|
|
MmcIni1 movlw 0x77 ;Send command 55 (expect R1-type response),
|
|
movwf M_CMDN ; which is a prelude to an 'app' command
|
|
clrf M_ADR3 ; "
|
|
clrf M_ADR2 ; "
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If we got a status with any error bits set,
|
|
andlw B'11111110' ; treat as a command failure
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfsc M_FLAGS,M_FAIL ;If this command fails, this is an unknown card
|
|
return ; so return the failure to caller
|
|
movlw 0x69 ;Send app command 41 (expect R1-type response)
|
|
movwf M_CMDN ; to initialize the card, setting the HCS
|
|
clrf M_ADR3 ; (high-capacity support) bit if we're dealing
|
|
btfsc M_FLAGS,M_CDVER ; with a V2.0+ card to let the card know that
|
|
bsf M_ADR3,6 ; we support cards bigger than 4 GB (up to 2
|
|
clrf M_ADR2 ; TB)
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If we got a status with any error bits set,
|
|
andlw B'11111110' ; treat as a command failure
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfsc M_FLAGS,M_FAIL ;If this command fails, this is an unknown card
|
|
return ; so return the failure to caller
|
|
btfss M_CMDN,0 ;If it returned an 0x00 status, initialization
|
|
bra MmcIni2 ; is finished
|
|
DELAY 40 ;If it returned an 0x01 status, delay for 120
|
|
decfsz TEMP,F ; cycles (15 us), decrement the retry counter,
|
|
bra MmcIni1 ; and try again
|
|
decfsz TEMP2,F ; "
|
|
bra MmcIni1 ; "
|
|
bsf M_FLAGS,M_FAIL ;If we've gone 65536 attempts and the card is
|
|
return ; still not ready, report failure to caller
|
|
MmcIni2 movlw 0x7A ;Send command 58 (expect R3-type response) to
|
|
movwf M_CMDN ; read the operating condition register (OCR)
|
|
clrf M_ADR3 ; "
|
|
clrf M_ADR2 ; "
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bsf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If we got a status with any error bits set,
|
|
btfss STATUS,Z ; treat as a command failure
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfsc M_FLAGS,M_FAIL ;If this command fails, something is wrong, so
|
|
return ; return the failure to caller
|
|
bsf M_FLAGS,M_BKADR ;If the card capacity status (CCS) bit of the
|
|
btfsc M_ADR3,6 ; OCR is set, we're using block addressing, so
|
|
bra MmcIni4 ; skip ahead
|
|
MmcIni3 bcf M_FLAGS,M_BKADR ;We're dealing with byte, not block addressing
|
|
movlw 0x50 ;Send command 16 (expect R1-type response) to
|
|
movwf M_CMDN ; tell the card we want to deal in 512-byte
|
|
clrf M_ADR3 ; sectors
|
|
clrf M_ADR2 ; "
|
|
movlw 0x02 ; "
|
|
movwf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If this command returned any response other
|
|
btfss STATUS,Z ; than 0x00, something is wrong, fail the init
|
|
bsf M_FLAGS,M_FAIL ; operation
|
|
btfsc M_FLAGS,M_FAIL ;If this command failed, something is wrong,
|
|
return ; fail the init operation
|
|
MmcIni4 movlw 0x7B ;Send command 59 (expect R1-type response) to
|
|
movwf M_CMDN ; tell the card we want to make life hard on
|
|
clrf M_ADR3 ; ourselves and have our CRCs checked by the
|
|
clrf M_ADR2 ; card
|
|
clrf M_ADR1 ; "
|
|
movlw 0x01 ; "
|
|
movwf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bcf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
movf M_CMDN,W ;If this command returned any response other
|
|
btfss STATUS,Z ; than 0x00, something is wrong, fail the init
|
|
bsf M_FLAGS,M_FAIL ; operation
|
|
btfsc M_FLAGS,M_FAIL ;If this command failed, something is wrong,
|
|
return ; fail the init operation
|
|
bsf PORTC,RC3 ;Deassert !CS
|
|
movf M_FLAGS,W ;Set up the card info byte of the status block
|
|
andlw B'00000111' ; "
|
|
movwf CARDINF ; "
|
|
return ;Congratulations, card is initialized!
|
|
|
|
;Convert a block address to a byte address if byte addressing is in effect.
|
|
; Sets M_FAIL if the block address is above 0x7FFFFF (and thus can't fit as a
|
|
; byte address).
|
|
MmcConvAddr
|
|
bcf M_FLAGS,M_FAIL ;Assume no failure to start with
|
|
btfsc M_FLAGS,M_BKADR ;If block addressing is in effect, the address
|
|
return ; does not need to be converted
|
|
movf M_ADR3,F ;Make sure that the top 9 bits of the block
|
|
btfss STATUS,Z ; address are clear; if they are not, set the
|
|
bsf M_FLAGS,M_FAIL ; fail flag
|
|
btfsc M_ADR2,7 ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfsc M_FLAGS,M_FAIL ;If the fail flag is set, we're done
|
|
return ; "
|
|
lslf M_ADR0,F ;Multiply the block address by 2 and then by
|
|
rlf M_ADR1,F ; 256
|
|
rlf M_ADR2,W ; "
|
|
movwf M_ADR3 ; "
|
|
movf M_ADR1,W ; "
|
|
movwf M_ADR2 ; "
|
|
movf M_ADR0,W ; "
|
|
movwf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
return
|
|
|
|
;Increment the address by one block according to the block/byte addressing
|
|
; mode. No protection is provided against the address wrapping around.
|
|
MmcIncAddr
|
|
movlw 0x01 ;Add 1 to the address if we're in block mode,
|
|
btfss M_FLAGS,M_BKADR ; add 512 to the address if we're in byte mode,
|
|
movlw 0 ; in either case carrying the remainder through
|
|
addwf M_ADR0,F ; "
|
|
movlw 0 ; "
|
|
btfss M_FLAGS,M_BKADR ; "
|
|
movlw 0x02 ; "
|
|
addwfc M_ADR1,F ; "
|
|
movlw 0 ; "
|
|
addwfc M_ADR2,F ; "
|
|
addwfc M_ADR3,F ; "
|
|
return
|
|
|
|
;Read 512 bytes of data from MMC card into buffer pointed to by FSR0. Sets
|
|
; M_FAIL on fail. Trashes TEMP, TEMP2, and FSR0.
|
|
MmcReadData
|
|
bcf M_FLAGS,M_FAIL ;Assume no failure to start with
|
|
movlb 4 ;Switch to the bank with the SSP registers
|
|
clrf TEMP ;Try 65536 times to get the data token
|
|
clrf TEMP2 ; "
|
|
MmcRea1 movlw 0xFF ;Clock a byte out of the MMC card while keeping
|
|
movwf SSP1BUF ; MOSI high
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;If we've received the data token, skip ahead
|
|
xorlw 0xFE ; "
|
|
btfsc STATUS,Z ; "
|
|
bra MmcRea2 ; "
|
|
decfsz TEMP,F ;If not, decrement the retry count and try
|
|
bra MmcRea1 ; again
|
|
decfsz TEMP2,F ; "
|
|
bra MmcRea1 ; "
|
|
bsf M_FLAGS,M_FAIL ;If we didn't get the data token after 65536
|
|
movlb 0 ; tries, give up and fail the operation
|
|
return ; "
|
|
MmcRea2 clrf TEMP ;Read 256 pairs of bytes
|
|
clrf CRC16H ;Start CRC16 registers at zero
|
|
clrf CRC16L ; "
|
|
MmcRea3 movlw 0xFF ;Clock the next data byte out of the MMC card
|
|
movwf SSP1BUF ; while keeping MOSI high
|
|
movf TEMP,F ;If this is the first byte, we don't have a
|
|
btfsc STATUS,Z ; previous byte to CRC, so skip ahead
|
|
bra MmcRea4 ; "
|
|
moviw -1[FSR0] ;Update the CRC with the previous byte while
|
|
xorwf CRC16H,W ; the next one is being received
|
|
movwf CRC16H ; "
|
|
movlp high LutCrc16H ; "
|
|
callw ; "
|
|
xorwf CRC16L,W ; "
|
|
xorwf CRC16H,F ; "
|
|
xorwf CRC16H,W ; "
|
|
xorwf CRC16H,F ; "
|
|
movlp high LutCrc16L ; "
|
|
callw ; "
|
|
movwf CRC16L ; "
|
|
MmcRea4 btfss SSP1STAT,BF ;Wait until the next byte is received
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;Move the byte we clocked out to the buffer and
|
|
movwi FSR0++ ; increment the pointer
|
|
movlw 0xFF ;Clock the next data byte out of the MMC card
|
|
movwf SSP1BUF ; while keeping MOSI high
|
|
moviw -1[FSR0] ;Update the CRC with the previous byte while
|
|
xorwf CRC16H,W ; the next one is being received
|
|
movwf CRC16H ; "
|
|
movlp high LutCrc16H ; "
|
|
callw ; "
|
|
xorwf CRC16L,W ; "
|
|
xorwf CRC16H,F ; "
|
|
xorwf CRC16H,W ; "
|
|
xorwf CRC16H,F ; "
|
|
movlp high LutCrc16L ; "
|
|
callw ; "
|
|
movwf CRC16L ; "
|
|
btfss SSP1STAT,BF ;Wait until the next byte is received
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;Move the byte we clocked out to the buffer and
|
|
movwi FSR0++ ; increment the pointer
|
|
decfsz TEMP,F ;Decrement the counter and go back to read the
|
|
bra MmcRea3 ; next byte pair, unless we're done
|
|
movlw 0xFF ;Clock the high CRC byte out of the MMC card
|
|
movwf SSP1BUF ; while keeping MOSI high
|
|
moviw -1[FSR0] ;Update the CRC with the final data byte while
|
|
xorwf CRC16H,W ; the high CRC byte is being received
|
|
movwf CRC16H ; "
|
|
movlp high LutCrc16H ; "
|
|
callw ; "
|
|
xorwf CRC16L,W ; "
|
|
xorwf CRC16H,F ; "
|
|
xorwf CRC16H,W ; "
|
|
xorwf CRC16H,F ; "
|
|
movlp high LutCrc16L ; "
|
|
callw ; "
|
|
movwf CRC16L ; "
|
|
movlp 0 ;Restore PCLATH from all the CRC calculating
|
|
btfss SSP1STAT,BF ;Wait until the byte is received
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;If it doesn't match what we calculated, set
|
|
xorwf CRC16H,W ; the fail flag
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
movlw 0xFF ;Clock the low CRC byte out of the MMC card
|
|
movwf SSP1BUF ; while keeping MOSI high
|
|
btfss SSP1STAT,BF ;Wait until the byte is received
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;If it doesn't match what we calculated, set
|
|
xorwf CRC16L,W ; the fail flag
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
movlb 0 ;Return to the default bank
|
|
btfss M_FLAGS,M_FAIL ;If the CRC check didn't fail, return now
|
|
return ; "
|
|
call MmcStopOngoing ;If the CRC check did fail, stop any ongoing
|
|
bsf M_FLAGS,M_FAIL ; read (since the card doesn't know anything's
|
|
return ; wrong) and then return failure
|
|
|
|
;Write 512 bytes of data to MMC card from buffer pointed to by FSR0. Sets
|
|
; M_FAIL on fail. Trashes TEMP, TEMP2, and FSR0.
|
|
MmcWriteData
|
|
bcf M_FLAGS,M_FAIL ;Assume no failure to start with
|
|
movlb 4 ;Switch to the bank with the SSP registers
|
|
clrf CRC16H ;Start CRC16 registers at zero
|
|
clrf CRC16L ; "
|
|
movlw 0xFF ;Clock a dummy byte while keeping MOSI high
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movlw 0xFE ;Clock the data token into the MMC card (note
|
|
btfsc M_FLAGS,M_MBWR ; that CMD25, multi-block write, requires a
|
|
movlw 0xFC ; different token than CMD24, single-block
|
|
movwf SSP1BUF ; write, so we differentiate based on the flag
|
|
btfss SSP1STAT,BF ; for ongoing multi-block write)
|
|
bra $-1 ; "
|
|
clrf TEMP ;Send 256 pairs of bytes
|
|
MmcWri0 moviw FSR0++ ;Clock the next data byte into the MMC card
|
|
movwf SSP1BUF ; "
|
|
xorwf CRC16H,W ;Update the CRC while the byte is transmitting
|
|
movwf CRC16H ; "
|
|
movlp high LutCrc16H ; "
|
|
callw ; "
|
|
xorwf CRC16L,W ; "
|
|
xorwf CRC16H,F ; "
|
|
xorwf CRC16H,W ; "
|
|
xorwf CRC16H,F ; "
|
|
movlp high LutCrc16L ; "
|
|
callw ; "
|
|
movwf CRC16L ; "
|
|
btfss SSP1STAT,BF ;Wait until the byte is done transmitting
|
|
bra $-1 ; "
|
|
moviw FSR0++ ;Clock the next data byte into the MMC card
|
|
movwf SSP1BUF ; "
|
|
xorwf CRC16H,W ;Update the CRC while the byte is transmitting
|
|
movwf CRC16H ; "
|
|
movlp high LutCrc16H ; "
|
|
callw ; "
|
|
xorwf CRC16L,W ; "
|
|
xorwf CRC16H,F ; "
|
|
xorwf CRC16H,W ; "
|
|
xorwf CRC16H,F ; "
|
|
movlp high LutCrc16L ; "
|
|
callw ; "
|
|
movwf CRC16L ; "
|
|
btfss SSP1STAT,BF ;Wait until the byte is done transmitting
|
|
bra $-1 ; "
|
|
decfsz TEMP,F ;Decrement the counter and go back to write the
|
|
bra MmcWri0 ; next byte pair, unless we're done
|
|
movlp 0 ;Restore PCLATH from all the CRC calculating
|
|
movf CRC16H,W ;Clock the high CRC byte into the MMC card
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf CRC16L,W ;Clock the low CRC byte into the MMC card
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movlw 0xFF ;Clock data response byte out of the MMC card
|
|
movwf SSP1BUF ; while keeping MOSI high
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;If the status byte indicates that the write
|
|
andlw B'00011111' ; was rejected for any reason, fail the write
|
|
xorlw B'00000101' ; operation
|
|
btfss STATUS,Z ; "
|
|
bsf M_FLAGS,M_FAIL ; "
|
|
btfss M_FLAGS,M_FAIL ;If we didn't fail, wait for the card not to be
|
|
call MmcWaitBusy ; busy anymore
|
|
movlb 0 ;Return to the default bank
|
|
return
|
|
|
|
;Stop a multiblock read or write, if one is ongoing, and deassert !CS. Sets
|
|
; M_FAIL on fail. Trashes TEMP and TEMP2.
|
|
MmcStopOngoing
|
|
bcf M_FLAGS,M_FAIL ;Assume no failure to start with
|
|
btfsc M_FLAGS,M_MBWR ;If there's an ongoing write operation, make it
|
|
bra MmcSto0 ; stop
|
|
btfss M_FLAGS,M_MBRD ;If there's not an ongoing read operation, this
|
|
return ; function was called needlessly, return
|
|
movlw 0x4C ;Send a CMD12 to stop the ongoing read, R1b
|
|
movwf M_CMDN ; reply type
|
|
clrf M_ADR3 ; "
|
|
clrf M_ADR2 ; "
|
|
clrf M_ADR1 ; "
|
|
clrf M_ADR0 ; "
|
|
bcf M_FLAGS,M_CMDLR ; "
|
|
bsf M_FLAGS,M_CMDRB ; "
|
|
call MmcCmd ; "
|
|
bcf M_FLAGS,M_MBRD ;Clear the ongoing multiblock read flag
|
|
bsf PORTC,RC3 ;Deassert !CS
|
|
return
|
|
MmcSto0 movlb 4 ;Switch to the bank with the SSP registers
|
|
movlw 0xFD ;Clock the end-of-data token into the MMC card
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movlw 0xFF ;Clock a dummy byte while keeping MOSI high
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
call MmcWaitBusy ;Wait for the card to not be busy anymore
|
|
movlb 0 ;Return to the default bank
|
|
bcf M_FLAGS,M_MBWR ;Clear the ongoing multiblock write flag
|
|
bsf PORTC,RC3 ;Deassert !CS
|
|
return
|
|
|
|
;Send the command contained in M_BUF1-6 to MMC card. Sets M_FAIL on fail.
|
|
; Trashes TEMP.
|
|
MmcCmd
|
|
bcf M_FLAGS,M_FAIL ;Assume no failure to start with
|
|
clrf TEMP ;Start the CRC7 register out at 0
|
|
movlp high LutCrc7 ;Point PCLATH to the CRC7 lookup table
|
|
movlb 4 ;Switch to the bank with the SSP registers
|
|
movf M_CMDN,W ;Clock out all six MMC buffer bytes as command,
|
|
movwf SSP1BUF ; calculating the CRC7 along the way
|
|
xorwf TEMP,W ; "
|
|
callw ; "
|
|
movwf TEMP ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf M_ADR3,W ; "
|
|
movwf SSP1BUF ; "
|
|
xorwf TEMP,W ; "
|
|
callw ; "
|
|
movwf TEMP ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf M_ADR2,W ; "
|
|
movwf SSP1BUF ; "
|
|
xorwf TEMP,W ; "
|
|
callw ; "
|
|
movwf TEMP ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf M_ADR1,W ; "
|
|
movwf SSP1BUF ; "
|
|
xorwf TEMP,W ; "
|
|
callw ; "
|
|
movwf TEMP ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf M_ADR0,W ; "
|
|
movwf SSP1BUF ; "
|
|
xorwf TEMP,W ; "
|
|
callw ; "
|
|
movlp 0 ; "
|
|
movwf TEMP ; "
|
|
bsf TEMP,0 ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf TEMP,W ; "
|
|
movwf SSP1BUF ; "
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
;TODO for CMD12, it is necessary to clock and throw away a stuff byte?
|
|
movlw 8 ;Try to get status as many as eight times
|
|
movwf TEMP ; "
|
|
MmcCmd1 movlw 0xFF ;Clock a byte out of the MMC card while keeping
|
|
movwf SSP1BUF ; MOSI high
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
incf SSP1BUF,W ;If we read back anything but 0xFF, skip ahead
|
|
btfss STATUS,Z ; "
|
|
bra MmcCmd2 ; "
|
|
decfsz TEMP,F ;Decrement the attempt counter until we've
|
|
bra MmcCmd1 ; tried eight times; if we haven't gotten a
|
|
bsf M_FLAGS,M_FAIL ; reply by the eighth attempt, signal failure
|
|
movlb 0 ; and return
|
|
return ; "
|
|
MmcCmd2 decf WREG,W ;Store the byte we received as R1-type status
|
|
movwf M_CMDN ; in the buffer
|
|
btfss M_FLAGS,M_CMDLR ;If we aren't expecting a long (R3/R7-type)
|
|
bra MmcCmd3 ; reply, we're done
|
|
movlw 0xFF ;Clock first extended reply byte out of the
|
|
movwf SSP1BUF ; MMC card while keeping MOSI high and store it
|
|
btfss SSP1STAT,BF ; in the buffer
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ; "
|
|
movwf M_ADR3 ; "
|
|
movlw 0xFF ;Clock second extended reply byte out of the
|
|
movwf SSP1BUF ; MMC card while keeping MOSI high and store it
|
|
btfss SSP1STAT,BF ; in the buffer
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ; "
|
|
movwf M_ADR2 ; "
|
|
movlw 0xFF ;Clock third extended reply byte out of the
|
|
movwf SSP1BUF ; MMC card while keeping MOSI high and store it
|
|
btfss SSP1STAT,BF ; in the buffer
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ; "
|
|
movwf M_ADR1 ; "
|
|
movlw 0xFF ;Clock fourth extended reply byte out of the
|
|
movwf SSP1BUF ; MMC card while keeping MOSI high and store it
|
|
btfss SSP1STAT,BF ; in the buffer
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ; "
|
|
movwf M_ADR0 ; "
|
|
MmcCmd3 btfsc M_FLAGS,M_CMDRB ;If we're expecting an R1b reply, wait for the
|
|
call MmcWaitBusy ; card not to be busy anymore before returning
|
|
movlb 0 ;Restore BSR to 0
|
|
return
|
|
|
|
;Waits for the card not to be busy anymore. Sets M_FAIL on fail. Trashes TEMP
|
|
; and TEMP2. Expects BSR to be 4 and does not set or reset this.
|
|
MmcWaitBusy
|
|
clrf TEMP ;Check 65536 times to see if the card is busy
|
|
clrf TEMP2 ; "
|
|
MmcWai0 movlw 0xFF ;Clock a byte out of the MMC card while keeping
|
|
movwf SSP1BUF ; MOSI high
|
|
btfss SSP1STAT,BF ; "
|
|
bra $-1 ; "
|
|
movf SSP1BUF,W ;Check if MISO is still low, if it's not, the
|
|
btfss STATUS,Z ; card is no longer busy and we can return
|
|
return ; "
|
|
decfsz TEMP,F ;If it's not done, try again
|
|
bra MmcWai0 ; "
|
|
decfsz TEMP2,F ; "
|
|
bra MmcWai0 ; "
|
|
bsf M_FLAGS,M_FAIL ;If out of tries, fail the operation
|
|
return
|
|
|
|
|
|
;;; Idle Handler ;;;
|
|
|
|
org 0x7F2
|
|
|
|
NoDevices
|
|
btfsc PORTA,RA5 ;Spin until our !ENBL goes low
|
|
bra $-1 ; "
|
|
bcf PORTA,RA0 ;Assert !ENBL for next device in chain
|
|
btfss PORTA,RA5 ;Spin until our !ENBL goes high
|
|
bra $-1 ; "
|
|
bsf PORTA,RA0 ;Deassert !ENBL for next device in chain
|
|
bra NoDevices
|
|
|
|
SelectNext
|
|
movlw B'00110010' ;Tristate RD
|
|
tris 7 ; "
|
|
bcf PORTA,RA0 ;Assert !ENBL for next device in chain
|
|
btfss PORTA,RA5 ;Spin until our !ENBL goes high
|
|
bra $-1 ; "
|
|
bsf PORTA,RA0 ;Deassert !ENBL for next device in chain
|
|
|
|
WaitEnbl
|
|
movlw B'00110010' ;Tristate RD
|
|
tris 7 ; "
|
|
bsf PORTC,RC4 ;Latch a 1 on RD for when we drive it
|
|
bcf FLAGS,DEVSEL1 ;Select device 0 in the flag bits
|
|
bcf FLAGS,DEVSEL0 ; "
|
|
btfsc PORTA,RA5 ;Spin until !ENBL goes low
|
|
bra $-1 ; "
|
|
movlw B'00100010' ;Drive the RD pin, high at first
|
|
tris 7 ; "
|
|
|
|
Dev0Jump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dev0Ph0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev0Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dev0Ph1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev0Jump ; drive RD high because what else can we do
|
|
Dev0Ph2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev0Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dev0Ph3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev0Jump ; way to escape the idle loop
|
|
Dev0Ph4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev0Jump ; drive RD high to deassert !HSHK
|
|
Dev0Ph5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev0Jump ; "
|
|
Dev0Ph6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev0Jump ; high
|
|
Dev0Ph7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev0Jump ; high
|
|
Dev0Ph8 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0Ph9 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhA bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhB bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhC bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhD bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhE bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0PhF bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev1 ; "
|
|
Dev0NEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
EnterDev1
|
|
btfss DV1FLAG,DV_EXST ;If there is no device 1, select the next
|
|
goto SelectNext ; device and wait for !ENBL to be deasserted
|
|
bcf FLAGS,DEVSEL1 ;Select device 1 in the flag bits
|
|
bsf FLAGS,DEVSEL0 ; "
|
|
|
|
Dev1SelJump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dv1SPh0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev1Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dv1SPh1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev1Jump ; drive RD high because what else can we do
|
|
Dv1SPh2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev1Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dv1SPh3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev1Jump ; way to escape the idle loop
|
|
Dv1SPh4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev1Jump ; drive RD high to deassert !HSHK
|
|
Dv1SPh5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev1Jump ; "
|
|
Dv1SPh6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1Jump ; high
|
|
Dv1SPh7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1Jump ; high
|
|
Dv1SPh8 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev1SelJump ; off from, so drive RD high to deassert !HSHK
|
|
Dv1SPh9 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev1SelJump ; drive RD high because what else can we do
|
|
Dv1SPhA bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev1SelJump ; idling, so drive RD high to deassert !HSHK
|
|
Dv1SPhB call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev1SelJump ; way to escape the idle loop
|
|
Dv1SPhC bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev1SelJump ; drive RD high to deassert !HSHK
|
|
Dv1SPhD bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev1SelJump ; "
|
|
Dv1SPhE bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1SelJump ; high
|
|
Dv1SPhF bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1SelJump ; high
|
|
Dv1SNEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
Dev1Jump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dev1Ph0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev1Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dev1Ph1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev1Jump ; drive RD high because what else can we do
|
|
Dev1Ph2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev1Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dev1Ph3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev1Jump ; way to escape the idle loop
|
|
Dev1Ph4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev1Jump ; drive RD high to deassert !HSHK
|
|
Dev1Ph5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev1Jump ; "
|
|
Dev1Ph6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1Jump ; high
|
|
Dev1Ph7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev1Jump ; high
|
|
Dev1Ph8 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1Ph9 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhA bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhB bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhC bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhD bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhE bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1PhF bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev2 ; "
|
|
Dev1NEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
EnterDev2
|
|
btfss DV2FLAG,DV_EXST ;If there is no device 2, select the next
|
|
goto SelectNext ; device and wait for !ENBL to be deasserted
|
|
bsf FLAGS,DEVSEL1 ;Select device 2 in the flag bits
|
|
bcf FLAGS,DEVSEL0 ; "
|
|
|
|
Dev2SelJump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dv2SPh0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev2Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dv2SPh1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev2Jump ; drive RD high because what else can we do
|
|
Dv2SPh2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev2Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dv2SPh3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev2Jump ; way to escape the idle loop
|
|
Dv2SPh4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev2Jump ; drive RD high to deassert !HSHK
|
|
Dv2SPh5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev2Jump ; "
|
|
Dv2SPh6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2Jump ; high
|
|
Dv2SPh7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2Jump ; high
|
|
Dv2SPh8 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev2SelJump ; off from, so drive RD high to deassert !HSHK
|
|
Dv2SPh9 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev2SelJump ; drive RD high because what else can we do
|
|
Dv2SPhA bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev2SelJump ; idling, so drive RD high to deassert !HSHK
|
|
Dv2SPhB call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev2SelJump ; way to escape the idle loop
|
|
Dv2SPhC bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev2SelJump ; drive RD high to deassert !HSHK
|
|
Dv2SPhD bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev2SelJump ; "
|
|
Dv2SPhE bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2SelJump ; high
|
|
Dv2SPhF bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2SelJump ; high
|
|
Dv2SNEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
Dev2Jump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dev2Ph0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev2Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dev2Ph1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev2Jump ; drive RD high because what else can we do
|
|
Dev2Ph2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev2Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dev2Ph3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev2Jump ; way to escape the idle loop
|
|
Dev2Ph4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev2Jump ; drive RD high to deassert !HSHK
|
|
Dev2Ph5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev2Jump ; "
|
|
Dev2Ph6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2Jump ; high
|
|
Dev2Ph7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev2Jump ; high
|
|
Dev2Ph8 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2Ph9 bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhA bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhB bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhC bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhD bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhE bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2PhF bsf PORTC,RC4 ;Mac wants to talk to next device
|
|
bra EnterDev3 ; "
|
|
Dev2NEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
EnterDev3
|
|
btfss DV3FLAG,DV_EXST ;If there is no device 3, select the next
|
|
goto SelectNext ; device and wait for !ENBL to be deasserted
|
|
bsf FLAGS,DEVSEL1 ;Select device 3 in the flag bits
|
|
bsf FLAGS,DEVSEL0 ; "
|
|
|
|
Dev3SelJump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dv3SPh0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev3Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dv3SPh1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev3Jump ; drive RD high because what else can we do
|
|
Dv3SPh2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev3Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dv3SPh3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev3Jump ; way to escape the idle loop
|
|
Dv3SPh4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev3Jump ; drive RD high to deassert !HSHK
|
|
Dv3SPh5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev3Jump ; "
|
|
Dv3SPh6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3Jump ; high
|
|
Dv3SPh7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3Jump ; high
|
|
Dv3SPh8 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev3SelJump ; off from, so drive RD high to deassert !HSHK
|
|
Dv3SPh9 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev3SelJump ; drive RD high because what else can we do
|
|
Dv3SPhA bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev3SelJump ; idling, so drive RD high to deassert !HSHK
|
|
Dv3SPhB call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev3SelJump ; way to escape the idle loop
|
|
Dv3SPhC bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev3SelJump ; drive RD high to deassert !HSHK
|
|
Dv3SPhD bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev3SelJump ; "
|
|
Dv3SPhE bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3SelJump ; high
|
|
Dv3SPhF bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3SelJump ; high
|
|
Dv3SNEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
Dev3Jump
|
|
decf PORTA,W ;32 entries in the jump table, each has two
|
|
brw ; instructions; jump to the one matching state
|
|
Dev3Ph0 bsf PORTC,RC4 ;HOFF is asserted but there's nothing to hold
|
|
bra Dev3Jump ; off from, so drive RD high to deassert !HSHK
|
|
Dev3Ph1 bsf PORTC,RC4 ;Mac wants to exchange data for some reason, so
|
|
bra Dev3Jump ; drive RD high because what else can we do
|
|
Dev3Ph2 bsf PORTC,RC4 ;Mac wants us to idle, cool, we're already
|
|
bra Dev3Jump ; idling, so drive RD high to deassert !HSHK
|
|
Dev3Ph3 call GetCommand ;Mac wants to send a command, this is the only
|
|
bra Dev3Jump ; way to escape the idle loop
|
|
Dev3Ph4 bsf PORTC,RC4 ;Mac wants us to reset, this is sorta reset, so
|
|
bra Dev3Jump ; drive RD high to deassert !HSHK
|
|
Dev3Ph5 bcf PORTC,RC4 ;Mac wants us to drive RD low, so drive RD low
|
|
bra Dev3Jump ; "
|
|
Dev3Ph6 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3Jump ; high
|
|
Dev3Ph7 bsf PORTC,RC4 ;Mac wants us to drive RD high, so drive RD
|
|
bra Dev3Jump ; high
|
|
Dev3Ph8 bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3Ph9 bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhA bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhB bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhC bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhD bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhE bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3PhF bsf PORTC,RC4 ;Mac wants to talk to next device, we have none
|
|
goto SelectNext ; so select the next and await !ENBL deasserted
|
|
Dev3NEn goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
goto WaitEnbl ;!ENBL has been deasserted, so get off the bus
|
|
nop ; and wait for it to be asserted again
|
|
|
|
|
|
;;; Icon ;;;
|
|
|
|
org 0xF00
|
|
|
|
Icon
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x03
|
|
retlw 0xFE
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x0E
|
|
retlw 0x07
|
|
retlw 0xB0
|
|
retlw 0x00
|
|
retlw 0x18
|
|
retlw 0x00
|
|
retlw 0x70
|
|
retlw 0x00
|
|
retlw 0x33
|
|
retlw 0x40
|
|
retlw 0xF0
|
|
retlw 0x00
|
|
retlw 0x2E
|
|
retlw 0xDB
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x3C
|
|
retlw 0x9B
|
|
retlw 0xC0
|
|
retlw 0x00
|
|
retlw 0x1D
|
|
retlw 0x9B
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x09
|
|
retlw 0x9B
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x09
|
|
retlw 0x9B
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x08
|
|
retlw 0x9B
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x08
|
|
retlw 0xBB
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x0C
|
|
retlw 0x7B
|
|
retlw 0xB0
|
|
retlw 0x7F
|
|
retlw 0xFC
|
|
retlw 0x3A
|
|
retlw 0x7E
|
|
retlw 0x80
|
|
retlw 0x06
|
|
retlw 0x00
|
|
retlw 0xF1
|
|
retlw 0x80
|
|
retlw 0x07
|
|
retlw 0x83
|
|
retlw 0xE1
|
|
retlw 0x80
|
|
retlw 0x03
|
|
retlw 0xFF
|
|
retlw 0xC1
|
|
retlw 0x80
|
|
retlw 0x00
|
|
retlw 0xFF
|
|
retlw 0x01
|
|
retlw 0x80
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x01
|
|
retlw 0x8C
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x01
|
|
retlw 0x80
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x01
|
|
retlw 0x80
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x01
|
|
retlw 0x7F
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFE
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x03
|
|
retlw 0xFE
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0xF0
|
|
retlw 0x00
|
|
retlw 0x1F
|
|
retlw 0xFF
|
|
retlw 0xF0
|
|
retlw 0x00
|
|
retlw 0x3F
|
|
retlw 0xFF
|
|
retlw 0xF0
|
|
retlw 0x00
|
|
retlw 0x3F
|
|
retlw 0xFF
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x3F
|
|
retlw 0xFF
|
|
retlw 0xC0
|
|
retlw 0x00
|
|
retlw 0x1F
|
|
retlw 0xFF
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0x00
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0xE0
|
|
retlw 0x00
|
|
retlw 0x0F
|
|
retlw 0xFF
|
|
retlw 0xF0
|
|
retlw 0x7F
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFE
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0x7F
|
|
retlw 0xFF
|
|
retlw 0xFF
|
|
retlw 0xFE
|
|
|
|
|
|
;;; Transmitter Code ;;;
|
|
|
|
org 0x1000
|
|
|
|
;Transmits GROUPS 7-byte groups of non-encoded data from the data buffer. Sets
|
|
; ABORTED if a phase change caused the command to be aborted, in which case
|
|
; caller should return to idle state as soon as possible. Trashes FSR0, TEMP,
|
|
; TEMP2, and GROUPS.
|
|
Transmit
|
|
movlb 0 ;Point BSR to 0 so we can access PORTA/PORTC
|
|
movlw 0x20 ;Point FSR0 at the top of the data buffer
|
|
movwf FSR0H ; "
|
|
movlw 0x48 ; "
|
|
movwf FSR0L ; "
|
|
bcf FLAGS,ABORTED ;Clear aborted flag to start
|
|
decf PORTA,W ;Check the current state
|
|
xorlw B'00000100' ;If it's 2, then mac is ready for us to request
|
|
btfss STATUS,Z ; to send; if it's anything else, signal an
|
|
bra XAbort ; abort to get us to the idle jump table ASAP
|
|
bcf PORTC,RC4 ;Assert !HSHK to request to send
|
|
Transm0 decf PORTA,W ;Check the current state
|
|
xorlw B'00000100' ;If we're still in state 2, keep checking
|
|
btfsc STATUS,Z ; "
|
|
bra Transm0 ; "
|
|
xorlw B'00000010' ;If we're in state 3, most likely mac is about
|
|
btfsc STATUS,Z ; to change to state 1, so keep checking
|
|
bra Transm0 ; "
|
|
xorlw B'00000100' ;If we're in state 1, get ready to send; if any
|
|
btfss STATUS,Z ; other state, we can't handle it, so signal an
|
|
bra XAbort ; abort to get us to the idle jump table ASAP
|
|
;fall through
|
|
|
|
Transmitter
|
|
movlw 128 ;Set up fractional delay counter (see below)
|
|
movwf TEMP ; "
|
|
clrf TEMP2 ;Clear counter for sync byte loop
|
|
movlp high XFromBuffer;Select from-buffer as transmit loop
|
|
bsf PORTC,RC4 ;Raise RD and then delay long enough to make
|
|
DELAY 55 ; sure that IWM is awaiting an MSB
|
|
|
|
XSyncByteLoop
|
|
incf TEMP2,F ;-2 Increment the sync bit counter; if it's
|
|
btfsc TEMP2,0 ;-1 odd, falling edge on RD to send a 1 bit;
|
|
bcf PORTC,RC4 ; 0 this way we send 0xAA as a sync byte
|
|
movlw 87 ;+1 (*1) Reckon the delay to slow this from a
|
|
addwf TEMP,F ;+2 2 us data cell to a 96/47 us data cell as
|
|
btfsc STATUS,C ;+3 16 cycles plus 16/47 of a cycle, which is
|
|
bra $+1 ;+4 approximated here as 87/256 of a cycle,
|
|
bsf PORTC,RC4 ;+5 and raise RD for the next falling edge
|
|
decf PORTA,W ;+6 (*2) Check the current state; if it is 0
|
|
andlw B'00111100' ;+7 (holdoff) or 1 (communication), continue
|
|
btfss STATUS,Z ;-8 transmitting; else, abort and get us back
|
|
goto XAbort ;-7 to idle loop ASAP
|
|
movlw 0x40 ;-6 If we've more sync bits to send, loop for
|
|
btfss TEMP2,3 ;-5 the next, else set LSBs register for the
|
|
bra XSyncByteLoop ;-4(-3) group we're about to send and jump
|
|
movwf TEMP2 ;-3 into the appropriate send loop
|
|
clrf PCL ;-2 -1 "
|
|
|
|
XFinished
|
|
decf PORTA,W ;Check the current state
|
|
xorlw B'00000010' ;If it's still 1 (communication), mac hasn't
|
|
btfsc STATUS,Z ; realized we're done transmitting yet, so loop
|
|
bra XFinished ; "
|
|
xorlw B'00000100' ;If it's 3 (request send), mac is probably
|
|
btfsc STATUS,Z ; transitioning through on its way to 2, so
|
|
bra XFinished ; loop
|
|
xorlw B'00000010' ;If it's anything but 2 (idle), set the flag
|
|
btfss STATUS,Z ; for an aborted command to let the caller know
|
|
bsf FLAGS,ABORTED ; that something weird's going on
|
|
movlp 0 ;Reset PCLATH to where we're returning
|
|
return
|
|
|
|
XSuspend
|
|
decf GROUPS,F ;We finished a group, so decrement group count
|
|
XSuspe0 decf PORTA,W ;Check the current state
|
|
btfsc STATUS,Z ;If it's 0 (holdoff), mac is still asking us to
|
|
bra XSuspe0 ; hold off, so loop again
|
|
xorlw B'00000010' ;If it's anything else but 1 (communication),
|
|
btfss STATUS,Z ; either mac wants to abort the command or
|
|
bra XAbort ; something weird's going on, so abort
|
|
movf GROUPS,F ;If mac asked us to suspend during the last
|
|
btfsc STATUS,Z ; group, we resume by being finished and
|
|
bra XFinished ; waiting to go to state 2 (idle)
|
|
clrf TEMP2 ;Clear counter for sync byte loop
|
|
goto XSyncByteLoop ;Resume transmission after interrupted group
|
|
|
|
XAbort
|
|
bsf PORTC,RC4 ;Deassert !HSHK if it was asserted
|
|
bsf FLAGS,ABORTED ;Raise the aborted flag
|
|
movlp 0 ;Reset PCLATH to where we're returning
|
|
return
|
|
|
|
org 0x1100
|
|
|
|
XFromBuffer
|
|
bcf PORTC,RC4 ; 0 Start 7-to-8-encoded group; MSB always set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,7 ;-1 Falling edge on RD if bit 7 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,6 ;-1 Falling edge on RD if bit 6 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,5 ;-1 Falling edge on RD if bit 5 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,4 ;-1 Falling edge on RD if bit 4 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,3 ;-1 Falling edge on RD if bit 3 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,2 ;-1 Falling edge on RD if bit 2 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc INDF0,1 ;-1 Falling edge on RD if bit 1 of this byte is
|
|
bcf PORTC,RC4 ; 0 set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
btfsc INDF0,0 ;+6 Copy the LSB of this byte into the LSB
|
|
bsf TEMP2,7 ;+7 register
|
|
addfsr FSR0,1 ;-8 Increment pointer to transmit next byte
|
|
nop ;-7
|
|
nop ;-6
|
|
nop ;-5
|
|
lsrf TEMP2,F ;-4 Shift the LSB register right by one; if a
|
|
btfss STATUS,C ;-3 one falls out, it's time to send the
|
|
clrf PCL ;-2(-1) LSBs, otherwise loop again
|
|
nop ;-1
|
|
bcf PORTC,RC4 ; 0 Start of LSB IWM byte; MSB always set
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,6 ;-1 Falling edge on RD if the 7th byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,5 ;-1 Falling edge on RD if the 6th byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,4 ;-1 Falling edge on RD if the 5th byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,3 ;-1 Falling edge on RD if the 4th byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,2 ;-1 Falling edge on RD if the 3rd byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,1 ;-1 Falling edge on RD if the 2nd byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
decf PORTA,W ;+6 (*2)
|
|
andlw B'00111100' ;+7 "
|
|
btfss STATUS,Z ;-8 "
|
|
goto XAbort ;-7 "
|
|
decf PORTA,W ;-6 (*2)
|
|
andlw B'00111100' ;-5 "
|
|
btfss STATUS,Z ;-4 "
|
|
goto XAbort ;-3 "
|
|
nop ;-2
|
|
btfsc TEMP2,0 ;-1 Falling edge on RD if the 1st byte's LSB
|
|
bcf PORTC,RC4 ; 0 was high
|
|
movlw 87 ;+1 (*1)
|
|
addwf TEMP,F ;+2 "
|
|
btfsc STATUS,C ;+3 "
|
|
bra $+1 ;+4 "
|
|
bsf PORTC,RC4 ;+5 "
|
|
movlw 0x40 ;+6 Reset the LSBs register for the next
|
|
movwf TEMP2 ;+7 group, if there is one
|
|
decf PORTA,W ;-8 Check the current state
|
|
btfsc STATUS,Z ;-7 If it's 0 (holdoff), then effect a suspend
|
|
goto XSuspend ;-6 now that we're done transmitting a group
|
|
nop ;-5
|
|
nop ;-4
|
|
decfsz GROUPS,F ;-3 We finished a group, decrement group count;
|
|
clrf PCL ;-2(-1) if there are more, loop again,
|
|
goto XFinished ;-1 otherwise we're finished transmitting
|
|
|
|
|
|
;;; Receiver Code ;;;
|
|
|
|
org 0x1800
|
|
|
|
RecvAbort
|
|
bsf PORTC,RC4 ;Deassert !HSHK if it was asserted
|
|
bsf FLAGS,ABORTED ;Raise the aborted flag
|
|
movlp 0 ;Reset PCLATH to where we're returning
|
|
return
|
|
|
|
;Receives data from the mac. Sets ABORTED if a phase change caused the command
|
|
; to be aborted, in which case caller should return to idle state as soon as
|
|
; possible. Overwrites data buffer with received data in the following way:
|
|
; first byte is sync byte, second byte is 0x80 + number of groups in command
|
|
; according to mac, third byte is 0x80 + number of groups in anticipated
|
|
; response, followed by a string of GROUPS seven-byte decoded groups. Trashes
|
|
; FSR0, FSR1, TEMP, and TEMP2.
|
|
Receive
|
|
movlb 0 ;Point BSR to 0 so we can access PORTA/PORTC
|
|
bcf FLAGS,ABORTED ;Clear aborted flag to start
|
|
movlw 0x20 ;Point FSR0 at the top of the data buffer
|
|
movwf FSR0H ; "
|
|
movlw 0x48 ; "
|
|
movwf FSR0L ; "
|
|
clrf GROUPS ;Clear counter of total received groups
|
|
Receiv0 decf PORTA,W ;Check the current state
|
|
xorlw B'00000100' ;If it's 2, then mac hasn't said it's ready to
|
|
btfsc STATUS,Z ; send yet, keep waiting
|
|
bra Receiv0 ; "
|
|
xorlw B'00000010' ;If it's 3, mac has said it's ready to send,
|
|
btfss STATUS,Z ; if it's anything else, we can't handle it
|
|
bra RecvAbort ; here so return to the idle jump table
|
|
bcf PORTC,RC4 ;Assert !HSHK to say we're ready to receive
|
|
Receiv1 decf PORTA,W ;If we're still in state 3, keep checking
|
|
xorlw B'00000110' ; "
|
|
btfsc STATUS,Z ; "
|
|
bra Receiv1 ; "
|
|
xorlw B'00000100' ;If we're in state 1, get ready to receive; if
|
|
btfss STATUS,Z ; we're in any other state, we can't handle it
|
|
bra RecvAbort ; here so return to the idle jump table
|
|
movlb 7 ;Clear any IOC flags that have been set up to
|
|
clrf IOCAF ; now
|
|
;fall through
|
|
|
|
Receiver
|
|
movlp high Receiver ;Point PCLATH to this page so gotos work
|
|
movlb 0 ;Point BSR to 0 so we can access PORTC
|
|
bsf INTCON,GIE ;Enable interrupts so we have a way to exit
|
|
RcSt0 btfss PORTC,RC5 ;Signal starts at zero, wait until transition
|
|
bra $-1 ; to one, this is MSB (always 1) of first byte
|
|
movlw B'10000000' ;003 cycles, 0.18 bit times
|
|
movwf INDF0 ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_6 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_6 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_6 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_6 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_6 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_6 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_6 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_6 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_5 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_5 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_5 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_5 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_5 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_5 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_5 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_5 ;040 cycles, 2.45 bit times
|
|
btfss PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo0_4 ;042 cycles, 2.57 bit times
|
|
btfss PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo0_4 ;044 cycles, 2.69 bit times
|
|
btfss PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo0_4 ;046 cycles, 2.82 bit times
|
|
btfss PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo0_4 ;048 cycles, 2.94 bit times
|
|
btfss PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo0_4 ;050 cycles, 3.06 bit times
|
|
btfss PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo0_4 ;052 cycles, 3.18 bit times
|
|
btfss PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo0_4 ;054 cycles, 3.30 bit times
|
|
btfss PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo0_4 ;056 cycles, 3.43 bit times
|
|
btfss PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo0_4 ;058 cycles, 3.55 bit times
|
|
btfss PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo0_3 ;060 cycles, 3.67 bit times
|
|
btfss PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo0_3 ;062 cycles, 3.79 bit times
|
|
btfss PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo0_3 ;064 cycles, 3.92 bit times
|
|
btfss PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo0_3 ;066 cycles, 4.04 bit times
|
|
btfss PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo0_3 ;068 cycles, 4.16 bit times
|
|
btfss PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo0_3 ;070 cycles, 4.28 bit times
|
|
btfss PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo0_3 ;072 cycles, 4.41 bit times
|
|
btfss PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo0_3 ;074 cycles, 4.53 bit times
|
|
btfss PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo0_2 ;076 cycles, 4.65 bit times
|
|
btfss PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo0_2 ;078 cycles, 4.77 bit times
|
|
btfss PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo0_2 ;080 cycles, 4.90 bit times
|
|
btfss PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo0_2 ;082 cycles, 5.02 bit times
|
|
btfss PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo0_2 ;084 cycles, 5.14 bit times
|
|
btfss PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo0_2 ;086 cycles, 5.26 bit times
|
|
btfss PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo0_2 ;088 cycles, 5.39 bit times
|
|
btfss PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo0_2 ;090 cycles, 5.51 bit times
|
|
btfss PORTC,RC5 ;091 cycles, 5.57 bit times
|
|
goto RcTo0_1 ;092 cycles, 5.63 bit times
|
|
btfss PORTC,RC5 ;093 cycles, 5.69 bit times
|
|
goto RcTo0_1 ;094 cycles, 5.75 bit times
|
|
btfss PORTC,RC5 ;095 cycles, 5.81 bit times
|
|
goto RcTo0_1 ;096 cycles, 5.88 bit times
|
|
btfss PORTC,RC5 ;097 cycles, 5.94 bit times
|
|
goto RcTo0_1 ;098 cycles, 6.00 bit times
|
|
btfss PORTC,RC5 ;099 cycles, 6.06 bit times
|
|
goto RcTo0_1 ;100 cycles, 6.12 bit times
|
|
btfss PORTC,RC5 ;101 cycles, 6.18 bit times
|
|
goto RcTo0_1 ;102 cycles, 6.24 bit times
|
|
btfss PORTC,RC5 ;103 cycles, 6.30 bit times
|
|
goto RcTo0_1 ;104 cycles, 6.36 bit times
|
|
btfss PORTC,RC5 ;105 cycles, 6.43 bit times
|
|
goto RcTo0_1 ;106 cycles, 6.49 bit times
|
|
btfss PORTC,RC5 ;107 cycles, 6.55 bit times
|
|
goto RcTo0_0 ;108 cycles, 6.61 bit times
|
|
btfss PORTC,RC5 ;109 cycles, 6.67 bit times
|
|
goto RcTo0_0 ;110 cycles, 6.73 bit times
|
|
btfss PORTC,RC5 ;111 cycles, 6.79 bit times
|
|
goto RcTo0_0 ;112 cycles, 6.85 bit times
|
|
btfss PORTC,RC5 ;113 cycles, 6.92 bit times
|
|
goto RcTo0_0 ;114 cycles, 6.98 bit times
|
|
btfss PORTC,RC5 ;115 cycles, 7.04 bit times
|
|
goto RcTo0_0 ;116 cycles, 7.10 bit times
|
|
btfss PORTC,RC5 ;117 cycles, 7.16 bit times
|
|
goto RcTo0_0 ;118 cycles, 7.22 bit times
|
|
btfss PORTC,RC5 ;119 cycles, 7.28 bit times
|
|
goto RcTo0_0 ;120 cycles, 7.34 bit times
|
|
btfss PORTC,RC5 ;121 cycles, 7.40 bit times
|
|
goto RcTo0_0 ;122 cycles, 7.47 bit times
|
|
btfss PORTA,RA1 ;123 cycles, 7.53 bit times
|
|
bcf INDF0,7 ;124 cycles, 7.59 bit times
|
|
addfsr FSR0,1 ;125 cycles, 7.65 bit times
|
|
goto RcSt1 ;126 cycles, 7.71 bit times
|
|
|
|
RcTo1_6 movlw B'01000000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_5 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_5 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_5 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_5 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_5 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_5 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_5 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_5 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_4 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_4 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_4 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_4 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_4 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_4 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_4 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_4 ;040 cycles, 2.45 bit times
|
|
btfss PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo0_3 ;042 cycles, 2.57 bit times
|
|
btfss PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo0_3 ;044 cycles, 2.69 bit times
|
|
btfss PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo0_3 ;046 cycles, 2.82 bit times
|
|
btfss PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo0_3 ;048 cycles, 2.94 bit times
|
|
btfss PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo0_3 ;050 cycles, 3.06 bit times
|
|
btfss PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo0_3 ;052 cycles, 3.18 bit times
|
|
btfss PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo0_3 ;054 cycles, 3.30 bit times
|
|
btfss PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo0_3 ;056 cycles, 3.43 bit times
|
|
btfss PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo0_3 ;058 cycles, 3.55 bit times
|
|
btfss PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo0_2 ;060 cycles, 3.67 bit times
|
|
btfss PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo0_2 ;062 cycles, 3.79 bit times
|
|
btfss PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo0_2 ;064 cycles, 3.92 bit times
|
|
btfss PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo0_2 ;066 cycles, 4.04 bit times
|
|
btfss PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo0_2 ;068 cycles, 4.16 bit times
|
|
btfss PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo0_2 ;070 cycles, 4.28 bit times
|
|
btfss PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo0_2 ;072 cycles, 4.41 bit times
|
|
btfss PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo0_2 ;074 cycles, 4.53 bit times
|
|
btfss PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo0_1 ;076 cycles, 4.65 bit times
|
|
btfss PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo0_1 ;078 cycles, 4.77 bit times
|
|
btfss PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo0_1 ;080 cycles, 4.90 bit times
|
|
btfss PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo0_1 ;082 cycles, 5.02 bit times
|
|
btfss PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo0_1 ;084 cycles, 5.14 bit times
|
|
btfss PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo0_1 ;086 cycles, 5.26 bit times
|
|
btfss PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo0_1 ;088 cycles, 5.39 bit times
|
|
btfss PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo0_1 ;090 cycles, 5.51 bit times
|
|
btfss PORTC,RC5 ;091 cycles, 5.57 bit times
|
|
goto RcTo0_0 ;092 cycles, 5.63 bit times
|
|
btfss PORTC,RC5 ;093 cycles, 5.69 bit times
|
|
goto RcTo0_0 ;094 cycles, 5.75 bit times
|
|
btfss PORTC,RC5 ;095 cycles, 5.81 bit times
|
|
goto RcTo0_0 ;096 cycles, 5.88 bit times
|
|
btfss PORTC,RC5 ;097 cycles, 5.94 bit times
|
|
goto RcTo0_0 ;098 cycles, 6.00 bit times
|
|
btfss PORTC,RC5 ;099 cycles, 6.06 bit times
|
|
goto RcTo0_0 ;100 cycles, 6.12 bit times
|
|
btfss PORTC,RC5 ;101 cycles, 6.18 bit times
|
|
goto RcTo0_0 ;102 cycles, 6.24 bit times
|
|
btfss PORTC,RC5 ;103 cycles, 6.30 bit times
|
|
goto RcTo0_0 ;104 cycles, 6.36 bit times
|
|
btfss PORTC,RC5 ;105 cycles, 6.43 bit times
|
|
goto RcTo0_0 ;106 cycles, 6.49 bit times
|
|
btfss PORTA,RA1 ;107 cycles, 6.55 bit times
|
|
bcf INDF0,7 ;108 cycles, 6.61 bit times
|
|
addfsr FSR0,1 ;109 cycles, 6.67 bit times
|
|
goto RcSt1 ;110 cycles, 6.73 bit times
|
|
|
|
RcTo1_5 movlw B'00100000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_4 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_4 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_4 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_4 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_4 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_4 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_4 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_4 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_3 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_3 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_3 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_3 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_3 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_3 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_3 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_3 ;040 cycles, 2.45 bit times
|
|
btfss PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo0_2 ;042 cycles, 2.57 bit times
|
|
btfss PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo0_2 ;044 cycles, 2.69 bit times
|
|
btfss PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo0_2 ;046 cycles, 2.82 bit times
|
|
btfss PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo0_2 ;048 cycles, 2.94 bit times
|
|
btfss PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo0_2 ;050 cycles, 3.06 bit times
|
|
btfss PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo0_2 ;052 cycles, 3.18 bit times
|
|
btfss PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo0_2 ;054 cycles, 3.30 bit times
|
|
btfss PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo0_2 ;056 cycles, 3.43 bit times
|
|
btfss PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo0_2 ;058 cycles, 3.55 bit times
|
|
btfss PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo0_1 ;060 cycles, 3.67 bit times
|
|
btfss PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo0_1 ;062 cycles, 3.79 bit times
|
|
btfss PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo0_1 ;064 cycles, 3.92 bit times
|
|
btfss PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo0_1 ;066 cycles, 4.04 bit times
|
|
btfss PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo0_1 ;068 cycles, 4.16 bit times
|
|
btfss PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo0_1 ;070 cycles, 4.28 bit times
|
|
btfss PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo0_1 ;072 cycles, 4.41 bit times
|
|
btfss PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo0_1 ;074 cycles, 4.53 bit times
|
|
btfss PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo0_0 ;076 cycles, 4.65 bit times
|
|
btfss PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo0_0 ;078 cycles, 4.77 bit times
|
|
btfss PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo0_0 ;080 cycles, 4.90 bit times
|
|
btfss PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo0_0 ;082 cycles, 5.02 bit times
|
|
btfss PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo0_0 ;084 cycles, 5.14 bit times
|
|
btfss PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo0_0 ;086 cycles, 5.26 bit times
|
|
btfss PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo0_0 ;088 cycles, 5.39 bit times
|
|
btfss PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo0_0 ;090 cycles, 5.51 bit times
|
|
btfss PORTA,RA1 ;091 cycles, 5.57 bit times
|
|
bcf INDF0,7 ;092 cycles, 5.63 bit times
|
|
addfsr FSR0,1 ;093 cycles, 5.69 bit times
|
|
goto RcSt1 ;094 cycles, 5.75 bit times
|
|
|
|
RcTo1_4 movlw B'00010000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_3 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_3 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_3 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_3 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_3 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_3 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_3 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_3 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_2 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_2 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_2 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_2 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_2 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_2 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_2 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_2 ;040 cycles, 2.45 bit times
|
|
btfss PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo0_1 ;042 cycles, 2.57 bit times
|
|
btfss PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo0_1 ;044 cycles, 2.69 bit times
|
|
btfss PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo0_1 ;046 cycles, 2.82 bit times
|
|
btfss PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo0_1 ;048 cycles, 2.94 bit times
|
|
btfss PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo0_1 ;050 cycles, 3.06 bit times
|
|
btfss PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo0_1 ;052 cycles, 3.18 bit times
|
|
btfss PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo0_1 ;054 cycles, 3.30 bit times
|
|
btfss PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo0_1 ;056 cycles, 3.43 bit times
|
|
btfss PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo0_1 ;058 cycles, 3.55 bit times
|
|
btfss PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo0_0 ;060 cycles, 3.67 bit times
|
|
btfss PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo0_0 ;062 cycles, 3.79 bit times
|
|
btfss PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo0_0 ;064 cycles, 3.92 bit times
|
|
btfss PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo0_0 ;066 cycles, 4.04 bit times
|
|
btfss PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo0_0 ;068 cycles, 4.16 bit times
|
|
btfss PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo0_0 ;070 cycles, 4.28 bit times
|
|
btfss PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo0_0 ;072 cycles, 4.41 bit times
|
|
btfss PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo0_0 ;074 cycles, 4.53 bit times
|
|
btfss PORTA,RA1 ;075 cycles, 4.59 bit times
|
|
bcf INDF0,7 ;076 cycles, 4.65 bit times
|
|
addfsr FSR0,1 ;077 cycles, 4.71 bit times
|
|
goto RcSt1 ;078 cycles, 4.77 bit times
|
|
|
|
RcTo1_3 movlw B'00001000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_2 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_2 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_2 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_2 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_2 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_2 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_2 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_2 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_1 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_1 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_1 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_1 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_1 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_1 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_1 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_1 ;040 cycles, 2.45 bit times
|
|
btfss PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo0_0 ;042 cycles, 2.57 bit times
|
|
btfss PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo0_0 ;044 cycles, 2.69 bit times
|
|
btfss PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo0_0 ;046 cycles, 2.82 bit times
|
|
btfss PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo0_0 ;048 cycles, 2.94 bit times
|
|
btfss PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo0_0 ;050 cycles, 3.06 bit times
|
|
btfss PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo0_0 ;052 cycles, 3.18 bit times
|
|
btfss PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo0_0 ;054 cycles, 3.30 bit times
|
|
btfss PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo0_0 ;056 cycles, 3.43 bit times
|
|
btfss PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo0_0 ;058 cycles, 3.55 bit times
|
|
btfss PORTA,RA1 ;059 cycles, 3.61 bit times
|
|
bcf INDF0,7 ;060 cycles, 3.67 bit times
|
|
addfsr FSR0,1 ;061 cycles, 3.73 bit times
|
|
goto RcSt1 ;062 cycles, 3.79 bit times
|
|
|
|
RcTo1_2 movlw B'00000100' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_1 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_1 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_1 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_1 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_1 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_1 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_1 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_1 ;024 cycles, 1.47 bit times
|
|
btfss PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo0_0 ;026 cycles, 1.59 bit times
|
|
btfss PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo0_0 ;028 cycles, 1.71 bit times
|
|
btfss PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo0_0 ;030 cycles, 1.84 bit times
|
|
btfss PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo0_0 ;032 cycles, 1.96 bit times
|
|
btfss PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo0_0 ;034 cycles, 2.08 bit times
|
|
btfss PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo0_0 ;036 cycles, 2.20 bit times
|
|
btfss PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo0_0 ;038 cycles, 2.33 bit times
|
|
btfss PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo0_0 ;040 cycles, 2.45 bit times
|
|
btfss PORTA,RA1 ;041 cycles, 2.51 bit times
|
|
bcf INDF0,7 ;042 cycles, 2.57 bit times
|
|
addfsr FSR0,1 ;043 cycles, 2.63 bit times
|
|
goto RcSt1 ;044 cycles, 2.69 bit times
|
|
|
|
RcTo1_1 movlw B'00000010' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfss PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo0_0 ;010 cycles, 0.61 bit times
|
|
btfss PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo0_0 ;012 cycles, 0.73 bit times
|
|
btfss PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo0_0 ;014 cycles, 0.86 bit times
|
|
btfss PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo0_0 ;016 cycles, 0.98 bit times
|
|
btfss PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo0_0 ;018 cycles, 1.10 bit times
|
|
btfss PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo0_0 ;020 cycles, 1.22 bit times
|
|
btfss PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo0_0 ;022 cycles, 1.35 bit times
|
|
btfss PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo0_0 ;024 cycles, 1.47 bit times
|
|
btfss PORTA,RA1 ;025 cycles, 1.53 bit times
|
|
bcf INDF0,7 ;026 cycles, 1.59 bit times
|
|
addfsr FSR0,1 ;027 cycles, 1.65 bit times
|
|
goto RcSt1 ;028 cycles, 1.71 bit times
|
|
|
|
RcTo1_0 movlw B'00000001' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
addfsr FSR0,1 ;007 cycles, 0.43 bit times
|
|
;fall through
|
|
|
|
RcSt1 btfsc PORTC,RC5 ;Signal starts at one, wait until transition
|
|
bra $-1 ; to zero, this is MSB (always 1) of first byte
|
|
movlw B'10000000' ;003 cycles, 0.18 bit times
|
|
movwf INDF0 ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_6 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_6 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_6 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_6 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_6 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_6 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_6 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_6 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_5 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_5 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_5 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_5 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_5 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_5 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_5 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_5 ;040 cycles, 2.45 bit times
|
|
btfsc PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo1_4 ;042 cycles, 2.57 bit times
|
|
btfsc PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo1_4 ;044 cycles, 2.69 bit times
|
|
btfsc PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo1_4 ;046 cycles, 2.82 bit times
|
|
btfsc PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo1_4 ;048 cycles, 2.94 bit times
|
|
btfsc PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo1_4 ;050 cycles, 3.06 bit times
|
|
btfsc PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo1_4 ;052 cycles, 3.18 bit times
|
|
btfsc PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo1_4 ;054 cycles, 3.30 bit times
|
|
btfsc PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo1_4 ;056 cycles, 3.43 bit times
|
|
btfsc PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo1_4 ;058 cycles, 3.55 bit times
|
|
btfsc PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo1_3 ;060 cycles, 3.67 bit times
|
|
btfsc PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo1_3 ;062 cycles, 3.79 bit times
|
|
btfsc PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo1_3 ;064 cycles, 3.92 bit times
|
|
btfsc PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo1_3 ;066 cycles, 4.04 bit times
|
|
btfsc PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo1_3 ;068 cycles, 4.16 bit times
|
|
btfsc PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo1_3 ;070 cycles, 4.28 bit times
|
|
btfsc PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo1_3 ;072 cycles, 4.41 bit times
|
|
btfsc PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo1_3 ;074 cycles, 4.53 bit times
|
|
btfsc PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo1_2 ;076 cycles, 4.65 bit times
|
|
btfsc PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo1_2 ;078 cycles, 4.77 bit times
|
|
btfsc PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo1_2 ;080 cycles, 4.90 bit times
|
|
btfsc PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo1_2 ;082 cycles, 5.02 bit times
|
|
btfsc PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo1_2 ;084 cycles, 5.14 bit times
|
|
btfsc PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo1_2 ;086 cycles, 5.26 bit times
|
|
btfsc PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo1_2 ;088 cycles, 5.39 bit times
|
|
btfsc PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo1_2 ;090 cycles, 5.51 bit times
|
|
btfsc PORTC,RC5 ;091 cycles, 5.57 bit times
|
|
goto RcTo1_1 ;092 cycles, 5.63 bit times
|
|
btfsc PORTC,RC5 ;093 cycles, 5.69 bit times
|
|
goto RcTo1_1 ;094 cycles, 5.75 bit times
|
|
btfsc PORTC,RC5 ;095 cycles, 5.81 bit times
|
|
goto RcTo1_1 ;096 cycles, 5.88 bit times
|
|
btfsc PORTC,RC5 ;097 cycles, 5.94 bit times
|
|
goto RcTo1_1 ;098 cycles, 6.00 bit times
|
|
btfsc PORTC,RC5 ;099 cycles, 6.06 bit times
|
|
goto RcTo1_1 ;100 cycles, 6.12 bit times
|
|
btfsc PORTC,RC5 ;101 cycles, 6.18 bit times
|
|
goto RcTo1_1 ;102 cycles, 6.24 bit times
|
|
btfsc PORTC,RC5 ;103 cycles, 6.30 bit times
|
|
goto RcTo1_1 ;104 cycles, 6.36 bit times
|
|
btfsc PORTC,RC5 ;105 cycles, 6.43 bit times
|
|
goto RcTo1_1 ;106 cycles, 6.49 bit times
|
|
btfsc PORTC,RC5 ;107 cycles, 6.55 bit times
|
|
goto RcTo1_0 ;108 cycles, 6.61 bit times
|
|
btfsc PORTC,RC5 ;109 cycles, 6.67 bit times
|
|
goto RcTo1_0 ;110 cycles, 6.73 bit times
|
|
btfsc PORTC,RC5 ;111 cycles, 6.79 bit times
|
|
goto RcTo1_0 ;112 cycles, 6.85 bit times
|
|
btfsc PORTC,RC5 ;113 cycles, 6.92 bit times
|
|
goto RcTo1_0 ;114 cycles, 6.98 bit times
|
|
btfsc PORTC,RC5 ;115 cycles, 7.04 bit times
|
|
goto RcTo1_0 ;116 cycles, 7.10 bit times
|
|
btfsc PORTC,RC5 ;117 cycles, 7.16 bit times
|
|
goto RcTo1_0 ;118 cycles, 7.22 bit times
|
|
btfsc PORTC,RC5 ;119 cycles, 7.28 bit times
|
|
goto RcTo1_0 ;120 cycles, 7.34 bit times
|
|
btfsc PORTC,RC5 ;121 cycles, 7.40 bit times
|
|
goto RcTo1_0 ;122 cycles, 7.47 bit times
|
|
btfss PORTA,RA1 ;123 cycles, 7.53 bit times
|
|
bcf INDF0,7 ;124 cycles, 7.59 bit times
|
|
addfsr FSR0,1 ;125 cycles, 7.65 bit times
|
|
goto RcSt0 ;126 cycles, 7.71 bit times
|
|
|
|
RcTo0_6 movlw B'01000000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_5 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_5 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_5 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_5 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_5 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_5 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_5 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_5 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_4 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_4 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_4 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_4 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_4 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_4 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_4 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_4 ;040 cycles, 2.45 bit times
|
|
btfsc PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo1_3 ;042 cycles, 2.57 bit times
|
|
btfsc PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo1_3 ;044 cycles, 2.69 bit times
|
|
btfsc PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo1_3 ;046 cycles, 2.82 bit times
|
|
btfsc PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo1_3 ;048 cycles, 2.94 bit times
|
|
btfsc PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo1_3 ;050 cycles, 3.06 bit times
|
|
btfsc PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo1_3 ;052 cycles, 3.18 bit times
|
|
btfsc PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo1_3 ;054 cycles, 3.30 bit times
|
|
btfsc PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo1_3 ;056 cycles, 3.43 bit times
|
|
btfsc PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo1_3 ;058 cycles, 3.55 bit times
|
|
btfsc PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo1_2 ;060 cycles, 3.67 bit times
|
|
btfsc PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo1_2 ;062 cycles, 3.79 bit times
|
|
btfsc PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo1_2 ;064 cycles, 3.92 bit times
|
|
btfsc PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo1_2 ;066 cycles, 4.04 bit times
|
|
btfsc PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo1_2 ;068 cycles, 4.16 bit times
|
|
btfsc PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo1_2 ;070 cycles, 4.28 bit times
|
|
btfsc PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo1_2 ;072 cycles, 4.41 bit times
|
|
btfsc PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo1_2 ;074 cycles, 4.53 bit times
|
|
btfsc PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo1_1 ;076 cycles, 4.65 bit times
|
|
btfsc PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo1_1 ;078 cycles, 4.77 bit times
|
|
btfsc PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo1_1 ;080 cycles, 4.90 bit times
|
|
btfsc PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo1_1 ;082 cycles, 5.02 bit times
|
|
btfsc PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo1_1 ;084 cycles, 5.14 bit times
|
|
btfsc PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo1_1 ;086 cycles, 5.26 bit times
|
|
btfsc PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo1_1 ;088 cycles, 5.39 bit times
|
|
btfsc PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo1_1 ;090 cycles, 5.51 bit times
|
|
btfsc PORTC,RC5 ;091 cycles, 5.57 bit times
|
|
goto RcTo1_0 ;092 cycles, 5.63 bit times
|
|
btfsc PORTC,RC5 ;093 cycles, 5.69 bit times
|
|
goto RcTo1_0 ;094 cycles, 5.75 bit times
|
|
btfsc PORTC,RC5 ;095 cycles, 5.81 bit times
|
|
goto RcTo1_0 ;096 cycles, 5.88 bit times
|
|
btfsc PORTC,RC5 ;097 cycles, 5.94 bit times
|
|
goto RcTo1_0 ;098 cycles, 6.00 bit times
|
|
btfsc PORTC,RC5 ;099 cycles, 6.06 bit times
|
|
goto RcTo1_0 ;100 cycles, 6.12 bit times
|
|
btfsc PORTC,RC5 ;101 cycles, 6.18 bit times
|
|
goto RcTo1_0 ;102 cycles, 6.24 bit times
|
|
btfsc PORTC,RC5 ;103 cycles, 6.30 bit times
|
|
goto RcTo1_0 ;104 cycles, 6.36 bit times
|
|
btfsc PORTC,RC5 ;105 cycles, 6.43 bit times
|
|
goto RcTo1_0 ;106 cycles, 6.49 bit times
|
|
btfss PORTA,RA1 ;107 cycles, 6.55 bit times
|
|
bcf INDF0,7 ;108 cycles, 6.61 bit times
|
|
addfsr FSR0,1 ;109 cycles, 6.67 bit times
|
|
goto RcSt0 ;110 cycles, 6.73 bit times
|
|
|
|
RcTo0_5 movlw B'00100000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_4 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_4 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_4 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_4 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_4 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_4 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_4 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_4 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_3 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_3 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_3 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_3 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_3 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_3 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_3 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_3 ;040 cycles, 2.45 bit times
|
|
btfsc PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo1_2 ;042 cycles, 2.57 bit times
|
|
btfsc PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo1_2 ;044 cycles, 2.69 bit times
|
|
btfsc PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo1_2 ;046 cycles, 2.82 bit times
|
|
btfsc PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo1_2 ;048 cycles, 2.94 bit times
|
|
btfsc PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo1_2 ;050 cycles, 3.06 bit times
|
|
btfsc PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo1_2 ;052 cycles, 3.18 bit times
|
|
btfsc PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo1_2 ;054 cycles, 3.30 bit times
|
|
btfsc PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo1_2 ;056 cycles, 3.43 bit times
|
|
btfsc PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo1_2 ;058 cycles, 3.55 bit times
|
|
btfsc PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo1_1 ;060 cycles, 3.67 bit times
|
|
btfsc PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo1_1 ;062 cycles, 3.79 bit times
|
|
btfsc PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo1_1 ;064 cycles, 3.92 bit times
|
|
btfsc PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo1_1 ;066 cycles, 4.04 bit times
|
|
btfsc PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo1_1 ;068 cycles, 4.16 bit times
|
|
btfsc PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo1_1 ;070 cycles, 4.28 bit times
|
|
btfsc PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo1_1 ;072 cycles, 4.41 bit times
|
|
btfsc PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo1_1 ;074 cycles, 4.53 bit times
|
|
btfsc PORTC,RC5 ;075 cycles, 4.59 bit times
|
|
goto RcTo1_0 ;076 cycles, 4.65 bit times
|
|
btfsc PORTC,RC5 ;077 cycles, 4.71 bit times
|
|
goto RcTo1_0 ;078 cycles, 4.77 bit times
|
|
btfsc PORTC,RC5 ;079 cycles, 4.83 bit times
|
|
goto RcTo1_0 ;080 cycles, 4.90 bit times
|
|
btfsc PORTC,RC5 ;081 cycles, 4.96 bit times
|
|
goto RcTo1_0 ;082 cycles, 5.02 bit times
|
|
btfsc PORTC,RC5 ;083 cycles, 5.08 bit times
|
|
goto RcTo1_0 ;084 cycles, 5.14 bit times
|
|
btfsc PORTC,RC5 ;085 cycles, 5.20 bit times
|
|
goto RcTo1_0 ;086 cycles, 5.26 bit times
|
|
btfsc PORTC,RC5 ;087 cycles, 5.32 bit times
|
|
goto RcTo1_0 ;088 cycles, 5.39 bit times
|
|
btfsc PORTC,RC5 ;089 cycles, 5.45 bit times
|
|
goto RcTo1_0 ;090 cycles, 5.51 bit times
|
|
btfss PORTA,RA1 ;091 cycles, 5.57 bit times
|
|
bcf INDF0,7 ;092 cycles, 5.63 bit times
|
|
addfsr FSR0,1 ;093 cycles, 5.69 bit times
|
|
goto RcSt0 ;094 cycles, 5.75 bit times
|
|
|
|
RcTo0_4 movlw B'00010000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_3 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_3 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_3 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_3 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_3 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_3 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_3 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_3 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_2 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_2 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_2 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_2 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_2 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_2 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_2 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_2 ;040 cycles, 2.45 bit times
|
|
btfsc PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo1_1 ;042 cycles, 2.57 bit times
|
|
btfsc PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo1_1 ;044 cycles, 2.69 bit times
|
|
btfsc PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo1_1 ;046 cycles, 2.82 bit times
|
|
btfsc PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo1_1 ;048 cycles, 2.94 bit times
|
|
btfsc PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo1_1 ;050 cycles, 3.06 bit times
|
|
btfsc PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo1_1 ;052 cycles, 3.18 bit times
|
|
btfsc PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo1_1 ;054 cycles, 3.30 bit times
|
|
btfsc PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo1_1 ;056 cycles, 3.43 bit times
|
|
btfsc PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo1_1 ;058 cycles, 3.55 bit times
|
|
btfsc PORTC,RC5 ;059 cycles, 3.61 bit times
|
|
goto RcTo1_0 ;060 cycles, 3.67 bit times
|
|
btfsc PORTC,RC5 ;061 cycles, 3.73 bit times
|
|
goto RcTo1_0 ;062 cycles, 3.79 bit times
|
|
btfsc PORTC,RC5 ;063 cycles, 3.86 bit times
|
|
goto RcTo1_0 ;064 cycles, 3.92 bit times
|
|
btfsc PORTC,RC5 ;065 cycles, 3.98 bit times
|
|
goto RcTo1_0 ;066 cycles, 4.04 bit times
|
|
btfsc PORTC,RC5 ;067 cycles, 4.10 bit times
|
|
goto RcTo1_0 ;068 cycles, 4.16 bit times
|
|
btfsc PORTC,RC5 ;069 cycles, 4.22 bit times
|
|
goto RcTo1_0 ;070 cycles, 4.28 bit times
|
|
btfsc PORTC,RC5 ;071 cycles, 4.35 bit times
|
|
goto RcTo1_0 ;072 cycles, 4.41 bit times
|
|
btfsc PORTC,RC5 ;073 cycles, 4.47 bit times
|
|
goto RcTo1_0 ;074 cycles, 4.53 bit times
|
|
btfss PORTA,RA1 ;075 cycles, 4.59 bit times
|
|
bcf INDF0,7 ;076 cycles, 4.65 bit times
|
|
addfsr FSR0,1 ;077 cycles, 4.71 bit times
|
|
goto RcSt0 ;078 cycles, 4.77 bit times
|
|
|
|
RcTo0_3 movlw B'00001000' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_2 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_2 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_2 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_2 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_2 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_2 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_2 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_2 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_1 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_1 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_1 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_1 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_1 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_1 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_1 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_1 ;040 cycles, 2.45 bit times
|
|
btfsc PORTC,RC5 ;041 cycles, 2.51 bit times
|
|
goto RcTo1_0 ;042 cycles, 2.57 bit times
|
|
btfsc PORTC,RC5 ;043 cycles, 2.63 bit times
|
|
goto RcTo1_0 ;044 cycles, 2.69 bit times
|
|
btfsc PORTC,RC5 ;045 cycles, 2.75 bit times
|
|
goto RcTo1_0 ;046 cycles, 2.82 bit times
|
|
btfsc PORTC,RC5 ;047 cycles, 2.88 bit times
|
|
goto RcTo1_0 ;048 cycles, 2.94 bit times
|
|
btfsc PORTC,RC5 ;049 cycles, 3.00 bit times
|
|
goto RcTo1_0 ;050 cycles, 3.06 bit times
|
|
btfsc PORTC,RC5 ;051 cycles, 3.12 bit times
|
|
goto RcTo1_0 ;052 cycles, 3.18 bit times
|
|
btfsc PORTC,RC5 ;053 cycles, 3.24 bit times
|
|
goto RcTo1_0 ;054 cycles, 3.30 bit times
|
|
btfsc PORTC,RC5 ;055 cycles, 3.37 bit times
|
|
goto RcTo1_0 ;056 cycles, 3.43 bit times
|
|
btfsc PORTC,RC5 ;057 cycles, 3.49 bit times
|
|
goto RcTo1_0 ;058 cycles, 3.55 bit times
|
|
btfss PORTA,RA1 ;059 cycles, 3.61 bit times
|
|
bcf INDF0,7 ;060 cycles, 3.67 bit times
|
|
addfsr FSR0,1 ;061 cycles, 3.73 bit times
|
|
goto RcSt0 ;062 cycles, 3.79 bit times
|
|
|
|
RcTo0_2 movlw B'00000100' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_1 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_1 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_1 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_1 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_1 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_1 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_1 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_1 ;024 cycles, 1.47 bit times
|
|
btfsc PORTC,RC5 ;025 cycles, 1.53 bit times
|
|
goto RcTo1_0 ;026 cycles, 1.59 bit times
|
|
btfsc PORTC,RC5 ;027 cycles, 1.65 bit times
|
|
goto RcTo1_0 ;028 cycles, 1.71 bit times
|
|
btfsc PORTC,RC5 ;029 cycles, 1.77 bit times
|
|
goto RcTo1_0 ;030 cycles, 1.84 bit times
|
|
btfsc PORTC,RC5 ;031 cycles, 1.90 bit times
|
|
goto RcTo1_0 ;032 cycles, 1.96 bit times
|
|
btfsc PORTC,RC5 ;033 cycles, 2.02 bit times
|
|
goto RcTo1_0 ;034 cycles, 2.08 bit times
|
|
btfsc PORTC,RC5 ;035 cycles, 2.14 bit times
|
|
goto RcTo1_0 ;036 cycles, 2.20 bit times
|
|
btfsc PORTC,RC5 ;037 cycles, 2.26 bit times
|
|
goto RcTo1_0 ;038 cycles, 2.33 bit times
|
|
btfsc PORTC,RC5 ;039 cycles, 2.39 bit times
|
|
goto RcTo1_0 ;040 cycles, 2.45 bit times
|
|
btfss PORTA,RA1 ;041 cycles, 2.51 bit times
|
|
bcf INDF0,7 ;042 cycles, 2.57 bit times
|
|
addfsr FSR0,1 ;043 cycles, 2.63 bit times
|
|
goto RcSt0 ;044 cycles, 2.69 bit times
|
|
|
|
RcTo0_1 movlw B'00000010' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
DNOP ;007-008 cycles, 0.43-0.49 bit times
|
|
btfsc PORTC,RC5 ;009 cycles, 0.55 bit times
|
|
goto RcTo1_0 ;010 cycles, 0.61 bit times
|
|
btfsc PORTC,RC5 ;011 cycles, 0.67 bit times
|
|
goto RcTo1_0 ;012 cycles, 0.73 bit times
|
|
btfsc PORTC,RC5 ;013 cycles, 0.80 bit times
|
|
goto RcTo1_0 ;014 cycles, 0.86 bit times
|
|
btfsc PORTC,RC5 ;015 cycles, 0.92 bit times
|
|
goto RcTo1_0 ;016 cycles, 0.98 bit times
|
|
btfsc PORTC,RC5 ;017 cycles, 1.04 bit times
|
|
goto RcTo1_0 ;018 cycles, 1.10 bit times
|
|
btfsc PORTC,RC5 ;019 cycles, 1.16 bit times
|
|
goto RcTo1_0 ;020 cycles, 1.22 bit times
|
|
btfsc PORTC,RC5 ;021 cycles, 1.29 bit times
|
|
goto RcTo1_0 ;022 cycles, 1.35 bit times
|
|
btfsc PORTC,RC5 ;023 cycles, 1.41 bit times
|
|
goto RcTo1_0 ;024 cycles, 1.47 bit times
|
|
btfss PORTA,RA1 ;025 cycles, 1.53 bit times
|
|
bcf INDF0,7 ;026 cycles, 1.59 bit times
|
|
addfsr FSR0,1 ;027 cycles, 1.65 bit times
|
|
goto RcSt0 ;028 cycles, 1.71 bit times
|
|
|
|
RcTo0_0 movlw B'00000001' ;003 cycles, 0.18 bit times
|
|
iorwf INDF0,F ;004 cycles, 0.24 bit times
|
|
btfss PORTA,RA1 ;005 cycles, 0.31 bit times
|
|
bcf INDF0,7 ;006 cycles, 0.37 bit times
|
|
addfsr FSR0,1 ;007 cycles, 0.43 bit times
|
|
goto RcSt0 ;008 cycles, 0.49 bit times
|
|
|
|
|
|
;;; Received Data Decoder ;;;
|
|
|
|
RecvDecode
|
|
movf RC_CMDG,W ;Trust the group count that mac sent is
|
|
andlw B'01111111' ; accurate and copy it into the group count
|
|
movwf GROUPS ; variable that we return as well as a temp var
|
|
movwf TEMP2 ; that we can trash
|
|
movlw 0x20 ;Start both pointers after the three initial
|
|
movwf FSR0H ; IWM bytes (the sync byte, the length of the
|
|
movwf FSR1H ; message in groups plus 0x80, the length of
|
|
movlw 0x4B ; the expected reply in groups plus 0x80)
|
|
movwf FSR0L ; "
|
|
movwf FSR1L ; "
|
|
|
|
RDLoop btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_7 ; into suspend here, switch loops
|
|
moviw FSR0++ ;Pick up the byte with the LSBs of the next
|
|
movwf TEMP ; seven
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_6 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the first byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_5 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the second byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_4 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the third byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_3 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the fourth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_2 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the fifth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_1 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the sixth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
btfss INDF0,7 ;If the MSB of the next byte is clear, we went
|
|
bra RDSus_0 ; into suspend here, switch loops
|
|
lsrf TEMP,F ;Rotate the LSB of the last byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
decfsz TEMP2,F ;Decrement the group count and loop if it's not
|
|
bra RDLoop ; yet zero
|
|
return
|
|
|
|
RDSus_7 moviw FSR0++ ;Pick up the byte with the LSBs of the next
|
|
movwf TEMP ; seven
|
|
RDSus_6 lsrf TEMP,F ;Rotate the LSB of the first byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_5 lsrf TEMP,F ;Rotate the LSB of the second byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_4 lsrf TEMP,F ;Rotate the LSB of the third byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_3 lsrf TEMP,F ;Rotate the LSB of the fourth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_2 lsrf TEMP,F ;Rotate the LSB of the fifth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_1 lsrf TEMP,F ;Rotate the LSB of the sixth byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
RDSus_0 lsrf TEMP,F ;Rotate the LSB of the last byte of the group
|
|
rlf INDF0,W ; into place
|
|
movwi FSR1++ ;Write the restored byte to memory
|
|
addfsr FSR0,1 ;Advance the input pointer
|
|
decf TEMP2,F ;Decrement the group count
|
|
btfsc STATUS,Z ;If the group count happens to be zero, mac
|
|
return ; suspended in the last group and we're done
|
|
RDSusLp moviw FSR0++ ;Read the next byte, and if it's a sync byte,
|
|
xorlw 0xAA ; continue processing data
|
|
btfsc STATUS,Z ; "
|
|
bra RDLoop ; "
|
|
btfss FSR0H,2 ;As a safety measure, check if we've gone off
|
|
bra RDSusLp ; the edge of linear memory before we loop
|
|
bsf FLAGS,ABORTED ; to check the next byte; if we have, set the
|
|
return ; aborted flag and return
|
|
|
|
|
|
;;; CRC Lookup Tables ;;;
|
|
|
|
org 0x1D00
|
|
|
|
LutCrc7
|
|
retlw 0x00
|
|
retlw 0x12
|
|
retlw 0x24
|
|
retlw 0x36
|
|
retlw 0x48
|
|
retlw 0x5A
|
|
retlw 0x6C
|
|
retlw 0x7E
|
|
retlw 0x90
|
|
retlw 0x82
|
|
retlw 0xB4
|
|
retlw 0xA6
|
|
retlw 0xD8
|
|
retlw 0xCA
|
|
retlw 0xFC
|
|
retlw 0xEE
|
|
retlw 0x32
|
|
retlw 0x20
|
|
retlw 0x16
|
|
retlw 0x04
|
|
retlw 0x7A
|
|
retlw 0x68
|
|
retlw 0x5E
|
|
retlw 0x4C
|
|
retlw 0xA2
|
|
retlw 0xB0
|
|
retlw 0x86
|
|
retlw 0x94
|
|
retlw 0xEA
|
|
retlw 0xF8
|
|
retlw 0xCE
|
|
retlw 0xDC
|
|
retlw 0x64
|
|
retlw 0x76
|
|
retlw 0x40
|
|
retlw 0x52
|
|
retlw 0x2C
|
|
retlw 0x3E
|
|
retlw 0x08
|
|
retlw 0x1A
|
|
retlw 0xF4
|
|
retlw 0xE6
|
|
retlw 0xD0
|
|
retlw 0xC2
|
|
retlw 0xBC
|
|
retlw 0xAE
|
|
retlw 0x98
|
|
retlw 0x8A
|
|
retlw 0x56
|
|
retlw 0x44
|
|
retlw 0x72
|
|
retlw 0x60
|
|
retlw 0x1E
|
|
retlw 0x0C
|
|
retlw 0x3A
|
|
retlw 0x28
|
|
retlw 0xC6
|
|
retlw 0xD4
|
|
retlw 0xE2
|
|
retlw 0xF0
|
|
retlw 0x8E
|
|
retlw 0x9C
|
|
retlw 0xAA
|
|
retlw 0xB8
|
|
retlw 0xC8
|
|
retlw 0xDA
|
|
retlw 0xEC
|
|
retlw 0xFE
|
|
retlw 0x80
|
|
retlw 0x92
|
|
retlw 0xA4
|
|
retlw 0xB6
|
|
retlw 0x58
|
|
retlw 0x4A
|
|
retlw 0x7C
|
|
retlw 0x6E
|
|
retlw 0x10
|
|
retlw 0x02
|
|
retlw 0x34
|
|
retlw 0x26
|
|
retlw 0xFA
|
|
retlw 0xE8
|
|
retlw 0xDE
|
|
retlw 0xCC
|
|
retlw 0xB2
|
|
retlw 0xA0
|
|
retlw 0x96
|
|
retlw 0x84
|
|
retlw 0x6A
|
|
retlw 0x78
|
|
retlw 0x4E
|
|
retlw 0x5C
|
|
retlw 0x22
|
|
retlw 0x30
|
|
retlw 0x06
|
|
retlw 0x14
|
|
retlw 0xAC
|
|
retlw 0xBE
|
|
retlw 0x88
|
|
retlw 0x9A
|
|
retlw 0xE4
|
|
retlw 0xF6
|
|
retlw 0xC0
|
|
retlw 0xD2
|
|
retlw 0x3C
|
|
retlw 0x2E
|
|
retlw 0x18
|
|
retlw 0x0A
|
|
retlw 0x74
|
|
retlw 0x66
|
|
retlw 0x50
|
|
retlw 0x42
|
|
retlw 0x9E
|
|
retlw 0x8C
|
|
retlw 0xBA
|
|
retlw 0xA8
|
|
retlw 0xD6
|
|
retlw 0xC4
|
|
retlw 0xF2
|
|
retlw 0xE0
|
|
retlw 0x0E
|
|
retlw 0x1C
|
|
retlw 0x2A
|
|
retlw 0x38
|
|
retlw 0x46
|
|
retlw 0x54
|
|
retlw 0x62
|
|
retlw 0x70
|
|
retlw 0x82
|
|
retlw 0x90
|
|
retlw 0xA6
|
|
retlw 0xB4
|
|
retlw 0xCA
|
|
retlw 0xD8
|
|
retlw 0xEE
|
|
retlw 0xFC
|
|
retlw 0x12
|
|
retlw 0x00
|
|
retlw 0x36
|
|
retlw 0x24
|
|
retlw 0x5A
|
|
retlw 0x48
|
|
retlw 0x7E
|
|
retlw 0x6C
|
|
retlw 0xB0
|
|
retlw 0xA2
|
|
retlw 0x94
|
|
retlw 0x86
|
|
retlw 0xF8
|
|
retlw 0xEA
|
|
retlw 0xDC
|
|
retlw 0xCE
|
|
retlw 0x20
|
|
retlw 0x32
|
|
retlw 0x04
|
|
retlw 0x16
|
|
retlw 0x68
|
|
retlw 0x7A
|
|
retlw 0x4C
|
|
retlw 0x5E
|
|
retlw 0xE6
|
|
retlw 0xF4
|
|
retlw 0xC2
|
|
retlw 0xD0
|
|
retlw 0xAE
|
|
retlw 0xBC
|
|
retlw 0x8A
|
|
retlw 0x98
|
|
retlw 0x76
|
|
retlw 0x64
|
|
retlw 0x52
|
|
retlw 0x40
|
|
retlw 0x3E
|
|
retlw 0x2C
|
|
retlw 0x1A
|
|
retlw 0x08
|
|
retlw 0xD4
|
|
retlw 0xC6
|
|
retlw 0xF0
|
|
retlw 0xE2
|
|
retlw 0x9C
|
|
retlw 0x8E
|
|
retlw 0xB8
|
|
retlw 0xAA
|
|
retlw 0x44
|
|
retlw 0x56
|
|
retlw 0x60
|
|
retlw 0x72
|
|
retlw 0x0C
|
|
retlw 0x1E
|
|
retlw 0x28
|
|
retlw 0x3A
|
|
retlw 0x4A
|
|
retlw 0x58
|
|
retlw 0x6E
|
|
retlw 0x7C
|
|
retlw 0x02
|
|
retlw 0x10
|
|
retlw 0x26
|
|
retlw 0x34
|
|
retlw 0xDA
|
|
retlw 0xC8
|
|
retlw 0xFE
|
|
retlw 0xEC
|
|
retlw 0x92
|
|
retlw 0x80
|
|
retlw 0xB6
|
|
retlw 0xA4
|
|
retlw 0x78
|
|
retlw 0x6A
|
|
retlw 0x5C
|
|
retlw 0x4E
|
|
retlw 0x30
|
|
retlw 0x22
|
|
retlw 0x14
|
|
retlw 0x06
|
|
retlw 0xE8
|
|
retlw 0xFA
|
|
retlw 0xCC
|
|
retlw 0xDE
|
|
retlw 0xA0
|
|
retlw 0xB2
|
|
retlw 0x84
|
|
retlw 0x96
|
|
retlw 0x2E
|
|
retlw 0x3C
|
|
retlw 0x0A
|
|
retlw 0x18
|
|
retlw 0x66
|
|
retlw 0x74
|
|
retlw 0x42
|
|
retlw 0x50
|
|
retlw 0xBE
|
|
retlw 0xAC
|
|
retlw 0x9A
|
|
retlw 0x88
|
|
retlw 0xF6
|
|
retlw 0xE4
|
|
retlw 0xD2
|
|
retlw 0xC0
|
|
retlw 0x1C
|
|
retlw 0x0E
|
|
retlw 0x38
|
|
retlw 0x2A
|
|
retlw 0x54
|
|
retlw 0x46
|
|
retlw 0x70
|
|
retlw 0x62
|
|
retlw 0x8C
|
|
retlw 0x9E
|
|
retlw 0xA8
|
|
retlw 0xBA
|
|
retlw 0xC4
|
|
retlw 0xD6
|
|
retlw 0xE0
|
|
retlw 0xF2
|
|
|
|
org 0x1E00
|
|
|
|
LutCrc16H
|
|
retlw 0x00
|
|
retlw 0x10
|
|
retlw 0x20
|
|
retlw 0x30
|
|
retlw 0x40
|
|
retlw 0x50
|
|
retlw 0x60
|
|
retlw 0x70
|
|
retlw 0x81
|
|
retlw 0x91
|
|
retlw 0xA1
|
|
retlw 0xB1
|
|
retlw 0xC1
|
|
retlw 0xD1
|
|
retlw 0xE1
|
|
retlw 0xF1
|
|
retlw 0x12
|
|
retlw 0x02
|
|
retlw 0x32
|
|
retlw 0x22
|
|
retlw 0x52
|
|
retlw 0x42
|
|
retlw 0x72
|
|
retlw 0x62
|
|
retlw 0x93
|
|
retlw 0x83
|
|
retlw 0xB3
|
|
retlw 0xA3
|
|
retlw 0xD3
|
|
retlw 0xC3
|
|
retlw 0xF3
|
|
retlw 0xE3
|
|
retlw 0x24
|
|
retlw 0x34
|
|
retlw 0x04
|
|
retlw 0x14
|
|
retlw 0x64
|
|
retlw 0x74
|
|
retlw 0x44
|
|
retlw 0x54
|
|
retlw 0xA5
|
|
retlw 0xB5
|
|
retlw 0x85
|
|
retlw 0x95
|
|
retlw 0xE5
|
|
retlw 0xF5
|
|
retlw 0xC5
|
|
retlw 0xD5
|
|
retlw 0x36
|
|
retlw 0x26
|
|
retlw 0x16
|
|
retlw 0x06
|
|
retlw 0x76
|
|
retlw 0x66
|
|
retlw 0x56
|
|
retlw 0x46
|
|
retlw 0xB7
|
|
retlw 0xA7
|
|
retlw 0x97
|
|
retlw 0x87
|
|
retlw 0xF7
|
|
retlw 0xE7
|
|
retlw 0xD7
|
|
retlw 0xC7
|
|
retlw 0x48
|
|
retlw 0x58
|
|
retlw 0x68
|
|
retlw 0x78
|
|
retlw 0x08
|
|
retlw 0x18
|
|
retlw 0x28
|
|
retlw 0x38
|
|
retlw 0xC9
|
|
retlw 0xD9
|
|
retlw 0xE9
|
|
retlw 0xF9
|
|
retlw 0x89
|
|
retlw 0x99
|
|
retlw 0xA9
|
|
retlw 0xB9
|
|
retlw 0x5A
|
|
retlw 0x4A
|
|
retlw 0x7A
|
|
retlw 0x6A
|
|
retlw 0x1A
|
|
retlw 0x0A
|
|
retlw 0x3A
|
|
retlw 0x2A
|
|
retlw 0xDB
|
|
retlw 0xCB
|
|
retlw 0xFB
|
|
retlw 0xEB
|
|
retlw 0x9B
|
|
retlw 0x8B
|
|
retlw 0xBB
|
|
retlw 0xAB
|
|
retlw 0x6C
|
|
retlw 0x7C
|
|
retlw 0x4C
|
|
retlw 0x5C
|
|
retlw 0x2C
|
|
retlw 0x3C
|
|
retlw 0x0C
|
|
retlw 0x1C
|
|
retlw 0xED
|
|
retlw 0xFD
|
|
retlw 0xCD
|
|
retlw 0xDD
|
|
retlw 0xAD
|
|
retlw 0xBD
|
|
retlw 0x8D
|
|
retlw 0x9D
|
|
retlw 0x7E
|
|
retlw 0x6E
|
|
retlw 0x5E
|
|
retlw 0x4E
|
|
retlw 0x3E
|
|
retlw 0x2E
|
|
retlw 0x1E
|
|
retlw 0x0E
|
|
retlw 0xFF
|
|
retlw 0xEF
|
|
retlw 0xDF
|
|
retlw 0xCF
|
|
retlw 0xBF
|
|
retlw 0xAF
|
|
retlw 0x9F
|
|
retlw 0x8F
|
|
retlw 0x91
|
|
retlw 0x81
|
|
retlw 0xB1
|
|
retlw 0xA1
|
|
retlw 0xD1
|
|
retlw 0xC1
|
|
retlw 0xF1
|
|
retlw 0xE1
|
|
retlw 0x10
|
|
retlw 0x00
|
|
retlw 0x30
|
|
retlw 0x20
|
|
retlw 0x50
|
|
retlw 0x40
|
|
retlw 0x70
|
|
retlw 0x60
|
|
retlw 0x83
|
|
retlw 0x93
|
|
retlw 0xA3
|
|
retlw 0xB3
|
|
retlw 0xC3
|
|
retlw 0xD3
|
|
retlw 0xE3
|
|
retlw 0xF3
|
|
retlw 0x02
|
|
retlw 0x12
|
|
retlw 0x22
|
|
retlw 0x32
|
|
retlw 0x42
|
|
retlw 0x52
|
|
retlw 0x62
|
|
retlw 0x72
|
|
retlw 0xB5
|
|
retlw 0xA5
|
|
retlw 0x95
|
|
retlw 0x85
|
|
retlw 0xF5
|
|
retlw 0xE5
|
|
retlw 0xD5
|
|
retlw 0xC5
|
|
retlw 0x34
|
|
retlw 0x24
|
|
retlw 0x14
|
|
retlw 0x04
|
|
retlw 0x74
|
|
retlw 0x64
|
|
retlw 0x54
|
|
retlw 0x44
|
|
retlw 0xA7
|
|
retlw 0xB7
|
|
retlw 0x87
|
|
retlw 0x97
|
|
retlw 0xE7
|
|
retlw 0xF7
|
|
retlw 0xC7
|
|
retlw 0xD7
|
|
retlw 0x26
|
|
retlw 0x36
|
|
retlw 0x06
|
|
retlw 0x16
|
|
retlw 0x66
|
|
retlw 0x76
|
|
retlw 0x46
|
|
retlw 0x56
|
|
retlw 0xD9
|
|
retlw 0xC9
|
|
retlw 0xF9
|
|
retlw 0xE9
|
|
retlw 0x99
|
|
retlw 0x89
|
|
retlw 0xB9
|
|
retlw 0xA9
|
|
retlw 0x58
|
|
retlw 0x48
|
|
retlw 0x78
|
|
retlw 0x68
|
|
retlw 0x18
|
|
retlw 0x08
|
|
retlw 0x38
|
|
retlw 0x28
|
|
retlw 0xCB
|
|
retlw 0xDB
|
|
retlw 0xEB
|
|
retlw 0xFB
|
|
retlw 0x8B
|
|
retlw 0x9B
|
|
retlw 0xAB
|
|
retlw 0xBB
|
|
retlw 0x4A
|
|
retlw 0x5A
|
|
retlw 0x6A
|
|
retlw 0x7A
|
|
retlw 0x0A
|
|
retlw 0x1A
|
|
retlw 0x2A
|
|
retlw 0x3A
|
|
retlw 0xFD
|
|
retlw 0xED
|
|
retlw 0xDD
|
|
retlw 0xCD
|
|
retlw 0xBD
|
|
retlw 0xAD
|
|
retlw 0x9D
|
|
retlw 0x8D
|
|
retlw 0x7C
|
|
retlw 0x6C
|
|
retlw 0x5C
|
|
retlw 0x4C
|
|
retlw 0x3C
|
|
retlw 0x2C
|
|
retlw 0x1C
|
|
retlw 0x0C
|
|
retlw 0xEF
|
|
retlw 0xFF
|
|
retlw 0xCF
|
|
retlw 0xDF
|
|
retlw 0xAF
|
|
retlw 0xBF
|
|
retlw 0x8F
|
|
retlw 0x9F
|
|
retlw 0x6E
|
|
retlw 0x7E
|
|
retlw 0x4E
|
|
retlw 0x5E
|
|
retlw 0x2E
|
|
retlw 0x3E
|
|
retlw 0x0E
|
|
retlw 0x1E
|
|
|
|
org 0x1F00
|
|
|
|
LutCrc16L
|
|
retlw 0x00
|
|
retlw 0x21
|
|
retlw 0x42
|
|
retlw 0x63
|
|
retlw 0x84
|
|
retlw 0xA5
|
|
retlw 0xC6
|
|
retlw 0xE7
|
|
retlw 0x08
|
|
retlw 0x29
|
|
retlw 0x4A
|
|
retlw 0x6B
|
|
retlw 0x8C
|
|
retlw 0xAD
|
|
retlw 0xCE
|
|
retlw 0xEF
|
|
retlw 0x31
|
|
retlw 0x10
|
|
retlw 0x73
|
|
retlw 0x52
|
|
retlw 0xB5
|
|
retlw 0x94
|
|
retlw 0xF7
|
|
retlw 0xD6
|
|
retlw 0x39
|
|
retlw 0x18
|
|
retlw 0x7B
|
|
retlw 0x5A
|
|
retlw 0xBD
|
|
retlw 0x9C
|
|
retlw 0xFF
|
|
retlw 0xDE
|
|
retlw 0x62
|
|
retlw 0x43
|
|
retlw 0x20
|
|
retlw 0x01
|
|
retlw 0xE6
|
|
retlw 0xC7
|
|
retlw 0xA4
|
|
retlw 0x85
|
|
retlw 0x6A
|
|
retlw 0x4B
|
|
retlw 0x28
|
|
retlw 0x09
|
|
retlw 0xEE
|
|
retlw 0xCF
|
|
retlw 0xAC
|
|
retlw 0x8D
|
|
retlw 0x53
|
|
retlw 0x72
|
|
retlw 0x11
|
|
retlw 0x30
|
|
retlw 0xD7
|
|
retlw 0xF6
|
|
retlw 0x95
|
|
retlw 0xB4
|
|
retlw 0x5B
|
|
retlw 0x7A
|
|
retlw 0x19
|
|
retlw 0x38
|
|
retlw 0xDF
|
|
retlw 0xFE
|
|
retlw 0x9D
|
|
retlw 0xBC
|
|
retlw 0xC4
|
|
retlw 0xE5
|
|
retlw 0x86
|
|
retlw 0xA7
|
|
retlw 0x40
|
|
retlw 0x61
|
|
retlw 0x02
|
|
retlw 0x23
|
|
retlw 0xCC
|
|
retlw 0xED
|
|
retlw 0x8E
|
|
retlw 0xAF
|
|
retlw 0x48
|
|
retlw 0x69
|
|
retlw 0x0A
|
|
retlw 0x2B
|
|
retlw 0xF5
|
|
retlw 0xD4
|
|
retlw 0xB7
|
|
retlw 0x96
|
|
retlw 0x71
|
|
retlw 0x50
|
|
retlw 0x33
|
|
retlw 0x12
|
|
retlw 0xFD
|
|
retlw 0xDC
|
|
retlw 0xBF
|
|
retlw 0x9E
|
|
retlw 0x79
|
|
retlw 0x58
|
|
retlw 0x3B
|
|
retlw 0x1A
|
|
retlw 0xA6
|
|
retlw 0x87
|
|
retlw 0xE4
|
|
retlw 0xC5
|
|
retlw 0x22
|
|
retlw 0x03
|
|
retlw 0x60
|
|
retlw 0x41
|
|
retlw 0xAE
|
|
retlw 0x8F
|
|
retlw 0xEC
|
|
retlw 0xCD
|
|
retlw 0x2A
|
|
retlw 0x0B
|
|
retlw 0x68
|
|
retlw 0x49
|
|
retlw 0x97
|
|
retlw 0xB6
|
|
retlw 0xD5
|
|
retlw 0xF4
|
|
retlw 0x13
|
|
retlw 0x32
|
|
retlw 0x51
|
|
retlw 0x70
|
|
retlw 0x9F
|
|
retlw 0xBE
|
|
retlw 0xDD
|
|
retlw 0xFC
|
|
retlw 0x1B
|
|
retlw 0x3A
|
|
retlw 0x59
|
|
retlw 0x78
|
|
retlw 0x88
|
|
retlw 0xA9
|
|
retlw 0xCA
|
|
retlw 0xEB
|
|
retlw 0x0C
|
|
retlw 0x2D
|
|
retlw 0x4E
|
|
retlw 0x6F
|
|
retlw 0x80
|
|
retlw 0xA1
|
|
retlw 0xC2
|
|
retlw 0xE3
|
|
retlw 0x04
|
|
retlw 0x25
|
|
retlw 0x46
|
|
retlw 0x67
|
|
retlw 0xB9
|
|
retlw 0x98
|
|
retlw 0xFB
|
|
retlw 0xDA
|
|
retlw 0x3D
|
|
retlw 0x1C
|
|
retlw 0x7F
|
|
retlw 0x5E
|
|
retlw 0xB1
|
|
retlw 0x90
|
|
retlw 0xF3
|
|
retlw 0xD2
|
|
retlw 0x35
|
|
retlw 0x14
|
|
retlw 0x77
|
|
retlw 0x56
|
|
retlw 0xEA
|
|
retlw 0xCB
|
|
retlw 0xA8
|
|
retlw 0x89
|
|
retlw 0x6E
|
|
retlw 0x4F
|
|
retlw 0x2C
|
|
retlw 0x0D
|
|
retlw 0xE2
|
|
retlw 0xC3
|
|
retlw 0xA0
|
|
retlw 0x81
|
|
retlw 0x66
|
|
retlw 0x47
|
|
retlw 0x24
|
|
retlw 0x05
|
|
retlw 0xDB
|
|
retlw 0xFA
|
|
retlw 0x99
|
|
retlw 0xB8
|
|
retlw 0x5F
|
|
retlw 0x7E
|
|
retlw 0x1D
|
|
retlw 0x3C
|
|
retlw 0xD3
|
|
retlw 0xF2
|
|
retlw 0x91
|
|
retlw 0xB0
|
|
retlw 0x57
|
|
retlw 0x76
|
|
retlw 0x15
|
|
retlw 0x34
|
|
retlw 0x4C
|
|
retlw 0x6D
|
|
retlw 0x0E
|
|
retlw 0x2F
|
|
retlw 0xC8
|
|
retlw 0xE9
|
|
retlw 0x8A
|
|
retlw 0xAB
|
|
retlw 0x44
|
|
retlw 0x65
|
|
retlw 0x06
|
|
retlw 0x27
|
|
retlw 0xC0
|
|
retlw 0xE1
|
|
retlw 0x82
|
|
retlw 0xA3
|
|
retlw 0x7D
|
|
retlw 0x5C
|
|
retlw 0x3F
|
|
retlw 0x1E
|
|
retlw 0xF9
|
|
retlw 0xD8
|
|
retlw 0xBB
|
|
retlw 0x9A
|
|
retlw 0x75
|
|
retlw 0x54
|
|
retlw 0x37
|
|
retlw 0x16
|
|
retlw 0xF1
|
|
retlw 0xD0
|
|
retlw 0xB3
|
|
retlw 0x92
|
|
retlw 0x2E
|
|
retlw 0x0F
|
|
retlw 0x6C
|
|
retlw 0x4D
|
|
retlw 0xAA
|
|
retlw 0x8B
|
|
retlw 0xE8
|
|
retlw 0xC9
|
|
retlw 0x26
|
|
retlw 0x07
|
|
retlw 0x64
|
|
retlw 0x45
|
|
retlw 0xA2
|
|
retlw 0x83
|
|
retlw 0xE0
|
|
retlw 0xC1
|
|
retlw 0x1F
|
|
retlw 0x3E
|
|
retlw 0x5D
|
|
retlw 0x7C
|
|
retlw 0x9B
|
|
retlw 0xBA
|
|
retlw 0xD9
|
|
retlw 0xF8
|
|
retlw 0x17
|
|
retlw 0x36
|
|
retlw 0x55
|
|
retlw 0x74
|
|
retlw 0x93
|
|
retlw 0xB2
|
|
retlw 0xD1
|
|
retlw 0xF0
|
|
|
|
|
|
;;; End of Program ;;;
|
|
end
|