We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I've created a little test program that runs fine in the simulator, but causes the hardware (80C390) to reset when a function with multiple long parameters is called. This is with v6.22. Am I missing something obvious? Running in the large memory model in a new project (I.E. all other settings as defaults.)
#include <REG390.H> #include <absacc.h> #include <stdio.h> void wait (void) { /* wait function */ int i; for (i=0;i<20000;i++) { ; } } void Serial0_Initialize(void) { // init serial interface 38400 baud @ 20MHz PCON |= 0x80; /* Double serial port 0 baud rate */ SCON0 = 0x50; /* Async receiver serial port 0 enable */ TMOD |= 0x21; /* Timer 0 16 bits, Timer 1 8 bits with auto reload mode */ TH1 = 0xF8; /* Load MSB of Timer 1 */ CKCON |= 0x10; /* Timer 1 clock select divide by 4 of xtal freq */ TCON = 0x50; /* Timer 0 run enable, Timer 1 run enable */ TI = 1; /* Serial port 0 transmitter interrupt flag set */ } unsigned char xdata* egdBufferGetInt(int buffer, int width, int height, int depth) { unsigned char xdata *curBuf = 0; return curBuf; } unsigned char xdata* egdBufferGet(long buffer, long width, long height, long depth) { unsigned char xdata *curBuf = 0; return curBuf; } long egdDrawInt(unsigned char xdata *buffer, int width, int height) { ; } long egdDraw(unsigned char xdata *buffer, long width, long height) { ; } void main (void) { unsigned char xdata *b; // Initialize serial port 0 Serial0_Initialize(); printf("Serial initialized!\n"); wait(); printf("Trying BufferGetInt...\n"); b=egdBufferGetInt(0, 320, 240, 1); printf("BufferGetInt success\n"); wait(); printf("Trying BufferGet...\n"); b=egdBufferGet(0, 320, 240, 1); printf("BufferGet success\n"); wait(); printf("Trying Draw Int...\n"); egdDrawInt(b, 320, 240); printf("Draw Int success\n"); wait(); printf("Trying Draw...\n"); egdDraw(b, 320, 240); printf("Draw success\n"); wait(); while (1) { printf("Waiting...\n"); wait(); } }
Serial initialized! Trying BufferGetInt... BufferGetInt success Trying BufferGet... erial initialized! Trying BufferGetInt... BufferGetInt success Trying BufferGet... erial initialized! Trying BufferGetInt... BufferGetInt success Trying BufferGet... erial initialized! Trying BufferGetInt... BufferGetInt success Trying BufferGet... erial initialized!
One of the differences for the caller/callee of your functions with the long parameters as opposed to those with int parameters, is that the long versions pass the parms on the external memory "stack", whereas the int versions pass the parms in R0-R7. Are there any START390.A51 aspects that need to be configured for running on your target hardware that you are getting away with not configuring when simulating?
Possibly. (I'm new to the hardware.) However, I'm able to successfully call a function with 8 integer params, which should use the same amout of param space as 4 longs...
OK, interesting. The difference now is that the int version of the call uses MOVX @DPTR to directly store the parms into XRAM, whereas the the long version uses the library function ?C?LSTKXDATA, which pops the return address into DPTR, copies the constant parms out of the code memory locations that immediately follow the call, advancing DPTR along the way, then returns "through" the DPTR (i.e., JMP @A+DPTR) to the instruction immediately following the constant parms. I'm familiar with some Dallas MCU's, but not the '390. Aren't there some considerations for DPTR-related instructions when dealing with code memory? I wonder if something is slightly askew in this area.
There are a number of compiler warnings that are generated for your code. Make the following changes and let us know if it works on your hardware after that:
unsigned char xdata* egdBufferGetInt(int buffer, int width, int height, int depth) { unsigned char xdata *curBuf = 0; buffer = buffer; width = width; height = height; depth = depth; return curBuf; } unsigned char xdata* egdBufferGet(long buffer, long width, long height, long depth) { unsigned char xdata *curBuf = 0; buffer = buffer; width = width; height = height; depth = depth; return curBuf; } long egdDrawInt(unsigned char xdata *buffer, int width, int height) { buffer = buffer; width = width; height = height; ; return (0); } long egdDraw(unsigned char xdata *buffer, long width, long height) { buffer = buffer; width = width; height = height; ; return (0); }