Open main menu

Difference between revisions of "SCI/Specifications/SCI virtual machine/The Sierra PMachine"

m
Text replacement - "</source>" to "</syntaxhighlight>"
m (Text replacement - "<source lang=" to "<syntaxhighlight lang=")
Tags: Mobile edit Mobile web edit
m (Text replacement - "</source>" to "</syntaxhighlight>")
Line 64: Line 64:
     ldi byte 2
     ldi byte 2
     push
     push
</source>
</syntaxhighlight>


Relative addresses are signed values.
Relative addresses are signed values.
Line 80: Line 80:
     pTos y ; push the y property
     pTos y ; push the y property
     callk OnControl, 6
     callk OnControl, 6
</source>
</syntaxhighlight>


Notice that, although the <tt>callk</tt> line specifies 6 bytes of parameters, the kernel routine has access to the list size (which is at offset 8)!
Notice that, although the <tt>callk</tt> line specifies 6 bytes of parameters, the kernel routine has access to the list size (which is at offset 8)!
Line 101: Line 101:
pop(): sp -= 2; return *sp;
pop(): sp -= 2; return *sp;
push(x): *sp = x; sp += 2; return x;
push(x): *sp = x; sp += 2; return x;
</source>
</syntaxhighlight>


The following rules apply to opcodes:
The following rules apply to opcodes:
Line 118: Line 118:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc ^= 0xffff;
acc ^= 0xffff;
</source>
</syntaxhighlight>




Line 126: Line 126:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc += pop();
acc += pop();
</source>
</syntaxhighlight>




Line 134: Line 134:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = pop() - acc;
acc = pop() - acc;
</source>
</syntaxhighlight>




Line 142: Line 142:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc *= pop();
acc *= pop();
</source>
</syntaxhighlight>




Line 150: Line 150:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = pop() / acc;
acc = pop() / acc;
</source>
</syntaxhighlight>
Division by zero is caught => acc = 0.
Division by zero is caught => acc = 0.


Line 159: Line 159:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = pop() % acc;
acc = pop() % acc;
</source>
</syntaxhighlight>
Modulo by zero is caught => acc = 0.
Modulo by zero is caught => acc = 0.


Line 168: Line 168:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = pop() >> acc;
acc = pop() >> acc;
</source>
</syntaxhighlight>




Line 176: Line 176:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = pop() << acc;
acc = pop() << acc;
</source>
</syntaxhighlight>




Line 184: Line 184:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc ^= pop();
acc ^= pop();
</source>
</syntaxhighlight>




Line 192: Line 192:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc &= pop();
acc &= pop();
</source>
</syntaxhighlight>




Line 200: Line 200:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc |= pop();
acc |= pop();
</source>
</syntaxhighlight>




Line 208: Line 208:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = -acc;
acc = -acc;
</source>
</syntaxhighlight>




Line 216: Line 216:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = !acc;
acc = !acc;
</source>
</syntaxhighlight>




Line 225: Line 225:
prev = acc;
prev = acc;
acc = (acc == pop());
acc = (acc == pop());
</source>
</syntaxhighlight>




Line 234: Line 234:
prev = acc;
prev = acc;
acc = !(acc == pop());
acc = !(acc == pop());
</source>
</syntaxhighlight>




Line 243: Line 243:
prev = acc;
prev = acc;
acc = (pop() > acc);
acc = (pop() > acc);
</source>
</syntaxhighlight>




Line 252: Line 252:
prev = acc;
prev = acc;
acc = (pop() >= acc);
acc = (pop() >= acc);
</source>
</syntaxhighlight>




Line 261: Line 261:
prev = acc;
prev = acc;
acc = (pop() < acc);
acc = (pop() < acc);
</source>
</syntaxhighlight>




Line 270: Line 270:
prev = acc;
prev = acc;
acc = (pop() <= acc);
acc = (pop() <= acc);
</source>
</syntaxhighlight>




Line 278: Line 278:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = (pop() > acc);
acc = (pop() > acc);
</source>
</syntaxhighlight>




Line 286: Line 286:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = (pop() >= acc);
acc = (pop() >= acc);
</source>
</syntaxhighlight>




Line 294: Line 294:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = (pop() < acc);
acc = (pop() < acc);
</source>
</syntaxhighlight>




Line 302: Line 302:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = (pop() >= acc);
acc = (pop() >= acc);
</source>
</syntaxhighlight>




