#include <arch/irq.h>
/*
 *	IRQ and IRQ return paths for Linux 8086
 */
 
#asm
!
!	Other IRQs (see IRQ 0 at the bottom for the
!	main code).
!
	.globl _irq1
	.globl _irq2
	.globl _irq3
	.globl _irq4
	.globl _irq5
	.globl _irq6
	.globl _irq7
	.globl _irq8
	.globl _irq9
	.globl _irq10
	.globl _irq11
	.globl _irq12
	.globl _irq13
	.globl _irq14
	.globl _irq15
_irq1:
	push	ax
	mov	ax,#1
	br	_irqit
_irq2:
	push	ax
	mov	ax,#2
	br	_irqit
_irq3:
	push	ax
	mov	ax,#3
	br	_irqit
_irq4:
	push	ax
	mov	ax,#4
	br	_irqit
_irq5:
	push	ax
	mov	ax,#5
	br	_irqit
_irq6:
	push	ax
	mov	ax,#6
	br	_irqit
_irq7:
	push	ax
	mov	ax,#7
	br	_irqit
!
!	AT interrupts
!	
_irq8:
	push	ax
	mov	ax,#8
	br	_irqit
_irq9:
	push	ax
	mov	ax,#9
	br	_irqit
_irq10:
	push	ax
	mov	ax,#10
	br	_irqit
_irq11:
	push	ax
	mov	ax,#11
	jmp	_irqit
_irq12:
	push	ax
	mov	ax,#12
	jmp	_irqit
_irq13:
	push	ax
	mov	ax,#13
	jmp	_irqit
_irq14:
	push	ax
	mov	ax,#14
	jmp	_irqit
_irq15:
	push	ax
	mov	ax,#15
	jmp	_irqit
!
!
!	Traps (we use IRQ 16->31 for these)
!
	.globl _div0
_div0:
	push	ax
	mov	ax,#16
	jmp	_irqit

	.globl _dbugtrap
_dbugtrap:
	push	ax
	mov	ax,#17
	jmp	_irqit

	.globl _nmi
_nmi:
	push	ax
	mov	ax,#18
	jmp	_irqit

	.globl	_brkpt
_brkpt:
	push 	ax
	mov	ax,#19
	jmp	_irqit

	.globl	_oflow
_oflow:
	push	ax
	mov	ax,#20
	jmp	_irqit

	.globl	_bounds
_bounds:
	push	ax
	mov	ax,#21
	jmp	_irqit
	
	.globl	_invop
_invop:
	push	ax
	mov	ax,#22
	jmp	_irqit
	
	.globl _devnp
_devnp:
	push	ax
	mov	ax,#23
	jmp	_irqit

	.globl	_dfault
_dfault:
	push	ax
	mov	ax,#24
	jmp	_irqit
;
;	trap 9 is reserved
;	
	.globl _itss
_itss:
	push	ax
	mov	ax,#26
	jmp	_irqit

	.globl _nseg
_nseg:
	push	ax
	mov	ax,#27
	jmp	_irqit
	
	.globl _stkfault
_stkfault:
	push 	ax
	mov	ax,#28
	jmp	_irqit

	.globl	_segovr
_segovr:
	push	ax
	mov	ax,#29
	jmp	_irqit
	
	.globl _pfault
_pfault:
	push	ax
	mov	ax,#30
	jmp	_irqit
;
;	trap 15 is reserved
;
	.globl	_fpetrap
_fpetrap:
	push	ax
	mov	ax,#32
	jmp	_irqit

	.globl	_algn
_algn:
	push	ax
	mov	ax,#33
	jmp	_irqit



	.globl	_irq0
_irq0:
	pushf
	push	ax
	xor	ax,ax
_irqit:
	push	ds
	push	es
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	bp
!
!	The registers are now stored. Remember were
!
	mov	bp,sp
	push	bp	! Register base
	push	ax	! IRQ number
!
!	Call the C code
!
	call	_doIRQ
!
!	Return path
!
	pop	ax		! We want the ax value back
	pop	bx		! Drop arguments
!
!	Restore any chips
!
	cmp	ax,#15
	jge	was_trap	! Traps need no reset
	cmp	ax,#8
	jge	sec_8259	! IRQ on low chip
!
!	Rest primary 8259
!
	mov	cl,al		! Save the IRQ number
	inb	al,0x21		! The chip line state
	jmp	a7
a7:	jmp	a8
a8:	movb	al,#1
	shl	al,cl		! Shift the irq (saved in cl) to a mask
	orb	al,cache_21
	movb	cache_21, al
	outb	0x21,al		! Now ack the IRQ
	jmp	a9
a9:	jmp	a10
a10:	movb	al,#0x20
	outb	0x20,al
	jmp	was_trap
	
!
!	Reset secondary 8259 if we have taken an AT rather
!	than XT irq. We also have to prod the primay
!	controller EOI..
!
sec_8259:
	mov	cl,al		! Save the IRQ for making masks
	inb	al,0xA1
	jmp	a1
a1:	jmp	a2
a2:	movb	al,#1
	shl	al,cl
	orb	al,cache_A1
	movb	cache_A1, al
	outb	0xA1,al		! Now ack the IRQ
	jmp	a3
a3:	jmp	a4
a4:	movb	al,#0x20
	outb	0xA0,al
	jmp	a5
a5:	jmp	a6
a6:	outb	0x20,al		! Ack on primary controller

!
!	And a trap does no hardware work	
!

was_trap:
	pop	bp
	pop 	di
	pop	si
	pop	dx
	pop	cx
!
!	The trap/IRQ may have wanted to reschedule when returning from the
!	IRQ/syscall. If so we pick it up here.	
!
	mov	_need_resched,bx
	cmp	bx,#0
	jnz	slowreturn
	pop	bx
	pop	es
	pop	ds
	pop	ax
	iret
!
!	Return and reschedule	
!
slowreturn:
	pop	bx
	pop	es
	pop	ds
	pop	ax
	int	0x80		! Schedule call is like this for now (WEIRD...)
	iret

#endasm
