Merge branch 'progsig-sx' into jgrpp

This commit is contained in:
Jonathan G Rennison
2015-08-16 16:58:23 +01:00
2 changed files with 60 additions and 54 deletions

View File

@@ -355,6 +355,7 @@ public:
{ {
uint64 p1 = 0; uint64 p1 = 0;
while(true) { while(true) {
if(si == NULL) break;
switch(si->Opcode()) { switch(si->Opcode()) {
case PSO_SET_SIGNAL: { case PSO_SET_SIGNAL: {
SB(p1, 0, 3, this->track); SB(p1, 0, 3, this->track);
@@ -365,6 +366,7 @@ public:
this->RebuildInstructionList(); this->RebuildInstructionList();
si = ((SignalSet*)si)->next; si = ((SignalSet*)si)->next;
} break; } break;
case PSO_IF: { case PSO_IF: {
SB(p1, 0, 3, this->track); SB(p1, 0, 3, this->track);
SB(p1, 3, 16, next); SB(p1, 3, 16, next);
@@ -393,11 +395,15 @@ public:
si = ((SignalIf*)si)->after; si = ((SignalIf*)si)->after;
} break; } break;
case PSO_LAST:
case PSO_IF_ELSE:
case PSO_IF_ENDIF:
return;
default:
NOT_REACHED();
} }
if(si == NULL) break;
if(si->Opcode() == PSO_LAST) break;
if(si->Opcode() == PSO_IF_ELSE) break;
if(si->Opcode() == PSO_IF_ENDIF) break;
} }
} }

View File

