Source to jet/intr.c


Enter a symbol's name here to quickly find it.

void trap_handlers(void)
{ asm("

	.globl  _dos
_dos:
	movl	#_dos_tab,_syscall_tab
	movw	_dos_max,_syscall_max
	bra	_syscall

	.globl  _bios
_bios:
	movl	#_bios_tab,_syscall_tab
	movw	_bios_max,_syscall_max
	bra	_syscall

	.globl  _xbios
_xbios:
	movl	#_xbios_tab,_syscall_tab
	movw	_xbios_max,_syscall_max
	bra	_syscall

	.globl	_aes
_aes:
	movl	#-1,d0
	rte

	.globl	_linea
_linea:
	movl	___aline,d0
	rte

_syscall:
	btst	#13,sp@		/* check the sr to see if caller was super */
	beq	L_usr		/* branch if not super */
	lea	sp@(8),a0	/* set a0 to point to what the ssp was before the trap */
	tstw	_longframe
	bne	L_save		/* 68000 uses a short frame */
	subl	#2,a0
	bra	L_save
L_usr:
	movl	usp,a0			
L_save:				/* by here a0 is always the pre-trap sp */
	movl	a0,_call_sp	/* save the caller's sp */
	movw	sp@+,_call_sr	/* save the caller's sr */
	movl	sp@+,_call_pc	/* save the return address */
	tstw	_longframe
	beq	L_regsave
	addw	#2,sp		/* adjust for longframes i.e. throw away long info */
L_regsave:
	moveml	d2-d7/a5,_call_regs /* save some calling registers */
	movel	_jet_stack,sp	/* set up our private stack */
	jsr	_pull_vector	/* restore the mac vectors, while in super mode */
	movel	_call_sp,a0	/* restore this since _pull_vector blew it away */
	moveml	a0@,d0-d7	/* get d0-d7 from the caller's stack */
	swap	d0		/* exchange this so low = function number */
	clrw	_swap		/* inidicate no super/user mode switch */
	cmpw	#0x20,d0	/* note d0 high = system call number */
	beq novm		/* execute s_uper in supervisor mode */
	cmpw	#0x26,d0
	beq novm		/* also s_upexec. Note: 20 is DOS only, 26 is XBIOS only */		
	tstw	_vm
	beq novm
	movew	#-1,_swap	/* indicate we've swapped stacks, mode */
	movel	usp,a0
	movel	a0,_mintusp	/* save the user stack */
	movel	sp,a0
	movel	a0,usp		/* make the super stack into user stack */
	movel	_macssp,sp	/* restore the mac super stack */
	andiw	#0xdfff,sr	/* enter the user mode */
novm:
	swap	d0		/* return d0 to normal */
	moveml	d0-d7,sp@-	/* save all registers on new stack */
	movl	0x904,a5	/* restore the mac a5 value */
	movel	d0,d7		/* get the calling argument */
	clrw	d7		/* zero out bottom */
	swap	d7		/* put argument in bottom, zero in top */
	cmpw	_syscall_max,d7	/* check if system call out of range */
	bge	_einvfn
	addl	d7,d7
	addl	d7,d7		/* times four to index in table */
	movl	_syscall_tab,a0
	addl	d7,a0
	movl	a0@,a0		/* get table address */
	cmpl	#0,a0
	beq	_einvfn		/* see if not allowed */
	addl	#2,sp		/* ?? room for a return result ? */
	jsr	a0@		/* go do the system call, (sp) has garbage word */
				/* followed by the 8 long words that were on the */
				/* caller's stack */

	.globl	_out
_out:
	movl	d0,d7		/* save d0 for blow away */
	tstw	_swap		/* see if we've swapped modes */
	beq	noswap
	movel	sp,_mintssp	/* this WOULD BE the mint ssp except that vm is on */
	moveql	#8,d0
	.word	0xa08d		/* enter the supervisor mode */
	movel	sp,_macssp	/* save the mac ssp */
	movel	_mintusp,a0
	movel	a0,usp		/* restore the mint usp */
	movel	_mintssp,sp	/* restore the would-be mint ssp */
noswap:
	jsr	_put_vector	/* restore mint vectors and interupts */
	movl	d7,d0
	btst	#13,_call_sr	/* check calling mode */
	beq	L_usr1		/* branch if called from user mode */
	movl	_call_sp,sp	/* restore the calling ssp */
	movl	_call_pc,sp@-	/* put on a return address */	
	bra	L_restore
L_usr1:
	movl	_call_sp,a0
	movl	_call_pc,a0@-	/* put return address on user stack */
	movl	a0,usp		/* restore user stack */
L_restore:
	moveml	_call_regs,d2-d7/a5	/* restore calling registers */
	movl	d2,a0		| hack for startup ??
	movw	_call_sr,sr	| this restores the user state if we called in user mode
	rts			| so that the user stack may be used for this rts

_einvfn:
	movel	_call_sp,a0
	movw	a0@,sp@-
	jsr	_badfn
	addw	#2,sp
	movl	#-32,d0
	bra	_out

	.globl	_mac_env
_mac_env:
	jsr	_pull_vector
	movel	a5,_minta5
	tstw	_vm
	beq	noneed
	movel	usp,a0
	movel	a0,_mintusp	/* save the user stack */
	movel	sp,a0
	movel	a0,usp		/* make the super stack into user stack */
	movel	_macssp,sp	/* restore the mac super stack */
	andiw	#0xdfff,sr	/* enter the user mode */
noneed:
	movel	0x904,a5	/* restore a5 */
	rts
	
	.globl	_mint_env
_mint_env:
	tstw	_vm
	beq	pvnovm		/* 9/9/96 out of range branch bug fixed! */
	movel	sp,_mintssp	/* this WOULD BE the mint ssp except that vm is on */
	moveql	#8,d0
	.word	0xa08d		/* enter the supervisor mode */
	movel	sp,_macssp	/* save the mac ssp */
	movel	_mintusp,a0
	movel	a0,usp		/* restore the mint usp */
	movel	_mintssp,sp	/* restore the would-be mint ssp */
pvnovm:
	movel	_minta5,a5
	jmp	_put_vector
	
	.globl	_Mem_Dispatch
_Mem_Dispatch:
	tstw	d0
	beq	addhold		/* this is a HoldMemory call */
	cmpw	#1,d0
	bne	memdone		/* not an UnholdMemory call */
	movel	a0,d0		/* save the starting address */
	movel	_holdstart,a0	/* get the top of the list */
	subql	#8,a0
mlp1:
	addql	#8,a0
	tstl	a0@
	bne	mfine
/* hmmm we're unholding somebody else */
/* this can happen with power management for instance */
	movel	d0,a0
	moveq	#1,d0
	bra	memdone
mfine:
	cmpl	a0@,d0		/* see if we found the entry of interest */
	bne	mlp1
mlp2:
	movel	a0@(8),a0@+
	tstl	a0@
	bne	mlp2		/* copy list up */
	subql	#8,_next_hold
	movel	d0,a0		/* restore starting address */
	moveq	#1,d0		/* and restore selector */
memdone:
	movel	_old_md,a7@-	/* put on a return address */
	rts
addhold:
	movel	a0,d0
	movel	_next_hold,a0	/* get place to store this */
	movel	d0,a0@+		/* save start */
	movel	a1,a0@+		/* and length */
	movel	a0,_next_hold	/* update position */
	subl	#3988,a0
	cmpl	_holdstart,a0	/* see if we're overflowing */
	bcs	addone
	.word	0xa9ff
addone:
	movel	d0,a0		/* restore starting point */
	clrl	d0		/* and selector */
	bra	memdone

");
}

void intr_handlers(void)
{
	asm("

	.globl	_spl7
_spl7:
	movew	sr, d0
	oriw	#0x0700, sr
	rts

	.globl	_spl
_spl:
	movew	sp@(4), d0
	movew	d0, sr
	rts

	.globl	_setsp
_setsp:
	movel	sp@(4),d0
	movel	sp@,a0
	movel	d0,sp
	jmp	a0@

	.globl	_intr
/* here we make a quick decision if a fake frame is necessary */
/* intr_flag is periodically set by the vbl routine */
/* and when it is, we build a fake frame that returns */
/* to the MiNT kernel instead of where we actually came from */

_intr:	bclr	#0,_intr_flag	/* this is less likely to have re-entrancy?? */
	beq	notme
	tstw	_longframe	/* here is where we do the preemptive dirty work */
	beq	L_short
	movw	d0,sp@-
   	movw	sp@(8),d0	/* get the frame type */
	cmpw	#0x0064,d0	/* we don't fool with ANYTHING unusual */
	bne	bad_frame	/* after all, who knows what a PowerPC may do */
	movw	sp@+,d0
	movw	sp@(6),sp@-	/* repeat the frame type - we build a fake frame */
L_short:
	movl	_sysvar+4,sp@-	/* pretend that this is where we came from */
	movw	sr,sp@-		/* we need to copy the current (supervisor sr) */
notme:
	movl	_old_intr,sp@-	/* so that when we come back, we're in super mode */
	rts			/* go do the normal interupt processing */

bad_frame:
	movw	sp@+,d0
	movl	_old_intr,sp@-
	rts

/* nullVBL is where the MiNT kernel eventually returns to */

	.globl	_nullVBL
_nullVBL:
	rte

	");
}