Source to jet/intr.c
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,[email protected] /* check the sr to see if caller was super */
beq L_usr /* branch if not super */
lea [email protected](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 [email protected]+,_call_sr /* save the caller's sr */
movl [email protected]+,_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 [email protected],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,[email protected] /* 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 [email protected],a0 /* get table address */
cmpl #0,a0
beq _einvfn /* see if not allowed */
addl #2,sp /* ?? room for a return result ? */
jsr [email protected] /* 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,[email protected] /* put on a return address */
bra L_restore
L_usr1:
movl _call_sp,a0
movl _call_pc,[email protected] /* 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 [email protected],[email protected]
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 [email protected]
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 [email protected],d0 /* see if we found the entry of interest */
bne mlp1
mlp2:
movel [email protected](8),[email protected]+
tstl [email protected]
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,[email protected] /* put on a return address */
rts
addhold:
movel a0,d0
movel _next_hold,a0 /* get place to store this */
movel d0,[email protected]+ /* save start */
movel a1,[email protected]+ /* 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 [email protected](4), d0
movew d0, sr
rts
.globl _setsp
_setsp:
movel [email protected](4),d0
movel [email protected],a0
movel d0,sp
jmp [email protected]
.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,[email protected]
movw [email protected](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 [email protected]+,d0
movw [email protected](6),[email protected] /* repeat the frame type - we build a fake frame */
L_short:
movl _sysvar+4,[email protected] /* pretend that this is where we came from */
movw sr,[email protected] /* we need to copy the current (supervisor sr) */
notme:
movl _old_intr,[email protected] /* so that when we come back, we're in super mode */
rts /* go do the normal interupt processing */
bad_frame:
movw [email protected]+,d0
movl _old_intr,[email protected]
rts
/* nullVBL is where the MiNT kernel eventually returns to */
.globl _nullVBL
_nullVBL:
rte
");
}