home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mint095s / syscall.s < prev    next >
Text File  |  1993-08-03  |  8KB  |  275 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:    call an external function, after first making sure that all
  13. |              registers are saved
  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.     .globl  _mint_bios, _mint_xbios
  40.     .globl    _mint_dos
  41.     .globl    _build_context
  42.     .globl    _restore_context
  43.  
  44.     .globl    _curproc
  45.     .globl    _bios_tab, _bios_max
  46.     .globl  _xbios_tab, _xbios_max
  47.     .globl    _dos_tab, _dos_max
  48.     .globl    _bconbuf, _bconbsiz, _bconbdev
  49.     .globl    _bflush
  50.  
  51.     .data
  52.     .comm    syscall_tab, 4        | set to which table to use for the call
  53.     .comm    syscall_max, 4        | maximum valid number for this call
  54.  
  55.     .text
  56.     .even
  57.  
  58. _mint_dos:
  59.     movel    #_dos_tab, syscall_tab
  60.     movew    _dos_max, syscall_max
  61.     bra    _syscall
  62.  
  63. _mint_xbios:
  64.     movel    #_xbios_tab, syscall_tab
  65.     movew    _xbios_max, syscall_max
  66.     bra    _syscall
  67.  
  68. _mint_bios:
  69. |
  70. | Bconout() is noticeably slower under MiNT, so we do a bit of a kludge
  71. | and special case Bconout() so that it doesn't take so long. We
  72. | do this by buffering Bconout calls until either another kind of
  73. | system call or a context switch happens.
  74. |
  75.     tstw    _bconbdev        | buffering on?
  76.     bmi    L_bios            | if bconbdev < 0, no buffering
  77.     btst    #13, sp@        | test for user/super mode
  78.     beq    L_usr            | 
  79.     lea    sp@(6), a1        | supervisor mode: args on stack
  80.     tstw    0x59e            | test longframe
  81.     beq    L_check
  82.     addql    #2, a1            | stack is a bit bigger
  83.     bra    L_check
  84. L_usr:
  85.     movel    usp, a1            | user mode: args on user stack
  86. L_check:
  87.     movew    a1@, d0            | check command
  88.     cmpw    #3, d0            | Bconout?
  89.     beq    do_bconout        | yes -- take some shortcuts
  90.                     | no -- fall through to the normal code
  91. L_bios:
  92.     movel    #_bios_tab, syscall_tab
  93.     movew    _bios_max, syscall_max
  94.  
  95. _syscall:
  96.     movel    _curproc, d0
  97.     addql    #4, d0
  98.     movel    d0, sp@-        | push pointer to syscall context save
  99.     jsr    _build_context
  100. |
  101. | copy parameters onto process stack. a1 was set by _build_context
  102. |
  103. L_copy:
  104.     movel    _curproc, a0
  105.     movel    a0@, a0            | fetch system call stack pointer
  106.     lea    a0@(-28), sp        | this puts us in our private stack
  107.     moveml    a1@, d1-d7        | copy parameters from user stack
  108.     moveml    d1-d7, sp@        | to ours (build_context set a1)
  109. |
  110.     jsr    _enter_kernel        | set up vectors appropriately
  111. |
  112. | check here to see if we need to flush the Bconout() buffers
  113. |
  114.     tstw    _bconbsiz        | characters in buffer?
  115.     beq    L_noflush        | nope: OK to proceed
  116. |
  117. | make sure we save syscall_tab and syscall_max
  118. |
  119.     movel    syscall_tab, sp@-
  120.     movew    syscall_max, sp@-
  121.     jsr    _bflush            | flush the buffer
  122.     movew    sp@+, syscall_max
  123.     movel    sp@+, syscall_tab
  124.  
  125. L_noflush:
  126. |
  127. | figure out which routine to call
  128. |
  129.     clrl    d0
  130.     movew    sp@, d0
  131.     cmpw    #-1, d0            | trapping with -1 means return
  132.     bne    check_max        | the corresponding system table
  133.     movel    syscall_tab, d0
  134.     bra    out
  135. check_max:
  136.     cmpw    syscall_max, d0
  137.     bge    error
  138.     addl    d0,d0
  139.     addl    d0,d0            | multiply by 4
  140.     movel    syscall_tab, a0
  141.     addl    d0, a0
  142.     movel    a0@, a0
  143.     cmpl    #0, a0            | null entry means invalid call
  144.     beq    error
  145.     addql    #2, sp            | pop function number off stack
  146.     jsr    a0@            | go do the call
  147. out:
  148.     movel    _curproc, a0
  149.     movel    d0, a0@(4)        | set d0 in the saved context
  150.     tstw    _proc_clock        | has process exceeded time slice?
  151.     bne    nosleep            | no -- continue
  152.     movew    a0@(68), d0        | get saved status register
  153.     btst    #13, d0            | caller in supervisor mode?
  154.     bne    nosleep            | yes -- don't interrupt
  155. sleep:
  156.     jsr    _preempt        | does a sleep(READY_Q)
  157. nosleep:
  158.     oriw    #0x0700, sr        | spl7()
  159.     jsr    _leave_kernel        | restore vectors
  160.     movel    _curproc, a0
  161.     pea    a0@(4)
  162.     jsr    _restore_context    | never returns
  163.  
  164. |
  165. | we handle errors by calling through to GEMDOS or the BIOS/XBIOS,
  166. | as appropriate, and letting them handle it -- that way, if the underlying
  167. | system has functions we don't know about, they still work
  168. |
  169.  
  170. error:
  171.     movel    syscall_tab, a0
  172.     cmpl    #_xbios_tab, a0
  173.     bne    maybe_dos
  174.     trap    #14
  175.     bra    out
  176. maybe_dos:
  177.     cmpl    #_dos_tab, a0
  178.     beq    trap_1
  179.     trap    #13
  180.     bra    out
  181. trap_1:
  182.     trap    #1
  183.     bra    out
  184.  
  185. |
  186. | sig_return: user signal handlers return to us. At that point, the
  187. | stack looks like this:
  188. |    (sp)      (long) signal number -- was a parameter for user routine
  189. |
  190.     .globl    _sig_return
  191.     .globl    _valid_return
  192. _sig_return:
  193.     addql    #4, sp            | pop signal number
  194.     movew    #0x11a, sp@-        | Psigreturn() system call
  195.     movew    #1, _valid_return    | tell kernel it's us!
  196.     trap    #1
  197. | we had better not come back; if we did, something terrible
  198. | happened, and we might as well terminate
  199.     movew    #-998, sp@-
  200.     movew    #0x4c, sp@-        | Pterm()
  201.     trap    #1
  202.  
  203. |
  204. | bconout special code: on entry, a1 points to the stack the user
  205. | was using. If possible, we just buffer the output until later.
  206. |
  207.  
  208. do_bconout:
  209.     movew    a1@(2), d0        | what device is this for?
  210.     beq    L_bios            | don't buffer the printer
  211.     cmpw    _bconbdev, d0        | same device as is buffered?
  212.     bne    new_dev            | no -- maybe we can't do this
  213. put_buf:
  214.     movew    a1@(4), d0        | get the character to output
  215.     movew    _bconbsiz, d1        | get index into buffer table
  216.     cmpw    #255, d1        | buffer full?
  217.     beq    L_bios            | yes -- flush it out
  218.     lea    _bconbuf, a0
  219.     addw    d1, a0
  220.     moveb    d0, a0@            | store the character
  221.     addqw    #1, d1
  222.     movew    d1, _bconbsiz
  223.     moveql    #-1, d0            | return character output OK
  224.     rte
  225.  
  226. new_dev:
  227.     tstw    _bconbsiz        | characters already in buffer?
  228.     bne    L_bios            | yes: we can't buffer this one
  229.     movew    d0, _bconbdev        | no: OK, we have a new device
  230.     bra    put_buf
  231. |
  232. |
  233. | _lineA0: MiNT calls this to get the address of the line A variables
  234. |
  235.     .globl    _lineA0
  236. _lineA0:
  237.     moveml    d2/a2, sp@-    | save scratch registers
  238.     .word    0xa000        | call the line A initialization routine
  239.     moveml    sp@+, d2/a2
  240.     rts
  241.  
  242. |
  243. | _call_aes: calls the GEM AES, using the control block passed as
  244. |            a parameter. Used only for doing appl_init(), to see
  245. |         if the AES is active yet
  246. |
  247.     .globl    _call_aes
  248. _call_aes:
  249.     movel    sp@(4), d1    | fetch pointer to parameter block
  250.     movew    #0xc8, d0    | magic number for AES
  251.     moveml    d2/a2, sp@-    | save scratch registers
  252.     trap    #2
  253.     moveml    sp@+, d2/a2
  254.     rts
  255.  
  256.  
  257. |
  258. | _callout: Call an external function, passing <32 bytes of arguments,
  259. | and return the value from the function. NOTE: we must be careful
  260. | to save all registers here!
  261. |
  262.     .globl    _callout
  263. _callout:
  264.     lea    sp@(8), a0        | pointer to args
  265.     movel    sp@(4), a1        | pointer to function
  266.     moveml    d2-d7/a2-a6, sp@-    | save registers
  267.     moveml    a0@, d0-d7        | copy parameters
  268.     lea    sp@(-32), sp        | NOTE: moveml auto-decrement
  269.     moveml    d0-d7, sp@        |    changes the order of things
  270.     movel    a1@, a0            | get function address
  271.     jsr    a0@            | go do it
  272.     addl    #32, sp
  273.     moveml    sp@+, d2-d7/a2-a6    | restore reggies
  274.     rts
  275.