8.4 Coding Example

This section shows an example of an actual startup program created for the simulator in the integrated development environment when the RX610 is selected as the CPU type.

(1)

Source Files

The startup program consists of the files shown in table 7.4.

Table 8.5

List of Programs Created in Integrated Development Environment

 

File Name

Description

(a)

resetprg.c

Initial setting routine (reset vector function)

(b)

intprg.c

Vector function definitions

(c)

vecttbl.c

Fixed vector table *1

(d)

dbsct.c

Section initialization processing (table)

(e)

lowsrc.c

Low-level interface routine (C language part)

(f)

lowlvl.src

Low-level interface routine (assembly language part)

(g)

sbrk.c

Low-level interface routine (sbrk function)

(h)

typedefine.h

Type definition header

(i)

vect.h

Vector function header

(j)

stacksct.h

Stack size settings

(k)

lowsrc.h

Low-level interface routine (C language header)

(l)

sbrk.h

Low-level interface routine (sbrk function header)

Notes 1.

This is for the RXv1 instruction-set architecture.
For an RX instruction-set architecture other than the RXv1 instruction-set architecture, this becomes the "exception vector table".

 

The following shows the contents of files (a) to (l).

(a)

resetprg.c: Initial Setting Routine (Reset Vector Function)

#include machine.h>
#include <_h_c_lib.h>
//#include <stddef.h>     // Remove the comment when you use errno
//#include <stdlib.h>     // Remove the comment when you use rand()
#include "typedefine.h"   // Define Types
#include "stacksct.h"     // Stack Sizes (Interrupt and User)
 
#ifdef __cplusplus        // For Use Reset vector
extern "C" {
#endif
void PowerOn_Reset_PC(void);
void main(void);
#ifdef __cplusplus
}
#endif
 
#ifdef __cplusplus        // For Use SIM I/O
extern "C" {
#endif
extern void _INIT_IOLIB(void);
extern void _CLOSEALL(void);
#ifdef __cplusplus
}
#endif
 
#define PSW_init       0x00010000  // PSW bit pattern
#define FPSW_DPSW_init 0x00000000  // FPSW/DPSW bit base pattern
 
//extern void srand(_UINT);   // Remove the comment when you use rand()
//extern _SBYTE *_s1ptr;      // Remove the comment when you use strtok()
 
//#ifdef __cplusplus          // Use Hardware Setup
//extern "C" {
//#endif
//extern void HardwareSetup(void);
//#ifdef __cplusplus
//}
//#endif
 
//#ifdef __cplusplus		         // Remove the comment when you use global class object
//extern "C" {               // Sections C$INIT and C$END will be generated
//#endif
//extern void _CALL_INIT(void);
//extern void _CALL_END(void);
//#ifdef __cplusplus
//}
//#endif
 
#pragma section ResetPRG     // output PowerOn_Reset_PC to PResetPRG section
 
#pragma entry PowerOn_Reset_PC
 
void PowerOn_Reset_PC(void)
{
#if (__RX_ISA_VERSION__ >= 2) || defined(__RXV2)
   set_extb(__sectop(”EXCEPTVECT”)); // Remove the comment when you want to set an address
                                    // into the Exception Vector Table Register of RXv2 or later
#endif
    set_intb(__sectop("C$VECT"));
#ifdef __FPU
#ifdef __ROZ                // Initialize FPSW/DPSW
#define _ROUND 0x00000001   // Let FPSW/DPSW RM/DRM bits=01 (round to zero)
#else
#define _ROUND 0x00000000   // Let FPSW/DPSW RM/DRM bits=00 (round to nearest)
#endif
#ifdef __DOFF
#define _DENOM 0x00000100   // Let FPSW/DPSW DN/DDN bit=1 (denormal as zero)
#else
#define _DENOM 0x00000000   // Let FPSW/DPSW DN/DDN bit=0 (denormal as is)
#endif
    set_fpsw(FPSW_DPSW_init | _ROUND | _DENOM);
#ifdef __DPFPU
     __set_dpsw(FPSW_DPSW_init | _ROUND | _DENOM);
#endif
#endif
 
_INITSCT();                // Initialize Sections
 
_INIT_IOLIB();             // Use SIM I/O
 
//errno=0;                 // Remove the comment when you use errno
//srand((_UINT)1);         // Remove the comment when you use rand()
//_s1ptr=NULL;             // Remove the comment when you use strtok()
 
//HardwareSetup();         // Use Hardware Setup
 
//_CALL_INIT();            // Remove the comment when you use global class object
 
set_psw(PSW_init);         // Set Ubit & Ibit for PSW
//chg_pmusr();             // Remove the comment when you need to change PSW 
// PMbit (SuperVisor->User)
 
main();
 
_CLOSEALL();               // Use SIM I/O
 
//_CALL_END();             // Remove the comment when you use global class 
// object
 
brk();
}

 