Line 310: Line 310:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
if (acc) pc += relpos;
if (acc) pc += relpos;
</source>
</syntaxhighlight>




Line 318: Line 318:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
if (!acc) pc += relpos;
if (!acc) pc += relpos;
</source>
</syntaxhighlight>




Line 326: Line 326:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
pc += relpos;
pc += relpos;
</source>
</syntaxhighlight>




Line 334: Line 334:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
acc = data;
acc = data;
</source>
</syntaxhighlight>
:Sign extension is done for 0x35 if required.
:Sign extension is done for 0x35 if required.


Line 343: Line 343:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
push(acc)
push(acc)
</source>
</syntaxhighlight>




Line 351: Line 351:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
push(data)
push(data)
</source>
</syntaxhighlight>
:Sign extension for 0x39 is performed where required.
:Sign extension for 0x39 is performed where required.


Line 360: Line 360:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
pop();
pop();
</source>
</syntaxhighlight>
:For confirmation: Yes, this simply tosses the TOS value away.
:For confirmation: Yes, this simply tosses the TOS value away.


Line 369: Line 369:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
push(*TOS);
push(*TOS);
</source>
</syntaxhighlight>




Line 376: Line 376:
<syntaxhighlight lang="C">
<syntaxhighlight lang="C">
sp += (size * 2);
sp += (size * 2);
</source>
</syntaxhighlight>




Line 386: Line 386:
sp -= (framesize + 2 + &rest_modifier);
sp -= (framesize + 2 + &rest_modifier);
&rest_modifier = 0;
&rest_modifier = 0;
</source>
</syntaxhighlight>
:This calls a script subroutine at the relative position relpos, setting up the <tt>ParmVar</tt> pointer first. <tt>ParmVar points</tt> to sp-<tt>''framesize''</tt> (but see also the <tt>&rest</tt> operation). The number of parameters is stored at word offset <tt>-1</tt> relative to <tt>ParmVar</tt>.
:This calls a script subroutine at the relative position relpos, setting up the <tt>ParmVar</tt> pointer first. <tt>ParmVar points</tt> to sp-<tt>''framesize''</tt> (but see also the <tt>&rest</tt> operation). The number of parameters is stored at word offset <tt>-1</tt> relative to <tt>ParmVar</tt>.


Line 398: Line 398:
&rest_modifier = 0;
&rest_modifier = 0;
(call kernel function kfunct)
(call kernel function kfunct)
</source>
</syntaxhighlight>




Line 408: Line 408:
sp -= (framesize + 2 + &rest_modifier);
sp -= (framesize + 2 + &rest_modifier);
&rest_modifier = 0;
&rest_modifier = 0;
</source>
</syntaxhighlight>
:This operation starts a new execution loop at the beginning of script 0, public method <tt>dispindex</tt> (Each script comes with a dispatcher list (type 7) that identifies public methods). Parameters are handled as in the call operation.
:This operation starts a new execution loop at the beginning of script 0, public method <tt>dispindex</tt> (Each script comes with a dispatcher list (type 7) that identifies public methods). Parameters are handled as in the call operation.


Line 419: Line 419:
sp -= (framesize + 2 + &rest_modifier);
sp -= (framesize + 2 + &rest_modifier);
&rest_modifier = 0;
&rest_modifier = 0;
</source>
</syntaxhighlight>
:This operation performs a function call (implicitly placing the current program counter on the execution stack) to an ``external'' procedure of a script. More precisely, exported procedure <tt>dispindex</tt> of script <tt>script</tt> is invoked, where <tt>dispindex</tt> is an offset into the script's Exports list (i.e., <tt>dispindex = ''n'' * 2</tt> references the ''n''th exported procedure).
:This operation performs a function call (implicitly placing the current program counter on the execution stack) to an ``external'' procedure of a script. More precisely, exported procedure <tt>dispindex</tt> of script <tt>script</tt> is invoked, where <tt>dispindex</tt> is an offset into the script's Exports list (i.e., <tt>dispindex = ''n'' * 2</tt> references the ''n''th exported procedure).
:The ``Exports list'' is defined in the script's type 7 object (cf. section [[SCI/Specifications/SCI_virtual_machine/Introduction#Script_resources|Script resources]]). It is an error to invoke a script which does not exist or which does not provide an Exports list, or to use a dispatch index which does not point into an even address within the Exports list.
:The ``Exports list'' is defined in the script's type 7 object (cf. section [[SCI/Specifications/SCI_virtual_machine/Introduction#Script_resources|Script resources]]). It is an error to invoke a script which does not exist or which does not provide an Exports list, or to use a dispatch index which does not point into an even address within the Exports list.
Line 446: Line 446:
   push0        ; This will read foo and return the value in acc.
   push0        ; This will read foo and return the value in acc.
   send 12      ; This operation does three quite different things.
   send 12      ; This operation does three quite different things.
