> How do the Compilers handle the various ports and functions within the PICs? > I would guess the true "C" way of doing things would be to write a library > (in Assembler?) and then call it from the main program. That would be a common method. I think the preferred method of handling things like integer math in C would be to have a couple registers reserved as an "integer accumulator" and have functions like [add int acc. to memory pointed to by FSR/W [function would have two entry points; the first would start with "MOVWF FSR" and fall through to the second]. For expressions which need more than one integer accumulator, turn the others into local variables [see below] > With regards to functions, how does the compiler pass arguements back and > forth? This is a huge question because there is also the problem of > pointers and structures based on the pointer. Non of the PICs have a stack > pointer, so the > passing of data can be tedious/dangerous (in terms of getting overwritten). Preferred approach I've seen on micro compilers is to have functions' argu- ments allocated statically using a call-graph to overlay variables [e.g. if function main calls foo and bar, neither of which calls each other, and all three functions have two byte-variables named main_i, main_j, foo_i, foo_j, bar_i, and bar_j, then a total of four bytes need to be allocated: one each for main_i and main_j, one shared between foo_i and bar_i, and one shared between foo_j and bar_j. Note that on many compilers the variables for a function must be located sequentially; this sometimes limits what the linker can do with allocation. For something like a PIC, it would be better if a compiler/linker could sub- divide functions into zones depending upon which variables were alive/dead, but I don't know if any do. Parameters on such compilers are defined as local variables, and are written to directly by the calling procedure. A variable argument list is defined as an array of char [of compiler-option-settable length] which is filled in by the calling procedure. > Are reenterant functions allowed? Generally not. > How are Interrupt Handlers handled? I know from personal experience that > there is more to an Interrupt Handler than just having the code starting at > address 4 and ending with a "retfie". How is the status and w registers > handled? Pretty much as you'd expect; the compiler creates standard prologue/epilogue code. For the PIC, you may get lucky and have a compiler skip, e.g., the saving of the status register, if nothing in the code affects status. I'd not expect such a thing, however; if your interrupt procedure consists only of, e.g., incrementing a counter I'd expect the compiler to generate [nb: code to reset cause of interrupt elided: .org 4 movwf WSAV swapf STATUS mofwf SSAV incfsz Timer goto $+2 incf Timer+1 swapf SSAV,w movwf STATUS swapf WSAV movf WSAV,w retfie rather than the [shorter and faster] .org 4 incfsz Timer goto $+3 incfsz Timer+1 nop retfie > And lastly, what type of data types are available and how are they > manipulated by the language? I would expect the space used for anything > greater than 8 bits to be a problem because of the space required for the > operation. Any decent micro compiler will support at least 16 bits decently [a 16-bit add translates as: movf Source,w addwf Dest btfsc C incf Dest+1 movf Source+1,w addwf Dest+1 [Saves time: 6 instructions; 6 cycles] or possibly as: movlw Source ;[address of] call Load16 movlw Dest call Add16f Load16: movwf FSR movf IND,w movwf AccL incf FSR movf IND,w movwf ACCH return Add16: movwf FSR movf IND,w addwf AccL btfsc C incf AccH incf FSR movf IND,w addwf AccH return [Saves code if many adds are used: 4 instructions per add; 24 cycles execution]