|
|
1.1 root 1: %include "magic.i"
2:
3: ;
4:
5: ; interrupt wrapping routines; these should just save registers and call
6:
7: ; the appropriate C handlers, unless speed is a major problem
8:
9: ;
10:
11: TEXT
12:
13: ;
14:
15: ; first, utilities for setting processor status level
16:
17: ;
18:
19: XDEF _spl7,_spl
20:
21: _spl7:
22:
23: move.w sr,d0
24:
25: ori.w #$0700,sr
26:
27: rts
28:
29: _spl:
30:
31: move.w 4(sp),d0
32:
33: move.w d0,sr
34:
35: rts
36:
37:
38:
39: XDEF _mint_5ms
40:
41: XDEF _mint_timer
42:
43: XDEF _mint_vbl
44:
45: XREF _timeout ; C time routine
46:
47: XREF _old_timer ; old GEMDOS time vector
48:
49: XREF _old_vbl ; old GEMDOS vbl vector
50:
51: XREF _old_5ms
52:
53: XREF _build_context
54:
55: XREF _restore_context
56:
57: XREF _proc_clock ; controls process' allocation of CPU time
58:
59: XREF _curproc
60:
61: XREF _enter_kernel
62:
63: XREF _leave_kernel
64:
65: XREF _preempt
66:
67: XREF _in_kernel
68:
69:
70:
71: ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
72:
73: _mint_5ms:
74:
75: move.l a0,-(sp)
76:
77: move.l _curproc,a0
78:
79: tst.w _in_kernel
80:
81: bne.s L_systime
82:
83: lea P_USRTIME(a0),a0 ; get offset to curproc->usrtime
84:
85: addq.l #5,(a0) ; update the time
86:
87: move.l (sp)+,a0
88:
89: move.l _old_5ms+8,-(sp) ; branch to old vector
90:
91: rts
92:
93: L_systime:
94:
95: lea P_SYSTIME(a0),a0 ; get offset to curproc->systime
96:
97: addq.l #5,(a0)
98:
99: move.l (sp)+,a0
100:
101: move.l _old_5ms+8,-(sp)
102:
103: rts
104:
105:
106:
107: _mint_timer:
108:
109: movem.l d0-d2/a0-a2,-(sp) ; save C registers
110:
111: jsr _timeout
112:
113: movem.l (sp)+,d0-d2/a0-a2
114:
115: move.l _old_timer+8,-(sp) ; jump to GEMDOS time vector
116:
117: rts
118:
119:
120:
121: _mint_vbl:
122:
123: tst.w ($59e).w ; test longframe (AKP)
124:
125: beq.s L_short1
126:
127: clr.w -(sp) ; yes, long frames: push a frame word
128:
129: L_short1:
130:
131: pea L_comeback ; push fake PC
132:
133: move.w sr,-(sp) ; push status register
134:
135: move.l _old_vbl+8,-(sp) ; go service the interrupt
136:
137: rts
138:
139:
140:
141: L_comeback:
142:
143: tst.w _proc_clock ; has time expired yet?
144:
145: beq.s L_expired ; yes -- maybe go switch processes
146:
147: L_out:
148:
149: rte ; no -- just return
150:
151:
152:
153: L_expired:
154:
155: btst #5,(sp) ; user mode?
156:
157: bne.s L_out ; no -- switching is not possible
158:
159: tst.w ($43e).w ; test floppy disk lock variable
160:
161: bne.s L_out ; if locked, can't switch
162:
163: tst.w _in_kernel ; are we doing a kernel operation?
164:
165: bne.s L_out
166:
167: L_switch:
168:
169: clr.w -(sp) ; no frame format needed
170:
171: move.l _curproc,-(sp)
172:
173: addq.l #4,(sp) ; to get &curproc->ctxt[SYSCALL]
174:
175: jsr _build_context ; build context
176:
177: move.l _curproc,a0
178:
179: move.l (a0),sp ; use curproc->sysstack
180:
181: jsr _enter_kernel ; enter kernel
182:
183: jsr _preempt ; yield processor
184:
185: ori.w #$700,sr ; spl7()
186:
187: jsr _leave_kernel ; restore vectors
188:
189: move.l _curproc,a0
190:
191: pea 4(a0)
192:
193: jsr _restore_context ; back to user
194:
195:
196:
197: ;
198:
199: ; reset routine -- called on a warm boot. Note that TOS sends the
200:
201: ; address to which we should return in register a6. Also note that
202:
203: ; the stack pointer is in an unknown state, so we set up our own
204:
205: ;
206:
207: XDEF _reset
208:
209: XREF _tmpstack ; see main.c
210:
211: XREF _restr_intr
212:
213:
214:
215: _reset:
216:
217: move.w #$2700,sr ; avoid interruption here
218:
219: move.l sp,_tmpstack ; save A7
220:
221: lea _tmpstack,sp ; set up temporary stack
222:
223: lea 256(sp),sp
224:
225: movem.l d0-d2/a0-a2,-(sp) ; save C registers
226:
227: jsr _restr_intr ; restore interrupts
228:
229: movem.l (sp)+,d0-d2/a0-a2 ; restore registers
230:
231: move.l _tmpstack,sp
232:
233: jmp (a6) ; reset again
234:
235:
236:
237: ;
238:
239: ; routine for doing a reboot
240:
241: ;
242:
243: XDEF _reboot
244:
245: _reboot:
246:
247: move.w #$2700,sr ; avoid interrupts
248:
249: move.l (0).w,sp ; get sp after reboot
250:
251: move.l (4).w,a6 ; get new reboot address
252:
253: jmp _reset
254:
255:
256:
257: ;
258:
259: ; routine for mouse packet handling
260:
261: ;
262:
263: XDEF _newmvec
264:
265: XDEF _newjvec
266:
267: XREF _mouse_handler
268:
269: ; Experimental three button mouse support (by [email protected],
270:
271: ; August 4, 1992
272:
273: ;
274:
275: ; Should work with the mice shipped with Atari's ASV or
276:
277: ; compatible ones (like Golden Image GI-6000). Might not work
278:
279: ; on ST/STE systems with older IKBD's or keyboards. The middle mouse
280:
281: ; button is wired to one of the joystick directions on joystick one.
282:
283: ;
284:
285: ; _newmvec is the same as before with two exceptions:
286:
287: ; 1. the first byte of the packet is saved for the joystick handler
288:
289: ; 2. the bit for the middle mouse button is ored in
290:
291: ;
292:
293: ; _newjvec hooks into the joystick vector and chains to the normal
294:
295: ; handler. The middle mouse button state is saved in a special
296:
297: ; register for _newmvec, and a 'fake' mouse packet is set up
298:
299: ; (by merging the last mouse packet header, or-ing in the
300:
301: ; middle button state and using 0/0 for the x/y increment).
302:
303: ;
304:
305: ; the faked_packet and third_button variables are declared at the
306:
307: ; end of this file
308:
309:
310:
311: _newmvec:
312:
313: move.l a0,-(sp)
314:
315: move.b (a0),d0
316:
317: move.b d0,faked_packet
318:
319: or.b third_button,d0
320:
321: move.b d0,(a0)
322:
323: jsr _mouse_handler
324:
325: move.l (sp)+,a0
326:
327: rts
328:
329: ;
330:
331: ; routine for joystick packet handling (used for three button mice)
332:
333: ;
334:
335: XDEF _newjvec
336:
337: XREF _oldjvec
338:
339:
340:
341: _newjvec:
342:
343: move.l a0,-(sp) ; save a0 on the stack
344:
345: move.b 2(a0),d0 ; joystick direction
346:
347: and.b #1,d0 ; middle mouse button in lowest bit
348:
349: add.b d0,d0 ; times 4
350:
351: add.b d0,d0
352:
353: move.b d0,third_button ; save it for use in newmvec
354:
355:
356:
357: lea faked_packet,a0 ; 'our' faked mouse event
358:
359: move.b (a0),d0
360:
361: and.b #$3,d0 ; unmask our mouse button
362:
363: or.b #$F8,d0 ; or in correct header
364:
365: or.b third_button,d0 ; or in the current status
366:
367: move.b d0,(a0) ; write it back
368:
369:
370:
371: move.l a0,-(sp) ; pass pointer to fake packet
372:
373: jsr _mouse_handler ; to \dev\mouse handler
374:
375: addq.l #4,sp ; pop parameter
376:
377: move.l (sp)+,a0 ; restore original a0 value
378:
379: move.l _oldjvec,-(sp) ; jump to original joystick handler
380:
381: rts
382:
383: ;
384:
385: ; new ikbd keyboard interrupt vector
386:
387: ; kintr is a global variable that should be non-zero if a keyboard
388:
389: ; event occured
390:
391: ;
392:
393: XDEF _new_ikbd
394:
395: XREF _old_ikbd
396:
397: XREF _kintr
398:
399:
400:
401: _new_ikbd:
402:
403: move.w #1,_kintr
404:
405: move.l _old_ikbd+8,-(sp)
406:
407: rts ; jump to system interrupt routine
408:
409:
410:
411: ;
412:
413: ; simple signal handlers
414:
415: ; global variables referenced:
416:
417: ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
418:
419: ; sig_routine: (signal.c): pointer to which signal catching routine to
420:
421: ; call (e.g. for SIGBUS, or whatever)
422:
423: ;
424:
425: XDEF _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
426:
427: XDEF _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
428:
429: XDEF _new_uninit,_new_spurious,_new_format,_new_cpv
430:
431: XREF _in_kernel,_sig_routine
432:
433: XREF _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
434:
435: XREF _haltformat,_haltcpv
436:
437: XREF _sig_exc
438:
439:
440:
441: _new_bus:
442:
443: move.w #$8,_sig_exc
444:
445: move.l #_sigbus,_sig_routine
446:
447: Do_sig:
448:
449: tst.w _in_kernel ; are we already in the kernel?
450:
451: bne.s Kernel ; yes
452:
453: move.w _sig_exc,-(sp)
454:
455: move.l _curproc,-(sp)
456:
457: addq.l #4,(sp) ; push offset of save area
458:
459: jsr _build_context
460:
461: move.l _curproc,a4
462:
463: move.l (a4),sp ; put us in the system stack
464:
465: jsr _enter_kernel ; set up kernel vectors
466:
467: move.l _sig_routine,a1 ; get signal handling routine
468:
469: jsr (a1) ; go do it
470:
471: ori.w #$0700,sr ; spl7()
472:
473: jsr _leave_kernel ; leave kernel
474:
475: addq.w #4,a4 ; get context save area address
476:
477: move.l a4,-(sp) ; push it
478:
479: jsr _restore_context ; restore the context
480:
481: ;
482:
483: ; here's what we do if we already were in the kernel
484:
485: ;
486:
487: Kernel:
488:
489: movem.l d0-d2/a0-a2,-(sp) ; save reggies
490:
491: move.l _sig_routine,a1 ; get handler
492:
493: jsr (a1) ; go do it
494:
495: movem.l (sp)+,d0-d2/a0-a2
496:
497: rte
498:
499: _new_addr:
500:
501: move.w #$c,_sig_exc
502:
503: move.l #_sigaddr,_sig_routine
504:
505: bra.s Do_sig
506:
507: _new_ill:
508:
509: move.w #$10,_sig_exc
510:
511: move.l #_sigill,_sig_routine
512:
513: bra.s Do_sig ; ASM pre-5.52.3 barfs on this :-(
514:
515: _new_divzero:
516:
517: move.w #$14,_sig_exc
518:
519: move.l #_sigfpe,_sig_routine
520:
521: bra Do_sig
522:
523: _new_linef:
524:
525: move.w #$2c,_sig_exc
526:
527: move.l #_sigill,_sig_routine
528:
529: bra Do_sig
530:
531: _new_chk:
532:
533: move.w #$18,_sig_exc
534:
535: move.l #_sigfpe,_sig_routine
536:
537: bra Do_sig
538:
539: _new_trapv:
540:
541: move.w #$1c,_sig_exc
542:
543: move.l #_sigfpe,_sig_routine
544:
545: bra Do_sig
546:
547: _new_fpcp:
548:
549: ; don't set _sig_exc - only needed for 68000 vectors
550:
551: move.l #_sigfpe,_sig_routine
552:
553: bra Do_sig
554:
555: _new_mmu:
556:
557: ; don't set _sig_exc - only needed for 68000 vectors
558:
559: move.l #_sigill,_sig_routine
560:
561: bra Do_sig
562:
563: _new_pmmuacc:
564:
565: ; don't set _sig_exc - only needed for 68000 vectors
566:
567: move.l #_sigbus,_sig_routine
568:
569: bra Do_sig
570:
571: _new_uninit:
572:
573: move.w #$3c,_sig_exc
574:
575: move.l #_sigbus,_sig_routine
576:
577: bra Do_sig
578:
579: _new_spurious:
580:
581: move.w #$60,_sig_exc
582:
583: move.l #_sigbus,_sig_routine
584:
585: bra Do_sig
586:
587: _new_format:
588:
589: move.l #_haltformat,_sig_routine
590:
591: bra Do_sig
592:
593: _new_cpv:
594:
595: move.l #_haltcpv,_sig_routine
596:
597: bra Do_sig
598:
599:
600:
601: XREF _old_priv ; old privilege violation vector
602:
603: _new_priv:
604:
605: move.w #$20,_sig_exc
606:
607: move.l #_sigpriv,_sig_routine
608:
609: tst.w ($59e).w ; 68000s always get SIGPRIV
610:
611: beq Do_sig
612:
613: movem.l d0/a0,-(a7)
614:
615: move.l 10(a7),a0 ; fetch exception address
616:
617: move.w (a0),d0
618:
619: and.w #$ffc0,d0 ; partially decode move sr,...
620:
621: cmp.w #$40c0,d0 ; and test it
622:
623: movem.l (a7)+,d0/a0 ; preserves the flags
624:
625: bne Do_sig ; doesn't look like sr,...
626:
627: move.l _old_priv+8,-(sp) ; let our parent handle it
628:
629: rts
630:
631:
632:
633: ; XBRA vectors from main.c
634:
635: XREF _old_dos,_old_bios,_old_xbios
636:
637: XREF _old_divzero,_old_chk,_old_trapv
638:
639:
640:
641: _new_trace:
642:
643: btst #5,(a7) ; only check when called from supervisor mode
644:
645: beq.s S_1
646:
647: cmp.l #_old_dos+12,2(a7) ; lets not trace the kernel !
648:
649: beq.s S_2
650:
651: cmp.l #_old_xbios+12,2(a7)
652:
653: beq.s S_2
654:
655: cmp.l #_old_bios+12,2(a7)
656:
657: beq.s S_2
658:
659: cmp.l #_old_divzero+12,2(a7)
660:
661: beq.s S_2
662:
663: cmp.l #_old_trapv+12,2(a7)
664:
665: beq.s S_2
666:
667: cmp.l #_old_chk+12,2(a7)
668:
669: beq.s S_2
670:
671: ; add any other non-traceable entities here...
672:
673:
674:
675: S_1: move.w #$24,_sig_exc
676:
677: move.l #_sigtrap,_sig_routine
678:
679: bra Do_sig
680:
681:
682:
683: S_2: and.w #$3fff,(a7) ; clear both trace bits
684:
685: rte ; and re-start the handler
686:
687:
688:
689: ;
690:
691: ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
692:
693: ; just in case some program (foolishly) attempts to access these drives
694:
695: ; directly and gets horribly confused
696:
697: ;
698:
699: XREF _old_getbpb ; old Getbpb vector
700:
701: XREF _old_mediach ; old Mediach vector
702:
703: XREF _old_rwabs ; old Rwabs vector
704:
705: XREF _aliasdrv ; array of drive aliases
706:
707: XDEF _new_getbpb
708:
709: XDEF _new_mediach
710:
711: XDEF _new_rwabs
712:
713:
714:
715: _new_getbpb:
716:
717: move.w 4(sp),d0 ; check the drive
718:
719: move.w d0,d1 ; get index
720:
721: add.w d0,d1 ; convert to index
722:
723: lea _aliasdrv,a0
724:
725: move.w 0(a0,d1.w),d1 ; alias drive?
726:
727: beq.s noalias0
728:
729: move.w d1,d0
730:
731: subq.w #1,d0 ; adjust for aliasdrv base of '@'
732:
733: noalias0:
734:
735: cmp.w #$1f,d0 ; is this a legal drive?
736:
737: bhi.s nobpb ; no -- ignore it
738:
739: cmp.w #$14,d0 ; drive U:?
740:
741: beq.s nobpb ; yes, no BPB available
742:
743: move.l _old_getbpb+8,a0 ; not our drive
744:
745: jmp (a0) ; call the old vector for it
746:
747: nobpb:
748:
749: moveq.l #0,d0 ; 0 means "no BPB read"
750:
751: rts
752:
753:
754:
755: _new_mediach:
756:
757: move.w 4(sp),d0 ; check the drive
758:
759: move.w d0,d1 ; get index
760:
761: add.w d0,d1 ; convert to index
762:
763: lea _aliasdrv,a0
764:
765: move.w 0(a0,d1.w),d1 ; alias drive?
766:
767: beq.s noalias1
768:
769: move.w d1,d0
770:
771: subq.w #1,d0 ; adjust for aliasdrv base
772:
773: noalias1:
774:
775: cmp.w #$1f,d0 ; legal drive?
776:
777: bhi.s nobpb ; no -- ignore it
778:
779: cmp.w #$14,d0 ; drive U:?
780:
781: beq.s nochng ; yes, no change
782:
783: move.l _old_mediach+8,a0 ; not our drive
784:
785: jmp (a0) ; call the old vector for it
786:
787: nochng:
788:
789: moveq.l #0,d0 ; 0 means "definitely no change"
790:
791: rts
792:
793:
794:
795: _new_rwabs:
796:
797: move.w $e(sp),d0 ; check the drive
798:
799: move.w d0,d1 ; get index
800:
801: add.w d0,d1 ; convert to index
802:
803: lea _aliasdrv,a0
804:
805: move.w 0(a0,d1.w),d1 ; alias drive?
806:
807: beq.s noalias2
808:
809: move.w d1,d0
810:
811: subq.w #1,d0 ; adjust for aliasdrv base
812:
813: noalias2:
814:
815: cmp.w #$1f,d0 ; legal drive?
816:
817: bhi.s nobpb ; no -- ignore it
818:
819: cmp.w #$14,d0 ; drive U:?
820:
821: beq.s rwdone ; yes, fake it
822:
823: move.l _old_rwabs+8,a0 ; not our drive
824:
825: jmp (a0) ; call the old vector for it
826:
827: rwdone:
828:
829: moveq.l #0,d0 ; 0 means "successful operation"
830:
831: rts
832:
833:
834:
835: DATA
836:
837: ; buffer for faked mouse packet (actually only 3 bytes)
838:
839:
840:
841: faked_packet:
842:
843: dc.l 0
844:
845:
846:
847: ; here we store the additional button state
848:
849: third_button:
850:
851: dc.w 0
852:
853:
854:
855: END
856:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.