(b)

intprg.c: Vector Function Definitions

#include <machine.h>
#include "vect.h"
#pragma section IntPRG
 
// Exception (Supervisor Instruction)
void Excep_SuperVisorInst(void){/* brk(); */}
 
// Exception (Undefined Instruction)
void Excep_UndefinedInst(void){/* brk(); */}
 
// Exception (Floating Point)
void Excep_FloatingPoint(void){/* brk(); */}
 
// NMI
void NonMaskableInterrupt(void){/* brk(); */}
 
// Dummy
void Dummy(void){/* brk(); */}
 
// BRK
void Excep_BRK(void){ wait(); }

(c)

vecttbl.c: Fixed Vector Table

#include "vect.h"
 
#pragma section C FIXEDVECT
 
void (*const Fixed_Vectors[])(void) = {
//;0xffffffd0  Exception (Supervisor Instruction)
    Excep_SuperVisorInst,
//;0xffffffd4  Reserved
    Dummy,
//;0xffffffd8  Reserved
    Dummy,
//;0xffffffdc  Exception (Undefined Instruction)
    Excep_UndefinedInst,
//;0xffffffe0  Reserved
    Dummy,
//;0xffffffe4  Exception (Floating Point)
    Excep_FloatingPoint,
//;0xffffffe8  Reserved
    Dummy,
//;0xffffffec  Reserved
    Dummy,
//;0xfffffff0  Reserved
    Dummy,
//;0xfffffff4  Reserved
    Dummy,
//;0xfffffff8  NMI
    NonMaskableInterrupt,
//;0xfffffffc  RESET
//;<<VECTOR DATA START (POWER ON RESET)>>
//;Power On Reset PC
PowerOn_Reset_PC
//;<<VECTOR DATA END (POWER ON RESET)>>
};

[Reference]

Case when an RX instruction-set architecture other than the RXv1 instruction-set architecture is selected (exception vector table)

#include "vect.h"
 
#pragma section C EXCEPTVECT
 
void (*const Excep_Vectors[])(void) = {
//;0xffffff80  Reserved
    Dummy,
//;0xffffff84  Reserved
    Dummy,
//;0xffffff88  Reserved
    Dummy,
//;0xffffff8c  Reserved
    Dummy,
//;0xffffff90  Reserved
    Dummy,
//;0xffffff94  Reserved
    Dummy,
//;0xffffff98  Reserved
    Dummy,
//;0xffffff9c  Reserved
    Dummy,
//;0xffffffa0  Reserved
    Dummy,
//;0xffffffa4  Reserved
    Dummy,
//;0xffffffa8  Reserved
    Dummy,
//;0xffffffac  Reserved
    Dummy,
//;0xffffffb0  Reserved
    Dummy,
//;0xffffffb4  Reserved
    Dummy,
//;0xffffffb8  Reserved
    Dummy,
//;0xffffffbc  Reserved
    Dummy,
//;0xffffffc0  Reserved
    Dummy,
//;0xffffffc4  Reserved
    Dummy,
//;0xffffffc8  Reserved
    Dummy,
//;0xffffffcc  Reserved
    Dummy,
//;0xffffffd0  Exception(Supervisor Instruction)
    Excep_SuperVisorInst,
//;0xffffffd4  Exception(Access Instruction)
    Excep_AccessInst,
//;0xffffffd8  Reserved
    Dummy,
//;0xffffffdc  Exception(Undefined Instruction)
    Excep_UndefinedInst,
//;0xffffffe0  Reserved
    Dummy,
//;0xffffffe4  Exception(Floating Point)
    Excep_FloatingPoint,
//;0xffffffe8  Reserved
    Dummy,
//;0xffffffec  Reserved
    Dummy,
//;0xfffffff0  Reserved
    Dummy,
//;0xfffffff4  Reserved
    Dummy,
//;0xfffffff8  NMI
    NonMaskableInterrupt,
};
 
#pragma section C RESETVECT
 
void (*const Reset_Vectors[])(void) = {
//;0xfffffffc  RESET
    PowerON_Reset_PC
};
 

 

(d)

