lignite 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce4cca8022a372bfd1ee229725d3a538376c6d54
4
- data.tar.gz: 7957e5d6aa35cf8551752d3a324f2cef141bd466
3
+ metadata.gz: b479941700df01dc46fa526001f014920e528ad3
4
+ data.tar.gz: 00d321b86f44d215261ad1bfbe1d88158c62f3e5
5
5
  SHA512:
6
- metadata.gz: fdf692daad988853107d65e5ebf31da38e0c6bd5d4bf6819e9b0e8e8ca5a140fe95bdf51d32db8c556f1e07298f3671aa389e8c994ff2293f087ae1c237cf1a7
7
- data.tar.gz: c5a98aedfde6259e69cdadbed737ee7fa1eed93d505a42489ee99a2a64ff8dcadabbdd8c1f4d7bca0a7cb004fc18caaa4cc33f61275153789a63386404896d18
6
+ metadata.gz: 1c9836db38d2bc17c096e3e73e1e26f54d6701f8be6cec34d0450dd79a6752afabd9db1b20087c7839df612799b5e3c02a5450740576759eaa75e651fc0b6aa4
7
+ data.tar.gz: fb64659ace34de87e7b133e704eb7577b07aadcd20e80868cc02871c7e5f4725d69b197d319821152b20ef42cf721fab9ef471832384e6a776e228cc504f0634
@@ -20,6 +20,11 @@ Performance/RedundantBlockCall:
20
20
  Style/SymbolArray:
21
21
  Enabled: false
22
22
 
