z80 0.2.0 → 0.3.1

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: f7127ba75b47ae54758721e1a7db87984334826633a39605772f4c0530e888f4
4
+ data.tar.gz: ad2660a9e28bd3b0f4ad08468c84066eea7a87351c4079717041ccdbd11aca03
5
5
  SHA512:
6
- metadata.gz: b1e1a6097cc49a5efe595675e4b63fb8027e9e6cc9ba152fd1c1aa1b7ba7519562f079dc68d86e00d5119fc22d1db6895639e71f4fdf28a237d0bc9682f8ba4c
7
- data.tar.gz: c3da2a05c7860e59e82827f0b2cf0a3ce70cbae64e6de4d8d3fc2f55850797fca015d24a357714b60fd14c11177336cafede3da347ed445aedff86162974e311
6
+ metadata.gz: 9d9e5ad2028dcffd3676260cf3b440c0a3f5e4c362ef6af1de0e13b9cd16faa888211d75f22cfae977b7664178e112d2a70d896e615f8d8079168d2134f9523a
7
+ data.tar.gz: a33735315fc7c33a6419e0e0d4af0d204962491a2f040002d4aa6f47bbdbc2baa60e677798eaba9dcd5313f3d09c63ee66009ceb99d19790f5c56afd8d84e99a
data/CHANGELOG.md CHANGED
@@ -1,4 +1,25 @@
1
- # Z80-Ruby ChangeLog
1
+ # Z80-Ruby Changelog
2
+
3
+ This is the version history and changelog of Z80-Ruby. Version numbers do not correlate with those of the Z80 library. Release dates are in UTC time zone.
4
+
5
+ ## 0.3.1 / 2024-01-05
6
+
7
+ ### Bugfixes
8
+
9
+ * Fixed `Z80#full_r`, which previously acted as `Z80#refresh_address` by mistake.
10
+
11
+ ## 0.3.0 / 2024-01-03
12
+
13
+ ### Enhancements
14
+
15
+ * 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?`.
16
+ * 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.
17
+ * The parameter of `Z80#power` is now optional and the default value is `true`.
18
+ * `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`.
19
+
20
+ ### Bugfixes
21
+
22
+ * Fixed a potential bug or error when compiling the extension for Ruby `< 3.0`.
2
23
 
3
24
  ## 0.2.0 / 2024-01-02
4
25
 
@@ -10,7 +31,7 @@
10
31
  ### Bugfixes
11
32
 
12
33
  * 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=`.
34
+ * Fixed typos in the names of `Z80#xyl`, `Z80#xyl=`, `Z80#wzh`, `Z80#wzh=`, `Z80#wzl` and `Z80#wzl=`.
14
35
 
15
36
  ### Project
16
37
 
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-05
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.1
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>
@@ -167,8 +168,7 @@ static CallbackInfo const callback_info_table[] = {
167
168
  {Z_MEMBER_OFFSET(Z80, reti ), NULL, proc_reti, method_reti, },
168
169
  {Z_MEMBER_OFFSET(Z80, retn ), NULL, proc_retn, method_retn, },
169
170
  {Z_MEMBER_OFFSET(Z80, hook ), NULL, proc_hook, method_hook, },
170
- {Z_MEMBER_OFFSET(Z80, illegal ), NULL, proc_illegal, method_illegal, }
171
- };
171
+ {Z_MEMBER_OFFSET(Z80, illegal ), NULL, proc_illegal, method_illegal, }};
172
172
 
173
173
 
174
174
  static void set_callback(VALUE self, VALUE object, zuint index)
@@ -242,129 +242,173 @@ static VALUE Z80__context(VALUE self)
242
242
  }
243
243
 
244
244
 
245
+ #define INTEGER_ACCESSOR(type, member, access, with, converter_affix) \
246
+ \
247
+ static VALUE Z80__##member(VALUE self) \
248
+ { \
249
+ GET_Z80; \
250
+ return converter_affix##2NUM(access(member, with)); \
251
+ } \
252
+ \
253
+ \
254
+ static VALUE Z80__set_##member(VALUE self, VALUE value) \
255
+ { \
256
+ GET_Z80; \
257
+ access(member, with) = (type)NUM2##converter_affix(value); \
258
+ return value; \
259
+ }
260
+
261
+
245
262
  #define MACRO( member, macro) macro(*z80)
