[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

One sure fire way to write incompatible software is to fail to follow the
Amiga programming guidelines listed in the beginning of your Amiga ROM
Kernel and Amiga Hardware manuals.  Please read the guidelines and follow
them!

The following improper Amiga programming practices are likely to fail on
new ROMs or hardware:

* Calling ROM code directly.

* Directly or indirectly reading or writing random memory addresses or
  low memory (especially location zero) due to improperly initialized
  pointers or structures.  Use Mungwall and Enforcer when writing and
  testing your code!

* Assuming addresses/location/amounts of RAM or system structures.

* Requiring all free RAM.

* Mishandling 32-bit addresses.  For example, using signed math or
  signed comparisons on addresses, or doing a BOOL or WORD test to
  determine if a pointer is non-zero.

* Overwriting memory allocations.  With 32-bit addresses, a 1-byte
  overwrite of a string array can wipe out the high byte of a pointer or
  stack return address.  This bug could go unnoticed on a 24-bit address
  machine (eg. A500,A2500, etc) but crash the system or cause other
  problems on an A3000.

* Shaving stack size too close.  System function stack usage changes
  with each OS release. o Improper flags or garbage in system structures.
  A bit that means nothing under one OS may drastically change the
  behavior of a function in a newer version of the OS.  Clear structures
  before using, and use correct flags.

* Passing garbage in previously unused upper bytes of function arguments
  (for example-the upper word of the ULONG AvailFonts() Flags parameter).

* Improper register or condition code handling.  Do not assume registers
  D0-D1/A0-A1 are preserved after system calls!  Some function calls
  happen to preserve some registers.  This can change in any revisions of
  the OS.  In some cases we have modifed the values returned in registers
  to keep certain applications from failing under 2.0.  We do not
  guarantee those modifications will remain in place.  Condition codes are
  also in an undefined state on the return from a system call.  Assembler
  code must test (TST,MOVE,CMP,etc.) D0 results before branching on
  condition codes.  Use Scratch by Bill Hawes (via the scratchall script)
  to catch scratch register misuse in assembler code.

* Misuse of function return values.  Use function prototypes and read
  the Autodocs for the functions you are using.  Some system functions
  return just success or failure, or nothing at all (void).  In such
  cases, the value which the function happens to return must not be used
  except as it is documented.

* Calling system library functions from assembler without placing the
  library base pointer in A6.  All system functions may assume that their
  library's base pointer is in A6.  A function's need to reference its
  library base can change in different OS revisions.

* Depending on unsupported side effects or undocumented behavior.  Be
  sure to read the RKM chapters, Autodocs, and include file comments.

* Poking/peeking system private structures.  Do not poke or peek any
  system structure unless told to do so in official Commodore
  documentation.

* Assuming current choices, configurations or initial values.  If the
  current possibilities are A, B, or C, do not assume C if it isn't A or
  B.  Check specifically for the choices currently implemented, and
  provide default behavior for unexpected values.

* Failure to properly allocate resources before using them.

* Failure to properly close/deallocate resources.

* Improper reading/writing of hardware registers.  You must mask out
  bits you are not interested in on reads, and write undefined bits as
  zero.

* Assuming initial values of hardware registers.  If you are going
  direct to the hardware, do not depend on the initial values of any
  hardware registers. The settings may not be the same on different
  versions of the OS or from boot to boot.  Always set up all of the
  hardware registers that affect your code. o Processor speed dependencies
  such as software delay loops.

* Processor instruction dependencies.  Do not use instructions which are
  privileged on any Motorola 68xxx family processor.  Do not use CLR on a
  hardware register which is triggered by any access (use MOVE #0
  instead). The 68000 CLR instruction performs two accesses (Read, then
  Write).  The 68020 and higher CLR instruction performs just one access.

* Depending on or failing to account for cache or prefetch effects.
  Self-modifying or trackdisk-loaded code requires cache flushes ( see the
  exec.library/CacheClearU() function ).

Amiga debugging tools such as Enforcer, Mungwall, and Scratch can find
many program bugs that may affect compatibility.  A program that is
Enforcer/Mungwall/Scratch clean stands a much better chance of working
well under current and future versions of the OS.  These tools are on the
Denver/Milano DevCon disks.  Enforcer and Mungwall are also on the
kickfile disks.