Forum Update - Announcement about May 10th, 2018 update and your password.

XBYTE question

12346

Comments

  • cgracey wrote: »
    There is also a 'reverse' operator in the assembler: "><".

    SKIPF #%011010110 >< 9

    I just realized in that example it wouldn't matter.

    Oh yes. Forgot about the "><" operator. I've never used it.

    So for the above example
    bytetable	long	r4 | 011_01_0% << 10	'forward byte branch
    becomes
    bytetable	long	r4 | (%011_01_0_0000000000000000 >< 22) << 10	'forward byte branch
    

    Melbourne, Australia
  • jmgjmg Posts: 11,261
    cgracey wrote: »
    There is also a 'reverse' operator in the assembler: "><".

    Cool - so this is already in the assembler, problem solved.

  • TonyB_TonyB_ Posts: 456
    edited August 2017 Vote Up0Vote Down
    cgracey wrote: »
    TonyB_ wrote: »
    TonyB_ wrote: »
    Using SETQ or SETQ2 with Q[9]=1 would seem to be the sensible way to enable CZ writing in XBYTE. This is a bit of a dummy's question: if the D in SETQ/SETQ2 is 9-bit immediate, are the top 23 bits written to Q all zero, ensuring that XBYTE will not modify CZ?

    Is CZ writing in XBYTE optional now, or is this yet to be done?

    I've been thinking, too, that SETQ D[9] could convey whether or not the C/Z bits are written with the two LSBs of the index. That's the last thing I need to implement before I can make another release.

    Just checking that CZ writing in XBYTE really is optional now. It is referred to briefly in v20 documentation but some catching up needed here as no mention of CALLs and interrupts working during skipping.

    Related to my dummy's question quoted above, is a 9-bit immediate source in a NOT instruction first zero-extended to 32 bits then the whole long inverted, so that negative values from -1 to -256 can be moved?
    Formerly known as TonyB
  • TonyB_ wrote: »
    cgracey wrote: »
    TonyB_ wrote: »
    TonyB_ wrote: »
    Using SETQ or SETQ2 with Q[9]=1 would seem to be the sensible way to enable CZ writing in XBYTE. This is a bit of a dummy's question: if the D in SETQ/SETQ2 is 9-bit immediate, are the top 23 bits written to Q all zero, ensuring that XBYTE will not modify CZ?

    Is CZ writing in XBYTE optional now, or is this yet to be done?

    I've been thinking, too, that SETQ D[9] could convey whether or not the C/Z bits are written with the two LSBs of the index. That's the last thing I need to implement before I can make another release.

    Just checking that CZ writing in XBYTE really is optional now. It is referred to briefly in v20 documentation but some catching up needed here as no mention of CALLs and interrupts working during skipping.

    Related to my dummy's question quoted above, is a 9-bit immediate source in a NOT instruction first zero-extended to 32 bits then the whole long inverted, so that negative values from -1 to -256 can be moved?

    I have SETQ D[9] working here on my current version. Not sure about v20, though I did just update the documentation to say it is in there. You just reminded me of what I need to catch up with in the doc's - these issues of CALLs and interrupts during skipping.

    Yes, a NOT instruction will zero-extend a 9-bit immediate value before doing a one's-complement and writing the result.
  • If you are updating the docs could you fix the descriptions of SCLU and SCL? I had posted the following comment a few weeks ago in another thread.
    Dave Hein wrote: »
    I was looking at the SCLU and SCL instructions, and there appears to be errors in their descriptions in the Propeller 2 Instruction document. The description for SCLU is "Next instruction's S value = unsigned (D[15:0] * S[15:0])." It appears that the product is also shifted to the right by 16 bits.

    The description for SCL is "Next instruction's S value = signed (D[15:0] * S[15:0]) / $4000." However, rather than dividing by $4000 it would be more accurate to say that it is shifted right by 14 bits with sign extension. If I multiply 1 * (-1) the result is -1. A division by $4000 would have produced a value of zero instead.
  • Dave Hein wrote: »
    If you are updating the docs could you fix the descriptions of SCLU and SCL? I had posted the following comment a few weeks ago in another thread.
    Dave Hein wrote: »
    I was looking at the SCLU and SCL instructions, and there appears to be errors in their descriptions in the Propeller 2 Instruction document. The description for SCLU is "Next instruction's S value = unsigned (D[15:0] * S[15:0])." It appears that the product is also shifted to the right by 16 bits.

    The description for SCL is "Next instruction's S value = signed (D[15:0] * S[15:0]) / $4000." However, rather than dividing by $4000 it would be more accurate to say that it is shifted right by 14 bits with sign extension. If I multiply 1 * (-1) the result is -1. A division by $4000 would have produced a value of zero instead.

    Dave, thanks for reminding me. I just fixed the spreadsheet.
  • TonyB_TonyB_ Posts: 456
    edited October 2017 Vote Up0Vote Down
    cgracey wrote: »
    TonyB_ wrote: »
    cgracey wrote: »
    TonyB_ wrote: »
    TonyB_ wrote: »
    Using SETQ or SETQ2 with Q[9]=1 would seem to be the sensible way to enable CZ writing in XBYTE.

    Is CZ writing in XBYTE optional now, or is this yet to be done?

    I've been thinking, too, that SETQ D[9] could convey whether or not the C/Z bits are written with the two LSBs of the index. That's the last thing I need to implement before I can make another release.

    Just checking that CZ writing in XBYTE really is optional now. It is referred to briefly in v20 documentation but some catching up needed here as no mention of CALLs and interrupts working during skipping.

    I have SETQ D[9] working here on my current version. Not sure about v20, though I did just update the documentation to say it is in there. You just reminded me of what I need to catch up with in the doc's - these issues of CALLs and interrupts during skipping.

    A final "just checking" message (I hope).

    In order to enable CZ writing in XBYTE, i.e. copying bytecode[1:0] to [C,Z], am I right in saying that SETQ[9] must be 1?

    Going back a bit, I think the CALL skip freeze counter (call+/ret-) is 3-bit. This means CALLs could be nested to a level of 7, but the maximum CALL nesting is not mentioned in the docs. In fact, I'm not sure CALLs during skipping are mentioned yet in the docs (last one I have is v20 and they are not).

    P.S.
    Many thanks, Chip, for adopting 'correct sign' !

    Formerly known as TonyB
  • cgraceycgracey Posts: 9,011
    edited October 2017 Vote Up0Vote Down
    TonyB_,

    Right, bit 9 of the SETQ value is 1 to enable C,Z being set to the two LSBs of the bytecode-lookup address in LUT.

    A four-bit counter tracks CALL/CALLPA/CALLPB depth, so the full 8 levels of the hardware stack can be used.

    This stuff is in the documentation now.
  • TonyB_TonyB_ Posts: 456
    edited January 29 Vote Up0Vote Down
    A couple of questions related to XBYTE:

    1. The documentation says the following:
    SKIPF works through all immediate-relative branches, which are the default for immediate branches within cog/LUT memory. If an absolute-address branch is being used (#\label, register, or RET, for example), you must not skip the instruction after the branch. This is not a problem with immediate-relative branches, however, since the variable stepping works to advantage, by landing the PC at the first instruction of interest at, or beyond, the branch address.

    During a SKIPF sequence, I'd like to jump to an instruction that might be skipped. Can an immediate-relative jump instruction always branch from anywhere in cog RAM to anywhere else cog RAM using a 9-bit immediate?

    2. Only absolute immediate or register indirect CALLs can be used in skip sequences. I'm interested here in a register indirect CALL that is never skipped, but instructions just before and after are. The register is loaded with an address earlier in the skip sequence and there are lots of possible addresses for various subroutines. Sometimes, though, the CALL is not needed but the flags are in use and I can't do a conditional CALL.

    To get to the point, which applies generally not just to skipping, would it be possible for register bit 31 to indicate whether the CALL should happen? If bit 31 = 0 the CALL can take place, whereas if bit 31 = 1 the address is considered to be "negative" or "invalid" and the call instruction acts as a two-cycle NOP.
    Formerly known as TonyB
  • cgraceycgracey Posts: 9,011
    edited January 30 Vote Up0Vote Down
    TonyB_ wrote: »
    A couple of questions related to XBYTE:

    1. The documentation says the following:
    SKIPF works through all immediate-relative branches, which are the default for immediate branches within cog/LUT memory. If an absolute-address branch is being used (#\label, register, or RET, for example), you must not skip the instruction after the branch. This is not a problem with immediate-relative branches, however, since the variable stepping works to advantage, by landing the PC at the first instruction of interest at, or beyond, the branch address.

    During a SKIPF sequence, I'd like to jump to an instruction that might be skipped. Can an immediate-relative jump instruction always branch from anywhere in cog RAM to anywhere else cog RAM using a 9-bit immediate?

    2. Only absolute immediate or register indirect CALLs can be used in skip sequences. I'm interested here in a register indirect CALL that is never skipped, but instructions just before and after are. The register is loaded with an address earlier in the skip sequence and there are lots of possible addresses for various subroutines. Sometimes, though, the CALL is not needed but the flags are in use and I can't do a conditional CALL.

    To get to the point, which applies generally not just to skipping, would it be possible for register bit 31 to indicate whether the CALL should happen? If bit 31 = 0 the CALL can take place, whereas if bit 31 = 1 the address is considered to be "negative" or "invalid" and the call instruction acts as a two-cycle NOP.

    1) 9-bit immediate-relative branches have a reach of -256 to +255. So, no, you can't jump anywhere within cog RAM using those. You can use 20-bit immediate-relative branches, though. The 9-bit branches use the D field (DJNZ, TJZ, etc.) for some condition, usually.

    2) You can do that. The Spin2 interpreter does that for reading/writing variable. Sometimes, that instruction is a RDLONG, while for bit fields it becomes a CALL, since more code is needed to do the job.

    Bit 31 could be used like that, but why not just put a NOP there, in case you want no CALL to occur. Or, do you always want the CALL instruction to be in place, but make it conditional by the S-address MSB? Wait, I see. That is what you want to do. Let me look into it.
  • TonyB_TonyB_ Posts: 456
    edited January 30 Vote Up0Vote Down
    cgracey wrote: »
    TonyB_ wrote: »
    A couple of questions related to XBYTE:

    1. The documentation says the following:
    SKIPF works through all immediate-relative branches, which are the default for immediate branches within cog/LUT memory. If an absolute-address branch is being used (#\label, register, or RET, for example), you must not skip the instruction after the branch. This is not a problem with immediate-relative branches, however, since the variable stepping works to advantage, by landing the PC at the first instruction of interest at, or beyond, the branch address.

    During a SKIPF sequence, I'd like to jump to an instruction that might be skipped. Can an immediate-relative jump instruction always branch from anywhere in cog RAM to anywhere else cog RAM using a 9-bit immediate?

    1) 9-bit immediate-relative branches have a reach of -256 to +255. So, no, you can't jump anywhere within cog RAM using those. You can use 20-bit immediate-relative branches, though. The 9-bit branches use the D field (DJNZ, TJZ, etc.) for some condition, usually.

    I think I could arrange the code so the branches are within range of 9-bit immediates.
    cgracey wrote: »
    TonyB_ wrote: »
    2. Only absolute immediate or register indirect CALLs can be used in skip sequences. I'm interested here in a register indirect CALL that is never skipped, but instructions just before and after are. The register is loaded with an address earlier in the skip sequence and there are lots of possible addresses for various subroutines. Sometimes, though, the CALL is not needed but the flags are in use and I can't do a conditional CALL.

    To get to the point, which applies generally not just to skipping, would it be possible for register bit 31 to indicate whether the CALL should happen? If bit 31 = 0 the CALL can take place, whereas if bit 31 = 1 the address is considered to be "negative" or "invalid" and the call instruction acts as a two-cycle NOP.

    2) You can do that. The Spin2 interpreter does that for reading/writing variable. Sometimes, that instruction is a RDLONG, while for bit fields it becomes a CALL, since more code is needed to do the job.

    Bit 31 could be used like that, but why not just put a NOP there, in case you want no CALL to occur. Or, do you always want the CALL instruction to be in place, but make it conditional by the S-address MSB? Wait, I see. That is what you want to do. Let me look into it.

    Yes, I don't want to overwrite the CALL with a NOP if it can be avoided, as I'd have to overwrite the NOP with a dummy CALL later. Ideally the CALL would stay as a CALL but act like a NOP sometimes. I thought of the MSB of the address as a flag because it should be zero normally and that idea worked well with RDFAST/WRFAST.

    I'm not sure it would be the S-address MSB. I'm looking at this particular instruction:
    EEEE 1101011 CZ0 DDDDDDDDD 000101101 CALL    D        {WC/WZ/WCZ}
    

    I don't know whether this new behaviour should apply to all register indirect calls. I would find it very useful and the CALL register could contain different values when the CALL is in "sleep" mode, e.g. $FFFF_FFFF or $FFFF_FFFE, which I would use for one of two functions by testing with TJF or TJNF.

    (A bit more info. The CALL in question is a "stepping-stone" instruction in the skip sequence, with eight skippable instructions directly before and after, which means it cannot itself be skipped.)

    A CALL that could be toggled on or off by changing the MSB of the address register strikes me as useful in general, not just for skipping.

    Formerly known as TonyB
  • cgraceycgracey Posts: 9,011
    edited January 30 Vote Up0Vote Down
    I looked through my Verilog code.

    Indeed, it would be much less error-prone to implement a general rule that ANY indirect (register-supplied address) branch be cancelled if some particular register bit was set, above bits 19..0. Remember, though, that register bits 31/30 can be used for C/Z flag storage and retrieval. So, any bit from 29..20 could serve the purpose of 'branch cancellation'.

    While such a change could provide new functionality, I worry that it might also pose a snare, in some cases, to the unsuspecting programmer who is using those empty bits, or even making high immediate addresses from NOT or NEG instructions.

    Are there any additional purposes these otherwise-unused bits could provide, beyond just cancellation?
  • SeairthSeairth Posts: 2,330
    edited January 30 Vote Up0Vote Down
    What if the semantics of CALL were changed such that if the address was of the CALL instruction itself, it was treated as a NOP. As it currently stands, you would have an infinite loop, which isn't of any use anyhow.

    (edit: actually, what if all of the branching instructions worked that way? Is there any good reason for a branch to jump to itself? For those that explicitly want an infinite loop, preface the branch with a NOP and jump to that.)
  • cgraceycgracey Posts: 9,011
    edited January 30 Vote Up0Vote Down
    Seairth wrote: »
    What if the semantics of CALL were changed such that if the address was of the CALL instruction itself, it was treated as a NOP. As it currently stands, you would have an infinite loop, which isn't of any use anyhow.

    (edit: actually, what if all of the branching instructions worked that way? Is there any good reason for a branch to jump to itself? For those that explicitly want an infinite loop, preface the branch with a NOP and jump to that.)

    I often do 'JMP #$' to keep a cog's pins going after running some code.

    What TonyB_ was suggesting was kind of neat, in that you could set a single bit to enable/disable a branch. And the rule could be that when reg[29:28] = %10, the branch becomes a NOP, in order to get around unintended triggering from a more-likely %11 value.
  • TonyB_TonyB_ Posts: 456
    edited January 31 Vote Up0Vote Down
    cgracey wrote: »
    I looked through my Verilog code.

    Indeed, it would be much less error-prone to implement a general rule that ANY indirect (register-supplied address) branch be cancelled if some particular register bit was set, above bits 19..0. Remember, though, that register bits 31/30 can be used for C/Z flag storage and retrieval. So, any bit from 29..20 could serve the purpose of 'branch cancellation'.

    While such a change could provide new functionality, I worry that it might also pose a snare, in some cases, to the unsuspecting programmer who is using those empty bits, or even making high immediate addresses from NOT or NEG instructions.

    Are there any additional purposes these otherwise-unused bits could provide, beyond just cancellation?

    Thanks for looking, Chip. Utilising bit 31 of D in RDFAST/WRFAST was simple and had no side effects, but I can see that would not be the case with addresses and it would be best to scrap the cancellation bit. In the absence of any other suggestions, I think the answer to the question is the unused bits could be used for any purposes the programmer chooses.
    Seairth wrote: »
    What if the semantics of CALL were changed such that if the address was of the CALL instruction itself, it was treated as a NOP. As it currently stands, you would have an infinite loop, which isn't of any use anyhow.

    (edit: actually, what if all of the branching instructions worked that way? Is there any good reason for a branch to jump to itself? For those that explicitly want an infinite loop, preface the branch with a NOP and jump to that.)

    Seairth, that's an excellent idea, for CALLs at least. It would help make P2 code a bit more idiot-proof and resolve my issue, but I don't know whether it's doable.

    Another possibility is for register indirect CALLs to zero to be ignored and the register value to be treated quite literally as a NOP. Other CALLs to zero would still be possible.

    To be honest, my issue is a minor one and the worst case is two extra longs and clock cycles are used. It's just a little bit annoying to restore a CALL every time when usually it will not need restoring.
    ' codex - read, execute, write
    ' codey - read, write (move)	 skip bit
    '				 |
    codex	instr_1x		'0
    	instr_2x		'?
    	instr_3x		'?
    	mov	reg,#addrx	'0 set call address x
    	jmp	#read		'0
    ...
    codey	instr_1y		'0
    	instr_2y		'?
    	instr_3y		'?
    	mov	exec,#0		'0 replace call with nop
    	jmp	#read		'0
    ...
    read	instr_6			'? read from 1 of 8 sources
    	instr_7			'?
    	instr_8			'?
    	instr_9			'?
    	instr_10		'?
    	instr_11		'?
    	instr_12		'?
    	instr_13		'?
    '
    exec	call	reg 		'0 do operation / nop
    '
    write	instr_15		'? write to 1 of 8 dests
    	instr_16		'?
    	instr_17		'?
    	instr_18		'?
    	instr_19		'?
    	instr_20		'?
    	instr_21		'?
    	instr_22		'?
    '				   
    	mov	exec,exec2	'  skipping over, restore call
    	...			'  other stuff
    ...
    reg	nop			'  holds call address
    exec2	call	reg		'  backup call instruction
    

    Just to confirm, immediate-relative jumps to read/write could skip instr_6/instr_15?

    EDIT:
    Written before I saw Chip's previous post.
    Formerly known as TonyB
  • TonyB_ wrote: »
    Just to confirm, immediate-relative jumps to read/write could skip instr_6/instr_15?

    That's right.
  • cgracey wrote: »
    TonyB_ wrote: »
    Just to confirm, immediate-relative jumps to read/write could skip instr_6/instr_15?

    That's right.

    Thanks, Chip.
    cgracey wrote: »
    What TonyB_ was suggesting was kind of neat, in that you could set a single bit to enable/disable a branch. And the rule could be that when reg[29:28] = %10, the branch becomes a NOP, in order to get around unintended triggering from a more-likely %11 value.

    I'd be very happy with that, if you consider it worthwhile and safe.
    reg[29:28] = %10 is much less risky than just reg[29] = %1.

    I was rather negative in my last post, because reg[31] was unavailable.
    Formerly known as TonyB
  • cgracey wrote: »
    I often do 'JMP #$' to keep a cog's pins going after running some code.


    True, but that's a bit of a P1 holdover, isn't it? I thought the new way was something like
    WAITINT
    JMP #-1
    

    And, of course, if you didn't set up any interrupts, you don't even need the JMP. Right?
  • Seairth wrote: »
    cgracey wrote: »
    I often do 'JMP #$' to keep a cog's pins going after running some code.


    True, but that's a bit of a P1 holdover, isn't it? I thought the new way was something like
    WAITINT
    JMP #-1
    

    And, of course, if you didn't set up any interrupts, you don't even need the JMP. Right?

    WAITINT would work. You just need a known instruction to execute when your code is done, so I use 'JMP #$'. In a real application, you probably wouldn't do that, but for test programs that I run, I need the cog to stay alive, so that its pin states are maintained.
  • TonyB_TonyB_ Posts: 456
    edited January 31 Vote Up0Vote Down
    This is how my XBYTE example could look with CALL disable:
    ' codex - read, execute, write
    ' codey - read, write (move)	 skip bit
    '				 |
    codex	instr_1x		'0
    	instr_2x		'?
    	instr_3x		'?
    	mov	reg,#addrx	'0 enable call to addrx, reg[29:28]=%00
    	jmp	#read		'0
    ...
    codey	instr_1y		'0
    	instr_2y		'?
    	instr_3y		'?
    	bith	reg,#29		'0 disable call, reg[29:28]=%10
    	jmp	#read		'0
    ...
    read	instr_6			'? read from 1 of 8 sources
    	instr_7			'?
    	instr_8			'?
    	instr_9			'?
    	instr_10		'?
    	instr_11		'?
    	instr_12		'?
    	instr_13		'?
    '
    exec	call	reg 		'0 do operation if enabled
    '
    write	instr_15		'? write to 1 of 8 dests
    	instr_16		'?
    	instr_17		'?
    	instr_18		'?
    	instr_19		'?
    	instr_20		'?
    	instr_21		'?
    	instr_22		'?
    '				   
    	...			'  skipping over, do other stuff
    ...
    reg	nop			'  holds call address
    
    Formerly known as TonyB
  • Thinking about this more, I don't want to make this change.

    The trickiest aspect is cancelling potential registers writes that are part of some CALLs. I would need a new mechanism to do that with and it would certainly lengthen the timing, as those signals are now registered before the start of the 2nd clock, but would then require resolution into the 2nd clock. I don't want to go there. I don't think it's worth the risk or the congestion that slower paths would introduce.
  • cgracey wrote: »
    Thinking about this more, I don't want to make this change.

    The trickiest aspect is cancelling potential registers writes that are part of some CALLs. I would need a new mechanism to do that with and it would certainly lengthen the timing, as those signals are now registered before the start of the 2nd clock, but would then require resolution into the 2nd clock. I don't want to go there. I don't think it's worth the risk or the congestion that slower paths would introduce.

    Thanks for trying, Chip.

    Is it possible for prefix 0000 to be decoded as IF_NEVER for definite branch instructions? SETNIB could change the top nibble to enable or disable the call or jump. Nothing else after the opcode would need fetching to determine whether or not the branch occurs.
    Formerly known as TonyB
  • TonyB_ wrote: »
    cgracey wrote: »
    Thinking about this more, I don't want to make this change.

    The trickiest aspect is cancelling potential registers writes that are part of some CALLs. I would need a new mechanism to do that with and it would certainly lengthen the timing, as those signals are now registered before the start of the 2nd clock, but would then require resolution into the 2nd clock. I don't want to go there. I don't think it's worth the risk or the congestion that slower paths would introduce.

    Thanks for trying, Chip.

    Is it possible for prefix 0000 to be decoded as IF_NEVER for definite branch instructions? SETNIB could change the top nibble to enable or disable the call or jump. Nothing else after the opcode would need fetching to determine whether or not the branch occurs.

    I suppose that could be done, but I wonder if it is really worth introducing a ripple into the design for. As well as a SETNIB instruction could enable the definite branch, a MOV could just move a whole instruction into place.
  • Cluso99Cluso99 Posts: 13,623
    edited February 1 Vote Up0Vote Down
  • TonyB_TonyB_ Posts: 456
    edited February 1 Vote Up0Vote Down
    cgracey wrote: »
    TonyB_ wrote: »
    Is it possible for prefix 0000 to be decoded as IF_NEVER for definite branch instructions? SETNIB could change the top nibble to enable or disable the call or jump. Nothing else after the opcode would need fetching to determine whether or not the branch occurs.

    I suppose that could be done, but I wonder if it is really worth introducing a ripple into the design for. As well as a SETNIB instruction could enable the definite branch, a MOV could just move a whole instruction into place.

    It's just an idea to use an otherwise disregarded prefix state and certainly not vital, I admit. A MOV would require another MOV to undo, whereas a prefix change would preserve the instruction (whatever it may be) and any branch address.

    No worries about a trap for beginners or which address bit to use as enable/disable.
    Formerly known as TonyB
  • Cluso99Cluso99 Posts: 13,623
    edited February 1 Vote Up0Vote Down
    Chip,
    A few years ago we discussed support for a USB NRZI instruction to help bit-banging the USB at Full Speed.
    While the Smart Pins mitigate this somewhat, I wonder if this is still possible and worthwhile for other uses.

    Here is the reference. Please note that I later realised that some of this had an error on my part and the solution was not correct, so it needs more refining. If it's possible to do something then I can work out the replacement solution.

    forums.parallax.com/discussion/151821/usb-helper-instruction-p2-possible-additional-instructions
    The bit-banging USB FS RX sequence for each bit currently is..
                  waitcnt   time, bittime           ' wait for next mid-bit sample time 
                  test      K, ina          wz      ' read usb pin
                  muxz      bits, bitmask   wc      ' b30 (mux mask for rx inbound xor register)
                  shl       bits, #1                ' shift new xor'd in bit to b31 (to prev bit)
                  test      JK, ina         wz      ' SE0 ? (ie EOP ?)
            if_z  jmp       #waitforend             ' y: wait for end
                  rcl       data, #1                ' accumulate bit into data byte
                  rcl       stuff, #6       wz      ' accumulate 6 bit blocks. If zero we need to unstuff next bit
                'currently no time to accumulate the crc16 here. A 1bit crc instruction has now been done :)
            if_z  call      #unstuff 
    

    To aid in bit-banging (reading) USB FS, I was trying to replace the following sequence with a single instruction...
            TEST     K,INA        WZ
            MUXZ     NRZI,MASK30  WC
            SHL      NRZI,#1
    ' C now holds the data bit value (not the read bit value)
    
    This would allow time to insert the new CRC generation instruction into the sequence.

    This instruction would also be useful for processing any bit-banging NRZI signalling and perhaps any bi-bit signalling too.

    Here was one previous possible solutions, although now I don't think it works quite the way I wanted ???
    CXORPIN [#]D [WZ],[WC]
    
    WC: C = C XOR PIN# where pin# is 0-127
    WZ: X = state of PIN#
    

    Similarly, I don't think this quite works...
    GETUSB [#]D WZ,WC 
    
    D = pin no (0..127)
    C = C XOR PINx
    Z = ! ( PINx OR PINy ) 'ie ZERO if both PINx and PINy are ZERO; PINy = PINx XOR #1
    Note1: PINx and PINy are a pair of pins. If PINx is even then PINy := PINx + 1 else if PINx is odd then PINy := PINx - 1
    - The allowance for the PINx/PINy pair to be reversed is for USB LS & HS where J/K are effectively swapped between D-/D+.
    Note2: WZ & WC could be permanently set on if required.
    
  • Cluso99,

    I'm having trouble understanding your post.

    Could you give a step sequence, or even code sequence, that would be certain? Even a description of what is needed. I could go from that.

    This would not be that hard to add, I think.
  • Cluso
    What about something like this for GETUSB
    getusb	testpn	#pinx wz
    	testpn	#piny andz
    	testp	#pinx xorc
    
    Melbourne, Australia
  • ozpropdev wrote: »
    Cluso
    What about something like this for GETUSB
    getusb	testpn	#pinx wz
    	testpn	#piny andz
    	testp	#pinx xorc
    

    So, Z = 1 if pins x and y are both low, and C = !C if pin x is high?
  • cgracey wrote: »
    So, Z = 1 if pins x and y are both low, and C = !C if pin x is high?
    I believe that's what Cluso was looking for.

    Melbourne, Australia
Sign In or Register to comment.