/* * esa1.c * Assemble a line. */ #include #include "esa.h" /* * Assemble a line. * The code is saved in the code * buffers for use by the listing * generator. * Binary code gets written right * out. */ asmline() { register struct sym *sp; register int rs, rd; int a, c, f, opcode; char id[NCPS]; listaddr = dot->s_value; listmode = SLIST; loop: if((c=getnb())=='\0' || c=='/') return; if(!alpha(c)) { err('q'); return; } getid(c, id); /* * Direct assignment. */ if((c=getnb()) == '=') { sp = lookup(id, ust); if(sp->s_type!=S_UND && (sp->s_flag&SF_ASG)==0) err('m'); sp->s_type = S_ABS; sp->s_flag |= SF_ASG; sp->s_value = listaddr = expr(); listmode = ALIST; /* * Label. */ } else if(c == ':') { if((sp=lookup(id, ust)) == dot) err('.'); else if(pass==0) { if(sp->s_type!=S_UND && (sp->s_flag&SF_ASG)==0) sp->s_flag |= SF_MDF; sp->s_type = S_ABS; sp->s_value = dot->s_value; } else { if((sp->s_flag&SF_MDF)!=0) err('m'); if(sp->s_type!=S_ABS || sp->s_value!=dot->s_value) err('p'); } listmode = ALIST; goto loop; /* * Normal (keyword) line. */ } else { putback(c); listmode = CLIST; if((sp=lookup(id, pst)) == NULL) err('o'); else { opcode = sp->s_value; switch(sp->s_type) { case S_BYTE: do { a = expr(); byte(a); codeb(a); } while((c=getnb()) == ','); putback(c); break; case S_WORD: do { a = expr(); codew(a); } while((c=getnb()) == ','); putback(c); break; case S_ASCII: ascii(0); break; case S_ASCIZ: ascii(1); break; case S_BLKB: a = expr(); if((c=getnb()) == ',') f = expr(); else { putback(c); f = 0; } while(a--) codeb(f); listmode = ALIST; break; case S_OP1: codeb(opcode); break; case S_OP2: a = expr(); byte(a); codeb(opcode); codeb(a); break; case S_OP3: a = expr(); codeb(opcode); codew(a); break; case S_OP4: lrp(LBI, LCI); break; case S_OP5: lrp(LDI, LEI); break; case S_OP6: lrp(LHI, LLI); break; case S_IN: a = expr(); if((a&~07) != 0) err('t'); codeb(opcode | a<<1); break; case S_OUT: a = expr(); if((a&~037)!=0 || a<010) err('t'); codeb(opcode | a<<1); break; default: err('o'); } } } if((c=getnb())!='\0' && c!='/') err('q'); } /* * Code a load register pair * instruction. * The opcode used to load up * the hi half is `hi'; the * one for the low half is * `lo'. */ lrp(hi, lo) { register int a; a = expr(); codeb(hi); codeb(a>>8); codeb(lo); codeb(a); } /* * Process the body of a `.ascii' or of a * `.asciz'. * The `z' flag is true for an * `.asciz'. */ ascii(z) { register int c, delim; if((delim=getnb()) == '\0') { err('q'); return; } while((c=getmap())!='\0' && c!=delim) codeb(c); if(c == '\0') err('q'); if(z) codeb(0); } /* * Given a number (usually the result * of an expression, check that the * number can be expressed in a byte. * If it cannot put out a `t' error. */ byte(b) { if((b&0200)!=0) b |= ~0377; if(b>127 || b<-128) err('t'); }