</source>
</syntaxhighlight>




Line 513: Line 513:
   return &((vars[(vt >> 1) &amp; 3])[vt &amp; 0x10 ? vi+acc : vi]);
   return &((vars[(vt >> 1) &amp; 3])[vt &amp; 0x10 ? vi+acc : vi]);
}
}
</source>
</syntaxhighlight>




Line 519: Line 519:
;<nowiki>op 0x5d: selfID (1 bytes)</nowiki>
;<nowiki>op 0x5d: selfID (1 bytes)</nowiki>
:Get 'self' identity: SCI uses heap pointers to identify objects, so this operation sets the accumulator to the address of the current object.
:Get 'self' identity: SCI uses heap pointers to identify objects, so this operation sets the accumulator to the address of the current object.
<syntaxhighlight lang="C">acc = object</source>
<syntaxhighlight lang="C">acc = object</syntaxhighlight>




Line 530: Line 530:
;<nowiki>op 0x61: pprev (1 bytes)</nowiki>
;<nowiki>op 0x61: pprev (1 bytes)</nowiki>
:Push prev: Pushes the value of the prev register, set by the last comparison bytecode (eq?, lt?, etc.), on the stack.
:Push prev: Pushes the value of the prev register, set by the last comparison bytecode (eq?, lt?, etc.), on the stack.
<syntaxhighlight lang="C">push(prev)</source>
<syntaxhighlight lang="C">push(prev)</syntaxhighlight>




Line 576: Line 576:
;<nowiki>op 0x73: lofsa B offset (2 bytes)</nowiki>
;<nowiki>op 0x73: lofsa B offset (2 bytes)</nowiki>
:Load Offset to Accumulator:
:Load Offset to Accumulator:
<syntaxhighlight lang="C">acc = pc + offset</source>
<syntaxhighlight lang="C">acc = pc + offset</syntaxhighlight>
:Adds a value to the post-operation pc and stores the result in the accumulator.
:Adds a value to the post-operation pc and stores the result in the accumulator.


Line 583: Line 583:
;<nowiki>op 0x75: lofss B offset (2 bytes)</nowiki>
;<nowiki>op 0x75: lofss B offset (2 bytes)</nowiki>
:Load Offset to Stack:
:Load Offset to Stack:
<syntaxhighlight lang="C">push(pc + offset)</source>
<syntaxhighlight lang="C">push(pc + offset)</syntaxhighlight>
:Adds a value to the post-operation pc and pushes the result on the stack.
:Adds a value to the post-operation pc and pushes the result on the stack.


Line 590: Line 590:
;<nowiki>op 0x77: push0 (1 bytes)</nowiki>
;<nowiki>op 0x77: push0 (1 bytes)</nowiki>
:Push 0:
:Push 0:
<syntaxhighlight lang="C">push(0)</source>
<syntaxhighlight lang="C">push(0)</syntaxhighlight>




Line 596: Line 596:
;<nowiki>op 0x79: push1 (1 bytes)</nowiki>
;<nowiki>op 0x79: push1 (1 bytes)</nowiki>
:Push 1:
:Push 1:
<syntaxhighlight lang="C">push(1)</source>
<syntaxhighlight lang="C">push(1)</syntaxhighlight>




Line 602: Line 602:
;<nowiki>op 0x7b: push2 (1 bytes)</nowiki>
;<nowiki>op 0x7b: push2 (1 bytes)</nowiki>
:Push 2:
:Push 2:
<syntaxhighlight lang="C">push(2)</source>
<syntaxhighlight lang="C">push(2)</syntaxhighlight>




Line 608: Line 608:
;<nowiki>op 0x7d: pushSelf (1 bytes)</nowiki>
;<nowiki>op 0x7d: pushSelf (1 bytes)</nowiki>
:Push self:
:Push self:
<syntaxhighlight lang="C">push(object)</source>
<syntaxhighlight lang="C">push(object)</syntaxhighlight>




TrustedUser
2,147

edits