z80 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: 4105cc740b5ab5ec51d21e3a26e9a05966c44ce7e6557c7fc3f37efa831a5ac9
4
- data.tar.gz: 3647f4f6f121f54963b7f09794a0a5aef3fa94204cbbd96cc904ee64eecdbb65
3
+ metadata.gz: 12b7a66c375de5f9ba5690822fcc76724d082ba22b4bcac8f0f13b3d8af27512
4
+ data.tar.gz: 2fdfab6e59f61340b4f2f72ad6e1ce7e715d5964b47d14cfc16e816e9b798d1e
5
5
  SHA512:
6
- metadata.gz: b1e1a6097cc49a5efe595675e4b63fb8027e9e6cc9ba152fd1c1aa1b7ba7519562f079dc68d86e00d5119fc22d1db6895639e71f4fdf28a237d0bc9682f8ba4c
7
- data.tar.gz: c3da2a05c7860e59e82827f0b2cf0a3ce70cbae64e6de4d8d3fc2f55850797fca015d24a357714b60fd14c11177336cafede3da347ed445aedff86162974e311
6
+ metadata.gz: 43d9460da873b3513cb3e7b661fd00fe08de1a3016e9716b6862a5ec726d32ef383c2c260dd1e470459dc1f4f636e10d0fce28f170b036b450ef1f82e47fb5ff
7
+ data.tar.gz: c5b2a9e632ce5f07cfd4b7020bf05205e3c3b3db66026606cf43430b91ef92c028ccff7ff9954b53102d3c9a89518ca962aea4294f3c4e3c4d0ebd457a6ec1a2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Z80-Ruby ChangeLog
2
2
 
3
+ ## 0.3.0 / 2024-01-03
4
+
5
+ ### Enhancements
6
+
7
+ * Added `Z80#sf?`, `Z80#zf?`, `Z80#yf?`, `Z80#hf?`, `Z80#xf?`, `Z80#pf?`, `Z80#nf?`, `Z80#cf?`, `Z80#iff1?`, `Z80#iff2?`, `Z80#int_line?` and `Z80#halt_line?`.
8
+ * Changed `Z80#sf`, `Z80#zf`, `Z80#yf`, `Z80#hf`, `Z80#xf`, `Z80#pf`, `Z80#nf` and `Z80#cf` to return an Integer instead of a boolean.
9
+ * The parameter of `Z80#power` is now optional and the default value is `true`.
10
+ * `Z80#to_h` now accepts one optional parameter. Passing `true` will create a Hash with boolean values for the following keys: `:iff1`, `:iff2`, `:int_line` and `:halt_line`.
11
+
12
+ ### Bugfixes
13
+
14
+ * Fixed a potential bug or error when compiling the extension for Ruby `< 3.0`.
15
+
3
16
  ## 0.2.0 / 2024-01-02
4
17
 
5
18
  ### Enhancements
@@ -10,7 +23,7 @@
10
23
  ### Bugfixes
11
24
 
12
25
  * Changed the order in which the files are required so that the extension is loaded before `'z80/version'`.
13
- * Fixed typos in the names of `#xyl`, `#xyl=`, `#wzh`, `#wzh=`, `#wzl` and `#wzl=`.
26
+ * Fixed typos in the names of `Z80#xyl`, `Z80#xyl=`, `Z80#wzh`, `Z80#wzh=`, `Z80#wzl` and `Z80#wzl=`.
14
27
 
15
28
  ### Project
16
29
 
data/CITATION.cff CHANGED
@@ -6,7 +6,7 @@ authors:
6
6
  email: manuel@zxe.io
7
7
  website: https://zxe.io
8
8
  cff-version: 1.2.0
9
- date-released: 2023-01-02
9
+ date-released: 2024-01-03
10
10
  keywords:
11
11
  - binding
12
12
  - CPU
@@ -20,5 +20,5 @@ message: If you use this software, please cite it using these metadata.
20
20
  repository-code: https://github.com/redcode/Z80-Ruby
21
21
  title: Z80-Ruby
22
22
  type: software
23
- version: 0.2.0
23
+ version: 0.3.0
24
24
  url: https://zxe.io/software/Z80-Ruby
data/LICENSE-0BSD CHANGED
@@ -1,6 +1,6 @@
1
1
  BSD Zero Clause License
2
2
 
3
- Copyright (C) 2023 Manuel Sainz de Baranda y Goñi.
3
+ Copyright (C) 2023-2024 Manuel Sainz de Baranda y Goñi.
4
4
 
5
5
  Permission to use, copy, modify, and/or distribute this software for any
6
6
  purpose with or without fee is hereby granted.
data/README.md CHANGED
@@ -79,6 +79,8 @@ cpu.hook do |context, address|
79
79
  end
80
80
  end