dbsct.c: Section Initialization Processing (table)

#include "typedefine.h"
 
#pragma unpack
 
#pragma section C C$DSEC
extern const struct {
    _UBYTE *rom_s;    /* Start address of the initialized data section in ROM */
    _UBYTE *rom_e;    /* End address of the initialized data section in ROM   */
    _UBYTE *ram_s;    /* Start address of the initialized data section in RAM */
}   _DTBL[] = {
    { __sectop("D"), __secend("D"), __sectop("R") },
    { __sectop("D_2"), __secend("D_2"), __sectop("R_2") },
    { __sectop("D_1"), __secend("D_1"), __sectop("R_1") }
};
#pragma section C C$BSEC
extern const struct {
    _UBYTE *b_s;         /* Start address of non-initialized data section */
    _UBYTE *b_e;         /* End address of non-initialized data section */
}   _BTBL[] = {
    { __sectop("B"), __secend("B") },
    { __sectop("B_2"), __secend("B_2") },
    { __sectop("B_1"), __secend("B_1") }
};
 
#pragma section
 
/*
** CTBL prevents excessive output of W0561100 messages when linking.
** Even if CTBL is deleted, the operation of the program does not change.
*/
_UBYTE * const _CTBL[] = {
    __sectop("C_1"), __sectop("C_2"), __sectop("C"),
    __sectop("W_1"), __sectop("W_2"), __sectop("W")
};
 
#pragma packoption

(e)

lowsrc.c : Low-Level Interface Routine (C Language Part)

#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include "lowsrc.h"
 
#define STDIN  0
#define STDOUT 1
#define STDERR 2
 
#define FLMIN  0
#define _MOPENR	0x1
#define _MOPENW	0x2
#define _MOPENA	0x4
#define _MTRUNC	0x8
#define _MCREAT	0x10
#define _MBIN		0x20
#define _MEXCL		0x40
#define _MALBUF	0x40
#define _MALFIL	0x80
#define _MEOF		0x100
#define _MERR		0x200
#define _MLBF		0x400
#define _MNBF		0x800
#define _MREAD		0x1000
#define _MWRITE	0x2000
#define _MBYTE		0x4000
#define _MWIDE		0x8000
 
#define O_RDONLY	0x0001
#define O_WRONLY	0x0002
#define O_RDWR		0x0004
#define O_CREAT	0x0008
#define O_TRUNC	0x0010
#define O_APPEND	0x0020
 
#define CR 0x0d
#define LF 0x0a
 
extern const long _nfiles;
char flmod[IOSTREAM];
 
unsigned char sml_buf[IOSTREAM];
 
#define FPATH_STDIN     "C:\\stdin"
#define FPATH_STDOUT    "C:\\stdout"
#define FPATH_STDERR    "C:\\stderr"
 
extern void charput(unsigned char);
extern unsigned char charget(void);
 
#include <stdio.h>
FILE *_Files[IOSTREAM];
char *env_list[] = {
    "ENV1=temp01",
    "ENV2=temp02",
    "ENV9=end",
    '\0'
};
 
char **environ = env_list;
 
void _INIT_IOLIB( void )
{
    _Files[0] = stdin;
    _Files[1] = stdout;
    _Files[2] = stderr;
 
    if( freopen( FPATH_STDIN, "r", stdin ) == NULL )
        stdin->_Mode = 0xffff;
    stdin->_Mode  = _MOPENR;
    stdin->_Mode |= _MNBF;
    stdin->_Bend = stdin->_Buf + 1;
 
    if( freopen( FPATH_STDOUT, "w", stdout ) == NULL )
        stdout->_Mode = 0xffff;
    stdout->_Mode |= _MNBF;
    stdout->_Bend = stdout->_Buf + 1;
 
    if( freopen( FPATH_STDERR, "w", stderr ) == NULL )
        stderr->_Mode = 0xffff;
    stderr->_Mode |= _MNBF;
    stderr->_Bend = stderr->_Buf + 1;
}
 
void _CLOSEALL( void )
{
    long i;
    for( i=0; i < _nfiles; i++ )
    {
        if( _Files[i]->_Mode & (_MOPENR | _MOPENW | _MOPENA ) )
        fclose( _Files[i] );
    }
}
 
