Startup.asm =========== $VER: Startup_asm 3.4 (5.9.95) Copyright © 1995, by Kenneth C. Nilsen. All rights reserved. The best startup code you find for assemblers. This source is free. Any kickstart (1.2+), any chip and configuration will do. WHY USE THIS CODE? ================== 1) It makes your programs safe from crashing on system that has lower processor configuration than you require. An error message is given and the program will exit without executing any of your code. 2) It prevents your program to crash if you start from Workbench/icon. 3) Expands your assembler with 10 more commands! 4) Very easy to open libraries. One line opens a library. Even error messages are given if any of the libraries can't be opened. 5) It enables easy argument parsing where one argument is given to you one by one. 6) Very easy to implement in your sources, just one include (itself). 7) Supports the 68060 processor (tested). 8) Source is completly safe. Contributed to the public domain by 12 years experience with programming. 9) You don't need any external includes to make this startup code work. 10) Learn how to deal with these situation by study the source. 11) Experiment with the source and make a startup code for your needs. 12) By using the internal NextArg macro you can have more UNIX like option command lines for your programs. The ReadArgs() function is limited in that manner. 13) Helps you setting the right return code at exit. 14) A demo program and source are following this archive. NEW FEATURES ============ 3.4: - Added macro. Use it like "Return 0" and it puts the return code in D0 and makes a RTS automatically. Added info to doc and startup example. Optimized some code. Added comments in the Startup.asm source! :) Added *n (newline) feature in argument parsing. Use this like: > Test "This is a test*nto see newline in *"qvotes*".". This will be: > This is a test > to see newline in "qvotes". Included a sample header source. 3.3beta: - Is now bug free! :) Only thing to change now is to read icon args/ tooltypes from Workbench due to a main release :) 3.2beta: - Added 68040 FPU options. Use: MathProc = 68881/68882 or 68040 to set FPU. 0=no FPU. BUG FIXES ========= 3.3beta: - an enforcer hit fixed (BYTE READ FROM 0). Occured when starting from icon with no argument. Never was dangerous, but still nice to have it all clean :) 3.2beta: - there was a bug testing for 68060. If you had a 040 with 040FPU this allowed you to run programs assembled for 060. - a bug where reported about the Version and TaskName macros. These work fine with AsmOne, but both DevPac and Barfly can not handle spaces between words even if they are in qvotes. Sorry, can not do something about this (I think) so write version strings manually and use TaskName with underscores instead of spaces... - an enforcer hit (BYTE READ FROM 0) where reported when started from workbench. Working on the problem, but no danger... :) 3.1beta: - Implemented an unfinished Startup.asm file in the 3.0 archive. - Expanded the NextArg macro to solve *" situations in arguments. - Added buffercount for output strings. This caused misunderstandings and people reported bugs. Not a bug, but not a good presentation :) (thanks to Eivind Olsen for reporting these bugs :) ) DOCUMENT OVERVIEW ================= Pre: - Why use this code? - New features - Bug fixes - Document overview - What is this? - How to use "Startup.asm" - Helping macros - Parsing arguments - Sections - Extras - Summary - Trouble shooting - Address - Source header example WHAT IS THIS? ============= For those of you who programs a lot this is a powerful aid in making your programs function saftly. You don't have to think about checking processor types, you don't have to open the libraries you need yourself, you don't have to think about giving error messages and you can run your program from both Shell and WORKBENCH. This is an include you should include first in all your sources. So, what's new about this startup include? * It opens all the libraries you need and give message if any error occurs on ALL libraries that would not open. * It checks the processor type for you so you wount run a 68020 program on a 68000 etc. * It checks your system for math-co-processor if you need that in your program. * Parse cli arguments one by one very easy, all done for you. * Enable/Disable icon startup while programming (eg. from AsmOne) * Need no includes to work. * Name your task in a very easy way at any time. * Easy accessing information about type of startup in your programs. * Easy defining libraries and requirements. * System-safe code. * Make xRef's and you can link it to c sources as well. * Highly optimized within legal conditions. * Short (about 1kb assembled) Future: * Read arguments from icons. * Self detaching startup from CLI (anyone got any code for this??) * Open devices? HOW TO USE THE "Startup.asm" ============================ You need to initialize 3 global values which describing what processors you need and how to run: 1) "StartSkip=", will be =0 when your program is finished. This enables you to run programs from icons as well as from CLI. 1 is made for those (like me) who programs in AsmOne. If you start your program from AsmOne it will do a WaitPort() forever. The "1" tells AsmOne to skip the WaitPort() and enable your program to start from AsmOne. This will also work with CLI startup, but not from WB so remember to set StartSkip to 0. 2) "Processor=", tells which processor you need. If any will do use "0" or "68000". If you don't use 0 you must define a known processor like: 68000, 68010, 68020, 68030, 68040 or 68060. Tip: Use =0 if you only need a 68000, this will be faster. 3) "MathProc=", will be defined if you need a FPU in your program. Initialize it with 0 if no FPU is needed, or define 68881 or 68882. If you define 68881 the 68882 will work as well. The same thing with the processor. If you have a "processor" or higher the program will work. If you have a 68040 with an FPU, use MathProc = 68040 instead. You can of course define these global values in the Startup.asm file if you always use the same setup or don't want the labels shown in your source. To set a condition to kickstarts you just have to request a library version for that kickstart, eg. DefLib dos,37 will require kick. 2.0 etc. See below. Nest step is to define the libraries you need to use. You must have the label "Init" first in your program. Do it like this: Init DefLib dos,37 ;remember to use small cases with library names! DefLib , ...and so on... DefEnd This part contains 2 macros: 1) DefLib, which defines the library and the version number. If the library cannot be opened you'll get a message about it. This is for every library you try to open, so it will not stop at the first error. Do NOT use any extensions, only the library name in LOWER cases. 2) DefEnd, This tells the startup code that you are finished with defining your init section. IMPORTANT: THE "DefEnd" MUST BE THE LAST ENTRY IN THE INIT IN ANY SITUATION OR THE STARTUP CODE MAY CRASH YOUR SYSTEM! It's also needed if you don't want any libraries opened. Just set: Init: DefEnd and you're safe! After the "DefEnd" macro, your program can start. You start with the label "Start". You can also put the Init: label in the Startup.asm file if you always opens the same libraries etc. Start: ...do ya thang... You now have the argument pointer in A0 and the length in D0. Now you can have the arguments seperated even if you start from an icon. See the NextArg macro how this is done. You don't need to preserve any registers on the stack. The startup code will do this for you. You must thow define a return code in D0 at the end of your program. This is now fixed for you by this macro: End: Return 0 where 0 is the return code. This macro also takes a RTS so you don't have to think about that. NOTE: The startup code and the rest of your function code must be in the same section. If you want to change this you have to remove the PC relatives in the macros in the "Startup.asm" file. The PC-rel. are made with the purpose to make the assembled file smaller. NOTE: If you use library versions bigger than 127, you have to alter the "Startup.asm" file in the macro "DefLib". Change the "moveq" to "move.l" (there is a little comment on that in the Startup.asm file). HELPING MACROS ============== 1) "StartFrom", returns true or false. If false (0) then your program where started from CLI else from Workbench: ## Example: StartFrom beq.b .fromCli ... 2) "LibBase ", gives you the library base in A6. Use it like this: Start: LibBase dos ... 3) "TaskName <"new task name">", will name your task with the name between the ""s. This macro is optional, but useful to prevent more than one of this task to run. You can use it at anytime in your code, but preferable as the first thing in the init list. Remember the qvotes (""). Init: TaskName "my_taskname" There seems to be a problem with DevPac and Barfly assemblers: you can not use spaces between the qvotes. If you get problems with this then use underscores. 4) "TaskPointer", will give you the task pointer to this task in d0. This macro does no library calls and it's only using the d0 register. The pointer to the task is stored internally in the startup code and processed by a library call at main startup. 5) "TaskPri", sets your taskpri like this: Init: TaskPri 1 6) "Return", will put a return code in D0 and make a RTS. Use it like this: End: Return 0 As you see, no need for RTS. See the Startup_example code to see how all this are done. PARSING ARGUMENTS ================= You can of course read the argument string in a0 your self or by the ReadArgs() function, but I have implemented a macro which makes this very easy: "NextArg" This macro read one argument from the argument string at a time. It cares about qvotes, tabs, spaces and asterix', so this one is good and fast! You read an argument with "NextArg" and d0 points to the argument text which is also null-terminated. If there are no more args d0 will be NULL. You get one argument at the time (you seperate args in the CLI ny spaces etc). In future this same macro will read tooltypes or icon arguments (if you started your task with a project icon which had your program as a default tool etc.) ## Example: Start: NextArg ;get first/next arg beq.w ArgEnd ;is (d0) null? then no more args move.l d0,a0 ;use pointer bsr.w CheckArg ;do something about it bra.b Start ;repeat ArgEnd ... ;no more args, continue code... Special argument functions: --------------------------- The argument parsing curently support 2 special situations: 1) If you want to use qvotes "" in your filename or argument 2) If you want to use newlines in your argument Lets call our program "Test". If you then type this: > test "This is a *"test*" to see qvotes *!" it will output like this: This is a "test" to see qvotes *! or type this: > test "This is a *"test*"*nto see qvotes *!" it will output: This is a "test" to see qvotes *! The asterix symbol is the sequence start. There is no problem to add more functions if wanted, just let me know. The *! is added so you can see that you can use the asterix in any other combinations if you want it as a symbol. This is also how you can do it with eg. the echo command. SECTIONS ======== For those who use sections in their programs: you may have to edit the macros a little. This is because I have used (PC) relatives in my code to make it faster and smaller. Anyway, if you do get problems while using sections just remove all the (PC) in the macros. I don't think it should be necessary to remove any other (PC) since those are used internally in the startup code, but I haven't tried this yet so I don't know. EXTRAS ====== In this archive you will also find another file called "Startup.i". This is just a very basic startup code which handles starts from Cli/Workbench. The only feature is that is allowing you to start your programs from icons. It does neither need any includes and it's consupt very little memory/place. To use this file you only need the "Start" label. incdir inc: include Startup.i Start movem.l d0-a6,-(sp) ;preserve registers ...your code... movem.l (sp)+,d0-a6 ;put registers back moveq #0,d0 ;return code rts In future I will expand this startup code so it may open devices as well, but that is just a thought. It will certantly get the argument feature added. The parse routine is finished, but I have to do some research on how to read the args. when started from a project icon for instant. Hm, if some of you guys/ girls has some info about that, then please let me know. I also need some info on how to self-detatch the code from eg. the cli. The cli argument parsing is finished thow (see "NextArg"). SUMMARY ======= Macros: DefEnd - Sets end of Init: section. *** ALWAYS REQUIRED *** ! DefLib - Defines the library name and version you want opened. Version - Init a version string to your binary (doesn't always work). TaskName - Sets a new name on your task (use underscores in name). TaskPri - Sets your task to a task priority. NextArg - D0 points to an extracted nullterminated argument. LibBase - Gives you the library base you ask for, in A6. StartFrom - Tells you if your program where started from CLI or WB. TaskPointer - Gives you the pointer to this taskstructure. Return - Gives a return code and exits. TROUBLE SHOOTING ================ DefLib You use lot of libraries (more than 17) and the machine crashes. SOLV: Edit the Startup.asm file and set the "zyxMax =" to a higher number. This buffer will be allocated (def: 204 bytes) by AllocMem(). Version You get assembler errors all the time about missing qvotes or similar. SOLV: Some assemblers (like DevPac and Barfly) doesn't tolerate spaces in macro arguments. In these cases it's smart not to use this macro. Edit a version string into your source manually. The "Version" suits for the version string to accompany the assembled program. With AsmOne this macro should not be a problem. TaskName You get the same problem as with the Version macro (see above). SOLV: Use underscores instead of spaces or compress the name like eg.: You want "My task", then use "My_task" or "MyTask" instead. If you find any bugs or have any decissions to come with, do not hasitate to write me. Currently I don't have an E-Mail, but please drop me a note at this address: Digital Surface Attn: Kenneth C. Nilsen Kvernhusrenen 31 N-5227 S-Neset (Norway). So, good luck and may your program work for ever! :) ------------------------------------------------------------------------------ Source header example: ------------------------------------------------------------------------------ Startskip = 0 ;0=WB/CLI, 1=CLI only Processor = 0 ;0 or 680x0 MathProc = 0 ;0 or 6888x/68040 Incdir "Includes:" Include "Startup.asm" Init: DefEnd Start: Close: Return 0 ------------------------------------------------------------------------------ This is all you need to get the startup code work! See the example source on how to take advantage of the features. ------------------------------------------------------------------------------