81
81
 
82
+ $stdout.sync = true if $stdout.tty?
83
+
82
84
  ARGV.each do |file_path|
83
85
  program = file_path == '-' ? $stdin.read : File.read(file_path)
84
86
  puts "#{file_path}:"
@@ -170,6 +172,8 @@ cpu.hook do |context, address|
170
172
  end
171
173
  end
172
174
 
175
+ $stdout.sync = true if $stdout.tty?
176
+
173
177
  ARGV.each do |file_path|
174
178
  program = file_path == '-' ? $stdin.read : File.read(file_path)
175
179
  puts "#{file_path}:"
data/ext/z80/z80.c CHANGED
@@ -3,7 +3,7 @@
3
3
  ____ \/__/ /\_\ __ \\ \/\ \ ______________________________________
4
4
  | /\_____\\_____\\_____\ |
5
5
  | Zilog \/_____//_____//_____/ CPU Emulator - Ruby Binding |
6
- | Copyright (C) 2023 Manuel Sainz de Baranda y Goñi. |
6
+ | Copyright (C) 2023-2024 Manuel Sainz de Baranda y Goñi. |
7
7
  | |
8
8
  | Permission to use, copy, modify, and/or distribute this software |
9
9
  | for any purpose with or without fee is hereby granted. |
@@ -20,6 +20,7 @@
20
20
  '===================================================================*/
21
21
 
22
22
  #include <ruby.h>
23
+ #include <ruby/version.h>
23
24
  #include <Z80.h>
24
25
  #include <Z/macros/array.h>
25
26
  #include <inttypes.h>
@@ -242,129 +243,173 @@ static VALUE Z80__context(VALUE self)
242
243
  }
243
244
 
244
245
 
246
+ #define INTEGER_ACCESSOR(type, member, access, with, converter_affix) \
247
+ \
248
+ static VALUE Z80__##member(VALUE self) \
249
+ { \
250
+ GET_Z80; \
251
+ return converter_affix##2NUM(access(member, with)); \
252
+ } \
253
+ \
254
+ \
255
+ static VALUE Z80__set_##member(VALUE self, VALUE value) \
256
+ { \
257
+ GET_Z80; \
258
+ access(member, with) = (type)NUM2##converter_affix(value); \
259
+ return value; \
260
+ }
261
+
262
+
245
263
  #define MACRO( member, macro) macro(*z80)
246
264
  #define DIRECT(member, macro) z80->member
247
- #define UINT_TO_BOOL(value) value ? Qtrue : Qfalse
248
265
 
