|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.