Calling PASM functions with spin?
eagletalontim
Posts: 1,399
I am still tinkering with my touchscreen code and was wondering if it was possible to call a PASM function from spin? Since PASM runs faster and I would like to have the screen run faster, I hope to convert as much as I can to PASM. The only way I can think of doing this is to have a cog running the PASM that listens for a change in a global variable. Once spin updates that global variable, the PASM will match the variable with one of the functions to run. I am in the beginning stages of learning PASM so hopefully I can get this working. I have been reading others code to get an idea of what I am getting into....yep..this will take awhile!
I am trying to make my first PASM function to clear the screen and set it to a specific color. I am not sure of the best method to do this, but this is what I have written :
I am trying to make my first PASM function to clear the screen and set it to a specific color. I am not sure of the best method to do this, but this is what I have written :
'init stuff before PUB Main ILI9325.Draw(0,0,240,320) repeat 76800 ' draws a box 10x10 pixels in white. ILI9325.Pixel($00,$FF) 'Clears the screen and makes it blue ' and the some of the screen functions PUB Pixel(VH,VL) ' send out a pixel, high byte then low byte Lcd_Write_Data(VH,VL) PRI LCD_Writ_Bus(VH,VL) OUTA[7..0] := VL OUTA[15..8] := VH WriteLow ' write pin low WriteHigh ' toggle write pin PRI Lcd_Write_Com(VH,VL) RSLow LCD_Writ_Bus(VH,VL) PRI Lcd_Write_Data(VH,VL) RSHigh LCD_Writ_Bus(VH,VL) PRI RSLow ' RS pin outa[RS] := 0 PRI RSHigh outa[RS] := 1 ' PRI WriteLow outa[LCD_WR] := 0 ' PRI WriteHigh outa[LCD_WR] := 1
Comments
I see something similar to this in every PASM example and have read up on each of the PASM commands, but still don't understand what exactly it does.
It's like a box of macaroni: a lot of the same little things.
These articles may be helpful:
-- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp0.pdf
-- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp10.pdf
Note, though, that I am now in the camp that says "Do not modify PASM code from Spin -- do everything through PAR." My May 2012 column will be a reboot of Spin-to-PASM basics that follow this guideline so that the PASM code may be used with Spin, as well as Prop-GCC (and probably other languages, too).
How would that be written in PASM?
Now that those pins are outputs and you have a value to write to them, here's how you can do it:
1 = command to run in pasm
2 = variable
3 = variable
4 = number of bytes to move.
Generally you would use this to move data from one place to another.
I tend to start by getting things working in spin first. Then take the block of spin and copy it into the pasm part and comment it all out. Then work on the lines one at a time and put a star or something in the line when that line has been translated to pasm.
Learning pasm can be tricky. One of the hardest concepts I found was the idea that this a 32 bit processor but it isn't really. In some ways it is more a 9 bit processor, so any constant that happens to be more than 511 (2^9-1) needs to be declared in a constant section at the end of the pasm code.
As an example (and yes there are other ways to do this with bitshifting), let's say you want to convert this line of code to pasm
declare a constant near the end of the pasm code and name it something that makes sense
and then in the code
if the pin you wanted to change happened to be P0 to P8 you could have used a constant. Oh yes, constants start with #. That gets me all the time too. So you could use #%00010000 to change P4.
generally pasm follows the machine code convention : instruction destination, source
I say generally because the other thing that gets very confusing is rdlong and wrlong.
I'll post other hints as I come across them.
It is important to remember the # symbol for constants, and you _must_ define a constant for values > 511 (nine-bit limit of source and destination fields).
Also remember that you can create generic IO subroutines in PASM as easily as they're created in Spin. In these examples, the variable called "pin" holds the pin # to affect before making the call. In the case of the input routine the c flag returns the result.
And if you wanted to move the input value to a variable, it's an easy update:
I think the key to learning PASM is studying code by others and constantly reviewing the manual. Some things will click very quickly, some things will not. There are some really clever coders here (I do not consider myself among them) and I am constantly gleaning new tricks by studying their code.
I forgot to add this little bit of code to retrieve the variables you passed to the pasm routine.
But there are some times where I doubt my ability to write anything that works!.
Pin won't change. Ok, stick in a call to an endless loop to stop the code at a known place
Try various variables. Pin still high. Try this code
And pins P0 to P15 are low and P16 to P23 are high.
So maybe I'm not the best person to ask about how to program in pasm!