TrustedUser
2,147
edits
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 | ||
</ | </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 | ||
</ | </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; | ||
</ | </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; | ||
</ | </syntaxhighlight> | ||
Line 126: | Line 126: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc += pop(); | acc += pop(); | ||
</ | </syntaxhighlight> | ||
Line 134: | Line 134: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = pop() - acc; | acc = pop() - acc; | ||
</ | </syntaxhighlight> | ||
Line 142: | Line 142: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc *= pop(); | acc *= pop(); | ||
</ | </syntaxhighlight> | ||
Line 150: | Line 150: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = pop() / acc; | acc = pop() / acc; | ||
</ | </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; | ||
</ | </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; | ||
</ | </syntaxhighlight> | ||
Line 176: | Line 176: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = pop() << acc; | acc = pop() << acc; | ||
</ | </syntaxhighlight> | ||
Line 184: | Line 184: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc ^= pop(); | acc ^= pop(); | ||
</ | </syntaxhighlight> | ||
Line 192: | Line 192: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc &= pop(); | acc &= pop(); | ||
</ | </syntaxhighlight> | ||
Line 200: | Line 200: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc |= pop(); | acc |= pop(); | ||
</ | </syntaxhighlight> | ||
Line 208: | Line 208: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = -acc; | acc = -acc; | ||
</ | </syntaxhighlight> | ||
Line 216: | Line 216: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = !acc; | acc = !acc; | ||
</ | </syntaxhighlight> | ||
Line 225: | Line 225: | ||
prev = acc; | prev = acc; | ||
acc = (acc == pop()); | acc = (acc == pop()); | ||
</ | </syntaxhighlight> | ||
Line 234: | Line 234: | ||
prev = acc; | prev = acc; | ||
acc = !(acc == pop()); | acc = !(acc == pop()); | ||
</ | </syntaxhighlight> | ||
Line 243: | Line 243: | ||
prev = acc; | prev = acc; | ||
acc = (pop() > acc); | acc = (pop() > acc); | ||
</ | </syntaxhighlight> | ||
Line 252: | Line 252: | ||
prev = acc; | prev = acc; | ||
acc = (pop() >= acc); | acc = (pop() >= acc); | ||
</ | </syntaxhighlight> | ||
Line 261: | Line 261: | ||
prev = acc; | prev = acc; | ||
acc = (pop() < acc); | acc = (pop() < acc); | ||
</ | </syntaxhighlight> | ||
Line 270: | Line 270: | ||
prev = acc; | prev = acc; | ||
acc = (pop() <= acc); | acc = (pop() <= acc); | ||
</ | </syntaxhighlight> | ||
Line 278: | Line 278: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = (pop() > acc); | acc = (pop() > acc); | ||
</ | </syntaxhighlight> | ||
Line 286: | Line 286: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = (pop() >= acc); | acc = (pop() >= acc); | ||
</ | </syntaxhighlight> | ||
Line 294: | Line 294: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = (pop() < acc); | acc = (pop() < acc); | ||
</ | </syntaxhighlight> | ||
Line 302: | Line 302: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = (pop() >= acc); | acc = (pop() >= acc); | ||
</ | </syntaxhighlight> | ||
Line 310: | Line 310: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
if (acc) pc += relpos; | if (acc) pc += relpos; | ||
</ | </syntaxhighlight> | ||
Line 318: | Line 318: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
if (!acc) pc += relpos; | if (!acc) pc += relpos; | ||
</ | </syntaxhighlight> | ||
Line 326: | Line 326: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
pc += relpos; | pc += relpos; | ||
</ | </syntaxhighlight> | ||
Line 334: | Line 334: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
acc = data; | acc = data; | ||
</ | </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) | ||
</ | </syntaxhighlight> | ||
Line 351: | Line 351: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
push(data) | push(data) | ||
</ | </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(); | ||
</ | </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); | ||
</ | </syntaxhighlight> | ||
Line 376: | Line 376: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
sp += (size * 2); | sp += (size * 2); | ||
</ | </syntaxhighlight> | ||
Line 386: | Line 386: | ||
sp -= (framesize + 2 + &rest_modifier); | sp -= (framesize + 2 + &rest_modifier); | ||
&rest_modifier = 0; | &rest_modifier = 0; | ||
</ | </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) | ||
</ | </syntaxhighlight> | ||
Line 408: | Line 408: | ||
sp -= (framesize + 2 + &rest_modifier); | sp -= (framesize + 2 + &rest_modifier); | ||
&rest_modifier = 0; | &rest_modifier = 0; | ||
</ | </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; | ||
</ | </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. | ||
</ | </syntaxhighlight> | ||
Line 513: | Line 513: | ||
return &((vars[(vt >> 1) & 3])[vt & 0x10 ? vi+acc : vi]); | return &((vars[(vt >> 1) & 3])[vt & 0x10 ? vi+acc : vi]); | ||
} | } | ||
</ | </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</ | <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)</ | <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</ | <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)</ | <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)</ | <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)</ | <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)</ | <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)</ | <syntaxhighlight lang="C">push(object)</syntaxhighlight> | ||