Evan, The instruction RETOLD seems to be confusing you. If it is, there is good explanation and examples in Microchip Technology Inc. DS00556 manual. What the instruction does is to load the WE rag with the literal value in the instruction and return to the address on the stack. Your program puts something in the WE rag then calls Uneatable. The ADDED instruction adds the WE value to the low byte of the program counter. Before this instruction, the pal contained the low byte if the next instruction, after the ADDED instruction, the low byte contains the address of the sine with a offset into the table. So is W reg had a 3 in it, the next instruction will be the forth RETLW instruction and the w reg will contain 0x098h. The RETLW instruction will return to the address on the stack, the instruction after the CALL sinetable. My assembler does not have a retw instruction as the example on the web site does. and I am not familiar with the dt directive you use. What you want is 64 instructions of RETLW H:00' RETLW H:03' RETLW H:06' and so on for the 64 values of the sine table. The input to the routine requires that the 'temp' reg contain the number of degrees (but instead of 360 degrees in a circle, there are 256 of these degrees in a circle. Decimal 32 in 'temp' reg will return sine of 45 real degrees) The sine is returned in the temp register but in a odd way. Bit 7 is used as a negative flag and bits 6 through 0 representing the value from 0 to 1, or a fraction of 1. Normally when a byte represents a number between 0 and 1, bit 7 has the value of 1/2 or 0.5, bit 6 1/4 or 0.25 bit 5 1/8 pr 0.125. But in this case, because of the need for using bit 7 as a negative flag, the rest of the bits represent twice their normal values. So the sine is the 'temp' register left shifted one bit with the old bit 7 signifying if it is positive or negative.. Now to answer the question "Why don't this work?:" It is like Mr. Ringer. Most Sundays when we would go to church we would stop at the crossroads and pick up Mr. Ringer and give him a ride to church. When the collection plate was passed during the service I noticed that sometimes he would put a dollar in the collection plate then take out for dollars, as if he was making change for a five dollar bill. Later in life I realized that Mr. Ringer had given much to the community and the church in earlier years and everyone knew he was "making change" but as he was sometimes very short on money and too proud to ask for charity, every one was happy that a small part of the collection was going directly to where it was needed. Just as Mr. Ringer put money in the collection plate when he had it, you return from the sinetable routine with the RETLW pulling a return address off the stack. And then at the end of the program you try that again with the RETLW 0 instruction. But there was nothing on the stack. And your program, unlike Mr. Ringer, goes to Hell! Just as a note, unless you want to return with a value in the W reg, just a RETURN instruction would be less confusing.. Also you assume that the 'zero' register contains 0. You should put a 0 in it before starting to use it. Maybe your program should have the following form. ;MAIN PROGRAM setup the option registers and such put 0 in 'zero' reg goto start START put a value in ';temp' reg call GETSINE HERE goto HERE loop on this instruction. GETSINE > MOVWF temp > BTFSC temp,6 > SUBWF zero, W > ANDLW 07fh > CALL SINETBL > BTFSC temp, 7 > SUBWF zero, w > MOVWF temp ; Move result to temp RETURN ;return to instruction after GETSINE was called By starting with different values in the 'temp' register, you will see the different sine values emerge. Bill ----- Original Message ----- From: "Evan" To: Sent: Thursday, January 12, 2006 3:08 AM Subject: [PIC] 16f84 sine table app > > Hi, > > I am trying to convert Eric Smith's sine function ( > http://www.brouhaha.com/~eric/pic/sine.html ) on a 16f84. I have included > the > code below. > > It does not seem to work. When I step through the code in MPLABS SINETBL > is > called, but returns after the ADDWF. Then the code reaches the final RETLW > and > goes back to CALL SINETBL, but does not call it, and ends up in a loop. > > Any help appreciated. > > > temp EQU 0xC > zero EQU 0xd > > ; Set up: PORTA = Input PORTB = Output > ; The bitstring to be checked will be entered in PORTA > BSF STATUS, RP0 ; Select bank 1 > MOVLW B'11111111' ; 1 to set input > MOVWF PORTA ; Set PORTA as Input > MOVLW B'00000000' ; 0 to set output > MOVWF PORTB ; Set PORTB as Output > BCF STATUS, RP0 ; Select bank 0 > > ;*********************************************************** > > GOTO START > > ;*********************************************************** > ; SUBROUTINE SECTION > SINETBL > > ADDWF PCL, F ; or PCL? > dt 000h,003h,006h,009h,00ch,010h,013h,016h > dt 019h,01ch,01fh,022h,025h,028h,02bh,02eh > dt 031h,033h,036h,039h,03ch,03fh,041h,044h > dt 047h,049h,04ch,04eh,051h,053h,055h,058h > dt 05ah,05ch,05eh,060h,062h,064h,066h,068h > dt 06ah,06bh,06dh,06fh,070h,071h,073h,074h > dt 075h,076h,078h,079h,07ah,07ah,07bh,07ch > dt 07dh,07dh,07eh,07eh,07eh,07fh,07fh,07fh > dt 07fh > > > ;*********************************************************** > ; MAIN PROGRAM > > > START > MOVF PORTA, 1 ; Read the contents of PORTA into itself > MOVF PORTA, W ; Move contents of PORTA into W > MOVWF temp > BTFSC temp,6 > SUBWF zero, W > ANDLW 07fh > CALL SINETBL > BTFSC temp, 7 > SUBWF zero, w > MOVWF temp ; Move result to temp > MOVF PORTB, w ; Move result from temp to PORTB > RETLW 0 > > > END ; End program > > > > Regards, > Evan > > ----- End forwarded message ----- > > > > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist