|
|
1.1 ! root 1: ; ! 2: ! 3: ; syscall: interface for system calls. The following entry points are ! 4: ! 5: ; defined: ! 6: ! 7: ; _mint_bios: entry point for the BIOS calls (trap #13) ! 8: ! 9: ; _mint_xbios: entry point for XBIOS calls (trap #14) ! 10: ! 11: ; _mint_dos: entry point for GEMDOS calls (trap #1) ! 12: ! 13: ; _sig_return: user signal handlers return to this routine (see signal.c) ! 14: ! 15: ; it is responsible for restoring the kernel's old context ! 16: ! 17: ; via the Psigreturn() system call ! 18: ! 19: ; _lineA0: calls the line A initialize routine ! 20: ! 21: ; _call_aes: calls the GEM AES ! 22: ! 23: ; _callout: calls an external function, after first saving all registers, ! 24: ! 25: ; and restores the registers afterward ! 26: ! 27: ; ! 28: ! 29: ; external variables referenced: ! 30: ! 31: ; _bios_tab, _bios_max: ! 32: ! 33: ; table of entry points for BIOS routines, max # of routine ! 34: ! 35: ; _xbios_tab, _xbios_max: ! 36: ! 37: ; ditto for XBIOS ! 38: ! 39: ; _dos_tab, _dos_max: ! 40: ! 41: ; ditto for GEMDOS ! 42: ! 43: ; _curproc: ! 44: ! 45: ; pointer to current process table entry, and hence to save area for ! 46: ! 47: ; context (this is always the first entry in the PROC table). ! 48: ! 49: ; _valid_return: ! 50: ! 51: ; used to indicate to the kernel that a valid return from user mode ! 52: ! 53: ; is taking place ! 54: ! 55: ; ! 56: ! 57: ; _bconbuf, _bconbsiz, _bconbdev: ! 58: ! 59: ; 256 byte buffer for Bconout() output. If _bconbsiz is non-zero, ! 60: ! 61: ; there are that many bytes in _bconbuf waiting to be flushed. The ! 62: ! 63: ; output is for device _bconbdev. ! 64: ! 65: ; ! 66: ! 67: ; The C function enter_kernel() is called on entry to the kernel, and the ! 68: ! 69: ; function leave_kernel() is called on exit. These functions are responsible ! 70: ! 71: ; for saving and restoring the various trap vectors, so that MiNT can trap ! 72: ! 73: ; out to TOS directly, but programs can only trap to MiNT. ! 74: ! 75: ; ! 76: ! 77: ; $Log: syscall.s,v $ ! 78: ! 79: ; Revision 1.3 1992/03/31 14:02:08 AGK ! 80: ! 81: ; Fixed for real Motorola syntax (many thanks to ERS for keeping these ! 82: ! 83: ; files in step with the GAS ones). ! 84: ! 85: ; ! 86: ! 87: ; Revision 1.2 1992/03/31 13:55:28 AGK ! 88: ! 89: ; Checked in MiNT 0.93 sources ! 90: ! 91: ; ! 92: ! 93: ; Revision 1.1 1991/05/30 17:24:16 AGK ! 94: ! 95: ; Initial revision ! 96: ! 97: ; ! 98: ! 99: SECTION TEXT ! 100: ! 101: ! 102: ! 103: XDEF _mint_bios,_mint_xbios ! 104: ! 105: XDEF _mint_dos ! 106: ! 107: XREF _build_context ! 108: ! 109: XREF _restore_context ! 110: ! 111: XREF _proc_clock ; controls process' allocation of CPU time ! 112: ! 113: XREF _enter_kernel ! 114: ! 115: XREF _leave_kernel ! 116: ! 117: XREF _preempt ! 118: ! 119: ! 120: ! 121: XREF _curproc ! 122: ! 123: XREF _bios_tab,_bios_max ! 124: ! 125: XREF _xbios_tab,_xbios_max ! 126: ! 127: XREF _dos_tab,_dos_max ! 128: ! 129: ! 130: ! 131: XREF _bconbuf,_bconbsiz,_bconbdev ! 132: ! 133: XREF _bflush ! 134: ! 135: ! 136: ! 137: _mint_dos: ! 138: ! 139: move.l #_dos_tab,syscall_tab ! 140: ! 141: move.w _dos_max,syscall_max ! 142: ! 143: bra.s _syscall ! 144: ! 145: ! 146: ! 147: _mint_xbios: ! 148: ! 149: move.l #_xbios_tab,syscall_tab ! 150: ! 151: move.w _xbios_max,syscall_max ! 152: ! 153: bra.s _syscall ! 154: ! 155: ! 156: ! 157: _mint_bios: ! 158: ! 159: ; ! 160: ! 161: ; Bconout() is noticeably slower under MiNT, so we do a bit of a kludge ! 162: ! 163: ; and special case Bconout() so that it doesn't take so long. We ! 164: ! 165: ; do this by buffering Bconout calls until either another kind of ! 166: ! 167: ; system call or a context switch happens. ! 168: ! 169: ; ! 170: ! 171: tst.w _bconbdev ; buffering on? ! 172: ! 173: bmi.s L_bios ; if bconbdev < 0, no buffering ! 174: ! 175: btst #13,(sp) ; test for user/super mode ! 176: ! 177: beq.s L_usr ; ! 178: ! 179: lea 6(sp),a1 ; supervisor mode: args on stack ! 180: ! 181: tst.w $59e ; test longframe ! 182: ! 183: beq.s L_check ! 184: ! 185: addq.l #2,a1 ; stack is a bit bigger ! 186: ! 187: bra.s L_check ! 188: ! 189: L_usr: ! 190: ! 191: move.l usp,a1 ; user mode: args on user stack ! 192: ! 193: L_check: ! 194: ! 195: move.w (a1),d0 ; check command ! 196: ! 197: cmp.w #3,d0 ; Bconout? ! 198: ! 199: beq do_bconout ; yes -- take some shortcuts ! 200: ! 201: ; no -- fall through to the normal code ! 202: ! 203: L_bios: ! 204: ! 205: move.l #_bios_tab,syscall_tab ! 206: ! 207: move.w _bios_max,syscall_max ! 208: ! 209: ! 210: ! 211: _syscall: ! 212: ! 213: move.l _curproc,d0 ! 214: ! 215: addq.l #4,d0 ! 216: ! 217: move.l d0,-(sp) ; push pointer to syscall context save ! 218: ! 219: jsr _build_context ! 220: ! 221: ; ! 222: ! 223: ; copy parameters onto process stack. a1 was set by _build_context ! 224: ! 225: ; ! 226: ! 227: L_copy: ! 228: ! 229: move.l _curproc,a0 ! 230: ! 231: move.l (a0),sp ; this puts us in our private stack ! 232: ! 233: move.l 24(a1),-(sp) ; a1 was set by build_context ! 234: ! 235: move.l 20(a1),-(sp) ! 236: ! 237: move.l 16(a1),-(sp) ! 238: ! 239: move.l 12(a1),-(sp) ! 240: ! 241: move.l 8(a1),-(sp) ! 242: ! 243: move.l 4(a1),-(sp) ! 244: ! 245: move.l (a1),-(sp) ! 246: ! 247: ; ! 248: ! 249: jsr _enter_kernel ; set up vectors appropriately ! 250: ! 251: ; ! 252: ! 253: ; check here to see if we need to flush the Bconout() buffer ! 254: ! 255: ; ! 256: ! 257: tst.w _bconbsiz ; characters in buffer? ! 258: ! 259: beq.s L_noflush ; no: OK to proceed ! 260: ! 261: ; ! 262: ! 263: ; make sure we save syscall_tab and syscall_max ! 264: ! 265: ; ! 266: ! 267: move.l syscall_tab,-(sp) ! 268: ! 269: move.w syscall_max,-(sp) ! 270: ! 271: jsr _bflush ; flush the buffer ! 272: ! 273: move.w (sp)+,syscall_max ! 274: ! 275: move.l (sp)+,syscall_tab ! 276: ! 277: ! 278: ! 279: L_noflush: ! 280: ! 281: ; ! 282: ! 283: ; figure out which routine to call ! 284: ! 285: ; ! 286: ! 287: clr.l d0 ! 288: ! 289: move.w (sp),d0 ! 290: ! 291: cmp.w #-1,d0 ; trapping with -1 means return ! 292: ! 293: bne.s check_max ; the corresponding system table ! 294: ! 295: move.l syscall_tab,d0 ! 296: ! 297: bra.s out ! 298: ! 299: check_max: ! 300: ! 301: cmp.w syscall_max,d0 ! 302: ! 303: bge.s error ! 304: ! 305: add.l d0,d0 ! 306: ! 307: add.l d0,d0 ; multiply by 4 ! 308: ! 309: move.l syscall_tab,a0 ! 310: ! 311: add.l d0,a0 ! 312: ! 313: move.l (a0),a0 ! 314: ! 315: cmp.l #0,a0 ; null entry means invalid call ! 316: ! 317: beq.s error ! 318: ! 319: addq.l #2,sp ; pop function number off stack ! 320: ! 321: jsr (a0) ; go do the call ! 322: ! 323: out: ! 324: ! 325: move.l _curproc,a0 ! 326: ! 327: move.l d0,4(a0) ; set d0 in the saved context ! 328: ! 329: tst.w _proc_clock ; has process exceeded time slice? ! 330: ! 331: bne.s nosleep ; no -- continue ! 332: ! 333: move.w 68(a0),d0 ; get saved status register ! 334: ! 335: btst #13,d0 ; caller in supervisor mode? ! 336: ! 337: bne nosleep ; yes -- don't interrupt ! 338: ! 339: sleep: ! 340: ! 341: jsr _preempt ; does a sleep(READY_Q) ! 342: ! 343: nosleep: ! 344: ! 345: ori.w #$0700,sr ; spl7() ! 346: ! 347: jsr _leave_kernel ; restore vectors ! 348: ! 349: move.l _curproc,a0 ! 350: ! 351: pea 4(a0) ! 352: ! 353: jsr _restore_context ; never returns ! 354: ! 355: ! 356: ! 357: ; ! 358: ! 359: ; we handle errors by calling through to GEMDOS or the BIOS/XBIOS, ! 360: ! 361: ; as appropriate, and letting them handle it -- that way, if the underlying ! 362: ! 363: ; system has functions we don't know about, they still work ! 364: ! 365: ; ! 366: ! 367: ! 368: ! 369: error: ! 370: ! 371: move.l syscall_tab,a0 ! 372: ! 373: cmp.l #_xbios_tab,a0 ! 374: ! 375: bne.s maybe_dos ! 376: ! 377: trap #14 ! 378: ! 379: bra.s out ! 380: ! 381: maybe_dos: ! 382: ! 383: cmp.l #_dos_tab,a0 ! 384: ! 385: beq.s trap_1 ! 386: ! 387: trap #13 ! 388: ! 389: bra.s out ! 390: ! 391: trap_1: ! 392: ! 393: trap #1 ! 394: ! 395: bra.s out ! 396: ! 397: ! 398: ! 399: ; ! 400: ! 401: ; sig_return: user signal handlers return to us. At that point, the ! 402: ! 403: ; stack looks like this: ! 404: ! 405: ; (sp) (long) signal number -- was a parameter for user routine ! 406: ! 407: ; ! 408: ! 409: XDEF _sig_return ! 410: ! 411: XREF _valid_return ! 412: ! 413: _sig_return: ! 414: ! 415: addq.l #4,sp ; pop signal number ! 416: ! 417: move.w #$11a,-(sp) ; Psigreturn() system call ! 418: ! 419: move.w #1,_valid_return ; tell kernel it's us! ! 420: ! 421: trap #1 ! 422: ! 423: ; we had better not come back; if we did, something terrible ! 424: ! 425: ; happened, and we might as well terminate ! 426: ! 427: move.w #-998,-(sp) ! 428: ! 429: move.w #$4c,-(sp) ; Pterm() ! 430: ! 431: trap #1 ! 432: ! 433: ; ! 434: ! 435: ; bconout special code: on entry, a1 points to the stack the user ! 436: ! 437: ; was using. If possible, we just buffer the output until later. ! 438: ! 439: ; ! 440: ! 441: ! 442: ! 443: do_bconout: ! 444: ! 445: move.w 2(a1),d0 ; what device is this for? ! 446: ! 447: beq L_bios ; don't buffer the printer ! 448: ! 449: cmp.w _bconbdev,d0 ; same device as is buffered? ! 450: ! 451: bne.s new_dev ; no -- maybe we can't do this ! 452: ! 453: put_buf: ! 454: ! 455: move.w 4(a1),d0 ; get the character to output ! 456: ! 457: move.w _bconbsiz,d1 ; get index into buffer table ! 458: ! 459: cmp.w #255,d1 ; buffer full? ! 460: ! 461: beq L_bios ; yes -- flush it out ! 462: ! 463: lea _bconbuf,a0 ! 464: ! 465: add.w d1,a0 ! 466: ! 467: move.b d0,(a0) ; store the character ! 468: ! 469: addq.w #1,d1 ! 470: ! 471: move.w d1,_bconbsiz ! 472: ! 473: moveq.l #-1,d0 ; return character output OK ! 474: ! 475: rte ! 476: ! 477: ! 478: ! 479: new_dev: ! 480: ! 481: tst.w _bconbsiz ; characters already in buffer? ! 482: ! 483: bne L_bios ; yes: we can't buffer this one ! 484: ! 485: move.w d0,_bconbdev ; no: OK, we have a new device ! 486: ! 487: bra.s put_buf ! 488: ! 489: ! 490: ! 491: ; ! 492: ! 493: ; _lineA0: MiNT calls this to get the address of the line A variables ! 494: ! 495: ; ! 496: ! 497: XDEF _lineA0 ! 498: ! 499: _lineA0: ! 500: ! 501: movem.l d2/a2,-(sp) ; save scratch registers ! 502: ! 503: dc.w $a000 ; call the line A initialization routine ! 504: ! 505: movem.l (sp)+,d2/a2 ! 506: ! 507: rts ! 508: ! 509: ! 510: ! 511: ; ! 512: ! 513: ; _call_aes: calls the GEM AES, using the control block passed as ! 514: ! 515: ; a parameter. Used only for doing appl_init(), to see ! 516: ! 517: ; if the AES is active yet ! 518: ! 519: ; ! 520: ! 521: XDEF _call_aes ! 522: ! 523: _call_aes: ! 524: ! 525: move.l 4(sp),d1 ; fetch pointer to parameter block ! 526: ! 527: move.w #$c8,d0 ; magic number for AES ! 528: ! 529: movem.l d2/a2,-(sp) ; save scratch registers ! 530: ! 531: trap #2 ! 532: ! 533: movem.l (sp)+,d2/a2 ! 534: ! 535: rts ! 536: ! 537: ! 538: ! 539: ; ! 540: ! 541: ; _callout: Call an external function, passing <32 bytes of arguments, ! 542: ! 543: ; and return the value from the function. NOTE: we must be careful ! 544: ! 545: ; to save all registers here! ! 546: ! 547: ; ! 548: ! 549: XDEF _callout ! 550: ! 551: _callout: ! 552: ! 553: lea 8(sp),a0 ; pointer to args ! 554: ! 555: move.l 4(sp),a1 ; pointer to function ! 556: ! 557: movem.l d2-d7/a2-a6,-(sp) ; save registers ! 558: ! 559: movem.l (a0),d0-d7 ; copy parameters ! 560: ! 561: lea -32(sp),sp ; NOTE: movem.l auto-decrement ! 562: ! 563: movem.l d0-d7,(sp) ; changes the order of things ! 564: ! 565: move.l (a1),a0 ; get function address ! 566: ! 567: jsr (a0) ; go do it ! 568: ! 569: add.l #32,sp ! 570: ! 571: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies ! 572: ! 573: rts ! 574: ! 575: ! 576: ! 577: SECTION BSS ! 578: ! 579: XDEF syscall_tab,syscall_max ! 580: ! 581: ! 582: ! 583: syscall_tab ds.l 1 ; set to which table to use for the call ! 584: ! 585: syscall_max ds.l 1 ; maximum valid number for this call ! 586: ! 587: END ! 588:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.