Community

SCI Programming => SCI Development Tools => Topic started by: lance.ewing on May 29, 2015, 08:10:14 PM

Title: Store with index opcodes (e.g. SAGI, SALI, etc)
Post by: lance.ewing on May 29, 2015, 08:10:14 PM
The SCI specs say the following:

Quote
Example: "sagi 2" would Store the Accumulator in the Global variable indexed with 2 plus the current accumulator value (this rarely makes sense, obviously).

Rather than rarely making sense, I would suggest that this would never make sense, which would make the instruction useless. I don't have an issue with an instruction not being used if its useless. - There do, however, appear to be quite a few examples of these opcodes (store with index) being used in games (kq4, sq3, pq2, lsl3, and probably a lot of others). The sagi opcode is used 5 times in script 10 of PQ2, in fact we've got 2 in a row at one point:

Code: [Select]
pushi $7
ldi $1
sagi global[$d7]
pushi $7
ldi $2
sagi global[$d7]

Looks to me like it could be using the stack for the value.

The "sali" opcode seems to be far more common. There's around 44 examples in pq2 script 10 alone. I'm seeing something similar for "sali":

Code: [Select]
pushi $fe
ldi $2
sali local[$19]
push2
ldi $3
sali local[$19]
push0
ldi $4
sali local[$19]

I'm guessing that this is already known, possibly even been discussed before, but can someone confirm that this interpretation is correct? And if this is correct, then what does the "a" in "sagi" mean? And then how does "sagi" differ from "ssgi"? I haven't been able to find an example of "ssgi" yet, but given what the specs say, I would have expected the examples from PQ2 above to have been using ssgi instead of sagi. It seems like a more consistent interpretation of what the "a" and "s" mean. The "sag" opcode certainly appears to store the accumulator, but perhaps not "sagi"?
Title: Re: Store with index opcodes (e.g. SAGI, SALI, etc)
Post by: troflip on May 29, 2015, 08:47:11 PM
I can verify that my decompiler assumes sagi consumes one stack. So I suspect it is identical to ssgi.
Title: Re: Store with index opcodes (e.g. SAGI, SALI, etc)
Post by: lskovlun on May 29, 2015, 11:34:17 PM
Source code for sagi and friends from ScummVM:
Code: [Select]
                        var_type = opcode & 0x3; // Gets the variable type: g, l, t or p
                        var_number = opparams[0] + (opcode >= op_sagi ? s->r_acc.requireSint16() : 0);
                        if (opcode >= op_sagi)  // load the actual value to store in the accumulator
                                s->r_acc = POP32();
                        write_var(s, var_type, var_number, s->r_acc);
                        break;
Source code for ssgi and friends from ScummVM:
Code: [Select]
                        var_type = opcode & 0x3; // Gets the variable type: g, l, t or p
                        var_number = opparams[0] + (opcode >= op_ssgi ? s->r_acc.requireSint16() : 0);
                        write_var(s, var_type, var_number, POP32());
                        break;
The only difference between them seems to be that sagi changes the accumulator, and ssgi doesn't. I guess that's why it was declared useless.
It is true that ssgi/friends do not appear in the Sierra games at all (much like lofss doesn't, despite its equivalent, lofsa/push being prevalent). I don't know why Sierra didn't use them, and I'm not sure how I would use them myself if I was writing a compiler.
Title: Re: Store with index opcodes (e.g. SAGI, SALI, etc)
Post by: lance.ewing on May 30, 2015, 05:06:29 AM
It seems that the comment in brackets beside the sagi example in the specs is implying that it is rarely used because it supposedly both "stores the accumulator" and also adds the current accumulator value as an index. Using the accumulator for both purposes would have crippled the instruction (which I'm fine with, given the consistent design of the second half of the instruction set, its probably unavoidable that some instructions wouldn't make much sense). What we're saying now though, both from the decompiler and the scummvm code, is that it isn't the accumulator that is being stored. Instead it is the top stack value that is being stored, which makes "sagi" useful in some situations, and is indeed used, but what it seems to mean is that "ssgi" is almost redundant (unless there is a situation where we'd want the index to remain in the accumulator). It seems like an inconsistency in their design.

Are we fairly certain that "ssgi" doesn't affect the accumulator value? If it isn't used by any games, then its probably difficult to verify. At some point, did someone assemble code to test this?
Title: Re: Store with index opcodes (e.g. SAGI, SALI, etc)
Post by: troflip on May 30, 2015, 12:35:59 PM
It does not, I just verified with this piece of asm:

Code: [Select]
  (asm
  ldi 7 // acc now 7
  push
  ldi 5 // acc now 5
  ssli buffer // acc is still 5
)

and sali:

Code: [Select]
  (asm
  ldi 7 // acc now 7
  push
  ldi 5 // acc now 5
  sali buffer // acc now 7
)