. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
For anyone who wants to see, here is the Verilog code that makes up the interrupt system. The only thing you're not seeing here is the LINK instruction mux in the pipeline and the event sources, both of which are almost nothing to look at.
This was 4-spaces-per-tab in Quartus, but I reformatted it to 8-spaces-per-tab so that you can look at it in Notepad, if you want:
How about a single HOLDINT instruction that takes a 3-bit mask.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
How about a single HOLDINT instruction that takes a 3-bit mask.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Chip, do the hub long r/w interrupts work with WORD and BYTE read and writes too?
It looks fantastic. Cannot wait to try them!
Any write within a sensitive %0000_0000_0000_00xx_xx00 boundary will trigger the event. If you write an overlapping word or long, you would cause two events! Same sensitivity for reading.
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
That is a quite common use in MCU interrupts.
Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.
Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.
Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Most small MCUs (even the 25c ones) have individual enables on interrupts.
An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
That is a quite common use in MCU interrupts.
Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.
Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.
Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Most small MCUs (even the 25c ones) have individual enables on interrupts.
An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.
You could always do a 'SETINTx #0' to shut off an interrupt source. When you turn it back on later, it would resume responding to its selected interrupt source. It's stateless that way. Does that suffice?
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues GETPER opcode minus WC& GETPER issues GETPER opcode, with required / user expected WC included by default.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.
How about a single HOLDINT instruction that takes a 3-bit mask.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?
If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.
If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.
I can see use cases where someone cuts and pastes code examples together.
Of course, any merge of interrupt code is going to need care, but if those code sections can cleanly manage their own interrupt flags there is much less effort needed, and the 'code reuse' mode Parallax strives for is easier.
How about a single HOLDINT instruction that takes a 3-bit mask.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?
If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.
If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.
Once you do SETEDG, you've selected the edge and source signal that will generate EDG events. There is a two-clock delay tied to SETEDG that prevents false EDG events resulting from changing edge and pin settings. Once SETEDG is done, any resulting EDG events are going to set the EDG event flag. Any GETEDG/WAITEDG instructions will clear the EDG event flag. If you select EDG as an interrupt source, the EDG event is used directly, neverminding the EDG event flag. The event flags are just there for the GETxxx and WAITxxx instructions. Interrupts don't use them. Signals that set event flags are also what trigger interrupts.
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues GETPER opcode minus WC& GETPER issues GETPER opcode, with required / user expected WC included by default.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.
Ah, yes, single-stepping. We could use some high bit in the SETBRK instruction to set that mode. I think all it would have to do is break on ANY address. One bit and one OR gate in addition to the comparator.
I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.
Here is a program:
dat org
mov dira,#%1111 'make pins 3..0 outputs
mov ijmp0,#isr0 'set int0 vector setbrk brk 'set single-step breakpoint setint0 #7 'enable single-step interrupt
:loop xor outa,#%0001 'this routine is getting single-stepped xor outa,#%0010 xor outa,#%0100 jmp @:loop
isr0 xor outa,#%1000 'this is the single-step interrupt routine reti0
brk long 1<<20
And here is what it looks like running (D3..D0 are pins 3..0):
The Prop2 is running at 20MHz, so each clock period is 50ns. The interrupt service routine is toggling the top square wave every 600ns, or 12 clocks, or 6 instructions. Here's what is executing:
XOR outa,#%0001 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0010 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0100 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dJMP @:loop 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'd<repeat>
I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.
Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?
I got the single-step interrupt working. The rule is: break when no interrupt service routine is executing. I'm changing that to allow for breaking within INT1 and INT2, though.
Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?
It would wait until multi-cycle opcodes finished before inserting the LINK. I must test that to see what it looks like.
You can't step within a REP. Maybe you could fake it, though. You can never step through an INT0 routine, of course, unless you faked that, too.
I've never thought much of adding hardware for debug assistance. Hand crafting debug code works a treat really. ISRs aren't much different to mainline then. Chip has just done one typical hand coded debug type exercise right above.
I've never thought much of adding hardware for debug assistance. Hand crafting debug code works a treat really. ISRs aren't much different to mainline then. Chip has just done one typical hand coded debug type exercise right above.
?? The above is the basic framework for single step debug, and that does need hardware assistance.It is that hardware assist, that Chip is testing.
I've got it stepping through INT1 and INT2 code now, as well as mainline code. I would like it to be able to do INT0, but that means we need one higher level of interrupt just for debugging. I'm looking into using the hidden RAM registers behind INA and INB for the interrupt LINK target. This way, you could single-step and breakpoint your entire application during development. I just need a gate to cut off reading INA and INB within the debug ISR so that I can read the RAM data behind them. The debug ISR can be a hub-exec affair.
I've never thought much of adding hardware for debug assistance. Hand crafting debug code works a treat really. ISRs aren't much different to mainline then. Chip has just done one typical hand coded debug type exercise right above.
I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
That's more an upper-level software issue, than a Single Step debug problem. (Plenty of sub standard Debuggers out there.)
Good simulators give users single-step debug, with 100% visibility, and they certainly are easy to use.
I would like it to be able to do INT0, but that means we need one higher level of interrupt just for debugging. I'm looking into using the hidden RAM registers behind INA and INB for the interrupt LINK target. This way, you could single-step and breakpoint your entire application during development.
because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
I think BLOCK prevents or defers or pauses or ignores interrupts - then, the details matter :
Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?
Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.
because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
I think BLOCK prevents or defers or pauses or ignores interrupts - then, the details matter :
Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?
Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.
Comments
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
This was 4-spaces-per-tab in Quartus, but I reformatted it to 8-spaces-per-tab so that you can look at it in Notepad, if you want:
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
Chip, do the hub long r/w interrupts work with WORD and BYTE read and writes too?
It looks fantastic. Cannot wait to try them!
IDEFER and IPERMIT work for me, makes it clear the flags are pending in nature. I presume all INT flags can be cleared manually, if the user wants only new-ints ?
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Chip, do the hub long r/w interrupts work with WORD and BYTE read and writes too?
It looks fantastic. Cannot wait to try them!
Any write within a sensitive %0000_0000_0000_00xx_xx00 boundary will trigger the event. If you write an overlapping word or long, you would cause two events! Same sensitivity for reading.
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
That is a quite common use in MCU interrupts.
Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.
Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.
Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Most small MCUs (even the 25c ones) have individual enables on interrupts.
An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.
I don't have a clear-pending-interrupts mechanism, but it would be trivial to add. Can you give a case where that would be needed?
That is a quite common use in MCU interrupts.
Sometime you want to know you are timing/starting a state engine from an edge about to arrive, not one that (may have) arrived at some unknown time in the past.
Sometimes sticky bits are useful, and sometimes they are a royal pain, so a means to clear sticky bits is important. Users can then simply choose which they need. A clean slate, or a deferral approach.
Also, (as I've mentioned before) it is ideal if the time to vector from that event is jitter free.
The old Scenix parts managed that, IIRC - and it keeps with the Prop's solidly deterministic philosophy.
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Most small MCUs (even the 25c ones) have individual enables on interrupts.
An example of where you may want to not disable an INT is Watchdog/COP operation, where a small stub of code, checks the pulse of the COG SW, and tries to catch lockups and freezes.
Of course, sometimes you do need to turn off all INTs (briefly), and a global flag does that.
You could always do a 'SETINTx #0' to shut off an interrupt source. When you turn it back on later, it would resume responding to its selected interrupt source. It's stateless that way. Does that suffice?
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues GETPER opcode minus WC& GETPER issues GETPER opcode, with required / user expected WC included by default.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?
If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.
If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.
Seems to me the majority use case will be to take third party code and run it on a COG like we do now on P1.
And where that is true, the clash of interrupts really isn't an issue.
Of course, any merge of interrupt code is going to need care, but if those code sections can cleanly manage their own interrupt flags there is much less effort needed, and the 'code reuse' mode Parallax strives for is easier.
HOLDINT #%111 ' Hold all interruptsHOLDINT #%011 ' Hold INT0 and INT1HOLDINT #0 ' Release all pending interrupts
Just AND the ~MASK bits to see if an interrupt can be inserted! I suppose you could invert the instruction itself (INTMASK?), but that feels a little less natural.
It would be easy to add this, but why would you want to hold off certain interrupts, instead of just all of them? I guess I haven't written much ISR code where I might have realized the need for such a thing.
Well, that depends. If I call SETEDG, is that enough to be able to use GETEDG and WAITEDG? Or do I have to also call SETINTx?
If GETxxx/WAITxxx only works with SETINTx, then you also need a mask to prevent insertion of LINK instructions.
If SETINTx is not required, then a single flag is probably good enough. The only reason I can otherwise think of having a mask is that you may be combining third-party code (which is more likely to happen with the P2) that each use interrupts. In that case, you wouldn't necessarily want one routine to inadvertently disable interrupt for an unrelated routine.
Once you do SETEDG, you've selected the edge and source signal that will generate EDG events. There is a two-clock delay tied to SETEDG that prevents false EDG events resulting from changing edge and pin settings. Once SETEDG is done, any resulting EDG events are going to set the EDG event flag. Any GETEDG/WAITEDG instructions will clear the EDG event flag. If you select EDG as an interrupt source, the EDG event is used directly, neverminding the EDG event flag. The event flags are just there for the GETxxx and WAITxxx instructions. Interrupts don't use them. Signals that set event flags are also what trigger interrupts.
Ah, those sticky bits can be cleared by just doing a GETxxx. For example, GETPER without WC would clear the timer's sticky bit, even though you didn't capture it into C.That's probably OK, tho hiding that in WC is perhaps too obtuse, and Assembler psuedo ops would be better.eg CLRPER issues GETPER opcode minus WC& GETPER issues GETPER opcode, with required / user expected WC included by default.
The interrupts, though, engage on the first clock of the event, never minding any sticky bit states. The are going to fully resolve back to idle before your mainline code gets any instructions in.
A common minor variant on that, used on small MCUs is to execute one mainline code op, before next interrupt.That allows single-step debug/monitor to be coded using interrupts & also prevents 100% stall on interrupt miss-handle.
Ah, yes, single-stepping. We could use some high bit in the SETBRK instruction to set that mode. I think all it would have to do is break on ANY address. One bit and one OR gate in addition to the comparator.
Here is a program:
dat org
mov dira,#%1111 'make pins 3..0 outputs
mov ijmp0,#isr0 'set int0 vector setbrk brk 'set single-step breakpoint setint0 #7 'enable single-step interrupt
:loop xor outa,#%0001 'this routine is getting single-stepped xor outa,#%0010 xor outa,#%0100 jmp @:loop
isr0 xor outa,#%1000 'this is the single-step interrupt routine reti0
brk long 1<<20
And here is what it looks like running (D3..D0 are pins 3..0):
The Prop2 is running at 20MHz, so each clock period is 50ns. The interrupt service routine is toggling the top square wave every 600ns, or 12 clocks, or 6 instructions. Here's what is executing:
XOR outa,#%0001 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0010 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dXOR outa,#%0100 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'dJMP @:loop 'mainline codeLINK $1F4,$1F5 wc,wz 'interrupt LINK occursNOP 'pipeline NOP'dXOR outa,#%1000 'interrupt codeJMP $1F4 wc,wz 'interrupt codeNOP 'pipeline NOP'd<repeat>
Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?
Looks good - how does that cope with REP, and multi-cycle opcodes ?I guess they complete, then yield to the Stepper-INT ?
If users wanted to step within a REP, the debug SW could swap-in TRAP type opcodes ?
It would wait until multi-cycle opcodes finished before inserting the LINK. I must test that to see what it looks like.
You can't step within a REP. Maybe you could fake it, though. You can never step through an INT0 routine, of course, unless you faked that, too.
?? The above is the basic framework for single step debug, and that does need hardware assistance.It is that hardware assist, that Chip is testing.
I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
I agree, but single-stepping can be great for learning how an architecture works. I've never had a single-stepping debugger that was easy to use, though. The setup has always been way more troublesome than some little ad hoc solution.
That's more an upper-level software issue, than a Single Step debug problem. (Plenty of sub standard Debuggers out there.)
Good simulators give users single-step debug, with 100% visibility, and they certainly are easy to use.
I would like it to be able to do INT0, but that means we need one higher level of interrupt just for debugging. I'm looking into using the hidden RAM registers behind INA and INB for the interrupt LINK target. This way, you could single-step and breakpoint your entire application during development.
That certainly would have appeal.
BLOCKI - block interrupts
ALLOWI - allow interrupts - default
because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
I think BLOCK prevents or defers or pauses or ignores interrupts - then, the details matter :
Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?
Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.
BLOCKI - block interrupts
ALLOWI - allow interrupts - default
because you use block elsewhere, a better name and clearer description would help those who are not native English speakers.
I think BLOCK prevents or defers or pauses or ignores interrupts - then, the details matter :
Are pending flags responded to on ALLOWI, or are they discarded, and only those after ALLOWI acted on ?
Interrupts are still gathered after BLOCKI and then responded to after ALLOWI.
I think 'defer' is the most descriptive word: DEFERI. Makes a wierd-looking instruction, though. IDEFER would be better, but that doesn't work for IALLOW. We need another word for 'allow' that starts with a consonant. IPERMIT? IDEFER and IPERMIT sound first-person and lawyerly. I agree about the conflict with the word BLOCK. Maybe the fast hub read/write block should be termed a FRAME with 'reload' rather than a BLOCK with 'wrap'.
I never heard or used the word defer (I'm german). Block I understood. That a interrupt is gathered I would have expected.Hold would also be good. Permit is ok.Frame for the read/write block would be ok.
Hold and Allow or Hold and Free would also be ok.
Perhaps even Hold and Release?
I am german too ...
There is a great web site and mailing list: one-word-a-day
so defer is the word of the day ;-)