amiga-ixemul/ixnet/start.S

316 lines
9.1 KiB
ArmAsm

/*
* This file is part of ixnet.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
* Portions Copyright (C) 1994 Rafael W. Luebbert
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define START
#include "ixnet.h"
//#include "version.h" //the version is in ix_internals_backup.h.No autobuild is use to better work with cross compile
/* size of C_PRIVATE was generated by create_header.c */
/* include the generated header */
#include "ix_internals_backup.h"
.text
| The first executable location. This should return an error
| in case someone tried to run you as a program (instead of
| loading you as a library).
.globl Start | we use this to force inclusion of start.s
Start:
movel #-1,d0
obsolete: | use this for obsolete syscalls
rts
|-----------------------------------------------------------------------
| A romtag structure. Both "exec" and "ramlib" look for
| this structure to discover magic constants about you
| (such as where to start running you from...).
|-----------------------------------------------------------------------
initDDescrip:
|STRUCTURE RT,0
.word RTC_MATCHWORD | UWORD RT_MATCHWORD
.long initDDescrip | APTR RT_MATCHTAG
.long EndCode | APTR RT_ENDSKIP
.byte RTF_AUTOINIT | UBYTE RT_FLAGS
.byte IXNET_VERSION | UBYTE RT_VERSION
.byte NT_LIBRARY | UBYTE RT_TYPE
.byte IXNET_PRIORITY | BYTE RT_PRI
.long ixName | APTR RT_NAME
.long idString | APTR RT_IDSTRING
.long Init | APTR RT_INIT
| this is just fool proof, and this library will never make it to ROM
| anyway, so resident tags are not that important ;-)
EndCode:
| this is the name that the library will have
ixName: .asciz IXNET_NAME
| this is an identifier tag to help in supporting the library
| format is 'name version.revision (dd.mm.yy)',<cr>,<lf>,<null>'
| without any leading zeros in dd.mm.yy
idString:
.ascii IXNET_IDSTRING
.byte 13
.byte 10
.byte 0
| force word alignment
.even
| The romtag specified that we were "RTF_AUTOINIT". This means
| that the RT_INIT structure member points to one of these
| tables below. If the AUTOINIT bit was not set then RT_INIT
| would point to a routine to run.
Init:
.long IXNETBASE_SIZEOF | size of library base data space
.long funcTable | pointer to function initializers
.long dataTable | pointer to data initializers
.long initRoutine | routine to run
funcTable:
|------ standard system routines
.long Open
.long Close
.long Expunge
.long Null
#define _obsolete29 obsolete
#define _obsolete30 obsolete
#define _obsolete31 obsolete
#define _obsolete32 obsolete
#define _obsolete33 obsolete
#define _obsolete34 obsolete
#define _obsolete35 obsolete
#define _obsolete36 obsolete
#define _obsolete37 obsolete
#define _obsolete40 obsolete
#define _obsolete41 obsolete
#define _obsolete47 obsolete
#define _obsolete56 obsolete
#define _obsolete57 obsolete
#define _obsolete58 obsolete
#define _obsolete59 obsolete
#define _obsolete74 obsolete
#define _obsolete75 obsolete
#define _obsolete76 obsolete
#define _obsolete77 obsolete
#define _obsolete78 obsolete
#define _obsolete79 obsolete
#define _obsolete80 obsolete
#define _obsolete81 obsolete
#define _obsolete82 obsolete
#define _obsolete83 obsolete
#define _obsolete84 obsolete
#define _obsolete95 obsolete
#define _obsolete96 obsolete
#define _obsolete97 obsolete
#define _obsolete98 obsolete
#define _obsolete99 obsolete
#define _obsolete100 obsolete
#define _obsolete102 obsolete
|------ my libraries definitions
#define SYSTEM_CALL(func, vec) .long _/**/func
#include <sys/ixnet_syscall_68k.def>
#undef SYSTEM_CALL
|------ function table end marker
.long -1
| The data table initializes static data structures.
| The format is specified in exec/InitStruct routines
| manual pages. The INITBYTE/INITWORD/INITLONG routines
| are in the file "exec/initializers.i". The first argument
| is the offset from the library base for this byte/word/long.
| The second argument is the value to put in that cell.
| The table is null terminated
| NOTE - LN_TYPE below is a correction - old example had LH_TYPE
dataTable:
INITBYTE (LN_TYPE, NT_LIBRARY)
INITLONG (LN_NAME, ixName)
INITBYTE (IXNETBASE_FLAGS, 0x6) |LIBF_CHANGED_SUMUSED
INITWORD (IXNETBASE_VERSION, IXNET_VERSION)
INITWORD (IXNETBASE_REVISION, IXNET_REVISION)
INITLONG (IXNETBASE_IDSTRING, idString)
.long 0
| This routine gets called after the library has been allocated.
| The library pointer is in D0. The segment list is in A0.
| If it returns non-zero then the library will be linked into
| the library list.
initRoutine:
|------ get the library pointer into a convenient A register
movel a5,sp@-
movel d0,a5
|------ save a pointer to our loaded code
movel a0,a5@(IXNETBASE_SEGLIST)
|------ do the higher-level initialization in C
pea a5@
jbsr _ixnet_init
lea sp@(4),sp
movel sp@+,a5
rts
|----------------------------------------------------------------------
|
| here begins the system interface commands. When the user calls
| OpenLibrary/CloseLibrary/RemoveLibrary, this eventually gets translated
| into a call to the following routines (Open/Close/Expunge). Exec
| has already put our library pointer in A6 for us. Exec has turned
| off task switching while in these routines (via Forbid/Permit), so
| we should not take too long in them.
|
|----------------------------------------------------------------------
| Open returns the library pointer in d0 if the open
| was successful. If the open failed then null is returned.
| It might fail if we allocated memory on each open, or
| if only open application could have the library open
| at a time...
Open: | ( libptr:a6, version:d0 )
|------ mark us as having another opener
addqw #1,a6@(IXNETBASE_OPENCNT)
|------ prevent delayed expunges
| !!!!!!
| commo - example code uses private flags field (IXNETBASE_MYFLAGS), WHY????
| !!!!!!
bclr #LIBB_DELEXP,a6@(IXNETBASE_FLAGS)
|------ do other things in C
pea a6@
jbsr _ixnet_open
lea sp@(4),sp
beq OpenFailed
|--- ix_open() should return the library base, if all ok
rts
OpenFailed:
subqw #1,a6@(IXNETBASE_OPENCNT)
rts
| There are two different things that might be returned from
| the Close routine. If the library is no longer open and
| there is a delayed expunge then Close should return the
| segment list (as given to Init). Otherwise close should
| return NULL.
Close: | ( libptr:a6 )
|------ do any cleanups needed in C
pea a6@
jsr _ixnet_close
lea sp@(4),sp
|------ set the return value
clrl d0
|------ mark us as having one fewer openers
subqw #1,a6@(IXNETBASE_OPENCNT)
|------ see if there is anyone left with us open
bne L11
|------ see if we have a delayed expunge pending
btst #LIBB_DELEXP,a6@(IXNETBASE_FLAGS) | SEE ABOVE!
beq L11
|------ do the expunge
bsr Expunge
L11:
rts
| There are two different things that might be returned from
| the Expunge routine. If the library is no longer open
| then Expunge should return the segment list (as given to
| Init). Otherwise Expunge should set the delayed expunge
| flag and return NULL.
|
| One other important note: because Expunge is called from
| the memory allocator, it may NEVER Wait() or otherwise
| take long time to complete.
Expunge: | ( libptr: a6 )
moveml d2/a5/a6,sp@-
movel a6,a5
movel 4:w,a6
|------ see if anyone has us open
tstw a5@(IXNETBASE_OPENCNT)
beq L21
|------ it is still open. set the delayed expunge flag
bset #LIBB_DELEXP,a5@(IXNETBASE_FLAGS) | SEE ABOVE !!
clrl d0
bra Expunge_End
L21:
|------ go ahead and get rid of us. Store our seglist in d2
movel a5@(IXNETBASE_SEGLIST),d2
|------ unlink from library list
movel a5,a1
jsr a6@(_LVORemove)
|
| device specific closings here...
|
pea a5@
jsr _ixnet_expunge
lea sp@(4),sp
|------ free our memory
clrl d0
movel a5,a1
movew a5@(IXNETBASE_NEGSIZE),d0
subl d0,a1
addw a5@(IXNETBASE_POSSIZE),d0
jsr a6@(_LVOFreeMem)
|------ set up our return value
movel d2,d0
Expunge_End:
moveml sp@+,d2/a5/a6
rts
Null:
clrl d0
rts