|
|
1.1 ! root 1: #include "asm.h" ! 2: ! 3: /* ! 4: * Address mode table. ! 5: * This table is indexed by the number ! 6: * that gets put in the r/m field, ! 7: * and holds a word containing a bit for ! 8: * each index register. ! 9: */ ! 10: ! 11: int amodes[] = { ! 12: (1<<reg(BX)) + (1<<reg(SI)), ! 13: (1<<reg(BX)) + (1<<reg(DI)), ! 14: (1<<reg(BP)) + (1<<reg(SI)), ! 15: (1<<reg(BP)) + (1<<reg(DI)), ! 16: (1<<reg(SI)), ! 17: (1<<reg(DI)), ! 18: (1<<reg(BP)), ! 19: (1<<reg(BX)) ! 20: }; ! 21: ! 22: char segovr[] = { ! 23: 0x26, ! 24: 0x2E, ! 25: 0x36, ! 26: 0x3E ! 27: }; ! 28: ! 29: /* ! 30: * Read an address. ! 31: * Return the addressing mode. ! 32: */ ! 33: addr(esp) ! 34: register struct expr *esp; ! 35: { ! 36: register c; ! 37: ! 38: if ((c = getnb()) == '$') { ! 39: expr(esp, 0); ! 40: esp->e_mode = IM; ! 41: return (IM); ! 42: } ! 43: if (c == '(') { ! 44: addrx(esp); ! 45: esp->e_type = E_ACON; ! 46: esp->e_addr = 0; ! 47: return (esp->e_mode & MMASK); ! 48: } ! 49: unget(c); ! 50: expr(esp, 0); ! 51: if (esp->e_type == E_AREG) { ! 52: esp->e_mode = esp->e_addr; ! 53: if ((esp->e_mode & MMASK) == SEGR) ! 54: if ((c = getnb()) == ':') { /* segment override */ ! 55: outab(segovr[reg(esp->e_addr)]); ! 56: addr(esp); ! 57: } else ! 58: unget(c); ! 59: return (esp->e_mode & MMASK); ! 60: } ! 61: if ((c = getnb()) == '(') { ! 62: addrx(esp); ! 63: if (esp->e_mode==IDX || esp->e_mode==ICL) ! 64: aerr("invalid index register"); ! 65: return (esp->e_mode & MMASK); ! 66: } ! 67: unget(c); ! 68: esp->e_mode = DIR; ! 69: return (DIR); ! 70: } ! 71: ! 72: /* ! 73: * Read in index register field ! 74: * of an address. The leading `(' has already ! 75: * been read. Set the mode into the `e_mode' ! 76: * field of the expression structure. ! 77: */ ! 78: addrx(esp) ! 79: struct expr *esp; ! 80: { ! 81: register struct sym *sp; ! 82: register c, i; ! 83: int mask, mode; ! 84: char id[NCPLN]; ! 85: ! 86: mode = 0; ! 87: do { ! 88: getid(id, -1); ! 89: if ((sp=lookup(id, 0))==NULL || sp->s_type!=E_AREG) ! 90: aerr("index by non-register"); ! 91: else { ! 92: mask = 01 << reg(sp->s_addr); ! 93: if ((mode&mask) != 0) ! 94: aerr("invalid index register"); ! 95: mode |= mask; ! 96: } ! 97: } while ((c = getnb()) == ','); ! 98: if (c != ')') ! 99: qerr("missing ')'"); ! 100: if (mode == (01<<reg(CL))) { ! 101: esp->e_mode = ICL; ! 102: return; ! 103: } ! 104: if (mode == (01<<reg(DX))) { ! 105: esp->e_mode = IDX; ! 106: return; ! 107: } ! 108: for (i=0; i<8; ++i) { ! 109: if (mode == amodes[i]) { ! 110: esp->e_mode = X | i; ! 111: return; ! 112: } ! 113: } ! 114: aerr("invalid index"); ! 115: esp->e_mode = D; ! 116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.