On Thu, 27 Feb 2003, Scott Dattalo wrote: > > On Thu, 27 Feb 2003, Wouter van Ooijen wrote: > > > > > coding challenge: > > > > > > - 14-bit core PIC > > > - forget about paging and banking issues > > > - smallest possible code > > > - assembler > > > > > > TMR1 is a free-running 16-bit timer that can be read as two file > > > registers TMR1H and TMR1L. Note that there is no buffering in the > > > reading, so for 00FF you might read FF as low byte and then 01 as high > > > byte (just after the rollover). I'm surprised no one noticed a really glaring error in the code that I posted. The low byte of the saved TMR was not adjusted if a rollover was detected. Here (I think) is a correction: movf TMR1L,W ; grab TMR1 movwf temp incf TMR1H,W ;Assume that the low byte is about to rollover movwf TMR1H_buff ; Check for rollover. If the low byte increments from ff to 00 then ; there's a rollover and we need to advance the high byte by one count ; However, the low byte may be any value between 0xfd and 0xff at ; the point we read it above. If it was then, well we have a rollover. ; One way to capture this condition is by monitoring the upper bit ; of TMR1L. If it is high when we read it above, and low when we read ; it next (just below), then a rollover has occurred. In fact, we ; have about 255 cycles to capture this rollover condition - ; anywhere from the first read being 0x80 to 0xff and the second ; read being 00 to 0x7f. If interrupts are enabled, then we need ; to ensure no isr takes longer than 255 cycles. movf TMR1L,W ; Read the low value again movwf TMR1L_buff ; and save it btfsc temp,7 ;If TMR1L on the first read was < 0x80 btfsc TMR1L_buff,7 ;or if the both reads are between decf TMR1H_buff,F ;0x80 and 0xff then leave the high byte alone The last three instructions will decrement the TMR1H value if the first read of TMR1L was less than 0x80 or if the two reads of TMR1L are both between 0x80 and 0xff. Note that the decrement just cancels the increment from above. The only condition that the decrement will not be executed is if the first read of TMR1L is between 0x80 and 0xff *and* the second read of TMR1L is between 0 and 0x7f - in other words, if TMR1L has rolled over. Here's a solution that saves one instruction: rlf TMR1L,W ; read the msb of tmr1L --> Carry incf TMR1H,W ;Assume that the low byte is about to rollover movwf TMR1H_buff movf TMR1L,W movwf TMR1L_buff skpnc ;If TMR1L on the first read was < 0x80 btfsc TMR1L_buff,7 ;or if the both reads are between decf TMR1H_buff,F ;0x80 and 0xff then leave the high byte alone 8 instructions. Any more optimizations? Scott -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body