Annotation of MiNT/src/syscall.spp, revision 1.1

1.1     ! root        1: %include "magic.i"
        !             2: 
        !             3: ;
        !             4: 
        !             5: ; syscall: interface for system calls. The following entry points are
        !             6: 
        !             7: ;    defined:
        !             8: 
        !             9: ; _mint_bios:  entry point for the BIOS calls (trap #13)
        !            10: 
        !            11: ; _mint_xbios: entry point for XBIOS calls (trap #14)
        !            12: 
        !            13: ; _mint_dos:   entry point for GEMDOS calls (trap #1)
        !            14: 
        !            15: ; _sig_return: user signal handlers return to this routine (see signal.c)
        !            16: 
        !            17: ;              it is responsible for restoring the kernel's old context
        !            18: 
        !            19: ;              via the Psigreturn() system call
        !            20: 
        !            21: ; _lineA0:     calls the line A initialize routine
        !            22: 
        !            23: ; _call_aes:   calls the GEM AES
        !            24: 
        !            25: ; _callout:    calls an external function, after first saving all registers,
        !            26: 
        !            27: ;              and restores the registers afterward
        !            28: 
        !            29: ;
        !            30: 
        !            31: ; external variables referenced:
        !            32: 
        !            33: ; _bios_tab, _bios_max:
        !            34: 
        !            35: ;    table of entry points for BIOS routines, max # of routine
        !            36: 
        !            37: ; _xbios_tab, _xbios_max:
        !            38: 
        !            39: ;    ditto for XBIOS
        !            40: 
        !            41: ; _dos_tab, _dos_max:
        !            42: 
        !            43: ;    ditto for GEMDOS
        !            44: 
        !            45: ; _curproc:
        !            46: 
        !            47: ;    pointer to current process table entry, and hence to save area for
        !            48: 
        !            49: ;    context (this is always the first entry in the PROC table).
        !            50: 
        !            51: ; _valid_return:
        !            52: 
        !            53: ;    used to indicate to the kernel that a valid return from user mode
        !            54: 
        !            55: ;    is taking place
        !            56: 
        !            57: ;
        !            58: 
        !            59: ; _bconbuf, _bconbsiz, _bconbdev:
        !            60: 
        !            61: ;    256 byte buffer for Bconout() output. If _bconbsiz is non-zero,
        !            62: 
        !            63: ;    there are that many bytes in _bconbuf waiting to be flushed. The
        !            64: 
        !            65: ;    output is for device _bconbdev.
        !            66: 
        !            67: ;
        !            68: 
        !            69: ; The C function enter_kernel() is called on entry to the kernel, and the
        !            70: 
        !            71: ; function leave_kernel() is called on exit. These functions are responsible
        !            72: 
        !            73: ; for saving and restoring the various trap vectors, so that MiNT can trap
        !            74: 
        !            75: ; out to TOS directly, but programs can only trap to MiNT.
        !            76: 
        !            77: ;
        !            78: 
        !            79: ; we also call certain BIOS functions directly if these are known not to
        !            80: 
        !            81: ; require saving/restoring of context
        !            82: 
        !            83: ;
        !            84: 
        !            85:        TEXT
        !            86: 
        !            87:        
        !            88: 
        !            89:        XDEF    _mint_bios,_mint_xbios
        !            90: 
        !            91:        XDEF    _mint_dos
        !            92: 
        !            93:        XREF    _build_context
        !            94: 
        !            95:        XREF    _restore_context
        !            96: 
        !            97:        XREF    _proc_clock             ; controls process' allocation of CPU time
        !            98: 
        !            99:        XREF    _enter_kernel
        !           100: 
        !           101:        XREF    _leave_kernel
        !           102: 
        !           103:        XREF    _preempt
        !           104: 
        !           105: 
        !           106: 
        !           107:        XREF    _curproc
        !           108: 
        !           109:        XREF    _bios_tab,_bios_max
        !           110: 
        !           111:        XREF    _xbios_tab,_xbios_max
        !           112: 
        !           113:        XREF    _dos_tab,_dos_max
        !           114: 
        !           115: 
        !           116: 
        !           117:        XREF    _bconbuf,_bconbsiz,_bconbdev
        !           118: 
        !           119:        XREF    _bflush
        !           120: 
        !           121: 
        !           122: 
        !           123:        XREF    _ubconstat,_do_bconin,_ubcostat,_kbshift
        !           124: 
        !           125:        
        !           126: 
        !           127: _mint_dos:
        !           128: 
        !           129:        clr.w   -(sp)                   ; no frame format needed
        !           130: 
        !           131:        move.l  _curproc,d0
        !           132: 
        !           133:        addq.l  #4,d0
        !           134: 
        !           135:        move.l  d0,-(sp)                ; push pointer to syscall context save
        !           136: 
        !           137:        jsr     _build_context
        !           138: 
        !           139:        move.l  #_dos_tab,a5            ; set syscall_tab
        !           140: 
        !           141:        move.w  _dos_max,d5             ; set syscall_max
        !           142: 
        !           143: ;
        !           144: 
        !           145: ; copy parameters onto process stack. a0 and a1 were set by _build_context
        !           146: 
        !           147: ;
        !           148: 
        !           149: 
        !           150: 
        !           151:        move.l  _curproc,a0
        !           152: 
        !           153:        move.l  (a0),sp                 ; this puts us in our private stack
        !           154: 
        !           155:        move.l  24(a1),-(sp)            ; a1 was set by build_context
        !           156: 
        !           157:        move.l  20(a1),-(sp)
        !           158: 
        !           159:        move.l  16(a1),-(sp)
        !           160: 
        !           161:        move.l  12(a1),-(sp)
        !           162: 
        !           163:        move.l  8(a1),-(sp)
        !           164: 
        !           165:        move.l  4(a1),-(sp)
        !           166: 
        !           167:        move.l  (a1),-(sp)
        !           168: 
        !           169:        jsr     _enter_kernel           ; set up vectors appropriately
        !           170: 
        !           171:        bra     _syscall
        !           172: 
        !           173: 
        !           174: 
        !           175: _mint_xbios:
        !           176: 
        !           177:        clr.w   -(sp)                   ; no frame format needed
        !           178: 
        !           179:        move.l  _curproc,d0
        !           180: 
        !           181:        addq.l  #4,d0
        !           182: 
        !           183:        move.l  d0,-(sp)                ; push pointer to syscall context save
        !           184: 
        !           185:        jsr     _build_context
        !           186: 
        !           187:        move.l  #_xbios_tab,a5          ; set syscall_tab
        !           188: 
        !           189:        move.w  _xbios_max,d5           ; set syscall_max
        !           190: 
        !           191: ;
        !           192: 
        !           193: ; copy parameters onto process stack. a0 and a1 were set by _build_context
        !           194: 
        !           195: ;
        !           196: 
        !           197: 
        !           198: 
        !           199:        move.l  _curproc,a0
        !           200: 
        !           201:        move.l  (a0),sp                 ; this puts us in our private stack
        !           202: 
        !           203:        move.l  24(a1),-(sp)            ; a1 was set by build_context
        !           204: 
        !           205:        move.l  20(a1),-(sp)
        !           206: 
        !           207:        move.l  16(a1),-(sp)
        !           208: 
        !           209:        move.l  12(a1),-(sp)
        !           210: 
        !           211:        move.l  8(a1),-(sp)
        !           212: 
        !           213:        move.l  4(a1),-(sp)
        !           214: 
        !           215:        move.l  (a1),-(sp)
        !           216: 
        !           217:        jsr     _enter_kernel           ; set up vectors appropriately
        !           218: 
        !           219:        bra     _syscall
        !           220: 
        !           221: 
        !           222: 
        !           223: _mint_bios:
        !           224: 
        !           225: ;
        !           226: 
        !           227: ; Entering the kernel can be very expensive; so, we take a short-cut
        !           228: 
        !           229: ; if possible -- we try some BIOS functions out, and if they
        !           230: 
        !           231: ; succeed without blocking then we're done; otherwise, we go
        !           232: 
        !           233: ; through the long procedure for entering the kernel
        !           234: 
        !           235: ;
        !           236: 
        !           237: ; These shortcuts aren't done when we're called in supervisor mode,
        !           238: 
        !           239: ; because TOS uses very tiny stacks (smaller than we want); the
        !           240: 
        !           241: ; shortcuts operate on the user-supplied ssp, whereas the "full"
        !           242: 
        !           243: ; BIOS code works on our (private) system stack
        !           244: 
        !           245: ;
        !           246: 
        !           247:        jsr     _enter_kernel           ; set up BIOS vectors
        !           248: 
        !           249:        btst    #5,(sp)                 ; test for user/super mode
        !           250: 
        !           251:        bne.s   L_bios                  ; if super, goto L_bios
        !           252: 
        !           253:        tst.w   _proc_clock             ; are we about to be preempted?
        !           254: 
        !           255:        beq.s   L_bios
        !           256: 
        !           257: 
        !           258: 
        !           259:        move.l  usp,a1                  ; user mode: args on user stack
        !           260: 
        !           261: L_ubios:
        !           262: 
        !           263:        move.w  (a1),d0                 ; get command
        !           264: 
        !           265:        cmp.w   #3,d0                   ; Bconout?
        !           266: 
        !           267:        beq     do_bconout              ; yes -- go do it
        !           268: 
        !           269: ;
        !           270: 
        !           271: ; most of the remaining functions require BIOS vectors to be properly
        !           272: 
        !           273: ; set up
        !           274: 
        !           275:        tst.w   _bconbsiz               ; is BIOS output waiting?
        !           276: 
        !           277:        bne.s   L_bios                  ; yes -- do regular code
        !           278: 
        !           279: 
        !           280: 
        !           281: ; test for various BIOS functions
        !           282: 
        !           283:        cmp.w   #1,d0                   ; Bconstat?
        !           284: 
        !           285:        bne.s   L_00
        !           286: 
        !           287:        move.w  2(a1),-(sp)             ; push arg
        !           288: 
        !           289:        jsr     _ubconstat
        !           290: 
        !           291: L_1out:
        !           292: 
        !           293:        addq.l  #2,sp
        !           294: 
        !           295: L_0out:
        !           296: 
        !           297:        move.l  d0,-(sp)                ; save d0
        !           298: 
        !           299:        ori.w   #$0700,sr               ; spl7()
        !           300: 
        !           301:        jsr     _leave_kernel
        !           302: 
        !           303:        move.l  (sp)+,d0                ; retrieve value to be returned
        !           304: 
        !           305:        rte                             ; return to user
        !           306: 
        !           307: L_00:
        !           308: 
        !           309:        cmp.w   #2,d0                   ; Bconin?
        !           310: 
        !           311:        bne.s   L_01
        !           312: 
        !           313:        move.w  2(a1),-(sp)             ; yes; push argument
        !           314: 
        !           315:        jsr     _do_bconin
        !           316: 
        !           317:        addq.l  #2,sp
        !           318: 
        !           319:        cmp.w   #$dead,d0               ; would Bconin block?
        !           320: 
        !           321:        bne.s   L_0out                  ; no -- we're done
        !           322: 
        !           323:        bra.s   L_bios                  ; yes -- do the long stuff
        !           324: 
        !           325: L_01:
        !           326: 
        !           327:        cmp.w   #8,d0                   ; Bcostat?
        !           328: 
        !           329:        bne.s   L_02
        !           330: 
        !           331:        move.w  2(a1),-(sp)             ; push device
        !           332: 
        !           333:        jsr     _ubcostat               ; get status
        !           334: 
        !           335:        bra.s   L_1out
        !           336: 
        !           337: L_02:
        !           338: 
        !           339:        cmp.w   #11,d0                  ; Kbshift?
        !           340: 
        !           341:        bne.s   L_bios
        !           342: 
        !           343:        move.w  2(a1),-(sp)             ; push arg
        !           344: 
        !           345:        jsr     _kbshift
        !           346: 
        !           347:        bra.s   L_1out
        !           348: 
        !           349: 
        !           350: 
        !           351: L_bios:
        !           352: 
        !           353:        clr.w   -(sp)                   ; no frame format needed
        !           354: 
        !           355:        move.l  _curproc,d0
        !           356: 
        !           357:        addq.l  #4,d0
        !           358: 
        !           359:        move.l  d0,-(sp)                ; push pointer to syscall context save
        !           360: 
        !           361:        jsr     _build_context
        !           362: 
        !           363:        move.l  #_bios_tab,a5           ; set syscall_tab
        !           364: 
        !           365:        move.w  _bios_max,d5            ; set syscall_max
        !           366: 
        !           367: ;
        !           368: 
        !           369: ; copy parameters onto process stack. a0 and a1 were set by _build_context
        !           370: 
        !           371: ;
        !           372: 
        !           373: 
        !           374: 
        !           375:        move.l  _curproc,a0
        !           376: 
        !           377:        move.l  (a0),sp                 ; this puts us in our private stack
        !           378: 
        !           379:        move.l  24(a1),-(sp)            ; a1 was set by build_context
        !           380: 
        !           381:        move.l  20(a1),-(sp)
        !           382: 
        !           383:        move.l  16(a1),-(sp)
        !           384: 
        !           385:        move.l  12(a1),-(sp)
        !           386: 
        !           387:        move.l  8(a1),-(sp)
        !           388: 
        !           389:        move.l  4(a1),-(sp)
        !           390: 
        !           391:        move.l  (a1),-(sp)
        !           392: 
        !           393: 
        !           394: 
        !           395: _syscall:
        !           396: 
        !           397: ;
        !           398: 
        !           399: ; check here to see if we need to flush the Bconout() buffer
        !           400: 
        !           401: ;
        !           402: 
        !           403:        tst.w   _bconbsiz               ; characters in buffer?
        !           404: 
        !           405:        beq.s   L_noflush               ; no: OK to proceed
        !           406: 
        !           407: ;
        !           408: 
        !           409: ; watch out, this could cause a context switch
        !           410: 
        !           411: ;
        !           412: 
        !           413:        jsr     _bflush                 ; flush the buffer
        !           414: 
        !           415: 
        !           416: 
        !           417: L_noflush:
        !           418: 
        !           419: ;
        !           420: 
        !           421: ; figure out which routine to call
        !           422: 
        !           423: ;
        !           424: 
        !           425:        move.w  (sp),d0
        !           426: 
        !           427:        cmp.w   #-1,d0                  ; trapping with -1 means return
        !           428: 
        !           429:        bne.s   check_max               ; the corresponding system table
        !           430: 
        !           431:        move.l  a5,d0
        !           432: 
        !           433:        bra.s   out
        !           434: 
        !           435: check_max:
        !           436: 
        !           437:        cmp.w   d5,d0
        !           438: 
        !           439:        bge.s   error
        !           440: 
        !           441:        add.w   d0,d0
        !           442: 
        !           443:        add.w   d0,d0                   ; multiply by 4
        !           444: 
        !           445:        move.l  0(a5,d0.w),d0           ; d0 = syscall_tab[d0]
        !           446: 
        !           447:        beq.s   error                   ; null entry means invalid call
        !           448: 
        !           449:        addq.l  #2,sp                   ; pop function number off stack
        !           450: 
        !           451:        move.l  d0,a0
        !           452: 
        !           453:        jsr     (a0)                    ; go do the call
        !           454: 
        !           455: out:
        !           456: 
        !           457:        move.l  _curproc,a0
        !           458: 
        !           459:        move.l  d0,P_SYSCTXT+C_D0(a0)   ; set d0 in the saved context
        !           460: 
        !           461:        move.w  P_SYSCTXT+C_SR(a0),d0   ; get saved status register
        !           462: 
        !           463:        
        !           464: 
        !           465:        tst.l   P_PTRACER(a0)           ; check curproc->ptracer, if not set
        !           466: 
        !           467:        beq.s   notrace                 ; then no pending trace; this ensures
        !           468: 
        !           469:        move.w  d0,d1                   ; we work with non-MiNT debuggers
        !           470: 
        !           471:        and.w   #$c000,d1               ; are either of the trace bits set
        !           472: 
        !           473:        sne     P_SYSCTXT+C_PTRACE(a0)  ; mark as trace pending/not
        !           474: 
        !           475: notrace:
        !           476: 
        !           477:        tst.w   _proc_clock             ; has process exceeded time slice?
        !           478: 
        !           479:        bne.s   nosleep                 ; no -- continue
        !           480: 
        !           481:        btst    #13,d0                  ; caller in supervisor mode?
        !           482: 
        !           483:        bne.s   nosleep                 ; yes -- don't interrupt
        !           484: 
        !           485:        tst.w   ($43e).w                ; test floppy disk lock variable
        !           486: 
        !           487:        bne.s   nosleep                 ; if locked, can't switch
        !           488: 
        !           489: sleep:
        !           490: 
        !           491:        jsr     _preempt                ; does a sleep(READY_Q)
        !           492: 
        !           493: nosleep:
        !           494: 
        !           495:        ori.w   #$0700,sr               ; spl7()
        !           496: 
        !           497:        jsr     _leave_kernel           ; restore vectors
        !           498: 
        !           499:        move.l  _curproc,a0
        !           500: 
        !           501:        pea     4(a0)
        !           502: 
        !           503:        jsr     _restore_context        ; never returns
        !           504: 
        !           505: 
        !           506: 
        !           507: ;
        !           508: 
        !           509: ; we handle errors by calling through to GEMDOS or the BIOS/XBIOS,
        !           510: 
        !           511: ; as appropriate, and letting them handle it -- that way, if the underlying
        !           512: 
        !           513: ; system has functions we don't know about, they still work
        !           514: 
        !           515: ; to figure out which trap we have to call, we use the system call
        !           516: 
        !           517: ; table placed in a5 earlier
        !           518: 
        !           519: 
        !           520: 
        !           521: error:
        !           522: 
        !           523:        cmp.l   #_xbios_tab,a5
        !           524: 
        !           525:        bne.s   maybe_bios
        !           526: 
        !           527:        trap    #14
        !           528: 
        !           529:        bra.s   out
        !           530: 
        !           531: maybe_bios:
        !           532: 
        !           533:        cmp.l   #_dos_tab,a5
        !           534: 
        !           535:        beq.s   trap_1
        !           536: 
        !           537:        trap    #13
        !           538: 
        !           539:        bra.s   out
        !           540: 
        !           541: trap_1:
        !           542: 
        !           543:        trap    #1
        !           544: 
        !           545:        bra.s   out
        !           546: 
        !           547: 
        !           548: 
        !           549: ;
        !           550: 
        !           551: ; sig_return: user signal handlers return to us. At that point, the
        !           552: 
        !           553: ; stack looks like this:
        !           554: 
        !           555: ;    (sp)      (long) signal number -- was a parameter for user routine
        !           556: 
        !           557: ;
        !           558: 
        !           559:        XDEF    _sig_return
        !           560: 
        !           561:        XREF    _valid_return
        !           562: 
        !           563: _sig_return:
        !           564: 
        !           565:        addq.l  #4,sp                   ; pop signal number
        !           566: 
        !           567:        move.w  #$11a,-(sp)             ; Psigreturn() system call
        !           568: 
        !           569:        move.w  #1,_valid_return        ; tell kernel it's us!
        !           570: 
        !           571:        trap    #1
        !           572: 
        !           573: ; we had better not come back; if we did, something terrible
        !           574: 
        !           575: ; happened, and we might as well terminate
        !           576: 
        !           577:        move.w  #-998,-(sp)
        !           578: 
        !           579:        move.w  #$4c,-(sp)              ; Pterm()
        !           580: 
        !           581:        trap    #1
        !           582: 
        !           583: ;
        !           584: 
        !           585: ; bconout special code: on entry, a1 points to the stack the user
        !           586: 
        !           587: ; was using. If possible, we just buffer the output until later.
        !           588: 
        !           589: ;
        !           590: 
        !           591: 
        !           592: 
        !           593: do_bconout:
        !           594: 
        !           595:        tst.w   _bconbdev               ; is BIOS buffering on?
        !           596: 
        !           597:        bmi     L_bios                  ; no buffering -- skip this code
        !           598: 
        !           599:        move.w  2(a1),d0                ; what device is this for?
        !           600: 
        !           601:        beq     L_bios                  ; don't buffer the printer
        !           602: 
        !           603:        cmp.w   _bconbdev,d0            ; same device as is buffered?
        !           604: 
        !           605:        bne.s   new_dev                 ; no -- maybe we can't do this
        !           606: 
        !           607: put_buf:
        !           608: 
        !           609:        move.w  4(a1),d0                ; get the character to output
        !           610: 
        !           611:        move.w  _bconbsiz,d1            ; get index into buffer table
        !           612: 
        !           613:        cmp.w   #255,d1                 ; buffer full?
        !           614: 
        !           615:        beq     L_bios                  ; yes -- flush it out
        !           616: 
        !           617:        lea     _bconbuf,a0
        !           618: 
        !           619:        add.w   d1,a0
        !           620: 
        !           621:        move.b  d0,(a0)                 ; store the character
        !           622: 
        !           623:        addq.w  #1,d1
        !           624: 
        !           625:        move.w  d1,_bconbsiz
        !           626: 
        !           627:        jsr     _leave_kernel           ; restore vectors
        !           628: 
        !           629:        moveq.l #-1,d0                  ; return character output OK
        !           630: 
        !           631:        rte
        !           632: 
        !           633: 
        !           634: 
        !           635: new_dev:
        !           636: 
        !           637:        tst.w   _bconbsiz               ; characters already in buffer?
        !           638: 
        !           639:        bne     L_bios                  ; yes: we can't buffer this one
        !           640: 
        !           641:        move.w  d0,_bconbdev            ; no: OK, we have a new device
        !           642: 
        !           643:        bra.s   put_buf
        !           644: 
        !           645: 
        !           646: 
        !           647: ;
        !           648: 
        !           649: ; _lineA0: MiNT calls this to get the address of the line A variables
        !           650: 
        !           651: ;
        !           652: 
        !           653:        XDEF    _lineA0
        !           654: 
        !           655: _lineA0:
        !           656: 
        !           657:        movem.l d2/a2,-(sp)     ; save scratch registers
        !           658: 
        !           659:        dc.w    $a000           ; call the line A initialization routine
        !           660: 
        !           661:        movem.l (sp)+,d2/a2
        !           662: 
        !           663:        rts
        !           664: 
        !           665: 
        !           666: 
        !           667: ;
        !           668: 
        !           669: ; _call_aes: calls the GEM AES, using the control block passed as
        !           670: 
        !           671: ;            a parameter. Used only for doing appl_init(), to see
        !           672: 
        !           673: ;           if the AES is active yet
        !           674: 
        !           675: ;
        !           676: 
        !           677:        XDEF    _call_aes
        !           678: 
        !           679: _call_aes:
        !           680: 
        !           681:        move.l  4(sp),d1        ; fetch pointer to parameter block
        !           682: 
        !           683:        move.w  #$c8,d0         ; magic number for AES
        !           684: 
        !           685:        movem.l d2/a2,-(sp)     ; save scratch registers
        !           686: 
        !           687:        trap    #2
        !           688: 
        !           689:        movem.l (sp)+,d2/a2
        !           690: 
        !           691:        rts
        !           692: 
        !           693: 
        !           694: 
        !           695: ;
        !           696: 
        !           697: ; _callout: Call an external function, passing <32 bytes of arguments,
        !           698: 
        !           699: ; and return the value from the function. NOTE: we must be careful
        !           700: 
        !           701: ; to save all registers here!
        !           702: 
        !           703: ;
        !           704: 
        !           705:        XDEF    _callout
        !           706: 
        !           707:        XDEF    _callout1
        !           708: 
        !           709:        XDEF    _callout2
        !           710: 
        !           711: ;
        !           712: 
        !           713: ; _callout is the general purpose one
        !           714: 
        !           715: ;
        !           716: 
        !           717: _callout:
        !           718: 
        !           719:        lea     8(sp),a0                ; pointer to args
        !           720: 
        !           721:        move.l  4(sp),a1                ; pointer to pointer to function
        !           722: 
        !           723:        movem.l d2-d7/a2-a6,-(sp)       ; save registers
        !           724: 
        !           725:        movem.l (a0),d0-d7              ; copy parameters
        !           726: 
        !           727:        lea     -32(sp),sp              ; NOTE: movem.l auto-decrement
        !           728: 
        !           729:        movem.l d0-d7,(sp)              ;    changes the order of things
        !           730: 
        !           731:        jsr     (a1)                    ; go do it
        !           732: 
        !           733:        lea     32(sp),sp
        !           734: 
        !           735:        movem.l (sp)+,d2-d7/a2-a6       ; restore reggies
        !           736: 
        !           737:        rts
        !           738: 
        !           739: ;
        !           740: 
        !           741: ; _callout2 and _callout1 are for functions with just 1 or
        !           742: 
        !           743: ; 2 16 bit parameters. We cheat and use the same code for
        !           744: 
        !           745: ; both, since passing 32 bits isn't much more expensive than
        !           746: 
        !           747: ; passing 16 bits (and since the called function will just
        !           748: 
        !           749: ; ignore any extra arg)
        !           750: 
        !           751: ;
        !           752: 
        !           753: 
        !           754: 
        !           755: _callout1:
        !           756: 
        !           757: _callout2:
        !           758: 
        !           759:        movem.l 4(sp),a0/a1             ; get function ptr & args
        !           760: 
        !           761:        movem.l d2-d7/a2-a6,-(sp)       ; save reggies
        !           762: 
        !           763:        move.l  a1,-(sp)                ; push args
        !           764: 
        !           765:        jsr     (a0)                    ; do function
        !           766: 
        !           767:        addq.l  #4,sp
        !           768: 
        !           769:        movem.l (sp)+,d2-d7/a2-a6       ; restore reggies
        !           770: 
        !           771:        rts
        !           772: 
        !           773: 
        !           774: 
        !           775:        END
        !           776: 

unix.superglobalmegacorp.com

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