After I read a comment by Oliver (about how the NMI trampoline works), I realized that I had written the wrong code. My original code called the serial driver's handler as though it is an ordinary subroutine. But, it really is an interrupt handler; it returns to its caller in a different way. Therefore, my bad code created an "unbalanced" hardware stack -- of course, the program crashed.
I think that this new code "simulates an interrupt" correctly.
After I read a comment by Oliver (about how the NMI trampoline works), I realized that I had written the wrong code. My original code called the serial driver's handler as though it is an ordinary subroutine. But, it really is an interrupt handler; it returns to its caller in a different way. Therefore, my bad code created an "unbalanced" hardware stack -- of course, the program crashed.
I think that this new code "simulates an interrupt" correctly.
(I also gave the trampoline a more generic name.)