246
263
  #define DIRECT(member, macro) z80->member
247
- #define UINT_TO_BOOL(value) value ? Qtrue : Qfalse
248
-
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
- }
268
264
 
265
+ INTEGER_ACCESSOR(zusize, cycles, DIRECT, Z_EMPTY, SIZET)
266
+ INTEGER_ACCESSOR(zusize, cycle_limit, DIRECT, Z_EMPTY, SIZET)
267
+ INTEGER_ACCESSOR(zuint16, memptr, MACRO, Z80_MEMPTR, UINT )
268
+ INTEGER_ACCESSOR(zuint16, pc, MACRO, Z80_PC, UINT )
269
+ INTEGER_ACCESSOR(zuint16, sp, MACRO, Z80_SP, UINT )
270
+ INTEGER_ACCESSOR(zuint16, xy, MACRO, Z80_XY, UINT )
271
+ INTEGER_ACCESSOR(zuint16, ix, MACRO, Z80_IX, UINT )
272
+ INTEGER_ACCESSOR(zuint16, iy, MACRO, Z80_IY, UINT )
273
+ INTEGER_ACCESSOR(zuint16, af, MACRO, Z80_AF, UINT )
274
+ INTEGER_ACCESSOR(zuint16, bc, MACRO, Z80_BC, UINT )
275
+ INTEGER_ACCESSOR(zuint16, de, MACRO, Z80_DE, UINT )
276
+ INTEGER_ACCESSOR(zuint16, hl, MACRO, Z80_HL, UINT )
277
+ INTEGER_ACCESSOR(zuint16, af_, MACRO, Z80_AF_, UINT )
278
+ INTEGER_ACCESSOR(zuint16, bc_, MACRO, Z80_BC_, UINT )
279
+ INTEGER_ACCESSOR(zuint16, de_, MACRO, Z80_DE_, UINT )
280
+ INTEGER_ACCESSOR(zuint16, hl_, MACRO, Z80_HL_, UINT )
281
+ INTEGER_ACCESSOR(zuint8, memptrh, MACRO, Z80_MEMPTRH, UINT )
282
+ INTEGER_ACCESSOR(zuint8, memptrl, MACRO, Z80_MEMPTRL, UINT )
283
+ INTEGER_ACCESSOR(zuint8, pch, MACRO, Z80_PCH, UINT )
284
+ INTEGER_ACCESSOR(zuint8, pcl, MACRO, Z80_PCL, UINT )
285
+ INTEGER_ACCESSOR(zuint8, sph, MACRO, Z80_SPH, UINT )
286
+ INTEGER_ACCESSOR(zuint8, spl, MACRO, Z80_SPL, UINT )
287
+ INTEGER_ACCESSOR(zuint8, xyh, MACRO, Z80_XYH, UINT )
288
+ INTEGER_ACCESSOR(zuint8, xyl, MACRO, Z80_XYL, UINT )
289
+ INTEGER_ACCESSOR(zuint8, ixh, MACRO, Z80_IXH, UINT )
290
+ INTEGER_ACCESSOR(zuint8, ixl, MACRO, Z80_IXL, UINT )
291
+ INTEGER_ACCESSOR(zuint8, iyh, MACRO, Z80_IYH, UINT )
292
+ INTEGER_ACCESSOR(zuint8, iyl, MACRO, Z80_IYL, UINT )
293
+ INTEGER_ACCESSOR(zuint8, a, MACRO, Z80_A, UINT )
294
+ INTEGER_ACCESSOR(zuint8, f, MACRO, Z80_F, UINT )
295
+ INTEGER_ACCESSOR(zuint8, b, MACRO, Z80_B, UINT )
296
+ INTEGER_ACCESSOR(zuint8, c, MACRO, Z80_C, UINT )
297
+ INTEGER_ACCESSOR(zuint8, d, MACRO, Z80_D, UINT )
298
+ INTEGER_ACCESSOR(zuint8, e, MACRO, Z80_E, UINT )
299
+ INTEGER_ACCESSOR(zuint8, h, MACRO, Z80_H, UINT )
300
+ INTEGER_ACCESSOR(zuint8, l, MACRO, Z80_L, UINT )
301
+ INTEGER_ACCESSOR(zuint8, a_, MACRO, Z80_A_, UINT )
302
+ INTEGER_ACCESSOR(zuint8, f_, MACRO, Z80_F_, UINT )
303
+ INTEGER_ACCESSOR(zuint8, b_, MACRO, Z80_B_, UINT )
304
+ INTEGER_ACCESSOR(zuint8, c_, MACRO, Z80_C_, UINT )
305
+ INTEGER_ACCESSOR(zuint8, d_, MACRO, Z80_D_, UINT )
306
+ INTEGER_ACCESSOR(zuint8, e_, MACRO, Z80_E_, UINT )
307
+ INTEGER_ACCESSOR(zuint8, h_, MACRO, Z80_H_, UINT )
308
+ INTEGER_ACCESSOR(zuint8, l_, MACRO, Z80_L_, UINT )
309
+ INTEGER_ACCESSOR(zuint8, r, DIRECT, Z_EMPTY, UINT )
310
+ INTEGER_ACCESSOR(zuint8, i, DIRECT, Z_EMPTY, UINT )
311
+ INTEGER_ACCESSOR(zuint8, r7, DIRECT, Z_EMPTY, UINT )
312
+ INTEGER_ACCESSOR(zuint8, im, DIRECT, Z_EMPTY, UINT )
313
+ INTEGER_ACCESSOR(zuint8, request, DIRECT, Z_EMPTY, UINT )
314
+ INTEGER_ACCESSOR(zuint8, resume, DIRECT, Z_EMPTY, UINT )
315
+ INTEGER_ACCESSOR(zuint8, q, DIRECT, Z_EMPTY, UINT )
316
+ INTEGER_ACCESSOR(zuint8, options, DIRECT, Z_EMPTY, UINT )
269
317
 
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
318
  #undef MACRO
