|
|
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: call an external function, after first making sure that all ! 24: ! 25: | registers are saved ! 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: .globl _mint_bios, _mint_xbios ! 78: ! 79: .globl _mint_dos ! 80: ! 81: .globl _build_context ! 82: ! 83: .globl _restore_context ! 84: ! 85: ! 86: ! 87: .globl _curproc ! 88: ! 89: .globl _bios_tab, _bios_max ! 90: ! 91: .globl _xbios_tab, _xbios_max ! 92: ! 93: .globl _dos_tab, _dos_max ! 94: ! 95: .globl _bconbuf, _bconbsiz, _bconbdev ! 96: ! 97: .globl _bflush ! 98: ! 99: ! 100: ! 101: .data ! 102: ! 103: .comm syscall_tab, 4 | set to which table to use for the call ! 104: ! 105: .comm syscall_max, 4 | maximum valid number for this call ! 106: ! 107: ! 108: ! 109: .text ! 110: ! 111: .even ! 112: ! 113: ! 114: ! 115: _mint_dos: ! 116: ! 117: movel #_dos_tab, syscall_tab ! 118: ! 119: movew _dos_max, syscall_max ! 120: ! 121: bra _syscall ! 122: ! 123: ! 124: ! 125: _mint_xbios: ! 126: ! 127: movel #_xbios_tab, syscall_tab ! 128: ! 129: movew _xbios_max, syscall_max ! 130: ! 131: bra _syscall ! 132: ! 133: ! 134: ! 135: _mint_bios: ! 136: ! 137: | ! 138: ! 139: | Bconout() is noticeably slower under MiNT, so we do a bit of a kludge ! 140: ! 141: | and special case Bconout() so that it doesn't take so long. We ! 142: ! 143: | do this by buffering Bconout calls until either another kind of ! 144: ! 145: | system call or a context switch happens. ! 146: ! 147: | ! 148: ! 149: tstw _bconbdev | buffering on? ! 150: ! 151: bmi L_bios | if bconbdev < 0, no buffering ! 152: ! 153: btst #13, sp@ | test for user/super mode ! 154: ! 155: beq L_usr | ! 156: ! 157: lea sp@(6), a1 | supervisor mode: args on stack ! 158: ! 159: tstw 0x59e | test longframe ! 160: ! 161: beq L_check ! 162: ! 163: addql #2, a1 | stack is a bit bigger ! 164: ! 165: bra L_check ! 166: ! 167: L_usr: ! 168: ! 169: movel usp, a1 | user mode: args on user stack ! 170: ! 171: L_check: ! 172: ! 173: movew a1@, d0 | check command ! 174: ! 175: cmpw #3, d0 | Bconout? ! 176: ! 177: beq do_bconout | yes -- take some shortcuts ! 178: ! 179: | no -- fall through to the normal code ! 180: ! 181: L_bios: ! 182: ! 183: movel #_bios_tab, syscall_tab ! 184: ! 185: movew _bios_max, syscall_max ! 186: ! 187: ! 188: ! 189: _syscall: ! 190: ! 191: movel _curproc, d0 ! 192: ! 193: addql #4, d0 ! 194: ! 195: movel d0, sp@- | push pointer to syscall context save ! 196: ! 197: jsr _build_context ! 198: ! 199: | ! 200: ! 201: | copy parameters onto process stack. a1 was set by _build_context ! 202: ! 203: | ! 204: ! 205: L_copy: ! 206: ! 207: movel _curproc, a0 ! 208: ! 209: movel a0@, a0 | fetch system call stack pointer ! 210: ! 211: lea a0@(-28), sp | this puts us in our private stack ! 212: ! 213: moveml a1@, d1-d7 | copy parameters from user stack ! 214: ! 215: moveml d1-d7, sp@ | to ours (build_context set a1) ! 216: ! 217: | ! 218: ! 219: jsr _enter_kernel | set up vectors appropriately ! 220: ! 221: | ! 222: ! 223: | check here to see if we need to flush the Bconout() buffers ! 224: ! 225: | ! 226: ! 227: tstw _bconbsiz | characters in buffer? ! 228: ! 229: beq L_noflush | nope: OK to proceed ! 230: ! 231: | ! 232: ! 233: | make sure we save syscall_tab and syscall_max ! 234: ! 235: | ! 236: ! 237: movel syscall_tab, sp@- ! 238: ! 239: movew syscall_max, sp@- ! 240: ! 241: jsr _bflush | flush the buffer ! 242: ! 243: movew sp@+, syscall_max ! 244: ! 245: movel sp@+, syscall_tab ! 246: ! 247: ! 248: ! 249: L_noflush: ! 250: ! 251: | ! 252: ! 253: | figure out which routine to call ! 254: ! 255: | ! 256: ! 257: clrl d0 ! 258: ! 259: movew sp@, d0 ! 260: ! 261: cmpw #-1, d0 | trapping with -1 means return ! 262: ! 263: bne check_max | the corresponding system table ! 264: ! 265: movel syscall_tab, d0 ! 266: ! 267: bra out ! 268: ! 269: check_max: ! 270: ! 271: cmpw syscall_max, d0 ! 272: ! 273: bge error ! 274: ! 275: addl d0,d0 ! 276: ! 277: addl d0,d0 | multiply by 4 ! 278: ! 279: movel syscall_tab, a0 ! 280: ! 281: addl d0, a0 ! 282: ! 283: movel a0@, a0 ! 284: ! 285: cmpl #0, a0 | null entry means invalid call ! 286: ! 287: beq error ! 288: ! 289: addql #2, sp | pop function number off stack ! 290: ! 291: jsr a0@ | go do the call ! 292: ! 293: out: ! 294: ! 295: movel _curproc, a0 ! 296: ! 297: movel d0, a0@(4) | set d0 in the saved context ! 298: ! 299: tstw _proc_clock | has process exceeded time slice? ! 300: ! 301: bne nosleep | no -- continue ! 302: ! 303: movew a0@(68), d0 | get saved status register ! 304: ! 305: btst #13, d0 | caller in supervisor mode? ! 306: ! 307: bne nosleep | yes -- don't interrupt ! 308: ! 309: sleep: ! 310: ! 311: jsr _preempt | does a sleep(READY_Q) ! 312: ! 313: nosleep: ! 314: ! 315: oriw #0x0700, sr | spl7() ! 316: ! 317: jsr _leave_kernel | restore vectors ! 318: ! 319: movel _curproc, a0 ! 320: ! 321: pea a0@(4) ! 322: ! 323: jsr _restore_context | never returns ! 324: ! 325: ! 326: ! 327: | ! 328: ! 329: | we handle errors by calling through to GEMDOS or the BIOS/XBIOS, ! 330: ! 331: | as appropriate, and letting them handle it -- that way, if the underlying ! 332: ! 333: | system has functions we don't know about, they still work ! 334: ! 335: | ! 336: ! 337: ! 338: ! 339: error: ! 340: ! 341: movel syscall_tab, a0 ! 342: ! 343: cmpl #_xbios_tab, a0 ! 344: ! 345: bne maybe_dos ! 346: ! 347: trap #14 ! 348: ! 349: bra out ! 350: ! 351: maybe_dos: ! 352: ! 353: cmpl #_dos_tab, a0 ! 354: ! 355: beq trap_1 ! 356: ! 357: trap #13 ! 358: ! 359: bra out ! 360: ! 361: trap_1: ! 362: ! 363: trap #1 ! 364: ! 365: bra out ! 366: ! 367: ! 368: ! 369: | ! 370: ! 371: | sig_return: user signal handlers return to us. At that point, the ! 372: ! 373: | stack looks like this: ! 374: ! 375: | (sp) (long) signal number -- was a parameter for user routine ! 376: ! 377: | ! 378: ! 379: .globl _sig_return ! 380: ! 381: .globl _valid_return ! 382: ! 383: _sig_return: ! 384: ! 385: addql #4, sp | pop signal number ! 386: ! 387: movew #0x11a, sp@- | Psigreturn() system call ! 388: ! 389: movew #1, _valid_return | tell kernel it's us! ! 390: ! 391: trap #1 ! 392: ! 393: | we had better not come back; if we did, something terrible ! 394: ! 395: | happened, and we might as well terminate ! 396: ! 397: movew #-998, sp@- ! 398: ! 399: movew #0x4c, sp@- | Pterm() ! 400: ! 401: trap #1 ! 402: ! 403: ! 404: ! 405: | ! 406: ! 407: | bconout special code: on entry, a1 points to the stack the user ! 408: ! 409: | was using. If possible, we just buffer the output until later. ! 410: ! 411: | ! 412: ! 413: ! 414: ! 415: do_bconout: ! 416: ! 417: movew a1@(2), d0 | what device is this for? ! 418: ! 419: beq L_bios | don't buffer the printer ! 420: ! 421: cmpw _bconbdev, d0 | same device as is buffered? ! 422: ! 423: bne new_dev | no -- maybe we can't do this ! 424: ! 425: put_buf: ! 426: ! 427: movew a1@(4), d0 | get the character to output ! 428: ! 429: movew _bconbsiz, d1 | get index into buffer table ! 430: ! 431: cmpw #255, d1 | buffer full? ! 432: ! 433: beq L_bios | yes -- flush it out ! 434: ! 435: lea _bconbuf, a0 ! 436: ! 437: addw d1, a0 ! 438: ! 439: moveb d0, a0@ | store the character ! 440: ! 441: addqw #1, d1 ! 442: ! 443: movew d1, _bconbsiz ! 444: ! 445: moveql #-1, d0 | return character output OK ! 446: ! 447: rte ! 448: ! 449: ! 450: ! 451: new_dev: ! 452: ! 453: tstw _bconbsiz | characters already in buffer? ! 454: ! 455: bne L_bios | yes: we can't buffer this one ! 456: ! 457: movew d0, _bconbdev | no: OK, we have a new device ! 458: ! 459: bra put_buf ! 460: ! 461: | ! 462: ! 463: | ! 464: ! 465: | _lineA0: MiNT calls this to get the address of the line A variables ! 466: ! 467: | ! 468: ! 469: .globl _lineA0 ! 470: ! 471: _lineA0: ! 472: ! 473: moveml d2/a2, sp@- | save scratch registers ! 474: ! 475: .word 0xa000 | call the line A initialization routine ! 476: ! 477: moveml sp@+, d2/a2 ! 478: ! 479: rts ! 480: ! 481: ! 482: ! 483: | ! 484: ! 485: | _call_aes: calls the GEM AES, using the control block passed as ! 486: ! 487: | a parameter. Used only for doing appl_init(), to see ! 488: ! 489: | if the AES is active yet ! 490: ! 491: | ! 492: ! 493: .globl _call_aes ! 494: ! 495: _call_aes: ! 496: ! 497: movel sp@(4), d1 | fetch pointer to parameter block ! 498: ! 499: movew #0xc8, d0 | magic number for AES ! 500: ! 501: moveml d2/a2, sp@- | save scratch registers ! 502: ! 503: trap #2 ! 504: ! 505: moveml sp@+, d2/a2 ! 506: ! 507: rts ! 508: ! 509: ! 510: ! 511: ! 512: ! 513: | ! 514: ! 515: | _callout: Call an external function, passing <32 bytes of arguments, ! 516: ! 517: | and return the value from the function. NOTE: we must be careful ! 518: ! 519: | to save all registers here! ! 520: ! 521: | ! 522: ! 523: .globl _callout ! 524: ! 525: _callout: ! 526: ! 527: lea sp@(8), a0 | pointer to args ! 528: ! 529: movel sp@(4), a1 | pointer to function ! 530: ! 531: moveml d2-d7/a2-a6, sp@- | save registers ! 532: ! 533: moveml a0@, d0-d7 | copy parameters ! 534: ! 535: lea sp@(-32), sp | NOTE: moveml auto-decrement ! 536: ! 537: moveml d0-d7, sp@ | changes the order of things ! 538: ! 539: movel a1@, a0 | get function address ! 540: ! 541: jsr a0@ | go do it ! 542: ! 543: addl #32, sp ! 544: ! 545: moveml sp@+, d2-d7/a2-a6 | restore reggies ! 546: ! 547: rts ! 548:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.