Page 191 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 191

168                                Chapter 6 Assembly Language Subroutines

        same effect as the SWI instruction except for minor changes in the CC and X registers.
        The subroutine at the address contained in $FFF6 and $FFF7 is called the SWI handler,
        A handler must end in an RTI instruction rather than an RTS instruction because all
        registers are pushed onto the stack with the SWI instruction. The RTI instruction at the
        end of an SWI handler does the same thing as the code in Figure 6.42.
            SWI differs from BSR in that the address of the handler is obtained indirectly
        through the implied address $FFF6. This makes the SWI instruction shorter, in this case
        one byte long. An SWI handler can be made to perform a function, such as our
         ubiquitous dot product. See Figure 6.43. The initialization of the high-address "vector"
         need be done only once, before the first SWI call is made, as shown in Figure 6.44a.
        Then, each time it's called, insert the SWI instruction in your calling program, as shown
        in Figure 6.44b. Note that in the calling routine, we pass arguments in registers; but
        inside the handler, we access these arguments using stack techniques.
             When you are debugging a program, you can use a program called a debugger or a
        monitor to help you debug the program that you are writing. You may want to display
        the values in some of the registers or memory locations or to insert some data into some
        of the registers or memory locations. As used with most debug programs, the SWI
        handler is a routine in the debug program that displays a prompt character, such as "*,"
        on the terminal and waits for the user to give commands to display or change the values
         in registers or memory locations. This can be used to display or change any amount of
        data or even to modify the program. This SWI instruction is called a breakpoint.
             A typical monitor program inserts a breakpoint at the start of an instruction by
        replacing the opcode byte with an SWI instruction. The address of the replaced opcode
         byte, as well as the byte itself, are kept in a part of RAM that the monitor uses for this
        purpose. The program now runs until it encounters the SWI breakpoint. Then the
         registers might be displayed together with a prompt for further commands to examine or
        change memory or register contents. It is indispensable that the SWI instruction be one
        byte long to be used as a breakpoint. If you tried to put breakpoints in the program with
        a JSR instruction, you would have to remove three bytes. If your program had a branch
         in it to the second byte being removed, unfathomable things might begin to happen! The
         problem in your program would be even harder to find now. However, if the single-word
         SWI instruction is used, this cannot happen, and the SWI handler call can be made to
         help you debug the program. One limitation of breakpoints is that the program being
        debugged must be in RAM. It is not possible to replace an opcode in ROM with an SWI
        instruction. Programs already in ROM are therefore more difficult to debug.



                         PULC            ; Restore condition codes
                         PULB            ; Restore accumulator B
                         PULA            ; Restore accumulator A
                         PULX            ; Restore X
                         PULY            ; Restore Y
                         RTS             ; Restore PC


                                Figure 6.42. Emulation of RTI
   186   187   188   189   190   191   192   193   194   195   196