|
|
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: calls an external function, after first saving all registers,
24:
25: ; and restores the registers afterward
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: ; $Log: syscall.s,v $
78:
79: ; Revision 1.3 1992/03/31 14:02:08 AGK
80:
81: ; Fixed for real Motorola syntax (many thanks to ERS for keeping these
82:
83: ; files in step with the GAS ones).
84:
85: ;
86:
87: ; Revision 1.2 1992/03/31 13:55:28 AGK
88:
89: ; Checked in MiNT 0.93 sources
90:
91: ;
92:
93: ; Revision 1.1 1991/05/30 17:24:16 AGK
94:
95: ; Initial revision
96:
97: ;
98:
99: SECTION TEXT
100:
101:
102:
103: XDEF _mint_bios,_mint_xbios
104:
105: XDEF _mint_dos
106:
107: XREF _build_context
108:
109: XREF _restore_context
110:
111: XREF _proc_clock ; controls process' allocation of CPU time
112:
113: XREF _enter_kernel
114:
115: XREF _leave_kernel
116:
117: XREF _preempt
118:
119:
120:
121: XREF _curproc
122:
123: XREF _bios_tab,_bios_max
124:
125: XREF _xbios_tab,_xbios_max
126:
127: XREF _dos_tab,_dos_max
128:
129:
130:
131: XREF _bconbuf,_bconbsiz,_bconbdev
132:
133: XREF _bflush
134:
135:
136:
137: _mint_dos:
138:
139: move.l #_dos_tab,syscall_tab
140:
141: move.w _dos_max,syscall_max
142:
143: bra.s _syscall
144:
145:
146:
147: _mint_xbios:
148:
149: move.l #_xbios_tab,syscall_tab
150:
151: move.w _xbios_max,syscall_max
152:
153: bra.s _syscall
154:
155:
156:
157: _mint_bios:
158:
159: ;
160:
161: ; Bconout() is noticeably slower under MiNT, so we do a bit of a kludge
162:
163: ; and special case Bconout() so that it doesn't take so long. We
164:
165: ; do this by buffering Bconout calls until either another kind of
166:
167: ; system call or a context switch happens.
168:
169: ;
170:
171: tst.w _bconbdev ; buffering on?
172:
173: bmi.s L_bios ; if bconbdev < 0, no buffering
174:
175: btst #13,(sp) ; test for user/super mode
176:
177: beq.s L_usr ;
178:
179: lea 6(sp),a1 ; supervisor mode: args on stack
180:
181: tst.w $59e ; test longframe
182:
183: beq.s L_check
184:
185: addq.l #2,a1 ; stack is a bit bigger
186:
187: bra.s L_check
188:
189: L_usr:
190:
191: move.l usp,a1 ; user mode: args on user stack
192:
193: L_check:
194:
195: move.w (a1),d0 ; check command
196:
197: cmp.w #3,d0 ; Bconout?
198:
199: beq do_bconout ; yes -- take some shortcuts
200:
201: ; no -- fall through to the normal code
202:
203: L_bios:
204:
205: move.l #_bios_tab,syscall_tab
206:
207: move.w _bios_max,syscall_max
208:
209:
210:
211: _syscall:
212:
213: move.l _curproc,d0
214:
215: addq.l #4,d0
216:
217: move.l d0,-(sp) ; push pointer to syscall context save
218:
219: jsr _build_context
220:
221: ;
222:
223: ; copy parameters onto process stack. a1 was set by _build_context
224:
225: ;
226:
227: L_copy:
228:
229: move.l _curproc,a0
230:
231: move.l (a0),sp ; this puts us in our private stack
232:
233: move.l 24(a1),-(sp) ; a1 was set by build_context
234:
235: move.l 20(a1),-(sp)
236:
237: move.l 16(a1),-(sp)
238:
239: move.l 12(a1),-(sp)
240:
241: move.l 8(a1),-(sp)
242:
243: move.l 4(a1),-(sp)
244:
245: move.l (a1),-(sp)
246:
247: ;
248:
249: jsr _enter_kernel ; set up vectors appropriately
250:
251: ;
252:
253: ; check here to see if we need to flush the Bconout() buffer
254:
255: ;
256:
257: tst.w _bconbsiz ; characters in buffer?
258:
259: beq.s L_noflush ; no: OK to proceed
260:
261: ;
262:
263: ; make sure we save syscall_tab and syscall_max
264:
265: ;
266:
267: move.l syscall_tab,-(sp)
268:
269: move.w syscall_max,-(sp)
270:
271: jsr _bflush ; flush the buffer
272:
273: move.w (sp)+,syscall_max
274:
275: move.l (sp)+,syscall_tab
276:
277:
278:
279: L_noflush:
280:
281: ;
282:
283: ; figure out which routine to call
284:
285: ;
286:
287: clr.l d0
288:
289: move.w (sp),d0
290:
291: cmp.w #-1,d0 ; trapping with -1 means return
292:
293: bne.s check_max ; the corresponding system table
294:
295: move.l syscall_tab,d0
296:
297: bra.s out
298:
299: check_max:
300:
301: cmp.w syscall_max,d0
302:
303: bge.s error
304:
305: add.l d0,d0
306:
307: add.l d0,d0 ; multiply by 4
308:
309: move.l syscall_tab,a0
310:
311: add.l d0,a0
312:
313: move.l (a0),a0
314:
315: cmp.l #0,a0 ; null entry means invalid call
316:
317: beq.s error
318:
319: addq.l #2,sp ; pop function number off stack
320:
321: jsr (a0) ; go do the call
322:
323: out:
324:
325: move.l _curproc,a0
326:
327: move.l d0,4(a0) ; set d0 in the saved context
328:
329: tst.w _proc_clock ; has process exceeded time slice?
330:
331: bne.s nosleep ; no -- continue
332:
333: move.w 68(a0),d0 ; get saved status register
334:
335: btst #13,d0 ; caller in supervisor mode?
336:
337: bne nosleep ; yes -- don't interrupt
338:
339: sleep:
340:
341: jsr _preempt ; does a sleep(READY_Q)
342:
343: nosleep:
344:
345: ori.w #$0700,sr ; spl7()
346:
347: jsr _leave_kernel ; restore vectors
348:
349: move.l _curproc,a0
350:
351: pea 4(a0)
352:
353: jsr _restore_context ; never returns
354:
355:
356:
357: ;
358:
359: ; we handle errors by calling through to GEMDOS or the BIOS/XBIOS,
360:
361: ; as appropriate, and letting them handle it -- that way, if the underlying
362:
363: ; system has functions we don't know about, they still work
364:
365: ;
366:
367:
368:
369: error:
370:
371: move.l syscall_tab,a0
372:
373: cmp.l #_xbios_tab,a0
374:
375: bne.s maybe_dos
376:
377: trap #14
378:
379: bra.s out
380:
381: maybe_dos:
382:
383: cmp.l #_dos_tab,a0
384:
385: beq.s trap_1
386:
387: trap #13
388:
389: bra.s out
390:
391: trap_1:
392:
393: trap #1
394:
395: bra.s out
396:
397:
398:
399: ;
400:
401: ; sig_return: user signal handlers return to us. At that point, the
402:
403: ; stack looks like this:
404:
405: ; (sp) (long) signal number -- was a parameter for user routine
406:
407: ;
408:
409: XDEF _sig_return
410:
411: XREF _valid_return
412:
413: _sig_return:
414:
415: addq.l #4,sp ; pop signal number
416:
417: move.w #$11a,-(sp) ; Psigreturn() system call
418:
419: move.w #1,_valid_return ; tell kernel it's us!
420:
421: trap #1
422:
423: ; we had better not come back; if we did, something terrible
424:
425: ; happened, and we might as well terminate
426:
427: move.w #-998,-(sp)
428:
429: move.w #$4c,-(sp) ; Pterm()
430:
431: trap #1
432:
433: ;
434:
435: ; bconout special code: on entry, a1 points to the stack the user
436:
437: ; was using. If possible, we just buffer the output until later.
438:
439: ;
440:
441:
442:
443: do_bconout:
444:
445: move.w 2(a1),d0 ; what device is this for?
446:
447: beq L_bios ; don't buffer the printer
448:
449: cmp.w _bconbdev,d0 ; same device as is buffered?
450:
451: bne.s new_dev ; no -- maybe we can't do this
452:
453: put_buf:
454:
455: move.w 4(a1),d0 ; get the character to output
456:
457: move.w _bconbsiz,d1 ; get index into buffer table
458:
459: cmp.w #255,d1 ; buffer full?
460:
461: beq L_bios ; yes -- flush it out
462:
463: lea _bconbuf,a0
464:
465: add.w d1,a0
466:
467: move.b d0,(a0) ; store the character
468:
469: addq.w #1,d1
470:
471: move.w d1,_bconbsiz
472:
473: moveq.l #-1,d0 ; return character output OK
474:
475: rte
476:
477:
478:
479: new_dev:
480:
481: tst.w _bconbsiz ; characters already in buffer?
482:
483: bne L_bios ; yes: we can't buffer this one
484:
485: move.w d0,_bconbdev ; no: OK, we have a new device
486:
487: bra.s put_buf
488:
489:
490:
491: ;
492:
493: ; _lineA0: MiNT calls this to get the address of the line A variables
494:
495: ;
496:
497: XDEF _lineA0
498:
499: _lineA0:
500:
501: movem.l d2/a2,-(sp) ; save scratch registers
502:
503: dc.w $a000 ; call the line A initialization routine
504:
505: movem.l (sp)+,d2/a2
506:
507: rts
508:
509:
510:
511: ;
512:
513: ; _call_aes: calls the GEM AES, using the control block passed as
514:
515: ; a parameter. Used only for doing appl_init(), to see
516:
517: ; if the AES is active yet
518:
519: ;
520:
521: XDEF _call_aes
522:
523: _call_aes:
524:
525: move.l 4(sp),d1 ; fetch pointer to parameter block
526:
527: move.w #$c8,d0 ; magic number for AES
528:
529: movem.l d2/a2,-(sp) ; save scratch registers
530:
531: trap #2
532:
533: movem.l (sp)+,d2/a2
534:
535: rts
536:
537:
538:
539: ;
540:
541: ; _callout: Call an external function, passing <32 bytes of arguments,
542:
543: ; and return the value from the function. NOTE: we must be careful
544:
545: ; to save all registers here!
546:
547: ;
548:
549: XDEF _callout
550:
551: _callout:
552:
553: lea 8(sp),a0 ; pointer to args
554:
555: move.l 4(sp),a1 ; pointer to function
556:
557: movem.l d2-d7/a2-a6,-(sp) ; save registers
558:
559: movem.l (a0),d0-d7 ; copy parameters
560:
561: lea -32(sp),sp ; NOTE: movem.l auto-decrement
562:
563: movem.l d0-d7,(sp) ; changes the order of things
564:
565: move.l (a1),a0 ; get function address
566:
567: jsr (a0) ; go do it
568:
569: add.l #32,sp
570:
571: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies
572:
573: rts
574:
575:
576:
577: SECTION BSS
578:
579: XDEF syscall_tab,syscall_max
580:
581:
582:
583: syscall_tab ds.l 1 ; set to which table to use for the call
584:
585: syscall_max ds.l 1 ; maximum valid number for this call
586:
587: END
588:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.