|
|
1.1.1.2 root 1: ; Copyright 1992 Eric R. Smith
2:
1.1.1.5 ! root 3: ; Copyright 1992,1993,1994 Atari Corporation
1.1.1.2 root 4:
5: ; All rights reserved.
6:
7:
8:
1.1 root 9: %include "magic.i"
10:
11: ;
12:
13: ; syscall: interface for system calls. The following entry points are
14:
15: ; defined:
16:
17: ; _mint_bios: entry point for the BIOS calls (trap #13)
18:
19: ; _mint_xbios: entry point for XBIOS calls (trap #14)
20:
21: ; _mint_dos: entry point for GEMDOS calls (trap #1)
22:
23: ; _sig_return: user signal handlers return to this routine (see signal.c)
24:
25: ; it is responsible for restoring the kernel's old context
26:
27: ; via the Psigreturn() system call
28:
29: ; _lineA0: calls the line A initialize routine
30:
31: ; _call_aes: calls the GEM AES
32:
1.1.1.4 root 33: ; _call_dosound: calls the XBIOS Dosound() function
34:
1.1.1.2 root 35: ; _do_usrcall: calls a user supplied function (e.g. for Supexec), with
36:
37: ; arguments supplied from global variables usrarg1, usrarg2, etc.
38:
1.1 root 39: ; _callout: calls an external function, after first saving all registers,
40:
41: ; and restores the registers afterward
42:
43: ;
44:
45: ; external variables referenced:
46:
47: ; _bios_tab, _bios_max:
48:
49: ; table of entry points for BIOS routines, max # of routine
50:
51: ; _xbios_tab, _xbios_max:
52:
53: ; ditto for XBIOS
54:
55: ; _dos_tab, _dos_max:
56:
57: ; ditto for GEMDOS
58:
59: ; _curproc:
60:
61: ; pointer to current process table entry, and hence to save area for
62:
63: ; context (this is always the first entry in the PROC table).
64:
65: ;
66:
67: ; _bconbuf, _bconbsiz, _bconbdev:
68:
69: ; 256 byte buffer for Bconout() output. If _bconbsiz is non-zero,
70:
71: ; there are that many bytes in _bconbuf waiting to be flushed. The
72:
73: ; output is for device _bconbdev.
74:
75: ;
76:
77: ; The C function enter_kernel() is called on entry to the kernel, and the
78:
79: ; function leave_kernel() is called on exit. These functions are responsible
80:
81: ; for saving and restoring the various trap vectors, so that MiNT can trap
82:
83: ; out to TOS directly, but programs can only trap to MiNT.
84:
85: ;
86:
87: ; we also call certain BIOS functions directly if these are known not to
88:
89: ; require saving/restoring of context
90:
91: ;
92:
93: TEXT
94:
95:
96:
97: XDEF _mint_bios,_mint_xbios
98:
99: XDEF _mint_dos
100:
1.1.1.5 ! root 101: XDEF _pc_valid_return
! 102:
1.1 root 103: XREF _build_context
104:
105: XREF _restore_context
106:
107: XREF _proc_clock ; controls process' allocation of CPU time
108:
109: XREF _enter_kernel
110:
111: XREF _leave_kernel
112:
113: XREF _preempt
114:
1.1.1.5 ! root 115: XREF _unwound_stack
! 116:
! 117:
! 118:
! 119: XREF _check_sigs
! 120:
1.1 root 121:
122:
123: XREF _curproc
124:
125: XREF _bios_tab,_bios_max
126:
1.1.1.2 root 127: XREF _xbios_tab,_xbios_max,_old_xbios
1.1 root 128:
129: XREF _dos_tab,_dos_max
130:
131:
132:
133: XREF _bconbuf,_bconbsiz,_bconbdev
134:
135: XREF _bflush
136:
137:
138:
139: XREF _ubconstat,_do_bconin,_ubcostat,_kbshift
140:
141:
142:
143: _mint_dos:
144:
145: clr.w -(sp) ; no frame format needed
146:
1.1.1.3 root 147: ; NOTE: FOR NOW, WE PRESERVE A0 ACROSS GEMDOS CALLS. THIS WILL CHANGE
148:
149: ; SOMEDAY, DON'T RELY ON IT!!!
150:
151: move.l _curproc,d0 ; note: preserve all regs but d0
152:
153: addq.l #4,d0 ; for compatibility
154:
1.1 root 155:
156:
157: move.l d0,-(sp) ; push pointer to syscall context save
158:
159: jsr _build_context
160:
1.1.1.3 root 161: lea _dos_tab,a5 ; set syscall_tab
1.1 root 162:
163: move.w _dos_max,d5 ; set syscall_max
164:
165: ;
166:
167: ; copy parameters onto process stack. a0 and a1 were set by _build_context
168:
169: ;
170:
171:
172:
173: move.l _curproc,a0
174:
175: move.l (a0),sp ; this puts us in our private stack
176:
177: move.l 24(a1),-(sp) ; a1 was set by build_context
178:
179: move.l 20(a1),-(sp)
180:
181: move.l 16(a1),-(sp)
182:
183: move.l 12(a1),-(sp)
184:
185: move.l 8(a1),-(sp)
186:
187: move.l 4(a1),-(sp)
188:
189: move.l (a1),-(sp)
190:
1.1.1.4 root 191: move.w #1,-(sp) ; flag for in GEMDOS
192:
1.1 root 193: jsr _enter_kernel ; set up vectors appropriately
194:
1.1.1.4 root 195: addq.w #2,sp
196:
1.1 root 197: bra _syscall
198:
199:
200:
201: _mint_xbios:
202:
1.1.1.2 root 203: ;
204:
205: ; Kludge for Setscreen: under Falcon TOS, this
206:
207: ; calls a GEMDOS function (Srealloc) and so
208:
209: ; we must *not* change any of the vectors!!
210:
211:
212:
1.1.1.3 root 213: btst #5,(sp) ; test for user/super mode
1.1.1.2 root 214:
1.1.1.3 root 215: beq.s LX_usr
1.1.1.2 root 216:
217: %ifdef ONLY030
218:
219: lea 8(sp),a1
220:
221: %else
222:
223: lea 6(sp),a1 ; supervisor mode: args on stack
224:
225: tst.w ($59e).w ; test longframe
226:
227: beq.s LX_check
228:
1.1.1.3 root 229: addq.w #2,a1 ; stack is a bit bigger
1.1.1.2 root 230:
231: %endif
232:
233: bra.s LX_check
234:
235: LX_usr:
236:
237: move.l usp,a1 ; user mode: args on user stack
238:
239: LX_check:
240:
1.1.1.3 root 241: cmp.w #5,(a1) ; check for Setscreen command
1.1.1.2 root 242:
1.1.1.3 root 243: beq.s LX_screen ; no -- fall through
1.1.1.2 root 244:
245:
246:
1.1 root 247: clr.w -(sp) ; no frame format needed
248:
1.1.1.3 root 249: move.l _curproc,a0
1.1 root 250:
1.1.1.3 root 251: pea 4(a0) ; push pointer to syscall context save
1.1 root 252:
253: jsr _build_context
254:
1.1.1.3 root 255: lea _xbios_tab,a5 ; set syscall_tab
1.1 root 256:
257: move.w _xbios_max,d5 ; set syscall_max
258:
259: ;
260:
261: ; copy parameters onto process stack. a0 and a1 were set by _build_context
262:
263: ;
264:
265:
266:
267: move.l _curproc,a0
268:
269: move.l (a0),sp ; this puts us in our private stack
270:
271: move.l 24(a1),-(sp) ; a1 was set by build_context
272:
273: move.l 20(a1),-(sp)
274:
275: move.l 16(a1),-(sp)
276:
277: move.l 12(a1),-(sp)
278:
279: move.l 8(a1),-(sp)
280:
281: move.l 4(a1),-(sp)
282:
283: move.l (a1),-(sp)
284:
1.1.1.5 ! root 285: %ifdef ONLY030
! 286:
! 287: clr.w -(sp) ; flag: NOT GEMDOS
! 288:
! 289: %else
! 290:
1.1.1.4 root 291: move.w #0,-(sp) ; flag: NOT GEMDOS
292:
1.1.1.5 ! root 293: %endif
! 294:
1.1 root 295: jsr _enter_kernel ; set up vectors appropriately
296:
1.1.1.4 root 297: addq.w #2,sp
298:
1.1 root 299: bra _syscall
300:
1.1.1.2 root 301: ;
302:
303: ; For setscreen, jump directly to the ROM vector --
304:
305: ; this avoids all hazards (like changing the vectors)
306:
307:
308:
309: LX_screen:
310:
311: move.l _old_xbios+8,a0
312:
313: jmp (a0)
314:
315:
316:
1.1 root 317:
318:
319: _mint_bios:
320:
321: ;
322:
323: ; Entering the kernel can be very expensive; so, we take a short-cut
324:
325: ; if possible -- we try some BIOS functions out, and if they
326:
327: ; succeed without blocking then we're done; otherwise, we go
328:
329: ; through the long procedure for entering the kernel
330:
331: ;
332:
333: ; These shortcuts aren't done when we're called in supervisor mode,
334:
335: ; because TOS uses very tiny stacks (smaller than we want); the
336:
337: ; shortcuts operate on the user-supplied ssp, whereas the "full"
338:
339: ; BIOS code works on our (private) system stack
340:
341: ;
342:
1.1.1.2 root 343: ; the shortcuts are also turned off if BIOSBUF=n
344:
345: ;
346:
1.1.1.5 ! root 347: %ifdef ONLY030
! 348:
! 349: clr.w -(sp) ; flag: NOT a GEMDOS call
! 350:
! 351: %else
! 352:
1.1.1.4 root 353: move.w #0,-(sp) ; flag: NOT a GEMDOS call
354:
1.1.1.5 ! root 355: %endif
! 356:
1.1 root 357: jsr _enter_kernel ; set up BIOS vectors
358:
1.1.1.4 root 359: addq.w #2,sp
360:
1.1.1.2 root 361: tst.w _bconbdev ; is BIOS buffering on?
362:
363: bmi L_bios ; no; skip all this
364:
365:
366:
1.1 root 367: btst #5,(sp) ; test for user/super mode
368:
369: bne.s L_bios ; if super, goto L_bios
370:
371: tst.w _proc_clock ; are we about to be preempted?
372:
1.1.1.3 root 373: beq.s L_bios
1.1 root 374:
375:
376:
377: move.l usp,a1 ; user mode: args on user stack
378:
379: L_ubios:
380:
381: move.w (a1),d0 ; get command
382:
383: cmp.w #3,d0 ; Bconout?
384:
385: beq do_bconout ; yes -- go do it
386:
387: ;
388:
389: ; most of the remaining functions require BIOS vectors to be properly
390:
391: ; set up
392:
393: tst.w _bconbsiz ; is BIOS output waiting?
394:
395: bne.s L_bios ; yes -- do regular code
396:
397:
398:
399: ; test for various BIOS functions
400:
401: cmp.w #1,d0 ; Bconstat?
402:
403: bne.s L_00
404:
405: move.w 2(a1),-(sp) ; push arg
406:
407: jsr _ubconstat
408:
409: L_1out:
410:
411: addq.l #2,sp
412:
413: L_0out:
414:
415: move.l d0,-(sp) ; save d0
416:
417: ori.w #$0700,sr ; spl7()
418:
419: jsr _leave_kernel
420:
421: move.l (sp)+,d0 ; retrieve value to be returned
422:
423: rte ; return to user
424:
425: L_00:
426:
427: cmp.w #2,d0 ; Bconin?
428:
429: bne.s L_01
430:
431: move.w 2(a1),-(sp) ; yes; push argument
432:
433: jsr _do_bconin
434:
1.1.1.3 root 435: addq.w #2,sp
1.1 root 436:
437: cmp.w #$dead,d0 ; would Bconin block?
438:
439: bne.s L_0out ; no -- we're done
440:
441: bra.s L_bios ; yes -- do the long stuff
442:
443: L_01:
444:
445: cmp.w #8,d0 ; Bcostat?
446:
447: bne.s L_02
448:
449: move.w 2(a1),-(sp) ; push device
450:
451: jsr _ubcostat ; get status
452:
453: bra.s L_1out
454:
455: L_02:
456:
457: cmp.w #11,d0 ; Kbshift?
458:
459: bne.s L_bios
460:
461: move.w 2(a1),-(sp) ; push arg
462:
463: jsr _kbshift
464:
465: bra.s L_1out
466:
467:
468:
469: L_bios:
470:
471: clr.w -(sp) ; no frame format needed
472:
1.1.1.3 root 473: move.l _curproc,a0
1.1 root 474:
1.1.1.3 root 475: pea 4(a0) ; push pointer to syscall context save
1.1 root 476:
477: jsr _build_context
478:
1.1.1.3 root 479: lea _bios_tab,a5 ; set syscall_tab
1.1 root 480:
481: move.w _bios_max,d5 ; set syscall_max
482:
483: ;
484:
485: ; copy parameters onto process stack. a0 and a1 were set by _build_context
486:
487: ;
488:
489:
490:
491: move.l _curproc,a0
492:
493: move.l (a0),sp ; this puts us in our private stack
494:
495: move.l 24(a1),-(sp) ; a1 was set by build_context
496:
497: move.l 20(a1),-(sp)
498:
499: move.l 16(a1),-(sp)
500:
501: move.l 12(a1),-(sp)
502:
503: move.l 8(a1),-(sp)
504:
505: move.l 4(a1),-(sp)
506:
507: move.l (a1),-(sp)
508:
509:
510:
511: _syscall:
512:
513: ;
514:
515: ; check here to see if we need to flush the Bconout() buffer
516:
517: ;
518:
519: tst.w _bconbsiz ; characters in buffer?
520:
521: beq.s L_noflush ; no: OK to proceed
522:
523: ;
524:
525: ; watch out, this could cause a context switch
526:
527: ;
528:
529: jsr _bflush ; flush the buffer
530:
531:
532:
533: L_noflush:
534:
535: ;
536:
537: ; figure out which routine to call
538:
539: ;
540:
541: move.w (sp),d0
542:
543: cmp.w #-1,d0 ; trapping with -1 means return
544:
545: bne.s check_max ; the corresponding system table
546:
547: move.l a5,d0
548:
549: bra.s out
550:
551: check_max:
552:
553: cmp.w d5,d0
554:
1.1.1.5 ! root 555: bcc error
! 556:
! 557: %ifdef ONLY030
! 558:
! 559: move.l 0(a5,d0.w*4),d0
! 560:
! 561: %else
1.1 root 562:
563: add.w d0,d0
564:
565: add.w d0,d0 ; multiply by 4
566:
567: move.l 0(a5,d0.w),d0 ; d0 = syscall_tab[d0]
568:
1.1.1.5 ! root 569: %endif
! 570:
! 571: beq error ; null entry means invalid call
1.1 root 572:
1.1.1.3 root 573: addq.w #2,sp ; pop function number off stack
1.1 root 574:
575: move.l d0,a0
576:
577: jsr (a0) ; go do the call
578:
579: out:
580:
581: move.l _curproc,a0
582:
583: move.l d0,P_SYSCTXT+C_D0(a0) ; set d0 in the saved context
584:
585: move.w P_SYSCTXT+C_SR(a0),d0 ; get saved status register
586:
587:
588:
589: tst.l P_PTRACER(a0) ; check curproc->ptracer, if not set
590:
591: beq.s notrace ; then no pending trace; this ensures
592:
593: move.w d0,d1 ; we work with non-MiNT debuggers
594:
595: and.w #$c000,d1 ; are either of the trace bits set
596:
597: sne P_SYSCTXT+C_PTRACE(a0) ; mark as trace pending/not
598:
599: notrace:
600:
601: tst.w _proc_clock ; has process exceeded time slice?
602:
603: bne.s nosleep ; no -- continue
604:
605: btst #13,d0 ; caller in supervisor mode?
606:
607: bne.s nosleep ; yes -- don't interrupt
608:
609: tst.w ($43e).w ; test floppy disk lock variable
610:
611: bne.s nosleep ; if locked, can't switch
612:
613: sleep:
614:
1.1.1.5 ! root 615: tst.l _unwound_stack ; did we unwind sysstack?
! 616:
! 617: beq.s noreload1
! 618:
! 619: move.l _curproc,a0 ; then reload it before
! 620:
! 621: move.l (a0),sp ; doing anything further
! 622:
! 623: noreload1:
! 624:
1.1 root 625: jsr _preempt ; does a sleep(READY_Q)
626:
627: nosleep:
628:
629: ori.w #$0700,sr ; spl7()
630:
631: jsr _leave_kernel ; restore vectors
632:
633: move.l _curproc,a0
634:
635: pea 4(a0)
636:
637: jsr _restore_context ; never returns
638:
639:
640:
641: ;
642:
643: ; we handle errors by calling through to GEMDOS or the BIOS/XBIOS,
644:
645: ; as appropriate, and letting them handle it -- that way, if the underlying
646:
647: ; system has functions we don't know about, they still work
648:
649: ; to figure out which trap we have to call, we use the system call
650:
651: ; table placed in a5 earlier
652:
653:
654:
655: error:
656:
657: cmp.l #_xbios_tab,a5
658:
659: bne.s maybe_bios
660:
661: trap #14
662:
1.1.1.5 ! root 663: bra out
1.1 root 664:
665: maybe_bios:
666:
667: cmp.l #_dos_tab,a5
668:
669: beq.s trap_1
670:
671: trap #13
672:
1.1.1.5 ! root 673: bra out
1.1 root 674:
675: trap_1:
676:
677: trap #1
678:
1.1.1.5 ! root 679: bra out
1.1 root 680:
681:
682:
683: ;
684:
685: ; sig_return: user signal handlers return to us. At that point, the
686:
687: ; stack looks like this:
688:
1.1.1.2 root 689: ; -4(sp) (long) sfmt
690:
1.1 root 691: ; (sp) (long) signal number -- was a parameter for user routine
692:
693: ;
694:
695: XDEF _sig_return
696:
1.1.1.5 ! root 697:
1.1 root 698:
699: _sig_return:
700:
1.1.1.3 root 701: addq.w #8,sp ; pop signal number and sfmt
1.1 root 702:
703: move.w #$11a,-(sp) ; Psigreturn() system call
704:
705: trap #1
706:
1.1.1.5 ! root 707: _pc_valid_return:
! 708:
1.1 root 709: ; we had better not come back; if we did, something terrible
710:
711: ; happened, and we might as well terminate
712:
713: move.w #-998,-(sp)
714:
715: move.w #$4c,-(sp) ; Pterm()
716:
717: trap #1
718:
719: ;
720:
721: ; bconout special code: on entry, a1 points to the stack the user
722:
723: ; was using. If possible, we just buffer the output until later.
724:
725: ;
726:
727:
728:
729: do_bconout:
730:
731: tst.w _bconbdev ; is BIOS buffering on?
732:
733: bmi L_bios ; no buffering -- skip this code
734:
735: move.w 2(a1),d0 ; what device is this for?
736:
737: beq L_bios ; don't buffer the printer
738:
739: cmp.w _bconbdev,d0 ; same device as is buffered?
740:
741: bne.s new_dev ; no -- maybe we can't do this
742:
743: put_buf:
744:
745: move.w 4(a1),d0 ; get the character to output
746:
747: move.w _bconbsiz,d1 ; get index into buffer table
748:
749: cmp.w #255,d1 ; buffer full?
750:
751: beq L_bios ; yes -- flush it out
752:
753: lea _bconbuf,a0
754:
755: add.w d1,a0
756:
757: move.b d0,(a0) ; store the character
758:
759: addq.w #1,d1
760:
761: move.w d1,_bconbsiz
762:
1.1.1.5 ! root 763: ori.w #$0700,sr ; spl7()
! 764:
1.1 root 765: jsr _leave_kernel ; restore vectors
766:
767: moveq.l #-1,d0 ; return character output OK
768:
769: rte
770:
771:
772:
773: new_dev:
774:
775: tst.w _bconbsiz ; characters already in buffer?
776:
777: bne L_bios ; yes: we can't buffer this one
778:
779: move.w d0,_bconbdev ; no: OK, we have a new device
780:
781: bra.s put_buf
782:
783:
784:
785: ;
786:
787: ; _lineA0: MiNT calls this to get the address of the line A variables
788:
789: ;
790:
791: XDEF _lineA0
792:
793: _lineA0:
794:
795: movem.l d2/a2,-(sp) ; save scratch registers
796:
797: dc.w $a000 ; call the line A initialization routine
798:
799: movem.l (sp)+,d2/a2
800:
801: rts
802:
803:
804:
805: ;
806:
807: ; _call_aes: calls the GEM AES, using the control block passed as
808:
809: ; a parameter. Used only for doing appl_init(), to see
810:
811: ; if the AES is active yet
812:
813: ;
814:
815: XDEF _call_aes
816:
817: _call_aes:
818:
819: move.l 4(sp),d1 ; fetch pointer to parameter block
820:
821: move.w #$c8,d0 ; magic number for AES
822:
823: movem.l d2/a2,-(sp) ; save scratch registers
824:
825: trap #2
826:
827: movem.l (sp)+,d2/a2
828:
829: rts
830:
1.1.1.4 root 831: ;
832:
833: ; _call_dosound:
834:
835: ;
836:
837: XDEF _call_dosound
838:
839: _call_dosound:
840:
1.1.1.5 ! root 841: move.l 4(sp),-(sp)
1.1.1.4 root 842:
843: move.w #32,-(sp)
844:
845: trap #14
846:
847: addq.w #6,sp
848:
849: rts
850:
1.1 root 851:
852:
853: ;
854:
855: ; _callout: Call an external function, passing <32 bytes of arguments,
856:
857: ; and return the value from the function. NOTE: we must be careful
858:
859: ; to save all registers here!
860:
861: ;
862:
863: XDEF _callout
864:
865: XDEF _callout1
866:
867: XDEF _callout2
868:
1.1.1.5 ! root 869: XDEF _callout6
! 870:
! 871: XDEF _callout6spl7
! 872:
1.1 root 873: ;
874:
875: ; _callout is the general purpose one
876:
877: ;
878:
879: _callout:
880:
881: lea 8(sp),a0 ; pointer to args
882:
883: move.l 4(sp),a1 ; pointer to pointer to function
884:
885: movem.l d2-d7/a2-a6,-(sp) ; save registers
886:
887: movem.l (a0),d0-d7 ; copy parameters
888:
1.1.1.4 root 889: movem.l d0-d7,-(sp)
1.1 root 890:
1.1.1.4 root 891: suba.l a5,a5 ; the BIOS expects 0 in a5
1.1 root 892:
893: jsr (a1) ; go do it
894:
895: lea 32(sp),sp
896:
897: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies
898:
899: rts
900:
901: ;
902:
903: ; _callout2 and _callout1 are for functions with just 1 or
904:
905: ; 2 16 bit parameters. We cheat and use the same code for
906:
907: ; both, since passing 32 bits isn't much more expensive than
908:
909: ; passing 16 bits (and since the called function will just
910:
911: ; ignore any extra arg)
912:
913: ;
914:
915:
916:
917: _callout1:
918:
919: _callout2:
920:
921: movem.l 4(sp),a0/a1 ; get function ptr & args
922:
923: movem.l d2-d7/a2-a6,-(sp) ; save reggies
924:
925: move.l a1,-(sp) ; push args
926:
1.1.1.4 root 927: suba.l a5,a5 ; the BIOS expects 0 in a5
928:
1.1 root 929: jsr (a0) ; do function
930:
1.1.1.3 root 931: addq.w #4,sp
1.1 root 932:
933: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies
934:
935: rts
936:
1.1.1.5 ! root 937: ;
! 938:
! 939: ; _callout6 passes 6 words, saving sr
! 940:
! 941: ;
! 942:
! 943: _callout6:
! 944:
! 945: movem.l d2-d7/a2-a6,-(sp) ; save registers
! 946:
! 947: movem.l 4+44(sp),a0-a3 ; get function ptr & args
! 948:
! 949: move.w sr,-(sp)
! 950:
! 951: movem.l a1-a3,-(sp) ; copy args
! 952:
! 953: suba.l a5,a5 ; the BIOS expects 0 in a5
! 954:
! 955: jsr (a0) ; go do it
! 956:
! 957: lea 12(sp),sp
! 958:
! 959: move.w (sp)+,sr
! 960:
! 961: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies
! 962:
! 963: rts
! 964:
! 965: ;
! 966:
! 967: ; _callout6spl7 passes 6 words at ipl7
! 968:
! 969: ;
! 970:
! 971: _callout6spl7:
! 972:
! 973: movem.l d2-d7/a2-a6,-(sp) ; save registers
! 974:
! 975: movem.l 4+44(sp),a0-a3 ; get function ptr & args
! 976:
! 977: move.w sr,-(sp)
! 978:
! 979: movem.l a1-a3,-(sp) ; copy args
! 980:
! 981: suba.l a5,a5 ; the BIOS expects 0 in a5
! 982:
! 983: ori.w #$0700,sr ; spl7()
! 984:
! 985: jsr (a0) ; go do it
! 986:
! 987: lea 12(sp),sp
! 988:
! 989: move.w (sp)+,sr
! 990:
! 991: movem.l (sp)+,d2-d7/a2-a6 ; restore reggies
! 992:
! 993: rts
! 994:
1.1 root 995:
996:
1.1.1.2 root 997: ;
998:
999: ; do_usrcall: call the user supplied function (*usrcall)(), with
1000:
1001: ; arguments given in the longwords usrarg1..usrarg5. Return value
1002:
1003: ; is placed in usrret. This function is used by the Supexec code
1004:
1005: ; in xbios.c.
1006:
1007:
1008:
1009: XDEF _do_usrcall
1010:
1011: XREF _usrret
1012:
1013: XREF _usrcall
1014:
1015: XREF _usrarg1,_usrarg2,_usrarg3,_usrarg4,_usrarg5
1016:
1017:
1018:
1019: _do_usrcall:
1020:
1021: move.l _usrarg5,-(sp)
1022:
1023: move.l _usrarg4,-(sp)
1024:
1025: move.l _usrarg3,-(sp)
1026:
1027: move.l _usrarg2,-(sp)
1028:
1029: move.l _usrarg1,-(sp)
1030:
1031: move.l _usrcall,-(sp) ; the user expects to see this on the stack
1032:
1.1.1.3 root 1033: pea ucret(pc) ; so rts puts us back here
1.1.1.2 root 1034:
1035: move.l _usrcall,-(sp) ; this copy is for us to use
1036:
1037: rts ; to jump to (we don't want to use registers)
1038:
1039: ucret:
1040:
1.1.1.3 root 1041: lea 24(sp),sp ; fix up stack
1.1.1.2 root 1042:
1043: move.l d0,_usrret ; save returned value
1044:
1045: rts ; back to caller
1046:
1047:
1048:
1.1 root 1049: END
1050:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.