long open(const char *name,
     long  mode,
     long  flg)
{
 
    if( strcmp( name, FPATH_STDIN ) == 0 )
    {
        if( ( mode & O_RDONLY ) == 0 ) return -1;
        flmod[STDIN] = mode;
        return STDIN;
    }
    else if( strcmp( name, FPATH_STDOUT ) == 0 )
    {
        if( ( mode & O_WRONLY ) == 0 ) return -1;
        flmod[STDOUT] = mode;
        return STDOUT;
    }
    else if(strcmp(name, FPATH_STDERR ) == 0 )
    {
        if( ( mode & O_WRONLY ) == 0 ) return -1;
        flmod[STDERR] = mode;
        return STDERR;
    }
    else return -1;
}
 
long close( long fileno )
{
    return 1;
}
 
long write(long  fileno,
      const unsigned char *buf,
      long  count)
{
    long    i;
    unsigned char    c;
 
    if(flmod[fileno]&O_WRONLY || flmod[fileno]&O_RDWR)
    {
        if( fileno == STDIN ) return -1;
        else if( (fileno == STDOUT) || (fileno == STDERR) )
        {
            for( i = count; i > 0; --i )
            {
                c = *buf++;
                charput(c);
            }
            return count;
        }
        else return -1;
    }
    else return -1;
}
 
long read( long fileno, unsigned char *buf, long count )
{
	   long i;
       if((flmod[fileno]&_MOPENR) || (flmod[fileno]&O_RDWR)){
             for(i = count; i > 0; i--){
                   *buf = charget();
                   if(*buf==CR){
                         *buf = LF;
                   }
                   buf++;
             }
             return count;
       }
       else {
             return -1;
       }
}
 
long lseek( long fileno, long offset, long base )
{
    return -1L;
}

 

(f)

lowlvl.src: Low-Level Interface Routine (Assembly Language Part)

         .GLB    _charput
         .GLB    _charget
 
SIM_IO   .EQU 0h
 
         .SECTION   P,CODE
;-----------------------------------------------------------------------
;  _charput:
;-----------------------------------------------------------------------
_charput:
         MOV.L      #IO_BUF,R2
         MOV.B      R1,[R2]
         MOV.L      #1220000h,R1
         MOV.L      #PARM,R3
         MOV.L      R2,[R3]
         MOV.L      R3,R2
         MOV.L      #SIM_IO,R3
         JSR        R3
         RTS
 
;-----------------------------------------------------------------------
;  _charget:
;-----------------------------------------------------------------------
_charget:
        MOV.L       #1210000h,R1
        MOV.L       #IO_BUF,R2
        MOV.L       #PARM,R3
        MOV.L       R2,[R3]
        MOV.L       R3,R2
        MOV.L       #SIM_IO,R3
        JSR         R3
        MOV.L       #IO_BUF,R2
        MOVU.B      [R2],R1
        RTS
 
;-----------------------------------------------------------------------
;  I/O Buffer
;-----------------------------------------------------------------------
         .SECTION  B,DATA,ALIGN=4
PARM:    .BLKL     1
         .SECTION  B_1,DATA
IO_BUF:  .BLKB     1
         .END

(g)

sbrk.c: Low-Level Interface Routine (sbrk Function)

#include <stddef.h>
#include <stdio.h>
#include "typedefine.h"
#include "sbrk.h"
 
_SBYTE  *sbrk(size_t size);
 
//const size_t _sbrk_size=    /* Specifies the minimum unit of */
                              /* the defined heap area*/
 
extern _SBYTE *_s1ptr;
 
union HEAP_TYPE {
    _SDWORD  dummy ;          /* Dummy for 4-byte boundary */
    _SBYTE heap[HEAPSIZE];    /* Declaration of the area managed by sbrk */
};
 
static union HEAP_TYPE heap_area ;
 
/* End address allocated by sbrk */
static _SBYTE *brk=(_SBYTE *)&heap_area;
 
/**************************************************************************/
/*     sbrk:Memory area allocation                                        */
/*          Return value:Start address of allocated area (Pass)           */
/*                       -1                              (Failure)        */
/**************************************************************************/
_SBYTE  *sbrk(size_t size)                      /* Assigned area size   */
{
    _SBYTE  *p;
 
    if(brk+size > heap_area.heap+HEAPSIZE){     /* Empty area size      */
        p = (_SBYTE *)-1;
    }
    else {
        p = brk;                                /* Area assignment      */
        brk += size;                            /* End address update   */
    }
    return p;
}

(h)

typedefine.h: Type Definition Header

typedef signed char _SBYTE;
typedef unsigned char _UBYTE;
typedef signed short _SWORD;
typedef unsigned short _UWORD;
typedef signed int _SINT;
typedef unsigned int _UINT;
typedef signed long _SDWORD;
typedef unsigned long _UDWORD;
typedef signed long long _SQWORD;
typedef unsigned long long _UQWORD;

(i)

vect.h: Vector Function Header

// Exception (Supervisor Instruction)
#pragma interrupt (Excep_SuperVisorInst)
void Excep_SuperVisorInst(void);
 
// Exception (Undefined Instruction)
#pragma interrupt (Excep_UndefinedInst)
void Excep_UndefinedInst(void);
 
// Exception (Floating Point)
#pragma interrupt (Excep_FloatingPoint)
void Excep_FloatingPoint(void);
 
// NMI
#pragma interrupt (NonMaskableInterrupt)
void NonMaskableInterrupt(void);
 
// Dummy
#pragma interrupt (Dummy)
void Dummy(void);
 
// BRK
#pragma interrupt (Excep_BRK(vect=0))
void Excep_BRK(void);
 
//;<<VECTOR DATA START (POWER ON RESET)>>
//;Power On Reset PC
extern void PowerOn_Reset_PC(void);
//;<<VECTOR DATA END (POWER ON RESET)>>

(j)

stacksct.h: Stack Size Settings

// #pragma stacksize su=0x100 // Remove the comment when you use user stack
#pragma stacksize si=0x300

(k)

lowsrc.h: Low-Level Interface Routine (C Language Header)

/*Number of I/O Streams*/
#define IOSTREAM 20

(l)

sbrk.h: Low-Level Interface Routine (sbrk Function Header)

/* Size of area managed by sbrk */
#define HEAPSIZE 0x400

(2)

Execution Commands

The following shows an example of commands for building these files.

In this example, the name of the user program file (containing the main function) is UserProgram.c, and the body of the file names (names excluding extensions) for the load module or library to be created is LoadModule.

lbgrx -isa=rxv1 -output=LoadModule.lib
ccrx -isa=rxv1 -output=obj UserProgram.c
ccrx -isa=rxv1 -output=obj resetprg.c
ccrx -isa=rxv1 -output=obj intprg.c
ccrx -isa=rxv1 -output=obj vecttbl.c
ccrx -isa=rxv1 -output=obj dbsct.c
ccrx -isa=rxv1 -output=obj lowsrc.c
asrx -isa=rxv1 lowlvl.src
ccrx -isa=rxv1 -output=obj sbrk.c
rlink -rom=D=R,D_1=R_1,D_2=R_2 -list=LoadModule.map -start=B_1,R_1,B_2,R_2,B,R,SI/01000,PResetPRG/0FFFF8000,C_1,C_2,C,C$*,D_1,D_2,D,P,PIntPRG,W*,L/0FFFF8100,FIXEDVECT/0FFFFFFD0 -library=LoadModule.lib -output=LoadModule.abs UserProgram.obj resetprg.obj intprg.obj vecttbl.obj dbsct.obj lowsrc.obj lowlvl.obj sbrk.obj
rlink -output=LoadModule.sty -form=stype -output=LoadModule.mot LoadModule.abs

[Reference]

An example of a command string for which the RXv2 instruction-set architecture was selected is shown.

lbgrx -isa=rxv2 -output=LoadModule.lib
ccrx -isa=rxv2 -output=obj UserProgram.c
ccrx -isa=rxv2 -output=obj resetprg.c
ccrx -isa=rxv2 -output=obj intprg.c
ccrx -isa=rxv2 -output=obj vecttbl.c
ccrx -isa=rxv2 -output=obj dbsct.c
ccrx -isa=rxv2 -output=obj lowsrc.c
asrx -isa=rxv2 lowlvl.src
ccrx -isa=rxv2 -output=obj sbrk.c
rlink -rom=D=R,D_1=R_1,D_2=R_2 -list=LoadModule.map -start=B_1,R_1,B_2,R_2,B,R,SU,SI/04,PResetPRG/0FFFF8000,C_1,C_2,C,C$DSEC,C$BSEC,C$INIT,C$VTBL,C$VECT,D_1,D_2,D,P,PIntPRG,W_1,W_2,W,L/0FFFF8100,EXCEPTVECT/0FFFFFF80,RESETVECT/0FFFFFFFC -=LoadModule.lib -output=LoadModule.abs UserProgram.obj resetprg.obj intprg.obj vecttbl.obj dbsct.obj lowsrc.obj lowlvl.obj sbrk.obj
rlink -output=LoadModule.sty -form=stype -output=LoadModule.mot LoadModule.abs