PASM
NickMikhay
Posts: 41
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
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 indlsb
should be multiples of $200.Modifying
rdlong
's D operand will adjust which cogRAM variable (register) is then loaded byrdlong
. 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 thestartx
method, the PAR value is a pointer topar_tail
. Adding 11*4 makes it a pointer topar_keys
, which as it happens is wherestartx
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.
Is there a link to the code?
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?
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.
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) ofx
.