Wednesday, April 11, 2018

Interrupt and Overflow Flags

This week we will finish off our look at the flags that the 6502 supports then next week we will start getting into the memory manipulation commands of the 6502. I have not had much time to work on the emulator  but have got some preliminary TIA functionality implemented. Being so far ahead may be a good thing but I was hoping to stay well ahead as this fall my spare time will drop to near zero.



The 6502 supports something known as interrupts to allow for devices to alert the CPU when they need servicing. When an interrupt request (IRQ) occurs control is given to the interrupt handler then returned to the program once the interrupt has finished. IRQs are maskable interrupts which means that they will not occur until the disable interrupt flag is clear. There are cases where you may not want to be interrupted such as timing critical stuff, turning off the device causing the interrupt, and changing the address of the interrupt handler to name a few. The procedure here is to disable interrupts with the SEI command, perform your critical work, turn interrupts back on using the CLI command.

Interrupts are not something that generally has to be dealt with in 2600 programming, but it is part of the instruction set. More details on the inner workings of interrupts will be covered when we get to the other interrupt related command RTI.

This leaves us with one final command for setting the overflow flag. Overflows will be covered when we implement the adding and subtracting commands ADC, SBC a while from now. Essentially an overflow is the signed number equivalent of a carry. There is no way of manually setting the overflow flag other than performing a math operation that causes it, but the CLV command will clear the overflow flag.

Astute readers will notice that there are no set or clear commands for the negative and zero flags. These are set by operations that change registers or memory. The zero flag is set when the last operation changes the register or memory being accessed to zero and is cleared if the memory or register is non-zero. The negative flag is set if the last memory or register changed set the high byte, which is known as the sign byte and used for signed arithmetic.


CLICLear Interrupt disable flag
Address Mode
Decimal OPCode
Hexadecimal OpCode
Size
Cycles
Implied
88
$58
1
2
Flags affected: I
Usage: Use to enable interrupts. Can be used within an interrupt handler to allow other interrupts to interrupt the interrupt if the interrupt being handled has a long execution time
Test Code:
     SEI
     CLI
     BRK
; Expect I = 0
Implementation:
m.state.flags = m.state.flags and (255 xor INTERRUPT_FLAG)

SEISEt Interrupt disable flag
Address Mode
Decimal OPCode
Hexadecimal OpCode
Size
Cycles
Implied
120
$78
1
2
Flags affected: I
Usage: Used to disable interrupts such as in the case where you are modifying a devices shared memory and can’t have that device running an interrupt handler while those changes are being made.
Test Code:
     CLI
     SEI
     BRK
; Expect I = 1

Implementation:
m.state.flags = m.state.flags or INTERRUPT_FLAG

CLVCLear Overflow flag
Address Mode
Decimal OPCode
Hexadecimal OpCode
Size
Cycles
Implied
184
$B8
1
2
Flags affected: V
Usage: If you are using signed arithmetic, this suld be used before executing an instruction that can cause an overflow (positive number turning negative or negative turning positive).
Test Code:
     CLV
     BRK
; Expect V = 0

Implementation:
m.state.flags = m.state.flags and (255 xor OVERFLOW_FLAG)

No comments:

Post a Comment