Open bernd-ulmann opened 4 years ago
The above description details the single step feature. What about the breakpoint feature ?
@MJoergen Well you are right: It is a single step feature only. The breakpoints are then implemented in software: If the hardware is able to break at every instruction, your debug ISR can check, i the address equals a breakpoint and/or if some other trigger conditions are met. I renamed the issue now to Hardware single step support.
Hi - basically, this feature can also be used for breakpoint handling in one of two ways:
A very :-) slow variant in which one turns the instruction-trap feature on, the ISR checks if the desired address is accessed for each instruction being executed. If the address is different, it just exits via RTI, if the address matches, it can do what ever is required at the specific break point.
Another variant would be to patch the code to be executed on the fly and replace the instruction found at the breakpoint address by an OR 0x0040, SR to switch to single instruction execution. The ISR must then take care of executing the instruction which was patched away. This "autopatch" feature could be included in the monitor, I think.
:-)
This is just a collection of implementation ideas so that we do not forget what we talked about:
We need some way to access the shadow registers used by ISR in order to display the PC when a single step interrupt occurred etc.
Therefore we need two additional instructions: RSR and WSR which will become new control instruction. The problem is that we have several shadow registers and not enough free bits in the current instruction format to code which shadow register to read or write. The idea is to do the following:
We reduce the current 6 bits which select which control instruction is to be executed to 3 bits, leaving three spare bits which can be used in conjunction with RSR and WSR to select the shadow register to be accessed.
The ugly thing is that we only have the lower 6 bits of a control instruction reserved for one operand, so we cannot distinguish between a source or destination operand. So RSR and WSR would both look like
RSR SPC, R0; here R0 is the destination WSR SPC, R0; while it is the source here
Change of plan! :-) At least slightly. I suggest (after sleeping over this issue) the following:
Instead of RSR/WSR which would be ugly due to the asymmetric handling of operands, we should introduce an EXC instruction which exchanges the contents of a shadow register with the contents of a "normal" register. Thus we have RSR and WSR in a single instruction which might come handy and solves the problem of using a destination operand as a source.
I also propose a slightly different way of encoding this new control instruction: As of now we use the six bits of the source operand to specify which of up to 64 control instructions is wanted. We will use the bit patterns 000000 to 011111 to specify "simple" control instructions (leaving is with up to 32 of those) and encode EXC with 1xxxxx where xxxxx is the number of the shadow register to be exchanged with a normal register. This allows up to 32 shadow registers for future developments and up to 33 (all in all) control instructions which should be plenty. Furthermore it does not break the way we already encode HALT, INT, RTI.
What do you think?
WOW! Bernd, from time to time you are showing the attributes of a true genius!
This idea is brilliant: Elegant. Non-breaking. (Q)Nice!
I could perfectly live with the slight inconvenience that when you want to make sure that the shadow register is exactly how it was, you always need to exchange twice ("in and out"). Compared with all the advantages I would say: Let's go for this.
Up to you Bernd:
Right now this must not be checked in to develop as we said V1.8. You would create a new branch "dev-v1.8" that we could use for that.
OR: As a non breaking change I would have no problem having this is 1.7 again. Then Bernd could do the Emu and I would enhance the CPU.
Up to you.
You are vastly exaggerating, but I am very happy that you like the idea! :-)
If you are OK with it, I will extend the documentation and emulator in the develop branch as it won't break any of our existing code. :-)
Absolutely OK. When done please do not close this issue but assign it to me as I need to implement it in hardware.
The assembler now understands the EXC instruction, the emulator, too, the documentation is updated, and both disassemblers (that in the emulator and the one in the monitor) also can disassemble the new instruction. Here is a sample code snippet:
.ORG 0x8000
MOVE 0x1000, R7
EXC SHSP, R7
HALT
EXC SHSP, R7
HALT
Hi Bernd, this issue is about the single step flag, too. Re-assigning...
Note to myself: Before closing this one: Volker's VASM does need to support EXC, too.
This issue is part of #67 and issue #66. We (Mirko and I) are thinking about breakpoint and single step support in QNICE and came up with the following idea:
We will use one of the two spare bits in the SR to denote a trap-on-instruction-fetch-feature. If set this will effectively cause a software interrupt every time a new instruction is fetched. Since this will be part of the CPU it will take precedence over any other interrupt and can also happen within an ISR. This bit will be called 'S' for single step.
When an instruction fetch triggers this feature, the current SR, PC, and SP are copied to a shadow register set as usual with out interrupt processing. After that this bit will automatically be cleared so that the ISR will proceed normally. Exiting the ISR with RTI will automatically restore the aforementioned registers and thus implicitly set this control bit again.
We will extend the three existing shadow register for interrupt processing (PC, SR, SP) by a fourth shadow register which will contain the ISR address for this feature.
The control instruction group will be extended by two additional instructions: RSR (read shadow register) and WSR (write shadow register). These allow to read/write all of the existing (and future) shadow registers. The number of the shadow register being read/written is specified in the src/dst field while the destination/source register/memory cell is specified in the dst/src field.