示例#1
0
//-------------------------------------------------------------------
unsigned int parse_branch_label ( unsigned int ra )
{
    unsigned int rb;
    unsigned int rc;

    is_const=0;
    is_label=0;
    for(;newline[ra];ra++) if(newline[ra]!=0x20) break;
    if(numchar[newline[ra]])
    {
        ra=parse_immed(ra); if(ra==0) return(0);
        is_const=1;
    }
    else
    {
        //assume label, find space or eol.
        for(rb=ra;newline[rb];rb++)
        {
            if(newline[rb]==0x20) break; //no spaces in labels
        }
        //got a label
        rc=rb-ra;
        if(rc==0)
        {
            printf("<%u> Error: Invalid label\n",line);
            return(0);
        }
        rc--;
        if(rc>=LABLEN)
        {
            printf("<%u> Error: Label too long\n",line);
            return(0);
        }
        for(rb=0;rb<=rc;rb++)
        {
            lab_struct[nlabs].name[rb]=newline[ra++];
        }
        lab_struct[nlabs].name[rb]=0;
        lab_struct[nlabs].addr=curradd;
        lab_struct[nlabs].line=line;
        lab_struct[nlabs].type=1;
        nlabs++;
        rx=0;
        is_label=1;
    }
    return(ra);
}
示例#2
0
//-------------------------------------------------------------------
//-------------------------------------------------------------------
int assemble ( void )
{
    unsigned int ra;
    unsigned int rb;
    unsigned int rc;


    curradd=0;
    nlabs=0;
    memset(mem,0x00,sizeof(mem));
    memset(mark,0x00,sizeof(mark));

    line=0;
    while(fgets(newline,sizeof(newline)-1,fpin))
    {
        line++;
        //tabs to spaces and other things
        for(ra=0;newline[ra];ra++)
        {
            if(newline[ra]<0x20)  newline[ra]=0x20;
            if(newline[ra]>=0x7F) newline[ra]=0;
        }

        //various ways to comment lines
        for(ra=0;newline[ra];ra++)
        {
            if(newline[ra]==';') newline[ra]=0;
            if(newline[ra]=='@') newline[ra]=0;
            if((newline[ra]=='/')&&(newline[ra+1]=='/')) newline[ra]=0;
            if(newline[ra]==0) break;
        }

        //skip spaces
        for(ra=0;newline[ra];ra++) if(newline[ra]!=0x20) break;
        if(newline[ra]==0) continue;

        //look for a label?
        for(rb=ra;newline[rb];rb++)
        {
            if(newline[rb]==0x20) break; //no spaces in labels
            if(newline[rb]==':') break;
        }
        if(newline[rb]==':')
        {
            //got a label
            rc=rb-ra;
            if(rc==0)
            {
                printf("<%u> Error: Invalid label\n",line);
                return(1);
            }
            rc--;
            if(rc>=LABLEN)
            {
                printf("<%u> Error: Label too long\n",line);
                return(1);
            }
            for(rb=0;rb<=rc;rb++)
            {
                lab_struct[nlabs].name[rb]=newline[ra++];
            }
            lab_struct[nlabs].name[rb]=0;
            lab_struct[nlabs].addr=0x3000+curradd;
            lab_struct[nlabs].line=line;
            lab_struct[nlabs].type=0;
            ra++;
            for(lab=0;lab<nlabs;lab++)
            {
                if(lab_struct[lab].type) continue;
                if(strcmp(lab_struct[lab].name,lab_struct[nlabs].name)==0) break;
            }
            if(lab<nlabs)
            {
                printf("<%u> Error: label [%s] already defined on line %u\n",line,lab_struct[lab].name,lab_struct[lab].line);
                return(1);
            }
            nlabs++;
            //skip spaces
            for(;newline[ra];ra++) if(newline[ra]!=0x20) break;
            if(newline[ra]==0) continue;
        }
// .word -----------------------------------------------------------
        if(strncmp(&newline[ra],".word ",6)==0)
        {
            ra+=6;
            ra=parse_immed(ra); if(ra==0) return(1);
            mem[curradd]=rx;
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// add -----------------------------------------------------------
        if(strncmp(&newline[ra],"add ",4)==0)
        {
            ra+=4;
            //add rd,rs,rx
            //add rd,rs,#imm
            ra=parse_two_regs(ra); if(ra==0) return(1);
            ra=parse_comma(ra); if(ra==0) return(1);
            if(newline[ra]=='#')
            {
                ra=parse_immed(ra+1); if(ra==0) return(1);
                if(check_simmed5(rx)) return(1);
                mem[curradd]=0x1020|(rd<<9)|(rs<<6)|(rx&0x1F);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                ra=parse_reg(ra); if(ra==0) return(1);
                mem[curradd]=0x1000|(rd<<9)|(rs<<6)|rx;
                mark[curradd]|=0x80000000;
                curradd++;
            }
            if(rest_of_line(ra)) return(1);
            continue;
        }
// and -----------------------------------------------------------
        if(strncmp(&newline[ra],"and ",4)==0)
        {
            ra+=4;
            //and rd,rs,rx
            //and rd,rs,#imm
            ra=parse_two_regs(ra); if(ra==0) return(1);
            ra=parse_comma(ra); if(ra==0) return(1);
            if(newline[ra]=='#')
            {
                ra=parse_immed(ra+1); if(ra==0) return(1);
                if(check_simmed5(rx)) return(1);
                mem[curradd]=0x5020|(rd<<9)|(rs<<6)|(rx&0x1F);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                ra=parse_reg(ra); if(ra==0) return(1);
                mem[curradd]=0x5000|(rd<<9)|(rs<<6)|rx;
                mark[curradd]|=0x80000000;
                curradd++;
            }
            if(rest_of_line(ra)) return(1);
            continue;
        }
// jmp -----------------------------------------------------------
        if(strncmp(&newline[ra],"jmp ",4)==0)
        {
            ra+=4;
            //jmp rs
            ra=parse_reg(ra); if(ra==0) return(1);
            mem[curradd]=0xC000|(rx<<6);
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// jsrr -----------------------------------------------------------
        if(strncmp(&newline[ra],"jsrr ",5)==0)
        {
            ra+=5;
            //jsrr rs
            ra=parse_reg(ra); if(ra==0) return(1);
            mem[curradd]=0x4000|(rx<<6);
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// not -----------------------------------------------------------
        if(strncmp(&newline[ra],"not ",4)==0)
        {
            ra+=4;
            //not rd,rs
            ra=parse_two_regs(ra); if(ra==0) return(1);
            mem[curradd]=0x9000|(rd<<9)|(rs<<6);
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// ret -----------------------------------------------------------
        if(strncmp(&newline[ra],"ret",3)==0)
        {
            ra+=3;
            //ret
            mem[curradd]=0xC1C0;
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// rti -----------------------------------------------------------
        if(strncmp(&newline[ra],"rti",3)==0)
        {
            ra+=3;
            //rti
            mem[curradd]=0x8000;
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// brn -----------------------------------------------------------
        if(strncmp(&newline[ra],"brn ",4)==0)
        {
            ra+=4;
            //brn offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0800|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0800;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brz -----------------------------------------------------------
        if(strncmp(&newline[ra],"brz ",4)==0)
        {
            ra+=4;
            //brz offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0400|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0400;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brp -----------------------------------------------------------
        if(strncmp(&newline[ra],"brp ",4)==0)
        {
            ra+=4;
            //brp offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0200|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0200;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brnz -----------------------------------------------------------
        if(strncmp(&newline[ra],"brnz ",5)==0)
        {
            ra+=5;
            //brnzp offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0C00|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0C00;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brnp -----------------------------------------------------------
        if(strncmp(&newline[ra],"brnp ",5)==0)
        {
            ra+=5;
            //brnp offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0A00|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0A00;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brzp -----------------------------------------------------------
        if(strncmp(&newline[ra],"brzp ",5)==0)
        {
            ra+=5;
            //brzp offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0600|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0600;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// brnzp -----------------------------------------------------------
        if(strncmp(&newline[ra],"brnzp ",6)==0)
        {
            ra+=6;
            //brnzp offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: branch too far\n",line);
                    return(1);
                }
                mem[curradd]=0x0E00|(rx&0x1FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x0E00;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// jsr -----------------------------------------------------------
        if(strncmp(&newline[ra],"jsr ",4)==0)
        {
            ra+=4;
            //jsr offset/label
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset11(rx))
                {
                    printf("<%u> Error: jsr too far\n",line);
                    return(1);
                }
                mem[curradd]=0x4800|(rx&0x07FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x4800;
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// ld -----------------------------------------------------------
        if(strncmp(&newline[ra],"ld ",3)==0)
        {
            ra+=3;
            //ld rd,offset/label
            ra=parse_reg(ra); if(ra==0) return(1);
            rd=rx;
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: ld too far\n",line);
                    return(1);
                }
                mem[curradd]=0x2000|(rd<<9)|(rx&0x01FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x2000|(rd<<9);
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// ldi -----------------------------------------------------------
        if(strncmp(&newline[ra],"ldi ",4)==0)
        {
            ra+=4;
            //ldi rd,offset/label
            ra=parse_reg(ra); if(ra==0) return(1);
            rd=rx;
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: ldi too far\n",line);
                    return(1);
                }
                mem[curradd]=0xA000|(rd<<9)|(rx&0x01FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0xA000|(rd<<9);
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// ldr -----------------------------------------------------------
        if(strncmp(&newline[ra],"ldr ",4)==0)
        {
            ra+=4;
            //ldr rd,rs,#offset
            ra=parse_two_regs(ra); if(ra==0) return(1);
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_pound(ra); if(ra==0) return(1);
            ra=parse_immed(ra); if(ra==0) return(1);
            if(rest_of_line(ra)) return(1);
            if(check_simmed6(rx)) return(1);
            mem[curradd]=0x6000|(rd<<9)|(rs<<6)|(rx&0x003F);
            mark[curradd]|=0x80000000;
            curradd++;
            continue;
        }
// lea -----------------------------------------------------------
        if(strncmp(&newline[ra],"lea ",4)==0)
        {
            ra+=4;
            //ldi rd,offset/label
            ra=parse_reg(ra); if(ra==0) return(1);
            rd=rx;
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: lea too far\n",line);
                    return(1);
                }
                mem[curradd]=0xE000|(rd<<9)|(rx&0x01FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0xE000|(rd<<9);
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// st -----------------------------------------------------------
        if(strncmp(&newline[ra],"st ",3)==0)
        {
            ra+=3;
            //st rd,offset/label
            ra=parse_reg(ra); if(ra==0) return(1);
            rd=rx;
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: st too far\n",line);
                    return(1);
                }
                mem[curradd]=0x3000|(rd<<9)|(rx&0x01FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0x3000|(rd<<9);
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// sti -----------------------------------------------------------
        if(strncmp(&newline[ra],"sti ",4)==0)
        {
            ra+=4;
            //sti rd,offset/label
            ra=parse_reg(ra); if(ra==0) return(1);
            rd=rx;
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_branch_label(ra); if(ra==0) return(0);
            if(rest_of_line(ra)) return(1);
            if(is_const)
            {
                if(check_offset9(rx))
                {
                    printf("<%u> Error: sti too far\n",line);
                    return(1);
                }
                mem[curradd]=0xB000|(rd<<9)|(rx&0x01FF);
                mark[curradd]|=0x80000000;
                curradd++;
            }
            else
            {
                mem[curradd]=0xB000|(rd<<9);
                mark[curradd]|=0x80000002;
                curradd++;
            }
            continue;
        }
// str -----------------------------------------------------------
        if(strncmp(&newline[ra],"str ",4)==0)
        {
            ra+=4;
            //str rd,rs,#offset
            ra=parse_two_regs(ra); if(ra==0) return(1);
            ra=parse_comma(ra); if(ra==0) return(1);
            ra=parse_pound(ra); if(ra==0) return(1);
            ra=parse_immed(ra); if(ra==0) return(1);
            if(rest_of_line(ra)) return(1);
            if(check_simmed6(rx)) return(1);
            mem[curradd]=0x7000|(rd<<9)|(rs<<6)|(rx&0x003F);
            mark[curradd]|=0x80000000;
            curradd++;
            continue;
        }
// trap -----------------------------------------------------------
        if(strncmp(&newline[ra],"trap ",5)==0)
        {
            ra+=5;
            //trap imm
            ra=parse_immed(ra); if(ra==0) return(1);
            if((rx&0xFF)!=rx)
            {
                printf("<%u> Error: invalid trap vector\n",line);
                return(1);
            }
            mem[curradd]=0xF000|(rx&0xFF);
            mark[curradd]|=0x80000000;
            curradd++;
            if(rest_of_line(ra)) return(1);
            continue;
        }
// -----------------------------------------------------------
        printf("<%u> Error: syntax error\n",line);
        return(1);
    }
    return(0);
}
示例#3
0
int
parse_inst(char *label, char *inst, char args[][16])
{
  int i=0;
  int j;
  WORD a[3];
  int len;

  /* find the instruction */
  while( instructions[i].inst ) {
    if( !strcasecmp(instructions[i].inst,inst) ) break;
    i++;
  }

  /* check if we had a match */
  if( !instructions[i].inst ) {
    /* didn't find the instruction */
    pendvm_error("undefined instruction");
    return -1;
  }

  /* we have a match. process each of the 3 args */
  for(j=0;j<3;j++) {
    switch(instructions[i].args[j]) {
    case NIL:
      a[j]=0;
      break;
    case REG: {
      int reg=parse_reg(args[j]);
      if(reg==-1) {
	pendvm_error("expected register");
	return -1;
      } else if(reg==-2) {
	pendvm_error("register out of range");
	return -1;
      } else {
	a[j]=reg;
      }
      break;
    }
    case AMT:
    case IMM: {
      int *immed;

      if( instructions[i].args[j]==AMT )
	len=16;
      else
	len=5; /* ??? */

      immed=parse_immed(args[j],len);

      if( !immed ) {
	pendvm_error("bad immediate/amt");
	return -1;
      } else {
	a[j]=*immed;
      }
      break;
    }
    case OFF:
    case LOFF: {
      int *absolute;

      if( instructions[i].args[j]==OFF )
	len=16;
      else
	len=26; /* ??? */

      absolute=parse_immed(args[j],len);

      if( !absolute ) {
	pendvm_error("bad offset");
	return -1;
      } else {
	a[j]=*absolute - m->PC;
      }
      break;
    }
    } /* switch */
  } /* for (step through 3 args) */

  /* now do the right thing */
  return (*instructions[i].func)(a[0],a[1],a[2]);

}