home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
PURE_B
/
PBMAG22A.MSA
/
MINT095S.ZIP
/
SRC
/
ASM
/
INTR.S
< prev
next >
Wrap
Text File
|
1987-04-22
|
7KB
|
277 lines
;
; interrupt wrapping routines; these should just save registers and call
; the appropriate C handlers, unless speed is a major problem
;
; $Log: intr.s,v $
; Revision 1.5 1992/04/18 10:57:18 AGK
; More +8s for 0.94
;
; Revision 1.4 1992/04/04 16:05:54 AGK
; Added some missing +8s in the vector pushes to allow for XBRA support
;
; Revision 1.3 1992/03/31 14:02:08 AGK
; Fixed for real Motorola syntax (many thanks to ERS for keeping these
; files in step with the GAS ones).
;
; Revision 1.2 1992/03/31 13:55:28 AGK
; Checked in MiNT 0.93 sources
;
; Revision 1.1 1991/05/30 17:22:18 AGK
; Initial revision
;
SECTION TEXT
;
; first, utilities for setting processor status level
;
XDEF _spl7,_spl
_spl7:
move.w sr,d0
ori.w #$0700,sr
rts
_spl:
move.w 4(sp),d0
move.w d0,sr
rts
XDEF _mint_5ms
XDEF _mint_timer
XDEF _mint_vbl
XREF _timeout ; C time routine
XREF _old_timer ; old GEMDOS time vector
XREF _old_vbl ; old GEMDOS vbl vector
XREF _old_5ms
XREF _build_context
XREF _restore_context
XREF _proc_clock ; controls process' allocation of CPU time
XREF _curproc
XREF _enter_kernel
XREF _leave_kernel
XREF _preempt
XREF _in_kernel
; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
_mint_5ms:
move.l a0,-(sp)
move.l _curproc,a0
add.w #$364,a0 ; $364 is offset to curproc->systime;
tst.w _in_kernel
bne L_5a ; usrtime is the branch-not-taken case
addq.l #4,a0
L_5a: addq.l #5,(a0)
move.l (sp)+,a0
move.l _old_5ms+8,-(sp)
rts
_mint_timer:
movem.l d0-d2/a0-a2,-(sp) ; save C registers
jsr _timeout
movem.l (sp)+,d0-d2/a0-a2
move.l _old_timer+8,-(sp) ; jump to GEMDOS time vector
rts
_mint_vbl:
tst.w ($59e).w ; test longframe (AKP)
beq.s L_short1
clr.w -(sp) ; yes, long frames: push a frame word
L_short1:
pea L_comeback ; push fake PC
move.w sr,-(sp) ; push status register
move.l _old_vbl+8,-(sp) ; go service the interrupt
rts
L_comeback:
tst.w _proc_clock ; has time expired yet?
beq.s L_expired ; yes -- maybe go switch processes
L_out:
rte ; no -- just return
L_expired:
btst #13,(sp) ; user mode?
bne.s L_out ; no -- switching is not possible
L_switch:
move.l _curproc,-(sp)
addq.l #4,(sp) ; to get &curproc->ctxt[SYSCALL]
jsr _build_context ; build context
move.l _curproc,a0
move.l (a0),sp ; use curproc->sysstack
jsr _enter_kernel ; enter kernel
jsr _preempt ; yield processor
ori.w #$700,sr ; spl7()
jsr _leave_kernel ; restore vectors
move.l _curproc,a0
pea 4(a0)
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
;
XDEF _reset
XREF _tmpstack ; see main.c
XREF _restr_intr
_reset:
move.w #$2700,sr ; avoid interruption here
move.l sp,_tmpstack ; save A7
lea _tmpstack,sp ; set up temporary stack
lea 256(sp),sp
movem.l d0-d2/a0-a2,-(sp) ; save C registers
jsr _restr_intr ; restore interrupts
movem.l (sp)+,d0-d2/a0-a2 ; restore registers
move.l _tmpstack,sp
jmp (a6) ; reset again
;
; routine for doing a reboot
;
XDEF _reboot
_reboot:
move.w #$2700,sr ; avoid interrupts
move.l (0).w,sp ; get sp after reboot
move.l (4).w,a6 ; get new reboot address
jmp _reset
;
; routine for mouse packet handling
;
XDEF _newmvec
XREF _mouse_handler
_newmvec:
move.l a0,-(sp)
jsr _mouse_handler
move.l (sp)+,a0
rts
;
; new ikbd keyboard interrupt vector
; kintr is a global variable that should be non-zero if a keyboard
; event occured
;
XDEF _new_ikbd
XREF _old_ikbd
XREF _kintr
_new_ikbd:
move.w #1,_kintr
move.l _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)
;
XDEF _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv
XDEF _new_trace
XREF _in_kernel,_sig_routine
XREF _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
_new_bus:
move.l #_sigbus,_sig_routine
Do_sig:
tst.w _in_kernel ; are we already in the kernel?
bne.s Kernel ; yes
move.l _curproc,-(sp)
add.l #4,(sp) ; push offset of save area
jsr _build_context
move.l _curproc,a4
move.l (a4),sp ; put us in the system stack
jsr _enter_kernel ; set up kernel vectors
move.l _sig_routine,a1 ; get signal handling routine
jsr (a1) ; go do it
ori.w #$0700,sr ; spl7()
jsr _leave_kernel ; leave kernel
lea 4(a4),a4 ; get context save area address
move.l a4,-(sp) ; push it
jsr _restore_context ; restore the context
;
; here's what we do if we already were in the kernel
;
Kernel:
movem.l d0-d2/a0-a2,-(sp) ; save reggies
move.l _sig_routine,a1 ; get handler
jsr (a1) ; go do it
movem.l (sp)+,d0-d2/a0-a2
rte
_new_addr:
move.l #_sigaddr,_sig_routine
bra.s Do_sig
_new_ill:
move.l #_sigill,_sig_routine
bra.s Do_sig
_new_divzero:
move.l #_sigfpe,_sig_routine
bra.s Do_sig
_new_priv:
move.l #_sigpriv,_sig_routine
bra Do_sig
_new_trace:
move.l #_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
;
XREF _old_getbpb ; old Getbpb vector
XREF _old_mediach ; old Mediach vector
XREF _old_rwabs ; old Rwabs vector
XDEF _new_getbpb
XDEF _new_mediach
XDEF _new_rwabs
_new_getbpb:
move.w 4(sp),d0 ; check the drive
cmp.w #$10,d0 ; drive Q:?
beq.s nobpb ; yes, no BPB available
cmp.w #$14,d0 ; drive U:?
beq.s nobpb ; yes, no BPB available
cmp.w #$15,d0 ; drive V:?
beq.s nobpb
cmp.w #$17,d0 ; drive X:?
beq.s nobpb
move.l _old_getbpb+8,a0 ; not our drive
jmp (a0) ; call the old vector for it
nobpb:
moveq.l #0,d0 ; 0 means "no BPB read"
rts
_new_mediach:
move.w 4(sp),d0 ; check the drive
cmp.w #$10,d0 ; drive Q:?
beq.s nochng ; yes, no change
cmp.w #$14,d0 ; drive U:?
beq.s nochng ; yes, no change
cmp.w #$15,d0 ; drive V:?
beq.s nochng
cmp.w #$17,d0 ; drive X:?
beq.s nochng
move.l _old_mediach+8,a0 ; not our drive
jmp (a0) ; call the old vector for it
nochng:
moveq.l #0,d0 ; 0 means "definitely no change"
rts
_new_rwabs:
move.w $e(sp),d0 ; check the drive
cmp.w #$10,d0 ; drive Q:?
beq.s rwdone ; yes, fake a successful I/O operation
cmp.w #$14,d0 ; drive U:?
beq.s rwdone ; yes, fake it
cmp.w #$15,d0 ; drive V:?
beq.s rwdone
cmp.w #$17,d0 ; drive X:?
beq.s rwdone
move.l _old_rwabs+8,a0 ; not our drive
jmp (a0) ; call the old vector for it
rwdone:
moveq.l #0,d0 ; 0 means "successful operation"
rts
END