7474
7575
7676/* MARK: - Precomputed Values of AF for `daa` */
77+ /*---------------------------------------------------------------------------.
78+ | Enabling `Z80_WITH_PRECOMPUTED_DAA` makes the `daa` instruction faster by |
79+ | using a lookup table. However, this instruction is rarely used in typical |
80+ | programs, so the overall speedup is minimal, and incresing the size of the |
81+ | emulator by 2 KiB may negatively impact cache efficiency. It is therefore |
82+ | recommended to leave this option disabled unless serious profiling on the |
83+ | target platform shows a significant benefit. |
84+ '===========================================================================*/
7785
7886#ifdef Z80_WITH_PRECOMPUTED_DAA
7987# define H (value ) Z_UINT16(0x##value)
@@ -250,7 +258,7 @@ typedef zuint8 (* Insn)(Z80 *self);
250258#endif
251259
252260
253- /* MARK: - Instance Variable and Callback Shortcuts */
261+ /* MARK: - Shortcuts for Instance Variables and Callbacks */
254262
255263#define MEMPTR self->memptr.uint16_value
256264#define PC self->pc.uint16_value
@@ -458,6 +466,15 @@ static Z_ALWAYS_INLINE void write_16b(Z80 *self, zuint16 address, zuint16 value)
458466
459467#define ZF_ZERO (value ) (!(value) << 6)
460468
469+ /*---------------------------------------------------------------------.
470+ | `PF_PARITY` computes PF according to the parity of the given byte. |
471+ | Enabling `Z80_WITH_PARITY_COMPUTATION` is strongly discouraged and |
472+ | is provided only for benchmarking and educational purposes. |
473+ | |
474+ | For an explanation of the parity computation formula, check: |
475+ | * http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel |
476+ '=====================================================================*/
477+
461478#ifdef Z80_WITH_PARITY_COMPUTATION
462479 static Z_ALWAYS_INLINE zuint8 pf_parity (zuint8 value )
463480 {return (zuint8 )(((0x9669U >> ((value ^ (value >> 4 )) & 0xF )) & 1 ) << 2 );}
@@ -489,7 +506,9 @@ static Z_ALWAYS_INLINE void write_16b(Z80 *self, zuint16 address, zuint16 value)
489506/*-----------------------------------------------------------------------------.
490507| `PF_OVERFLOW` computes PF according to whether signed overflow occurs in the |
491508| addition or subtraction of two integers. For additions, `rhs` must be passed |
492- | bit-wise ~inverted. For an explanation of the formula, check: |
509+ | bitwise ~inverted. |
510+ | |
511+ | For an explanation of the formula, check: |
493512| * https://stackoverflow.com/a/199668 |
494513| * http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Comb/overflow.html |
495514'=============================================================================*/
@@ -2678,20 +2697,20 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
26782697 hook = self -> hook ;
26792698 self -> hook = Z_NULL ;
26802699
2681- /*------------------------------------------------------------------------ .
2682- | The `Z80::fetch` callback is temporarily replaced by a trampoline that |
2683- | invokes `Z80::int_fetch`. This trampoline needs to access the callback |
2684- | pointer in addition to the initial, non-incremented value of PC, so the |
2685- | value of `Z80::context` is temporarily replaced by a pointer to an |
2686- | `IM0` object that holds the real context and all this data, which also |
2687- | makes it necessary to replace other callbacks with trampolines so that |
2688- | the real context can be passed to them. |
2689- | |
2690- | The main idea here is that the instruction code will invoke trampolines |
2691- | rather than callbacks, and the one assigned to `Z80::fetch` will ignore |
2692- | the received fetch address, passing instead to `Z80::int_fetch` the |
2693- | initial, non-incremented value of PC. |
2694- '======================================================================== */
2700+ /*-----------------------------------------------------------------------.
2701+ | The `Z80::fetch` callback is temporarily replaced with a trampoline |
2702+ | that invokes `Z80::int_fetch`. This trampoline needs access to the |
2703+ | callback pointer as well as the initial, non-incremented value of PC. |
2704+ | To provide this, the value of `Z80::context` is temporarily replaced |
2705+ | with a pointer to an `IM0` object that holds the real context and all |
2706+ | required data. As a consequence, other callbacks must also be replaced |
2707+ | with trampolines so that the real context can be passed to them. |
2708+ | |
2709+ | The main idea is that the instruction code invokes trampolines rather |
2710+ | than callbacks. The trampoline assigned to `Z80::fetch` ignores the |
2711+ | received fetch address and passes the initial, non-incremented value |
2712+ | of PC to `Z80::int_fetch` instead. |
2713+ '=======================================================================*/
26952714 im0 .z80 = self ;
26962715 im0 .context = CONTEXT ;
26972716 im0 .fetch = self -> fetch ;
@@ -2709,16 +2728,16 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
27092728
27102729 im0_execute :
27112730
2712- /*------------------------------------------------------------------------ .
2713- | `call`, `djnz`, `jr` and `rst` increment PC before pushing it onto the |
2714- | stack or using it as the base address. This makes it necessary to |
2715- | decrement PC before executing any of these instructions so that the |
2716- | final address is correct. `jmp` and `ret` are handled here too because |
2717- | in their case this pre-decrement has no effect and PC must also not be |
2718- | corrected after executing the instruction. These groups of instructions |
2719- | are identified by using a table of decrements. Note that `jmp (XY)` and |
2720- | `reti/ retn` are prefixed and will be handled later. |
2721- '======================================================================== */
2731+ /*-----------------------------------------------------------------------.
2732+ | `call`, `djnz`, `jr` and `rst` increment PC before pushing it onto the |
2733+ | stack or using it as the base address. This makes it necessary to |
2734+ | decrement PC before executing any of these instructions so that the |
2735+ | final address is correct. `jmp` and `ret` are handled here as well |
2736+ | because in this case the pre-decrement has no effect and PC must not |
2737+ | be corrected either after executing the instruction. This group of |
2738+ | instructions is identified using a table of decrements. Note that |
2739+ | `jmp (XY)`, ` reti` and ` retn` are prefixed and will be handled later. |
2740+ '=======================================================================*/
27222741 if (im0_pc_decrement_table [ird ])
27232742 {
27242743 PC -= im0_pc_decrement_table [ird ];
@@ -2779,7 +2798,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
27792798 self -> cycles += 4 + 8 ;
27802799
27812800 else {
2782- DATA [2 ] = 4 ;
2801+ DATA [2 ] = 4 ; /* Notify wait T-states. */
27832802 self -> cycles += 4 + self -> illegal (self , ird );
27842803 }
27852804 }
0 commit comments