Annotation of MiNT/src/gas/syscall.s, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.