Shop OBEX P1 Docs P2 Docs Learn Events
PASM self modifying code the best method to do this? — Parallax Forums

PASM self modifying code the best method to do this?

ke4pjwke4pjw Posts: 1,173
edited 2010-08-28 08:11 in Propeller 1
I am working with Timothy D. Swieter's venerable DMX Rx Driver (ver 01.4) and would like to add a feature to it. I want it to be able to invert the DMX pin input via software.

It seems to me the easiest way to invert the pin is to replace the instructions for "waitpne rmask, rmask" with the instruction "waitpeq rmask, rmask" and vice versa. I believe it would be a matter of knowing the address of the opcode and replacing the old opcode with the new one.

I am not at all sure if this is the best method or even if this type of thing is possible. I would hate to have to load two copies of this driver, one inverted and one not, into the eeprom. I know that is the easy way, but I figure I will learn something from this exercise :D

Any help would be greatly appreciated.

Regards,
Terry

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-08-27 13:48
    It's probably possible, but may not be the easiest or most elegant. I have my own DMX RX driver so you'll have to port my changes to what you're using; consulting FullDuplexSerial shows that it's pretty easy.

    In my driver, as with FDS, there is no WAITPNE or WAITPEQ for the start bit. The code checks the invert bit, scans the rx input, and when these two bits don't match you have a valid start. After the byte is received the bits are inverted if that is the mode.

    I suppose you could use WAITPxx like this:
    waitstart               test    rxinvert, #1            wz      ' check invert bit
            if_z            waitpne ina, rxmask                     ' true mode start bit
            if_nz           waitpeq ina, rxmask                     ' inverted mode start bit
    

    After you have the bits you will need to invert them:
    fixrxbits               test    rxinvert, #1            wc      ' inverted?
            if_c            xor     rxwork, #$FF                    '  yes invert bits
    
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-08-27 13:53
    Yeah, I thought about doing that, but was worried I might mess up the bit timing loops. I suppose with instruction execution speeds at near 50ns, it's not that big a deal, huh?

    PS- Thanks for the reply!
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-08-27 14:06
    No, you won't have any trouble.

    BTW, I had to pull my code down because adding inversion needed updates in more that just the RX section. You've have to check Tim's code for BREAK and MAB detection and modify those sections as well.
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-08-27 20:56
    Instructions like this are often changed. You can either use a mov, a movi or just set/reset the appropriate bits. Use a label to identify the instruction you need to change and make sure you place a comment on the line that it may be a waitpne/peq. Note you need to do this movi with at least 1 instruction between the movi and the waitpne/peq to allow for the pipeline.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-08-28 06:30
    ke4pjw,

    To answer your original question, you have the right idea for self-modifying code.

    If you look at the Propeller manual under "Propeller Assembly Instruction Master Table" page 350 for me, but I have an older manual so it could be different.

    look at the difference in the -INSTR- register between waitpne and waitpeq commands...

    111101 for waitpne and 111100 for waitpeq

    ...notice the ZCR bits in this table also. <-- Yes you can preset the state of the Z,C, and R flags.

    Now take a look at the MOVI instruction


    The code might look something like this...

    to function like a waitpne
                    movi modify,  #%111101_000
                       {other code can go here}
    modify          test rmask, rmask          '<-- when the program gets to here it
                                                        '      acts like a waitpne
    

    to function like a waitpeq
                    movi modify,  #%111100_000
                       {other code can go here}
    modify          test rmask, rmask          '<-- when the program gets to here it
                                                        '      acts like a waitpeq
    

    ...Note, the 'test' instruction is a 'do nothing' instruction here if wz and wc are not specified, but at the same time it will load the source and destination fields with the proper values. <-That in and of itself can come in handy with self modifying code, because you can eliminate the need to use MOVS or MOVD in a self modifying situation where it might be necessary or applicable to do so.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-08-28 06:38
    I see nobody else has asked this question, what is "self-modifying code"? Are we talking about developing "virus" code?

    Ray
  • tonyp12tonyp12 Posts: 1,951
    edited 2010-08-28 07:55
    Not a virus.

    Most of the time in self-modifying code
    the reserved space is used for a variable.

    So you actually just use a label name at the program line itself.
    instead of reserving a space in a data field below.

    In this case they are actually modifying the code execution.
    Something that is thrown on as it makes it's hard to follow your code.
  • Heater.Heater. Posts: 21,230
    edited 2010-08-28 08:11
    Rsadeika,
    ...what is "self-modifying code"? Are we talking about developing "virus" code?

    I have not heard of any Propeller viruses yet, one day when we have some networked operating systems running on the Prop....:)

    Simply put "self-modifying" code is exactly what it says. All instructions live in memory, all data lives in the same memory space. Well what if some code that is running treats it's own instructions as data and writes over it, i.e. modifies it?

    Historically the computer programming fraternity has frowned upon self-modifying code. But in the Propeller it's almost essential.

    Example: You have a JMP instruction to some location
    here     jmp    #somewhere
    

    Well, let's say sometimes you want that JMP to go somewhere else your program could have:
            movd here, #somewhere_else
    

    That changes the destination of the jump.

    This technique can also me used for modifying source and destinations of other instructions for operating on arrays etc.
Sign In or Register to comment.