asm and ram hub adress
henrib75
Posts: 17
in Propeller 1
Hello everyone,
I'm just starting to do some interesting things with the Propeller, so I have a silly question… I'd like to have a compiled assembly program in the RAM hub (which doesn't run) after initialization, and then have a cog load this code snippet from its memory address and execute it. This is simple with another MCU, but I don't know how to do it with the Propeller. I want to emphasize that I need to be able to launch it from its address (not a DAT spin block whose location I don't actually know…). Perhaps it's simple?
Thanks
PS: This is an automatic translation

Comments
Yes. The @ symbol gives you the address of code in a DAT block (which lives in RAM and can be copied to one or more cogs).
For example, here's a simple 50% duty-cycle flasher for a pin.
dat org 0 flashpin mov t1, par ' point to parameters rdlong t2, t1 ' read pin mov pinmask, #1 ' convert to mask shl pinmask, t2 or dira, pinmask ' set to output add t1, #4 rdlong delayticks, t1 ' get 1/2 cycle ticks mov t1, cnt add t1, delayticks loop or outa, pinmask ' led pin high waitcnt t1, delayticks andn outa, pinmask ' led pin low waitcnt t1, delayticks jmp #loop ' ' -------------------------------------------------------------------------------------------------- pinmask res 1 delayticks res 1 t1 res 1 ' work vars t2 res 1 t3 res 1It needs two consecutive longs to provide the pin # and the half-cycle delay in ticks
Set the pin and delay and then start with cognew()
pub main flasher := 26 ticks := CLK_FREQ >> 1 cognew(@entry, @flasher) repeat waitcnt(0)This is in fact doing what you ask for:
Just a note: If you want to know if your cog loaded and what cog it's in, this is the standard practice
If cognew() works then cog will be > 0 (evaluates as true), otherwise cog will be 0 (false). If you want to shutdown that cog
You can use coginit() to load a specific cog.
Thanks. Yes, I know how to do that, but I want to be able to assign an address as a hexadecimal number, like when you start a Cog program in assembly... but in Spin. And above all, how do I put compiled assembly code at a specific address in the RAM hub?
Guess you could first copy the assembly to that fixed place and then load the cog from there? Maybe that would work?
That kind of goes against the grain for the Parallax Spin.
FlexProp's spin has an absolute address operator that might make things easier. I know if from P2, but think works with P1 too...
Yes, I could copy to a specific location, but how? In Spin, I can't provide a hexadecimal address using Longmove? And how can I know the length of the compiled DAT file? And how can I avoid writing to the Spin code that's currently executing, since I don't know its address either?
If you are using the Prop Tool, you can do info and see the memory map. Just stay a bit away from the very end because Spin uses that for stack space.
I'd just copy 512 longs, that way can make sure it's all there...
Longmove should work?
Just for fun -- but I don't know how useful this will be -- I took that little blinker demo, copied the DAT section to upper memory, and ran it from both places. Each instance is running on its own pin with its own blink rate.
This is the output from the program.
You don't actually need a second DAT section -- just put the marker at the end of your PASM code.
dat { cog driver } org 0 entry mov t1, par ' point to parameters rdlong t2, t1 ' read pin mov pinmask, #1 ' convert to mask shl pinmask, t2 or dira, pinmask ' set to output add t1, #4 rdlong delayticks, t1 ' get 1/2 cycle ticks mov t1, cnt ' sync blink timer add t1, delayticks ' set initial delay loop or outa, pinmask ' led pin high waitcnt t1, delayticks andn outa, pinmask ' led pin low waitcnt t1, delayticks jmp #loop ' ' -------------------------------------------------------------------------------------------------- pinmask res 1 delayticks res 1 t1 res 1 ' work vars t2 res 1 t3 res 1 end_of_pasmIf I can retrieve the hexadecimal code from the compiled assembly, I can indeed write it myself using a snippet of assembly code at a specific location. I'll look into that idea, thanks...
Hexadecimal is simply a display convention for programmers; internally, the numbers are the same. I'm sure you know this, but as I'll remind myself and others, the hub RAM looks like an array of bytes while the cog RAM looks like an array of longs.
I still don't know why you'd want to relocate code from hub RAM to hub RAM before moving it into a cog. Since you can read the assembled source out of a DAT section, I thought it might be interesting to write that to a file, and then read it into a RAM buffer that could be transferred into a cog and run. I tried it, and it works. I went with Ray's suggestion and put the code buffer at $7800 which is the last 2K in hub RAM, just enough for cog code.
If you have a PAB you can run the attached demo as-is. Of course, the idea of this program is to show that assembly segments can be stored on a uSD and loaded as needed. This only works for projects that use an SD card.
A long time ago I wondered if a programmer -- for their own reasons -- could release an object with obfuscated code. If that code is PASM, they can. I took the little blinker blob and wrapped it up in an object as a demonstration. I'm sure there's a PASM 1 disassembler somewhere, so this isn't a security thing, it just prevents newbies from making changes to PASM code that could be harmful.