File:  [Atari MiNT] / MiNT / src / gas / syscall.s
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:55:36 2018 UTC (8 years, 1 month ago) by root
Branches: mint, MAIN
CVS tags: mint095, HEAD
MiNT 0.95 pl13

|

| syscall: interface for system calls. The following entry points are

|    defined:

| _mint_bios:  entry point for the BIOS calls (trap #13)

| _mint_xbios: entry point for XBIOS calls (trap #14)

| _mint_dos:   entry point for GEMDOS calls (trap #1)

| _sig_return: user signal handlers return to this routine (see signal.c)

|              it is responsible for restoring the kernel's old context

|              via the Psigreturn() system call

| _lineA0:     calls the line A initialize routine

| _call_aes:   calls the GEM AES

| _callout:    call an external function, after first making sure that all

|              registers are saved

|

| external variables referenced:

| _bios_tab, _bios_max:

|    table of entry points for BIOS routines, max # of routine

| _xbios_tab, _xbios_max:

|    ditto for XBIOS

| _dos_tab, _dos_max:

|    ditto for GEMDOS

| _curproc:

|    pointer to current process table entry, and hence to save area for

|    context (this is always the first entry in the PROC table).

| _valid_return:

|    used to indicate to the kernel that a valid return from user mode

|    is taking place

|

| _bconbuf, _bconbsiz, _bconbdev:

|    256 byte buffer for Bconout() output. If _bconbsiz is non-zero,

|    there are that many bytes in _bconbuf waiting to be flushed. The

|    output is for device _bconbdev.

|

| The C function enter_kernel() is called on entry to the kernel, and the

| function leave_kernel() is called on exit. These functions are responsible

| for saving and restoring the various trap vectors, so that MiNT can trap

| out to TOS directly, but programs can only trap to MiNT.

|

	.globl  _mint_bios, _mint_xbios

	.globl	_mint_dos

	.globl	_build_context

	.globl	_restore_context



	.globl	_curproc

	.globl	_bios_tab, _bios_max

	.globl  _xbios_tab, _xbios_max

	.globl	_dos_tab, _dos_max

	.globl	_bconbuf, _bconbsiz, _bconbdev

	.globl	_bflush



	.data

	.comm	syscall_tab, 4		| set to which table to use for the call

	.comm	syscall_max, 4		| maximum valid number for this call



	.text

	.even



_mint_dos:

	movel	#_dos_tab, syscall_tab

	movew	_dos_max, syscall_max

	bra	_syscall



_mint_xbios:

	movel	#_xbios_tab, syscall_tab

	movew	_xbios_max, syscall_max

	bra	_syscall



_mint_bios:

|

| Bconout() is noticeably slower under MiNT, so we do a bit of a kludge

| and special case Bconout() so that it doesn't take so long. We

| do this by buffering Bconout calls until either another kind of

| system call or a context switch happens.

|

	tstw	_bconbdev		| buffering on?

	bmi	L_bios			| if bconbdev < 0, no buffering

	btst	#13, sp@		| test for user/super mode

	beq	L_usr			| 

	lea	sp@(6), a1		| supervisor mode: args on stack

	tstw	0x59e			| test longframe

	beq	L_check

	addql	#2, a1			| stack is a bit bigger

	bra	L_check

L_usr:

	movel	usp, a1			| user mode: args on user stack

L_check:

	movew	a1@, d0			| check command

	cmpw	#3, d0			| Bconout?

	beq	do_bconout		| yes -- take some shortcuts

					| no -- fall through to the normal code

L_bios:

	movel	#_bios_tab, syscall_tab

	movew	_bios_max, syscall_max



_syscall:

	movel	_curproc, d0

	addql	#4, d0

	movel	d0, sp@-		| push pointer to syscall context save

	jsr	_build_context

|

| copy parameters onto process stack. a1 was set by _build_context

|

L_copy:

	movel	_curproc, a0

	movel	a0@, a0			| fetch system call stack pointer

	lea	a0@(-28), sp		| this puts us in our private stack

	moveml	a1@, d1-d7		| copy parameters from user stack

	moveml	d1-d7, sp@		| to ours (build_context set a1)

|

	jsr	_enter_kernel		| set up vectors appropriately

|

| check here to see if we need to flush the Bconout() buffers

|

	tstw	_bconbsiz		| characters in buffer?

	beq	L_noflush		| nope: OK to proceed

|

| make sure we save syscall_tab and syscall_max

|

	movel	syscall_tab, sp@-

	movew	syscall_max, sp@-

	jsr	_bflush			| flush the buffer

	movew	sp@+, syscall_max

	movel	sp@+, syscall_tab



L_noflush:

|

| figure out which routine to call

|

	clrl	d0

	movew	sp@, d0

	cmpw	#-1, d0			| trapping with -1 means return

	bne	check_max		| the corresponding system table

	movel	syscall_tab, d0

	bra	out

check_max:

	cmpw	syscall_max, d0

	bge	error

	addl	d0,d0

	addl	d0,d0			| multiply by 4

	movel	syscall_tab, a0

	addl	d0, a0

	movel	a0@, a0

	cmpl	#0, a0			| null entry means invalid call

	beq	error

	addql	#2, sp			| pop function number off stack

	jsr	a0@			| go do the call

out:

	movel	_curproc, a0

	movel	d0, a0@(4)		| set d0 in the saved context

	tstw	_proc_clock		| has process exceeded time slice?

	bne	nosleep			| no -- continue

	movew	a0@(68), d0		| get saved status register

	btst	#13, d0			| caller in supervisor mode?

	bne	nosleep			| yes -- don't interrupt

sleep:

	jsr	_preempt		| does a sleep(READY_Q)

nosleep:

	oriw	#0x0700, sr		| spl7()

	jsr	_leave_kernel		| restore vectors

	movel	_curproc, a0

	pea	a0@(4)

	jsr	_restore_context	| never returns



|

| we handle errors by calling through to GEMDOS or the BIOS/XBIOS,

| as appropriate, and letting them handle it -- that way, if the underlying

| system has functions we don't know about, they still work

|



error:

	movel	syscall_tab, a0

	cmpl	#_xbios_tab, a0

	bne	maybe_dos

	trap	#14

	bra	out

maybe_dos:

	cmpl	#_dos_tab, a0

	beq	trap_1

	trap	#13

	bra	out

trap_1:

	trap	#1

	bra	out



|

| sig_return: user signal handlers return to us. At that point, the

| stack looks like this:

|    (sp)      (long) signal number -- was a parameter for user routine

|

	.globl	_sig_return

	.globl	_valid_return

_sig_return:

	addql	#4, sp			| pop signal number

	movew	#0x11a, sp@-		| Psigreturn() system call

	movew	#1, _valid_return	| tell kernel it's us!

	trap	#1

| we had better not come back; if we did, something terrible

| happened, and we might as well terminate

	movew	#-998, sp@-

	movew	#0x4c, sp@-		| Pterm()

	trap	#1



|

| bconout special code: on entry, a1 points to the stack the user

| was using. If possible, we just buffer the output until later.

|



do_bconout:

	movew	a1@(2), d0		| what device is this for?

	beq	L_bios			| don't buffer the printer

	cmpw	_bconbdev, d0		| same device as is buffered?

	bne	new_dev			| no -- maybe we can't do this

put_buf:

	movew	a1@(4), d0		| get the character to output

	movew	_bconbsiz, d1		| get index into buffer table

	cmpw	#255, d1		| buffer full?

	beq	L_bios			| yes -- flush it out

	lea	_bconbuf, a0

	addw	d1, a0

	moveb	d0, a0@			| store the character

	addqw	#1, d1

	movew	d1, _bconbsiz

	moveql	#-1, d0			| return character output OK

	rte



new_dev:

	tstw	_bconbsiz		| characters already in buffer?

	bne	L_bios			| yes: we can't buffer this one

	movew	d0, _bconbdev		| no: OK, we have a new device

	bra	put_buf

|

|

| _lineA0: MiNT calls this to get the address of the line A variables

|

	.globl	_lineA0

_lineA0:

	moveml	d2/a2, sp@-	| save scratch registers

	.word	0xa000		| call the line A initialization routine

	moveml	sp@+, d2/a2

	rts



|

| _call_aes: calls the GEM AES, using the control block passed as

|            a parameter. Used only for doing appl_init(), to see

|	     if the AES is active yet

|

	.globl	_call_aes

_call_aes:

	movel	sp@(4), d1	| fetch pointer to parameter block

	movew	#0xc8, d0	| magic number for AES

	moveml	d2/a2, sp@-	| save scratch registers

	trap	#2

	moveml	sp@+, d2/a2

	rts





|

| _callout: Call an external function, passing <32 bytes of arguments,

| and return the value from the function. NOTE: we must be careful

| to save all registers here!

|

	.globl	_callout

_callout:

	lea	sp@(8), a0		| pointer to args

	movel	sp@(4), a1		| pointer to function

	moveml	d2-d7/a2-a6, sp@-	| save registers

	moveml	a0@, d0-d7		| copy parameters

	lea	sp@(-32), sp		| NOTE: moveml auto-decrement

	moveml	d0-d7, sp@		|    changes the order of things

	movel	a1@, a0			| get function address

	jsr	a0@			| go do it

	addl	#32, sp

	moveml	sp@+, d2-d7/a2-a6	| restore reggies

	rts


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.