00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "UCProcess.h"
00022 #include "UCMachine.h"
00023 #include "Usecode.h"
00024 #include "GameData.h"
00025 #include "IDataSource.h"
00026 #include "ODataSource.h"
00027
00028
00029 DEFINE_RUNTIME_CLASSTYPE_CODE(UCProcess,Process);
00030
00031 UCProcess::UCProcess() : Process()
00032 {
00033 usecode = GameData::get_instance()->getMainUsecode();
00034 }
00035
00036 UCProcess::UCProcess(uint16 classid_, uint16 offset_, uint32 this_ptr,
00037 int thissize, const uint8* args, int argsize)
00038 : Process()
00039 {
00040 classid = 0xFFFF;
00041 ip = 0xFFFF;
00042 bp = 0x0000;
00043 usecode = GameData::get_instance()->getMainUsecode();
00044 temp32 = 0;
00045
00046 load(classid_, offset_, this_ptr, thissize, args, argsize);
00047 }
00048
00049 UCProcess::~UCProcess()
00050 {
00051
00052 }
00053
00054 void UCProcess::load(uint16 classid_, uint16 offset_, uint32 this_ptr,
00055 int thissize, const uint8* args, int argsize)
00056 {
00057 if (usecode->get_class_size(classid_) == 0)
00058 perr << "Class is empty..." << std::endl;
00059
00060 classid = 0xFFFF;
00061 ip = 0xFFFF;
00062 bp = 0x0000;
00063 uint16 thissp = 0;
00064
00065
00066 if (this_ptr != 0 && thissize > 0) {
00067 stack.addSP(-thissize);
00068 UCMachine::get_instance()->
00069 dereferencePointer(this_ptr, stack.access(), thissize);
00070 thissp = stack.getSP();
00071 }
00072
00073
00074 stack.push(args, argsize);
00075
00076
00077 if (thissp != 0)
00078 stack.push4(UCMachine::stackToPtr(pid, thissp));
00079
00080
00081 call(classid_, offset_);
00082 }
00083
00084 bool UCProcess::run(const uint32 )
00085 {
00086 if (flags & PROC_SUSPENDED)
00087 return false;
00088
00089
00090
00091 return UCMachine::get_instance()->execProcess(this);
00092 }
00093
00094 void UCProcess::call(uint16 classid_, uint16 offset_)
00095 {
00096 stack.push2(classid);
00097 stack.push2(ip);
00098 stack.push2(bp);
00099
00100 classid = classid_;
00101 ip = offset_;
00102 bp = static_cast<uint16>(stack.getSP());
00103 }
00104
00105 bool UCProcess::ret()
00106 {
00107 stack.setSP(bp);
00108
00109 bp = stack.pop2();
00110 ip = stack.pop2();
00111 classid = stack.pop2();
00112
00113 if (ip == 0xFFFF && classid == 0xFFFF)
00114 return true;
00115 else
00116 return false;
00117 }
00118
00119 void UCProcess::freeOnTerminate(uint16 index, int type)
00120 {
00121 assert(type >= 1 && type <= 3);
00122
00123 std::pair<uint16, int> p;
00124 p.first = index;
00125 p.second = type;
00126
00127 freeonterminate.push_back(p);
00128 }
00129
00130 void UCProcess::terminate()
00131 {
00132 std::list<std::pair<uint16, int> >::iterator i;
00133
00134 for (i = freeonterminate.begin(); i != freeonterminate.end(); ++i) {
00135 uint16 index = (*i).first;
00136 int type = (*i).second;
00137
00138 switch (type) {
00139 case 1:
00140 UCMachine::get_instance()->freeString(index);
00141 break;
00142 case 2:
00143 UCMachine::get_instance()->freeStringList(index);
00144 break;
00145 case 3:
00146 UCMachine::get_instance()->freeList(index);
00147 break;
00148 }
00149 }
00150
00151 freeonterminate.clear();
00152
00153 Process::terminate();
00154 }
00155
00156 void UCProcess::dumpInfo()
00157 {
00158 Process::dumpInfo();
00159
00160 if (classid == 0xFFFF) {
00161 pout.printf("IP undefined\n");
00162 } else {
00163 const char* classname = GameData::get_instance()->getMainUsecode()->
00164 get_class_name(classid);
00165 pout.printf("classname: %s, IP: %04X:%04X\n", classname, classid, ip);
00166 }
00167 }
00168
00169 void UCProcess::saveData(ODataSource* ods)
00170 {
00171 Process::saveData(ods);
00172
00173 ods->write2(bp);
00174 ods->write2(classid);
00175 ods->write2(ip);
00176 ods->write4(temp32);
00177 ods->write4(freeonterminate.size());
00178 std::list<std::pair<uint16, int> >::iterator iter;
00179 for (iter = freeonterminate.begin(); iter != freeonterminate.end(); ++iter)
00180 {
00181 ods->write2(iter->first);
00182 ods->write4(static_cast<uint32>(iter->second));
00183 }
00184 stack.save(ods);
00185 }
00186
00187 bool UCProcess::loadData(IDataSource* ids, uint32 version)
00188 {
00189 if (!Process::loadData(ids, version)) return false;
00190
00191 bp = ids->read2();
00192 classid = ids->read2();
00193 ip = ids->read2();
00194 temp32 = ids->read4();
00195 uint32 freecount = ids->read4();
00196 for (unsigned int i = 0; i < freecount; ++i) {
00197 std::pair<uint16, int> p;
00198 p.first = ids->read2();
00199 p.second = static_cast<int>(ids->read4());
00200 freeonterminate.push_back(p);
00201 }
00202 stack.load(ids, version);
00203
00204 return true;
00205 }