|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.