|
|
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.