Shop Learn
PASM — Parallax Forums

PASM

Hello,
Just wanted to see if anyone can help. The driver in question here is the ps/2 keyboard driver v1.0.1

When you get to the assembler code on line 6:
:par rdlong 0,x
add :par,dlsb

Not sure about which piece of data :par is referring to when adding dlsb

The more I read the code the less it makes sense.
Initially my hunch was that par_keys passes the start parameters into the cog; but at entry it looks like it’s trying to count to something like it was calculating an address, I don’t know.

And the add to :par just has me stumped.

Comments

  • evanhevanh Posts: 13,106
    edited 2022-04-26 07:16

    It's performing address arithmetic via self-modifying code ... :par is an assembler label of the register to increment. The :par register contains an instruction with an op-code and two operands.

    Indications are that the 0 D operand is the target of the self-modifying address increment. It's common practise to use 0 or 0-0 as the placeholder. So the value in dlsb should be multiples of $200.

    Modifying rdlong's D operand will adjust which cogRAM variable (register) is then loaded by rdlong. There will presumably be a table of cogRAM variables that are filled as the code loops.

  • Yes, that is what I figured, but the values it loads in the variables starting at _dpin and multiples of $200 don’t make sense.

    In the first iteration x is set 44 and loaded to _dpin address

    The a few lines down there is: shl dmask,_dpin
    to me this means shift left 44 bits, which is not right. x sounds like it’s the pin no. that it is trying to decode, so expecting a 0 - 31 for x?

    But later

  • No, x is set to the value from the PAR register and then 44 is added. As you can see in the startx method, the PAR value is a pointer to par_tail. Adding 11*4 makes it a pointer to par_keys, which as it happens is where startx copies the pin values into. So by reading through the pointer, the pin values end up in the relevant registers.

    Relatedly, a shift by 44 just becomes a shift by 12, only the bottom 5 bits of the shift value are actually used.

  • with x now a pointer to par_keys adding four would point it to the next long after dpin in main memory.
    but now
    add :par, dlsb

    the D-fields are 9 bits so not possible to add $200 which is a 10 bit value, is it adding the first 9 bits?
    I think we’re after an increment of one for :par for the _cpin address since it is located right after, but don’t see how adding zero would do anything.

    this would really make things clear. Will have to ck back tomorrow. Thanks.

  • evanhevanh Posts: 13,106

    Is there a link to the code?

  • @NickMikhay said:
    with x now a pointer to par_keys adding four would point it to the next long after dpin in main memory.
    but now
    add :par, dlsb

    the D-fields are 9 bits so not possible to add $200 which is a 10 bit value, is it adding the first 9 bits?
    I think we’re after an increment of one for :par for the _cpin address since it is located right after, but don’t see how adding zero would do anything.

    It's because the lowest 9 bits are the S-field. The next 9 bits are the D field, so $200 has to be added to increment the D field by 1.

  • Amazing how you see these things.

  • Just one more point
    If we are modifying the entire line of :par with the add :par, dlsb
    and the source field is zero, (dlsb padded the value)
    when :par is executed after the jump it will/has to load the variable x into S field.
    but how will it know to do this if the entire register was overwritten with $200, and has zeros in S field?

  • @NickMikhay said:
    but how will it know to do this if the entire register was overwritten with $200, and has zeros in S field?

    Because it doesn't get overwritten. It's an ADD. If you have the number 42, you can add 100 to it as often as you want, the last two digits stay 42.

  • evanhevanh Posts: 13,106
    edited 2022-04-28 01:42

    @NickMikhay said:
    when :par is executed after the jump it will/has to load the variable x into S field.

    A detail: x variable is loaded into the ALU. Aka, fetching the S operand. Not loaded to the instruction S field. The instruction's S field contains the address (register number) of x.

Sign In or Register to comment.