/* * 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 #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)',,,' | 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 #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 #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