6. Structure of a Compiled Program

PBC is designed to be easy to use. Programs can be compiled and run with little thought to PBC's internal workings. Some people, however, only have confidence in a product when they understand its internal workings. Others are just plain curious.

This section is for them. It describes the output generated by PBC and gives some idea of exactly what is going on.

6.1. Target (PICmicro) Specific Header (B##.INC)

The first thing a PBC generated program does is define the symbol PBCX to be 1 if PBC extensions are enabled, or 0 if PBC extensions are disabled (-C option). This allows the library to selectively define additional variables and functions needed for PBC extensions.

Next, a target specific header file is included. By default, this file is B16C84.INC, although this can be changed using the -P option.

This header is, in turn, responsible for including (via MACLIB) the processor specific header supplied with PM. The PM header, in turn, defines all the processor specific information needed to assemble programs for that PICmicro.

The B##.INC header then uses the DEVICE pseudo-op to set the processor's fuses. For NAP and SLEEP to work, the Watchdog Timer must be enabled. The oscillator must also be set appropriately. Other fuse positions can be set at the user's discretion. See the Microchip data sheet for the particular device for information about the configuration fuses.

The DATA pseudo-op is next used to select the data segment as the current segment. It should also place the load pointer at the base of usable RAM in the target processor. In the case of a PIC16Cxxx, this will either be 0Ch or 20h. Selecting one of these addresses is important because PBC's internal bit numbering scheme relies on selecting one of these two addresses.

The header should then execute NLIST to disable listing. This hides tedious, uninteresting and unchanging implementation details in PBH.INC.

Then PBH.INC is included. If desired, macro and bit addresses defined in PBH.INC can be overridden by being defined here.

When PBH.INC is done, listing is enabled and the code segment is selected. At this point, any target specific library routines should be added. Since these routines must be assembled before the user's code is assembled, they must assemble unconditionally (unlike the normal library routines). Hence, such target specific routines should be as brief as possible.

The last thing left to do is define the main label, which is where the user's code will start execution.

6.2. PBH.INC

PBH.INC first defines user variables in the data segment. This is followed by the definition of working and temporary registers used by PBC's libraries. User variables can occupy up to 80 bytes of memory unless the -C option is used, in which case only 14 bytes are used. Working variables and temporary registers occupy another 13-16 bytes.

PINx, DIRx, and other bit locations are numbered. All bits of interest (PORT, TRIS, and the bits of W0) need to be spanned by an 8-bit value in order to take best advantage of the W register. Since normal PICmicro numbering requires 11 bits, a custom system was developed. Its details are uninteresting, but it is important to understand that PBC bit numbers need to be converted before use and cannot be used verbatim in an assembly language subroutine.

A number of macros are defined. Some are simple utility macros. Some perform the bit mapping mentioned earlier. And some macros access the PINS and DIRS registers. These are particularly interesting since they can be overridden by definitions in B##.INC.

The code segment is then selected and startup code is generated. This is followed by a set mandatory library routines. The FW@Pin and FW@Mask functions are responsible for the run time mapping of PBC bit numbers onto the FSR and W registers.

6.3. PBC Generated Code

B##.INC and PBH.INC have now laid all the ground work for the compiled code. The code segment is the current segment and the load pointer is set to main, the place where the user's code begins execution.

After the user's code is assembled, PBC's library PBL.INC is included.

6.4. PBL.INC

PBL.INC contains library support routines. Most of the routines corresponding to PBC statements end in the '@' character. Block comments indicate each routine's functionality. Routines are ordered such that every routine in the library is only dependent on routines which occur later in the library. Each routine is conditionally assembled only if it is explicitly referenced (via the REF operator). In this way, only needed library routines are actually assembled.

The first module in PBL.INC is end@. Unlike other modules in the library, end@ is always assembled. This simulates the END statement implicitly at the end of each PBC program.