Annotation of MiNT/src/gas/syscall.s, revision 1.1.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.