Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly is an interrupt?

I want to understand what exactly an interrupt is for my 6502 work-alike processor project in Logisim. I know that an interrupt does the following steps:

  1. Stops the current program from processing

  2. Saves all unfinished data into the stack

  3. Does "SOMETHING"

  4. Loads back the unfinished data and let's the program keep running normally.

    My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location? If so, where is that special program usually stored in the memory? And can you make such a CPU that will handle different kinds of interrupts? Maybe if you press the button "a" then it's ASCII will be stored in A register, but if you press the button "b" then it will be stored in X register?

Any help is greatly appreciated.

Edit: Thanks to everybody for answers. I learned a lot and now can proceed with my project.

like image 592
Senijs Avatar asked Mar 21 '19 11:03

Senijs


People also ask

What is the purpose of interrupt in computer?

In system programming, an interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code the processor is executing.

What are the types of interrupts?

Types of Interrupts. When a Process is executed by the CPU and when a user Request for another Process then this will create disturbance for the Running Process. This is also called as the Interrupt. Interrupts can be generated by User, Some Error Conditions and also by Software’s and the hardware’s.

What happens when an interrupt request is made?

The requested action is performed. An interrupt is enabled and the interrupted program is resumed. When more than one device raises an interrupt request signal, then additional information is needed to decide which device to be considered first.

What is an interrupt service routine?

It alerts the processor to a high-priority process requiring interruption of the current working process. In I/O devices one of the bus control lines is dedicated for this purpose and is called the Interrupt Service Routine (ISR) .


3 Answers

My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed?

What happens with a 6502 maskable interrupt is this:

  • the interrupt is raised (by this I mean the interrupt pin on the chip is forced low.
  • when it's time to execute a new instruction, the 6502 checks if the interrupt pin is low and the interrupt mask in the status register is not set. If either is not thew case i.e. if the interrupt pin is high or the interrupt mask is high, the CPU just carries on.
  • Assuming an interrupt is required, the CPU saves the PC on the stack
  • The CPU then saves the status register on the stack but with the B bit set to 0. The B bit is the "break" bit. It would be set to 1 for a BRK instruction and that is the only way to tell the difference between a hardware interrupt and a BRK instruction.
  • The CPU then fetches the address at locations $FFFE and $FFFF and stuffs it into the PC, so execution begins again at that address.

That's all it does. Everything else is up to the programmer until the programmer executes an RTI, then the status word and the return address are pulled off the stack and restored into their respective registers. It is the programmer's responsibility to save any registers and other data.

Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location?

That is correct. In 6502 based computer systems, there are three vectors at the top of memory:

$FFFA - $FFFB : Non maskable interrupt (as above except the I bit in the status register is ignored).

$FFFC - $FFFD : Reset vector used when the CPU detects a reset

$FFFE - $FFFF : Normal interrupt vector.

The above are usually in ROM because the reset vector (at least) has to be there when the CPU powers up. Each address will point to a routine in the machine's operating system for handling interrupts.

Typically, the interrupt routine will first do an indirect jump through a vector stored in RAM. This allows the interrupt routine to be changed when the machine is running.

Then the interrupt routine has to determine the source of the interrupt. For example, on the Commodore PET thew interrupt might originate from the VIA chip or either of the PIA chips and each of those may raise an interrupt for various reasons e.g. one of the PIA chips raises an interrupt when the monitor does a vertical blank i.e. when it finishes scanning the screen and goes back to the top line. During this interrupt, the PET executes a routine to scan the keyboard and another routine to invert the cursor. Another interrupt might occur when the VIA timer hits zero and the programmer can insert an interrupt routine to, for example toggle an output line to generate a square wave for sound.


Some answers to questions in the comments.

program counter goes to address $FFFE to get relocate to the address

No, the program counter is set to whatever is at that address. If you have:

FFFE: 00 
FFFF: 10

the program counter will be set to $1000 (6502 is little endian) and that's where the interrupt routine must start. Also, the vector for NMI is at $FFFA. The normal interrupt shares $FFFE with the BRK instruction, not the NMI.

What exactly the reset vector does? Does it reset the cpu?

The reset vector contains the location of the code that runs after the processor has been powered on or when a reset occurs.

What's the difference between NMI and IRQ? Then I also would like to know what's up with masking? Is it the way to set the "I" flag in Processor Status Register high or low?

The 6502 status register contains seven flags. Mostly they are to do with the results of arithmetic instructions e.g. Z is set if the result of an operation is zero, C is set when an operation overflows eight bits and for shifts. The I flag enables and disables the normal interrupt (IRQ). If it's zero, interrupts on IRQ will be respected. If it's 1, interrupts are disabled. You can set it and disable it manually with the SEI and CLI instructions and it is set automatically when an interrupt occurs (this is to prevent an interrupt from interrupting an interrupt).

NMI is a non maskable interrupt. The difference is that it ignores the state of the I flag and uses a different vector.

And finally, what are vectors? Are they synonymous for indirect addresses?

Yes.

Oh, and if you do know, how are interrupt addresses starting from $FFFA stored in ROM instead of RAM in real 6502?

You have to arrange for the address decoding logic to point those address at ROM instead of RAM. In fact, in Commodore systems the whole block from $F000 is ROM containing part of the operating system. The same probably applies to most other 6502 based systems.

like image 184
JeremyP Avatar answered Oct 19 '22 05:10

JeremyP


There are four types of interrupt on the 6502: RESET, NMI, IRQ and BRK. The first three are hardware interrupts and the last is a software interrupt. The hardware interrupts have physical input voltages on pins on the microprocessor itself. The software interrupt is caused by a BRK instruction.

All interrupts are 'vectored'. That means when they occur the program counter (PC) is immediately loaded from an address stored in memory, and instruction execution continues from that address.

The addresses are stored as two bytes little endian format at the end of the 64k memory space. They are (in hex):

NMI     $FFFA/$FFFB 
RESET   $FFFC/$FFFD
IRQ     $FFFE/$FFFF 
BRK     $FFFE/$FFFF

In the case of NMI, IRQ and BRK, the current PC address is pushed on to the stack, before loading the interrupt address. The processor status register is also pushed on to the stack.

Pushing the registers on to the stack, is enough information to resume execution after the interrupt has been serviced (processed). The A, X and Y registers however, are not pushed automatically on to the stack. Instead the interrupt service routine should do this if necessary - and pull them back off the stack at the end of the service.

Notice that the IRQ and BRK vectors have the same address. In order to distinguish what happened in your service code, you need to examine the Break Bit of the pushed processor status register. The Break Bit is set if the interrupt came from a BRK instruction.

The currently executing instruction will always be completed before servicing the interrupt.

There are many subtleties to interrupt processing. One of which is which type of interrupt wins in the case that they happen (asserted) at the same time. Another is the point at which an interrupt occurs during the instruction cycle. If the interrupt occurs before the penultimate cycle of the instruction, then it will be serviced on the next instruction. If on or after the penultimate cycle, then it will be delayed until one instruction after.

IRQ interrupts can be 'switched off' or ignored by setting a bit in the processor status register, using the SEI instruction.

Typically the interrupt service routine needs to determine the cause of the interrupt (disc drive, keyboard etc.) and to make sure the interrupt condition is cleared and perform any processing (e.g. putting key presses into a buffer). It can normally do this by reading/writing specific memory locations which are mapped to hardware.

There is more information at this link: https://www.pagetable.com/?p=410

Some more information on how interrupts work in a real 8 bit machine (pages 59, 86, 295): BBC Microcomputer Advanced User Guide

And more information on the physical chip package where you can see the NMI, RES(ET) and IRQ pins on the chip package itself (pages 2,3): 6502 Datasheet

like image 45
Guillermo Phillips Avatar answered Oct 19 '22 04:10

Guillermo Phillips


I guess you ask for hardware interrupt (IRQ or NMI). At your step 2 in stack (not in stack register) are stored program counter and flags register. Later you call RTI to resume program execution. The program counter is loaded with start address of "something" which is interrupt subroutine or program to process the interrupt. It has to store A, X, Y registers if need to modify their values and restore them before RTI. The IRQ interrupt can be masked (delayed) with I flag and NMI is non-maskable i.e. it is always processed. They have different addresses for subroutine.

like image 23
i486 Avatar answered Oct 19 '22 05:10

i486