For correct execution of C code, the compiler makes a number of assumptions about the state of the MAXQ processor during program execution. It does this both to reduce code size and increase execution speed, usually you won't need to be aware of what assumptions the C compiler makes. However, if you are interfacing C code to assembly language subroutines, or calling C code from your own assembly language subroutines, you must be aware of the following points.
The control registers APC and DPC should always be set in the following modes for correct execution of C programs:
In particular, note that if you call a C subroutine from assembly code, you must ensure that both APC and DPC must be set as above before making the call to the function.
CrossWorks uses the accumulator A[8] as a soft stack pointer. A[8] is a word-based pointer into data memory for creating stack frames in memory. The soft stack descends from high to low memory. On function entry, A[8] is the word address of the lowest used word in the stack frame.
If you intend to call C code from a hand-written assembly code interrupt service routine, you must first ensure that you drop A[8] by at least 16 words. This is because there can be up to 16 words of valid data below A[8] as a consequence of normal code generation. Thus, your interrupt service routine must look something like this:
ISR: push PSF ; save processor state push APC push DPC move APC, #0 ; APC.0 = APC.1 = 0 move DPC, #18H ; DPC.2 = 0; DPC.3 = DPC.4 = 1 move AP, #8 ; point to A[8] sub #16 ; A[8] = A[8]-16 call _c_func ; call C code move AP, #8 ; point to A[8] add #16 ; restore A[8] pop DPC ; restore processor state pop APC pop PSF reti