|
|
1.1 root 1: #include "asm.pri"
2: #include "core.pub"
3: #include "format.pub"
4: #include "parse.h"
5: #include "expr.pub"
6: #include "frame.pub"
7: #include "process.pub"
8: #include "symtab.pub"
9: #include "symbol.h"
10: #include "bpts.pub"
11: SRCFILE("asm.c")
12:
13: char *Instr::arg(int) { return "<arg>"; }
14: char *Instr::mnemonic() { return sf("0x%X?", opcode&0xFF); }
15: int Instr::argtype(int) { return 0; }
16: int Instr::nargs() { return 0; }
17: char *Asm::literaldelimiter() { return "<literal>"; }
18: Instr *Asm::newInstr(long) { return 0; }
19:
20: Asm::Asm(Core *c)
21: {
22: trace( "%d.Asm(%d)", this, c ); VOK;
23: core = c;
24: fmt = F_SYMBOLIC|F_HEX;
25: }
26:
27: void Asm::userclose()
28: {
29: trace( "%d.userclose()", this ); VOK;
30: delete pad;
31: pad = 0;
32: Instr *instrsetsib;
33: for( ; instrset; instrset = instrsetsib ){
34: instrsetsib = instrset->sib; // new malloc
35: delete instrset;
36: }
37: }
38:
39: void Asm::banner()
40: {
41: trace( "%d.banner()", this ); VOK;
42: if( pad ){
43: pad->banner("Assembler: %s", core->procpath());
44: pad->name("Asm %s", basename(core->procpath()));
45: }
46: }
47:
48: void Asm::open(long a)
49: {
50: trace("%d.open(%d)", this, a); VOK;
51: if( !pad ){
52: Menu m;
53: pad = new Pad( (PadRcv*) this );
54: banner();
55: m.last( "display pc", (Action)&Asm::displaypc );
56: if( core->online() ){
57: m.first( "run", (Action)&Asm::go );
58: m.last( "step 1 instr ", (Action)&Asm::instrstep, 1 );
59: m.last( "step 4 instrs", (Action)&Asm::instrstep, 4 );
60: m.last( "step 16 instrs", (Action)&Asm::instrstep, 16 );
61: m.last( "step 64 instrs", (Action)&Asm::instrstep, 64 );
62: m.last( "step over call", (Action)&Asm::stepover );
63: }
64: pad->menu(m);
65: }
66: pad->makecurrent();
67: if( a ) newInstr(a);
68: }
69:
70: void Asm::go()
71: {
72: trace( "%d.go()", this ); VOK;
73: core->process()->go();
74: }
75:
76: void Asm::displaypc()
77: {
78: trace("%d.displaypc()", this); VOK;
79: open(core->pc());
80: }
81:
82: char *Asm::help()
83: {
84: trace( "%d.help()", this );
85: return ".=<expr> {display instruction at address}";
86: }
87:
88: char *Asm::kbd(char *s)
89: {
90: Parse y(G_DOTEQ_CONEX,0);
91: Expr *e;
92: Bls error;
93:
94: trace( "%d.kbd(%s)", this, s ); OK("kbd");
95: if( !(e = (Expr*)y.parse(s)) )
96: return sf("%s: %s", y.error, s);
97: e->evaltext(core->process()->globals, error);
98: if( e->evalerr )
99: return sf("%s: %s", s, error.text);
100: newInstr(e->val.lng);
101: return 0;
102: }
103:
104: char *Instr::literal(long f) /* is Format right? */
105: {
106: static char t[128];
107:
108: trace( "%d.literal(0x%X) 0x%X %g", this, f, m.lng, m.flt ); OK("literal");
109: sprintf( t, "%s%s", _asm->literaldelimiter(),
110: Format(f&~F_SYMBOLIC).f(m.lng,m.dbl) );
111: return t;
112: }
113:
114: char *Instr::symbolic(char *prefix) /* is Format right? */
115: {
116: static char t[128];
117:
118: trace( "%d.symbolic(%s) 0x%X", this, prefix, m.lng ); OK("symbolic");
119: strcpy(t, prefix);
120: strcat(t, Format(fmt, _asm->core->symtab()).f(m.lng));
121: return t;
122: }
123:
124: Var *Instr::local(UDisc d, long a) /* VAX */
125: {
126: Func *f;
127: Block *b;
128:
129: trace("%d.local(0x%X,%d)", this, d, a); OK(0);
130: if( !(f = (Func*)_asm->core->symtab()->loctosym(U_FUNC, addr)) ) return 0;
131: if( !(b = f->blk(addr)) ) return 0;
132: BlkVars bv(b);
133: Var *v;
134: while( v = bv.gen() )
135: if( v->disc() == d && v->range.lo == a )
136: break;
137: return v;
138: }
139:
140: Var *Instr::field(Var *v, long a)
141: {
142: trace( "%d.field(%d,%d)", this, v, a ); OK(0);
143: if( !v->type.isptr() ) return 0;
144: DType *d = v->type.decref();
145: if( !d->isstrun() ) return 0;
146: TypMems tm(d->utype());
147: while( v = tm.gen() )
148: if( v->range.lo == a ) break;
149: return v;
150: }
151:
152: char *Instr::regarg(char *lay, long f) /* is Format right? */
153: {
154: static char t[128];
155: char *o, *r;
156: Var *v;
157:
158: trace("%d.regarg(%s,0x%X) %d 0x%X", this, lay, f, reg, m.lng); OK("regarg");
159: r = _asm->core->regname(reg);
160: o = Format(f&~F_SYMBOLIC).f(m.lng);
161: if( f&F_SYMBOLIC ){
162: if( reg == _asm->core->REG_AP() ){
163: if( v = local(U_ARG, m.lng) )
164: o = v->text();
165: } else if( reg == _asm->core->REG_FP() ){
166: if( v = local(U_AUT, m.lng) )
167: o = v->text();
168: } else {
169: if( v = local(U_REG, reg) ){
170: r = sf("%s=%s", v->text(), r);
171: if( v = field(v, m.lng) )
172: o = v->text();
173: }
174: }
175: }
176: sprintf(t, lay, o, r);
177: return t;
178: }
179:
180: void Instr::dobpt(int setorclr)
181: {
182: trace( "%d.dobpt(%d)", this, setorclr ); VOK;
183: Stmt *stmt = new Stmt(0,0,0);
184: stmt->range.lo = addr;
185: stmt->process = _asm->core->process();
186: stmt->dobpt(setorclr);
187: }
188:
189: Instr::Instr(Asm *a, long l)
190: {
191: trace( "%d.Instr(%d,%d)", this, a, l ); VOK;
192: if( !l ) return;
193: addr = l;
194: _asm = a;
195: sib = _asm->instrset;
196: _asm->instrset = this;
197: _asm->banner(); /* why here? */
198: fmt = _asm->fmt;
199: bpt = _asm->core->process()->bpts()->isasmbpt(addr);
200: }
201:
202: void Instr::display()
203: {
204: int i;
205: Bls t;
206:
207: trace( "%d.display()", this ); VOK;
208: if( !addr ) return;
209: t.af("%s%s", bpt?">>>":"", Format(fmt,_asm->core->symtab()).f(addr));
210: opcode = _asm->core->peekcode(addr)->chr;
211: next = addr+1;
212: char *mnem = mnemonic();
213: if( mnem ){
214: t.af(": %s ", mnem);
215: int n = nargs();
216: for( i = 0; i < n; ++i )
217: t.af("%s%s", i?",":"", arg(i));
218: }
219: _asm->pad->insert(addr, SELECTLINE, (PadRcv*)this, carte(), "%s", t.text);
220: }
221:
222: void Instr::showsrc()
223: {
224: trace( "%d.showsrc()", this ); ok();
225: Stmt *stmt = (Stmt*) _asm->core->symtab()->loctosym(U_STMT, addr);
226: if( stmt ) stmt->select();
227: }
228:
229: long AF[] = { F_OCTAL, F_SIGNED, F_HEX, F_SYMBOLIC, 0 };
230:
231: Index Instr::carte()
232: {
233: Menu m, f;
234:
235: trace( "%d.carte()", this ); ok();
236: if( _asm->core->online() ){
237: if( bpt )
238: m.last( "clr bpt", (Action)&Instr::dobpt, 0 );
239: else
240: m.last( "set bpt", (Action)&Instr::dobpt, 1 );
241: }
242: if( _asm->core->symtab()->loctosym(U_STMT, addr) )
243: m.last( "src text", (Action)&Instr::showsrc, 0 );
244: m.last( "open frame", (Action)&Instr::openframe );
245: m.last( "next 1", (Action)&Instr::succ, 1 );
246: m.last( "next 5", (Action)&Instr::succ, 5 );
247: m.last( "next 10", (Action)&Instr::succ, 10 );
248: for( int i = 0; AF[i]; ++i ){
249: long b = AF[i];
250: if( fmt&b ) b |= F_TURNOFF;
251: f.last(FmtName(b), (Action)&Instr::reformat, b);
252: }
253: m.last(f.index("format"));
254: m.last( "refresh", (Action)&Instr::succ, -1 );
255: m.last( "raw mem", (Action)&Instr::memory, 0 );
256: return m.index();
257: }
258:
259: void Instr::openframe()
260: {
261: trace( "%d.openframe()", this ); VOK;
262: _asm->core->process()->openframe(addr);
263: }
264:
265: void Instr::reformat(int f)
266: {
267: trace( "%d.reformat(0x%X) 0x%X", this, f, fmt ); VOK;
268: if( f&F_TURNOFF)
269: fmt &= ~f;
270: else
271: fmt |= f;
272: if( !fmt ) fmt = F_HEX;
273: _asm->fmt = fmt;
274: _asm->newInstr(addr);
275: }
276:
277: void Instr::succ(int n) /* think about it! */
278: {
279: trace( "%d.succ(%d)", this, n ); VOK;
280: _asm->fmt = fmt;
281: if( n>0 ) _asm->newInstr(next)->succ(n-1);
282: else if( n<0 ) _asm->newInstr(addr);
283: }
284:
285: void Instr::memory()
286: {
287: trace( "%d.memory()" ); VOK;
288: _asm->core->process()->openmemory(addr);
289: }
290:
291: void Asm::instrstep(long i)
292: {
293: trace( "%d.instrstep(%d)", this, i ); VOK;
294: core->process()->instrstep(i);
295: }
296:
297: void Asm::stepover()
298: {
299: trace( "%d.stepover()", this ); VOK;
300: core->process()->
301: stepover( core->pc(), newInstr(core->pc())->next );
302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.