249
- #define BOOL_NUM_TO_UINT(value) \
250
- (value == Qfalse ? 0 : (value == Qtrue ? 1 : !!NUM2UINT(value)))
251
-
252
-
253
- #define ACCESSOR(type, member, access, with, c_to_ruby, ruby_to_c) \
254
- \
255
- static VALUE Z80__##member(VALUE self) \
256
- { \
257
- GET_Z80; \
258
- return c_to_ruby(access(member, with)); \
259
- } \
260
- \
261
- \
262
- static VALUE Z80__set_##member(VALUE self, VALUE value) \
263
- { \
264
- GET_Z80; \
265
- access(member, with) = (type)ruby_to_c(value); \
266
- return value; \
267
- }
266
+ INTEGER_ACCESSOR(zusize, cycles, DIRECT, Z_EMPTY, SIZET)
267
+ INTEGER_ACCESSOR(zusize, cycle_limit, DIRECT, Z_EMPTY, SIZET)
268
+ INTEGER_ACCESSOR(zuint16, memptr, MACRO, Z80_MEMPTR, UINT )
269
+ INTEGER_ACCESSOR(zuint16, pc, MACRO, Z80_PC, UINT )
270
+ INTEGER_ACCESSOR(zuint16, sp, MACRO, Z80_SP, UINT )
271
+ INTEGER_ACCESSOR(zuint16, xy, MACRO, Z80_XY, UINT )
272
+ INTEGER_ACCESSOR(zuint16, ix, MACRO, Z80_IX, UINT )
273
+ INTEGER_ACCESSOR(zuint16, iy, MACRO, Z80_IY, UINT )
274
+ INTEGER_ACCESSOR(zuint16, af, MACRO, Z80_AF, UINT )
275
+ INTEGER_ACCESSOR(zuint16, bc, MACRO, Z80_BC, UINT )
276
+ INTEGER_ACCESSOR(zuint16, de, MACRO, Z80_DE, UINT )
277
+ INTEGER_ACCESSOR(zuint16, hl, MACRO, Z80_HL, UINT )
278
+ INTEGER_ACCESSOR(zuint16, af_, MACRO, Z80_AF_, UINT )
279
+ INTEGER_ACCESSOR(zuint16, bc_, MACRO, Z80_BC_, UINT )
280
+ INTEGER_ACCESSOR(zuint16, de_, MACRO, Z80_DE_, UINT )
281
+ INTEGER_ACCESSOR(zuint16, hl_, MACRO, Z80_HL_, UINT )
282
+ INTEGER_ACCESSOR(zuint8, memptrh, MACRO, Z80_MEMPTRH, UINT )
283
+ INTEGER_ACCESSOR(zuint8, memptrl, MACRO, Z80_MEMPTRL, UINT )
284
+ INTEGER_ACCESSOR(zuint8, pch, MACRO, Z80_PCH, UINT )
285
+ INTEGER_ACCESSOR(zuint8, pcl, MACRO, Z80_PCL, UINT )
286
+ INTEGER_ACCESSOR(zuint8, sph, MACRO, Z80_SPH, UINT )
287
+ INTEGER_ACCESSOR(zuint8, spl, MACRO, Z80_SPL, UINT )
288
+ INTEGER_ACCESSOR(zuint8, xyh, MACRO, Z80_XYH, UINT )
289
+ INTEGER_ACCESSOR(zuint8, xyl, MACRO, Z80_XYL, UINT )
290
+ INTEGER_ACCESSOR(zuint8, ixh, MACRO, Z80_IXH, UINT )
291
+ INTEGER_ACCESSOR(zuint8, ixl, MACRO, Z80_IXL, UINT )
292
+ INTEGER_ACCESSOR(zuint8, iyh, MACRO, Z80_IYH, UINT )
293
+ INTEGER_ACCESSOR(zuint8, iyl, MACRO, Z80_IYL, UINT )
294
+ INTEGER_ACCESSOR(zuint8, a, MACRO, Z80_A, UINT )
295
+ INTEGER_ACCESSOR(zuint8, f, MACRO, Z80_F, UINT )
296
+ INTEGER_ACCESSOR(zuint8, b, MACRO, Z80_B, UINT )
297
+ INTEGER_ACCESSOR(zuint8, c, MACRO, Z80_C, UINT )
298
+ INTEGER_ACCESSOR(zuint8, d, MACRO, Z80_D, UINT )
299
+ INTEGER_ACCESSOR(zuint8, e, MACRO, Z80_E, UINT )
300
+ INTEGER_ACCESSOR(zuint8, h, MACRO, Z80_H, UINT )
301
+ INTEGER_ACCESSOR(zuint8, l, MACRO, Z80_L, UINT )
302
+ INTEGER_ACCESSOR(zuint8, a_, MACRO, Z80_A_, UINT )
303
+ INTEGER_ACCESSOR(zuint8, f_, MACRO, Z80_F_, UINT )
304
+ INTEGER_ACCESSOR(zuint8, b_, MACRO, Z80_B_, UINT )
305
+ INTEGER_ACCESSOR(zuint8, c_, MACRO, Z80_C_, UINT )
306
+ INTEGER_ACCESSOR(zuint8, d_, MACRO, Z80_D_, UINT )
307
+ INTEGER_ACCESSOR(zuint8, e_, MACRO, Z80_E_, UINT )
308
+ INTEGER_ACCESSOR(zuint8, h_, MACRO, Z80_H_, UINT )
309
+ INTEGER_ACCESSOR(zuint8, l_, MACRO, Z80_L_, UINT )
310
+ INTEGER_ACCESSOR(zuint8, r, DIRECT, Z_EMPTY, UINT )
311
+ INTEGER_ACCESSOR(zuint8, i, DIRECT, Z_EMPTY, UINT )
312
+ INTEGER_ACCESSOR(zuint8, r7, DIRECT, Z_EMPTY, UINT )
313
+ INTEGER_ACCESSOR(zuint8, im, DIRECT, Z_EMPTY, UINT )
314
+ INTEGER_ACCESSOR(zuint8, request, DIRECT, Z_EMPTY, UINT )
315
+ INTEGER_ACCESSOR(zuint8, resume, DIRECT, Z_EMPTY, UINT )
316
+ INTEGER_ACCESSOR(zuint8, q, DIRECT, Z_EMPTY, UINT )
317
+ INTEGER_ACCESSOR(zuint8, options, DIRECT, Z_EMPTY, UINT )
268
318
 
