> I got this code of the net ... Looks like you got about what you paid for it. I don't know who this Eric Smith guy is that claims to have written it, but I would stay away from anything else that has his name on it. There are too many individual things I don't like in that code to list here, so here are just a few highlights: > ; Copyright 1997 Eric Smith Consider this a warning message. > ringadv macro ptr,base,size > local pow2,aligned,bit,val > pow2 SET !(size&(size-1)) > aligned SET pow2&&((base&(size-1))==0) > > if aligned > val set size > bit set 0 > while val>1 > bit set bit+1 > val set val>>1 > endw > endif > > incf ptr,F > > if (aligned&&!(base&(1< bcf ptr,bit > else > movf ptr,W > xorlw base+size > movlw base > btfsc STATUS,Z > movwf ptr > endif > endm Good thing it's so well commented! > ;------------------------------------------------------------------------- ---- > ; ram > ;------------------------------------------------------------------------- ---- > > org rambase > > ; interrupt state save > irqw: res 1 ; must be in same loc in both banks Actually it needs to be in all *4* banks, because that's how many the 16F877 has, which this code was apparently written for given the LIST directive above. > ramb2 equ ($ + 80h) This is apparently an attempt to make sure the offset of IRQW is reserved in all banks, although doing this without a comment is just plain irresponsible. Apparently his strategy is to start using other banks at RAMB2, which will guarantee that the offset of IRQW is not used in the other banks. However, this assumes that the general registers start at the same offset in all banks, which is not the case for many PICs. On the 18F877 general registers start at offset 10h in banks 2 and 3 instead of 20h as in banks 0 and 1. That will cause wasted space in this case. On other PICs, it could cause collision with special function registers. The immediately following code defines his variables, although there is not a single comment explaining what any of them are for. I won't bother repeat his mess here. > org 4 > > movwf irqw > swapf irqw,F > swapf STATUS,W > bcf STATUS,RP0 > movwf irqstat > movf FSR,W > movwf irqfsr > > btfsc PIR1,RCIF > call rxint This needlessly uses up an additional call stack location that will not be available anywhere else an interrupt could occur. It is a good idea to keep stack useage within an interrupt to the minimum you can manage. > btfsc PIR1,TXIF > call txint > ;------------------------------------------------------------------------- ---- > ; UART receive interrupt > ;------------------------------------------------------------------------- ---- > > rxint: movf rx_ring_cnt,W ; is buffer full? > xorlw rx_ring_size > btfsc STATUS,Z > goto rx_overrun > > movf rx_ring_ip,W ; store character in buffer > movwf FSR > movf RCREG,W > movwf INDF > > incf rx_ring_cnt,F ; increment count > > ringadv rx_ring_ip,rx_ring,rx_ring_size ; advance pointer > > return > > rx_overrun: > movf RCREG,W ; read and discard character > return Finally a few comments, although there is a lot more that could use explaning. This routine will only work if everything goes right. If a UART overrun ever occurs, it will never recover. There is also no handling of framing errors. I could go on, but that would be pointless. Just because something is on the web doesn't make it correct. If you want to see properly written interrupt and UART routines, go to http://www.embedinc.com/pic and check out the QQQ_INTR.ASPIC and QQQ_UART.ASPIC template modules in particular. There are also a bunch of FIFO manipulation macros and lots of other stuff in STD.INS.ASPIC. And, the license is much less restrictive in that you are allowed to use this code in a commercial product at no charge. ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.