           ttl     Interrupt Processing
           use     rompage
*
.   take an entry from FIRQ and turn it into a vanilla interrupt
.
firq       leas    -1,s                make more room on the stack
           pshs    cc,a,b,dp,x,y       push most of the registers
           lda     9,s                 pick up old condition codes
           stu     8,s                 store the proper U register
           ora     #%10000000          put them back the way they were
           sta     0,s                 cram onto the stack
           ldd     #romap              set map top         4-14-80
           std     datbox+iod_seg                          4-14-80
           ldx     #firqvec            point to firq vector
           bra     process
*
.   handle non-(system call) type interrupts
.
swi        ldx     #swi_vec            point to RAM swi (3) vector
           ldd     #romap              load top entry of ma4-14-80
           std     datbox+iod_seg      and stuff into the slot
           bra     process

nmi        ldx     #nmi_vec            point to ABORT vector
           ldd     #romap              load top entry of map
           std     datbox+iod_seg      and stuff into the slot
           bra     process

irq        ldx     #irq_vec            point to maskable IRQ vector
           ldd     #romap              load top entry of map
           std     datbox+iod_seg      and stuff into the slot
           bra     process

           use     *
*
.   process an interrupt as special
.
process    lda     #ramap&$00FF        load resident RAM page
           sta     datbox+sys_seg      stuff into the datbox
           inc     >kernal             increment the interrupt level
           bne     jvector             if non-zero, system is mapped in
           clra
           tfr     a,dpr               set up the direct page registe
*
.   map in the entirity of system address space
.
           lda     usertop             get page that holds user block
           sta     datbox+userseg      map in his segment
           ldu     sysmap+sys_seg+1
           stu     datbox+sys_seg+1
           ldu     sysmap+sys_seg+3
           stu     datbox+sys_seg+3
           ldu     sysmap+sys_seg+5
           stu     datbox+sys_seg+5
           ldu     sysmap+sys_seg+7
           stu     datbox+sys_seg+7
           ldu     sysmap+sys_seg+9
           stu     datbox+sys_seg+9
*
.   set up the system stack and invoke the interrupt routine
.
           sts     usp                 save the user stack pointer
           lds     #systack            and load the system stack
jvector    jsr     [0,x]               invoke the interupt process
           scc     irq,firq            disable interrupts
           tst     kernal              decrement interrupt level
           beq     userti              if level zero, exit to user
           dec     kernal              decrement interrupt level
           rti
*
.   Return from Level Zero:
.
.   If "chpflg" is non-zero, swap in a new task before re-establishing
.               the user's address space.  This is the only place that
.               a task swap may occur.  The swap vector is initialized
.               to point to an RTS instruction by the RESET processing.
.
           use     rompage

userti     lda     chpflg              check task flag
           beq     un_map
           jsr     [chtask]            change task stuff
*
.   re-write the entire user map
.
un_map     scc     irq,firq            mask interrupts
           dec     kernal              decrement interrupt level
           lds     usp                 get back user stack pointer
           ldu     #datbox+10
           ldy     usermap+8
           ldx     usermap+6
           ldd     usermap+4
           pshu    d,x,y
           ldx     usermap+2
           ldd     usermap+0
           pshu    d,x
           ldu     #datbox+16
           ldy     usermap+14
           ldx     usermap+12
           ldd     usermap+10
           pshu    d,x,y
rti        rti

           use     *
