OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [Tools/] [as09/] [pseudo.c] - Rev 118

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *      pseudo --- pseudo op processing
 */
 
#define RMB     0       /* Reserve Memory Bytes         */
#define FCB     1       /* Form Constant Bytes          */
#define FDB     2       /* Form Double Bytes (words)    */
#define FCC     3       /* Form Constant Characters     */
#define ORG     4       /* Origin                       */
#define EQU     5       /* Equate                       */
#define ZMB     6       /* Zero memory bytes            */
#define FILL    7       /* block fill constant bytes    */
#define OPT     8       /* assembler option             */
#define NULL_OP 9       /* null pseudo op               */
#define PAGE    10      /* new page                     */
#define INCLUDE 11      /* include <file> or "file" ver TER_2.0 */
#define END     12      /* include <file> terminator ver TER_2.0 */
#define IFD     13      /* if define <symbol> ver TER_2.0 */
#define IFND    14      /* if not define <symbol> ver TER_2.0 */
#define ELSE    15      /* else (for IF statements) ver TER_2.0 */
#define ENDIF   16      /* endif (for IF statements) ver TER_2.0 */
#define BSS     17      /* block storage segment (RAM) ver TER_2.09 */
#define CODE    18      /* code segment ver TER_2.09 25 Jul 89 */
#define DATA    19      /* data segment ver TER_2.09 25 Jul 89 */
#define AUTO    20      /* data segment ver TER_2.09 25 Jul 89 */
 
struct oper pseudo[] = {
"=",    PSEUDO, EQU,    0,      /* ver TER_2.09 25 Jul 89 */
"auto", PSEUDO, AUTO,   0,      /* ver TER_2.09 25 Jul 89 */
"bss",  PSEUDO, BSS,    0,      /* ver TER_2.09 25 Jul 89 */
"bsz",  PSEUDO, ZMB,    0,
"code", PSEUDO, CODE,   0,      /* ver TER_2.09 25 Jul 89 */
"data", PSEUDO, DATA,   0,      /* ver TER_2.09 25 Jul 89 */
"else", PSEUDO, ELSE,   0,      /* ver TER_2.0 6/17/89 */
"end",  PSEUDO, END,    0,      /* ver TER_2.0 6/17/89 */
"endif",PSEUDO, ENDIF,  0,      /* ver TER_2.0 6/17/89 */
"equ",  PSEUDO, EQU,    0,
"fcb",  PSEUDO, FCB,    0,
"fcc",  PSEUDO, FCC,    0,
"fdb",  PSEUDO, FDB,    0,
"fill", PSEUDO, FILL,   0,
"ifd",  PSEUDO, IFD,    0,      /* ver TER_2.0 6/17/89 */
"ifnd", PSEUDO, IFND,   0,      /* ver TER_2.0 6/17/89 */
"include", PSEUDO, INCLUDE, 0,  /* ver TER_2.0 6/17/89 */
"nam",  PSEUDO, NULL_OP,0,
"name", PSEUDO, NULL_OP,0,
"opt",  PSEUDO, OPT,    0,
"org",  PSEUDO, ORG,    0,
"pag",  PSEUDO, PAGE,   0,
"page", PSEUDO, PAGE,   0,
"ram",  PSEUDO, BSS,    0,      /* ver TER_2.09 25 Jul 89 */
"rmb",  PSEUDO, RMB,    0,
"spc",  PSEUDO, NULL_OP,0,
"ttl",  PSEUDO, NULL_OP,0,
"zmb",  PSEUDO, ZMB,    0
};
 
/*
 *      do_pseudo --- do pseudo op processing
 */
do_pseudo(op)
int op; /* which op */
{
        char    fccdelim, *strsave();
        int     fill;
        int c;  /*test variable  ver TER_2.0 6/18/89 */
        char    *skip_white(), *savept; /* savept is pointer to string save */
        FILE    *FdTemp, *fopen();      /* ver TER_2.0 6/17/89 */
        void    IfMachine(); /* rel TER_2.0 6/18/89 */
        void    PC_Exchange();  /* ver TER_2.09 25 Jul 89 */
 
        if( op != EQU && *Label )
                install(Label,Pc);
 
        P_force++;
 
#ifdef DEBUG3
    printf("%s, line no. ",Argv[Cfn]);  /* current file name */
    printf("%d: ",Line_num);    /* current line number */
    printf(" Pseudo Op=%u\n",op);
#endif
 
        switch(op){
                case RMB:                       /* reserve memory bytes */
                        if( eval() ){
                                Pc +=  Result;
                                f_record();     /* flush out bytes */
                                }
                        else
                                error("Undefined Operand during Pass One");
                        break;
                case ZMB:                       /* zero memory bytes */
                        if( eval() )
                                while( Result-- )
                                        emit(0);
                        else
                                error("Undefined Operand during Pass One");
                        break;
                case FILL:                      /* fill memory with constant */
                        eval();
                        fill = Result;
                        if( *Optr++ != ',' )
                                error("Bad fill");
                        else{
                                Optr = skip_white(Optr);
                                eval();
                                while( Result-- )
                                        emit(fill);
                                }
                        break;
                case FCB:                       /* form constant byte(s) */
                        do{
                                Optr = skip_white(Optr);
                                eval();
                                if( Result > 0xFF ){
                                        if(!Force_byte)
                                                warn("Value truncated");
                                        Result = lobyte(Result);
                                        }
                                emit(Result);
                        }while( *Optr++ == ',' );
                        break;
                case FDB:                       /* form double byte(s) */
                        do{
                                Optr = skip_white(Optr);
                                eval();
                                eword(Result);
                        }while( *Optr++ == ',' );
                        break;
                case FCC:                       /* form constant characters */
                        if(*Operand==EOS)
                                break;
                        fccdelim = *Optr++;
                        while( *Optr != EOS && *Optr != fccdelim)
                                emit(*Optr++);
                        if(*Optr == fccdelim)
                                Optr++;
                        else
                                error("Missing Delimiter");
                        break;
                case ORG:                       /* origin */
                        if( eval() ){
                                Old_pc = Pc = Result;
                                f_record();     /* flush out any bytes */
                                }
                        else
                                error("Undefined Operand during Pass One");
                        break;
                case EQU:                       /* equate */
                        if(*Label==EOS){
                                error("EQU requires label");
                                break;
                                }
                        if( eval() ){
                                install(Label,Result);
                                Old_pc = Result;        /* override normal */
                                }
                        else
                                error("Undefined Operand during Pass One");
                        break;
                case OPT:                       /* assembler option */
                        P_force=0;
                        if( head(Operand,"l") )
                                Lflag=1;
                        else if (head(Operand,"nol"))
                                Lflag=0;
                        else if (head(Operand,"c")){
                                Cflag=1;
                                Ctotal=0;
                                }
                        else if (head(Operand,"noc"))
                                Cflag=0;
                        else if (head(Operand,"contc")){
                                Cflag=1;
                                }
                        else if (head(Operand,"s"))
                                Sflag = 1;
                        else if (head(Operand,"cre"))
                                CREflag = 1;
                        else if (head(Operand,"p50")){  /* turn on 50 lines/page flag */
                                Pflag50 = 1;
                                Pflag75 = 0;
                                }																	/* separately. ver TER_2.0 6/17/89 */
                        else if (head(Operand,"p75")){  /* turn on 75 lines/page flag */
                                Pflag50 = 0;
                                Pflag75 = 1;
                                }																	/* separately. ver TER_2.0 6/17/89 */
                        else if (head(Operand,"crlf"))  /* add <CR> <LF> to  */
				CRflag = 1;             /* S record ver TER_2.08 */
                        else if (head(Operand,"nnf"))   /* no extra line no. */
				nfFlag = 0;             /* w include files ver TER_2.08 */
                        else
                                error("Unrecognized OPT");
                        break;
                case PAGE:                      /* go to a new page */
                        P_force=0;
                        N_page = 1;
                        if (Pass == 2 )
                         if (Lflag) NewPage();
                        break;
                case NULL_OP:                   /* ignored psuedo ops */
                        P_force=0;
                        break;
                case INCLUDE:   /* case INCLUDE added ver TER_2.0 6/17/89 */
                        P_force=0;      /* no PC in printed output */
                        if ((c=FNameGet(InclFName))==0)
                          error("Improper INCLUDE statement");
                        else
                        {
                        if (FdCount > MAXINCFILES)
                          error("too many INCLUDE files");
                        else
                         {
                          if ((FdTemp = fopen(InclFName,"r"))==0)
                           {
                            printf("%s, line no. ",Argv[Cfn]);
                                        /* current file name */
                            printf("%d: ",Line_num); /* current line number */
                            Page_lines++;       /* increment lines per page */
                printf("warning:can't open INCLUDE file %s\n",InclFName);
                           }
                          else
                           {
                            if ((savept=strsave(InclFName))==0)
                              error("out of memory for INCLUDE file name");
                            else
                            {
                            InclFiles[FdCount].fp=Fd;   /* save current fp */
                            if (nfFlag)
                             {
                              InclFiles[FdCount].line_num=Line_num;
                                        /* save current line count */
                              Line_num=0;       /* reset for new file */
                             }
                            InclFiles[FdCount].name=Argv[Cfn];
                                /* save pointer to current name */
                            Argv[Cfn]=savept;
                                /* now replace pointer to current name with
                                   pointer to name of Include file */
                            Fd=FdTemp;  /* now replace current file with
                                           INCLUDE fp */
                            FdCount++;  /* and increment "stack" */
#ifdef DEBUG2
        printf("pseudo INCLUDE: FdCount=%d\n",FdCount);
        printf("  new input file pointer=%d\n",Fd);
        printf("  new file name=%s\n",Argv[Cfn]);
#endif
                            }
                           }
                         }
                        }
                        break;
                case END:
                        P_force=0;
                        if (FdCount>0)  /* skip END statements in files
                                           received from CLI arguments */
                         {
                          fclose(Fd);   /* close file from this level nest */
                          FdCount--;    /* "pop stack" */
                          Fd=InclFiles[FdCount].fp;     /* restore fp from
                                        nested stack */
                          if(nfFlag) Line_num=InclFiles[FdCount].line_num;
                          Argv[Cfn]=InclFiles[FdCount].name;
                                /* restore file name pointer */
#ifdef DEBUG2
        printf("pseudo END: FdCount=%d\n",FdCount);
        printf("  new input file pointer=%d\n",Fd);
        printf("  new file name=%s\n",Argv[Cfn]);
#endif
                         }
                        break;
                case IFD:
#ifdef DEBUG3
                        printf("case IFD: in pseudo\n");
#endif
                        P_force=0;
                        c=eval_ifd();
                        IfMachine(c);
                        break;
                case IFND:
                        P_force=0;
                        c=eval_ifnd();
                        IfMachine(c);
                        break;
                case ELSE:
                        P_force=0;
                        IfMachine(IF_ELSE);
                        break;
                case ENDIF:
                        P_force=0;
                        IfMachine(IF_ENDIF);
                        break;
                case CODE:      /* CODE,DATA,BSS,AUTO ver TER_2.09 */
                        PC_Exchange(0);
                        break;
                case DATA:
                        PC_Exchange(1);
                        break;
                case BSS:
                        PC_Exchange(2);
                        break;
                case AUTO:
                        PC_Exchange(3);
                        break;
                default:
                        fatal("Pseudo error");
                        break;
                }
}
 
 
/*
*       PC_Exchange --- Save current PC and recover requested one
                added ver TER_2.09
*/
void PC_Exchange(PC_ptr_new)
int PC_ptr_new; /* request 0=CODE,1=DATA,2=BSS */
  {
  P_force = 0;  /* no PC in output cuz wrong first time (?) */
  PC_Save[PC_ptr] = Pc; /* save current PC */
  PC_ptr = PC_ptr_new;  /* remember which one we're using */
  Old_pc = Pc = PC_Save[PC_ptr];  /* recover the one requested */
  f_record();   /* flush out any bytes, this is really an ORG */
  }
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.