Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ---------------------------------------------------------------------------
- ; Newd13 disassembly
- ;
- ; Newd13 with the following changes:
- ; InsA0-FF sending bytes bug fixed
- ; Ins70 instruction cycle counting routine added
- ; ---------------------------------------------------------------------------
- .INCLUDE "2313def.inc"
- ; Processor : AVR [AT90S2313]
- ; Target assembler: AVR Assembler
- ; ---------------------------------------------------------------------------
- ; IO Pins Usage (Reference Modded Kypro Tucker Unlooper)
- ; B0 - LED red
- ; B1 - LED green
- ; B2 - VCC glitch
- ; B3 - LM358 (PWM)
- ; B4 - cardslot switch
- ; B5 - (ICP MOSI)
- ; B6 - CLK line (ICP MISO)
- ; B7 - (ICP SCK)
- ; D0 - UART RXD (PC)
- ; D1 - UART TXD (PC)
- ; D2 - ISO VCC Mux Select
- ; D3 - Clock Enable (When 1)
- ; D4 - Glitch Enable (When 0)
- ; D5 - card RST
- ; D6 - card IO
- ; ---------------------------------------------------------------------------
- ; setup equates for PORTD and PORTB usage
- .equ CARDIO = 6 ; card IO = D6
- .equ CARDRST = 5 ; card RST = D5
- .equ CARDVCC = 4 ; card VCC = D4
- .equ CLK46 = 3 ; 4.608 MHz CLK enable = D3
- .equ CLKOUT = 6 ; CLK output = B6
- .equ CARDSLOT = 4 ; cardslot switch status = B4
- .equ VCCGLITCH = 2 ; VCC glitch enable = B2
- ; ---------------------------------------------------------------------------
- ; define register names
- .def RxVectorLow = r2
- .def RxVectorHigh = r3
- .def TxVectorLow = r4
- .def TxVectorHigh = r5
- .def GlitchOn = r6
- .def GlitchExtend = r7 ; unused
- .def GlitchOff = r8
- .def EEP_Pointer = r9
- .def TimeoutCounter = r13
- .def TimeoutLimit = r14
- .def ResponseLen = r15
- .def BitCount = r16 ; used within Tx/Rx routines, can be reused outside for temp use
- .def IOReg = r19
- .def DelayLowByte = r21
- .def DelayMidByte = r22
- .def DelayHighByte = r23
- ; ===========================================================================
- .org 0
- rjmp Start ; POR
- rjmp Start ; IRQ0
- rjmp Start ; IRQ1
- rjmp Start ; Timer1 Capture
- rjmp Start ; Timer1 Compare
- rjmp Start ; Timer1 Overflow
- rjmp TimeoutISR ; Timer0 Overflow
- rjmp Start ; UART RX Complete
- rjmp Start ; UDR Empty
- rjmp Start ; UART TX Complete
- rjmp Start ; Analog Comparator
- ; ---------------------------------------------------------------------------
- ; Start of Ins jump vectors, do not re-locate unless other adjustments are made (must start below 0100)
- ; * denotes instruction modified in NewdRS
- InsJumpVectors:
- rjmp EndProg ; Ins00 - end program
- rjmp Ins01 ; Ins01 - Reset Card - freeze Card Clock at 0000
- rjmp Ins02 ; Ins02 - Stop Card clock
- rjmp Ins03 ; Ins03 - Start Card clock
- rjmp Ins04 ;*Ins04 - DOUBLE HIT Glitch, CLOCK LOW, .5 CYCLE DELAY
- rjmp Ins05 ;*Ins05 - DOUBLE HIT Glitch, CLOCK LOW, 1.5 CYCLE DELAY
- rjmp Ins06 ;*Ins06 - DOUBLE HIT Glitch, CLOCK LOW, 6 CYCLE DELAY,
- rjmp Ins07 ;*Ins07 - Three HITS Glitch, CLOCK LOW , 6 CYCLE DELAY = 18 cycle spread
- rjmp Ins08 ;*Ins08 - Five HITS Glitch, LOW CLOCK, 5 CYCLE DELAY = 25 cycle spread
- rjmp Ins09 ;*Ins09 - LOW CLOCK single hit glitch
- rjmp Ins0A ;*Ins0A - save data to EEPROM buffer
- rjmp Ins0B ;*Ins0B - send data to card from EEPROM buffer
- rjmp Ins0C ; Ins0C - unused instruction
- rjmp Ins0D ;*Ins0D - unused instruction
- rjmp Ins0E ; Ins0E - set timeout for WDT
- rjmp Ins0F ;*Ins0F - receive bytes from card and send to PC immediately (0F0000 = receive 1 byte)
- rjmp Ins1x ;*Ins1x - set Tx/Rx speeds (select routines via vectors)
- rjmp Ins2x ; Ins2x - delay Atmel cycles (200000 - 2FFFFF)
- rjmp Ins3x ; Ins3x - unused instruction
- rjmp Ins4x ; Ins4x - unused instruction
- rjmp Ins5x ; Ins50 xx - receive xx bytes
- rjmp Ins6x ; Ins60 xx - send xx bytes
- rjmp Ins7x ;*Ins70 - ins timer test routine (custom - not in ND13)
- rjmp Ins8x ; Block Rx - 80 = receive 1 byte, 9F = receive 32 bytes
- rjmp Ins8x ; Block Rx - 80 = receive 1 byte, 9F = receive 32 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- rjmp InsAx ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- ; ---------------------------------------------------------------------------
- ; Start of Cmd jump vectors, do not re-locate unless other adjustments are made (must start below 0100)
- CmdJumpVectors:
- rjmp Cmd8x ; Cmd80 - Check for card present
- rjmp Cmd9x ; Cmd90 - send Atmel flash version to PC
- rjmp CmdAx ; CmdAx - Set LED - 0(off), 1(red) or 2(green)
- rjmp CmdBx ; CmdB0 - set glitch VCC - VCC = (5/255) * Param1
- rjmp CmdCx ; CmdCx - unused command
- rjmp CmdDx ; CmdDx - unused command
- rjmp CmdEx ; CmdEx - unused command
- rjmp CmdFx ; CmdF0 - send data in EEPROM buffer to PC
- ; ===========================================================================
- ; Power On Reset start
- Start:
- cli
- ldi r17, 0x10 ; raise PortB pin 4. (Card Switch Sense/Start)
- out PORTB, r17
- ldi r17, 0x12 ; raise PortD pins 4 and 1. (Glitch disable, UART TXD)
- out PORTD, r17
- ldi r17, 0x4F ; Set pins for New CLK Line, ADC, VCC Glitch, LED as output.
- out DDRB, r17
- ldi r17, 0x3A ; Set pins for ISO Reset, Glitch Enable, CLK Enable, UART TXD as output.
- out DDRD, r17
- clr YH ; clear memory indexing registers
- clr XH
- ldi r17, 5 ; Set timer/counter0 pre-scaler to CLK/1024.
- out TCCR0, r17
- ldi r17, 2 ; Enable timer/counter0 Oveflow interrupt
- out TIMSK, r17
- out OCR1AH, XH ; Set timer/counter1 output
- ldi r17, 0x81 ; output compare to $81.
- out OCR1AL, r17
- out TCCR1A, r17 ; clear OC1 output line, set PWM to 8-bits.
- ldi r17, 1 ; Set timer/counter1 pre-scaler to CLK/1.
- out TCCR1B, r17
- ldi r17, 4 ; Set BAUD rate to 115200 (18.432 MHz crystal)
- out UBRR, r17
- ldi r17, 0x18 ; Enable RX and TX.
- out UCR, r17
- ldi r17, 0xDF ; Init. stack pointer to start at $DF.
- out SPL, r17
- ldi r17, 0x54 ; Set glitch registers
- mov GlitchOn, r17
- ldi r17, 0x50
- mov GlitchOff, r17
- mov GlitchExtend, r17
- clr r17 ; Default tx/rx = of Rx1 and Tx1 jump vectors (during ATR time).
- rcall SetRxTxVectors ; low nibble of instruction codes Tx/Rx selection - bits 0-1 = rx, bits 2-3 = tx
- GetProgOrCmd: ; Get byte from UART (sent by PC)
- rcall RecvFromHost
- tst IOReg
- breq GetProgOrCmd ; loop until received byte is non-zero.
- brpl GetProgram ; If IOReg < $80 it is length of program
- mov ZL, IOReg ; setup Z for indirect jump to command's jump vector entry
- swap ZL
- andi ZL, 7
- ldi ZH, 0
- adiw ZL, Low(CmdJumpVectors) ; 2A = start of command jump vectors
- ijmp ; indirect jump to Z (command's jump vector Cmd8x-CmdFx)
- ; ---------------------------------------------------------------------------
- GetProgram:
- mov r0, IOReg ; First byte is packet length
- ldi YL, 0x60 ; 0060 = start of program packet from PC
- loop_GetPacket:
- rcall RecvFromHost
- st Y+, IOReg
- dec r0
- brne loop_GetPacket ; loop to receive r0 bytes of data from PC (receive full packet)
- ldi IOReg, 3
- mov TimeoutLimit, IOReg ; initialize TimeoutLimit to 3
- clr ResponseLen ; initialize ResponseLen to 0
- ldi XL, 0x60 ; set packet PC to start of program packet in RAM
- ExecProg: ; Get byte from RX'ed block, increment byte index.
- ld r17, X+
- mov ZL, r17 ; set up indirect jump to Ins00-InsFx
- cpi ZL, 0x10
- brcs GotInsBelow10
- swap ZL
- andi ZL, 0xF
- adiw ZL, 0xF
- GotInsBelow10:
- ldi ZH, 0
- adiw ZL, Low(InsJumpVectors) ; 0B = start of Ins jump vectors
- ijmp ; indirect jump to Z (instruction's jump vector Ins00-InsAx)
- ; ---------------------------------------------------------------------------
- EndProg: ; reset stack pointer to DF
- ldi r17, 0xDF
- out SPL, r17
- mov IOReg, XL ; Get PC pointer into program packet
- subi IOReg, 0x60 ; adjusted pointer for start of program packet in RAM
- rcall SendToPC ; send exec'd bytes of packet to PC (first byte of response)
- mov IOReg, ResponseLen
- rcall SendToPC ; send number of response data bytes to PC (second byte of response)
- tst ResponseLen
- breq ResponseSent
- mov r17, YL
- cp YL, XL
- brcs SendResponse_Overflow
- breq SendResponse_Overflow
- sub YL, ResponseLen ; set Y to point to beginning of response data bytes
- loop_SendResponseData: ; read byte from response data bytes in RAM
- ld IOReg, Y+
- rcall SendToPC
- dec ResponseLen
- brne loop_SendResponseData ; loop to send all response data bytes to PC
- ResponseSent: ; Receive and process command/packet from PC
- rjmp GetProgOrCmd
- ; ---------------------------------------------------------------------------
- SendResponse_Overflow:
- mov r17, ResponseLen
- mov ZL, YL
- subi ZL, 0x60
- sub ResponseLen, ZL
- ldi YL, 0xD8
- sub YL, ResponseLen
- loop_SendResponseData2:
- ld IOReg, Y+
- rcall SendToPC
- dec ResponseLen
- brne loop_SendResponseData2
- ldi YL, 0x60
- loc_90:
- ld IOReg, Y+
- rcall SendToPC
- dec ZL
- brne loc_90
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function Start
- ; ===========================================================================
- ; Ins01 - Reset Card - freeze Card Clock at 0000
- Ins01:
- sbi PORTD, CARDVCC ; inhibit on (glitch disable)
- ; turn card off
- cbi DDRD, CARDIO ; make D6 input
- cbi PORTD, CARDIO ; high Z D6
- cbi PORTD, CLK46 ; 4.608 MHz CLK off
- cbi PORTB, VCCGLITCH ; VCC glitch off
- cbi PORTB, CLKOUT ; CLK low
- cbi PORTD, CARDRST ; reset low (chip in reset state)
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins01
- ; ===========================================================================
- ; Ins02 - Stop Card clock
- Ins02:
- cbi PORTD, CLK46 ; 4.608 MHz CLK off
- cbi PORTB, CLKOUT ; CLK low
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins02
- ; ===========================================================================
- ; Ins03 - Start Card clock
- Ins03:
- cbi PORTD, CARDVCC ; inhibit off (glitch enable)
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz CLK on
- ldi ZL, Low(0x60)
- ldi ZH, High(0x60)
- rcall DelayCardCycles ; delay 96 + 4 card cycles
- sbi PORTD, CARDRST ; reset high (chip in running state)
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins03
- ; ===========================================================================
- ; Ins04 - DOUBLE HIT Glitch, CLOCK LOW, .5 CYCLE DELAY
- Ins04:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- nop
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz CLK on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins04
- ; ===========================================================================
- ; Ins05 - DOUBLE HIT Glitch, CLOCK LOW, 1.5 CYCLE DELAY
- Ins05:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- nop ; one cycle delay
- nop
- nop
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz CLK on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins05
- ; ===========================================================================
- ; Ins06 - DOUBLE HIT Glitch, CLOCK LOW, 6 CYCLE DELAY,
- Ins06:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz CLK on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz CLK on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins06
- ; ===========================================================================
- ; Ins07 - Three HITS Glitch, CLOCK LOW , 6 CYCLE DELAY = 18 cycle spread
- Ins07:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins07
- ; ===========================================================================
- ; Ins08 - Five HITS Glitch, LOW CLOCK, 5 CYCLE DELAY = 25 cycle spread
- Ins08:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- nop ; one cycle delay
- nop
- ldi r16, 0x14 ; setup GlitchOn (one cycle delay)
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff (one cycle delay)
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins08
- ; ===========================================================================
- ; Ins09 - LOW CLOCK single hit glitch
- Ins09:
- ldi r16, 0x14 ; setup GlitchOn
- mov GlitchOn, r16
- ldi r17, 0x10 ; setup GlitchOff
- mov GlitchOff, r17
- out PORTB, GlitchOn ; glitch for half a card cycle
- out PORTB, GlitchOff
- sbi PORTB, CLKOUT ; CLK high
- sbi PORTD, CLK46 ; 4.608 MHz on
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins09
- ; ===========================================================================
- ; Ins4x - unused instruction
- Ins4x:
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins4x
- ; ---------------------------------------------------------------------------
- rjmp ExecProg ; execute next instruction in program packet
- ; ===========================================================================
- ; Ins3x - unused instruction
- Ins3x:
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins3x
- ; ---------------------------------------------------------------------------
- rjmp ExecProg ; execute next instruction in program packet
- ; ===========================================================================
- ; Ins0D - unused instruction
- Ins0D:
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins0D
- ; ===========================================================================
- ; Ins0E - set timeout for WDT
- Ins0E:
- ld TimeoutLimit, X+ ; TimeoutLimit for WDT = byte following 0E in program packet
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins0E
- ; ===========================================================================
- ; Ins1x - set Tx/Rx speeds (select routines via vectors)
- Ins1x:
- rcall SetRxTxVectors ; low nibble of instruction codes Tx/Rx selection - bits 0-1 = rx, bits 2-3 = tx
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins1x
- ; ===========================================================================
- ; Ins2x - delay Atmel cycles (200000 - 2FFFFF)
- Ins2x:
- subi r17, 0x20 ; adjust byte from packet for offset of 20 (200000 = 0 delay)
- mov DelayHighByte, r17
- ld DelayMidByte, X+ ; read mid byte of delay value from program packet
- ld DelayLowByte, X+ ; read low byte of delay value from program packet
- lsr DelayLowByte
- brcs loc_15D
- loc_15D:
- lsr DelayLowByte
- brcc loc_161
- nop
- rjmp loc_161
- loc_161:
- inc DelayLowByte
- inc DelayMidByte
- inc DelayHighByte
- loc_164:
- nop
- dec DelayLowByte
- brne loc_164
- nop
- ldi DelayLowByte, 0x3F
- dec DelayMidByte
- brne loc_164
- nop
- dec DelayLowByte
- dec DelayHighByte
- brne loc_164
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins2x
- ; ===========================================================================
- ; Block Rx - 80 = receive 1 byte, 9F = receive 32 bytes
- Ins8x:
- andi r17, 0x1F ; mask off bits of instruction to give # of bytes to receive, 00-1F
- mov r1, r17
- inc r1 ; inc number of bytes to receive (adjust for 0=1)
- loop_BlockRx:
- rcall CardRx
- st Y+, IOReg
- inc ResponseLen
- dec r1
- brne loop_BlockRx
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins8x
- ; ===========================================================================
- ; Block Tx - A0 = send 1 byte, FF = send 96 bytes
- InsAx:
- subi r17, 0xA0 ; adjust instruction so A0=00 (number of bytes to send)
- mov r1, r17
- inc r1 ; inc number of bytes to send (adjust for 0=1)
- loop_BlockTx:
- ld IOReg, X+
- rcall CardTx
- dec r1
- brne loop_BlockTx
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function InsAx
- ; ===========================================================================
- ; Cmd80 - Check for card present
- Cmd8x:
- clr IOReg ; default status = 00 (no card)
- sbic PINB, CARDSLOT ; check cardslot switch status
- dec IOReg ; if cardslot switch status is high, set status = FF (card inserted)
- rcall SendToPC
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function Cmd8x
- ; ===========================================================================
- ; Cmd90 - send Atmel flash version to PC
- Cmd9x:
- ldi IOReg, 'N'
- rcall SendToPC
- ldi IOReg, 'D'
- rcall SendToPC
- ldi IOReg, '1'
- rcall SendToPC
- ldi IOReg, '3'
- rcall SendToPC
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function Cmd9x
- ; ===========================================================================
- ; CmdAx - Set LED - 0(off), 1(red) or 2(green)
- CmdAx:
- andi IOReg, 3 ; mask off all but low 2 bits of cmd
- in r17, PORTB ; read PORTB status (LED is PB0-PB1)
- andi r17, 0xFC ; mask off PB0-PB1 (LED)
- or r17, IOReg ; turn on requested LED bits
- out PORTB, r17 ; output PORTB status (with updated LED status)
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function CmdAx
- ; ===========================================================================
- ; CmdB0 - set glitch VCC - VCC = (5/255) * Param1
- CmdBx:
- rcall RecvFromHost ; get requested VCC value
- out OCR1AH, XH ; setup PWM (00yy) where yy=requested VCC value
- out OCR1AL, IOReg
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function CmdBx
- ; ===========================================================================
- ; CmdCx - unused command
- CmdCx:
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function CmdCx
- ; ===========================================================================
- ; CmdDx - unused command
- CmdDx:
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function CmdDx
- ; ===========================================================================
- RecvFromHost:
- sbis USR, RXC
- rjmp RecvFromHost ; loop until there is data waiting in UART receive buffer
- in IOReg, UDR ; copy UART data into software IOReg
- ret
- ; End of function RecvFromHost
- ; ===========================================================================
- SendToPC:
- sbis USR, UDRE
- rjmp SendToPC ; loop until UART is ready to transmit
- out UDR, IOReg ; output software IOReg to UART
- ret
- ; End of function SendToPC
- ; ===========================================================================
- ; DelayCardCycles - delay for total of 4 + Z card cycles, including ldi/call/ret
- DelayCardCycles:
- lsr ZH ; Z = cycles to delay
- ror ZL
- loop_DelayCardCycles:
- sbiw ZL, 1
- brne loop_DelayCardCycles ; loop to use up requested delay
- ret
- ; End of function DelayCardCycles
- ; ===========================================================================
- ; ClockCard - Clock card at 921.6 KHz ZH:ZL card clocks [UNUSED IN ND13]
- ClockCard:
- ldi r16, 0x50 ; setup CLK high
- ldi r17, 0x10 ; setup CLK low
- loop_ClockCard: ; CLK high
- out PORTB, r16
- rjmp cc_waste1 ; 2 atmel cycles
- cc_waste1: ; 2 atmel cycles
- rjmp cc_waste2
- cc_waste2: ; CLK low
- out PORTB, r17
- sbiw ZL, 1
- brne loop_ClockCard ; loop to give Z clocks
- ret
- ; End of function ClockCard
- ; ===========================================================================
- ; EnableTimeout - enable software watchdog timer while executing program packet
- EnableTimeout:
- out TCNT0, XL
- ldi r17, 2 ; enable Timer0 overflow interrupt
- out TIFR, r17
- mov TimeoutCounter, TimeoutLimit ; init TimeoutCounter = TimeoutLimit
- sei ; enable interrupts (for WDT)
- ret
- ; End of function EnableTimeout
- ; ===========================================================================
- ; Timer/Counter0 Overflow
- TimeoutISR:
- dec TimeoutCounter
- breq WDT_Expired ; if TimeoutCounter = 0, WDT has expired
- reti
- ; ---------------------------------------------------------------------------
- WDT_Expired:
- cli
- sbi PORTD, CARDVCC ; inhibit on (glitch disable)
- cbi DDRD, CARDIO ; make D6 input
- cbi PORTD, CARDIO ; high Z D6
- cbi PORTD, CLK46 ; CLK off
- cbi PORTB, VCCGLITCH ; VCC glitch off
- cbi PORTB, CARDSLOT ; CLK low
- cbi PORTD, CARDRST ; reset low
- rjmp EndProg
- ; End of function TimeoutISR
- ; ===========================================================================
- ; GetStartBit - wait for falling edge of start bit on card IO
- GetStartBit:
- cbi DDRD, CARDIO ; make D6 input
- sbi PORTD, CARDIO ; enable pullup
- rcall EnableTimeout
- wait_BeforeStart:
- sbis PIND, CARDIO
- rjmp wait_BeforeStart ; loop until IO is high (not active / flow control disabled)
- wait_StartFallingEdge:
- sbic PIND, CARDIO
- rjmp wait_StartFallingEdge ; loop until falling edge of start bit
- cli
- ret
- ; End of function GetStartBit
- ; ===========================================================================
- ; WaitForIOIdle - wait for card IO to be high (idle)
- WaitForIOIdle:
- cbi DDRD, CARDIO ; make D6 input
- sbi PORTD, CARDIO ; enable pullup
- rcall EnableTimeout
- wait_IOIdle:
- sbis PIND, CARDIO
- rjmp wait_IOIdle ; loop until IO is high (not active / flow control disabled)
- cli
- ret
- ; End of function WaitForIOIdle
- ; ===========================================================================
- ; CalcParity - calculate parity of IOReg, return with r17.7 = parity
- CalcParity:
- mov r17, IOReg
- swap r17
- eor r17, IOReg
- mov r0, r17
- lsl r0
- lsl r0
- eor r17, r0
- mov r0, r17
- lsl r0
- eor r17, r0
- andi r17, 0x80 ; mask off bits 0-6, leave bit 7 as parity
- ret
- ; End of function CalcParity
- ; ===========================================================================
- ; CardRx - receive one byte from card, using selected routine from CardRxTable
- CardRx:
- mov ZL, RxVectorLow ; setup Z for indirect jump to Rx routine
- mov ZH, RxVectorHigh
- ijmp ; indirect jump to card Rx routine
- ; End of function CardRx
- ; ---------------------------------------------------------------------------
- CardRxTable: ; Rx from card at ATR speed (etu = 372 cycles) 9600 @ 3.58 MHz
- rjmp Rx_etu372
- rjmp Rx_etu32 ; Rx from card at working speed (etu = 32 cycles)
- rjmp nullsub_2 ; unused transmit/receive speed
- rjmp rx_4 ; Rx from card at speed based on start bit timing (nonstandard protocol added to ND13)
- ; ===========================================================================
- ; CardTx - send one byte to card, using selected routine from CardTxTable
- CardTx:
- mov ZL, TxVectorLow ; setup Z for indirect jump to Tx routine
- mov ZH, TxVectorHigh
- ijmp ; indirect jump to card Tx routine
- ; End of function CardTx
- ; ---------------------------------------------------------------------------
- CardTxTable: ; unused transmit speed (should be ATR speed tx)
- rjmp nullsub_1
- rjmp Tx_etu32 ; Tx to card at working speed (etu = 32 cycles)
- rjmp nullsub_2 ; unused transmit/receive speed
- rjmp Tx_etu32 ; Tx to card at working speed (etu = 32 cycles)
- ; ===========================================================================
- ; SetRxTxVectors - low nibble of instruction codes Tx/Rx selection - bits 0-1 = rx, bits 2-3 = tx
- SetRxTxVectors:
- andi r17, 0xF ; Passed bits 0,1 = RX offset: 2,3= TX offset
- mov r0, r17
- andi r17, 3 ; mask all but bits 0-1 (rx offset)
- lsr r0
- lsr r0
- ldi IOReg, Low(CardRxTable)
- mov r2, IOReg
- ldi IOReg, High(CardRxTable)
- mov r3, IOReg
- add r2, r0
- adc r3, XH
- ldi IOReg, Low(CardTxTable)
- mov TxVectorLow, IOReg
- ldi IOReg, High(CardTxTable)
- mov TxVectorHigh, IOReg
- add TxVectorLow, r17
- adc TxVectorHigh, XH
- ret
- ; End of function SetRxTxVectors
- ; ===========================================================================
- ; Rx_etu372 - Rx from card at ATR speed (etu = 372 cycles) 9600 @ 3.58 MHz
- Rx_etu372:
- rcall GetStartBit
- ldi ZL, Low(0xB4)
- ldi ZH, High(0xB4)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- ldi BitCount, 8
- loc_204:
- ldi ZL, Low(0x16B)
- ldi ZH, High(0x16B)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- rjmp Rx1_waste1
- Rx1_waste1:
- nop
- clc
- sbis PIND, CARDIO ; check IO status
- sec
- rol IOReg
- dec BitCount
- brne loc_204
- ldi ZL, Low(0x31C)
- ldi ZH, High(0x31C)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- cbi DDRD, CARDIO
- cbi PORTD, CARDIO
- ret
- ; End of function Rx_etu372
- ; ===========================================================================
- ; Rx_etu32 - Rx from card at working speed (etu = 32 cycles)
- Rx_etu32:
- rcall GetStartBit
- ldi ZL, Low(0xA)
- ldi ZH, High(0xA)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- ldi r16, 8
- loc_21A:
- ldi ZL, Low(0x17)
- ldi ZH, High(0x17)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- rjmp loc_21E
- loc_21E:
- nop
- clc
- sbis PIND, CARDIO
- sec
- rol IOReg
- dec r16
- brne loc_21A
- nop
- ldi ZL, Low(0x1B)
- ldi ZH, High(0x1B)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- cbi DDRD, CARDIO
- cbi PORTD, CARDIO
- ret
- ; End of function Rx_etu32
- ; ===========================================================================
- ; unused transmit speed (should be ATR speed tx)
- nullsub_1:
- ret
- ; End of function nullsub_1
- ; ===========================================================================
- ; Tx_etu32 - Tx to card at working speed (etu = 32 cycles)
- Tx_etu32:
- ldi ZL, Low(0x2B8)
- ldi ZH, High(0x2B8)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- rcall WaitForIOIdle
- rcall CalcParity ; calculate parity of IOReg, return with r17.7 = parity
- ldi r16, 0xA
- sec
- loc_234:
- brcc loc_238
- cbi PORTD, CARDIO
- sbi DDRD, CARDIO
- rjmp loc_23B
- ; ---------------------------------------------------------------------------
- loc_238:
- nop
- sbi PORTD, CARDIO
- cbi DDRD, CARDIO
- loc_23B:
- ldi ZL, Low(0x15)
- ldi ZH, High(0x15)
- rcall DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- rjmp loc_23F
- loc_23F:
- lsl r17
- rol IOReg
- dec r16
- brne loc_234
- nop
- cbi DDRD, CARDIO
- cbi PORTD, CARDIO
- ret
- ; End of function Tx_etu32
- ; ===========================================================================
- ; Ins0B - send data to card from EEPROM buffer
- Ins0B:
- clr EEP_Pointer
- clr ZL
- rcall EEP_Read ; read byte from EEPROM @ ZL to IOReg
- mov r1, IOReg ; r1 = byte EEPROM:00 (length of data to send)
- inc EEP_Pointer
- loop_SendFromEE:
- mov ZL, EEP_Pointer
- rcall EEP_Read ; read byte from EEPROM @ ZL to IOReg
- rcall CardTx
- inc EEP_Pointer
- dec r1
- brne loop_SendFromEE ; loop to send data from EEPROM buffer
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins0B
- ; ===========================================================================
- ; Ins50 xx - receive xx bytes
- Ins5x:
- ld r17, X+ ; read length from program packet
- cpi r17, 0x78 ; limit = 78h (120) bytes
- brcs loc_257
- rjmp ExecProg ; execute next instruction in program packet
- ; ---------------------------------------------------------------------------
- loc_257: ; check if respone data pointer has reached 00D8 (max)
- cpi YL, 0xD8
- brcs loc_25A
- ldi YL, 0x60 ; init response data pointer to 0060
- loc_25A:
- mov r1, r17
- inc r1
- loop_rx50:
- rcall CardRx
- st Y+, IOReg
- inc ResponseLen
- cp YL, XL ; check if response data pointer has reached packet PC
- breq abort_rx50
- cpi YL, 0xD8 ; check if response data pointer has reached D8 (max)
- brcs loc_264
- ldi YL, 0x60 ; reset response data pointer to 0060
- loc_264:
- dec r1
- brne loop_rx50 ; loop to rx requested bytes
- abort_rx50: ; execute next instruction in program packet
- rjmp ExecProg
- ; End of function Ins5x
- ; ===========================================================================
- ; Ins60 xx - send xx bytes
- Ins6x:
- ld r17, X+ ; read length from program packet
- mov r1, r17
- inc r1
- loop_tx60: ; read byte to transmit from program packet
- ld IOReg, X+
- rcall CardTx
- dec r1
- brne loop_tx60 ; loop to tx bytes
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins6x
- ; ===========================================================================
- ; CmdF0 - send data in EEPROM buffer to PC
- CmdFx:
- clr ZL
- rcall EEP_Read ; read byte from EEPROM @ ZL to IOReg
- mov r1, IOReg
- rcall SendToPC
- inc ZL
- loop_sendEEtoPC: ; read byte from EEPROM @ ZL to IOReg
- rcall EEP_Read
- rcall SendToPC
- inc ZL
- dec r1
- brne loop_sendEEtoPC
- rjmp GetProgOrCmd ; Receive and process command/packet from PC
- ; End of function CmdFx
- ; ===========================================================================
- ; Ins0A - save data to EEPROM buffer
- Ins0A:
- ld r1, X+ ; read length from program packet
- clr ZL
- mov IOReg, r1
- rcall EEP_Write ; write length to EEPROM:00
- inc ZL
- rcall WriteXBufToEEP ; write r1 bytes from X to EEPROM @ ZL
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins0A
- ; ===========================================================================
- ; Ins0C - unused instruction
- Ins0C:
- rjmp ExecProg
- ; End of function Ins0C
- ; ===========================================================================
- ; CmdEx - unused command
- CmdEx:
- rjmp GetProgOrCmd
- ; End of function CmdEx
- ; ===========================================================================
- ; EEP_Read - read byte from EEPROM @ ZL to IOReg
- EEP_Read:
- sbic EECR, EEWE
- rjmp EEP_Read ; read byte from EEPROM @ ZL to IOReg
- out EEAR, ZL
- sbi EECR, EERE
- in IOReg, EEDR
- ret
- ; End of function EEP_Read
- ; ===========================================================================
- ; EEP_Write write byte from IOReg to EEPROM @ ZL
- EEP_Write:
- sbic EECR, EEWE
- rjmp EEP_Write ; write byte from IOReg to EEPROM @ ZL
- out EEAR, ZL
- out EEDR, IOReg
- sbi EECR, EEMWE
- sbi EECR, EEWE
- ret
- ; End of function EEP_Write
- ; ===========================================================================
- ; WriteXBufToEEP - write r1 bytes from X to EEPROM @ ZL
- WriteXBufToEEP:
- ld EEP_Pointer, X+
- rcall EEP_Read ; read byte from EEPROM @ ZL to IOReg
- cp IOReg, EEP_Pointer
- breq SkipWrite ; don't write value if it is already in EEP
- mov IOReg, EEP_Pointer
- rcall EEP_Write ; write byte from IOReg to EEPROM @ ZL
- SkipWrite:
- inc ZL
- dec r1
- brne WriteXBufToEEP ; write r1 bytes from X to EEPROM @ ZL
- ret
- ; End of function WriteXBufToEEP
- ; ===========================================================================
- ; rx_4 - Rx from card at speed based on start bit timing (nonstandard protocol added to ND13)
- rx_4:
- out TCCR1B, XH
- out TCCR1A, XH
- out TCNT1H, XH
- out TCNT1L, XH
- ldi r24, 1
- rcall EnableTimeout
- loc_2A0:
- sbis PIND, CARDIO
- rjmp loc_2A0
- cli
- rcall GetStartBit
- out TCCR1B, r24
- rcall EnableTimeout
- loc_2A6:
- sbis PIND, CARDIO
- rjmp loc_2A6
- out TCCR1B, XH
- cli
- in r24, TCNT1L
- in r25, TCNT1H
- sbiw r24, 0x10
- lsr r25
- ror r24
- rcall GetStartBit
- rcall sub_2C0
- ldi r16, 8
- loc_2B2:
- rcall sub_2BD
- clc
- sbis PIND, CARDIO
- sec
- rol IOReg
- dec r16
- brne loc_2B2
- rcall sub_2BD
- cbi DDRD, CARDIO
- cbi PORTD, CARDIO
- ret
- ; End of function rx_4
- ; ===========================================================================
- sub_2BD:
- mov ZL, r24
- mov ZH, r25
- rjmp DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- ; End of function sub_2BD
- ; ===========================================================================
- sub_2C0:
- mov ZL, r24
- mov ZH, r25
- sbiw ZL, 8
- lsr ZH
- ror ZL
- rjmp DelayCardCycles ; delay for total of 4 + Z card cycles, including ldi/call/ret
- ; End of function sub_2C0
- ; ===========================================================================
- ; unused transmit/receive speed
- nullsub_2:
- ret
- ; End of function nullsub_2
- ; ===========================================================================
- ; Ins0F - receive bytes from card and send to PC immediately (0F0000 = receive 1 byte)
- Ins0F:
- ld r11, X+ ; get high byte of requested length from program packet
- ld r10, X+ ; get low byte of requested length from program packet
- mov ZL, r10
- mov ZH, r11
- adiw ZL, 1
- loop_Ins0FRx:
- mov r10, ZL
- mov r11, ZH
- rcall rx_4
- rcall SendToPC
- mov ZL, r10
- mov ZH, r11
- sbiw ZL, 1
- brne loop_Ins0FRx
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins0F
- ; ===========================================================================
- ; Ins70 - ins timer test routine (custom - not in ND13/NDRS)
- Ins7x:
- clr r16
- out TCCR1A, r16
- out TCCR1B, r16
- out TCNT1H, r16
- out TCNT1L, r16
- mov r1, r16 ; this will be used to stop timer
- ldi r16, 1
- clr r17
- cbi PORTD, CARDIO ; set IO low
- sbi DDRD, CARDIO ; set port as output
- Ins70_TrigLoop:
- dec r17
- brne Ins70_TrigLoop
- sbi PORTD, CARDIO ; set IO high
- cbi DDRD, CARDIO ; set port as input (pull-up on)
- nop
- Ins80_waitLowIO: ; wait for IO to go low
- sbic PIND, CARDIO
- rjmp Ins80_waitLowIO
- out TCCR1B, r16 ; start Counter1
- Ins70_waitHighIO: ; wait for IO to go high
- sbis PIND, CARDIO
- rjmp Ins70_waitHighIO
- out TCCR1B, r1 ; stop Counter1
- in r16, TCNT1L ; read Timer1 value
- in r17, TCNT1H
- st Y+, r17 ; save Timer1 value in response data buffer
- st Y+, r16
- inc ResponseLen ; adjust ResponseLen for the two bytes added to response data
- inc ResponseLen
- rjmp ExecProg ; execute next instruction in program packet
- ; End of function Ins7x
- ; ---------------------------------------------------------------------------
- .exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement