Atmel AVR assembler

Have to write some AVR code and therefore have read the AVR Instruction Set manual and tried the assembler included in AVR studio. I think the used syntax is completely unusable, so I decided to write my own assembler. A very first version can be downloaded from:

ftp://137.193.64.130/pub/assembler/adela.zip

Maybe there are some AVR experts who can give some suggestions for an improvement or are even willing to do some testing.

The used syntax:

*******************************************************************
  • Instruction set *
*******************************************************************

add.b ri,rj ; i,j=0..31 ADD addc.b ri,rj ; i,j=0..31 ADC addq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1 ADIW and.b #imm8,rj ; j=16..31 ANDI and.b ri,rj ; i,j=0..31 AND asr.b #1,rj ; j=0..31 ASR bcc.b label ; C=0 BRCC bcs.b label ; C=1 BRCS beq.b label ; Z=1 BREQ bge.b label ; S=(N eor V) = 0 BRGE bhcc.b label ; H=0 BRHC bhcs.b label ; H=1 BRHS bhs.b label ; C=0 BRSH bic.b label ; I=0 BRID bis.b label ; I=1 BRIE blo.b label ; C=1 BRLO blt.b label ; S=(N eor V) = 1 BRLT bmi.b label ; N=1 BRMI bne.b label ; Z=0 BRNE bpl.b label ; N=0 BRPL btc.b label ; T=0 BRTC bts.b label ; T=1 BRTS bvc.b label ; V=0 BRVC bvs.b label ; V=1 BRVS br.w label RJMP bsr.w label RCALL cmp.b #imm8,rj ; j=16..31 CPI cmp.b ri,rj ; i,j=0..31 CP cmpc.b ri,rj ; i,j=0..31 CPC dec.b rj ; j=0..31 DEC eor.b ri,rj ; i,j=0..31 EOR fmuls.b ri,rj,r1|r0 ; i,j=16..23 FMULS fmulsu.b ri,rj,r1|r0 ; i,j=16..23 FMULSU fmulu.b ri,rj,r1|r0 ; i,j=16..23 FMUL halt BREAK inc.b rj ; j=0..31 INC jmp.l (*|r31|r30) EIJMP jmp.l label JMP jmp.w (r31|r30) IJMP jsr.l (*|r31|r30) EICALL jsr.l label CALL jsr.w (r31|r30) ICALL lsr.b #1,rj ; j=0..31 LSR move.b #imm8,rj ; j=16..31 LDI move.b ri,rj ; i,j=0..31 MOV move.b adr,rj ; j=0..31 LDS move.b ri,adr ; i=0..31 STS move.b (r27|r26),rj ; j=0..31 LD move.b imm6(r29|r28),rj ; j=0..31 LDD move.b imm6(r31|r30),rj ; j=0..31 LDD move.b ri, (r27|r26) ; i=0..31 ST move.b ri,imm6(r29|r28) ; i=0..31 STD move.b ri,imm6(r31|r30) ; i=0..31 STD move.b -(r27|r26),rj ; j=0..31 LD move.b -(r29|r28),rj ; j=0..31 LD move.b -(r31|r30),rj ; j=0..31 LD move.b ri,-(r27|r26) ; i=0..31 ST move.b ri,-(r29|r28) ; i=0..31 ST move.b ri,-(r31|r30) ; i=0..31 ST move.b (r27|r26)+,rj ; j=0..31 LD move.b (r29|r28)+,rj ; j=0..31 LD move.b (r31|r30)+,rj ; j=0..31 LD move.b ri,(r27|r26)+ ; i=0..31 ST move.b ri,(r29|r28)+ ; i=0..31 ST move.b ri,(r31|r30)+ ; i=0..31 ST move.b +(sp),rj ; j=0..31 POP move.b rj,(sp)- ; j=0..31 PUSH move.b ?adr6,rj ; adr6=0..63 j=0..31 IN move.b ri,?adr6 ; adr6=0..63 i=0..31 OUT move.bit rj[imm3],sr[6] ; j=0..31 BST move.bit sr[6],rj[imm3] ; j=0..31 BLD move.bit #0,sr[imm3] ; ITHSVNZC BCLR move.bit #1,sr[imm3] ; ITHSVNZC BSET move.bit #0,?adr5[imm3] ; adr5=0..31 CBI move.bit #1,?adr5[imm3] ; adr5=0..31 SBI move.w ri|rj,rk|rm ; j,m=0,2,..,30 i=j+1 k=m+1 MOVW movePM.b (r31|r30),r0 LPM movePM.b (r31|r30),rj ; j=0..31 LPM movePM.b (r31|r30)+,rj ; j=0..31 LPM movePM.b (*|r31|r30),r0 ELPM movePM.b (*|r31|r30),rj ; j=0..31 ELPM movePM.b (*|r31|r30)+,rj ; j=0..31 ELPM muls.b ri,rj,r1|r0 ; i,j=16..31 MULS mulsu.b ri,rj,r1|r0 ; i,j=16..23 MULSU mulu.b ri,rj,r1|r0 ; i,j=0..31 MUL neg.b rj ; j=0..31 NEG nop NOP not.b rj ; j=0..31 COM or.b #imm8,rj ; j=16..31 ORI or.b ri,rj ; i,j=0..31 OR prog SPM rocr.b #1,rj ; j=0..31 ROR rol.b #4,rj ; j=0..31 SWAP ror.b #4,rj ; j=0..31 SWAP rte RETI rts RET skipeq.b ri,rj ; i,j=0..31 CPSE skipeq.bit #0,?adr5[imm3] ; adr5=0..31 SBIC skipeq.bit #0,rj[imm3] ; j=0..31 SBRC skipeq.bit #1,?adr5[imm3] ; adr5=0..31 SBIS skipeq.bit #1,rj[imm3] ; j=0..31 SBRS sleep SLEEP sub.b #imm8,rj ; j=16..31 SUBI sub.b ri,rj ; i,j=0..31 SUB subc.b #imm8,rj ; j=16..31 SBCI subc.b ri,rj ; i,j=0..31 SBC subq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1 SBIW wdog_reset WDR

BRBC -> branch Befehle CBR -> and.b CLR -> eor.b CLC,CLH,CLI,CLN,CLS,CLT,CLV,CLZ -> move.bit LSL -> add.b ROL -> addc.b SBR -> or.b SEC,SEH,SEI,SEN,SES,SET,SEV,SEZ -> move.bit SER -> or.b TST -> and.b

*******************************************************************
  • Opcode list *
*******************************************************************

0000 0000 0000 0000 nop

0000 0001 jjjj iiii move.w ri|rj,rk|rm ; j,m=0,2,..,30 i=j+1 k=m+1 0000 0010 jjjj iiii muls.b ri,rj,r1|r0 ; i,j=16..31 0000 0011 0jjj 0iii mulsu.b ri,rj,r1|r0 ; i,j=16..23 0000 0011 0jjj 1iii fmulu.b ri,rj,r1|r0 ; i,j=16..23 0000 0011 1jjj 0iii fmuls.b ri,rj,r1|r0 ; i,j=16..23 0000 0011 1jjj 1iii fmulsu.b ri,rj,r1|r0 ; i,j=16..23 0000 01ij jjjj iiii cmpc.b ri,rj ; i,j=0..31 0000 10ij jjjj iiii subc.b ri,rj ; i,j=0..31 0000 11ij jjjj iiii add.b ri,rj ; i,j=0..31

0001 00ij jjjj iiii skipeq.b ri,rj ; i,j=0..31

0001 01ij jjjj iiii cmp.b ri,rj ; i,j=0..31 0001 10ji jjjj iiii sub.b ri,rj ; i,j=0..31 0001 11ij jjjj iiii addc.b ri,rj ; i,j=0..31

0010 00ij jjjj iiii and.b ri,rj ; i,j=0..31

0010 01ij jjjj iiii eor.b ri,rj ; i,j=0..31 0010 10ji jjjj iiii or.b ri,rj ; i,j=0..31 0010 11ij jjjj iiii move.b ri,rj ; i,j=0..31

0011 #### jjjj #### cmp.b #imm8,rj ; j=16..31

