|
|
MiNT 0.95 pl13
; ; 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.1.1.1 2018/04/24 17:55:36 root ; MiNT 0.95 pl13 ; ; 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.