Shop OBEX P1 Docs P2 Docs Learn Events
assembly programing — Parallax Forums

assembly programing

[Deleted User][Deleted User] Posts: 0
edited 2006-12-05 19:24 in Propeller 1
Hi,
·I'm trying to add 2 numbers together & display them out the debug term , the debug is working fine , but I get a little smilie face where my answer should be.

Thank's Brian




'' *******************
'' *· PC_Debug_Test· *
'' *******************

CON
· _clkmode····· = xtal1 + pll16x······················· ' use crystal x 16
· _xinfreq····· = 5_000_000···························· ' external xtal is 5 MHz
· CR··········· = 13
· FF··········· = 12
· LF··········· = 10
· Space········ = " "

OBJ
· debug : "pc_debug"

PUB main
· debug.start(460_800)································
· debug.str(@title)·
· debug.crlf
· debug.dec(@total)
· debug.crlf
· debug.crlf
·
· debug.stop
············································
dat
title·· byte·········· "Assembly programing test ",0
total·· res·· 1
······· add·· first,#second
······· mov·· total,#first
first·· long· 2365
second· long· 6985
···

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-03 05:44
    Nowhere in your code do you execute the assembly instructions. They don't just execute automatically. The way assembly works on the Propeller is that you use a COGINIT or COGNEW statement to copy 512 longs from somewhere in main memory (like in a DAT section) to a specific (COGINIT) or any available (COGNEW) cog, then start the cog beginning at location zero. Typically, only a part of the 512 longs actually contain something useful or desired and the rest are ignored.

    In your simple test, the first instruction adds the address of "second" to the contents of "first" rather than the contents of "second". Try leaving out the "#" to do what you probably want. Similarly, the second instruction will move the address of "first" to "total" rather than the value of "first".

    You can copy values into a DAT section using an assignment and they will be copied to the cog's memory by the COGINIT/COGNEW, but you can't get the values out. The "@total" refers to the location in the DAT section, not the contents of the corresponding cog location. Typically, what people do is pass the address of a main memory variable in the PAR register (as the second parameter of the COGINIT/COGNEW statement). Then they use a "WRLONG address,PAR" to copy the contents of "address" to the main memory variable where it can be displayed.

    Your brief program will need a way to stop itself. The best way is to have some temporary location "temp", then do a "cogid temp" followed by a "cogstop temp". You could just have a jump instruction that jumps to itself, but the cogstop turns off the cog so it doesn't take any significant amount of power.
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 06:28
    Is this getting any closer ?

    ·
    '' *******************
    '' *· PC_Debug_Test· *
    '' *******************
    CON
    · _clkmode····· = xtal1 + pll16x······················· ' use crystal x 16
    · _xinfreq····· = 5_000_000···························· ' external xtal is 5 MHz
    · CR··········· = 13
    · FF··········· = 12
    · LF··········· = 10
    · Space········ = " "
    var
    ······· long········· stack[noparse][[/noparse]9]
    ······· byte········· cog
    ······· long········· total
    OBJ
    · debug : "pc_debug"
    PUB main | temp
    · COGNEW(cog:=@addfor, @total)
    · debug.start(460_800)································
    · debug.str(@title)·
    · debug.crlf
    · debug.str(@total)
    · debug.crlf
    · debug.crlf
    ·
    · debug.stop
    · cogstop (cog)
    Dat
    ······· ORG·· 0

    title···· ··· byte·········· "Assembly programing test ",0
    addfor··· · add·· first , second
    ············· wrlong· total , first
    first·········long· 2365
    second···· long· 6985
    total······· res·· 1





    Thanks Brian

    Post Edited (truckwiz) : 12/3/2006 3:29:33 PM GMT
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 14:01
    Hi,

    ·Here's the code.

    Thanks , Brian


    Post Edited (truckwiz) : 12/3/2006 3:17:36 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-03 17:02
    There's a thread at the beginning of this forum called "Assembly Code Examples for the Beginner" and near the end is an interchange between LucidGuppy and Beau Schwabe where Beau gives an example of adding two numbers. Please start with that and add your debug code around it.
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 18:40
    Mike,

    ·I'm pulling my hair out , I redid the code to place the result in num_1 . I get the number that was in num_1 , so· I added another VAR , now i have the same problem I had with the first code.

    Thanks , Brian····· freaked.gif

    Post Edited (truckwiz) : 12/3/2006 6:50:11 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-03 21:25
    I've modified what you wrote. It should work.

    Notice that your program never called AddNums so the assembly stuff was never executed. It's very important ... The first public method (routine) in the main program is what gets executed when you start the Propeller. Nothing else is executed unless it is called by that method or some other method called from the first public method. Methods that are not called directly or indirectly by that first public method are not even loaded into RAM or EEPROM by the Propeller Tool.
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 22:37
    Mike ,
    ·Thank's for your help ! I have to say that when I started with trying to get the propeller to add & display the results in assembly , I didn't think it would take that much code . Heres my code to do it in just spin .

    Thanks , Brian·· smile.gif

    CON
    · _clkmode····· = xtal1 + pll16x
    · _xinfreq····· = 5_000_000
    · CR··········· = 13
    · FF··········· = 12
    · LF··········· = 10
    · Space········ = " "
    ·······
    OBJ
    · debug : "pc_debug"
    PUB main
    ·
    · debug.start(460_800)
    · debug.str(string("spin testing"))
    · debug.crlf································
    · debug.dec(5632 + 9658)·
    · debug.crlf
    · debug.stop
    ·
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-03 22:45
    It's not really that complicated, but you do need the communication back and forth between the two independent memory spaces. The main advantage of assembly is when raw speed or very precise (and short) timing is required. SPIN just can't do that.
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 23:02
    Hi,

    ·This might sound like a stupid question·. But how come you don't have to fire·· another cog up for spin or is that the only thing that cog does?

    Thank's Brian
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-03 23:11
    The on-chip reset hardware starts up a bootstrap loader in the first cog which is written in assembly. This either copies the contents of the EEPROM on pins 28/29 into RAM or looks for a connection to a PC running the Propeller Tool on pins 30/31 for a download to RAM and/or EEPROM. Once the RAM is loaded, the bootstrap loader does a COGINIT into its own cog from the part of ROM that contains the SPIN interpreter.
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-03 23:21
    Page 18 , That still don't answer at what point that another cog "must be" started. For example this program is using DAT· , but is still using the 1rst cog.


    CON
    · _clkmode····· = xtal1 + pll16x······················· ' use crystal x 16
    · _xinfreq····· = 5_000_000···························· ' external xtal is 5 MHz
    · CR··········· = 13
    · FF··········· = 12
    · LF··········· = 10
    · Space········ = " "

    OBJ
    · debug : "pc_debug"
    PUB main
    ·
    · debug.start(460_800)································
    · debug.str(@title)·
    · debug.crlf
    · debug.str(@total)
    · debug.crlf
    · debug.crlf
    ·
    · debug.stop
    ·······················································
    dat
    title·· byte·········· "Assembly programing test ",0


    Thank's Brian
    ·
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-04 05:10
    As far as you're concerned, each cog is an independent computer that happens to share I/O devices with the others in the "cluster". Consider HUB memory as an I/O device. Any cog can force a reset of itself or any other cog (COGINIT/COGNEW) setting a single parameter register (PAR) and a hidden register used by the cog loading process. That's it.

    One cog gets loaded with the SPIN interpreter from ROM (another I/O device) on a master reset. There's nothing requiring any other cog to be used. If your application needs the speed or parallelism, it can force another cog to be started either with the SPIN interpreter or an assembly language program you supply. If it's the SPIN interpreter, it executes a method (routine) you specify that it finds in RAM. Since SPIN code is read-only, two (or more) interpreters can interpret the same routines at the same time. You have to provide logic to keep the two (or more) interpreters from changing common variables at the same time (if they're not supposed to do so).
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-05 03:06
    Thank's for your help Mike , Brian··· smile.gif
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-05 13:32
    Mike,
    ·Works awesome! Do you have to notify parallax·when you modify a object (I redid LCD so that it would display dec , hex & bin). My next step is to try to display the flags. I haven’t had time to check into that yet. how does par know to save results in Num3 ?
    Thanks, Brian


    Post Edited (truckwiz) : 12/6/2006 3:57:29 AM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-05 14:58
    Brian,
    Look at the description of the COGINIT instruction in the assembly portion of the Propeller Manual. When you do a COGINIT/COGNEW statement in SPIN, the interpreter ends up doing a COGINIT instruction. The second parameter of the COGINIT/COGNEW eventually ends up in the PAR register of the new cog. The low order 2 bits get forced to zero which is usually ok because this is normally used as the address in hub memory of a long word. In the case of your routine, "@Num3" is used as the 2nd parameter so the assembly code will have the address of Num3 in the PAR register.
    Mike
  • [Deleted User][Deleted User] Posts: 0
    edited 2006-12-05 19:24
    Hi,
    I'll answer the first part of my question so nobody else has to swear at me . Brian , make sure that there is not already a object that does what you want it to do before you modify other objects !

    Thanks, Brian

    Post Edited (truckwiz) : 12/6/2006 3:56:23 AM GMT
Sign In or Register to comment.