0100 #### jjjj #### subc.b #imm8,rj ; j=16..31 0101 #### jjjj #### sub.b #imm8,rj ; j=16..31 0110 #### jjjj #### or.b #imm8,rj ; j=16..31 0111 #### jjjj #### and.b #imm8,rj ; j=16..31

10#0 ##0j jjjj 0### move.b imm6(r31|r30),rj ; j=0..31

10#0 ##0j jjjj 1### move.b imm6(r29|r28),rj ; j=0..31 10#0 ##1i iiii 0### move.b ri,imm6(r31|r30) ; i=0..31 10#0 ##1i iiii 1### move.b ri,imm6(r29|r28) ; i=0..31

1001 000j jjjj 0000 move.b adr,rj ; j=0..31 #### #### #### ####

1001 000j jjjj 0001 move.b (r31|r30)+,rj ; j=0..31 1001 000j jjjj 0010 move.b -(r31|r30),rj ; j=0..31 1001 000j jjjj 0100 movePM.b (r31|r30),rj ; j=0..31 1001 000j jjjj 0101 movePM.b (r31|r30)+,rj ; j=0..31 1001 000j jjjj 0110 movePM.b (*|r31|r30),rj ; j=0..31 1001 000j jjjj 0111 movePM.b (*|r31|r30)+,rj ; j=0..31 1001 000j jjjj 1001 move.b (r29|r28)+,rj ; j=0..31 1001 000j jjjj 1010 move.b -(r29|r28),rj ; j=0..31 1001 000j jjjj 1100 move.b (r27|r26),rj ; j=0..31 1001 000j jjjj 1101 move.b (r27|r26)+,rj ; j=0..31 1001 000j jjjj 1110 move.b -(r27|r26),rj ; j=0..31 1001 000j jjjj 1111 move.b +(sp),rj ; j=0..31 1001 001i iiii 0000 move.b ri,adr ; i=0..31 #### #### #### #### 1001 001i iiii 0001 move.b ri,(r31|r30)+ ; i=0..31 1001 001i iiii 0010 move.b ri,-(r31|r30) ; i=0..31 1001 001i iiii 1001 move.b ri,(r29|r28)+ ; i=0..31 1001 001i iiii 1100 move.b ri,(r27|r26) ; i=0..31 1001 001i iiii 1101 move.b ri,(r27|r26)+ ; i=0..31 1001 001i iiii 1010 move.b ri,-(r29|r28) ; i=0..31 1001 001i iiii 1110 move.b ri,-(r27|r26) ; i=0..31 1001 001j jjjj 1111 move.b rj,(sp)- ; j=0..31

1001 010j jjjj 0000 not.b rj ; j=0..31

1001 010j jjjj 0001 neg.b rj ; j=0..31 1001 010j jjjj 0010 rol.b #4,rj ; j=0..31 1001 010j jjjj 0010 ror.b #4,rj ; j=0..31 1001 010j jjjj 0011 inc.b rj ; j=0..31 1001 010j jjjj 0101 asr.b #1,rj ; j=0..31 1001 010j jjjj 0110 lsr.b #1,rj ; j=0..31 1001 010j jjjj 0111 rocr.b #1,rj ; j=0..31

1001 0100 0### 1000 move.bit #1,sr[imm3] ; ITHSVNZC

1001 0100 1### 1000 move.bit #0,sr[imm3] ; ITHSVNZC 1001 0101 0000 1000 rts 1001 0101 0001 1000 rte 1001 0101 1000 1000 sleep 1001 0101 1001 1000 halt 1001 0101 1010 1000 wdog_reset 1001 0101 1100 1000 movePM.b (r31|r30),r0 1001 0101 1101 1000 movePM.b (*|r31|r30),r0 1001 0101 1110 1000 prog

1001 0100 0000 1001 jmp.w (r31|r30)

1001 0101 0001 1001 jsr.l (*|r31|r30) 1001 0100 0001 1001 jmp.l (*|r31|r30) 1001 0101 0000 1001 jsr.w (r31|r30)

1001 010j jjjj 1010 dec.b rj ; j=0..31

1001 010# #### 110# jmp.l label #### #### #### #### 1001 010# #### 111# jsr.l label #### #### #### ####

1001 0110 ##jj #### addq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1

1001 0111 ##jj #### subq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1 1001 1000 jjjj j### move.bit #0,?adr5[imm3] ; adr5=0..31 1001 1001 jjjj j### skipeq.bit #0,?adr5[imm3] ; adr5=0..31 1001 1010 jjjj j### move.bit #1,?adr5[imm3] ; adr5=0..31 1001 1011 jjjj j### skipeq.bit #1,?adr5[imm3] ; adr5=0..31 1001 11ij jjjj iiii mulu.b ri,rj,r1|r0 ; i,j=0..31

1011 0##j jjjj #### move.b ?adr6,rj ; adr6=0..63 j=0..31

1011 1##i iiii #### move.b ri,?adr6 ; adr6=0..63 i=0..31

1100 #### #### #### br.w label

1101 #### #### #### bsr.w label

1110 #### jjjj #### move.b #imm8,rj ; j=16..31

1111 00## #### #000 bcs.b label ; C=1 1111 00## #### #000 blo.b label ; C=1 1111 00## #### #001 beq.b label ; Z=1 1111 00## #### #010 bmi.b label ; N=1 1111 00## #### #011 bvs.b label ; V=1 1111 00## #### #100 blt.b label ; S=(N eor V) = 1 1111 00## #### #101 bhcs.b label ; H=1 1111 00## #### #110 bts.b label ; T=1 1111 00## #### #111 bis.b label ; I=1 1111 01## #### #000 bcc.b label ; c=0 1111 01## #### #000 bhs.b label ; C=0 1111 01## #### #001 bne.b label ; Z=0 1111 01## #### #010 bpl.b label ; N=0 1111 01## #### #011 bvc.b label ; V=0 1111 01## #### #100 bge.b label ; S=(N eor V) = 0 1111 01## #### #101 bhcc.b label ; H=0 1111 01## #### #110 btc.b label ; T=0 1111 01## #### #111 bic.b label ; I=0 1111 100j jjjj 0### move.bit sr[6],rj[imm3] ; j=0..31 1111 101j jjjj 0### move.bit rj[imm3],sr[6] ; j=0..31 1111 110j jjjj 0### skipeq.bit #0,rj[imm3] ; j=0..31 1111 111j jjjj 0### skipeq.bit #1,rj[imm3] ; j=0..31

*******************************************************************

  • example program for STK500 (Mega32) *
*******************************************************************

; connect port B to LED port_b_dir=$17 port_b_dat=$18

move.b #$ff,r16 move.b r16,?port_b_dir eor.b r0,r0 move.b #$7f,r16 move.b #$3f,r17 move.b #$1f,r18 move.b #$0f,r19

loop: move.b r16,?port_b_dat move.b #255,r20 _10: dec.b r20 bne.b _10 move.b r17,?port_b_dat move.b #128,r20 _20: dec.b r20 bne.b _20 move.b r18,?port_b_dat move.b #64,r20 _30: dec.b r20 bne.b _30 move.b r19,?port_b_dat move.b #32,r20 _40: dec.b r20 bne.b _40 dec.b r4 bne.b loop add.b r16,r16 addc.b r0,r16 add.b r17,r17 addc.b r0,r17 add.b r18,r18 addc.b r0,r18 add.b r19,r19 addc.b r0,r19 br.w loop

Reply to
Herbert Kleebauer
Loading thread data ...

"Herbert Kleebauer" schreef in bericht news: snipped-for-privacy@unibwm.de...

I fail to see what's so unusable about the AVR assembler syntax. Your effort resembles 68000 code. Writing a good assembler takes time, are you writing it from scratch? I think that's a complete wombat; better invest in learning the AVR syntax, which is really not that difficult and not unusual.

Also nice for the one that has to maintain your code, long after you've left. Are you going to write an assembler for every uC or uP come across, redefining it's assembly language every time?

Reply to
Jeroen

What makes an assembler a "good assembler"? I think a good assembler should allow you to write bug free code in a minimum of time. And to do this you don't need a powerful macro system or a high speed assembler or an integrated development system but you surely need a well designed instruction syntax. And to write a simple assembler (without a macro system and which is neither optimized for speed nor size) isn't a big deal. Yes, you have to spend a few hours to write the assembler, but this will save you much more time when you write and debug your assembler programs.

