home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / PURE_B / PBMAG22A.MSA / MINT095S.ZIP / SRC / ASM / SYSCALL.S < prev   
Text File  |  1987-04-22  |  9KB  |  295 lines

  1. ;
  2. ; syscall: interface for system calls. The following entry points are
  3. ;    defined:
  4. ; _mint_bios:  entry point for the BIOS calls (trap #13)
  5. ; _mint_xbios: entry point for XBIOS calls (trap #14)
  6. ; _mint_dos:   entry point for GEMDOS calls (trap #1)
  7. ; _sig_return: user signal handlers return to this routine (see signal.c)
  8. ;              it is responsible for restoring the kernel's old context
  9. ;              via the Psigreturn() system call
  10. ; _lineA0:     calls the line A initialize routine
  11. ; _call_aes:   calls the GEM AES
  12. ; _callout:    calls an external function, after first saving all registers,
  13. ;              and restores the registers afterward
  14. ;
  15. ; external variables referenced:
  16. ; _bios_tab, _bios_max:
  17. ;    table of entry points for BIOS routines, max # of routine
  18. ; _xbios_tab, _xbios_max:
  19. ;    ditto for XBIOS
  20. ; _dos_tab, _dos_max:
  21. ;    ditto for GEMDOS
  22. ; _curproc:
  23. ;    pointer to current process table entry, and hence to save area for
  24. ;    context (this is always the first entry in the PROC table).
  25. ; _valid_return:
  26. ;    used to indicate to the kernel that a valid return from user mode
  27. ;    is taking place
  28. ;
  29. ; _bconbuf, _bconbsiz, _bconbdev:
  30. ;    256 byte buffer for Bconout() output. If _bconbsiz is non-zero,
  31. ;    there are that many bytes in _bconbuf waiting to be flushed. The
  32. ;    output is for device _bconbdev.
  33. ;
  34. ; The C function enter_kernel() is called on entry to the kernel, and the
  35. ; function leave_kernel() is called on exit. These functions are responsible
  36. ; for saving and restoring the various trap vectors, so that MiNT can trap
  37. ; out to TOS directly, but programs can only trap to MiNT.
  38. ;
  39. ; $Log: syscall.s,v $
  40. ; Revision 1.3  1992/03/31  14:02:08  AGK
  41. ; Fixed for real Motorola syntax (many thanks to ERS for keeping these
  42. ; files in step with the GAS ones).
  43. ;
  44. ; Revision 1.2  1992/03/31  13:55:28  AGK
  45. ; Checked in MiNT 0.93 sources
  46. ;
  47. ; Revision 1.1  1991/05/30  17:24:16  AGK
  48. ; Initial revision
  49. ;
  50.     SECTION    TEXT
  51.     
  52.     XDEF    _mint_bios,_mint_xbios
  53.     XDEF    _mint_dos
  54.     XREF    _build_context
  55.     XREF    _restore_context
  56.     XREF    _proc_clock        ; controls process' allocation of CPU time
  57.     XREF    _enter_kernel
  58.     XREF    _leave_kernel
  59.     XREF    _preempt
  60.  
  61.     XREF    _curproc
  62.     XREF    _bios_tab,_bios_max
  63.     XREF    _xbios_tab,_xbios_max
  64.     XREF    _dos_tab,_dos_max
  65.  
  66.     XREF    _bconbuf,_bconbsiz,_bconbdev
  67.     XREF    _bflush
  68.     
  69. _mint_dos:
  70.     move.l    #_dos_tab,syscall_tab
  71.     move.w    _dos_max,syscall_max
  72.     bra.s    _syscall
  73.  
  74. _mint_xbios:
  75.     move.l    #_xbios_tab,syscall_tab
  76.     move.w    _xbios_max,syscall_max
  77.     bra.s    _syscall
  78.  
  79. _mint_bios:
  80. ;
  81. ; Bconout() is noticeably slower under MiNT, so we do a bit of a kludge
  82. ; and special case Bconout() so that it doesn't take so long. We
  83. ; do this by buffering Bconout calls until either another kind of
  84. ; system call or a context switch happens.
  85. ;
  86.     tst.w    _bconbdev        ; buffering on?
  87.     bmi.s    L_bios            ; if bconbdev < 0, no buffering
  88.     btst    #13,(sp)        ; test for user/super mode
  89.     beq.s    L_usr            ; 
  90.     lea    6(sp),a1        ; supervisor mode: args on stack
  91.     tst.w    $59e            ; test longframe
  92.     beq.s    L_check
  93.     addq.l    #2,a1            ; stack is a bit bigger
  94.     bra.s    L_check
  95. L_usr:
  96.     move.l    usp,a1            ; user mode: args on user stack
  97. L_check:
  98.     move.w    (a1),d0            ; check command
  99.     cmp.w    #3,d0            ; Bconout?
  100.     beq    do_bconout        ; yes -- take some shortcuts
  101.                     ; no -- fall through to the normal code
  102. L_bios:
  103.     move.l    #_bios_tab,syscall_tab
  104.     move.w    _bios_max,syscall_max
  105.  
  106. _syscall:
  107.     move.l    _curproc,d0
  108.     addq.l    #4,d0
  109.     move.l    d0,-(sp)        ; push pointer to syscall context save
  110.     jsr    _build_context
  111. ;
  112. ; copy parameters onto process stack. a1 was set by _build_context
  113. ;
  114. L_copy:
  115.     move.l    _curproc,a0
  116.     move.l    (a0),sp            ; this puts us in our private stack
  117.     move.l    24(a1),-(sp)        ; a1 was set by build_context
  118.     move.l    20(a1),-(sp)
  119.     move.l    16(a1),-(sp)
  120.     move.l    12(a1),-(sp)
  121.     move.l    8(a1),-(sp)
  122.     move.l    4(a1),-(sp)
  123.     move.l    (a1),-(sp)
  124. ;
  125.     jsr    _enter_kernel        ; set up vectors appropriately
  126. ;
  127. ; check here to see if we need to flush the Bconout() buffer
  128. ;
  129.     tst.w    _bconbsiz        ; characters in buffer?
  130.     beq.s    L_noflush        ; no: OK to proceed
  131. ;
  132. ; make sure we save syscall_tab and syscall_max
  133. ;
  134.     move.l    syscall_tab,-(sp)
  135.     move.w    syscall_max,-(sp)
  136.     jsr    _bflush            ; flush the buffer
  137.     move.w    (sp)+,syscall_max
  138.     move.l    (sp)+,syscall_tab
  139.  
  140. L_noflush:
  141. ;
  142. ; figure out which routine to call
  143. ;
  144.     clr.l    d0
  145.     move.w    (sp),d0
  146.     cmp.w    #-1,d0            ; trapping with -1 means return
  147.     bne.s    check_max        ; the corresponding system table
  148.     move.l    syscall_tab,d0
  149.     bra.s    out
  150. check_max:
  151.     cmp.w    syscall_max,d0
  152.     bge.s    error
  153.     add.l    d0,d0
  154.     add.l    d0,d0            ; multiply by 4
  155.     move.l    syscall_tab,a0
  156.     add.l    d0,a0
  157.     move.l    (a0),a0
  158.     cmp.l    #0,a0            ; null entry means invalid call
  159.     beq.s    error
  160.     addq.l    #2,sp            ; pop function number off stack
  161.     jsr    (a0)            ; go do the call
  162. out:
  163.     move.l    _curproc,a0
  164.     move.l    d0,4(a0)        ; set d0 in the saved context
  165.     tst.w    _proc_clock        ; has process exceeded time slice?
  166.     bne.s    nosleep            ; no -- continue
  167.     move.w    68(a0),d0        ; get saved status register
  168.     btst    #13,d0            ; caller in supervisor mode?
  169.     bne    nosleep            ; yes -- don't interrupt
  170. sleep:
  171.     jsr    _preempt        ; does a sleep(READY_Q)
  172. nosleep:
  173.     ori.w    #$0700,sr        ; spl7()
  174.     jsr    _leave_kernel        ; restore vectors
  175.     move.l    _curproc,a0
  176.     pea    4(a0)
  177.     jsr    _restore_context    ; never returns
  178.  
  179. ;
  180. ; we handle errors by calling through to GEMDOS or the BIOS/XBIOS,
  181. ; as appropriate, and letting them handle it -- that way, if the underlying
  182. ; system has functions we don't know about, they still work
  183. ;
  184.  
  185. error:
  186.     move.l    syscall_tab,a0
  187.     cmp.l    #_xbios_tab,a0
  188.     bne.s    maybe_dos
  189.     trap    #14
  190.     bra.s    out
  191. maybe_dos:
  192.     cmp.l    #_dos_tab,a0
  193.     beq.s    trap_1
  194.     trap    #13
  195.     bra.s    out
  196. trap_1:
  197.     trap    #1
  198.     bra.s    out
  199.  
  200. ;
  201. ; sig_return: user signal handlers return to us. At that point, the
  202. ; stack looks like this:
  203. ;    (sp)      (long) signal number -- was a parameter for user routine
  204. ;
  205.     XDEF    _sig_return
  206.     XREF    _valid_return
  207. _sig_return:
  208.     addq.l    #4,sp            ; pop signal number
  209.     move.w    #$11a,-(sp)        ; Psigreturn() system call
  210.     move.w    #1,_valid_return    ; tell kernel it's us!
  211.     trap    #1
  212. ; we had better not come back; if we did, something terrible
  213. ; happened, and we might as well terminate
  214.     move.w    #-998,-(sp)
  215.     move.w    #$4c,-(sp)        ; Pterm()
  216.     trap    #1
  217. ;
  218. ; bconout special code: on entry, a1 points to the stack the user
  219. ; was using. If possible, we just buffer the output until later.
  220. ;
  221.  
  222. do_bconout:
  223.     move.w    2(a1),d0        ; what device is this for?
  224.     beq    L_bios            ; don't buffer the printer
  225.     cmp.w    _bconbdev,d0        ; same device as is buffered?
  226.     bne.s    new_dev            ; no -- maybe we can't do this
  227. put_buf:
  228.     move.w    4(a1),d0        ; get the character to output
  229.     move.w    _bconbsiz,d1        ; get index into buffer table
  230.     cmp.w    #255,d1            ; buffer full?
  231.     beq    L_bios            ; yes -- flush it out
  232.     lea    _bconbuf,a0
  233.     add.w    d1,a0
  234.     move.b    d0,(a0)            ; store the character
  235.     addq.w    #1,d1
  236.     move.w    d1,_bconbsiz
  237.     moveq.l    #-1,d0            ; return character output OK
  238.     rte
  239.  
  240. new_dev:
  241.     tst.w    _bconbsiz        ; characters already in buffer?
  242.     bne    L_bios            ; yes: we can't buffer this one
  243.     move.w    d0,_bconbdev        ; no: OK, we have a new device
  244.     bra.s    put_buf
  245.  
  246. ;
  247. ; _lineA0: MiNT calls this to get the address of the line A variables
  248. ;
  249.     XDEF    _lineA0
  250. _lineA0:
  251.     movem.l    d2/a2,-(sp)    ; save scratch registers
  252.     dc.w    $a000        ; call the line A initialization routine
  253.     movem.l    (sp)+,d2/a2
  254.     rts
  255.  
  256. ;
  257. ; _call_aes: calls the GEM AES, using the control block passed as
  258. ;            a parameter. Used only for doing appl_init(), to see
  259. ;         if the AES is active yet
  260. ;
  261.     XDEF    _call_aes
  262. _call_aes:
  263.     move.l    4(sp),d1    ; fetch pointer to parameter block
  264.     move.w    #$c8,d0        ; magic number for AES
  265.     movem.l    d2/a2,-(sp)    ; save scratch registers
  266.     trap    #2
  267.     movem.l    (sp)+,d2/a2
  268.     rts
  269.  
  270. ;
  271. ; _callout: Call an external function, passing <32 bytes of arguments,
  272. ; and return the value from the function. NOTE: we must be careful
  273. ; to save all registers here!
  274. ;
  275.     XDEF    _callout
  276. _callout:
  277.     lea    8(sp),a0        ; pointer to args
  278.     move.l    4(sp),a1        ; pointer to function
  279.     movem.l    d2-d7/a2-a6,-(sp)    ; save registers
  280.     movem.l    (a0),d0-d7        ; copy parameters
  281.     lea    -32(sp),sp        ; NOTE: movem.l auto-decrement
  282.      movem.l    d0-d7,(sp)        ;    changes the order of things
  283.     move.l    (a1),a0            ; get function address
  284.     jsr    (a0)            ; go do it
  285.     add.l    #32,sp
  286.     movem.l    (sp)+,d2-d7/a2-a6    ; restore reggies
  287.     rts
  288.  
  289.     SECTION    BSS
  290.     XDEF    syscall_tab,syscall_max
  291.     
  292. syscall_tab    ds.l    1        ; set to which table to use for the call
  293. syscall_max    ds.l    1        ; maximum valid number for this call
  294.     END
  295.