Proper 65C02 core
Re: Proper 65C02 core
Garth:
I have been bit by noisy, jittery clocks in FPGAs that I just never would have thought of your solution. In fact, DEC engineers used a similar technique in some of their microprogrammed CPUs to get behavior like you describe in order to match the execution of each microcycle to match the logic delays.
I have been bit by noisy, jittery clocks in FPGAs that I just never would have thought of your solution. In fact, DEC engineers used a similar technique in some of their microprogrammed CPUs to get behavior like you describe in order to match the execution of each microcycle to match the logic delays.
Michael A.
Re: Proper 65C02 core
MichaelM wrote:
I have been bit by noisy, jittery clocks in FPGAs that I just never would have thought of your solution.
Quote:
In fact, DEC engineers used a similar technique in some of their microprogrammed CPUs to get behavior like you describe in order to match the execution of each microcycle to match the logic delays.
best regards,
Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Proper 65C02 core
MichaelM wrote:
If your intent is to implement the core to execute a program from external memory, you will probably find that the Tcko values will require that the clock be slowed to 40 MHz or less. I've not sat down to consider how the input and output path delays would impact the achievable operating speed with an external asynchronous RAM.
Re: Proper 65C02 core
MichaelM wrote:
[...]
To implement the BRK in the manner described would require a change to the microcode to fetch the byte following the BRK into memory operand register, OP1. The external interrupt controller would then apply the value of the OP1 register as an offset to the value of the BRK vector.
[...]
To implement the BRK in the manner described would require a change to the microcode to fetch the byte following the BRK into memory operand register, OP1. The external interrupt controller would then apply the value of the OP1 register as an offset to the value of the BRK vector.
[...]
In any way, I think things would have been easier if the core accepted the Int, and, when ready, produced a 'Gimme the vector' signal, instead of an 'I'm following the vector now' signal. The interrupt controller could then tell that it's a BRK by the absence of other (higher priority) interrupts.
MichaelM wrote:
If your intent is to implement the core to execute a program from external memory, you will probably find that the Tcko values will require that the clock be slowed to 40 MHz or less. I've not sat down to consider how the input and output path delays would impact the achievable operating speed with an external asynchronous RAM.
Re: Proper 65C02 core
Windfall:
BRK would be signalled to the interrupt controller by a zero detector applied to the instruction register, IR. On the cycle that IR goes to zero, the microsequencer starts the first microinstruction of BRK. The vector is loaded into the operand register pair {OP2, OP1} in parallel with the the interrupt's register push sequence: {PCH, PCL, P}. During the cycle that P is being written to the hardware stack, the {OP2, OP1} register pair is loaded into PC, and on the following cycle, that address is presented to memory in order to load the first opcode of the ISR.
The first change to the BRK processing that would be required is that an extra state at the start would be required to capture the byte following the BRK into OP1. That byte, plus the BRK signal from IR, would allow the interrupt vector controller to modify the BRK ISR's vector.
I've not stopped to think too deeply on your suggested modification regarding the signalling of the interrupt controller from the core. It appears to be a valid approach, and I think that you could easily modify the core, or add a wrapper to the core, that would perform interrupt handling just as you suggest.
Quote:
MichaelM wrote:
[...]
To implement the BRK in the manner described would require a change to the microcode to fetch the byte following the BRK into memory operand register, OP1. The external interrupt controller would then apply the value of the OP1 register as an offset to the value of the BRK vector.
[...]
I think I may have to rephrase my question, because I just don't see it answered here : How is the BRK signalled to the 'interrupt controller', and what does it expect in return ?
In any way, I think things would have been easier if the core accepted the Int, and, when ready, produced a 'Gimme the vector' signal, instead of an 'I'm following the vector now' signal. The interrupt controller could then tell that it's a BRK by the absence of other (higher priority) interrupts.
[...]
To implement the BRK in the manner described would require a change to the microcode to fetch the byte following the BRK into memory operand register, OP1. The external interrupt controller would then apply the value of the OP1 register as an offset to the value of the BRK vector.
[...]
I think I may have to rephrase my question, because I just don't see it answered here : How is the BRK signalled to the 'interrupt controller', and what does it expect in return ?
In any way, I think things would have been easier if the core accepted the Int, and, when ready, produced a 'Gimme the vector' signal, instead of an 'I'm following the vector now' signal. The interrupt controller could then tell that it's a BRK by the absence of other (higher priority) interrupts.
The first change to the BRK processing that would be required is that an extra state at the start would be required to capture the byte following the BRK into OP1. That byte, plus the BRK signal from IR, would allow the interrupt vector controller to modify the BRK ISR's vector.
I've not stopped to think too deeply on your suggested modification regarding the signalling of the interrupt controller from the core. It appears to be a valid approach, and I think that you could easily modify the core, or add a wrapper to the core, that would perform interrupt handling just as you suggest.
Michael A.
Re: Proper 65C02 core
Arlet:
That's exactly the approach that I am taking. The address generator logic will deassert an internal Rdy signal whenever a non-sequential read address is to be the next address. If the address propogates out of this core to external memory, or other memory mapped logic, then the additional cycle provides sufficient time for the next level logic to take control of the Ack signal and further extend the memory cycle.
The real problem is ironing out the wrinkles in the gray matter that multiple, pipelined operations cause.
That's exactly the approach that I am taking. The address generator logic will deassert an internal Rdy signal whenever a non-sequential read address is to be the next address. If the address propogates out of this core to external memory, or other memory mapped logic, then the additional cycle provides sufficient time for the next level logic to take control of the Ack signal and further extend the memory cycle.
The real problem is ironing out the wrinkles in the gray matter that multiple, pipelined operations cause.
Michael A.
Re: Proper 65C02 core
Dr Jefyll:
No, just an affectation regarding comma separated lists of adjectives.
If I remember correctly: Am2925A.
No, just an affectation regarding comma separated lists of adjectives.
If I remember correctly: Am2925A.
Michael A.
Re: Proper 65C02 core
MichaelM wrote:
BRK would be signalled to the interrupt controller by a zero detector applied to the instruction register, IR. On the cycle that IR goes to zero, the microsequencer starts the first microinstruction of BRK. The vector is loaded into the operand register pair {OP2, OP1} in parallel with the the interrupt's register push sequence: {PCH, PCL, P}. During the cycle that P is being written to the hardware stack, the {OP2, OP1} register pair is loaded into PC, and on the following cycle, that address is presented to memory in order to load the first opcode of the ISR.
The first change to the BRK processing that would be required is that an extra state at the start would be required to capture the byte following the BRK into OP1. That byte, plus the BRK signal from IR, would allow the interrupt vector controller to modify the BRK ISR's vector.
The first change to the BRK processing that would be required is that an extra state at the start would be required to capture the byte following the BRK into OP1. That byte, plus the BRK signal from IR, would allow the interrupt vector controller to modify the BRK ISR's vector.
Re: Proper 65C02 core
MichaelM wrote:
The real problem is ironing out the wrinkles in the gray matter that multiple, pipelined operations cause.
Re: Proper 65C02 core
Windfall:
The default vector from the interrupt controller is the vector for IRQ. The interrupt controller is informed of BRK by the value in the IR. If the IR is zero, then the vector provided is that of either RST or IRQ. If BRK and RST occur simultaneously, then Reset takes priority. If BRK and NMI or IRQ occur simultaneously, then BRK takes precedence. Only if NMI occcurs simultaneously with IRQ does the interrupt controller provide the NMI vector.
Quote:
How is the BRK signalled to the 'interrupt controller', and what does it expect in return ?
Michael A.
Re: Proper 65C02 core
MichaelM wrote:
The interrupt controller is informed of BRK by the value in the IR. If the IR is zero, then the vector provided is that of either RST or IRQ.
Re: Proper 65C02 core
Windfall:
I just can't bring myself to hide all of the internal registers. Since I usually use ISim with its tendency to not connect to internal signals in buried modules, I simply bring out all of the important internal signals on the ports of the module so that I don't have to keep "reconnecting" to signals in buried modules. This technique can be a problem at the top-most level, but at the lower levels it provides visibility into the workings of a module with less effort.
The 65C02 does not have a separate vector for BRK. BRK and IRQ share the same vector. Apparently, the '816/'802 provides an option to separate the BRK and IRQ vectors. Catching whiff of this from the WDC datasheets, I decided to provide a mechanism for the M65C02 core to easily support separate vectors.
I would think that feature would be useful in any situation where backward compatibility with original 6502/65C02 software is not required. I just can't imagine the tediousness of testing the value of P on the stack to determine if the interrupt is due to IRQ or to BRK.
I just can't bring myself to hide all of the internal registers. Since I usually use ISim with its tendency to not connect to internal signals in buried modules, I simply bring out all of the important internal signals on the ports of the module so that I don't have to keep "reconnecting" to signals in buried modules. This technique can be a problem at the top-most level, but at the lower levels it provides visibility into the workings of a module with less effort.
The 65C02 does not have a separate vector for BRK. BRK and IRQ share the same vector. Apparently, the '816/'802 provides an option to separate the BRK and IRQ vectors. Catching whiff of this from the WDC datasheets, I decided to provide a mechanism for the M65C02 core to easily support separate vectors.
I would think that feature would be useful in any situation where backward compatibility with original 6502/65C02 software is not required. I just can't imagine the tediousness of testing the value of P on the stack to determine if the interrupt is due to IRQ or to BRK.
Michael A.
Re: Proper 65C02 core
MichaelM wrote:
I just can't bring myself to hide all of the internal registers. Since I usually use ISim with its tendency to not connect to internal signals in buried modules, I simply bring out all of the important internal signals on the ports of the module so that I don't have to keep "reconnecting" to signals in buried modules. This technique can be a problem at the top-most level, but at the lower levels it provides visibility into the workings of a module with less effort.
The real work lies in defining the signals that will always be there, regardless of future rewrites of the guts to exploit new ideas. Again, I would suggest modeling that after the original 65C02, with its 'ancient' interface, and leave the more flexible (and perhaps somewhat transient) interface available for those who want to make use of it. Supplying a top level that only exposes that 'ancient' interface (with perhaps a few obvious, minor tweaks, like avoiding tristate signals, or providing separate read and write strobes) can also serve as a good example of how to use the more advanced one.
Re: Proper 65C02 core
Michael :
There's a bug in your microcode. For _LDX_abs you have specified _RO_AbsX instead of _RO_Abs. I'm not sure how to generate the .coe file, so I did a bit of puzzling and managed to change it by hand to check if the fix worked, and it did.
There must be more bugs however, because a large piece of code I'm trying to run still gives wrong results, and it's hard to track down where it goes wrong (I came across the one I mentioned by accident, when I was testing something else). I could not find any obvious bugs in the microcode source, after looking at it for some time.
There's a bug in your microcode. For _LDX_abs you have specified _RO_AbsX instead of _RO_Abs. I'm not sure how to generate the .coe file, so I did a bit of puzzling and managed to change it by hand to check if the fix worked, and it did.
There must be more bugs however, because a large piece of code I'm trying to run still gives wrong results, and it's hard to track down where it goes wrong (I came across the one I mentioned by accident, when I was testing something else). I could not find any obvious bugs in the microcode source, after looking at it for some time.
Re: Proper 65C02 core
Windfall:
Thanks for the update. Hate that you found an error, but certainly appreciate the notification. I've established a repository for these files on GitHub.
I made the correction that you indicated, and also did another look through the source to find typos similar to the one you found. Did not find any additional errors of that kind. Have not gone back through my test program to determine how I missed the finding the error you found. It may be due to a zero value in the X register at the time the Abs,X indexing operation was performed. Still no excuse.
In the meantime, I uploaded the corrected M65C02_uPgm_V3 files (.txt and .coe) along with a listing file (.out). The listing file will help in making manual changes to the coe file when that is necessary. I am working toward releasing my simple microprogram assembler as a utility, but in the short term, I will not be able to release it as either source or executable.
The repository can be found at:
https://github.com/MorrisMA
Once again thanks for the heads up.
Thanks for the update. Hate that you found an error, but certainly appreciate the notification. I've established a repository for these files on GitHub.
I made the correction that you indicated, and also did another look through the source to find typos similar to the one you found. Did not find any additional errors of that kind. Have not gone back through my test program to determine how I missed the finding the error you found. It may be due to a zero value in the X register at the time the Abs,X indexing operation was performed. Still no excuse.
In the meantime, I uploaded the corrected M65C02_uPgm_V3 files (.txt and .coe) along with a listing file (.out). The listing file will help in making manual changes to the coe file when that is necessary. I am working toward releasing my simple microprogram assembler as a utility, but in the short term, I will not be able to release it as either source or executable.
The repository can be found at:
https://github.com/MorrisMA
Once again thanks for the heads up.
Michael A.