Not every uP I come across, but every uP I have to program in assembler and which uses an awful syntax like the Intel x86 or the Atmel AVR (I liked the PDP11 or 68k syntax).

Reply to
Herbert Kleebauer

A good assembler should use the mnemonics and rules specified by the device manufacturer, where there is such a specification. It should assemble, with the minimum possible modification, code intended for other assemblers targeting the same part.

An assembler that doesn't follow the device manufacturer's rules is a very low-level HLL, not an assembler.

Reply to
larwe

... snip ...

And then every time you want to use some code from outside, or from the chip manufacturer, you have to laboriously transcribe it into your 'better' mnemnonics and syntax, without error. Similarly for the joker out there in either space or time who has to use your special code.

I strongly advise letting the manufacturer set the assembly language. Even small deviations can have evil consequences, as I have found out in the past.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

That's the nice thing on assembly programming: you can assembly and disassembly it to convert the source to an different assembler. The AVR simulator has no problem to disassemble and simulate the code generated by my assembler. But it seems even Atmel is aware that they use a crazy syntax because any disassembled instruction gets an comment which explains what this instruction does. I prefer a syntax where you directly see what the instruction does without needing a comment.

When small deviations can have evil consequences, then most probably small deviations can also have positive consequences. Why not try to start an evolution to the better side?

Reply to
Herbert Kleebauer

Great logic. Let's use a bad design because we then at least are compatible to the other bad designs! Why not use a superior design so you are better than all this compatible bad designs?

I think this is a definition of an assembler which we hadn't here in a.l.a till now (and we had many different definitions). So, if the manufacturer decides to change his rules, then all the existing assemblers becomes a low-level HLL and some low-level HLL's (which already used the new rules of the manufacturer) becomes an assembler. A real consistent definition of an assembler.

Reply to
Herbert Kleebauer

If you really want to use a different assembler syntax, rather write software that translates your syntax into the manufacturer specified syntax. Keeping all the symbols as symbols and not translating them to numbers. You then can use a standard assembler for the device to generate your executable.

Regards Anton Erasmus

Reply to
Anton Erasmus

wrote: | > What makes an assembler a "good assembler"? I think a good assembler | > should allow you to write bug free code in a minimum of time. And | A good assembler should use the mnemonics and rules specified by the | device manufacturer, where there is such a specification. It should | assemble, with the minimum possible modification, code intended for | other assemblers targeting the same part. | An assembler that doesn't follow the device manufacturer's rules is a | very low-level HLL, not an assembler.

I can't agree, CPU/MC-producers actually don't care about sense-making mnemonics.

And like Herbert, I also use 'my very own' syntax to at least try to cover all MC/CPU I ever worked on with one cross-compatible language.

Of course, x86-coders are not familiar with Herbert's 68000 styled or my Zilog-styled syntax. Therefore I use it only personal and don't try to make it a public need.

But Herbert's conversion is pure logical based, even I use hardware ordered register-numbers and have the size-casts in/at the operands.

__ wolfgang

Reply to
wolfgang kern

I can't see any advantage in generating an intermediate source file but a big disadvantage: for debugging you need a list file and it doesn't help if you get a list file from the "standard" assembler when you have written the source in a different syntax.

But how are AVR programs debugged at all? Are there AVR versions which have support for hardware breakpoints or at least single step interrupts? The only alternative I see at the moment is, to add an assembler directive which automatically inserts a call to a debug routine after each instruction. But this would double the size of the code to debug.

Reply to
Herbert Kleebauer

As to debugging. Reserve at least a single pin which can be set and reset, or pulsed by yoour software. A pulse lets you figure out that a certain position in the code has been passed. The next step is to serially shift out data through this pin. With some more resources, use the SPI or the serial as long as they don't interfere with your code. With some other pins to spare you can write parallel. I made a hardware decoder

formatting link
that lets one decode whatver parallel data.

Once you have your hardware running, have some debug commands in your communication. The next step with realtime data is a multichannel DAC on a plugable pcb that lets you write parallel datastreams in realtime to an oscilloscope.

And yes, a code change means a new upload of your code to the cpu.

Rene

--
Ing.Buero R.Tschaggelar - http://www.ibrtses.com
& commercial newsgroups - http://www.talkto.net
Reply to
Rene Tschaggelar

Most platforms have rather good C compilers, which is mostly much more efficient in terms of development time and often more than good enough in terms of execution time. When I started ARM programming, I didn't have to care about Assembler syntax at all. Of course, Assembler parts can be linked in where needed, but these parts are mostly small compared to the size of the whole system.

I don't think writing a complete new assembler for a given platform being incompatible to the vendor standards makes sense. Using C saves more time and costs.

My AVR projects are all >95% C code.

Mit freundlichen Grüßen

Frank-Christian Krügel

Reply to
Frank-Christian Kruegel

That's probably true but irrelevant. Assembly language is defined by the CPU vendor. Anything you do that deviate from the vendor's spec is writing a new language.

This is a semantic issue. I can't call the OP's product an assembler because although what goes in looks like assembly language, it is not in fact assembly language for any known processor.

Reply to
larwe
[snip...snip...]

While I admire your purity of spirit, please do not ever use your "improved" assembler on any project involving another programmer or, most especially, on any project that may require life cycle support for decades.

Maintenance programmers have a hard enough time as it is. Being introduced to a project that needs "a few small changes" and being told that, "Oh by the way, the guy that wrote this 17 years ago made up his own assembler directives" is not a happy thought. Have a heart.

--
Rich Webb   Norfolk, VA
Reply to
Rich Webb

You're the one with flawed logic here. You say that the vendor's syntax is hard for you to work with. Fine, write a new language with syntax that doesn't offend you. But don't call it an AVR assembler. Saying it's an AVR assembler implies that it assembles AVR assembly language, the syntax of which was defined by Atmel.

If you're trying to write a Spanish-to-English translator, and you decide that the syntax of Spanish is inconveniently difficult, and you wind up writing an Esperanto-to-English translator, well that might be a useful product in some scenario, but it is not accepting Spanish input so don't advertise it as such.

What you have written is some kind of pseudo-assembler. It might save a small amount of time for *you* to work with this tool *alone*, but for normal AVR users who have to think about maintainability, multi-member teams, integration with other toolsets, etc. it is a time sink.

Reply to
larwe

Op 23 Jul 2005 11:29:27 -0700 schreef snipped-for-privacy@larwe.com:

You've nevwe programmed in Forth, did you? An assembler in Forth can use the same syntax as a 'normal' assembler, by using the order: opcode, destiny, source like (I assume) the one of AVR does. But it is simpler to implement, and easier to understand (for a Forth programmer) in the order: source, destiny, opcode. Postfix so to speak. I know lots of people that use this syntax and they can program each and every program with it.

Coos

--
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
Reply to
Coos Haak

So by your definition of syntax equivalency, Yoda speaks normal English?

Reply to
larwe

Aside from the typical pin twiddling, etc. in hardware, the AVR Assembler has a very good simulator. With it, you can develop and test most of a project without a hardware platform, tweak the inputs in bizarre ways, and see the effects on every register bit.

It's not a substitute for testing on the platform, but it gets through the early stages and logic issues much faster with excellent visibility.

Richard

Reply to
Richard H.

repied: | > I can't agree, | > CPU/MC-producers actually don't care about sense-making mnemonics. | | That's probably true but irrelevant. Assembly language is defined by | the CPU vendor. Anything you do that deviate from the vendor's spec is | writing a new language.

That's new to me, AT&T/gas/gcc/.. use Intel/AMD recommeded style? | This is a semantic issue. I can't call the OP's product an assembler | because although what goes in looks like assembly language, it is not | in fact assembly language for any known processor.

There are that many ASM-dialects around, that any attempt to create one more logical syntax count for itself, regardless of portability. I'm not familiar with Herbert's way either, but I can see the idea.

If you like to see a few options of my disassembler:

formatting link
,[codesnips],[HEXTUTOR]

__ wolfgang

Reply to
wolfgang kern

What he could do, without raising hackles everywhere, is write a set of macros for m4 to process his version of assembly language into the generally accepted source. m4 is generally known, and available.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.