mirror of
https://frontier.innolan.net/github/amiga-ixemul.git
synced 2026-09-13 19:32:15 +00:00
376 lines
12 KiB
ArmAsm
376 lines
12 KiB
ArmAsm
/*
|
|
* This file is part of ixemul.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 <ixemul.h>
|
|
#include "version.h"
|
|
|
|
/* 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
|
|
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 IX_VERSION | UBYTE RT_VERSION
|
|
.byte NT_LIBRARY | UBYTE RT_TYPE
|
|
.byte IX_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 IX_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 IX_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 IXBASE_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 _libOpen
|
|
.long _libClose
|
|
.long _libExpunge
|
|
.long Null
|
|
|
|
|------ my libraries definitions
|
|
|
|
#define ___must_recompile27 ___must_recompile
|
|
#define ___must_recompile28 ___must_recompile
|
|
#define ___must_recompile29 ___must_recompile
|
|
#define ___must_recompile30 ___must_recompile
|
|
#define ___must_recompile31 ___must_recompile
|
|
#define ___must_recompile32 ___must_recompile
|
|
#define ___must_recompile33 ___must_recompile
|
|
#define ___must_recompile34 ___must_recompile
|
|
#define ___must_recompile215 ___must_recompile
|
|
#define ___must_recompile216 ___must_recompile
|
|
#define ___must_recompile217 ___must_recompile
|
|
#define ___must_recompile220 ___must_recompile
|
|
#define ___must_recompile221 ___must_recompile
|
|
#define ___must_recompile222 ___must_recompile
|
|
#define ___must_recompile223 ___must_recompile
|
|
#define ___must_recompile224 ___must_recompile
|
|
#define ___must_recompile226 ___must_recompile
|
|
#define ___must_recompile229 ___must_recompile
|
|
#define ___must_recompile235 ___must_recompile
|
|
#define ___must_recompile237 ___must_recompile
|
|
#define ___must_recompile239 ___must_recompile
|
|
#define ___must_recompile240 ___must_recompile
|
|
#define ___must_recompile241 ___must_recompile
|
|
#define ___must_recompile242 ___must_recompile
|
|
#define ___must_recompile243 ___must_recompile
|
|
#define ___must_recompile244 ___must_recompile
|
|
#define ___must_recompile253 ___must_recompile
|
|
#define ___must_recompile254 ___must_recompile
|
|
#define ___must_recompile255 ___must_recompile
|
|
#define ___must_recompile256 ___must_recompile
|
|
#define ___must_recompile259 ___must_recompile
|
|
#define ___must_recompile262 ___must_recompile
|
|
#define ___must_recompile267 ___must_recompile
|
|
#define ___must_recompile273 ___must_recompile
|
|
#define ___must_recompile274 ___must_recompile
|
|
#define ___must_recompile275 ___must_recompile
|
|
#define ___must_recompile277 ___must_recompile
|
|
#define ___must_recompile279 ___must_recompile
|
|
#define ___must_recompile386 ___must_recompile
|
|
#define ___must_recompile387 ___must_recompile
|
|
#define ___must_recompile388 ___must_recompile
|
|
#define ___must_recompile389 ___must_recompile
|
|
#define ___must_recompile390 ___must_recompile
|
|
#define ___must_recompile447 ___must_recompile
|
|
#define ___must_recompile448 ___must_recompile
|
|
#define ___must_recompile449 ___must_recompile
|
|
#define ___must_recompile450 ___must_recompile
|
|
#define ___must_recompile502 ___must_recompile
|
|
#define ___must_recompile503 ___must_recompile
|
|
#define ___must_recompile504 ___must_recompile
|
|
#define ___must_recompile505 ___must_recompile
|
|
#define ___must_recompile506 ___must_recompile
|
|
#define ___must_recompile507 ___must_recompile
|
|
#define ___must_recompile520 ___must_recompile
|
|
#define ___must_recompile521 ___must_recompile
|
|
#define ___must_recompile523 ___must_recompile
|
|
#define ___must_recompile524 ___must_recompile
|
|
#define ___must_recompile525 ___must_recompile
|
|
#define ___must_recompile526 ___must_recompile
|
|
#define ___must_recompile527 ___must_recompile
|
|
#define ___must_recompile528 ___must_recompile
|
|
#define ___must_recompile529 ___must_recompile
|
|
#define ___must_recompile530 ___must_recompile
|
|
#define ___must_recompile570 ___must_recompile
|
|
#define _setjmp_mos _setjmp
|
|
#define _sigsetjmp_mos _sigsetjmp
|
|
#define __setjmp_mos __setjmp
|
|
#define _mblen_mos _mblen
|
|
#define _mbstowcs_mos _mbstowcs
|
|
#define _mbtowc_mos _mbtowc
|
|
#define _wcstombs_mos _wcstombs
|
|
#define _wctomb_mos _wctomb
|
|
|
|
#ifdef TRACE_LIBRARY
|
|
#define SYSTEM_CALL(func, vec) .long trace_/**/func
|
|
#else
|
|
#define SYSTEM_CALL(func, vec) .long _/**/func
|
|
#endif
|
|
#include <sys/syscall_68k.def>
|
|
#undef SYSTEM_CALL
|
|
|
|
|------ function table end marker
|
|
.long -1
|
|
|
|
#ifdef TRACE_LIBRARY
|
|
|
|
# Make sure tracing doesn't clobber A1, as that will be used to return a
|
|
# pointer to a structure.
|
|
|
|
#define SYSTEM_CALL(func, vec) \
|
|
trace_/**/func: ; \
|
|
moveml d0/d1/a0/a1,sp@-; \
|
|
pea _/**/func; \
|
|
pea vec; \
|
|
jsr _trace_entry; \
|
|
lea sp@(8),sp; \
|
|
tstl d0; \
|
|
beq 1f; /* jump directly there */ \
|
|
moveml sp@+,d0/d1/a0/a1; \
|
|
/* in that case, trace_entry already provided the result */ \
|
|
movel sp@(-20),d0; \
|
|
rts; \
|
|
1: moveml sp@+,d0/d1/a0/a1; \
|
|
jmp _/**/func;
|
|
#include <sys/syscall_68k.def>
|
|
#undef SYSTEM_CALL
|
|
#endif
|
|
|
|
|
|
|
|
| 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 (IXBASE_FLAGS, 0x6) |LIBF_CHANGED_SUMUSED
|
|
INITWORD (IXBASE_VERSION, IX_VERSION)
|
|
INITWORD (IXBASE_REVISION, IX_REVISION)
|
|
INITLONG (IXBASE_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@(IXBASE_SEGLIST)
|
|
|
|
|------ do the higher-level initialization in C
|
|
|------ the ix_init_glue() function checks if the hardware is supported
|
|
|------ (using 68000 instructions only) and if so will call ix_init()
|
|
|------ for the main initialization.
|
|
pea a5@
|
|
jsr _ix_init_glue
|
|
addqw #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...
|
|
|
|
_libOpen: | ( libptr:a6, version:d0 )
|
|
|
|
|
|
|------ mark us as having another opener
|
|
addqw #1,a6@(IXBASE_OPENCNT)
|
|
|
|
|------ prevent delayed expunges
|
|
| !!!!!!
|
|
| commo - example code uses private flags field (IXBASE_MYFLAGS), WHY????
|
|
| !!!!!!
|
|
bclr #LIBB_DELEXP,a6@(IXBASE_FLAGS)
|
|
|
|
|------ do other things in C
|
|
pea a6@
|
|
jsr _ix_open
|
|
addqw #4,sp
|
|
beq OpenFailed
|
|
|--- ix_open() should return the library base, if all ok
|
|
|
|
rts
|
|
|
|
OpenFailed:
|
|
subqw #1,a6@(IXBASE_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.
|
|
|
|
_libClose: | ( libptr:a6 )
|
|
|
|
|------ do any cleanups needed in C
|
|
pea a6@
|
|
jsr _ix_close
|
|
addqw #4,sp
|
|
|
|
|------ mark us as having one fewer openers
|
|
subqw #1,a6@(IXBASE_OPENCNT)
|
|
|
|
|------ see if there is anyone left with us open
|
|
bne Null
|
|
|
|
|------ see if we have a delayed expunge pending
|
|
btst #LIBB_DELEXP,a6@(IXBASE_FLAGS) | SEE ABOVE!
|
|
bne _libExpunge
|
|
|
|
| reserved entry
|
|
|
|
Null:
|
|
moveq #0,d0
|
|
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.
|
|
|
|
_libExpunge: | ( libptr: a6 )
|
|
moveml a2/a5/a6,sp@-
|
|
movel a6,a5
|
|
|
|
|------ assume we can't expunge
|
|
subal a2,a2
|
|
bset #LIBB_DELEXP,a5@(IXBASE_FLAGS) | SEE ABOVE !!
|
|
|
|
|------ see if anyone has us open
|
|
tstw a5@(IXBASE_OPENCNT)
|
|
bne L21
|
|
|
|
|------ go ahead and get rid of us. Store our seglist in a2
|
|
movel a5@(IXBASE_SEGLIST),a2
|
|
movel 4:w,a6
|
|
|
|
|------ unlink from library list
|
|
movel a5,a1
|
|
jsr a6@(_LVORemove)
|
|
|
|
|
|
|
| device specific closings here...
|
|
|
|
|
pea a5@
|
|
jsr _ix_expunge
|
|
addqw #4,sp
|
|
|
|
|------ free our memory
|
|
movel a5,a1
|
|
moveq #0,d0
|
|
movew a5@(IXBASE_NEGSIZE),d0
|
|
subl d0,a1
|
|
addw a5@(IXBASE_POSSIZE),d0
|
|
jsr a6@(_LVOFreeMem)
|
|
|
|
L21: |------ set up our return value
|
|
movel a2,d0
|
|
|
|
moveml sp@+,a2/a5/a6
|
|
rts
|