269
-
270
- ACCESSOR(zusize, cycles, DIRECT, Z_EMPTY, SIZET2NUM, NUM2SIZET )
271
- ACCESSOR(zusize, cycle_limit, DIRECT, Z_EMPTY, SIZET2NUM, NUM2SIZET )
272
- ACCESSOR(zuint16, memptr, MACRO, Z80_MEMPTR, UINT2NUM, NUM2UINT )
273
- ACCESSOR(zuint16, pc, MACRO, Z80_PC, UINT2NUM, NUM2UINT )
274
- ACCESSOR(zuint16, sp, MACRO, Z80_SP, UINT2NUM, NUM2UINT )
275
- ACCESSOR(zuint16, xy, MACRO, Z80_XY, UINT2NUM, NUM2UINT )
276
- ACCESSOR(zuint16, ix, MACRO, Z80_IX, UINT2NUM, NUM2UINT )
277
- ACCESSOR(zuint16, iy, MACRO, Z80_IY, UINT2NUM, NUM2UINT )
278
- ACCESSOR(zuint16, af, MACRO, Z80_AF, UINT2NUM, NUM2UINT )
279
- ACCESSOR(zuint16, bc, MACRO, Z80_BC, UINT2NUM, NUM2UINT )
280
- ACCESSOR(zuint16, de, MACRO, Z80_DE, UINT2NUM, NUM2UINT )
281
- ACCESSOR(zuint16, hl, MACRO, Z80_HL, UINT2NUM, NUM2UINT )
282
- ACCESSOR(zuint16, af_, MACRO, Z80_AF_, UINT2NUM, NUM2UINT )
283
- ACCESSOR(zuint16, bc_, MACRO, Z80_BC_, UINT2NUM, NUM2UINT )
284
- ACCESSOR(zuint16, de_, MACRO, Z80_DE_, UINT2NUM, NUM2UINT )
285
- ACCESSOR(zuint16, hl_, MACRO, Z80_HL_, UINT2NUM, NUM2UINT )
286
- ACCESSOR(zuint8, memptrh, MACRO, Z80_MEMPTRH, UINT2NUM, NUM2UINT )
287
- ACCESSOR(zuint8, memptrl, MACRO, Z80_MEMPTRL, UINT2NUM, NUM2UINT )
288
- ACCESSOR(zuint8, pch, MACRO, Z80_PCH, UINT2NUM, NUM2UINT )
289
- ACCESSOR(zuint8, pcl, MACRO, Z80_PCL, UINT2NUM, NUM2UINT )
290
- ACCESSOR(zuint8, sph, MACRO, Z80_SPH, UINT2NUM, NUM2UINT )
291
- ACCESSOR(zuint8, spl, MACRO, Z80_SPL, UINT2NUM, NUM2UINT )
292
- ACCESSOR(zuint8, xyh, MACRO, Z80_XYH, UINT2NUM, NUM2UINT )
293
- ACCESSOR(zuint8, xyl, MACRO, Z80_XYL, UINT2NUM, NUM2UINT )
294
- ACCESSOR(zuint8, ixh, MACRO, Z80_IXH, UINT2NUM, NUM2UINT )
295
- ACCESSOR(zuint8, ixl, MACRO, Z80_IXL, UINT2NUM, NUM2UINT )
296
- ACCESSOR(zuint8, iyh, MACRO, Z80_IYH, UINT2NUM, NUM2UINT )
297
- ACCESSOR(zuint8, iyl, MACRO, Z80_IYL, UINT2NUM, NUM2UINT )
298
- ACCESSOR(zuint8, a, MACRO, Z80_A, UINT2NUM, NUM2UINT )
299
- ACCESSOR(zuint8, f, MACRO, Z80_F, UINT2NUM, NUM2UINT )
300
- ACCESSOR(zuint8, b, MACRO, Z80_B, UINT2NUM, NUM2UINT )
301
- ACCESSOR(zuint8, c, MACRO, Z80_C, UINT2NUM, NUM2UINT )
302
- ACCESSOR(zuint8, d, MACRO, Z80_D, UINT2NUM, NUM2UINT )
303
- ACCESSOR(zuint8, e, MACRO, Z80_E, UINT2NUM, NUM2UINT )
304
- ACCESSOR(zuint8, h, MACRO, Z80_H, UINT2NUM, NUM2UINT )
305
- ACCESSOR(zuint8, l, MACRO, Z80_L, UINT2NUM, NUM2UINT )
306
- ACCESSOR(zuint8, a_, MACRO, Z80_A_, UINT2NUM, NUM2UINT )
307
- ACCESSOR(zuint8, f_, MACRO, Z80_F_, UINT2NUM, NUM2UINT )
308
- ACCESSOR(zuint8, b_, MACRO, Z80_B_, UINT2NUM, NUM2UINT )
309
- ACCESSOR(zuint8, c_, MACRO, Z80_C_, UINT2NUM, NUM2UINT )
310
- ACCESSOR(zuint8, d_, MACRO, Z80_D_, UINT2NUM, NUM2UINT )
311
- ACCESSOR(zuint8, e_, MACRO, Z80_E_, UINT2NUM, NUM2UINT )
312
- ACCESSOR(zuint8, h_, MACRO, Z80_H_, UINT2NUM, NUM2UINT )
313
- ACCESSOR(zuint8, l_, MACRO, Z80_L_, UINT2NUM, NUM2UINT )
314
- ACCESSOR(zuint8, r, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
315
- ACCESSOR(zuint8, i, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
316
- ACCESSOR(zuint8, r7, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
317
- ACCESSOR(zuint8, im, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
318
- ACCESSOR(zuint8, request, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
319
- ACCESSOR(zuint8, resume, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
320
- ACCESSOR(zuint8, iff1, DIRECT, Z_EMPTY, UINT_TO_BOOL, BOOL_NUM_TO_UINT)
321
- ACCESSOR(zuint8, iff2, DIRECT, Z_EMPTY, UINT_TO_BOOL, BOOL_NUM_TO_UINT)
322
- ACCESSOR(zuint8, q, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
323
- ACCESSOR(zuint8, options, DIRECT, Z_EMPTY, UINT2NUM, NUM2UINT )
324
- ACCESSOR(zuint8, int_line, DIRECT, Z_EMPTY, UINT_TO_BOOL, BOOL_NUM_TO_UINT)
325
- ACCESSOR(zuint8, halt_line, DIRECT, Z_EMPTY, UINT_TO_BOOL, BOOL_NUM_TO_UINT)
326
-
327
- #undef UINT_TO_BOOL
328
319
  #undef MACRO
329
320
  #undef DIRECT
330
- #undef ACCESSOR
331
-
332
-
333
- #define FLAG_ACCESSOR(flag, shift) \
334
- \
335
- static VALUE Z80__##flag(VALUE self) \
336
- { \
337
- GET_Z80; \
338
- return UINT2NUM((Z80_F(*z80) >> shift) & 1); \
339
- } \
340
- \
341
- static VALUE Z80__set_##flag(VALUE self, VALUE value) \
342
- { \
343
- zuint8 bit = (zuint8)(NUM2UINT(value) & 1); \
344
- GET_Z80; \
345
- Z80_F(*z80) = (Z80_F(*z80) & ~(1U << shift)) | (bit << shift); \
346
- return UINT2NUM(bit); \
321
+ #undef INTEGER_ACCESSOR
322
+
323
+
324
+ #define BOOL_NUM_TO_UINT(value) \
325
+ (value == Qfalse ? 0U : (value == Qtrue ? 1U : !!NUM2UINT(value)))
326
+
327
+
328
+ #define BOOLEAN_ACCESSOR(member) \
329
+ \
330
+ static VALUE Z80__##member(VALUE self) \
331
+ { \
332
+ GET_Z80; \
333
+ return UINT2NUM(z80->member); \
334
+ } \
335
+ \
336
+ static VALUE Z80__##member##_p(VALUE self) \
337
+ { \
338
+ GET_Z80; \
339
+ return z80->member ? Qtrue : Qfalse; \
340
+ } \
341
+ \
342
+ \
343
+ static VALUE Z80__set_##member(VALUE self, VALUE value) \
344
+ { \
345
+ GET_Z80; \
346
+ z80->member = BOOL_NUM_TO_UINT(value); \
347
+ return value; \
347
348
  }
348
349
 
349
350
 
350
- FLAG_ACCESSOR(sf, 7)
351
- FLAG_ACCESSOR(zf, 6)
352
- FLAG_ACCESSOR(yf, 5)
353
- FLAG_ACCESSOR(hf, 4)
354
- FLAG_ACCESSOR(xf, 3)
355
- FLAG_ACCESSOR(pf, 2)
356
- FLAG_ACCESSOR(nf, 1)
357
- FLAG_ACCESSOR(cf, 0)
351
+ BOOLEAN_ACCESSOR(iff1 )
352
+ BOOLEAN_ACCESSOR(iff2 )
353
+ BOOLEAN_ACCESSOR(int_line )
354
+ BOOLEAN_ACCESSOR(halt_line)
355
+
356
+ #undef BOOLEAN_ACCESSOR
357
+
358
+
359
+ #define FLAG_ACCESSOR(flag, mask, shift) \
360
+ \
361
+ static VALUE Z80__##flag(VALUE self) \
362
+ { \
363
+ GET_Z80; \
364
+ return UINT2NUM((Z80_F(*z80) >> shift) & 1); \
365
+ } \
366
+ \
367
+ \
368
+ static VALUE Z80__##flag##_p(VALUE self) \
369
+ { \
370
+ GET_Z80; \
371
+ return Z80_F(*z80) & Z80_##mask ? Qtrue : Qfalse; \
372
+ } \
373
+ \
374
+ \
375
+ static VALUE Z80__set_##flag(VALUE self, VALUE value) \
376
+ { \
377
+ GET_Z80; \
378
+ \
379
+ Z80_F(*z80) = \
380
+ (Z80_F(*z80) & ~(1U << shift)) | \
381
+ (BOOL_NUM_TO_UINT(value) << shift); \
382
+ \
383
+ return value; \
384
+ }
385
+
386
+
387
+ FLAG_ACCESSOR(sf, SF, 7)
388
+ FLAG_ACCESSOR(zf, ZF, 6)
389
+ FLAG_ACCESSOR(yf, YF, 5)
390
+ FLAG_ACCESSOR(hf, HF, 4)
391
+ FLAG_ACCESSOR(xf, XF, 3)
392
+ FLAG_ACCESSOR(pf, PF, 2)
393
+ FLAG_ACCESSOR(nf, NF, 1)
394
+ FLAG_ACCESSOR(cf, CF, 0)
358
395
 
359
396
  #undef FLAG_ACCESSOR
397
+ #undef BOOL_NUM_TO_UINT
360
398
 
361
399
 
362
400
  /* MARK: - Methods */
363
401
 
364
- static VALUE Z80__power(VALUE self, VALUE state)
402
+ static VALUE Z80__power(int argc, VALUE *argv, VALUE self)
365
403
  {
366
- GET_Z80;
367
- z80_power(z80, RB_TEST(state));
404
+ Z80 *z80;
405
+
406
+ if (argc > 1) rb_raise(
407
+ rb_eArgError,
408
+ "wrong number of arguments (given %d, expected 0 or 1)",
409
+ argc);
410
+
411
+ TypedData_Get_Struct(self, Z80, &z80_data_type, z80);
412
+ z80_power(z80, RB_TEST(argv[0]));
368
413
  return self;
369
414
  }
370
415
 
@@ -445,7 +490,7 @@ static VALUE Z80__out_cycle(VALUE self)
445
490
 
446
491
  static struct {char const* name; zuint offset;} const
447
492
 
448
- members_16[] = {
493
+ uint16_members[] = {
449
494
  {"memptr", Z_MEMBER_OFFSET(Z80, memptr )},
450
495
  {"pc", Z_MEMBER_OFFSET(Z80, pc )},
451
496
  {"sp", Z_MEMBER_OFFSET(Z80, sp )},
@@ -462,39 +507,57 @@ members_16[] = {
462
507
  {"hl_", Z_MEMBER_OFFSET(Z80, hl_ )}
463
508
  },
464
509
 
465
- members_8[] = {
466
- {"r", Z_MEMBER_OFFSET(Z80, r )},
510
+ uint8_members[] = {
467
511
  {"i", Z_MEMBER_OFFSET(Z80, i )},
512
+ {"r", Z_MEMBER_OFFSET(Z80, r )},
468
513
  {"r7", Z_MEMBER_OFFSET(Z80, r7 )},
514
+ {"q", Z_MEMBER_OFFSET(Z80, q )},
469
515
  {"im", Z_MEMBER_OFFSET(Z80, im )},
470
516
  {"request", Z_MEMBER_OFFSET(Z80, request )},
471
517
  {"resume", Z_MEMBER_OFFSET(Z80, resume )},
518
+ {"options", Z_MEMBER_OFFSET(Z80, options )},
472
519
  {"iff1", Z_MEMBER_OFFSET(Z80, iff1 )},
473
520
  {"iff2", Z_MEMBER_OFFSET(Z80, iff2 )},
474
- {"q", Z_MEMBER_OFFSET(Z80, q )},
475
- {"options", Z_MEMBER_OFFSET(Z80, options )},
476
521
  {"int_line", Z_MEMBER_OFFSET(Z80, int_line )},
477
522
  {"halt_line", Z_MEMBER_OFFSET(Z80, halt_line)}
478
523
  };
479
524
 
480
525
 
481
- static VALUE Z80__to_h(VALUE self)
526
+ static VALUE Z80__to_h(int argc, VALUE *argv, VALUE self)
482
527
  {
483
- VALUE hash = rb_hash_new();
484
- VALUE kv[(Z_ARRAY_SIZE(members_16) + Z_ARRAY_SIZE(members_8)) * 2];
485
- int i = 0, j;
486
- GET_Z80;
528
+ Z80 *z80;
529
+ VALUE hash;
530
+ VALUE kv[(Z_ARRAY_SIZE(uint16_members) + Z_ARRAY_SIZE(uint8_members)) * 2];
531
+ int i, j, uint8_member_count;
487
532
 
488
- for (j = 0; j < Z_ARRAY_SIZE(members_16);)
533
+ if (argc > 1) rb_raise(
534
+ rb_eArgError,
535
+ "wrong number of arguments (given %d, expected 0 or 1)",
536
+ argc);
537
+
538
+ TypedData_Get_Struct(self, Z80, &z80_data_type, z80);
539
+ hash = rb_hash_new();
540
+
541
+ uint8_member_count =
542
+ Z_ARRAY_SIZE(uint8_members) -
543
+ ((argc && RB_TEST(argv[0])) << 2); /* 4 or 0 */
544
+
545
+ for (i = j = 0; j < Z_ARRAY_SIZE(uint16_members);)
489
546
  {
490
- kv[i++] = rb_id2sym(rb_intern(members_16[j].name));
491
- kv[i++] = UINT2NUM(*(zuint16 *)(void *)((char *)z80 + members_16[j++].offset));
547
+ kv[i++] = rb_id2sym(rb_intern(uint16_members[j].name));
548
+ kv[i++] = UINT2NUM(*(zuint16 *)(void *)((char *)z80 + uint16_members[j++].offset));
492
549
  }
493
550
 
494
- for (j = 0; j < Z_ARRAY_SIZE(members_8);)
551
+ for (j = 0; j < uint8_member_count;)
495
552
  {
496
- kv[i++] = rb_id2sym(rb_intern(members_8[j].name));
497
- kv[i++] = UINT2NUM(*((zuint8 *)z80 + members_8[j++].offset));
553
+ kv[i++] = rb_id2sym(rb_intern(uint8_members[j].name));
554
+ kv[i++] = UINT2NUM(*((zuint8 *)z80 + uint8_members[j++].offset));
555
+ }
556
+
557
+ while (j < Z_ARRAY_SIZE(uint8_members))
558
+ {
559
+ kv[i++] = rb_id2sym(rb_intern(uint8_members[j].name));
560
+ kv[i++] = *((zuint8 *)z80 + uint8_members[j++].offset) ? Qtrue : Qfalse;
498
561
  }
499
562
 
500
563
  rb_hash_bulk_insert_into_st_table(Z_ARRAY_SIZE(kv), kv, hash);
@@ -529,7 +592,7 @@ static VALUE Z80__print(VALUE self)
529
592
  "%c %c %c %c %c %c %c %c IFF2 %" PRIu8 " R7 %" PRIu8 " RI %" PRIu8 "\n",
530
593
  Z80_PC(*z80), Z80_AF(*z80), Z80_AF_(*z80), Z80_IX(*z80),
531
594
  Z80_SP(*z80), Z80_BC(*z80), Z80_BC_(*z80), Z80_IY(*z80),
532
- z80->i, z80->r, Z80_DE(*z80), Z80_DE_(*z80), Z80_IX(*z80),
595
+ z80->i, z80->r, Z80_DE(*z80), Z80_DE_(*z80), Z80_IX(*z80),
533
596
  Z80_MEMPTR(*z80), Z80_HL(*z80), Z80_HL_(*z80), z80->q,
534
597
  z80->iff1, z80->im, '\0',
535
598
  one_hyphen[!(f & Z80_SF)],
@@ -580,13 +643,13 @@ static void Z80__compact(Z80 *z80)
580
643
  static rb_data_type_t const z80_data_type = {
581
644
  .wrap_struct_name = "z80",
582
645
  .function = {
583
- .dmark = (void (*)(void *))Z80__mark,
584
- .dfree = (void (*)(void *))Z80__free,
585
- .dsize = NULL,
586
- .dcompact = (void (*)(void *))Z80__compact
587
- },
588
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
589
- };
646
+ # if defined(RUBY_API_VERSION_MAJOR) && RUBY_API_VERSION_MAJOR >= 3
647
+ .dcompact = (void (*)(void *))Z80__compact,
648
+ # endif
649
+ .dmark = (void (*)(void *))Z80__mark,
650
+ .dfree = (void (*)(void *))Z80__free,
651
+ .dsize = NULL},
652
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
590
653
 
591
654
 
592
655
  static VALUE Z80__alloc(VALUE klass)
@@ -608,7 +671,7 @@ static VALUE Z80__alloc(VALUE klass)
608
671
  z80->nop =
609
672
  z80->nmia =
610
673
  z80->inta =
611
- z80->int_fetch =
674
+ z80->int_fetch =
612
675
  z80->hook = NULL;
613
676
  z80->ld_i_a =
614
677
  z80->ld_r_a =
@@ -690,8 +753,8 @@ void Init_z80(void)
690
753
  DEFINE_ACCESSOR(reti )
691
754
  DEFINE_ACCESSOR(retn )
692
755
  DEFINE_ACCESSOR(hook )
693
- DEFINE_ACCESSOR(illegal )
694
- DEFINE_ACCESSOR(context )
756
+ DEFINE_ACCESSOR(illegal )
757
+ DEFINE_ACCESSOR(context )
695
758
  DEFINE_ACCESSOR(cycles )
696
759
  DEFINE_ACCESSOR(cycle_limit )
697
760
  DEFINE_ACCESSOR(memptr )
@@ -708,8 +771,8 @@ void Init_z80(void)
708
771
  DEFINE_ACCESSOR(bc_ )
709
772
  DEFINE_ACCESSOR(de_ )
710
773
  DEFINE_ACCESSOR(hl_ )
711
- DEFINE_ACCESSOR(memptrh )
712
- DEFINE_ACCESSOR(memptrl )
774
+ DEFINE_ACCESSOR(memptrh )
775
+ DEFINE_ACCESSOR(memptrl )
713
776
  DEFINE_ACCESSOR(pch )
714
777
  DEFINE_ACCESSOR(pcl )
715
778
  DEFINE_ACCESSOR(sph )
@@ -740,37 +803,43 @@ void Init_z80(void)
740
803
  DEFINE_ACCESSOR(i )
741
804
  DEFINE_ACCESSOR(r7 )
742
805
  DEFINE_ACCESSOR(im )
743
- DEFINE_ACCESSOR(request )
806
+ DEFINE_ACCESSOR(request )
744
807
  DEFINE_ACCESSOR(resume )
745
- DEFINE_ACCESSOR(iff1 )
746
- DEFINE_ACCESSOR(iff2 )
747
808
  DEFINE_ACCESSOR(q )
748
- DEFINE_ACCESSOR(options )
749
- DEFINE_ACCESSOR(int_line )
750
- DEFINE_ACCESSOR(halt_line )
751
- DEFINE_ACCESSOR(sf )
752
- DEFINE_ACCESSOR(zf )
753
- DEFINE_ACCESSOR(yf )
754
- DEFINE_ACCESSOR(hf )
755
- DEFINE_ACCESSOR(xf )
756
- DEFINE_ACCESSOR(pf )
757
- DEFINE_ACCESSOR(nf )
758
- DEFINE_ACCESSOR(cf )
809
+ DEFINE_ACCESSOR(options )
810
+
811
+ # define DEFINE_BOOLEAN_ACCESSOR(name) \
812
+ DEFINE_ACCESSOR(name) \
813
+ rb_define_method(klass, #name "?", Z80__##name##_p, 0);
814
+
815
+ DEFINE_BOOLEAN_ACCESSOR(iff1 )
816
+ DEFINE_BOOLEAN_ACCESSOR(iff2 )
817
+ DEFINE_BOOLEAN_ACCESSOR(int_line )
818
+ DEFINE_BOOLEAN_ACCESSOR(halt_line)
819
+ DEFINE_BOOLEAN_ACCESSOR(sf )
820
+ DEFINE_BOOLEAN_ACCESSOR(zf )
821
+ DEFINE_BOOLEAN_ACCESSOR(yf )
822
+ DEFINE_BOOLEAN_ACCESSOR(hf )
823
+ DEFINE_BOOLEAN_ACCESSOR(xf )
824
+ DEFINE_BOOLEAN_ACCESSOR(pf )
825
+ DEFINE_BOOLEAN_ACCESSOR(nf )
826
+ DEFINE_BOOLEAN_ACCESSOR(cf )
759
827
 
760
828
  # undef DEFINE_ACCESSOR
829
+ # undef DEFINE_FLAG_ACCESSOR
761
830
 
762
- rb_define_method(klass, "power", Z80__power, 1);
831
+ rb_define_method(klass, "power", Z80__power, -1);
763
832
  rb_define_method(klass, "instant_reset", Z80__instant_reset, 0);
764
833
  rb_define_method(klass, "int", Z80__int, 1);
765
834
  rb_define_method(klass, "nmi", Z80__nmi, 0);
766
835
  rb_define_method(klass, "execute", Z80__execute, 1);
767
836
  rb_define_method(klass, "run", Z80__run, 1);
768
837
  rb_define_method(klass, "terminate", Z80__terminate, 0);
769
- rb_define_method(klass, "full_r", Z80__refresh_address, 0);
838
+ rb_define_method(klass, "full_r", Z80__refresh_address, 0);
770
839
  rb_define_method(klass, "refresh_address", Z80__refresh_address, 0);
771
840
  rb_define_method(klass, "in_cycle", Z80__in_cycle, 0);
772
841
  rb_define_method(klass, "out_cycle", Z80__out_cycle, 0);
773
- rb_define_method(klass, "to_h", Z80__to_h, 0);
842
+ rb_define_method(klass, "to_h", Z80__to_h, -1);
774
843
  rb_define_method(klass, "print", Z80__print, 0);
775
844
  /* rb_define_method(klass, "to_s", Z80__to_s, 0);*/
776
845
 
data/lib/z80/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Z80
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z80
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Sainz de Baranda y Goñi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-02 00:00:00.000000000 Z
11
+ date: 2024-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler