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