|
|
1.1 root 1: /*
2: * Output routines.
3: * Intel iAPX-86.
4: * Small model.
5: */
6: #include <canon.h>
7: #include "asm.h"
8:
9: #define NTXT 128
10: #define NREL 128
11:
12: #define outlst(b) { if (cp < &cb[NCODE]) *cp++ = (b); }
13:
14: address txtla;
15: long crbase;
16: long crseek;
17: struct ldheader ldh;
18: struct loc *txtlp;
19: char txt[NTXT];
20: char rel[NREL];
21: char *txtp = { txt };
22: char *relp = { rel };
23:
24: outab(b)
25: {
26: if (pass == 2) {
27: if (inbss)
28: serr();
29: else {
30: outlst(b);
31: outchk(1, 0);
32: *txtp++ = fbyte(b);
33: }
34: }
35: ++dot->s_addr;
36: }
37:
38: outaw(w)
39: {
40: if (pass == 2) {
41: if (inbss)
42: serr();
43: else {
44: outlst(fbyte(w));
45: outlst(sbyte(w));
46: outchk(2, 0);
47: *txtp++ = fbyte(w);
48: *txtp++ = sbyte(w);
49: }
50: }
51: dot->s_addr += 2;
52: }
53:
54: outrb(esp, pcrf)
55: register struct expr *esp;
56: {
57: register address a;
58: register n;
59: int t;
60:
61: if (pass == 2) {
62: if (inbss)
63: serr();
64: else {
65: t = esp->e_type;
66: if (t==E_AREG || t==E_ASEG)
67: t = E_ACON;
68: a = esp->e_addr;
69: if (pcrf)
70: a -= dot->s_addr+1;
71: outlst(fbyte(a));
72: if (t == E_ACON) {
73: n = 0;
74: if (pcrf)
75: n = 3;
76: outchk(1, n);
77: *txtp++ = fbyte(a);
78: if (pcrf) {
79: *relp++ = LR_BYTE|LR_PCR|L_ABS;
80: *relp++ = fbyte(dot->s_addr);
81: *relp++ = sbyte(dot->s_addr);
82: }
83: } else {
84: n = 3;
85: if (t == E_SYM)
86: n = 5;
87: outchk(1, n);
88: *txtp++ = fbyte(a);
89: n = LR_BYTE;
90: if (pcrf)
91: n |= LR_PCR;
92: if (t == E_SYM)
93: n |= L_SYM;
94: else
95: n |= esp->e_base.e_lp->l_seg;
96: *relp++ = n;
97: *relp++ = fbyte(dot->s_addr);
98: *relp++ = sbyte(dot->s_addr);
99: if (t == E_SYM) {
100: n = esp->e_base.e_sp->s_ref;
101: *relp++ = fbyte(n);
102: *relp++ = sbyte(n);
103: }
104: }
105: }
106: }
107: ++dot->s_addr;
108: }
109:
110: outrw(esp, pcrf)
111: register struct expr *esp;
112: {
113: register address a;
114: register n;
115: int t;
116:
117: if (pass == 2) {
118: if (inbss)
119: serr();
120: else {
121: t = esp->e_type;
122: if (t==E_AREG || t==E_ASEG)
123: t = E_ACON;
124: a = esp->e_addr;
125: if (pcrf)
126: a -= dot->s_addr+2;
127: outlst(fbyte(a));
128: outlst(sbyte(a));
129: if (t == E_ACON) {
130: n = 0;
131: if (pcrf)
132: n = 3;
133: outchk(2, n);
134: *txtp++ = fbyte(a);
135: *txtp++ = sbyte(a);
136: if (pcrf) {
137: *relp++ = LR_WORD|LR_PCR|L_ABS;
138: *relp++ = fbyte(dot->s_addr);
139: *relp++ = sbyte(dot->s_addr);
140: }
141: } else {
142: n = 3;
143: if (t == E_SYM)
144: n = 5;
145: outchk(2, n);
146: *txtp++ = fbyte(a);
147: *txtp++ = sbyte(a);
148: n = LR_WORD;
149: if (pcrf)
150: n |= LR_PCR;
151: if (t == E_SYM)
152: n |= L_SYM;
153: else
154: n |= esp->e_base.e_lp->l_seg;
155: *relp++ = n;
156: *relp++ = fbyte(dot->s_addr);
157: *relp++ = sbyte(dot->s_addr);
158: if (t == E_SYM) {
159: n = esp->e_base.e_sp->s_ref;
160: *relp++ = fbyte(n);
161: *relp++ = sbyte(n);
162: }
163: }
164: }
165: }
166: dot->s_addr += 2;
167: }
168:
169: /*
170: * Make sure there is room in
171: * the buffers for `nt' bytes worth
172: * text and `nr' bytes of rel.
173: * If not, write the buffers out
174: * to the file.
175: */
176: outchk(nt, nr)
177: {
178: register unsigned n;
179: register tn;
180: long ts;
181:
182: if (txtp+nt>&txt[NTXT] || relp+nr>&rel[NREL]) {
183: if ((n = txtp-txt) != 0) {
184: ts = txtla + sizeof(ldh);
185: tn = txtlp->l_seg;
186: if (tn > L_BSSI) {
187: ts -= ldh.l_ssize[L_BSSI];
188: if (tn > L_BSSD)
189: ts -= ldh.l_ssize[L_BSSD];
190: }
191: fseek(ofp, ts, 0);
192: xwrite(txt, sizeof(char), n);
193: if ((n = relp-rel) != 0) {
194: fseek(ofp, crseek, 0);
195: xwrite(rel, sizeof(char), n);
196: crseek += n;
197: relp = rel;
198: }
199: }
200: txtp = txt;
201: }
202: if (txtp == txt) {
203: txtla = dot->s_addr;
204: txtlp = dot->s_base.s_lp;
205: }
206: }
207:
208: outinit()
209: {
210: register struct loc *lp;
211: register struct sym *sp;
212: register i;
213: struct ldsym lds;
214: int rn;
215: long sb, ss;
216:
217: ldh.l_magic = L_MAGIC;
218: ldh.l_flag = 0;
219: ldh.l_machine = M_8086;
220: ldh.l_entry = 0;
221: sb = sizeof(ldh);
222: for (i=0; i<nloc; ++i) {
223: ss = 0;
224: lp = loc[i];
225: while (lp != NULL) {
226: ss += locrup(lp->l_break);
227: lp = lp->l_lp;
228: }
229: ldh.l_ssize[i] = ss;
230: if (i!=L_BSSI && i!=L_BSSD)
231: sb += ss;
232: }
233: fseek(ofp, sb, 0);
234: ss = 0;
235: rn = 0;
236: for (i=0; i<NHASH; ++i) {
237: sp = symhash[i];
238: while (sp != NULL) {
239: if (((sp->s_flag&S_SYMT) != 0)
240: && ((xflag == 0) || ((sp->s_flag&S_GBL) != 0))) {
241: sp->s_ref = rn++;
242: symcopy(lds.ls_id, sp->s_id);
243: if (sp->s_kind == S_NEW)
244: lds.ls_type = L_REF;
245: else if (sp->s_type != E_DIR)
246: lds.ls_type = L_ABS;
247: else
248: lds.ls_type = sp->s_base.s_lp->l_seg;
249: if ((sp->s_flag&S_GBL) != 0)
250: lds.ls_type |= L_GLOBAL;
251: lds.ls_addr = sp->s_addr;
252: xwrite(&lds, sizeof(lds), 1);
253: ss += sizeof(lds);
254: }
255: sp = sp->s_sp;
256: }
257: }
258: ldh.l_ssize[L_SYM] = ss;
259: crseek = sb+ss;
260: crbase = crseek;
261: }
262:
263: /*
264: * Finish up l.out
265: */
266: outfinish()
267: {
268: register int i;
269:
270: ldh.l_ssize[L_REL] = crseek-crbase;
271: canint(ldh.l_magic);
272: canint(ldh.l_flag);
273: canint(ldh.l_machine);
274: canvaddr(ldh.l_entry);
275: for (i=0; i<NLSEG; i++)
276: cansize(ldh.l_ssize[i]);
277: fseek(ofp, (long)0, 0);
278: xwrite(&ldh, sizeof(ldh), 1);
279: fclose(ofp);
280: }
281:
282: /*
283: * Write code file.
284: * Check for any errors.
285: */
286: xwrite(p, s, n)
287: char *p;
288: {
289: if (fwrite(p, s, n, ofp) != n) {
290: fprintf(stderr, "%s: I/O error.\n", ofn);
291: exit(1);
292: }
293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.