329
319
  #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); \
320
+ #undef INTEGER_ACCESSOR
321
+
322
+
323
+ #define BOOL_NUM_TO_UINT(value) \
324
+ (value == Qfalse ? 0U : (value == Qtrue ? 1U : !!NUM2UINT(value)))
325
+
326
+
327
+ #define BOOLEAN_ACCESSOR(member) \
328
+ \
329
+ static VALUE Z80__##member(VALUE self) \
330
+ { \
331
+ GET_Z80; \
332
+ return UINT2NUM(z80->member); \
333
+ } \
334
+ \
335
+ static VALUE Z80__##member##_p(VALUE self) \
336
+ { \
337
+ GET_Z80; \
338
+ return z80->member ? Qtrue : Qfalse; \
339
+ } \
340
+ \
341
+ \
342
+ static VALUE Z80__set_##member(VALUE self, VALUE value) \
343
+ { \
344
+ GET_Z80; \
345
+ z80->member = BOOL_NUM_TO_UINT(value); \
346
+ return value; \
347
347
  }
348
348
 
349
349
 
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)
350
+ BOOLEAN_ACCESSOR(iff1 )
351
+ BOOLEAN_ACCESSOR(iff2 )
352
+ BOOLEAN_ACCESSOR(int_line )
353
+ BOOLEAN_ACCESSOR(halt_line)
354
+
355
+ #undef BOOLEAN_ACCESSOR
356
+
357
+
358
+ #define FLAG_ACCESSOR(flag, mask, shift) \
359
+ \
360
+ static VALUE Z80__##flag(VALUE self) \
361
+ { \
362
+ GET_Z80; \
363
+ return UINT2NUM((Z80_F(*z80) >> shift) & 1); \
364
+ } \
365
+ \
366
+ \
367
+ static VALUE Z80__##flag##_p(VALUE self) \
368
+ { \
369
+ GET_Z80; \
370
+ return Z80_F(*z80) & Z80_##mask ? Qtrue : Qfalse; \
371
+ } \
372
+ \
373
+ \
374
+ static VALUE Z80__set_##flag(VALUE self, VALUE value) \
375
+ { \
376
+ GET_Z80; \
377
+ \
378
+ Z80_F(*z80) = \
379
+ (Z80_F(*z80) & ~(1U << shift)) | \
380
+ (BOOL_NUM_TO_UINT(value) << shift); \
381
+ \
382
+ return value; \
383
+ }
384
+
385
+
386
+ FLAG_ACCESSOR(sf, SF, 7)
387
+ FLAG_ACCESSOR(zf, ZF, 6)
388
+ FLAG_ACCESSOR(yf, YF, 5)
389
+ FLAG_ACCESSOR(hf, HF, 4)
390
+ FLAG_ACCESSOR(xf, XF, 3)
391
+ FLAG_ACCESSOR(pf, PF, 2)
392
+ FLAG_ACCESSOR(nf, NF, 1)
393
+ FLAG_ACCESSOR(cf, CF, 0)
358
394
 
