home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
mint
/
mint095s
/
intr.s
< prev
next >
Wrap
Text File
|
1993-08-03
|
6KB
|
246 lines
|
| 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