This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Functions with multiple long params

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();
  }
}

Here is the output from the serial port:
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!

Parents
  • Ths point is that Kevin states that:

    "The target is a 80C390, but I'm not
    running in contiguous mode (yet), just in the large memory model."

    So the C?LSTKXDATA is being emitted.


    OK, then what's the problem with the JMP @A+DPTR instruction in 16-bit mode?

    Jon

Reply
  • Ths point is that Kevin states that:

    "The target is a 80C390, but I'm not
    running in contiguous mode (yet), just in the large memory model."

    So the C?LSTKXDATA is being emitted.


    OK, then what's the problem with the JMP @A+DPTR instruction in 16-bit mode?

    Jon

Children
  • Here's a simple program with which Kevin can test the "jmp @a+dptr" instruction.

    File: Sub.c
    Options: Generate SRC, Assemble SRC

    void PseudoRet( void )
    {
      #pragma asm
        pop dph
        pop dpl
        clr a
        jmp @a+dptr
      #pragma endasm
    }
    

    File: Main.c
    #include <REG390.H>
    
    #include <stdio.h> 
    
    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 */
    }
    
    void PseudoRet( void );
    
    void main (void)
    {
      Serial0_Initialize();
      printf("Serial initialized!\n");
    
      PseudoRet();
      printf("Nope, this is not the problem.\n");
    
      while (1)
        ;
    }
    


  • By the way, if the user is optimizing for speed, the compiler can get massive speed/size impovements by not calling routines like C?LSTKXDATA.

  • OK, more information.

    I noticed that our HEX file loader in EPROM is leaving the processor in 22 bit paged mode before jumping to my program in flash.

    I.E.

     TA = 0xAA;  TA = 0x55; ACON = 1; 

    If I *force* 16 bit mode in the example program, it works fine.

    I.E.
     TA = 0xAA;  TA = 0x55; ACON = 0; 


    Now the question is, can 22 bit paged mode be used successfully with functions that require multiple long parameters? The Dallas spec says "This (mode) is transparent to standard 8051 compilers." (Except for instruction timing changes.)

    Until I get the HEX file loader re-written to accept the new format I'm stuck with using paged mode.