This file is about how to do coding for EmuTOS and to use what coding
styles. It is far from being complete (my most loved sentence!):

Rules for the format of source files
====================================

In order to avoid trouble with Git when using several text editors,
please do 'make gitready' before committing files. This will ensure that:

- all non-binary files are in Unix Line ending convention

- no hard TABs are present in source files (.c, .h and .S)

However, for 'make gitready' to work correctly, please make sure that:

- if you use TABs in your editor, set them to 8 spaces.

- To help the tool determining which file is non-binary, make sure that
  no non-printable ISO latin 1 characters are in text files.

- use \t instead of TABs in strings ("example") and quoted ascii
  chars ('!'), especially in strings marked for translation _("...")


Rules for C coding
==================

Well, at first these are not much. If you have any recommendations, just
write them in here, and we can discuss it later.

- use an indention of 4 spaces for all things.

- try to avoid source code that generates warnings when compiled using
  gcc -Wall

- avoid source code that generates warnings when passed through GNU indent.

The tool GNU indent is run as an option. Doing 'make checkindent' will run
indent on all C source files, and only check for warnings (it will not
alter the files). Doing 'make indent' will alter the files, unless for
those file which cause warnings. Typically:

- avoid comments in the form /**/ or /*UPPERCASE*/  (indent generates
  bad input when finding such comments)

- instead of 'a =& routine;' do 'a = &routine;'  (indent complains
  about old syntax '=&' for '&=')

- avoid cpp tricks that do not respect brace balancing, like:

  instead of     please do    |  instead of     please do
                              |
  if( a &&    |  if( a        |  foo_t a = {  | foo_t a = {
  #if FOO     |  #if FOO      |    1,         |   1,
      foo )   |     && foo    |  #if FOO      | #if FOO
  #else       |  #else        |    2};        |   2,
      bar )   |     && bar    |  #else        | #else
  #endif      |  #endif       |    4};        |   4,
     ...      |    ) ...      |  #endif       | #endif
              |               |               | };

Also, when in doubt please refer to the file doc/old_code.txt, which
contains a summary of bugs linked to old C code and ways to fix them.

Rules for assembler coding
==========================

As a general rule, try to ensure that external functions and
variables can be accessed from C language. To achieve this:
- name external symbols with a leading underscore;
- make sure external functions use CDECL conventions
  o parameters passed on the stack,
  o registers saved except d0-d1/a0-a1,
  o return value in d0

When the TOS specifications or efficiency considerations
impose that a routine have special register-parameters
conventions, name this routine with no underscore and try
to make a C glue for it using CDECL, like in the following
example:

  _my_routine:
    move.w 4(sp),d0
    move.w 6(sp),d1
  my_routine:
    ...
    rts

(where C code would call my_routine(a,b), and asm code would
pass parameters in D0 and D1)

Exceptions to the 'underscore leading' rule are:
- routines and variables that can only be used from assembler,
  and whose addresses need not to be manipulated by C code.
  example is the memory configuration routines.
  Note: the exception routines will never be *called* by C code,
  however they will be *accessed* by C code copying their address
  into the vector.
- addresses used to represent the names of fields in a structure.
  example:

    _struct_a:
    structamemberx:  dc.l 1
    structamembery:  dc.l 1

  accompanied by the following header:

    extern struct {
      long x;
      long y;
    } struct_a;


Use 68000-only instructions and addressing modes. If for some reason
you need 680X0 intructions not present on the 68000, code them using
dc.w/dc.l and put the 680x0 mnemonics in a comment. Example:

  dc.l    0x4e7b0002      // movec   d0,cacr

To reduce the possibility of mistakes, there are now macros that will
generate dc.w/dc.l statements for some of the commonly-used 680x0
mnemonics: see asmdefs.h for specifics.

Do NOT use movem.w to save/restore registers, as the upper 16 bits
of the registers will be clobbered upon restoring. Always use
movem.l instead.


See also
========

- the notice on processor-specific support in bios/processor.h