359
395
  #undef FLAG_ACCESSOR
396
+ #undef BOOL_NUM_TO_UINT
360
397
 
361
398
 
362
399
  /* MARK: - Methods */
363
400
 
364
- static VALUE Z80__power(VALUE self, VALUE state)
401
+ static VALUE Z80__power(int argc, VALUE *argv, VALUE self)
365
402
  {
366
- GET_Z80;
367
- z80_power(z80, RB_TEST(state));
403
+ Z80 *z80;
404
+
405
+ if (argc > 1) rb_raise(
406
+ rb_eArgError,
407
+ "wrong number of arguments (given %d, expected 0 or 1)",
408
+ argc);
409
+
410
+ TypedData_Get_Struct(self, Z80, &z80_data_type, z80);
411
+ z80_power(z80, RB_TEST(argv[0]));
368
412
  return self;
369
413
  }
370
414
 
@@ -445,7 +489,7 @@ static VALUE Z80__out_cycle(VALUE self)
445
489
 
446
490
  static struct {char const* name; zuint offset;} const
447
491
 
448
- members_16[] = {
492
+ uint16_members[] = {
449
493
  {"memptr", Z_MEMBER_OFFSET(Z80, memptr )},
450
494
  {"pc", Z_MEMBER_OFFSET(Z80, pc )},
451
495
  {"sp", Z_MEMBER_OFFSET(Z80, sp )},
@@ -459,42 +503,58 @@ members_16[] = {
459
503
  {"af_", Z_MEMBER_OFFSET(Z80, af_ )},
460
504
  {"bc_", Z_MEMBER_OFFSET(Z80, bc_ )},
461
505
  {"de_", Z_MEMBER_OFFSET(Z80, de_ )},
462
- {"hl_", Z_MEMBER_OFFSET(Z80, hl_ )}
463
- },
506
+ {"hl_", Z_MEMBER_OFFSET(Z80, hl_ )}},
464
507
 
465
- members_8[] = {
466
- {"r", Z_MEMBER_OFFSET(Z80, r )},
508
+ uint8_members[] = {
467
509
  {"i", Z_MEMBER_OFFSET(Z80, i )},
510
+ {"r", Z_MEMBER_OFFSET(Z80, r )},
468
511
  {"r7", Z_MEMBER_OFFSET(Z80, r7 )},
512
+ {"q", Z_MEMBER_OFFSET(Z80, q )},
469
513
  {"im", Z_MEMBER_OFFSET(Z80, im )},
470
514
  {"request", Z_MEMBER_OFFSET(Z80, request )},
471
515
  {"resume", Z_MEMBER_OFFSET(Z80, resume )},
516
+ {"options", Z_MEMBER_OFFSET(Z80, options )},
472
517
  {"iff1", Z_MEMBER_OFFSET(Z80, iff1 )},
473
518
  {"iff2", Z_MEMBER_OFFSET(Z80, iff2 )},
474
- {"q", Z_MEMBER_OFFSET(Z80, q )},
475
- {"options", Z_MEMBER_OFFSET(Z80, options )},
476
519
  {"int_line", Z_MEMBER_OFFSET(Z80, int_line )},
477
- {"halt_line", Z_MEMBER_OFFSET(Z80, halt_line)}
478
- };
520
+ {"halt_line", Z_MEMBER_OFFSET(Z80, halt_line)}};
479
521
 
480
522
 
481
- static VALUE Z80__to_h(VALUE self)
523
+ static VALUE Z80__to_h(int argc, VALUE *argv, VALUE self)
482
524
  {
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;
525
+ Z80 *z80;
526
+ VALUE hash;
527
+ VALUE kv[(Z_ARRAY_SIZE(uint16_members) + Z_ARRAY_SIZE(uint8_members)) * 2];
528
+ int i, j, uint8_member_count;
487
529
 
488
- for (j = 0; j < Z_ARRAY_SIZE(members_16);)
530
+ if (argc > 1) rb_raise(
531
+ rb_eArgError,
532
+ "wrong number of arguments (given %d, expected 0 or 1)",
533
+ argc);
534
+
535
+ TypedData_Get_Struct(self, Z80, &z80_data_type, z80);
536
+ hash = rb_hash_new();
537
+
538
+ uint8_member_count =
539
+ Z_ARRAY_SIZE(uint8_members) -
540
+ ((argc && RB_TEST(argv[0])) << 2); /* 4 or 0 */
541
+
542
+ for (i = j = 0; j < Z_ARRAY_SIZE(uint16_members);)
489
543
  {
490
- kv[i++] = rb_id2sym(rb_intern(members_16[j].name));
491
- kv[i++] = UINT2NUM(*(zuint16 *)(void *)((char *)z80 + members_16[j++].offset));
544
+ kv[i++] = rb_id2sym(rb_intern(uint16_members[j].name));
545
+ kv[i++] = UINT2NUM(*(zuint16 *)(void *)((char *)z80 + uint16_members[j++].offset));
492
546
  }
493
547
 
494
- for (j = 0; j < Z_ARRAY_SIZE(members_8);)
548
+ for (j = 0; j < uint8_member_count;)
495
549
  {
496
- kv[i++] = rb_id2sym(rb_intern(members_8[j].name));
497
- kv[i++] = UINT2NUM(*((zuint8 *)z80 + members_8[j++].offset));
550
+ kv[i++] = rb_id2sym(rb_intern(uint8_members[j].name));
551
+ kv[i++] = UINT2NUM(*((zuint8 *)z80 + uint8_members[j++].offset));
552
+ }
553
+
554
+ while (j < Z_ARRAY_SIZE(uint8_members))
555
+ {
556
+ kv[i++] = rb_id2sym(rb_intern(uint8_members[j].name));
557
+ kv[i++] = *((zuint8 *)z80 + uint8_members[j++].offset) ? Qtrue : Qfalse;
498
558
  }
499
559
 
500
560
  rb_hash_bulk_insert_into_st_table(Z_ARRAY_SIZE(kv), kv, hash);
@@ -529,7 +589,7 @@ static VALUE Z80__print(VALUE self)
529
589
  "%c %c %c %c %c %c %c %c IFF2 %" PRIu8 " R7 %" PRIu8 " RI %" PRIu8 "\n",
530
590
  Z80_PC(*z80), Z80_AF(*z80), Z80_AF_(*z80), Z80_IX(*z80),
531
591
  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),
592
+ z80->i, z80->r, Z80_DE(*z80), Z80_DE_(*z80), Z80_IX(*z80),
533
593
  Z80_MEMPTR(*z80), Z80_HL(*z80), Z80_HL_(*z80), z80->q,
534
594
  z80->iff1, z80->im, '\0',
535
595
  one_hyphen[!(f & Z80_SF)],
@@ -580,13 +640,13 @@ static void Z80__compact(Z80 *z80)
580
640
  static rb_data_type_t const z80_data_type = {
581
641
  .wrap_struct_name = "z80",
582
642
  .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
- };
643
+ # if defined(RUBY_API_VERSION_MAJOR) && RUBY_API_VERSION_MAJOR >= 3
644
+ .dcompact = (void (*)(void *))Z80__compact,
645
+ # endif
646
+ .dmark = (void (*)(void *))Z80__mark,
647
+ .dfree = (void (*)(void *))Z80__free,
648
+ .dsize = NULL},
649
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
590
650
 
