|
|
1.1 ! root 1: #include "core.pub" ! 2: #include "symtab.pub" ! 3: #include "memory.pri" ! 4: #include "parse.h" ! 5: #include "expr.pub" ! 6: #include "frame.pub" ! 7: #include "process.pub" ! 8: #include "format.pub" ! 9: #include "journal.pub" ! 10: SRCFILE("memory.c") ! 11: ! 12: Memory::Memory(Core *c) ! 13: { ! 14: core = c; ! 15: prevpat = 0; ! 16: } ! 17: ! 18: void Memory::userclose() ! 19: { ! 20: trace("%d.userclose()", this); VOK; ! 21: delete pad; ! 22: pad = 0; ! 23: invalidate(); ! 24: Cell *cellsetsib; ! 25: for( ; cellset; cellset = cellsetsib ){ ! 26: cellsetsib = cellset->sib; // new malloc ! 27: delete cellset; ! 28: } ! 29: current = 0; ! 30: } ! 31: ! 32: void Memory::makecell(Cell *model, long addr ) ! 33: { ! 34: Cell *c; ! 35: ! 36: trace( "%d.makecell(%d,%d)", this, model, addr ); VOK; ! 37: if( !model ){ ! 38: model = new Cell(this); ! 39: model->fmt = F_HEX; ! 40: model->size = 1; ! 41: } ! 42: for( c = cellset; c; c = c->sib ) ! 43: if( addr == c->addr ) break; ! 44: if( !c ){ ! 45: c = new Cell(this); ! 46: c->addr = addr; ! 47: c->sib = cellset; ! 48: cellset = c; ! 49: } ! 50: c->fmt = model->fmt; ! 51: c->size = model->size; ! 52: c->display(); ! 53: current = c; ! 54: } ! 55: ! 56: void Memory::banner() ! 57: { ! 58: trace( "%d.banner()", this ); VOK; ! 59: if( pad ){ ! 60: pad->banner("Memory: %s", core->procpath()); ! 61: pad->name("Mem %s", basename(core->procpath())); ! 62: } ! 63: } ! 64: ! 65: void Memory::open(long a) ! 66: { ! 67: trace( "%d.open(%d)", this, a ); VOK; ! 68: if( !pad ){ ! 69: pad = new Pad((PadRcv*) this); ! 70: banner(); ! 71: } ! 72: pad->makecurrent(); ! 73: if( a ) makecell(current,a); ! 74: } ! 75: ! 76: char *Memory::help() ! 77: { ! 78: return ".=<expr> {show memory cell at address}"; ! 79: } ! 80: ! 81: char *Memory::kbd(char *s) ! 82: { ! 83: Parse y(G_DOTEQ_CONEX,0); ! 84: Expr *e; ! 85: Bls error; ! 86: ! 87: trace( "%d.kbd(%s)", this, s ); OK(0); ! 88: if( !(e = (Expr*)y.parse(s)) ) ! 89: return sf("%s: %s", y.error, s); ! 90: e->evaltext(core->process()->globals, error); ! 91: if( e->evalerr ) ! 92: return sf("%s: %s", s, error.text); ! 93: makecell(current,e->val.lng); ! 94: return 0; ! 95: } ! 96: ! 97: struct FmtSize { ! 98: long fmt; ! 99: long size; ! 100: }; ! 101: ! 102: FmtSize FS[] = { ! 103: F_DECIMAL, 7, ! 104: F_SIGNED, 7, ! 105: F_OCTAL, 7, ! 106: F_HEX, 7, ! 107: F_ASCII, 7, ! 108: F_SYMBOLIC, 7, ! 109: F_TIME, 4, ! 110: F_FLOAT, 4, ! 111: F_DOUBLE, 8, ! 112: F_DBLHEX, 8, ! 113: 0, 0 ! 114: }; ! 115: ! 116: Index Cell::carte() ! 117: { ! 118: Menu m, s, f; ! 119: ! 120: OK(ZIndex); ! 121: m.last( spy ? "unspy" : "spy on", (Action)&Cell::setspy, !spy ); ! 122: s.last("1 byte ", (Action)&Cell::resize, 1); ! 123: s.last("2 bytes", (Action)&Cell::resize, 2); ! 124: s.last("4 bytes", (Action)&Cell::resize, 4); ! 125: s.last("8 bytes", (Action)&Cell::resize, 8); ! 126: m.last(s.index("size")); ! 127: ! 128: for( int i = 0; FS[i].fmt; ++i ) ! 129: if( FS[i].size & size ){ ! 130: long b = FS[i].fmt; ! 131: if( fmt&b ) b |= F_TURNOFF; ! 132: f.last(FmtName(b), (Action)&Cell::reformat, b); ! 133: } ! 134: m.last(f.index("format")); ! 135: m.last( ".+1", (Action)&Cell::relative, 1 ); ! 136: m.last( ".+2", (Action)&Cell::relative, 2 ); ! 137: m.last( ".+4", (Action)&Cell::relative, 4 ); ! 138: if( size < 8 ) ! 139: m.last( "* thru .", (Action)&Cell::indirect, 0 ); ! 140: m.last( ".-1", (Action)&Cell::relative, -1 ); ! 141: m.last( ".-2", (Action)&Cell::relative, -2 ); ! 142: m.last( ".-4", (Action)&Cell::relative, -4 ); ! 143: ! 144: m.last( "asmblr", (Action)&Cell::asmblr, 0 ); ! 145: ! 146: return m.index(); ! 147: } ! 148: ! 149: void Cell::dodisplay(Bls &t) ! 150: { ! 151: Cslfd *m; ! 152: long afmt = fmt&~(F_ASCII|F_DOUBLE|F_FLOAT|F_DBLHEX|F_TIME); ! 153: long cfmt = fmt&~F_SYMBOLIC; ! 154: switch( size ){ ! 155: case 8: ! 156: if( !(cfmt &= F_DOUBLE|F_DBLHEX) ) ! 157: cfmt = F_DOUBLE; ! 158: break; ! 159: default: ! 160: if( !(cfmt &= ~(F_DOUBLE|F_DBLHEX)) ) ! 161: cfmt = F_HEX; ! 162: } ! 163: Format a(afmt?afmt:F_HEX, memory->core->symtab()); ! 164: Format c(cfmt); ! 165: if( spy ) t.af( ">>> " ); ! 166: t.af( "%s/%d: ", a.f(addr), size ); ! 167: switch( size ){ ! 168: case 1: c.format |= F_MASKEXT8; break; ! 169: case 2: c.format |= F_MASKEXT16; break; ! 170: } ! 171: if( m = memory->core->peek(addr,0) ){ ! 172: long val; ! 173: switch( size ){ ! 174: case 1: c.format |= F_MASKEXT8; ! 175: val = m->chr; ! 176: break; ! 177: case 2: c.format |= F_MASKEXT16; ! 178: val = m->sht; ! 179: break; ! 180: case 4: val = m->lng; ! 181: } ! 182: t.af( "%s", c.f(val, m->dbl) ); ! 183: if( spy ) *spy = *m; ! 184: } else ! 185: t.af( "cannot read" ); ! 186: } ! 187: ! 188: void Cell::display(char *error, int j) ! 189: { ! 190: Bls t; ! 191: ! 192: trace( "%d.display()", this ); VOK; ! 193: dodisplay(t); ! 194: if( error ) t.af( " %s", error ); ! 195: Attrib attrib = ACCEPT_KBD|SELECTLINE; ! 196: if( spy ) attrib |= DONT_CUT; ! 197: memory->pad->insert(addr, attrib, (PadRcv*)this, carte(), "%s", t.text); ! 198: if( j ) ! 199: memory->core->process()->journal()->insert("%s", t.text); ! 200: } ! 201: ! 202: int Cell::changed() ! 203: { ! 204: int changed = 0; ! 205: Cslfd *m; ! 206: ! 207: trace( "%d.changed()" ); OK(0); ! 208: if( !spy ) return 0; ! 209: m = memory->core->peek(addr); ! 210: switch( size ){ ! 211: case 1: if( m->chr != spy->chr ) changed = 1; break; ! 212: case 2: if( m->sht != spy->sht ) changed = 1; break; ! 213: case 4: if( m->lng != spy->lng ) changed = 1; break; ! 214: case 8: if( m->dbl != spy->dbl ) changed = 1; break; ! 215: } ! 216: if( changed ) display(0,1); ! 217: return changed; ! 218: } ! 219: ! 220: ! 221: void Cell::setspy(long s) ! 222: { ! 223: trace( "%d.setspy(%d)", this, s ); VOK; ! 224: if( !s && spy ){ ! 225: delete spy; ! 226: spy = 0; ! 227: } else if( s ) ! 228: spy = new Cslfd; ! 229: display(); ! 230: } ! 231: ! 232: void Cell::relative(long a) ! 233: { ! 234: trace( "%d.relative(%d)", this, a ); VOK; ! 235: memory->makecell(this,addr+a*size); ! 236: } ! 237: ! 238: void Cell::indirect() ! 239: { ! 240: Cslfd *m; ! 241: ! 242: trace( "%d.indirect()", this ); VOK; ! 243: if( !(m = memory->core->peek(addr,0)) ) ! 244: display(); /* will have same problem */ ! 245: else ! 246: memory->makecell(this, size==1 ? (unsigned char) m->chr ! 247: : size==2 ? (unsigned short) m->sht : m->lng); ! 248: } ! 249: ! 250: char *Cell::help() ! 251: { ! 252: return "$=<expr> {update cell} | .=<expr> {open cell} | [/?]<string> {search}"; ! 253: } ! 254: ! 255: char *Cell::search(int dir, char *pat) ! 256: { ! 257: Cell s(memory); ! 258: ! 259: trace("%d.search(%d,%s)", this, dir, pat?pat:"0"); OK("Cell::search"); ! 260: if( !pat || !*pat || !strcmp(pat,"?") || !strcmp(pat,"/") ) ! 261: pat = memory->prevpat; ! 262: memory->prevpat = sf("%s", pat); ! 263: int patlen = strlen(pat); ! 264: s = *this; ! 265: long t0 = time(0); ! 266: for( s.addr = addr+dir*size; s.addr != addr; s.addr += dir*size ){ ! 267: Cslfd *m = memory->core->peek(s.addr, 0); ! 268: if( !m ){ ! 269: memory->makecell(this,s.addr); ! 270: return "memory not contiguously readable for search"; ! 271: } ! 272: Bls t; ! 273: s.dodisplay(t); ! 274: register char *p, pat0 = *pat; ! 275: for( p = t.text; *p; ++p ){ ! 276: if( *p == pat0 && !strncmp(p, pat, patlen) ){ ! 277: memory->makecell(this,s.addr); ! 278: return 0; ! 279: } ! 280: } ! 281: const timeout = 10; ! 282: if( time(0) > t0+timeout ){ ! 283: memory->makecell(this,s.addr); ! 284: return sf("search timeout (%d secs)", timeout); ! 285: } ! 286: } ! 287: } ! 288: ! 289: char *Cell::kbd(char *s) /* should eval against loader symbol frame */ ! 290: { ! 291: Parse y(G_DOLEQ_CONEX, 0); ! 292: Expr *e; ! 293: Bls t; ! 294: ! 295: trace( "%d.kbd(%s)", this, s ); OK("kbd"); ! 296: if( !*s ){ ! 297: relative(1); ! 298: return 0; ! 299: } ! 300: if( s[0] == '/' ) ! 301: return search( 1, s+1); ! 302: if( s[0] == '?' ) ! 303: return search(-1, s+1); ! 304: if( (e = (Expr*)y.parse(s)) ){ ! 305: e->evaltext(memory->core->process()->globals, t); ! 306: display(e->evalerr ? t.text ! 307: : memory->core->poke(addr,e->val.lng,size)); ! 308: return 0; ! 309: } ! 310: return memory->kbd(s); ! 311: } ! 312: ! 313: void Cell::reformat(long f) ! 314: { ! 315: trace( "%d.reformat(0x%X) 0x%X ", this, f, fmt ); VOK; ! 316: fmt ^= f; ! 317: if( f&F_TURNOFF ) ! 318: fmt &= ~f; ! 319: else ! 320: fmt |= f; ! 321: display(); ! 322: } ! 323: ! 324: void Cell::resize(int s) ! 325: { ! 326: trace( "%d.resize(%d) %d", this, s, size ); VOK; ! 327: size = s; ! 328: reformat(0); ! 329: } ! 330: ! 331: void Cell::asmblr() ! 332: { ! 333: trace( "%d.asmblr()" ); VOK; ! 334: memory->core->process()->openasm(addr); ! 335: } ! 336: ! 337: int Memory::changes(long verbose) ! 338: { ! 339: Cell *c; ! 340: long changes = 0, key = 0x40000000, spies = 0; /* !!! */ ! 341: trace( "%d.changes()", this ); OK(0); ! 342: ! 343: pad->removeline(key); ! 344: for( c = cellset; c; c = c->sib ) ! 345: if( c->spy ){ ! 346: ++spies; ! 347: changes += c->changed(); ! 348: } ! 349: if( verbose ){ ! 350: if( spies == 0 ) ! 351: pad->insert( key, SELECTLINE, "no spies" ); ! 352: else if( changes==0 ) ! 353: pad->insert( key, SELECTLINE, "no spies changed" ); ! 354: } ! 355: return changes; ! 356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.