23
+ # self.sleep is Ev3Ops#sleep, sleep is Kernel#sleep
24
+ Style/RedundantSelf:
25
+ Exclude:
26
+ - spec/data/*.rb
27
+
23
28
  Metrics/BlockLength:
24
29
  Exclude:
25
30
  - lignite.gemspec
data/NEWS.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
+ ## 0.5.0, 2018-03-05
6
+
7
+ - Ev3Ops: added missing array_* ops (with PARV in the signature).
8
+ - loop_while added, with a Condition prototype: Lt32.
9
+ - Corrected the variable argument calling convention (PARNO).
10
+ Before, it was necessary to manually add a parameter specifying the number
11
+ of the remaining parameters. Now it is automatic.
12
+
5
13
  ## 0.4.0, 2018-03-04
6
14
 
7
15
  - Generate Ev3Ops ahead of time, enabling YARD docs for them,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
@@ -6,14 +6,13 @@ dc = Lignite::DirectCommands.new
6
6
  # see 28/31 of Comm dev kit, read light sensor value on port 3
7
7
  LAYER0 = 0
8
8
  MODE = 0
9
- count = 1
10
9
  pct = dc.with_reply do
11
10
  # global vars
12
11
  dataf :light
13
12
 
14
13
  # TODO: make the block optional if there are no locals. or #with_locals
15
14
  block do
16
- input_device_ready_si(LAYER0, Lignite::PORT_3, Lignite::TYPE_KEEP, MODE, count, :light)
15
+ input_device_ready_si(LAYER0, Lignite::PORT_3, Lignite::TYPE_KEEP, MODE, :light)
17
16
  end
18
17
  end
19
18
  puts "Light sensor percentage: #{pct}"
@@ -1,11 +1,24 @@
1
+ require "lignite/rbf_declarer"
1
2
  require "lignite/variables"
2
3
 
3
4
  module Lignite
4
5
  # Assemble a complete RBF program file.
6
+ #
7
+ # The compilation has two passes:
8
+ #
9
+ # 1. pass1, Declaration
10
+ # 2. pass2, Resolution
11
+ #
12
+ # After P1, the instruction sequence is iterated. If an item responds to
13
+ # :pass2, it is replaced by the result of that call.
14
+ # After pass2 we have a sequence of ByteStrings which are just concatenated
15
+ #
16
+ # No, pass1, gather names, pass2 do all the rest
5
17
  class Assembler
6
18
  include Bytes
7
19
  include Logger
8
20
 
21
+ HEADER_SIZE = 16
9
22
  SIGNATURE = "LEGO".freeze
10
23
  def image_header(image_size:, version:, object_count:, global_bytes:)
11
24
  SIGNATURE + u32(image_size) + u16(version) + u16(object_count) +
@@ -27,24 +40,34 @@ module Lignite
27
40
  @objects = []
28
41
  @globals = Variables.new
29
42
 
43
+ @declarer = RbfDeclarer.new
44
+ @declarer.instance_eval(rb_text, rb_filename, 1) # 1 is the line number
30
45
  instance_eval(rb_text, rb_filename, 1) # 1 is the line number
31
46
 
47
+ write(rbf_filename, version)
48
+ end
49
+
50
+ def write(rbf_filename, version)
51
+ image_size = HEADER_SIZE + @objects.map(&:size).reduce(0, :+)
52
+
32
53
  File.open(rbf_filename, "w") do |f|
33
- dummy_header = image_header(image_size: 0, version: 0, object_count: 0, global_bytes: 0)
34
- f.write(dummy_header)
54
+ header = image_header(image_size: image_size,
55
+ version: version,
56
+ object_count: @objects.size,
57
+ global_bytes: @globals.bytesize)
58
+ f.write(header)
59
+
60
+ object_instruction_offset = HEADER_SIZE + @objects.count * RbfObject::HEADER_SIZE
35
61
  @objects.each do |obj|
36
- h = obj.header(f.tell)
62
+ h = obj.header(object_instruction_offset)
37
63
  f.write(h)
64
+ object_instruction_offset += obj.body.bytesize
65
+ end
66
+
67
+ @objects.each do |obj|
38
68
  f.write(obj.body)
39
69
  # align??
40
70
  end
41
- size = f.tell
42
- f.pos = 0
43
- header = image_header(image_size: size,
44
- version: version,
45
- object_count: @objects.size,
46
- global_bytes: @globals.bytesize)
47
- f.write(header)
48
71
  end
49
72
  end
50
73
 
@@ -53,16 +76,27 @@ module Lignite
53
76
  end
54
77
  include VariableDeclarer
55
78
 
56
- def vmthread(id, &body)
79
+ def vmthread(name, &body)
57
80
  @locals = Variables.new
58
- bodyc = BodyCompiler.new(@globals, @locals)
81
+ bodyc = BodyCompiler.new(@globals, @locals, @declarer)
59
82
  bodyc.instance_exec(&body)
60
83
  bodyc.instance_exec { object_end }
61
- # FIXME: id is not written?!
62
- logger.debug "VMTHREAD #{id}"
84
+ logger.debug "VMTHREAD #{name}"
63
85
  logger.debug " size #{bodyc.bytes.bytesize}"
64
86
  logger.debug " " + bin_to_hex(bodyc.bytes)
65
87
  @objects << RbfObject.vmthread(body: bodyc.bytes, local_bytes: @locals.bytesize)
66
88
  end
89
+
90
+ def sub(_name, &body)
91
+ @locals = Variables.new
92
+ bodyc = BodyCompiler.new(@globals, @locals, @declarer)
93
+ bodyc.instance_exec(&body)
94
+ bodyc.instance_exec do
95
+ self.return
96
+ object_end
97
+ end
98
+ @objects << RbfObject.subcall(body: bodyc.param_decl_header + bodyc.bytes,
99
+ local_bytes: @locals.bytesize)
100
+ end
67
101
  end
68
102
  end
@@ -1,4 +1,30 @@
1
1
  module Lignite
2
+ # Less-than (32 bit)
3
+ class Lt32 # < Condition
4
+ def initialize(a, b)
5
+ @a = a
6
+ @b = b
7
+ end
8
+
9
+ def not
10
+ Ge32.new(@a, @b)
11
+ end
12
+
13
+ def jump_forward(compiler, body_size)
14
+ compiler.jr_lt32(@a, @b, Complex(body_size, 2))
15
+ end
16
+
17
+ def jump_back(compiler, body_size, self_size = nil)
18
+ if self_size.nil?
19
+ fake = compiler.clone_context
20
+ jump_back(fake, body_size, 0)
21
+ self_size = fake.bytes.bytesize
22
+ end
23
+
24
+ compiler.jr_lt32(@a, @b, Complex(- (body_size + self_size), 2))
25
+ end
26
+ end
27
+
2
28
  # Extends {OpCompiler} by
3
29
  # - variable declarations: {VariableDeclarer}
4
30
  # - high level flow control: {#loop}
@@ -8,20 +34,36 @@ module Lignite
8
34
  # @return [Variables]
9
35
  attr_reader :locals
10
36
 
37
+ attr_reader :declared_objects
38
+
11
39
  def variables
12
40
  locals
13
41
  end
14
42
  include VariableDeclarer
15
43
 
16
- def initialize(globals, locals)
44
+ def parameters
45
+ locals
46
+ end
47
+ include ParameterDeclarer
48
+
49
+ def param_decl_header
50
+ parameters.param_decl_header
51
+ end
52
+
53
+ def initialize(globals, locals, declared_objects)
17
54
  @bytes = ""
18
55
  @globals = globals
19
56
  @locals = locals
57
+ @declared_objects = declared_objects
20
58
  @op_compiler = OpCompiler.new(@globals, @locals)
21
59
  end
22
60
 
61
+ def clone_context
62
+ BodyCompiler.new(@globals, @locals, @declared_objects)
63
+ end
64
+
23
65
  def if(flag8, &body)
24
- subc = BodyCompiler.new(@globals, @locals)
66
+ subc = BodyCompiler.new(@globals, @locals, @declared_objects)
25
67
  subc.instance_exec(&body)
26
68
 
27
69
  jr_false(flag8, Complex(subc.bytes.bytesize, 2))
@@ -29,7 +71,7 @@ module Lignite
29
71
  end
30
72
 
31
73
  def loop(&body)
32
- subc = BodyCompiler.new(@globals, @locals)
74
+ subc = BodyCompiler.new(@globals, @locals, @declared_objects)
33
75
  subc.instance_exec(&body)
34
76
  @bytes << subc.bytes
35
77
  # the jump takes up 4 bytes: JR, LC2, LO, HI
@@ -37,13 +79,37 @@ module Lignite
37
79
  end
38
80
 
39
81
  def loop_while_postcond(flag8, &body)
40
- subc = BodyCompiler.new(@globals, @locals)
82
+ subc = BodyCompiler.new(@globals, @locals, @declared_objects)
41
83
  subc.instance_exec(&body)
42
84
  @bytes << subc.bytes
43
- # the jump takes up 4 bytes: JR_TRUE, LV0(flag8), LC2, LO, HI
85
+ # the jump takes up 5 bytes: JR_TRUE, LV0(flag8), LC2, LO, HI
44
86
  jr_true(flag8, Complex(- (subc.bytes.bytesize + 5), 2))
45
87
  end
46
88
 
89
+ def loop_while(a, b)
90
+ if a.respond_to? :call
91
+ loop_while_post(b, &a)
92
+ else
93
+ loop_while_pre(a, &b)
94
+ end
95
+ end
96
+
97
+ def loop_while_post(condition, &body)
98
+ subc = BodyCompiler.new(@globals, @locals, @declared_objects)
99
+ subc.instance_exec(&body)
100
+ @bytes << subc.bytes
101
+ body_size = subc.bytes.bytesize
102
+ condition.jump_back(self, body_size)
103
+ end
104
+
105
+ def call(name, *args)
106
+ obj_id = declared_objects.index_of(name)
107
+ raise "Name #{name} not found" if obj_id.nil?
108
+
109
+ # TODO: check that args match their declaration
110
+ super(obj_id, *args) # Ev3Ops::call
111
+ end
112
+
47
113
  # Delegate the ops to the {OpCompiler},
48
114
  # but also aggregate the result in @bytes.
49
115
  def method_missing(name, *args)
@@ -1,3 +1,5 @@
1
+ require "lignite/rbf_declarer"
2
+
1
3
  module Lignite
2
4
  # This enables sending commands without wrapping them in a .rbf program
3
5
  class DirectCommands
@@ -35,7 +37,7 @@ module Lignite
35
37
 
36
38
  def block(&body)
37
39
  locals = Variables.new
38
- bodyc = BodyCompiler.new(@globals, locals)
40
+ bodyc = BodyCompiler.new(@globals, locals, RbfDeclarer::Dummy.new)
39
41
  bodyc.instance_exec(&body)
40
42
 
41
43
  bs = bodyc.bytes
@@ -7521,7 +7521,22 @@ module Lignite
7521
7521
  #
7522
7522
  Lignite::FILL = 6
7523
7523
 
7524
- # Could not define array_fill: Unhandled param type PARV
7524
+ #
7525
+ # @param handle [PAR16] (in) Array handle
7526
+ # @param value [PARV] (in) Value to write - type depends on type of array
7527
+ def array_fill(handle, value)
7528
+ logger.debug do
7529
+ args = [handle, value]
7530
+ "called array_fill with #{args.inspect}"
7531
+ end
7532
+
7533
+ bytes = u8(0xC1)
7534
+ bytes += param_simple(6)
7535
+ bytes += param_simple(handle)
7536
+ bytes += param_simple(value)
7537
+ logger.debug "returning bytecode: #{bytes.inspect}"
7538
+ bytes
7539
+ end
7525
7540
  #
7526
7541
  Lignite::COPY = 7
7527
7542
 
@@ -7693,11 +7708,57 @@ module Lignite
7693
7708
  __send__("array_#{csym}", *args)
7694
7709
  end
7695
7710
 
7696
- # Could not define array_write: Unhandled param type PARV
7711
+ # Array element write
7712
+ # @param handle [PAR16] (in) Array handle
7713
+ # @param index [PAR32] (in) Index to first byte to write
7714
+ # @param value [PARV] (in) Value to write - type depends on type of array
7715
+ def array_write(handle, index, value)
7716
+ logger.debug do
7717
+ args = [handle, index, value]
7718
+ "called array_write with #{args.inspect}"
7719
+ end
7697
7720
 
7698
- # Could not define array_read: Unhandled param type PARV
7721
+ bytes = u8(0xC2)
7722
+ bytes += param_simple(handle)
7723
+ bytes += param_simple(index)
7724
+ bytes += param_simple(value)
7725
+ logger.debug "returning bytecode: #{bytes.inspect}"
7726
+ bytes
7727
+ end
7699
7728
 
7700
- # Could not define array_append: Unhandled param type PARV
7729
+ # Array element read
7730
+ # @param handle [PAR16] (in) Array handle
7731
+ # @param index [PAR32] (in) Index to first byte to write
7732
+ # @param value [PARV] (out) Value to read - type depends on type of array
7733
+ def array_read(handle, index, value)
7734
+ logger.debug do
7735
+ args = [handle, index, value]
7736
+ "called array_read with #{args.inspect}"
7737
+ end
7738
+
7739
+ bytes = u8(0xC3)
7740
+ bytes += param_simple(handle)
7741
+ bytes += param_simple(index)
7742
+ bytes += param_simple(value)
7743
+ logger.debug "returning bytecode: #{bytes.inspect}"
7744
+ bytes
7745
+ end
7746
+
7747
+ # Array element append
7748
+ # @param handle [PAR16] (in) Array handle
7749
+ # @param value [PARV] (in) Value (new element) to append - type depends on type of array
7750
+ def array_append(handle, value)
7751
+ logger.debug do
7752
+ args = [handle, value]
7753
+ "called array_append with #{args.inspect}"
7754
+ end
7755
+
7756
+ bytes = u8(0xC4)
7757
+ bytes += param_simple(handle)
7758
+ bytes += param_simple(value)
7759
+ logger.debug "returning bytecode: #{bytes.inspect}"
7760
+ bytes
7761
+ end
7701
7762
 
7702
7763
  # Get memory usage
7703
7764
  # @param total [PAR32] (out) Total memory [KB]
@@ -9092,25 +9153,205 @@ module Lignite
9092
9153
  bytes
9093
9154
  end
9094
9155
 
9095
- # Could not define dynload_entry_0: Unhandled param type PARV
9156
+ # Execute Entry Point function 0 in Third Party VM
9157
+ # @param cmd [PAR8] (in) Sub command to be executed
9158
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9159
+ # @param length_out [PAR16] (out) Amount of data returned
9160
+ # @param value [PARV] (out) Data from opcode
9161
+ def dynload_entry_0(cmd, length_in, length_out, value)
9162
+ logger.debug do
9163
+ args = [cmd, length_in, length_out, value]
9164
+ "called dynload_entry_0 with #{args.inspect}"
9165
+ end
9096
9166
 
9097
- # Could not define dynload_entry_1: Unhandled param type PARV
9167
+ bytes = u8(0xF2)
9168
+ bytes += param_simple(cmd)
9169
+ bytes += param_simple(length_in)
9170
+ bytes += param_simple(length_out)
9171
+ bytes += param_simple(value)
9172
+ logger.debug "returning bytecode: #{bytes.inspect}"
9173
+ bytes
9174
+ end
9098
9175
 
9099
- # Could not define dynload_entry_2: Unhandled param type PARV
9176
+ # Execute Entry Point function 1 in Third Party VM
9177
+ # @param cmd [PAR8] (in) Sub command to be executed
9178
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9179
+ # @param length_out [PAR16] (out) Amount of data returned
9180
+ # @param value [PARV] (out) Data from opcode
9181
+ def dynload_entry_1(cmd, length_in, length_out, value)
9182
+ logger.debug do
9183
+ args = [cmd, length_in, length_out, value]
9184
+ "called dynload_entry_1 with #{args.inspect}"
9185
+ end
9100
9186
 
9101
- # Could not define dynload_entry_3: Unhandled param type PARV
9187
+ bytes = u8(0xF3)
9188
+ bytes += param_simple(cmd)
9189
+ bytes += param_simple(length_in)
9190
+ bytes += param_simple(length_out)
9191
+ bytes += param_simple(value)
9192
+ logger.debug "returning bytecode: #{bytes.inspect}"
9193
+ bytes
9194
+ end
9102
9195
 
9103
- # Could not define dynload_entry_4: Unhandled param type PARV
9196
+ # Execute Entry Point function 2 in Third Party VM
9197
+ # @param cmd [PAR8] (in) Sub command to be executed
9198
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9199
+ # @param length_out [PAR16] (out) Amount of data returned
9200
+ # @param value [PARV] (out) Data from opcode
9201
+ def dynload_entry_2(cmd, length_in, length_out, value)
9202
+ logger.debug do
9203
+ args = [cmd, length_in, length_out, value]
9204
+ "called dynload_entry_2 with #{args.inspect}"
9205
+ end
9104
9206
 
9105
- # Could not define dynload_entry_5: Unhandled param type PARV
9207
+ bytes = u8(0xF4)
9208
+ bytes += param_simple(cmd)
9209
+ bytes += param_simple(length_in)
9210
+ bytes += param_simple(length_out)
9211
+ bytes += param_simple(value)
9212
+ logger.debug "returning bytecode: #{bytes.inspect}"
9213
+ bytes
9214
+ end
9215
+
9216
+ # Execute Entry Point function 3 in Third Party VM
9217
+ # @param cmd [PAR8] (in) Sub command to be executed
9218
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9219
+ # @param length_out [PAR16] (out) Amount of data returned
9220
+ # @param value [PARV] (out) Data from opcode
9221
+ def dynload_entry_3(cmd, length_in, length_out, value)
9222
+ logger.debug do
9223
+ args = [cmd, length_in, length_out, value]
9224
+ "called dynload_entry_3 with #{args.inspect}"
9225
+ end
9226
+
9227
+ bytes = u8(0xF5)
9228
+ bytes += param_simple(cmd)
9229
+ bytes += param_simple(length_in)
9230
+ bytes += param_simple(length_out)
9231
+ bytes += param_simple(value)
9232
+ logger.debug "returning bytecode: #{bytes.inspect}"
9233
+ bytes
9234
+ end
9235
+
9236
+ # Execute Entry Point function 4 in Third Party VM
9237
+ # @param cmd [PAR8] (in) Sub command to be executed
9238
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9239
+ # @param length_out [PAR16] (out) Amount of data returned
9240
+ # @param value [PARV] (out) Data from opcode
9241
+ def dynload_entry_4(cmd, length_in, length_out, value)
9242
+ logger.debug do
9243
+ args = [cmd, length_in, length_out, value]
9244
+ "called dynload_entry_4 with #{args.inspect}"
9245
+ end
9246
+
9247
+ bytes = u8(0xF6)
9248
+ bytes += param_simple(cmd)
9249
+ bytes += param_simple(length_in)
9250
+ bytes += param_simple(length_out)
9251
+ bytes += param_simple(value)
9252
+ logger.debug "returning bytecode: #{bytes.inspect}"
9253
+ bytes
9254
+ end
9255
+
9256
+ # Execute Entry Point function 5 in Third Party VM
9257
+ # @param cmd [PAR8] (in) Sub command to be executed
9258
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9259
+ # @param length_out [PAR16] (out) Amount of data returned
9260
+ # @param value [PARV] (out) Data from opcode
9261
+ def dynload_entry_5(cmd, length_in, length_out, value)
9262
+ logger.debug do
9263
+ args = [cmd, length_in, length_out, value]
9264
+ "called dynload_entry_5 with #{args.inspect}"
9265
+ end
9266
+
9267
+ bytes = u8(0xF7)
9268
+ bytes += param_simple(cmd)
9269
+ bytes += param_simple(length_in)
9270
+ bytes += param_simple(length_out)
9271
+ bytes += param_simple(value)
9272
+ logger.debug "returning bytecode: #{bytes.inspect}"
9273
+ bytes
9274
+ end
9106
9275
 
9107
- # Could not define dynload_entry_6: Unhandled param type PARV
9276
+ # Execute Entry Point function 6 in Third Party VM
9277
+ # @param cmd [PAR8] (in) Sub command to be executed
9278
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9279
+ # @param length_out [PAR16] (out) Amount of data returned
9280
+ # @param value [PARV] (out) Data from opcode
9281
+ def dynload_entry_6(cmd, length_in, length_out, value)
9282
+ logger.debug do
9283
+ args = [cmd, length_in, length_out, value]
9284
+ "called dynload_entry_6 with #{args.inspect}"
9285
+ end
9286
+
9287
+ bytes = u8(0xF8)
9288
+ bytes += param_simple(cmd)
9289
+ bytes += param_simple(length_in)
9290
+ bytes += param_simple(length_out)
9291
+ bytes += param_simple(value)
9292
+ logger.debug "returning bytecode: #{bytes.inspect}"
9293
+ bytes
9294
+ end
9295
+
9296
+ # Execute Entry Point function 7 in Third Party VM
9297
+ # @param cmd [PAR8] (in) Sub command to be executed
9298
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9299
+ # @param length_out [PAR16] (out) Amount of data returned
9300
+ # @param value [PARV] (out) Data from opcode
9301
+ def dynload_entry_7(cmd, length_in, length_out, value)
9302
+ logger.debug do
9303
+ args = [cmd, length_in, length_out, value]
9304
+ "called dynload_entry_7 with #{args.inspect}"
9305
+ end
9306
+
9307
+ bytes = u8(0xF9)
9308
+ bytes += param_simple(cmd)
9309
+ bytes += param_simple(length_in)
9310
+ bytes += param_simple(length_out)
9311
+ bytes += param_simple(value)
9312
+ logger.debug "returning bytecode: #{bytes.inspect}"
9313
+ bytes
9314
+ end
9315
+
9316
+ # Execute Entry Point function 8 in Third Party VM
9317
+ # @param cmd [PAR8] (in) Sub command to be executed
9318
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9319
+ # @param length_out [PAR16] (out) Amount of data returned
9320
+ # @param value [PARV] (out) Data from opcode
9321
+ def dynload_entry_8(cmd, length_in, length_out, value)
9322
+ logger.debug do
9323
+ args = [cmd, length_in, length_out, value]
9324
+ "called dynload_entry_8 with #{args.inspect}"
9325
+ end
9108
9326
 
9109
- # Could not define dynload_entry_7: Unhandled param type PARV
9327
+ bytes = u8(0xFA)
9328
+ bytes += param_simple(cmd)
9329
+ bytes += param_simple(length_in)
9330
+ bytes += param_simple(length_out)
9331
+ bytes += param_simple(value)
9332
+ logger.debug "returning bytecode: #{bytes.inspect}"
9333
+ bytes
9334
+ end
9110
9335
 
9111
- # Could not define dynload_entry_8: Unhandled param type PARV
9336
+ # Execute Entry Point function 9 in Third Party VM
9337
+ # @param cmd [PAR8] (in) Sub command to be executed
9338
+ # @param length_in [PAR8] (in) Amount of data passed to this opcode
9339
+ # @param length_out [PAR16] (out) Amount of data returned
9340
+ # @param value [PARV] (out) Data from opcode
9341
+ def dynload_entry_9(cmd, length_in, length_out, value)
9342
+ logger.debug do
9343
+ args = [cmd, length_in, length_out, value]
9344
+ "called dynload_entry_9 with #{args.inspect}"
9345
+ end
9112
9346
 
9113
- # Could not define dynload_entry_9: Unhandled param type PARV
9347
+ bytes = u8(0xFB)
9348
+ bytes += param_simple(cmd)
9349
+ bytes += param_simple(length_in)
9350
+ bytes += param_simple(length_out)
9351
+ bytes += param_simple(value)
9352
+ logger.debug "returning bytecode: #{bytes.inspect}"
9353
+ bytes
9354
+ end
9114
9355
 
9115
9356
  # Get the index of the currently loaded VM
9116
9357
  # @param result [PAR8] (out) VM Index, Robotc = 0, Labview = 1, -1 for no loaded VM