@@ -23,30 +23,30 @@ typedef std::vector<byte> Buffer;
static void WriteVLI(Buffer &b, uint i) static void WriteVLI(Buffer &b, uint i)
{ {
uint lsmask = 0x7F; uint lsmask = 0x7F;
uint msmask = ~0x7F; uint msmask = ~0x7F;
while(i & msmask) { while(i & msmask) {
byte part = (i & lsmask) | 0x80; byte part = (i & lsmask) | 0x80;
b.push_back(part); b.push_back(part);
i >>= 7; i >>= 7;
} }
b.push_back((byte) i); b.push_back((byte) i);
} }
static uint ReadVLI() static uint ReadVLI()
{ {
uint shift = 0; uint shift = 0;
uint val = 0; uint val = 0;
byte b; byte b;
b = SlReadByte(); b = SlReadByte();
while(b & 0x80) { while(b & 0x80) {
val |= uint(b & 0x7F) << shift; val |= uint(b & 0x7F) << shift;
shift += 7; shift += 7;
b = SlReadByte(); b = SlReadByte();
} }
val |= uint(b) << shift; val |= uint(b) << shift;
return val; return val;
} }
static void WriteCondition(Buffer &b, SignalCondition *c) static void WriteCondition(Buffer &b, SignalCondition *c)
@@ -59,13 +59,13 @@ static void WriteCondition(Buffer &b, SignalCondition *c)
WriteVLI(b, vc->comparator); WriteVLI(b, vc->comparator);
WriteVLI(b, vc->value); WriteVLI(b, vc->value);
} break; } break;
case PSC_SIGNAL_STATE: { case PSC_SIGNAL_STATE: {
SignalStateCondition *sc = static_cast<SignalStateCondition*>(c); SignalStateCondition *sc = static_cast<SignalStateCondition*>(c);
WriteVLI(b, sc->sig_tile); WriteVLI(b, sc->sig_tile);
WriteVLI(b, sc->sig_track); WriteVLI(b, sc->sig_track);
} break; } break;
default: default:
break; break;
} }
@@ -83,13 +83,13 @@ static SignalCondition *ReadCondition(SignalReference this_sig)
c->value = ReadVLI(); c->value = ReadVLI();
return c; return c;
} }
case PSC_SIGNAL_STATE: { case PSC_SIGNAL_STATE: {
TileIndex ti = (TileIndex) ReadVLI(); TileIndex ti = (TileIndex) ReadVLI();
Trackdir td = (Trackdir) ReadVLI(); Trackdir td = (Trackdir) ReadVLI();
return new SignalStateCondition(this_sig, ti, td); return new SignalStateCondition(this_sig, ti, td);
} }
default: default:
return new SignalSimpleCondition(code); return new SignalSimpleCondition(code);
} }
@@ -111,17 +111,16 @@ static void Save_SPRG()
if(i == e) break; if(i == e) break;
} }
} }
// OK, we can now write out our programs // OK, we can now write out our programs
Buffer b; Buffer b;
WriteVLI(b, _signal_programs.size()); WriteVLI(b, _signal_programs.size());
for(ProgramList::iterator i = _signal_programs.begin(), e = _signal_programs.end(); for(ProgramList::iterator i = _signal_programs.begin(), e = _signal_programs.end();
i != e; ++i) { i != e; ++i) {
SignalReference ref = i->first;
SignalProgram *prog = i->second; SignalProgram *prog = i->second;
prog->DebugPrintProgram(); prog->DebugPrintProgram();
WriteVLI(b, prog->tile); WriteVLI(b, prog->tile);
WriteVLI(b, prog->track); WriteVLI(b, prog->track);
WriteVLI(b, prog->instructions.Length()); WriteVLI(b, prog->instructions.Length());
@@ -137,44 +136,45 @@ static void Save_SPRG()
WriteVLI(b, s->next->Id()); WriteVLI(b, s->next->Id());
break; break;
} }
case PSO_LAST: break; case PSO_LAST: break;
case PSO_IF: { case PSO_IF: {
SignalIf *i = static_cast<SignalIf*>(insn); SignalIf *i = static_cast<SignalIf*>(insn);
WriteCondition(b, i->condition); WriteCondition(b, i->condition);
WriteVLI(b, i->if_true->Id()); WriteVLI(b, i->if_true->Id());
WriteVLI(b, i->if_false->Id()); WriteVLI(b, i->if_false->Id());
WriteVLI(b, i->after->Id()); WriteVLI(b, i->after->Id());
break; break;
} }
case PSO_IF_ELSE: case PSO_IF_ELSE:
case PSO_IF_ENDIF: { case PSO_IF_ENDIF: {
SignalIf::PseudoInstruction *p = static_cast<SignalIf::PseudoInstruction*>(insn); SignalIf::PseudoInstruction *p = static_cast<SignalIf::PseudoInstruction*>(insn);
WriteVLI(b, p->block->Id()); WriteVLI(b, p->block->Id());
break; break;
} }
case PSO_SET_SIGNAL: { case PSO_SET_SIGNAL: {
SignalSet *s = static_cast<SignalSet*>(insn); SignalSet *s = static_cast<SignalSet*>(insn);
WriteVLI(b, s->next->Id()); WriteVLI(b, s->next->Id());
WriteVLI(b, s->to_state ? 1 : 0); WriteVLI(b, s->to_state ? 1 : 0);
break; break;
} }
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
} }
uint size = b.size(); uint size = b.size();
SlSetLength(size); SlSetLength(size);
for(uint i = 0; i < size; i++) for(uint i = 0; i < size; i++) {
SlWriteByte(b[i]); // TODO Gotta be a better way SlWriteByte(b[i]); // TODO Gotta be a better way
}
} }
// We don't know the pointer values that need to be stored in various // We don't know the pointer values that need to be stored in various
// instruction fields at load time, so we need to instead store the IDs and // instruction fields at load time, so we need to instead store the IDs and
// then fix them up once all of the instructions have been loaded. // then fix them up once all of the instructions have been loaded.
// //
@@ -185,7 +185,7 @@ struct Fixup {
Fixup(SignalInstruction **p, SignalOpcode type) Fixup(SignalInstruction **p, SignalOpcode type)
: type(type), ptr(p) : type(type), ptr(p)
{} {}
SignalOpcode type; SignalOpcode type;
SignalInstruction **ptr; SignalInstruction **ptr;
}; };
@@ -205,9 +205,9 @@ static void DoFixups(FixupList &l, InstructionList &il)
uint id = reinterpret_cast<size_t>(*i->ptr); uint id = reinterpret_cast<size_t>(*i->ptr);
if(id >= il.Length()) if(id >= il.Length())
NOT_REACHED(); NOT_REACHED();
*i->ptr = il[id]; *i->ptr = il[id];
if(i->type != PSO_INVALID && (*i->ptr)->Opcode() != i->type) { if(i->type != PSO_INVALID && (*i->ptr)->Opcode() != i->type) {
DEBUG(sl, 0, "Expected Id %d to be %d, but was in fact %d", id, i->type, (*i->ptr)->Opcode()); DEBUG(sl, 0, "Expected Id %d to be %d, but was in fact %d", id, i->type, (*i->ptr)->Opcode());
NOT_REACHED(); NOT_REACHED();
@@ -224,10 +224,10 @@ static void Load_SPRG()
Track track = (Track) ReadVLI(); Track track = (Track) ReadVLI();
uint instructions = ReadVLI(); uint instructions = ReadVLI();
SignalReference ref(tile, track); SignalReference ref(tile, track);
SignalProgram *sp = new SignalProgram(tile, track, true); SignalProgram *sp = new SignalProgram(tile, track, true);
_signal_programs[ref] = sp; _signal_programs[ref] = sp;
for(uint j = 0; j < instructions; j++) { for(uint j = 0; j < instructions; j++) {
SignalOpcode op = (SignalOpcode) ReadVLI(); SignalOpcode op = (SignalOpcode) ReadVLI();
switch(op) { switch(op) {
@@ -237,24 +237,24 @@ static void Load_SPRG()
MakeFixup(l, sp->first_instruction->next, ReadVLI()); MakeFixup(l, sp->first_instruction->next, ReadVLI());
break; break;
} }
case PSO_LAST: { case PSO_LAST: {
sp->last_instruction = new SignalSpecial(sp, PSO_LAST); sp->last_instruction = new SignalSpecial(sp, PSO_LAST);
sp->last_instruction->next = NULL; sp->last_instruction->next = NULL;
MakeFixup(l, sp->last_instruction->GetPrevHandle(), ReadVLI()); MakeFixup(l, sp->last_instruction->GetPrevHandle(), ReadVLI());
break; break;
} }
case PSO_IF: { case PSO_IF: {
SignalIf *i = new SignalIf(sp, true); SignalIf *i = new SignalIf(sp, true);
MakeFixup(l, i->GetPrevHandle(), ReadVLI()); MakeFixup(l, i->GetPrevHandle(), ReadVLI());
i->condition = ReadCondition(ref); i->condition = ReadCondition(ref);
MakeFixup(l, i->if_true, ReadVLI()); MakeFixup(l, i->if_true, ReadVLI());
MakeFixup(l, i->if_false, ReadVLI()); MakeFixup(l, i->if_false, ReadVLI());
MakeFixup(l, i->after, ReadVLI()); MakeFixup(l, i->after, ReadVLI());
break; break;
} }
case PSO_IF_ELSE: case PSO_IF_ELSE:
case PSO_IF_ENDIF: { case PSO_IF_ENDIF: {
SignalIf::PseudoInstruction *p = new SignalIf::PseudoInstruction(sp, op); SignalIf::PseudoInstruction *p = new SignalIf::PseudoInstruction(sp, op);
@@ -262,7 +262,7 @@ static void Load_SPRG()
MakeFixup(l, p->block, ReadVLI(), PSO_IF); MakeFixup(l, p->block, ReadVLI(), PSO_IF);
break; break;
} }
case PSO_SET_SIGNAL: { case PSO_SET_SIGNAL: {
SignalSet *s = new SignalSet(sp); SignalSet *s = new SignalSet(sp);
MakeFixup(l, s->GetPrevHandle(), ReadVLI()); MakeFixup(l, s->GetPrevHandle(), ReadVLI());
@@ -271,11 +271,11 @@ static void Load_SPRG()
if(s->to_state > SIGNAL_STATE_MAX) NOT_REACHED(); if(s->to_state > SIGNAL_STATE_MAX) NOT_REACHED();
break; break;
} }
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
DoFixups(l, sp->instructions); DoFixups(l, sp->instructions);
sp->DebugPrintProgram(); sp->DebugPrintProgram();
} }