File:  [Atari MiNT] / MiNT / src / gas / intr.s
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:55:36 2018 UTC (8 years, 1 month ago) by root
Branches: mint, MAIN
CVS tags: mint095, HEAD
MiNT 0.95 pl13

|

| interrupt wrapping routines; these should just save registers and call

| the appropriate C handlers, unless speed is a major problem

|



|

| first, utilities for setting processor status level

|

	.globl	_spl7, _spl

_spl7:

	movew	sr, d0

	oriw	#0x0700, sr

	rts

_spl:

	movew	sp@(4), d0

	movew	d0, sr

	rts



	.globl	_mint_5ms

	.globl	_mint_timer

	.globl	_mint_vbl

	.globl	_timeout	| C time routine

	.globl	_old_timer	| old GEMDOS time vector

	.globl	_old_vbl	| old GEMDOS vbl vector

	.globl	_old_5ms

	.globl	_build_context

	.globl	_restore_context

	.globl	_proc_clock		| controls process' allocation of CPU time

	.globl	_curproc

	.globl	_in_kernel



| AKP: this code is hit once every 5ms; it updates the time fields of curproc.

_mint_5ms:

	movel	a0,sp@-

	movel	_curproc,a0

	addw	#0x364,a0		| $364 is offset to curproc->systime;

	tstw	_in_kernel

	bne	L_5a			| usrtime is the branch-not-taken case

	addql	#4,a0

L_5a:	addql	#5,a0@

	movel	sp@+,a0

	movel	_old_5ms+8,sp@-

	rts



_mint_timer:

	moveml	d0-d2/a0-a2, sp@-	| save C registers

	jsr	_timeout

	moveml	sp@+, d0-d2/a0-a2

	movel	_old_timer+8, sp@-	| jump to GEMDOS time vector

	rts



_mint_vbl:

	tstw	0x59e			| test longframe (AKP)

	beq	L_short1

	clrw	sp@-			| yes, long frames: push a frame word

L_short1:

	pea	L_comeback		| push fake PC

	movew	sr, sp@-		| push status register

	movel	_old_vbl+8, sp@-	| go service the interrupt

	rts



L_comeback:

	tstw	_proc_clock		| has time expired yet?

	beq	L_expired		| yes -- maybe go switch processes

L_out:

	rte				| no -- just return



L_expired:

	btst	#13, sp@		| user mode?

	bne	L_out			| no -- switching is not possible

L_switch:

	movel	_curproc, sp@-

	addl	#4, sp@			| to get &curproc->ctxt[SYSCALL]

	jsr	_build_context		| build context

	movel	_curproc, a0

	movel	a0@, sp			| use curproc->sysstack

	jsr	_enter_kernel		| enter kernel

	jsr	_preempt		| yield processor

	oriw	#0x0700, sr		| spl7()

	jsr	_leave_kernel		| restore vectors

	movel	_curproc, a0

	pea	a0@(4)

	jsr	_restore_context	| back to user

|

| reset routine -- called on a warm boot. Note that TOS sends the

| address to which we should return in register a6. Also note that

| the stack pointer is in an unknown state, so we set up our own

|

	.globl	_reset

	.globl	_tmpstack		| see main.c



_reset:

	movew	#0x2700, sr		| avoid interruption here

	movel	sp, _tmpstack		| save A7

	lea	_tmpstack, sp		| set up temporary stack

	lea	sp@(256), sp

	moveml	d0-d2/a0-a2, sp@-	| save C registers

	jsr	_restr_intr		| restore interrupts

	moveml	sp@+, d0-d2/a0-a2	| restore registers

	movel	_tmpstack, sp

	jmp	a6@			| reset again



|

| routine for doing a reboot

|

	.globl	_reboot

_reboot:

	movew	#0x2700, sr		| avoid interrupts

	movel	0x00, sp		| get sp after reboot

	movel	0x04, a6		| get new reboot address

	jmp	_reset



|

| routine for mouse packet handling

|

	.globl	_newmvec

_newmvec:

	movel	a0, sp@-

	jsr	_mouse_handler

	movel	sp@+, a0

	rts



|

| new ikbd keyboard interrupt vector

| kintr is a global variable that should be non-zero if a keyboard

| event occured

|

	.globl	_new_ikbd

_new_ikbd:

	movew	#1, _kintr

	movel	_old_ikbd+8, sp@-

	rts			| jump to system interrupt routine



|

| simple signal handlers

| global variables referenced:

| in_kernel: (main.c): flag to indicate that we're in the MiNT kernel

| sig_routine: (signal.c): pointer to which signal catching routine to

|          call (e.g. for SIGBUS, or whatever)

|

	.globl	_new_bus, _new_addr, _new_ill, _new_divzero, _new_priv

	.globl	_new_trace

	.globl	_in_kernel, _sig_routine

_new_bus:

	movel	#_sigbus, _sig_routine

Do_sig:

	tstw	_in_kernel		| are we already in the kernel?

	bne	Kernel			| yes

	movel	_curproc, sp@-

	addl	#4, sp@			| push offset of save area

	jsr	_build_context

	movel	_curproc, a4

	movel	a4@, sp			| put us in the system stack

	jsr	_enter_kernel		| set up kernel vectors

	movel	_sig_routine, a1	| get signal handling routine

	jsr	a1@			| go do it

	oriw	#0x0700, sr		| spl7()

	jsr	_leave_kernel		| leave kernel

	lea	a4@(4), a4		| get context save area address

	movel	a4, sp@-		| push it

	jsr	_restore_context	| restore the context

|

| here's what we do if we already were in the kernel

|

Kernel:

	moveml	d0-d2/a0-a2, sp@-	| save reggies

	movel	_sig_routine, a1	| get handler

	jsr	a1@			| go do it

	moveml	sp@+, d0-d2/a0-a2

	rte	

_new_addr:

	movel	#_sigaddr, _sig_routine

	bra	Do_sig

_new_ill:

	movel	#_sigill, _sig_routine

	bra	Do_sig

_new_divzero:

	movel	#_sigfpe, _sig_routine

	bra	Do_sig

_new_priv:

	movel	#_sigpriv, _sig_routine

	bra	Do_sig

_new_trace:

	movel	#_sigtrap, _sig_routine

	bra	Do_sig



|

| BIOS disk vectors for pseudo-disks like U: and X:; these are present

| just in case some program (foolishly) attempts to access these drives

| directly and gets horribly confused

|

	.globl	_old_getbpb	| old Getbpb vector

	.globl	_old_mediach	| old Mediach vector

	.globl	_old_rwabs	| old Rwabs vector



	.globl	_new_getbpb

_new_getbpb:

	movew	sp@(4), d0	| check the drive

	cmpw	#0x10, d0	| drive Q:?

	beq	nobpb		| yes, no BPB available

	cmpw	#0x14, d0	| drive U:?

	beq	nobpb		| yes, no BPB available

	cmpw	#0x15, d0	| drive V:?

	beq	nobpb

	cmpw	#0x17, d0	| drive X:?

	beq	nobpb

	movel	_old_getbpb+8, a0	| not our drive

	jmp	a0@		| call the old vector for it

nobpb:

	moveql	#0, d0		| 0 means "no BPB read"

	rts



	.globl	_new_mediach

_new_mediach:

	movew	sp@(4), d0	| check the drive

	cmpw	#0x10, d0	| drive Q:?

	beq	nochng		| yes, no change

	cmpw	#0x14, d0	| drive U:?

	beq	nochng		| yes, no change

	cmpw	#0x15, d0	| drive V:?

	beq	nochng

	cmpw	#0x17, d0	| drive X:?

	beq	nochng

	movel	_old_mediach+8, a0	| not our drive

	jmp	a0@		| call the old vector for it

nochng:

	moveql	#0, d0		| 0 means "definitely no change"

	rts



	.globl	_new_rwabs

_new_rwabs:

	movew	sp@(0xe), d0	| check the drive

	cmpw	#0x10, d0	| drive Q:?

	beq	rwdone		| yes, fake a successful I/O operation

	cmpw	#0x14, d0	| drive U:?

	beq	rwdone		| yes, fake it

	cmpw	#0x15, d0	| drive V:?

	beq	rwdone

	cmpw	#0x17, d0	| drive X:?

	beq	rwdone

	movel	_old_rwabs+8, a0 | not our drive

	jmp	a0@		| call the old vector for it

rwdone:

	moveql	#0, d0		| 0 means "successful operation"

	rts


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.