 lib environment
 opt nol
 lib inttab
 lib fio
 opt lis
 data
 sttl Device Interrupt Handlers
 pag
 name inthan.gimix
 global irqhan,frqhan,idle_tsk,swi3han,Fault

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

irqhan lda #CLKMSK get clock mask
 bita CLKSEL check clock int
 beq irqha0 no - try something else
 tst FD5cnt waiting for disk time-out?
 beq 00f
 dec FD5cnt disk time-out complete?
 bne 00f
 jsr dmfTO disk has timed-out
00 ldd CLKLAT reset interrupt
 jmp clkint go handle clock interrupt
irqha0 lda DMFINT get dma status
 bita #%01000000 check int status
 lbne dmfint go service disk
 lda SASI_CSR is it SASI 5" winchester?
 lbmi winint
irqha1 ldx #inttab point to table
 lda 0,x+ get count
irqha2 ldb intype,x get device type
 cmpb #2 is this an IOP?
 beq 00f yes
 ldb inmask,x get mask
 andb [instat,x] check status
 beq 90f jump if no interrupt present
 ldd indev,x get device number
 jmp [inhand,x] goto routine
* -- Check IOP device
00 leax 2*INTSIZ,x IOP takes 3 slots in tables
 suba #2
 ldu instat,x get FIO address
 ldy intbrg,x get IOP control block address
 ldb FIOint,u check interrupt vector address
 andb inmask,x
 cmpb #%00001110 message interrupt?
 bne 90f no - ignore it
 pshs a,x
 lda #ist_reg0 make sure it really is a message interrupt
 jsr fio_get
 puls a,x
 bitb #FIO_MIP message interrupt pending?
 beq 90f no
 ldx iop_Qptr,y
 jsr fio_rcv get response byte
 stb ,x+ put in Q
 stx iop_Qptr,y
 lda #ist_reg0 clear interrupt
 ldb #FIO_CIUS
 jsr fio_put
 cmpx iop_Qend,y Q full?
 beq 05f yes - go process input message
 rts no - wait for another interrupt
05 leax iop_Q,y reset Q pointer
 stx iop_Qptr,y
 jmp fio_int yes - go process IOP interrupt
90 leax INTSIZ,x get to next entry
 deca dec the count
 bne irqha2 repeat til done
irqha5
 jmp dmfint must be disk

 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 frqha3 jump if no interrupt
 pshs x
 ldd indev,x pick up device #
 jsr [inhand,x] call interrupt handler
 puls x
frqha3 leax INTSIZ,x next entry
 cmpx #fntend end of table?
 bne frqha2 loop til done
 rts return

*
* idle_tsk - System Idle task - called when UniFLEX
* has nothing else to do.
*
idle_tsk pshs d,x,y,u save registers
99 puls d,x,y,u,pc return to UniFLEX scheduler
 pag

*
* Fault - Handle Hardware Detected Error
*  -- Uses "nmihan" to signal task
*
Fault ldb #FALTS Assume memory fault
 lda TSR get task status
 bita #$C0 memory fault bits set?
 bne 99f yes - exit
 ldb #TIMES no - try timeout
 bita #$01 Watchdog timer?
 bne 99f
 pshs d,x can't figure it!
 ldx #00f
 jsr Pdata
 lda 0,s
 jsr Phex
 ldx #01f
 jmp blowup
99 lda #0 reset TSR
 sta TSR
 jmp nmihan signal task & exit
*
00 fcc $d,'Unknown FAULT - Code = $',0
01 fcc 'System Hardware Failure!',0
 pag

*
* SWI3 (System call) interrupt handler
*  -- Fetch arguments and place in User Block
*  -- Call system call handler
*  -- Store return parameters on stack
*  -- Return to program (via ROM)
*
P_TRC equ 0
 if P_TRC
swi3msg0 fcc $d,'SWI3 Processing',0
swi3msg1 fcc $d,'Entering Syscall',0
swi3msg2 fcc '-Back!',0
swi3msg3 fcc ',PC=',0
swi3msg4 fcc ',OP=',0
 endif
swi3han
OLD_ROM set 0
 if OLD_ROM
 if P_TRC
 ldx #swi3msg0
 jsr Pdata
 endif
 ldx usp get user stack pointer
 leax 10,x point to user pc
 jsr gtuwrd get the pc
 pshs d save it
 if P_TRC
 pshs d,x
 ldx #swi3msg3
 jsr Pdata
 lda 0,s
 jsr Phex
 lda 1,s
 jsr Phex
 puls d,x
 endif
 tfr d,x point to pc location
 jsr gtubyt get post byte
 if P_TRC
 pshs d,x
 ldx #swi3msg4
 jsr Pdata
 lda 1,s
 jsr Phex
 puls d,x
 endif
 stb upostb save in user block
 puls d get pc back
 addd #1 bump past post byte
 std urglst+UPC save in user block
 ldx usp get stack pointer
 leax 10,x point to pc
 jsr ptuwrd set back on stack
 endif
*
 if P_TRC
 ldx #swi3msg1
 jsr Pdata
 endif
 jsr syscl process system call
 if P_TRC
 ldx #swi3msg2
 jsr Pdata
 endif
*
 if OLD_ROM
 if 0
 ldx usp does stack cross page boundary?
 tfr x,d
 anda #$F0
 pshs a
 leax 10,x
 tfr x,d
 anda #$F0
 cmpa ,s+
 bne 10f jump if stack crosses page boundaries
 ldx usp
 ldb urglst+UCC get c-codes
 jsr ptubyt put on stack
 ldx ptu_ptr get mapped pointer
 ldd urglst+UD get d reg
 std 1,x
 ldd urglst+UX get x reg
 std 4,x
 ldd urglst+UPC get user pc
 std 10,x
 rts
 endif
* Stack crosses page - return values brute force
10 ldx usp point to user stack
 ldb urglst+UCC get c-codes
 jsr ptubyt put on stack
 leax 1,x point to d reg
 ldd urglst+UD get d reg
 jsr ptuwrd put on stack
 leax 3,x point to x reg
 ldd urglst+UX get x reg
 jsr ptuwrd put on stack
 leax 6,x point to pc
 ldd urglst+UPC get user pc
 jsr ptuwrd put on stack
 endif
 rts return
