           ttl     Software Interrupt Processing
*
.   user software interrupt processing
.
           use     rompage

swi2       pshs    cc,a,x,u            save some registers
           scc     irq,firq            disable maskable interrupts
           lda     #ramap&$00FF        get the system page
           sta     datbox+sys_seg      stuff into the datbox
           lda     >usertop            get userblock page
           sta     datbox+userseg      stuff into user segment space
           ldx     uswiv               get user swi vector
*
.   fix up the user memory map
.
           lda     usermap+sys_seg
           sta     datbox+sys_seg      restore the system segment
           lda     usermap+userseg
           sta     datbox+userseg      restore user segment
           leax    0,x
           beq     swi2exit            just exit if address is zero
           stx     4,s
swi2exit   ret     cc,a,x
*
.   Handle SWI3 which is system call
.
swi3       ccc     c                   start off by clearing the carry
           tfr     cc,dpr              save in the direct page register
           tfr     d,y                 save D register in Y register
           ldu     10,s                get the program counter value
           ldb     0,u+                get post byte, increment counter
           stu     10,s                stuff back on user stack
*
.   map in the rest of the ROM and do most of the SWI3 stuff there
.
           scc     irq,firq            disable interrupts at this point
           lda     #romap&$00FF        load the ROM segment value
           sta     datbox+rom_seg      and map in the rest of the ROM
           lda     #romap>>8               setup io segment
           sta     datbox+iod_seg
           bra     swi3doit
*
.   get the user block mapped in
.
           use     *

swi3doit   lda     #ramap&$00FF        load resident RAM page
           sta     datbox+sys_seg      stuff into the datbox
           lda     >usertop            get page that holds user block
           sta     datbox+userseg      map in his segment
*
.   save the pertinant entry registers in the user block
.
           sty     user_d              save user's D register value
           stx     user_x              save user's X register value
           stu     userpc              save user's updated Program Counter
           stb     userpb              save Post Byte
           clra                        set up our direct page register
           exg     dpr,a               and recover the user's condition codes
           sta     usercc              stuff these into the user block
*
.   map in the rest of the system space
.
           ldu     #datbox+11
           ldy     sysmap+9
           ldx     sysmap+7
           ldd     sysmap+5
           pshu    d,x,y
           ldx     sysmap+3
           ldd     sysmap+1
           pshu    d,x
*
.   set up the system stack and invoke the system call handler
.
           sts     usp                 save the user stack pointer
           lds     #systack            and load the system stack
           inc     kernal              increment the interrupt level
           ccc     irq,firq            enable interrupts
           jsr     [swi3vec]           invoke the system call routine
           scc     irq,firq
           lda     chpflg              check task flag
           beq     un_swi              if zero, just map stuff back
           jsr     [chtask]            change task stuff
*
.   rewrite all of the map except the user block and the ROM
.
un_swi     scc     irq,firq            mask interrupts
           dec     kernal              decrement interrupt level
           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
           sta     datbox+10
           bra     swi3undo

           use     rompage
*
.   put back his register values and go back to user processing
.
swi3undo   pshu    x,y                 map back upper 16K of user memory
           lds     #usercc             point to user's condition codes
           puls    a,x,y,u             get CCR, D, X, and PC register values
           lds     usp                 get back the user stack pointer
           stb     datbox+11           give back the user block memory
           sta     0,s                 store back his condition flags
           stx     1,s                 store back his D register
           sty     4,s                 store back his X register
           stu     10,s                and his program counter
           rti

           errif   *=>datbox

           use     *