591
651
 
592
652
  static VALUE Z80__alloc(VALUE klass)
@@ -608,7 +668,7 @@ static VALUE Z80__alloc(VALUE klass)
608
668
  z80->nop =
609
669
  z80->nmia =
610
670
  z80->inta =
611
- z80->int_fetch =
671
+ z80->int_fetch =
612
672
  z80->hook = NULL;
613
673
  z80->ld_i_a =
614
674
  z80->ld_r_a =
@@ -690,8 +750,8 @@ void Init_z80(void)
690
750
  DEFINE_ACCESSOR(reti )
691
751
  DEFINE_ACCESSOR(retn )
692
752
  DEFINE_ACCESSOR(hook )
693
- DEFINE_ACCESSOR(illegal )
694
- DEFINE_ACCESSOR(context )
753
+ DEFINE_ACCESSOR(illegal )
754
+ DEFINE_ACCESSOR(context )
695
755
  DEFINE_ACCESSOR(cycles )
696
756
  DEFINE_ACCESSOR(cycle_limit )
697
757
  DEFINE_ACCESSOR(memptr )
@@ -708,8 +768,8 @@ void Init_z80(void)
708
768
  DEFINE_ACCESSOR(bc_ )
709
769
  DEFINE_ACCESSOR(de_ )
