           opt     nol
           lib     hardware
           lib     environment
           lib     inttab
           opt     lis
           sttl    Device Interrupt Handlers
           pag
           name    inthan
           data

           global  irqhan,frqhan,swi3han,idle_tsk


leftover fdb 0  number of pulses missed from timer


*
* irqhan
*
* The irg interrupt handler is called after initial
* system setup to process an irq type interrupt.
*

irqhan
           lda     $E88D               DUMMY UNUSED VIA??
           bita    #$80
           beq     todirq
           sta     $E88D
           pshs    a,b,x,y,cc
           ldx     #knowNN
           jsr     Pdata
           puls    a,b,x,y,cc
           rts

knowNN     fcc     'BAD IRQ on IFRNN'
           fcb     07,00

todirq     lda     IFR08               X-12 via
           bita    #$80
           beq     chk29
           bita    #i_t2cnt            .1 sec from X-12?
           beq     chk29               no
           ldd     T2CNTR              get count from timer
* adjust clock if pulses missed during floppy I/O
 exg a,b correct order from part
 addd leftover add in any leftover
 clr leftover
 clr leftover+1
 pshs d
 ldd #6 true pulse count(+1 since T2CNTR always returns -1)
 addd 0,s++ subtract off missed pulses
 bpl rsttmr go restart timer if >=0
 std leftover
 ldd #0
rsttmr     exg     a,b                 fix order for part
           std     T2CNTR              stuff it
           lbra    clkint              and let UniFlex do the rest
*
*
chk29      lda     IFR29               look at interrupts from the VIA
*   Is it the VIA?
           bita    #i_via              any via interrupt?
           beq     not_via             guess not
*   Is it the WDxx hard disk?
           bita    #i_wdxx             Check WDxx (CA2)
           lbne    w5int
*   Is it the 1797 irq?
           bita    #i_1797             Check 1797 (CA1)
           lbne    flopint
*   Is it time to deselect floppy drives?
           bita    #i_unld             drive time out
           lbne    dselint
           anda    #$7f                strip bizarre IRQ
           sta     IFR29               clobber this one
           pshs    a,b,x,y,cc
           ldx     #know29
           jsr     Pdata
           puls    a,b,x,y,cc
           rts

know29     fcc     'BAD IRQ on IFR29'
           fcb     07,00


not_via
irqha1     ldx     #inttab             point to table
           lda     0,x+                get count
irqha2     ldb     intype,x            check device type
           cmpb    #6                  special code for VIA
           bne     irqha3              if not, skip it
           ldb     inmask,x            get mask
           andb    [instat,x]          check status
           lbeq    irqha99             jump if not interrupt
           ldd     indev,x             get device number
           jmp     [inhand,x]          goto routine
*
* Special interrupt handler for 8274 type device
*
irqha3     cmpb    #5
           bne     irqha99
           pshs    a                   save count
           ldu     instat,x            get device address
           lda     #2                  poll the device
           sta     3,u
           lda     3,u                 get response
           ldb     2,u
           bitb    inmask,x            interrupt pending?
           lbeq    10F                 no - jump
           leas    1,s                 yes - clean up stack
           pshs    d                   place device status on stack for handler
           bita    #$04                channel B (second device)?
           bne     0F
           leax    INTSIZ,x            yes - bump pointer
           ldu     instat,x
           ldb     2,u                 get proper status for B side
           stb     1,s                 place on stack
0          lda     0,s
           anda    #!$04
           sta     0,s
           ldd     indev,x             get device #
           ldu     instat,x            get device address
           jsr     [inhand,x]          go process interrupt
           leas    2,s                 clean up stack (remove device status)
           rts                         return from interrupt
10         leax    INTSIZ,x            skip over second device
           puls    a                   restore count
           deca                        also skip second device
*
irqha99    leax    INTSIZ,x            get to next entry
           deca                        dec the count
           lbne    irqha2              repeat til done
*          pshs    a,b,x,y,cc
*          ldx     #whoknow
*          jsr     Pdata
*          puls    a,b,x,y,cc
           rts                         *** Unexpected interrupt - what else to
whoknow    fcc     'Unknown interrupt'
           fcb     07,00

           global  Pdata,Phex,Pspace

*
*  These routines map onto ROM routines
*
Pdata      jmp     [$F800]
Phex       jmp     [$F802]
Pspace     jmp     [$F804]

           pag

*
* frqhan
*
* Handle the firq interrupt.  Works like irq.
*

frqhan     ldx     #fnttab             point to table
frqha2     ldb     inmask,x            get mask
           andb    instat,x            check status
           beq     frqha99
           ldd     indev,x
           jmp     [inhand,x]
frqha99    leax    INTSIZ,x            next entry
           cmpx    #fntend             end of table?
           bne     frqha2              loop til done
           rts                         return

           pag

*
* SWI3 (System call) interrupt handler
*  -- Just pass on to "syscl" - UniFLEX handler
*
swi3han    jmp     syscl

           pag

*
* idle_tsk
*
* CPU Idle task
*
idle_tsk   pshs    d,x,y,u             save registers
99         puls    d,x,y,u,pc          return
