ALTSN D,{#}S and SETNIB D,{#}S,#N Syntax Qestion
ALTSN D,{#}S
Alter subsequent SETNIB instruction. Next D field = (D[11:3] + S) & $1FF, N field = D[2:0].
D += sign-extended S[17:9].
SETNIB D,{#}S,#N
Set S[3:0] into nibble N in D, keeping rest of D same.
In the SETNIB the nibbles are numbered 0-7 , N point to the nibble to be changed and the S[3:0] containes the nibble value . D is what is going to be changed.
I assume if ALTSN D,{#}S is the instruction that is executed prior to SETNIB. The ALTSN D register D[2:0] = N is loaded into the SETNIB Instruction for N the nibble to be operated on and the ALTSN D register is loaded into the SETNIB D register .The nibble value stored in SETNIB S register will then get loaded into the ALTSN Register D which is D = (D[11:3] + S) & $1FF . D[11:3] is a 9 bit number S is a 9 bit register number (0-511 or 0-$1FF) but D[2:0] must contain N value I just got lost. Help!
If someone could clarify it would be apreciated.
Regards and thanks
Bob (WRD)
Comments
That's one of those very strange instructions...
I'm not actually sure what that means either. I'd guess that the D in the ALTSN instruction itself gets modified by it's own S. Maybe that'd be useful in a loop somehow...
@Bob
Here's a demo of ALTGN but the principle applies to ALTSN,ALTSW etc
A cogram table is indexed and output to the terminal.
As best I can make out, the ALTSN allows two longs to specify the parameters to step through a table of nibbles in COG ram by an arbitrary step size:
S[8:0] holds the base address of the table of nibbles.
S[17:9] holds the adjustment value (number of nibbles to increment or decrement the index by); this is sign-extended before being added to the current index and constrained to 9 bits.
The D input holds the address index (D[11:3]) and nibble index (D[2:0]).
The D output stores the adjusted address index and nibble in the D register of the ALTSN instruction, for a subsequent loop.
The sum of the base and index (constrained to 9 bits) is fed forward to overwrite the D field for the SETNIB instruction.
The nibble index is fed forward to overwrite the N field for the SETNIB instruction.
There is an alias, SETNIB {#}S, provided for use with ALTSN that allows one to ignore the D field of the SETNIB instruction, as it is not used.
I hope this is clear and correct.
Yeah, it's for using a variable to index into tables/buffers within cogRAM. D is your index. S is just a base reference for start of table/buffer. It effective gives you nibble granularity addressing.
It also allows a smaller and faster code footprint to achieve this, as the whole thing could have been achieved with 'standard' instructions.
Cool, I've definitely overlooked that feature in the past. I've used it with ALTS more recently though.
The alias is just S=#0. ie: Effectively using D without S. D must be a variable (register).
According to Row 86 of the Instruction spreadsheet it is the D field that is zero
SETNIB {#}S Math and Logic EEEE 1000000 00I 000000000 SSSSSSSSS alias Set S[3:0] into nibble established by prior ALTSN instruction.
Oops, sorry, I misread that as the alias of ALTSN, not SETNIB.
Yes, of course, use the alias of SETNIB when prefixed with ALTSN.
PS: I've asked (probably not the first to ask) Chip for these to be turned into macro-instructions. Like AUGx is already.
AUGx is simple to make into a macro as it is only the two instruction longs that need to be generated.
Making an ALTSN, SETNIB pair (e.g.) also requires generation of the input S register’s contents. Not impossible, but definitely more complicated.
I guess it would need the input to look something like
and the output would be
and S prepopulated with #increment << 9 | #base
That shouldn’t interfere with the current syntax, as omitting the base parameter can simply generate a standalone SETNIB with the same target for writing the nibble, just without updating D.
Edit: one problem that might crop up would be if S was reused for something else by other code
Thanks for the example @ozpropdev . That shows how most of this works...
Incrementing the D field of altgn in the loop iterates the table via: address index (D[11:3]) and nibble index (D[2:0])
So, all you need to do is increment the D (index) that says which nibble to use in D[2:0], and when that rolls over it automagically points to the next register in the table using D[11:3].
Doesn't look like this example uses the "D += sign-extended S[17:9]" part.
As @AJL mentioned, this looks like it could be used to increment the table index automatically.
However, in this example S is an immediate (constant value) and so limited to 9 bits.
So, I guess to have it automatically increment the table, you'd use a separate register set to the register number of "table" and add in your increment left shifted by 9.
Then, get rid of the # so it's not immediate and stick in this new register's name in place of "table".
But then, you'd need to figure out how to exit the loop.
The incmod instruction used here is a neat way to do that using the index in D instead...
Also be aware when using auto inc/dec feature to avoid using AUGS variants.
`
'This won't work
loop altgn index,##table | 1 << 9
getnib pa
'this does
loop altgn index,config
getnib pa
.
.
config long table | 1 << 9 'auto +1
`
The INCMOD approach works well for single stepping through the table, and exiting once you've reached the limit.
If you want larger steps then putting the increment in S[17:9] of the ALTx instruction gets you that operation 'for free', noting that, if a REP loop isn't used an explicit compare is necessary to set the condition flags for branching out.
ozpropdev's example can't use a REP loop due to the CALL to #txbyte.
ALTSN D,{#}S
Alter subsequent SETNIB instruction. Next D field = (D[11:3] + S) & $1FF, N field = D[2:0].
D += sign-extended S[17:9].
It appears t S contains a value which can be index offset to base address D[11:3] but what does a register pointer have to do with D += sign-extended S[17:9]? D I thought is register address with a nibble address to write too. Looks like some information is missing. Is it possible S[17:9] should be loaded with some sort of address it is 9 bits. Trying to test instruction with attached file. (Not so good)
Regards
Bob (WRD)
Try this Bob.
Bob, It works the other way around: for ALTSN, {#}S contains the base address and D contains the index.
The pointer address is then the bottom 9 bits of (D[11:3]+S) which is fed forward to the SETNIB instruction.
If you use a register for S, then the base address is S[8:0], and if S[17:9] is non-zero then it will be sign-extended and added to the initial contents D, before being written back to the D register (updating the index) as a result of the ALTSN instruction.
The SETNIB instruction is then using the pointer address (from the feed forward circuit), the nibble selector (from the feed forward circuit), and S[3:0] (from the SETNIB instruction encoding) to modify the nibble pointed at.
Edit: You've provided your code, but what is the output you get?
Here is a paint image of output using program with ALTSN_D_S(I modified program comments) for program previously posted . I will look at switching base address to S. Attached also is program using only ALTSN D which seems to work without the offset (D[11:3]+S). D in this program is an address register (PR0 =$1D8). This program writes the same nibble value to each of the of the D[11:3] register nibbles N(0-7)
thanks for looking at this
Regards
Bob (WRD)
AJL
Yes switching offset and baseAddress works. I have attached program and results.
Thanks
Bob (WRD)