710
770
  DEFINE_ACCESSOR(hl_ )
711
- DEFINE_ACCESSOR(memptrh )
712
- DEFINE_ACCESSOR(memptrl )
771
+ DEFINE_ACCESSOR(memptrh )
772
+ DEFINE_ACCESSOR(memptrl )
713
773
  DEFINE_ACCESSOR(pch )
714
774
  DEFINE_ACCESSOR(pcl )
715
775
  DEFINE_ACCESSOR(sph )
@@ -740,37 +800,43 @@ void Init_z80(void)
740
800
  DEFINE_ACCESSOR(i )
741
801
  DEFINE_ACCESSOR(r7 )
742
802
  DEFINE_ACCESSOR(im )
743
- DEFINE_ACCESSOR(request )
803
+ DEFINE_ACCESSOR(request )
744
804
  DEFINE_ACCESSOR(resume )
745
- DEFINE_ACCESSOR(iff1 )
746
- DEFINE_ACCESSOR(iff2 )
747
805
  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 )
806
+ DEFINE_ACCESSOR(options )
807
+
808
+ # define DEFINE_BOOLEAN_ACCESSOR(name) \
809
+ DEFINE_ACCESSOR(name) \
810
+ rb_define_method(klass, #name "?", Z80__##name##_p, 0);
811
+
812
+ DEFINE_BOOLEAN_ACCESSOR(iff1 )
813
+ DEFINE_BOOLEAN_ACCESSOR(iff2 )
814
+ DEFINE_BOOLEAN_ACCESSOR(int_line )
815
+ DEFINE_BOOLEAN_ACCESSOR(halt_line)
816
+ DEFINE_BOOLEAN_ACCESSOR(sf )
817
+ DEFINE_BOOLEAN_ACCESSOR(zf )
818
+ DEFINE_BOOLEAN_ACCESSOR(yf )
819
+ DEFINE_BOOLEAN_ACCESSOR(hf )
820
+ DEFINE_BOOLEAN_ACCESSOR(xf )
821
+ DEFINE_BOOLEAN_ACCESSOR(pf )
822
+ DEFINE_BOOLEAN_ACCESSOR(nf )
823
+ DEFINE_BOOLEAN_ACCESSOR(cf )
759
824
 
760
825
  # undef DEFINE_ACCESSOR
826
+ # undef DEFINE_FLAG_ACCESSOR
761
827
 
762
- rb_define_method(klass, "power", Z80__power, 1);
828
+ rb_define_method(klass, "power", Z80__power, -1);
763
829
  rb_define_method(klass, "instant_reset", Z80__instant_reset, 0);
764
830
  rb_define_method(klass, "int", Z80__int, 1);
765
831
  rb_define_method(klass, "nmi", Z80__nmi, 0);
766
832
  rb_define_method(klass, "execute", Z80__execute, 1);
767
833
  rb_define_method(klass, "run", Z80__run, 1);
768
834
  rb_define_method(klass, "terminate", Z80__terminate, 0);
769
- rb_define_method(klass, "full_r", Z80__refresh_address, 0);
835
+ rb_define_method(klass, "full_r", Z80__full_r, 0);
770
836
  rb_define_method(klass, "refresh_address", Z80__refresh_address, 0);
771
837
  rb_define_method(klass, "in_cycle", Z80__in_cycle, 0);
772
838
  rb_define_method(klass, "out_cycle", Z80__out_cycle, 0);
773
- rb_define_method(klass, "to_h", Z80__to_h, 0);
839
+ rb_define_method(klass, "to_h", Z80__to_h, -1);
774
840
  rb_define_method(klass, "print", Z80__print, 0);
775
841
  /* rb_define_method(klass, "to_s", Z80__to_s, 0);*/
776
842
 
data/lib/z80/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Z80
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.1'
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.1
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-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler