added protocol stack: pjrc, vusb
This commit is contained in:
		
							parent
							
								
									5552b5afea
								
							
						
					
					
						commit
						acc974c64b
					
				
					 55 changed files with 836 additions and 1832 deletions
				
			
		
							
								
								
									
										750
									
								
								vusb/usbdrv/usbdrvasm128.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										750
									
								
								vusb/usbdrv/usbdrvasm128.inc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,750 @@
 | 
			
		|||
/* Name: usbdrvasm128.inc
 | 
			
		||||
 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
 | 
			
		||||
 * Author: Christian Starkjohann
 | 
			
		||||
 * Creation Date: 2008-10-11
 | 
			
		||||
 * Tabsize: 4
 | 
			
		||||
 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
 | 
			
		||||
 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
 | 
			
		||||
 * This Revision: $Id: usbdrvasm128.inc 758 2009-08-06 10:12:54Z cs $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
 | 
			
		||||
 * appropriate implementation!
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
General Description:
 | 
			
		||||
This file is the 12.8 MHz version of the USB driver. It is intended for use
 | 
			
		||||
with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed
 | 
			
		||||
calibration range of the oscillator, almost all AVRs can reach this frequency.
 | 
			
		||||
This version contains a phase locked loop in the receiver routine to cope with
 | 
			
		||||
slight clock rate deviations of up to +/- 1%.
 | 
			
		||||
 | 
			
		||||
See usbdrv.h for a description of the entire driver.
 | 
			
		||||
 | 
			
		||||
LIMITATIONS
 | 
			
		||||
===========
 | 
			
		||||
Although it may seem very handy to save the crystal and use the internal
 | 
			
		||||
RC oscillator of the CPU, this method (and this module) has some serious
 | 
			
		||||
limitations:
 | 
			
		||||
(1) The guaranteed calibration range of the oscillator is only 8.1 MHz.
 | 
			
		||||
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
 | 
			
		||||
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
 | 
			
		||||
the write procedure is timed from the RC oscillator.
 | 
			
		||||
(3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked
 | 
			
		||||
if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may
 | 
			
		||||
cause problems with old hubs which delay SE0 by up to one cycle.
 | 
			
		||||
(4) Code size is much larger than that of the other modules.
 | 
			
		||||
 | 
			
		||||
Since almost all of this code is timing critical, don't change unless you
 | 
			
		||||
really know what you are doing! Many parts require not only a maximum number
 | 
			
		||||
of CPU cycles, but even an exact number of cycles!
 | 
			
		||||
 | 
			
		||||
Implementation notes:
 | 
			
		||||
======================
 | 
			
		||||
min frequency: 67 cycles for 8 bit -> 12.5625 MHz
 | 
			
		||||
max frequency: 69.286 cycles for 8 bit -> 12.99 MHz
 | 
			
		||||
nominal frequency: 12.77 MHz ( = sqrt(min * max))
 | 
			
		||||
 | 
			
		||||
sampling positions: (next even number in range [+/- 0.5])
 | 
			
		||||
cycle index range: 0 ... 66
 | 
			
		||||
bits:
 | 
			
		||||
.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125
 | 
			
		||||
[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59]
 | 
			
		||||
 | 
			
		||||
bit number:     0   1   2   3   4   5   6   7
 | 
			
		||||
spare cycles    1   2   1   2   1   1   1   0
 | 
			
		||||
 | 
			
		||||
operations to perform:      duration cycle
 | 
			
		||||
                            ----------------
 | 
			
		||||
    eor     fix, shift          1 -> 00
 | 
			
		||||
    andi    phase, USBMASK      1 -> 08
 | 
			
		||||
    breq    se0                 1 -> 16 (moved to 11)
 | 
			
		||||
    st      y+, data            2 -> 24, 25
 | 
			
		||||
    mov     data, fix           1 -> 33
 | 
			
		||||
    ser     data                1 -> 41
 | 
			
		||||
    subi    cnt, 1              1 -> 49
 | 
			
		||||
    brcs    overflow            1 -> 50
 | 
			
		||||
 | 
			
		||||
layout of samples and operations:
 | 
			
		||||
[##] = sample bit
 | 
			
		||||
<##> = sample phase
 | 
			
		||||
*##* = operation
 | 
			
		||||
 | 
			
		||||
0:  *00* [01]  02   03   04  <05>  06   07
 | 
			
		||||
1:  *08* [09]  10   11   12  <13>  14   15  *16*
 | 
			
		||||
2:  [17]  18   19   20  <21>  22   23
 | 
			
		||||
3:  *24* *25* [26]  27   28   29  <30>  31   32
 | 
			
		||||
4:  *33* [34]  35   36   37  <38>  39   40
 | 
			
		||||
5:  *41* [42]  43   44   45  <46>  47   48
 | 
			
		||||
6:  *49* *50* [51]  52   53   54  <55>  56   57   58
 | 
			
		||||
7:  [59]  60   61   62  <63>  64   65   66
 | 
			
		||||
*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* we prefer positive expressions (do if condition) instead of negative
 | 
			
		||||
 * (skip if condition), therefore use defines for skip instructions:
 | 
			
		||||
 */
 | 
			
		||||
#define ifioclr sbis
 | 
			
		||||
#define ifioset sbic
 | 
			
		||||
#define ifrclr  sbrs
 | 
			
		||||
#define ifrset  sbrc
 | 
			
		||||
 | 
			
		||||
/* The registers "fix" and "data" swap their meaning during the loop. Use
 | 
			
		||||
 * defines to keep their name constant.
 | 
			
		||||
 */
 | 
			
		||||
#define fix     x2
 | 
			
		||||
#define data    x1
 | 
			
		||||
#undef phase        /* phase has a default definition to x4 */
 | 
			
		||||
#define phase   x3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
USB_INTR_VECTOR:
 | 
			
		||||
;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0
 | 
			
		||||
    push    YL              ;2 push only what is necessary to sync with edge ASAP
 | 
			
		||||
    in      YL, SREG        ;1
 | 
			
		||||
    push    YL              ;2
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
; Synchronize with sync pattern:
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
 | 
			
		||||
;sync up with J to K edge during sync pattern -- use fastest possible loops
 | 
			
		||||
;The first part waits at most 1 bit long since we must be in sync pattern.
 | 
			
		||||
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
 | 
			
		||||
;waitForJ, ensure that this prerequisite is met.
 | 
			
		||||
waitForJ:
 | 
			
		||||
    inc     YL
 | 
			
		||||
    sbis    USBIN, USBMINUS
 | 
			
		||||
    brne    waitForJ        ; just make sure we have ANY timeout
 | 
			
		||||
waitForK:
 | 
			
		||||
;The following code results in a sampling window of 1/4 bit which meets the spec.
 | 
			
		||||
    sbis    USBIN, USBMINUS
 | 
			
		||||
    rjmp    foundK
 | 
			
		||||
    sbis    USBIN, USBMINUS
 | 
			
		||||
    rjmp    foundK
 | 
			
		||||
    sbis    USBIN, USBMINUS
 | 
			
		||||
    rjmp    foundK
 | 
			
		||||
    sbis    USBIN, USBMINUS
 | 
			
		||||
    rjmp    foundK
 | 
			
		||||
    sbis    USBIN, USBMINUS ;[0]
 | 
			
		||||
    rjmp    foundK          ;[1]
 | 
			
		||||
#if USB_COUNT_SOF
 | 
			
		||||
    lds     YL, usbSofCount
 | 
			
		||||
    inc     YL
 | 
			
		||||
    sts     usbSofCount, YL
 | 
			
		||||
#endif  /* USB_COUNT_SOF */
 | 
			
		||||
#ifdef USB_SOF_HOOK
 | 
			
		||||
    USB_SOF_HOOK
 | 
			
		||||
#endif
 | 
			
		||||
    rjmp    sofError
 | 
			
		||||
 | 
			
		||||
foundK:
 | 
			
		||||
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
 | 
			
		||||
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
 | 
			
		||||
;are cycles from center of first sync (double K) bit after the instruction
 | 
			
		||||
    push    YH                  ;[2]
 | 
			
		||||
    lds     YL, usbInputBufOffset;[4]
 | 
			
		||||
    clr     YH                  ;[6]
 | 
			
		||||
    subi    YL, lo8(-(usbRxBuf));[7]
 | 
			
		||||
    sbci    YH, hi8(-(usbRxBuf));[8]
 | 
			
		||||
 | 
			
		||||
    sbis    USBIN, USBMINUS     ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5]
 | 
			
		||||
    rjmp    haveTwoBitsK        ;[10]
 | 
			
		||||
    pop     YH                  ;[11] undo the push from before
 | 
			
		||||
    rjmp    waitForK            ;[13] this was not the end of sync, retry
 | 
			
		||||
haveTwoBitsK:
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
; push more registers and initialize values while we sample the first bits:
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
#define fix     x2
 | 
			
		||||
#define data    x1
 | 
			
		||||
 | 
			
		||||
    push    shift               ;[12]
 | 
			
		||||
    push    x1                  ;[14]
 | 
			
		||||
    push    x2                  ;[16]
 | 
			
		||||
    ldi     shift, 0x80         ;[18] prevent bit-unstuffing but init low bits to 0
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5]
 | 
			
		||||
    ori     shift, 1<<0         ;[02]
 | 
			
		||||
    push    x3                  ;[03]
 | 
			
		||||
    push    cnt                 ;[05]
 | 
			
		||||
    push    r0                  ;[07]
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[09] <--- bit 1
 | 
			
		||||
    ori     shift, 1<<1         ;[10]
 | 
			
		||||
    ser     fix                 ;[11]
 | 
			
		||||
    ldi     cnt, USB_BUFSIZE    ;[12]
 | 
			
		||||
    mov     data, shift         ;[13]
 | 
			
		||||
    lsl     shift               ;[14]
 | 
			
		||||
    nop2                        ;[15]
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[17] <--- bit 2
 | 
			
		||||
    ori     data, 3<<2          ;[18] store in bit 2 AND bit 3
 | 
			
		||||
    eor     shift, data         ;[19] do nrzi decoding
 | 
			
		||||
    andi    data, 1<<3          ;[20]
 | 
			
		||||
    in      phase, USBIN        ;[21] <- phase
 | 
			
		||||
    brne    jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1
 | 
			
		||||
    nop                         ;[23]
 | 
			
		||||
    rjmp    entryAfterClr       ;[24]
 | 
			
		||||
jumpToEntryAfterSet:
 | 
			
		||||
    rjmp    entryAfterSet       ;[24]
 | 
			
		||||
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
; Receiver loop (numbers in brackets are cycles within byte after instr)
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
#undef  fix
 | 
			
		||||
#define  fix    x1
 | 
			
		||||
#undef  data
 | 
			
		||||
#define data    x2
 | 
			
		||||
 | 
			
		||||
bit7IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[62] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[63]
 | 
			
		||||
    in      phase, USBIN        ;[64] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 7       ;[65]
 | 
			
		||||
    nop                         ;[66]
 | 
			
		||||
;;;;rjmp    bit0AfterSet        ; -> [00] == [67] moved block up to save jump
 | 
			
		||||
bit0AfterSet:
 | 
			
		||||
    eor     fix, shift          ;[00]
 | 
			
		||||
#undef  fix
 | 
			
		||||
#define fix     x2
 | 
			
		||||
#undef  data
 | 
			
		||||
#define data    x1  /* we now have result in data, fix is reset to 0xff */
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[01] <--- sample 0
 | 
			
		||||
    rjmp    bit0IsClr           ;[02]
 | 
			
		||||
    andi    shift, ~(7 << 0)    ;[03]
 | 
			
		||||
    breq    unstuff0s           ;[04]
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase
 | 
			
		||||
    rjmp    bit1AfterSet        ;[06]
 | 
			
		||||
unstuff0s:
 | 
			
		||||
    in      phase, USBIN        ;[06] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 0)      ;[07]
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[00]
 | 
			
		||||
    ifioset USBIN, USBPLUS      ;[01]
 | 
			
		||||
    rjmp    bit0IsClr           ;[02] executed if first expr false or second true
 | 
			
		||||
se0AndStore:                    ; executed only if both bits 0
 | 
			
		||||
    st      y+, x1              ;[15/17] cycles after start of byte
 | 
			
		||||
    rjmp    se0                 ;[17/19]
 | 
			
		||||
 | 
			
		||||
bit0IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[04] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[05]
 | 
			
		||||
    in      phase, USBIN        ;[06] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 0       ;[07]
 | 
			
		||||
bit1AfterClr:
 | 
			
		||||
    andi    phase, USBMASK      ;[08]
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[09] <--- sample 1
 | 
			
		||||
    rjmp    bit1IsSet           ;[10]
 | 
			
		||||
    breq    se0AndStore         ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0
 | 
			
		||||
    andi    shift, ~(7 << 1)    ;[12]
 | 
			
		||||
    in      phase, USBIN        ;[13] <- phase
 | 
			
		||||
    breq    unstuff1c           ;[14]
 | 
			
		||||
    rjmp    bit2AfterClr        ;[15]
 | 
			
		||||
unstuff1c:
 | 
			
		||||
    andi    fix, ~(1 << 1)      ;[16]
 | 
			
		||||
    nop2                        ;[08]
 | 
			
		||||
    nop2                        ;[10]
 | 
			
		||||
bit1IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[12] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[13]
 | 
			
		||||
    in      phase, USBIN        ;[14] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 1       ;[15]
 | 
			
		||||
    nop                         ;[16]
 | 
			
		||||
bit2AfterSet:
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[17] <--- sample 2
 | 
			
		||||
    rjmp    bit2IsClr           ;[18]
 | 
			
		||||
    andi    shift, ~(7 << 2)    ;[19]
 | 
			
		||||
    breq    unstuff2s           ;[20]
 | 
			
		||||
    in      phase, USBIN        ;[21] <- phase
 | 
			
		||||
    rjmp    bit3AfterSet        ;[22]
 | 
			
		||||
unstuff2s:
 | 
			
		||||
    in      phase, USBIN        ;[22] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 2)      ;[23]
 | 
			
		||||
    nop2                        ;[16]
 | 
			
		||||
    nop2                        ;[18]
 | 
			
		||||
bit2IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[20] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[21]
 | 
			
		||||
    in      phase, USBIN        ;[22] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 2       ;[23]
 | 
			
		||||
bit3AfterClr:
 | 
			
		||||
    st      y+, data            ;[24]
 | 
			
		||||
entryAfterClr:
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[26] <--- sample 3
 | 
			
		||||
    rjmp    bit3IsSet           ;[27]
 | 
			
		||||
    andi    shift, ~(7 << 3)    ;[28]
 | 
			
		||||
    breq    unstuff3c           ;[29]
 | 
			
		||||
    in      phase, USBIN        ;[30] <- phase
 | 
			
		||||
    rjmp    bit4AfterClr        ;[31]
 | 
			
		||||
unstuff3c:
 | 
			
		||||
    in      phase, USBIN        ;[31] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 3)      ;[32]
 | 
			
		||||
    nop2                        ;[25]
 | 
			
		||||
    nop2                        ;[27]
 | 
			
		||||
bit3IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[29] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[30]
 | 
			
		||||
    in      phase, USBIN        ;[31] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 3       ;[32]
 | 
			
		||||
bit4AfterSet:
 | 
			
		||||
    mov     data, fix           ;[33] undo this move by swapping defines
 | 
			
		||||
#undef  fix
 | 
			
		||||
#define fix     x1
 | 
			
		||||
#undef  data
 | 
			
		||||
#define data    x2
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[34] <--- sample 4
 | 
			
		||||
    rjmp    bit4IsClr           ;[35]
 | 
			
		||||
    andi    shift, ~(7 << 4)    ;[36]
 | 
			
		||||
    breq    unstuff4s           ;[37]
 | 
			
		||||
    in      phase, USBIN        ;[38] <- phase
 | 
			
		||||
    rjmp    bit5AfterSet        ;[39]
 | 
			
		||||
unstuff4s:
 | 
			
		||||
    in      phase, USBIN        ;[39] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 4)      ;[40]
 | 
			
		||||
    nop2                        ;[33]
 | 
			
		||||
    nop2                        ;[35]
 | 
			
		||||
bit4IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[37] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[38]
 | 
			
		||||
    in      phase, USBIN        ;[39] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 4       ;[40]
 | 
			
		||||
bit5AfterClr:
 | 
			
		||||
    ser     data                ;[41]
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[42] <--- sample 5
 | 
			
		||||
    rjmp    bit5IsSet           ;[43]
 | 
			
		||||
    andi    shift, ~(7 << 5)    ;[44]
 | 
			
		||||
    breq    unstuff5c           ;[45]
 | 
			
		||||
    in      phase, USBIN        ;[46] <- phase
 | 
			
		||||
    rjmp    bit6AfterClr        ;[47]
 | 
			
		||||
unstuff5c:
 | 
			
		||||
    in      phase, USBIN        ;[47] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 5)      ;[48]
 | 
			
		||||
    nop2                        ;[41]
 | 
			
		||||
    nop2                        ;[43]
 | 
			
		||||
bit5IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[45] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[46]
 | 
			
		||||
    in      phase, USBIN        ;[47] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 5       ;[48]
 | 
			
		||||
bit6AfterSet:
 | 
			
		||||
    subi    cnt, 1              ;[49]
 | 
			
		||||
    brcs    jumpToOverflow      ;[50]
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[51] <--- sample 6
 | 
			
		||||
    rjmp    bit6IsClr           ;[52]
 | 
			
		||||
    andi    shift, ~(3 << 6)    ;[53]
 | 
			
		||||
    cpi     shift, 2            ;[54]
 | 
			
		||||
    in      phase, USBIN        ;[55] <- phase
 | 
			
		||||
    brlt    unstuff6s           ;[56]
 | 
			
		||||
    rjmp    bit7AfterSet        ;[57]
 | 
			
		||||
 | 
			
		||||
jumpToOverflow:
 | 
			
		||||
    rjmp    overflow
 | 
			
		||||
 | 
			
		||||
unstuff6s:
 | 
			
		||||
    andi    fix, ~(1 << 6)      ;[50]
 | 
			
		||||
    lpm                         ;[51]
 | 
			
		||||
bit6IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[54] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[55]
 | 
			
		||||
    in      phase, USBIN        ;[56] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 6       ;[57]
 | 
			
		||||
    nop                         ;[58]
 | 
			
		||||
bit7AfterClr:
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[59] <--- sample 7
 | 
			
		||||
    rjmp    bit7IsSet           ;[60]
 | 
			
		||||
    andi    shift, ~(1 << 7)    ;[61]
 | 
			
		||||
    cpi     shift, 4            ;[62]
 | 
			
		||||
    in      phase, USBIN        ;[63] <- phase
 | 
			
		||||
    brlt    unstuff7c           ;[64]
 | 
			
		||||
    rjmp    bit0AfterClr        ;[65] -> [00] == [67]
 | 
			
		||||
unstuff7c:
 | 
			
		||||
    andi    fix, ~(1 << 7)      ;[58]
 | 
			
		||||
    nop                         ;[59]
 | 
			
		||||
    rjmp    bit7IsSet           ;[60]
 | 
			
		||||
 | 
			
		||||
bit7IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[62] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[63]
 | 
			
		||||
    in      phase, USBIN        ;[64] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 7       ;[65]
 | 
			
		||||
    nop                         ;[66]
 | 
			
		||||
;;;;rjmp    bit0AfterClr        ; -> [00] == [67] moved block up to save jump
 | 
			
		||||
bit0AfterClr:
 | 
			
		||||
    eor     fix, shift          ;[00]
 | 
			
		||||
#undef  fix
 | 
			
		||||
#define fix     x2
 | 
			
		||||
#undef  data
 | 
			
		||||
#define data    x1  /* we now have result in data, fix is reset to 0xff */
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[01] <--- sample 0
 | 
			
		||||
    rjmp    bit0IsSet           ;[02]
 | 
			
		||||
    andi    shift, ~(7 << 0)    ;[03]
 | 
			
		||||
    breq    unstuff0c           ;[04]
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase
 | 
			
		||||
    rjmp    bit1AfterClr        ;[06]
 | 
			
		||||
unstuff0c:
 | 
			
		||||
    in      phase, USBIN        ;[06] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 0)      ;[07]
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[00]
 | 
			
		||||
    ifioset USBIN, USBPLUS      ;[01]
 | 
			
		||||
    rjmp    bit0IsSet           ;[02] executed if first expr false or second true
 | 
			
		||||
    rjmp    se0AndStore         ;[03] executed only if both bits 0
 | 
			
		||||
bit0IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[04] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[05]
 | 
			
		||||
    in      phase, USBIN        ;[06] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 0       ;[07]
 | 
			
		||||
bit1AfterSet:
 | 
			
		||||
    andi    shift, ~(7 << 1)    ;[08] compensated by "ori shift, 1<<1" if bit1IsClr
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[09] <--- sample 1
 | 
			
		||||
    rjmp    bit1IsClr           ;[10]
 | 
			
		||||
    breq    unstuff1s           ;[11]
 | 
			
		||||
    nop2                        ;[12] do not check for SE0 if bit 0 was 1
 | 
			
		||||
    in      phase, USBIN        ;[14] <- phase (one cycle too late)
 | 
			
		||||
    rjmp    bit2AfterSet        ;[15]
 | 
			
		||||
unstuff1s:
 | 
			
		||||
    in      phase, USBIN        ;[13] <- phase
 | 
			
		||||
    andi    fix, ~(1 << 1)      ;[14]
 | 
			
		||||
    lpm                         ;[07]
 | 
			
		||||
    nop2                        ;[10]
 | 
			
		||||
bit1IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[12] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[13]
 | 
			
		||||
    in      phase, USBIN        ;[14] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 1       ;[15]
 | 
			
		||||
    nop                         ;[16]
 | 
			
		||||
bit2AfterClr:
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[17] <--- sample 2
 | 
			
		||||
    rjmp    bit2IsSet           ;[18]
 | 
			
		||||
    andi    shift, ~(7 << 2)    ;[19]
 | 
			
		||||
    breq    unstuff2c           ;[20]
 | 
			
		||||
    in      phase, USBIN        ;[21] <- phase
 | 
			
		||||
    rjmp    bit3AfterClr        ;[22]
 | 
			
		||||
unstuff2c:
 | 
			
		||||
    in      phase, USBIN        ;[22] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 2)      ;[23]
 | 
			
		||||
    nop2                        ;[16]
 | 
			
		||||
    nop2                        ;[18]
 | 
			
		||||
bit2IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[20] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[21]
 | 
			
		||||
    in      phase, USBIN        ;[22] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 2       ;[23]
 | 
			
		||||
bit3AfterSet:
 | 
			
		||||
    st      y+, data            ;[24]
 | 
			
		||||
entryAfterSet:
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[26] <--- sample 3
 | 
			
		||||
    rjmp    bit3IsClr           ;[27]
 | 
			
		||||
    andi    shift, ~(7 << 3)    ;[28]
 | 
			
		||||
    breq    unstuff3s           ;[29]
 | 
			
		||||
    in      phase, USBIN        ;[30] <- phase
 | 
			
		||||
    rjmp    bit4AfterSet        ;[31]
 | 
			
		||||
unstuff3s:
 | 
			
		||||
    in      phase, USBIN        ;[31] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 3)      ;[32]
 | 
			
		||||
    nop2                        ;[25]
 | 
			
		||||
    nop2                        ;[27]
 | 
			
		||||
bit3IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[29] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[30]
 | 
			
		||||
    in      phase, USBIN        ;[31] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 3       ;[32]
 | 
			
		||||
bit4AfterClr:
 | 
			
		||||
    mov     data, fix           ;[33] undo this move by swapping defines
 | 
			
		||||
#undef  fix
 | 
			
		||||
#define fix     x1
 | 
			
		||||
#undef  data
 | 
			
		||||
#define data    x2
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[34] <--- sample 4
 | 
			
		||||
    rjmp    bit4IsSet           ;[35]
 | 
			
		||||
    andi    shift, ~(7 << 4)    ;[36]
 | 
			
		||||
    breq    unstuff4c           ;[37]
 | 
			
		||||
    in      phase, USBIN        ;[38] <- phase
 | 
			
		||||
    rjmp    bit5AfterClr        ;[39]
 | 
			
		||||
unstuff4c:
 | 
			
		||||
    in      phase, USBIN        ;[39] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 4)      ;[40]
 | 
			
		||||
    nop2                        ;[33]
 | 
			
		||||
    nop2                        ;[35]
 | 
			
		||||
bit4IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[37] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[38]
 | 
			
		||||
    in      phase, USBIN        ;[39] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 4       ;[40]
 | 
			
		||||
bit5AfterSet:
 | 
			
		||||
    ser     data                ;[41]
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[42] <--- sample 5
 | 
			
		||||
    rjmp    bit5IsClr           ;[43]
 | 
			
		||||
    andi    shift, ~(7 << 5)    ;[44]
 | 
			
		||||
    breq    unstuff5s           ;[45]
 | 
			
		||||
    in      phase, USBIN        ;[46] <- phase
 | 
			
		||||
    rjmp    bit6AfterSet        ;[47]
 | 
			
		||||
unstuff5s:
 | 
			
		||||
    in      phase, USBIN        ;[47] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << 5)      ;[48]
 | 
			
		||||
    nop2                        ;[41]
 | 
			
		||||
    nop2                        ;[43]
 | 
			
		||||
bit5IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[45] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[46]
 | 
			
		||||
    in      phase, USBIN        ;[47] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 5       ;[48]
 | 
			
		||||
bit6AfterClr:
 | 
			
		||||
    subi    cnt, 1              ;[49]
 | 
			
		||||
    brcs    overflow            ;[50]
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[51] <--- sample 6
 | 
			
		||||
    rjmp    bit6IsSet           ;[52]
 | 
			
		||||
    andi    shift, ~(3 << 6)    ;[53]
 | 
			
		||||
    cpi     shift, 2            ;[54]
 | 
			
		||||
    in      phase, USBIN        ;[55] <- phase
 | 
			
		||||
    brlt    unstuff6c           ;[56]
 | 
			
		||||
    rjmp    bit7AfterClr        ;[57]
 | 
			
		||||
unstuff6c:
 | 
			
		||||
    andi    fix, ~(1 << 6)      ;[50]
 | 
			
		||||
    lpm                         ;[51]
 | 
			
		||||
bit6IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[54] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[55]
 | 
			
		||||
    in      phase, USBIN        ;[56] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << 6       ;[57]
 | 
			
		||||
bit7AfterSet:
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[59] <--- sample 7
 | 
			
		||||
    rjmp    bit7IsClr           ;[60]
 | 
			
		||||
    andi    shift, ~(1 << 7)    ;[61]
 | 
			
		||||
    cpi     shift, 4            ;[62]
 | 
			
		||||
    in      phase, USBIN        ;[63] <- phase
 | 
			
		||||
    brlt    unstuff7s           ;[64]
 | 
			
		||||
    rjmp    bit0AfterSet        ;[65] -> [00] == [67]
 | 
			
		||||
unstuff7s:
 | 
			
		||||
    andi    fix, ~(1 << 7)      ;[58]
 | 
			
		||||
    nop                         ;[59]
 | 
			
		||||
    rjmp    bit7IsClr           ;[60]
 | 
			
		||||
 | 
			
		||||
macro POP_STANDARD ; 14 cycles
 | 
			
		||||
    pop     r0
 | 
			
		||||
    pop     cnt
 | 
			
		||||
    pop     x3
 | 
			
		||||
    pop     x2
 | 
			
		||||
    pop     x1
 | 
			
		||||
    pop     shift
 | 
			
		||||
    pop     YH
 | 
			
		||||
    endm
 | 
			
		||||
macro POP_RETI     ; 5 cycles
 | 
			
		||||
    pop     YL
 | 
			
		||||
    out     SREG, YL
 | 
			
		||||
    pop     YL
 | 
			
		||||
    endm
 | 
			
		||||
 | 
			
		||||
#include "asmcommon.inc"
 | 
			
		||||
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
; Transmitting data
 | 
			
		||||
;----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
txByteLoop:
 | 
			
		||||
txBitloop:
 | 
			
		||||
stuffN1Delay:                   ;     [03]
 | 
			
		||||
    ror     shift               ;[-5] [11] [63]
 | 
			
		||||
    brcc    doExorN1            ;[-4]      [64]
 | 
			
		||||
    subi    x3, 1               ;[-3]
 | 
			
		||||
    brne    commonN1            ;[-2]
 | 
			
		||||
    lsl     shift               ;[-1] compensate ror after rjmp stuffDelay
 | 
			
		||||
    nop                         ;[00] stuffing consists of just waiting 8 cycles
 | 
			
		||||
    rjmp    stuffN1Delay        ;[01] after ror, C bit is reliably clear
 | 
			
		||||
 | 
			
		||||
sendNakAndReti:
 | 
			
		||||
    ldi     cnt, USBPID_NAK ;[-19]
 | 
			
		||||
    rjmp    sendCntAndReti  ;[-18]
 | 
			
		||||
sendAckAndReti:
 | 
			
		||||
    ldi     cnt, USBPID_ACK ;[-17]
 | 
			
		||||
sendCntAndReti:
 | 
			
		||||
    mov     r0, cnt         ;[-16]
 | 
			
		||||
    ldi     YL, 0           ;[-15] R0 address is 0
 | 
			
		||||
    ldi     YH, 0           ;[-14]
 | 
			
		||||
    ldi     cnt, 2          ;[-13]
 | 
			
		||||
;   rjmp    usbSendAndReti      fallthrough
 | 
			
		||||
 | 
			
		||||
; USB spec says:
 | 
			
		||||
; idle = J
 | 
			
		||||
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
 | 
			
		||||
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
 | 
			
		||||
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
 | 
			
		||||
 | 
			
		||||
;usbSend:
 | 
			
		||||
;pointer to data in 'Y'
 | 
			
		||||
;number of bytes in 'cnt' -- including sync byte
 | 
			
		||||
;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt]
 | 
			
		||||
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
 | 
			
		||||
usbSendAndReti:
 | 
			
		||||
    in      x2, USBDDR          ;[-10] 10 cycles until SOP
 | 
			
		||||
    ori     x2, USBMASK         ;[-9]
 | 
			
		||||
    sbi     USBOUT, USBMINUS    ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups)
 | 
			
		||||
    out     USBDDR, x2          ;[-6] <--- acquire bus
 | 
			
		||||
    in      x1, USBOUT          ;[-5] port mirror for tx loop
 | 
			
		||||
    ldi     shift, 0x40         ;[-4] sync byte is first byte sent (we enter loop after ror)
 | 
			
		||||
    ldi     x2, USBMASK         ;[-3]
 | 
			
		||||
doExorN1:
 | 
			
		||||
    eor     x1, x2              ;[-2] [06] [62]
 | 
			
		||||
    ldi     x3, 6               ;[-1] [07] [63]
 | 
			
		||||
commonN1:
 | 
			
		||||
stuffN2Delay:
 | 
			
		||||
    out     USBOUT, x1          ;[00] [08] [64] <--- set bit
 | 
			
		||||
    ror     shift               ;[01]
 | 
			
		||||
    brcc    doExorN2            ;[02]
 | 
			
		||||
    subi    x3, 1               ;[03]
 | 
			
		||||
    brne    commonN2            ;[04]
 | 
			
		||||
    lsl     shift               ;[05] compensate ror after rjmp stuffDelay
 | 
			
		||||
    rjmp    stuffN2Delay        ;[06] after ror, C bit is reliably clear
 | 
			
		||||
doExorN2:
 | 
			
		||||
    eor     x1, x2              ;[04] [12]
 | 
			
		||||
    ldi     x3, 6               ;[05] [13]
 | 
			
		||||
commonN2:
 | 
			
		||||
    nop2                        ;[06] [14]
 | 
			
		||||
    subi    cnt, 171            ;[08] [16] trick: (3 * 171) & 0xff = 1
 | 
			
		||||
    out     USBOUT, x1          ;[09] [17] <--- set bit
 | 
			
		||||
    brcs    txBitloop           ;[10]      [27] [44]
 | 
			
		||||
 | 
			
		||||
stuff6Delay:
 | 
			
		||||
    ror     shift               ;[45] [53]
 | 
			
		||||
    brcc    doExor6             ;[46]
 | 
			
		||||
    subi    x3, 1               ;[47]
 | 
			
		||||
    brne    common6             ;[48]
 | 
			
		||||
    lsl     shift               ;[49] compensate ror after rjmp stuffDelay
 | 
			
		||||
    nop                         ;[50] stuffing consists of just waiting 8 cycles
 | 
			
		||||
    rjmp    stuff6Delay         ;[51] after ror, C bit is reliably clear
 | 
			
		||||
doExor6:
 | 
			
		||||
    eor     x1, x2              ;[48] [56]
 | 
			
		||||
    ldi     x3, 6               ;[49]
 | 
			
		||||
common6:
 | 
			
		||||
stuff7Delay:
 | 
			
		||||
    ror     shift               ;[50] [58]
 | 
			
		||||
    out     USBOUT, x1          ;[51] <--- set bit
 | 
			
		||||
    brcc    doExor7             ;[52]
 | 
			
		||||
    subi    x3, 1               ;[53]
 | 
			
		||||
    brne    common7             ;[54]
 | 
			
		||||
    lsl     shift               ;[55] compensate ror after rjmp stuffDelay
 | 
			
		||||
    rjmp    stuff7Delay         ;[56] after ror, C bit is reliably clear
 | 
			
		||||
doExor7:
 | 
			
		||||
    eor     x1, x2              ;[54] [62]
 | 
			
		||||
    ldi     x3, 6               ;[55]
 | 
			
		||||
common7:
 | 
			
		||||
    ld      shift, y+           ;[56]
 | 
			
		||||
    nop                         ;[58]
 | 
			
		||||
    tst     cnt                 ;[59]
 | 
			
		||||
    out     USBOUT, x1          ;[60] [00]<--- set bit
 | 
			
		||||
    brne    txByteLoop          ;[61] [01]
 | 
			
		||||
;make SE0:
 | 
			
		||||
    cbr     x1, USBMASK         ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles]
 | 
			
		||||
    lds     x2, usbNewDeviceAddr;[03]
 | 
			
		||||
    lsl     x2                  ;[05] we compare with left shifted address
 | 
			
		||||
    subi    YL, 2 + 0           ;[06] Only assign address on data packets, not ACK/NAK in r0
 | 
			
		||||
    sbci    YH, 0               ;[07]
 | 
			
		||||
    out     USBOUT, x1          ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
 | 
			
		||||
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
 | 
			
		||||
;set address only after data packet was sent, not after handshake
 | 
			
		||||
    breq    skipAddrAssign      ;[01]
 | 
			
		||||
    sts     usbDeviceAddr, x2   ; if not skipped: SE0 is one cycle longer
 | 
			
		||||
skipAddrAssign:
 | 
			
		||||
;end of usbDeviceAddress transfer
 | 
			
		||||
    ldi     x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
 | 
			
		||||
    USB_STORE_PENDING(x2)       ;[04]
 | 
			
		||||
    ori     x1, USBIDLE         ;[05]
 | 
			
		||||
    in      x2, USBDDR          ;[06]
 | 
			
		||||
    cbr     x2, USBMASK         ;[07] set both pins to input
 | 
			
		||||
    mov     x3, x1              ;[08]
 | 
			
		||||
    cbr     x3, USBMASK         ;[09] configure no pullup on both pins
 | 
			
		||||
    lpm                         ;[10]
 | 
			
		||||
    lpm                         ;[13]
 | 
			
		||||
    out     USBOUT, x1          ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
 | 
			
		||||
    out     USBDDR, x2          ;[17] <-- release bus now
 | 
			
		||||
    out     USBOUT, x3          ;[18] <-- ensure no pull-up resistors are active
 | 
			
		||||
    rjmp    doReturn
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
The following PHP script generates a code skeleton for the receiver routine:
 | 
			
		||||
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
function printCmdBuffer($thisBit)
 | 
			
		||||
{
 | 
			
		||||
global $cycle;
 | 
			
		||||
 | 
			
		||||
    $nextBit = ($thisBit + 1) % 8;
 | 
			
		||||
    $s = ob_get_contents();
 | 
			
		||||
    ob_end_clean();
 | 
			
		||||
    $s = str_replace("#", $thisBit, $s);
 | 
			
		||||
    $s = str_replace("@", $nextBit, $s);
 | 
			
		||||
    $lines = explode("\n", $s);
 | 
			
		||||
    for($i = 0; $i < count($lines); $i++){
 | 
			
		||||
        $s = $lines[$i];
 | 
			
		||||
        if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){
 | 
			
		||||
            $c = $cycle + (int)$regs[1];
 | 
			
		||||
            $s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s);
 | 
			
		||||
        }
 | 
			
		||||
        if(strlen($s) > 0)
 | 
			
		||||
            echo "$s\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function printBit($isAfterSet, $bitNum)
 | 
			
		||||
{
 | 
			
		||||
    ob_start();
 | 
			
		||||
    if($isAfterSet){
 | 
			
		||||
?>
 | 
			
		||||
    ifioclr USBIN, USBMINUS     ;[00] <--- sample
 | 
			
		||||
    rjmp    bit#IsClr           ;[01]
 | 
			
		||||
    andi    shift, ~(7 << #)    ;[02]
 | 
			
		||||
    breq    unstuff#s           ;[03]
 | 
			
		||||
    in      phase, USBIN        ;[04] <- phase
 | 
			
		||||
    rjmp    bit@AfterSet        ;[05]
 | 
			
		||||
unstuff#s:
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << #)      ;[06]
 | 
			
		||||
    nop2                        ;[-1]
 | 
			
		||||
    nop2                        ;[01]
 | 
			
		||||
bit#IsClr:
 | 
			
		||||
    ifrset  phase, USBMINUS     ;[03] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[04]
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << #       ;[06]
 | 
			
		||||
<?php
 | 
			
		||||
    }else{
 | 
			
		||||
?>
 | 
			
		||||
    ifioset USBIN, USBMINUS     ;[00] <--- sample
 | 
			
		||||
    rjmp    bit#IsSet           ;[01]
 | 
			
		||||
    andi    shift, ~(7 << #)    ;[02]
 | 
			
		||||
    breq    unstuff#c           ;[03]
 | 
			
		||||
    in      phase, USBIN        ;[04] <- phase
 | 
			
		||||
    rjmp    bit@AfterClr        ;[05]
 | 
			
		||||
unstuff#c:
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase (one cycle too late)
 | 
			
		||||
    andi    fix, ~(1 << #)      ;[06]
 | 
			
		||||
    nop2                        ;[-1]
 | 
			
		||||
    nop2                        ;[01]
 | 
			
		||||
bit#IsSet:
 | 
			
		||||
    ifrclr  phase, USBMINUS     ;[03] check phase only if D- changed
 | 
			
		||||
    lpm                         ;[04]
 | 
			
		||||
    in      phase, USBIN        ;[05] <- phase (one cycle too late)
 | 
			
		||||
    ori     shift, 1 << #       ;[06]
 | 
			
		||||
<?php
 | 
			
		||||
    }
 | 
			
		||||
    printCmdBuffer($bitNum);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59);
 | 
			
		||||
for($i = 0; $i < 16; $i++){
 | 
			
		||||
    $bit = $i % 8;
 | 
			
		||||
    $emitClrCode = ($i + (int)($i / 8)) % 2;
 | 
			
		||||
    $cycle = $bitStartCycles[$bit];
 | 
			
		||||
    if($emitClrCode){
 | 
			
		||||
        printf("bit%dAfterClr:\n", $bit);
 | 
			
		||||
    }else{
 | 
			
		||||
        printf("bit%dAfterSet:\n", $bit);
 | 
			
		||||
    }
 | 
			
		||||
    ob_start();
 | 
			
		||||
    echo "    *****                       ;[-1]\n";
 | 
			
		||||
    printCmdBuffer($bit);
 | 
			
		||||
    printBit(!$emitClrCode, $bit);
 | 
			
		||||
    if($i == 7)
 | 
			
		||||
        echo "\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
*****************************************************************************/
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue