Permalink
Browse files

SCI32: Remove reg32_t and use reg_t in all cases

reg32_t was a transitive solution, before reg_t's were
adapted to use 32-bit addresses internally, and before
support for SCI3 was added. It was introduced as another
way to handle large script offsets in SCI3, and was only
used for the program counter (PC). It's no longer
needed, as we now support SCI3 script offsets using
reg_t's, so we can use make_reg32 in all cases where
we need to access offsets over 64KB
  • Loading branch information...
bluegr committed Aug 25, 2018
1 parent 66cbaee commit 941869c466354356c7ebf76e5c6fe37fe06785cf
@@ -4576,14 +4576,10 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
relativeOffset = true;

if (!scumm_strnicmp(str + 1, "PC", 2)) {
reg32_t pc = s->_executionStack.back().addr.pc;
dest->setSegment(pc.getSegment());
dest->setOffset(pc.getOffset());
*dest = s->_executionStack.back().addr.pc;
offsetStr = str + 3;
} else if (!scumm_strnicmp(str + 1, "P", 1)) {
reg32_t pc = s->_executionStack.back().addr.pc;
dest->setSegment(pc.getSegment());
dest->setOffset(pc.getOffset());
*dest = s->_executionStack.back().addr.pc;;
offsetStr = str + 2;
} else if (!scumm_strnicmp(str + 1, "PREV", 4)) {
*dest = s->r_prev;
@@ -33,7 +33,7 @@ namespace Sci {
class SciEngine;
struct List;

reg_t disassemble(EngineState *s, reg32_t pos, const Object *obj, bool printBWTag, bool printBytecode);
reg_t disassemble(EngineState *s, reg_t pos, const Object *obj, bool printBWTag, bool printBytecode);
bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpOffset);

class Console : public GUI::Debugger {
@@ -58,7 +58,7 @@ enum BreakpointAction {
struct Breakpoint {
BreakpointType _type;
uint32 _address; ///< Breakpoints on exports
reg32_t _regAddress; ///< Breakpoints on addresses
reg_t _regAddress; ///< Breakpoints on addresses
Common::String _name; ///< Breakpoints on selector names
BreakpointAction _action;
};
@@ -298,10 +298,7 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) {
s->variables[VAR_GLOBAL][kGlobalVarSpeed] = make_reg(0, 6);
}

reg_t addr;
addr.setSegment(scriptSeg);
addr.setOffset(address);
return addr;
return make_reg32(scriptSeg, address);
}

reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {
@@ -152,8 +152,7 @@ void Object::init(const Script &owner, reg_t obj_pos, bool initVariables) {
const uint32 nameOffset = _propertyOffsetsSci3[0];
const uint32 relocOffset = owner.getRelocationOffset(nameOffset);
if (relocOffset != kNoRelocation) {
_name.setSegment(obj_pos.getSegment());
_name.setOffset(relocOffset + buf.getUint16SEAt(nameOffset));
_name = make_reg32(obj_pos.getSegment(), relocOffset + buf.getUint16SEAt(nameOffset));
}
#endif
}
@@ -233,10 +233,7 @@ class Object : public Common::Serializable {
* @returns A pointer to the code for the method at the given index.
*/
reg_t getFunction(const uint16 index) const {
reg_t addr;
addr.setSegment(_pos.getSegment());
addr.setOffset(_baseMethod[index * 2 + 1]);
return addr;
return make_reg32(_pos.getSegment(), _baseMethod[index * 2 + 1]);
}

/**
@@ -1060,11 +1060,7 @@ void Script::initializeClasses(SegManager *segMan) {
error("Invalid species %d(0x%x) unknown max %d(0x%x) while instantiating script %d",
species, species, segMan->classTableSize(), segMan->classTableSize(), _nr);

SegmentId segmentId = segMan->getScriptSegment(_nr);
reg_t classOffset;
classOffset.setSegment(segmentId);
classOffset.setOffset(classpos);
segMan->setClassOffset(species, classOffset);
segMan->setClassOffset(species, make_reg32(segMan->getScriptSegment(_nr), classpos));
}

seeker += seeker.getUint16SEAt(2) * mult;
@@ -1195,14 +1191,7 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {
SciSpan<const byte> seeker = getSci3ObjectsPointer();

while (seeker.getUint16SEAt(0) == SCRIPT_OBJECT_MAGIC_NUMBER) {
// We call setSegment and setOffset directly here, instead of using
// make_reg, as in large scripts, seeker - _buf can be larger than
// a 16-bit integer
reg_t reg;
reg.setSegment(segmentId);
reg.setOffset(seeker - *_buf);

Object *obj = scriptObjInit(reg);
Object *obj = scriptObjInit(make_reg32(segmentId, seeker - *_buf));
obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
seeker += seeker.getUint16SEAt(2);
}
@@ -81,12 +81,10 @@ void DebugState::updateActiveBreakpointTypes() {
}

// Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
reg_t disassemble(EngineState *s, reg32_t pos, const Object *obj, bool printBWTag, bool printBytecode) {
reg_t disassemble(EngineState *s, reg_t pos, const Object *obj, bool printBWTag, bool printBytecode) {
SegmentObj *mobj = s->_segMan->getSegment(pos.getSegment(), SEG_TYPE_SCRIPT);
Script *script_entity = NULL;
reg_t retval;
retval.setSegment(pos.getSegment());
retval.setOffset(pos.getOffset() + 1);
reg_t retval = make_reg32(pos.getSegment(), pos.getOffset() + 1);
uint16 param_value = 0xffff; // Suppress GCC warning by setting default value, chose value as invalid to getKernelName etc.
uint i = 0;
Kernel *kernel = g_sci->getKernel();
@@ -261,9 +259,7 @@ reg_t disassemble(EngineState *s, reg32_t pos, const Object *obj, bool printBWTa
}

const uint32 offset = findOffset(param_value, script_entity, pos.getOffset() + bytecount);
reg_t addr;
addr.setSegment(retval.getSegment());
addr.setOffset(offset);
reg_t addr = make_reg32(retval.getSegment(), offset);
if (!s->_segMan->isObject(addr)) {
debugN("\t\"%s\"", s->_segMan->derefString(addr));
} else {
@@ -438,7 +434,7 @@ void SciEngine::scriptDebug() {
}

if (_debugState.seeking != kDebugSeekNothing) {
const reg32_t pc = s->xs->addr.pc;
const reg_t pc = s->xs->addr.pc;
SegmentObj *mobj = s->_segMan->getSegment(pc.getSegment(), SEG_TYPE_SCRIPT);

if (mobj) {
@@ -762,7 +758,7 @@ bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
return found;
}

bool SciEngine::checkAddressBreakpoint(const reg32_t &address) {
bool SciEngine::checkAddressBreakpoint(const reg_t &address) {
if (!(_debugState._activeBreakpointTypes & BREAK_ADDRESS))
return false;

@@ -292,7 +292,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt

ExecStackType stackType = EXEC_STACK_TYPE_VARSELECTOR;
StackPtr curSP = NULL;
reg32_t curFP = make_reg32(0, 0);
reg_t curFP = make_reg32(0, 0);
if (selectorType == kSelectorMethod) {
stackType = EXEC_STACK_TYPE_CALL;
curSP = sp;
@@ -83,7 +83,7 @@ struct ExecStack {

union {
ObjVarRef varp; // Variable pointer for r/w access
reg32_t pc; // Pointer to the initial program counter. Not accurate for the TOS element
reg_t pc; // Pointer to the initial program counter. Not accurate for the TOS element
} addr;

StackPtr fp; // Frame pointer
@@ -105,7 +105,7 @@ struct ExecStack {
reg_t* getVarPointer(SegManager *segMan) const;

ExecStack(reg_t objp_, reg_t sendp_, StackPtr sp_, int argc_, StackPtr argp_,
SegmentId localsSegment_, reg32_t pc_, Selector debugSelector_,
SegmentId localsSegment_, reg_t pc_, Selector debugSelector_,
int debugKernelFunction_, int debugKernelSubFunction_,
int debugExportId_, int debugLocalCallOffset_, int debugOrigin_,
ExecStackType type_) {
@@ -179,51 +179,15 @@ static inline reg_t make_reg(SegmentId segment, uint16 offset) {
return r;
}

#define PRINT_REG(r) (kSegmentMask) & (unsigned) (r).getSegment(), (unsigned) (r).getOffset()

// A true 32-bit reg_t
struct reg32_t {
// Segment and offset. These should never be accessed directly
SegmentId _segment;
uint32 _offset;

inline SegmentId getSegment() const {
return _segment;
}

inline void setSegment(SegmentId segment) {
_segment = segment;
}

inline uint32 getOffset() const {
return _offset;
}

inline void setOffset(uint32 offset) {
_offset = offset;
}

inline void incOffset(int32 offset) {
setOffset(getOffset() + offset);
}

// Comparison operators
bool operator==(const reg32_t &x) const {
return (getOffset() == x.getOffset()) && (getSegment() == x.getSegment());
}

bool operator!=(const reg32_t &x) const {
return (getOffset() != x.getOffset()) || (getSegment() != x.getSegment());
}
};

static inline reg32_t make_reg32(SegmentId segment, uint32 offset) {
reg32_t r;
static inline reg_t make_reg32(SegmentId segment, uint32 offset) {
reg_t r;
r.setSegment(segment);
r.setOffset(offset);
return r;
}

#define PRINT_REG(r) (kSegmentMask) & (unsigned) (r).getSegment(), (unsigned) (r).getOffset()

// Stack pointer type
typedef reg_t *StackPtr;

@@ -316,7 +316,7 @@ class SciEngine : public Engine {
void scriptDebug();
bool checkExportBreakpoint(uint16 script, uint16 pubfunct);
bool checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector);
bool checkAddressBreakpoint(const reg32_t &address);
bool checkAddressBreakpoint(const reg_t &address);

public:
bool checkKernelBreakpoint(const Common::String &name);

0 comments on commit 941869c

Please sign in to comment.