z80 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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