MCS6500

Microcomputer Family

Programming Manual


CHAPTER 8 STACK PROCESSING 8.0 INTRODUCTION TO STACK AND TO PUSH DOWN STACK CONCEPT In all of the discussions on addressing, it has been assumed that either the exact location or at least a relation to an exact location of a memory address was known. Although this is true in most of the programming for control applications, there are certain types of programming and applications which require that the basic program not be working with known memory locations but only with a known order for accessing memory. This type of programming is called re-entrant coding and is often used in servicing interrupts. To implement this type of addressing, the microprocessor maintains a separate address generator which is used by the program to access memory. This address generator uses a push down stack concept. Discussions of push down stacks are usually best stated considering that if one were given 3 cards, an ace, a king and a ten and were told that the order of cards was important and asked to lay them down on the table in the order in which they were given, ace first, the king on top of it and finally the ten, and then if they were retrieved, 1 card at a time, the ten is retrieved first even though it was put on last, the king is retrieved second, the ace retrieved last, even though it was put on first. The only commands needed to implement this operation are "put next card on stack" and "pull next card from the stack." The stack could be processing clubs and then go to diamonds and back to clubs. However, we know that while we are processing clubs, we will always find ten first, king second, etc. The hardware implementation of the ordered card stack which just described is a 16-bit counter, into which the address of a memory location is stored. This counter is called a "Stack Pointer." Every time data is to be pushed onto the stack, the stack pointer is put out on the address bus, data is written into the memory addressed by the stack pointer, and the stack pointer is decremented by 1 as may be seen in Example 8.1. Every time data is pulled from the stack, the stack pointer is incremented by 1. The stack pointer is put out on the address bus, and data is read from the memory location addressed by the stack pointer. This implementation using the stack pointer gives the effect of a push down stack which is program independent addressing. Example 8.1: Basic stack map for 3-deep JMP to subroutine sequence Stack Address Data 01FF PCH 1 01FE PCL 1 01FD PCH 2 01FC PCL 2 01FB PCH 3 01FA PCL 3 01F9 In the above example, the stack pointer starts out at OlFF. The stack pointer is used to store the first state of the program counter by storing the content of program counter high at OlFF and the content of program counter low at OlFE. The stack pointer would now be pointed at OlFD. The second time the store program count is performed, the program counter high number is stored on the stack at 01FD and the program counter low is stored at 01FC. The stack pointer would now be pointing at 01FB. The same procedure is used to store the third program counter. When data is taken from the stack, the PCL 3 will come first and the PCH 3 will come second just by adding 1 to the stack pointer before each memory read. The example above contains the program count for 3 successive jump and store operations where the jump transfers control to a subroutine and stores the value of the program counter onto the stack in order to remember to which address the program should return after completion of the subroutine. Following is an example of a program that would create the Example 8.1 stack operation.
Basic stack operation
This is known as subroutine nesting and is often encountered in solving complex control equations. To correctly use the stack for this type of operation requires a jump to subroutine and a return from subroutine instruction. 8.1 JSR - JUMP TO SUBROUTINE This instruction transfers control of the program counter to a subroutine location but leaves a return pointer on the stack to allow the user to return to perform the next instruction in the main program after the subroutine is complete. To accomplish this, JSR instruction stores the program counter address which points to the last byte of the jump instruction onto the stack using the stack pointer. The stack byte contains the program count high first, followed by program count low. The JSR then transfers the addresses following the jump instruction to the program counter low and the program counter high, thereby directing the program to begin at that new address. The symbolic notation for this is PC + 2+, (PC + 1) → PCL, (PC + 2) → PCH. The JSR instruction affects no flags, causes the stack pointer to be decremented by 2 and substitutes new values into the program counter low and the program counter high. The addressing mode for the JSR is always Absolute. Example 8.3 gives the details of a JSR instruction. Example 8.3: Illustration of JSR instruction Program Memory PC Data 0100 JSR 0101 ADL 0102 ADH Subroutine Stack Memory Stack Pointer Stack 01FD 01FE 02 01FF 01 External Internal Cycle Address Bus Data Bus Operations Operations 1 0100 OP CODE Fetch Finish Previous Instruction Operation; Increment PC to 0101 2 0101 New ADL Fetch Decode JSR; New ADL Increment PC to 0102 3 01FF Store ADL 4 01FF PCH Store PCH Hold ADL, Decrement S to 01FE 5 01FE PCL Store PCL Hold ADL, Decrement S to 01FD 6 0102 ADH Fetch ADH Store Stack Pointer 7 ADH, ADL New Fetch New ADL → PCL OP CODE OP CODE ADH → PCH * S denotes "Stack Pointer." In this example, it can be seen that during the first cycle the microprocessor fetches the JSR instruction. During the second cycle, address low for new program counter low is fetched. At the end of cycle 2, the microprocessor has decoded the JSR instruction and holds the address low in the microprocessor until the stack operations are complete. NOTE: The stack is always stored in Page 1 (Hex address 0100-01FF). The operation of the stack in the MCS650X microprocessor is such that the stack pointer is always left pointing at the next memory location into which data can be stored. In Example 8.3, the stack pointer is assumed to be at OlFF in the beginning and PC at location 0100. During the third cycle, the microprocessor puts the stack pointer onto the address lines and on the fourth writes the contents of the current value of the program counter high, 01, into the memory location indicated by the stack pointer address. During the time that the write is being accomplished, the stack pointer is being automatically decremented by 1 to 01FE. During the fifth cycle the PCL is stored in the next memory location with the stack pointer being automatically decremented. It should be noted that the program counter low, which is now stored in the stack, is pointing at the last address in the JSR sequence. This is not what would be expected as a result of a JSR instruction. It would be expected that the stack points at the next instruction. This apparent anomaly in the machine is corrected during the Return from Subroutine instruction. Note: At the end of the JSR instruction, the values on the stack contain the program counter low and the program counter high which referenced the last address of the JSR instruction. Any subroutine calls which want to use the program counter as an intermediate pointer must consider this fact. It should be noted also that the Return from Subroutine instruction performs an automatic increment at the end of the RTS which means that any program counters which are substituted on the stack must be 1 byte or 1 pointer count less than the program count to which the programmer expects the RTS to return. The advantage of delaying the accessing of the address high until after the current program counter can be written in the stack is that only the address low has to be stored in the microprocessor. This has the effect of shortening the JSR instruction by 1 byte and also minimizing internal storage requirements. After both program counter low and high have been transferred to the stack, the program counter is used to access the next byte which is the address high for the JSR. During this operation, the sixth cycle, internally the microprocessor is storing the stack pointer which is now pointing at OlFD or the next location at which memory can be loaded. During the seventh cycle the address high from the data bus and the address low stored in the microprocessor are transferred to the new program counter and are used to access the next OP CODE, thus making JSR a 6-cycle instruction. At the completion of the subroutine the programmer wants to return to the instruction following the Jump-to-Subroutine instruction. This is accomplished by transferring the last 2 stack bytes to the program counter which allows the microprocessor to resume operations at the instruction following the JSR, and it is done by means of the RTS instruction. 8.2 RTS - RETURN FROM SUBROUTINE This instruction loads the program count low and program count high from the stack into the program counter and increments the program counter Ro that it points to the instruction following the JSR. The stack pointer is adjusted by incrementing it twice. The symbolic notation for the RTS is PC+, INC PC. The RTS instruction does not affect any flags and affects only PCL and PCH. RTS is a single-byte instruction and its addressing mode is Implied. The following Example 8.4 gives the details of the RTS instruction. It is the complete reverse of the JSR shown in Example 8.3. Example 8.4: Illustration of RTS instruction Program Memory PC Data 0300 RTS 0301 ? Stack Memory Stack Pointer Stack 01FD ? 01FE 02 01FF 01 Return from Subroutine (Example) External Internal Cycle Address Bus Data Bus Operations Operations 1 0300 OP CODE Fetch Finish Previous OP CODE Operation, 0301 → PC 2 0301 Discarded Fetch Dis- Decode RTS Data carded Data 3 01FD Discarded Fetch Dis- Increment Stack Data carded Data Pointer to 01FE 4 01FE 02 Fetch PCL Increment Stack Pointer to 01FF 5 01FF 01 Fetch PCH 6 0102 Discarded Put Out PC Increment PC by 1 Data to 103 7 0103 Next Fetch Next OP CODE OP CODE As we can see, the RTS instruction effectively unwinds what was done to the stack in the JSR instruction. Because RTS is a single-byte instruction it wastes the second memory access in doing a look-ahead operation. During the second cycle the value located at the next program address after the RTS is read but not used in this operation. It should be noted that the stack is always left pointing at the next empty location, which means that to pull off the stack, the microprocessor has to wait 1 cycle while it adds 1 to the stack address. This is done to shorten the interrupt sequence which will be discussed below; therefore, cycle 3 is a dead cycle in which the microprocessor fetches but does not use the current value of the stack and, like the fetch of address low on Indexed and Zero Page Indexed operations, does nothing other than initialize the microprocessor to the proper state. It can be seen that the stack pointer decrements as data is pushed on to the stack and increments as data is pulled from the stack. In the fourth cycle of the RTS, the microprocessor puts out the OlFE address, reads the data stored there which is the program count low which was written in the second write cycle of the JSR. During the fifth cycle, the microprocessor puts out the incremented stack picking up the program count high which was written in the first write cycle of the JSR. As is indicated during the discussions of JSR, the program counter stored on the stack really points to the last address of the JSR instruction itself; therefore, during the sixth cycle the RTS causes the program count from the stack to be incremented. That is the only purpose of the sixth cycle. Finally, in the seventh cycle, the incremented program counter is used to fetch the next instruction; therefore, RTS takes 6 cycles. Because every subroutine requires 1 JSR followed by 1 RTS, the time to jump to and return from a subroutine is 12 cycles. In the previous 2 examples, we have shown the operations of the JSR located in location 100 and the RTS located in location 300. The following pictorial diagram. Example 8.5, illustrates how the memory map for this operation might look:
Memory map for RTS instruction
With this capability of subroutining, the microprocessor allows the programmer to go from the main program to 1 subroutine, to the second subroutine, to a third subroutine, then finally working its way back to the main program. Example 8.6 is an expansion of Example 8.2 with the returns included.
Expansion of RTS memory map
This concept is known as nesting of subroutines, and the number of subroutines which can be called and returned from in such a manner is limited by only the length of the stack. 8.3 IMPLEMENTATION OF STACK IN MCS6501 THROUGH MCS6505 As we have seen, the primary requirement for the stack is that irrespective of where or when a stack operation is called, the microprocessor must have an independent counter or register which contains the current memory location value of the stack address. This register is called the Stack Pointer, S. The stack becomes an auxiliary field in memory which is basically independent of programmer control. We will discuss later how the stack pointer becomes initialized, but once it is initialized, the primary requirement is that it be self-adjusted; in other words, operations which put data on the stack cause the pointer to be decremented automatically; operations which take data off from the stack cause the pointer to be incremented automatically. Only under rare circumstances should the programmer find it necessary to move his stack from one location to another if he is using the stack as designed. On this basis, there is no need for a stack to be longer than 256 bytes To perform a single subroutine call takes only 2 bytes of stack memory. To perform an interrupt takes only 3 bytes of stack memory. Therefore, with 256 bytes, one can access 128 subroutines deep or interrupt ourselves 85 times. Therefore the length of the stack is extremely unlikely to be limiting. The MCS6501 through MCS6505 have a 256-byte stack length. Figure 8.1, which is now the complete block diagram, shows all of the microprocessor registers. The 8-bit stack pointer register, S, has been added. It is initialized by the programmer and thereafter automatically increments or decrements , depending on whether data is being put on to the stack or taken off the stack by the microprocessor under control of the program or the interrupt lines.
Partial Block Diagram of MCS650X Including Stack Pointer, S
The primary purpose of the stack is to furnish a block of memory locations in which the microprocessor can write data such as the program counter for use in later processing. In many control systems the requirements for Read/Write memory are very small and the stack just represents another demand on Read/Write memory. Therefore these applications would like the stack to be in the Page Zero location in order that memory allocation for the stack, the Zero Page operations, and the indirect addresses can be performed. Therefore, one of the requirements of a stack is that it be easily locatable into Page Zero. On the other hand, if more than 1 page of RAM is needed because of the amount of data that must be handled by the user programs, having the stack in Page Zero is an unnecessary waste of Page Zero memory in the sense that the stack can take no real advantage of being located in Zero Page, whereas other operations can. In each of the examples, the stack has been located at high order address 01 followed by a low order address . In the same manner as the microprocessor forces locations 00 on to the high order 8 bits of the address lines for Zero Page operations, the microprocessor automatically puts 01 Hex on to the high order 8-bit address lines during each stack operation. This has the advantage to the user of locating the stack into Page One of memory which would be the next memory location added if the Zero Page operation requirements exceed Page Zero memory capacity. This has the advantage of the stack not requiring memory to be added specifically for the stack but only requiring the allocation of existing memory locations. It should be noted that the selected addressing concepts of the MCS650X microprocessor support devices would involve connecting the memories such that bit 8, which is the selection bit for the Page One versus Page Zero, is a "don't care" for operations in which the user does not need more than 1 page of Read/Write memory. This gives the user the effect of locating stack in Page Zero for those applications. The second feature that should be noted from the examples is that the stack was located at the end of Page One and decremented from that point towards the beginning of the page. This is the natural operation of the stack. RAM memory comes in discrete increments, 64, 128, 256 bytes so the normal method of allocating stack addressing is for the user to calculate the number of bytes probably needed for stack access. This could be done by analyzing the number of subroutines which might be called and the amount of data which might be put onto the stack in order to communicate between subroutines or the number of interrupts plus subroutines which might occur with the respective data that would be stored on the stack for each of them. By counting 3 bytes for each interrupt, 2 bytes for each jump to subroutine, plus 1 byte for each programmer-controlled stack operation, the microprocessor designer can estimate the amount of memory which must be allocated for the stack. This is part of his decision-making process in deciding how much memory is necessary for his whole program. Once the allocation has been made, it is recommended that the user assign his working storage from the beginning of memory forward and always load his stack at the end of either Page Zero, Page One, or at the end of his physical memory which is located in one of those locations. This will give the effect of having the highest bytes of memory allocated to the stack, lower bytes of memory allocated to user working storage and hopefully the two shall never overlap. It should be noted that the natural operation of the stack, which often is called by hardware not totally under program control, is such that it will continue to decrement throughout the page to which it is allocated irrespective of the user's desire to have it do so. A normal mistake in allocation in memory can result in the user writing data into a memory location and later accessing it with another subroutine or another part of his program, only to find that the stack has very carefully written over that area as the result of its performing hardware control operations . This is one of the more difficult problems to diagnose. If this problem is suspected by the programmer, he should analyze memory locations higher than unexplained disturbed locations. There is a distinctive pattern for stack operations which are unique to the user's program but which are quite predictable. An analysis of the value which has been destroyed will often indicate that it is part of an which would normally be expected during the execution of the program between the time data was stored and the time it was fetched. This is a very strong indication of the fact that the stack somehow or other did get into the user's program area. This is almost always caused by improper control of interrupt lines or unexpected operations of interrupt or subroutine calls and has only 2 solutions: (1) If the operation is normal and predictable, the user must assign more memory to his program and particularly reassign his memory such that the stack has more room to operate; or (2) if the operation of the interrupt lines is not predictable, attention must be given to solving the hardware problem that causes this type of unpredictable operation. 8.3.1 Summary of Stack Implementation The MCS6501 through MCS6505 microprocessors have a single 8-bit stack register. This register is automatically incremented and decremented under control of the microprocessor to perform stack manipulation operations, under direction of the user program or the interrupt lines. Once the programmer has initialized the stack pointer to the end of whatever memory he wants the stack to operate in, the programmer can ignore stack addressing other than in those cases where there is an interference between stack operations and his normal program working space. In the MCS6501 through MCS6505, the stack is automatically located in Page One. The microprocessor always puts out the address 0100 plus stack register for every stack operation. By selected memory techniques, the user can either locate the stack in Page Zero or Page One, depending on whether or not Page One exists for his hardware. 8.4 USE OF THE STACK BY THE PROGRAMMER Discussed in Section 8.1 was the use of the JSR to call a subroutine. However, not indicated was the technique by which the subroutine knew which data to operate on. There are 3 classical techniques for communicating data between subroutines. The first and most straightforward technique is that each subroutine has a defined set of working registers located in the Page Zero in which the user has left values to be operated on by the subroutine. The registers can either contain the values directly or can contain indirect pointers to addresses to values which would be operated on. The following example shows the combination of these: Example 8.7: Call-a-move subroutine using preassigned memory locations Location 10 = Count Location 11, 12 = Base from Address Location 13, 14 = Base to Address Main Line Routine No. of Bytes Instruction Comment 2 LDA #Count -1 Load Fixed Value for the Move 2 STA 10 2 LDA #FRADH 2 STA 12 Set up "FROM" Pointer 2 LDA #FRADL 2 STA 11 2 LDA #TOADL 2 STA 13 2 LDA #TOADH 2 STA 14 Set up "TO" Pointer 3 JSR SUB1 23 bytes Subroutine Coding No. of Bytes Label Instruction 2 SUB1 LDY 10 2 LOOP LDA (11), Y 2 STA (13), Y 1 DEY 2 BNE LOOP 1 RTS total 33 bytes As has been previously developed, the loop time is the overriding consideration rather than setup time for a large number of executions. It can be seen that we have used the techniques developed in previous sections of the indirect referencing, the jump to subroutine and the return from subroutine to perform this type of subroutine value communication. In this operation, there was no use of the stack except for the program counter value. A second form of communication is the use of the stack itself as an intermediate storage for data which is going to be communicated to the subroutine. In order for the programmer to use the stack as an intermediate storage, he needs instructions which allow him to put data on the stack and to read from the stack. These instructions are known as push and pull instructions. 8.5 PHA - PUSH ACCUMULATOR ON STACK This instruction transfers the current value of the accumulator to the next location on the stack, automatically decrementing the stack to point to the next empty location. The symbolic notation for this operation is A^. Noted should be that the notation 4- means push to the stack, f means pull from the stack. The Push A instruction only affects the stack pointer register which is decremented by 1 as a result of the operation. It affects no flags. PHA is a single-byte instruction and its addressing mode is Implied. The following example shows the operations which occur during Push A instruction. Example 8.8: Operation of PHA, assuming stack at 01FF External Internal Cycle Address Bus Data Bus Operations Operations 1 0100 OP CODE Fetch Finish Previous Instruction Operation, Increment PC to 0101 2 0101 Next Fetch Next Interpret PHA Instruction, OP CODE OP CODE Hold and Discard P-Counter 3 01FF (A) Write A on Decrement Stack Stack Pointer to 01FE 4 0101 Next Fetch Next OP CODE OP CODE As can be seen, the PHA takes 3 cycles and takes advantage of the fact that the stack pointer is pointing to the correct location to write the value of A. As a result of this operation, the stack pointer will be setting at 01FF. The notation (A) implies contents of A. Now that the data is on the stack, later on in the program the programmer will call for the data to be retrieved from the stack with a PLA instruction. 8.6 PLA - PULL ACCUMULATOR FROM STACK This instruction adds 1 to the current value of the stack pointer and uses it to address the stack and loads the contents of the stack into the A register. The symbolic notation for this is A↑. The PLA instruction does not affect the carry or overflow flags. It sets N if the bit 7 is on in accumulator A as a result of instructions, otherwise it is reset. If accumulator A is zero as a result of the PLA, then the Z flag is set, otherwise it is reset. The PLA instruction changes content of the accumulator A to the contents of the memory location at stack register plus 1 and also increments the stack register. The PLA instruction is a single-byte instruction and the addressing mode is Implied. In the following example, the data stored on the stack in Example 8.8 is transferred to the accumulator. Example 8.9: Operation of PLA stack from Example 8.8 External Internal Cycle Address Bus Data Bus Operations Operations 1 0200 PLA Fetch Finish Previous Operation, Instruction Increment PC to 101 2 0201 Next Fetch Next Interpret Instruction, OP CODE OP CODE and Hold P-Counter Discard 3 01FE Read Stack Increment Stack Pointer to 01FF 4 01FF (A) Fetch A Save Stack 5 0201 Next Fetch Next M → A OP CODE OP CODE When taking data off the stack, there is 1 extra cycle during which time the current contents of the stack register are accessed but not used and the stack pointer is incremented by 1 to allow access to the value that was previously stored on the stack. The stack pointer is left pointing at this location because it is now considered to be an empty location to be used by the stack during a subsequent operation. 8.7 USE OF PUSHES AND PULLS TO COMMUNICATE VARIBLES BETWEEN SUBROUTINE OPERATIONS In Example 8.10, we perform the same operation as we did in Example 8.7; only here, instead of using fixed locations to pick up the pointers, we are going to use the stack as a communications vehicle: Example 8.10: Call-a-move subroutine using the stack to communicate Location 11, 12 = Base "FROM" Address Location 13, 14 = Base "TO" Address Main Line Routine Bytes Instruction 2 LDA #Count -1 1 PHA 2 LDA #FRADL 1 PHA 2 LDA #FRADH 1 PHA 2 LDA #TOADL 1 PHA 2 LDA #TOADH 1 STA 14 Set up "TO" Pointer 3 JSR SUB1 18 Subroutine Bytes Label Instruction Comments 2 SUB1 LDX 6 1 LOOP1 PLA 2 STA 10,X 1 DEX Move Stack to Memory 2 BNE LOOP 1 2 PLA Set up Count 2 TAY 2 LOOP2 LDA (11),Y 2 LDA (13),Y Move Memory Location 2 DEY 2 BNE LOOP 2 2 LDA 15 2 PHA 2 LDA 16 Restore PC to Stack 2 PHA 1 RTS Total 42 Bytes We can see from this example that using the stack as a communication vehicle actually increases the number of bytes in the subroutine and the total bytes overall. However, the only time one should be using subroutines in this case is when the subroutine is fairly long and the number of times the subroutine is used is fairly frequent. This technique does reduce the number of bytes in the calling sequence. The calling sequence is normally repeated once for every time the instruction is called; therefore the use of the stack to communicate should result in a net reduction in the number of bytes used in the total program. Up until this time, we have been considering that the stack is at a fixed location and that all stack references use the stack pointer. It has not been explained how the stack pointer in the microprocessor gets loaded and accessed. This is done through communication between the stack pointer and index register X. 8.8 TXS - TRANSFER INDEX X TO STACK POINTER This instruction transfers the value in the index register X to the stack pointer. Symbolic notation is X → S. TXS changes only the stack pointer, making it equal to the content of the index register X. It does not affect any of the flags. TXS is a single-byte instruction and its addressing mode is Implied Another application for TXS is the concept of passing parameters to the subroutine by storing them immediately after the jump to subroutine instruction. In Example 8.11, the from and to address, plus the count of number of values would be written right after the JSR instruction and its address. By locating the stack in Page Zero, the address of the last byte of the JSR can be incremented to point at the parameter bytes and then used as an indirect pointer to move the parameter to its memory location. The key to this approach is transferring the stack pointer to X which allows the program to operate directly on the address while it is in the stack. It should be noted that this approach automatically leaves the address on the stack, positioned so that the RTS picks up the next OP CODE address. Example 8.11: Jump to subroutine (JSR) followed by parameters Address Bus Data 0100 JSR 0101 ADL 0102 ADH 0103 To High 0104 To Low 0105 From High 0106 From Low 0107 Count 0108 Next OP CODE Before concluding this discussion on subroutines and parameter passing, one should again note the use of subroutines should be limited to those cases where the user expects to duplicate code of significant length several times in the program. In these cases, and only in these cases, is subroutine call warranted rather than the normal mode of knowing the addresses and specifying them in an instruction. In all cases where timing is of significant interest, subroutines should also be avoided. Subroutines add significantly to the setup and execution time of problem solution. However, subroutines definitely have their place in microcomputer code and there have been presented 3 alternatives for use in application programs. The user will find a combination of the above techniques most useful for solving his particular problem. 8.9 TSX - TRANSFER STACK POINTER TO INDEX X This instruction transfers the value in the stack pointer to the index register X. Symbolic notation is S → X. TSX does not affect the carry or overflow flags. It sets N if bit 7 is on in index X as a result of the instruction, otherwise it is reset. If index X is zero as a result of the TSX, the Z flag is set, otherwise it is reset. TSX changes the value of index X, making it equal to the content of the stack pointer. TSX is a single-byte instruction and the addressing mode is Implied. 8.10 SAVING OF THE PROCESSOR STATUS REGISTER During the interrupt sequences, the current contents of the processor status register (P) are saved on the stack automatically. However, there are times in a program where the current contents of the P register must be saved for performing some type of other operation. A particular example of this would be the case of a subroutine which is called independently and which involves decimal arithmetic. It is important that the programmer keeps track of the arithmetic mode the program is in at all times. One way to do this is to establish the convention that the machine will always be in binary or decimal mode, with every subroutine changing its mode being responsible for restoring it back to the known state. This is a superior convention to the one that is about to be described. A more general convention would be one in which the subroutine that wanted to change modes of operation would push P onto the stack, then set the decimal mode to perform the subroutine and then pull P back from the stack prior to returning from the subroutine. Instructions which allow the user to accomplish this are as follows: 8.11 PHP - PUSH PROCESSOR STATUS ON STACK This instruction transfers the contents of the processor status register unchanged to the stack, as governed by the stack pointer. Symbolic notation for this is P↓. The PHP instruction affects no registers or flags in the microprocessor. PHP is a single-byte instruction and the addressing mode is Implied 8.12 PLP - PULL PROCESSOR STATUS FROM STACK This instruction transfers the next value on the stack to the Processor Status register, thereby changing all of the flags and setting the mode switches to the values from the stack. Symbolic notation is P↑. The PLP instruction affects no registers in the processor other than the status register. This instruction could affect all flags in the status register. PLP is a single-byte instruction and the addressing mode is Implied. 8.13 SUMMARY ON THE STACK The stack in the MCS650X family is a push-down stack implemented by a processor register called the stack pointer which the programmer initializes by means of a Load X immediately followed by a TXS instruction and thereafter is controlled by the microprocessor which loads data into memory based on an address constructed by adding the contents of the stack pointer to a fixed address. Hex address 0100. Every time the microprocessor loads data into memory using the stack pointer, it automatically decrements the stack pointer, thereby leaving the stack pointer pointing at the next open memory byte. Every time the microprocessor accesses data from the stack, it adds 1 to the current value of the stack pointer and reads the memory location by putting out the address 0100 plus the stack pointer. The status register is automatically pointing at the next memory location to which data can now be written. The stack makes an interesting place to store interim data without the programmer having to worry about the actual memory location in which data will be directly stored. There are 8 instructions which affect the stack. They are: BRK, JSR, PHA, PHP, PLA, PLP, RTI, and RTS. BRK and RTI involve the handling of the interrupts.