6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat May 11, 2024 4:50 am

All times are UTC




Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Sat Oct 20, 2018 3:46 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
About carry: I was surprised to see some odd use of the carry with respect to SBC in the recently uncovered source to the Furby toy. Possibly the programmers came from the other tradition and didn't have time to flip their brains, or didn't realise that's what they needed to do.

Code:
; remember SBC if there is a borrow carry is CLEARED
; also SBC if the two numbers are equal you still get a negative result
...
LDA Task_ptr ; get it
CLC
SBC #08 ;ck if off end
BCC Ck_tsk_A ;jump if <9


About the target speed of a new microprocessor implementation: I think the process starts with deep thought and sketches. These days, in the teams I'm familiar with, the microarchitecture is designed with a target logic depth in mind, which is derived from the target speed for the application, the expected performance of the code and compiler, and the expected gate delay in the target process. Lots of variables there. Back in those days, it was harder, although the machines were simpler. To a degree, you can speed up a logic path by making drivers bigger, but that presents more load to their drivers, and so on, and the power use goes up. Sometimes that's felt to be a good deal, other times not.

I suspect with the 6502, the 16 bit PC increment was expected to be important, and that part was carefully designed, and whatever logic has to act to control the increment would also be sketched out. At this point, the ease of decoding the instructions could be relevant: if it's easy to spot the single-byte instructions, and the branches, that might help a lot. So the instruction encoding comes into play. In a way, it's easiest if there's an obvious critical path which will surely be the limit, as it means you can focus on that. The 8 bit ALU carry path is likely to be important, as is, possibly, the BCD correction logic. An optimal design would have lots of paths very close to critical: nothing is faster than it needs to be, and there's no "long pole" which is limiting performance. These days a lot of chip design sticks to a discipline of synchronous flop-based design, which can be timing-analysed so all possible paths are known and bounded. Back in those days, you'd need to rent time on a remote minicomputer to do a circuit simulation, which might take overnight or over a weekend, so you'd only be able to simulate 10 or 20 logic gates. Probably slide rules, and rules of thumb, came into play.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 1:53 am 
Offline
User avatar

Joined: Sun May 20, 2018 7:20 pm
Posts: 20
Thanks BigEd!

Next weekend, I think I'm going to make the following changes to my ISA and then call it done:

1. Rename SBB -> SBC and double-down on the carry/not-borrow bit.

2. To heck with the ISA encoding scheme, I'll add LDB/STB/TAB/TBA/PHB/PLB in some of the free instruction slots I have (anyways, I can sort-of explain my way out of where I'm putting them logically, so maybe it's not so much of a stretch to have it). This will allow me to rename zero-page addressing mode to base-page addressing mode, where the page we act upon may be set/stored by the provided instructions. I want to avoid calling it direct addressing mode since it's a little different in that it still acts exactly like zero-page in 6502, but you may set the page we act upon to any page (but cannot set to some random page offset, like 0x0213, basically BP will be a register connected directly to the ADH bus, and control lines will signal that instead of bus drains to prepare for zero-page access). I think this will give the K65 a neat difference to set itself apart as a fun little ISA, with a mostly-complete set of instructions. (Though I am going to do one more pass on the addressing modes and see if I want to change anything.)

I'll still need to add some more unit tests, specifically I think there is an issue with the current implementation involving how interrupts are handled. But after this change I think my ISA will be pretty much set in stone for this particular project. Thank you all so much for all the feedback and advice! If you have anything more to say, please don't be afraid to, or just general comments. Otherwise, I'll consider this feedback thread complete.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 2:34 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
TrentoReedo wrote:
This will allow me to rename zero-page addressing mode to base-page addressing mode, where the page we act upon may be set/stored by the provided instructions. I want to avoid calling it direct addressing mode since it's a little different in that it still acts exactly like zero-page in 6502, but you may set the page we act upon to any page (but cannot set to some random page offset, like 0x0213, basically BP will be a register connected directly to the ADH bus, and control lines will signal that instead of bus drains to prepare for zero-page access). I think this will give the K65 a neat difference to set itself apart as a fun little ISA, with a mostly-complete set of instructions. (Though I am going to do one more pass on the addressing modes and see if I want to change anything.)

Consider what Jeff wrote here, regarding the 65816:
    Quote:
    For me there was a big light bulb that went on when I realized that a TSC instruction followed by a TCD puts your Direct Page on stack. Suddenly Direct Page ceases to be a crowded place! And you get some amazing new address-mode flexibility -- for example being able to use a three-byte indirect pointer that's on-stack.

    My admiration for the '816 designers went up several notches. The 256 super-flexible processor registers that Garth mentioned can be a stack frame! Despite certain downsides it's an idea which IMO gives '816 programming a whole new level of sophistication as compared to 6502/65C02.

    And, speaking of 3-byte pointers: the "16-bit version" generates 24-bit addresses, so that's a huge step up from what the '02 and 'C02 can do!

Quote:
Otherwise, I'll consider this feedback thread complete.

Nothing on 6502.org is ever complete! :lol: Projects continue for years, and the learning and the collection of information never ends.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 2:40 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
TrentoReedo wrote:
base-page addressing mode [...] I want to avoid calling it direct addressing mode
The word "base" maybe isn't the most descriptive. Is there anything else you could call it? If not, never mind -- I'm just nit-picking. Certainly "base-page" is a big improvement over "direct-page" (which results in confusing, oxymoronic combinations such as "direct indirect" address mode!). :roll:

Quote:
you may set the page we act upon to any page (but cannot set to some random page offset, like 0x0213, basically BP will be a register connected directly to the ADH bus, and control lines will signal that instead of bus drains to prepare for zero-page access). I think this will give the K65 a neat difference to set itself apart as a fun little ISA
Sounds good. The 65CE02 works this way, IIRC. As for the more complex idea of being able to "set to some random offset, like 0x0213," that's a tradeoff, implying both costs and benefits. You need an adder, and the adder will consume a cycle (and some imaginary silicon, of course). The benefit -- which is not a small one! -- is being able to use the "Direct Page Register" (I'm using the 65816 term) as an extra index register. To mention just one example, copying S to the DPR allows the fancy Direct-Page address modes to apply to a hunk of space on stack. :!:

[Oops, I see Garth just posted this example as I was typing. There are other examples, too, though perhaps not as dramatic. ]

Two quick parting comments. Instead of (or in addition to) adding new register transfer instructions (eg: TYX), consider adding one or more register exchange instructions. Unlike transfer instructions, they wouldn't destroy any on-chip information that might need to be reloaded from memory later. And, re JMP indirect (mentioned earlier in this thread): if you find this difficult to do in one instruction then maybe your new ISA can allow the equivalent but using two instructions. IOW you don't need a direct replacement. In fact, two separate instructions may prove more flexible (ie, each of them could combine with other instructions; they needn't always be used with each other).

cheers
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Mon Oct 22, 2018 3:01 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 2:59 am 
Offline
User avatar

Joined: Sun May 20, 2018 7:20 pm
Posts: 20
(Note: I will think about the naming here before making the change, but for now I will call it "base-page addressing mode" to keep things sensible in this discussion.)

This change would modify all existing "zero-page" like addressing modes to be "base-page" like (perhaps I wasn't clear in describing this, if not I apologize). So for example, "zero-page, X-indexed" will become "base-page, X-indexed". You would be able to simulate a zero-page access by LDB #00 before using any of these addressing modes. While I believe I can easily fit a BP register for a multiple of 0x0100 offset since it'd only require one new 8-bit register connected to ADH (by setting BP, which drives ADH in base-page addressing modes), I really don't think I can fit anything more complicated without serious redesigns at this time. However, I imagine you could accomplish a similar thing with base-page, x-indexed addressing mode.

Code:
LDB #01
TSX
; Access stack values using base-page, x-indexed


I will think seriously on the JMP indirect equivalent, that's a good thing to call-out. Thanks!


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 3:35 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
TrentoReedo wrote:
I really don't think I can fit anything more complicated without serious redesigns at this time.
Right -- that sounds sensible.

Quote:
However, I imagine you could accomplish a similar thing with base-page, x-indexed addressing mode.
To some extent, yes. What's missing is the ability to efficiently index twice -- both pre- and post-indirection. Forth is just one context where this is extremely handy. Very often on stack you'll have a pointer to a multi-byte structure, and generally you'll wanna index into that structure. I'm not trying to talk you into undertaking a serious redesign; I'm just blabbering about the "both pre- and post-indirection indexing" thing; which, on an '816, is possible with (d,s),y mode or with TSC then TCD, followed by use of (ind),y or [ind],y mode.

Double indexing is also incorporated in an ISA redesign of my own. Again it's a two-instruction sequence (illustrating that other point), and it accelerates a key Forth primitive by 89%. For details, see X-Indirect-Y Addressing Using the W Register, part of the article about my mutant 65C02 KK Computer.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 3:40 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
As a postscript on the SEC/CLC thing, it's worth noting that most CPUs (but not the 6502) have ADD and SUB which don't take the prior carry flag as an input, as well as ADC and SBC which do. On modern CPUs, the registers and ALU are wide enough that the use of ADC and SBC is quite rare - and in fact the C language has no direct support for the equivalent operations, despite often being described as a sort of portable assembly language. In the 8-bit world, however, multi-precision arithmetic is essential and arguably more common than pure 8-bit arithmetic, so the carrying instructions took precedence in the instruction set.

For programmers prone to forgetting SEC/CLC, you can define macros named ADD and SUB which simply prefix ADC and SBC with CLC and SEC respectively. You can then code as if you have "modern" ADD and SUB instructions to use at the start of your carry chains.

It must be remembered that, when first released, the 6502 was the cheapest microprocessor on the market, and not by a small margin. That was in large part achieved by making the hardware as simple as possible, allowing it to fit on a small slice of silicon. That MOS had a comparatively high-yield NMOS process to manufacture it with also helped a great deal, but the minor sacrifices of making the instruction set subordinate to the hardware design (rather than vice versa) were instrumental.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 22, 2018 4:38 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
All good points, Chromatix.

Also, it highlights another instance of how a simple sequence (CLC / ADC) can adequately replace a "missing" instruction (ADD), and of course the comparable case involving subtraction.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 28, 2018 6:34 pm 
Offline
User avatar

Joined: Sun May 20, 2018 7:20 pm
Posts: 20
I decided I'm sticking with the name "base-page", for one it seems to me like a natural naming evolution from "zero-page", but also I found in the 65CE02 datasheets they actually refer to this style of addressing mode as "base-page" as well! (http://archive.6502.org/datasheets/mos_65ce02_mpu.pdf) I feel pretty good about this addition, and though I know more now about ISA layout and what would make better instructions to add, I'm going to lock into my current design and deal with what I've made - I think it'll be a fun experiment, and I don't think I'd be too particularly limited.

Some new thoughts that I'd like to seek feedback on, though:

Different Functionality for WAI Instruction

I changed how WAI works (originally had this concept named WFI, or "Wait For Interrupt", but renamed to WAI to match the WDC 65C02). How I understand WAI works in something like the 65C02 is that it'll effectively block where it might've once considered the instruction complete (SYNC point), and wait for an interrupt so that it may be handled immediately (to avoid being in a state where we may not be in a SYNC point due to an infinitely branching loop or something to simulate a wait). One feature of this is that it allows maskable IRQs to interrupt the WAIT, but if the IRQ is masked we will just continue from where we were in code (aka a "super-fast interrupt"). The way I have constructed WAI is that it's basically BRK, but it pauses right before going to sample the interrupt vector until one of the internal interrupt-pending flip-flops is brought high, at which point we stop waiting and continue executing the WAI which shortens the time-to-respond of an interrupt.

A side-effect of this change is that this 1-cycle "super fast" masked IRQ interrupt is not possible, a masked IRQ in this model would just literally be a masked IRQ, nothing other than an actual interrupt that we would expect to be handled would allow execution to continue. The benefit of this model is that we speed up the path for actually handling an interrupt though by doing everything we can do while we wait for an interrupt to come in. So, for example, we can push elements onto the stack (PC and PS), and then wait to fetch from the interrupt vector until we know what we want to fetch.

The logic looks something like this:
1. Prepare ADH (0x01)
2. Move S into BI and 0xFF into AI to process stack decrement, use current S as ABL to write PCH.
3. Move ALU result back into AI to process next stack decrement, use new S as ABL to write PCL.
4. Move ALU result back into AI to process next stack decrement, use new S as ABL to write PS.

At this point we block on PHI2 (NRDY high) until an interrupt passes through to the internal pending flip-flops. Then:

5. Takes one cycle to allow the pending flip-flop to propagate from the pin input, promote pending interrupts to processing interrupts and continue.
6. Receive Interrupt Vector Low (depending on which flip-flop is promoted to processing).
7. Receive Interrupt Vector High (depending on which flip-flop is promoted to processing), at this point we can construct full address that we should update PC/AB to read the next instruction.
8. AB read propagates from DB to PD, we are in a good state to continue executing now.

This means we immediately handle the interrupt, and responding to an interrupt only takes 4-cycles (as opposed to 7-cycles + N-cycles due to SYNC offset for NMI/IRQ since we cannot interrupt mid-instruction for those). However, with this mechanism "super fast" masked IRQ interrupts are not possible.

My main worries:
+ Really, I kind of like this logic - I think it's very clean and the code for this is very optimal from what I can tell. I didn't really have to "hack" anything in, because the K65 supports a NRDY pin which can be brought high to say that the processor is not ready to continue for one reason or another (external chips can also bring NRDY high, it basically is two-way and allows the processor to tell you it is not ready because it needs an interrupt, or that some memory controller external to the CPU is not ready because the read/write is not finished).
+ HOWEVER, I do worry since it is named the same as WAI that people who are familiar with WAI might be confused. Really this is more like a "Block For Interrupt", because we literally have to wait for an actual interrupt to continue. Should I rename this BLK or something like that to differentiate from WAI? Or should I restructure WAI to work like traditional WAI instead of doing my own thing here?

Different Functionality for Reset

On RES, it became painfully obvious that I'd really like the registers and PS to be set to some expected state (especially with the addition of the BP register). So one of the things I changed about BRK is that the last cycle we process an addition of 0x00 and 0x00, and then depending on if the processing interrupt is RES or not, we would signal a bunch of register sets (AC, IX, IY, BP, S) and update all of the PS flags (New State: cZI---vs) to get the processor into a known-good state. It does all this using existing busses and signal wires; so after the addition is processed the value 0x00 is on SB, and we conditionally turn all registers to sample SB if RES is the interrupt that we are handling.

Here are my concerns with where this might be confusing:
+ Right now, all registers get set to 0x00 - including S (stack pointer). I think I can fix this without increasing cycle count (I have a spot where 0xFF is on SB where we could conditionally set S without adding a bunch of new connections). This would add a new signal wire though - think it's worth fixing? (I'm leaning heavily on yes for this, actually - but would like opinions) One of the things I don't like about this change is it distributes the reset logic over two separate cycles - with the current implementation there is exactly one half-cycle during PHI2 that we sample to see if RES is processing to signal all the other important wires, so it's very logically (and physically?) compact in its current implementation.
+ Because we set the processor status flags based on the final addition of 0x00 and 0x00, this means that all PS flags are low except zero flag. I want to say this actually makes sense, because all registers have zeros in them - but I could see an argument against this by saying that the status of zero being set did not originate from any actual known operation of the program. I could fix this, but again this would require another signal wire to handle the special case of setting PSZ low instead of just re-using the ADDZxPSZ signal wire like I am now.

Interrupt Handling Worries

For convenience of the simulation, interrupts are scheduled by pulling the bits high on the PIN bitfield in the CPU structure. When scheduling an interrupt, the PIN bitfield is sampled during PHI1 and if an interrupt should be schedule, a "pending flip-flop" is set per interrupt to show that an interrupt is pending for the next available interrupt time (for NMI/IRQ this is during SYNC, for RES a pending interrupt can stop mid-instruction and reset the whole processor).
After these PIN values are sampled and persisted in "interrupt-pending flip-flops", when we reach a SYNC point, the pending flip-flops are checked to see if we ought to start processing any interrupts. At this point, if any pending flip-flops are sampled into another set of flip-flops called "interrupt-processing flip-flops", and we drain IR so that we force a BRK instruction into the execution.
How BRK works is, when it goes to sample the interrupt vector, the constants it constructs in ADL are based on the "processing flip-flops". Mostly this is to ensure that you can't trip up the interrupt handling by signalling IRQ one cycle, then NMI the next causing one byte from IRQ and one byte from NMI to be read (which would be invalid). Of the processing flip-flops there is an order of precedence - RES, NMI, IRQ, BRK. That is, a RES interrupt will take precedence over an NMI interrupt, and so on. At the end of handling the interrupt, we pull all processing and pending flip-flops low, marking the interrupt as complete.

This logic worries me for the following reasons:
+ Say NMI and IRQ happen at the same time, in this logic we will "swallow" IRQ and never handle it. I could, without the addition of new signal wires, allow them to be scheduled so that we don't lose an interrupt, but should we? Definitely a RES should swallow NMI/IRQ since we are resetting the system, but if we get NMI and IRQ, should we process NMI and then process IRQ, or just process the more "important" signal and swallow the other one?
+ Does the priority I have assigned make sense? Specifically I'm worried about NMI vs. IRQ - if IRQ is unmasked and scheduled along with NMI, and I support handling multiple interrupts by priority order, which one should we handle first? Which one should we handle second? Basically, if I handle NMI interrupt first, then IRQ, we will be in a state where we are executing for IRQ, and after we RTI we'll go back to handle NMI interrupt. Does this sound appropriate, or should I want to be left in a state where we are handling NMI first, then RTI to handle IRQ?


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 29, 2018 3:53 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Interrupts, first part:  If you want the speed, how about having the vectors in processor registers designed for the purpose, so you don't have to go out on the bus and read them when the urgency hits.  These processor registers can be loaded from memory before the interrupts are set up, when there's no urgency yet.  They could be changed at any time.  You could have as many as you have interrupt inputs.

Quote:
This logic worries me for the following reasons:
+ Say NMI and IRQ happen at the same time, in this logic we will "swallow" IRQ and never handle it. I could, without the addition of new signal wires, allow them to be scheduled so that we don't lose an interrupt, but should we? Definitely a RES should swallow NMI/IRQ since we are resetting the system, but if we get NMI and IRQ, should we process NMI and then process IRQ, or just process the more "important" signal and swallow the other one?
+ Does the priority I have assigned make sense? Specifically I'm worried about NMI vs. IRQ - if IRQ is unmasked and scheduled along with NMI, and I support handling multiple interrupts by priority order, which one should we handle first? Which one should we handle second? Basically, if I handle NMI interrupt first, then IRQ, we will be in a state where we are executing for IRQ, and after we RTI we'll go back to handle NMI interrupt. Does this sound appropriate, or should I want to be left in a state where we are handling NMI first, then RTI to handle IRQ?

As long as IRQ\ is a level-sensitive input, this problem will not occur.  Whatever is causing the interrupt will continue to hold the line down until you service it, whether an NMI\ hits at the same time or just before.  In the existing processors, any interrupt sets the I (interrupt-disable) flag, so concurrent or subsequent maskable interrupts won't be given any attention until you do a CLI or reach the RTI, whichever comes first.  NMI is edge-sensitive, so there won't be any more NMI's until you address the interrupting hardware and clear the condition.  If you clear it and it interrupts again before the ISR finishes, you've got other problems to tend to, as there is not adequate performance to do all that the programmer intended to do in the allotted amount of time.  The only solutions are to reduce the interrupt's frequency, or turn up the clock speed, or shorten the ISR.

In the reset sequence, certain registers will need initialization (like your BP, and like the 816's DP and bank registers); but I don't think there's any need for further initialization of P (the processor-status register) bits beyond what is done in the existing CMOS 65's.  The first thing normally done in the reset routine is LDX #$FF, TXS, which will already set N and clear Z.  The CMOS 65xx processors clear D and set I in the reset sequence.  B is not a physical bit, so that one is irrelevant until its position in the stacked record is examined in an ISR.  C may initially be wanted set sometimes and clear sometimes, so there's no point in initializing it in the reset sequence either.  V's initial value is never relevant unless you use the SO\ input; but if you do, it will get used multiple times and you'll need CLV in the program anyway.  (Jeff has some cool uses for that!)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2018 1:34 am 
Offline
User avatar

Joined: Sun May 20, 2018 7:20 pm
Posts: 20
Thanks for the feedback! :)

The interrupt registers idea is pretty cool, and I hadn't considered such a setup; do any chips actually do this?
I'll keep it in mind, but probably won't implement it in this design (for a number of reasons).
However, I have thought about this more and I've decided I'll rename my WAI mnemonic to avoid confusion of it working the same way.

GARTHWILSON wrote:
As long as IRQ\ is a level-sensitive input, this problem will not occur. Whatever is causing the interrupt will continue to hold the line down until you service it, whether an NMI\ hits at the same time or just before. In the existing processors, any interrupt sets the I (interrupt-disable) flag, so concurrent or subsequent maskable interrupts won't be given any attention until you do a CLI or reach the RTI, whichever comes first. NMI is edge-sensitive, so there won't be any more NMI's until you address the interrupting hardware and clear the condition. If you clear it and it interrupts again before the ISR finishes, you've got other problems to tend to, as there is not adequate performance to do all that the programmer intended to do in the allotted amount of time. The only solutions are to reduce the interrupt's frequency, or turn up the clock speed, or shorten the ISR.


I didn't realize IRQ was level-triggered, so probably I'll need to fix that. This is probably my lack of understanding of hardware here, but I still kind of don't understand how level-triggered IRQs don't occur multiple times. I originally assumed they were edge-triggered, and that you would signal when each interrupt should occur - learning that IRQ is level-triggered, and that BRK micro-ops set PS(I) high during any interrupt seems fine until we RTI (restoring PS). What tells the external hardware that the IRQ was handled? Do you basically have to signal it via some memory-mapped hardware register? I guess that would make sense, and maybe now I've talked myself into understanding it - but I'll still post in case I am misunderstanding here.

So is IRQ always treated like an alarm that you have to "do something to signal the external hardware that you handled"? VPB pin wasn't present in original 6502, and even if it were it doesn't provide context to which (if multiple) interrupt was being handled.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2018 1:41 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
The interrupting hardware needs to have the interrupt condition cleared by software in the ISR (interrupt-service routine).  It's all in my 6502 interrupts primer.

Garth, the interrupts junkie

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2018 4:23 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
TrentoReedo wrote:
I still kind of don't understand how level-triggered IRQs don't occur multiple times.
They will occur multiple times if you put a CLI in your ISR and it's too soon -- ie, it happens before you've cleared the interrupt source.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 30, 2018 6:46 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Dr Jefyll wrote:
TrentoReedo wrote:
I still kind of don't understand how level-triggered IRQs don't occur multiple times.
They will occur multiple times if you put a CLI in your ISR and it's too soon -- ie, it happens before you've cleared the interrupt source.

TrentoReedo, the 7-clock interrupt sequence includes pushing the processor-status register P onto the stack and then setting the interrupt-disable flag so you won't continue to just loop over and over and endlessly re-enter the ISR without finishing.  After you've cleared the interrupt condition in the IC that caused it, that is, the condition you're taking care of, you can re-enable interrupts like Jeff says, using CLI (CLear Interrupt-disable flag).  That's not normal though.  The reason you might do it is if you want a higher-priority interrupt that's quick to service to be able to interrupt the servicing of another interrupt whose priority is lower but takes longer to service.

Regardless, an NMI can always cut in on the servicing of an IRQ.  The NMI\ input is edge-triggered though, and there won't be any more edges until it is serviced.

Do not bracket your ISR with SEI and CLI.  Note also the time constant of the passive IRQ\ pullup.  These, too, are discussed in the 6502 interrupts primer linked above.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: