119#define GET_C_FLAG(x) (x->flags & BIT_0_MASK)
120#define GET_Z_FLAG(x) (x->flags & BIT_1_MASK)
121#define GET_I_FLAG(x) (x->flags & BIT_2_MASK)
122#define GET_D_FLAG(x) (x->flags & BIT_3_MASK)
123#define GET_B_FLAG(x) (x->flags & BIT_4_MASK)
124#define GET_P_FLAG(x) (x->flags & BIT_5_MASK)
125#define GET_V_FLAG(x) (x->flags & BIT_6_MASK)
126#define GET_N_FLAG(x) (x->flags & BIT_7_MASK)
128#define SET_C_FLAG(x) (x->flags = x->flags | BIT_0_MASK)
129#define SET_Z_FLAG(x) (x->flags = x->flags | BIT_1_MASK)
130#define SET_I_FLAG(x) (x->flags = x->flags | BIT_2_MASK)
131#define SET_D_FLAG(x) (x->flags = x->flags | BIT_3_MASK)
132#define SET_B_FLAG(x) (x->flags = x->flags | BIT_4_MASK)
133#define SET_P_FLAG(x) (x->flags = x->flags | BIT_5_MASK)
134#define SET_V_FLAG(x) (x->flags = x->flags | BIT_6_MASK)
135#define SET_N_FLAG(x) (x->flags = x->flags | BIT_7_MASK)
137#define SET_ALL_FLAGS(x) (x->flags = x->flags | 0xFF)
139#define CLEAR_C_FLAG(x) (x->flags = x->flags & NBIT_0_MASK)
140#define CLEAR_Z_FLAG(x) (x->flags = x->flags & NBIT_1_MASK)
141#define CLEAR_I_FLAG(x) (x->flags = x->flags & NBIT_2_MASK)
142#define CLEAR_D_FLAG(x) (x->flags = x->flags & NBIT_3_MASK)
143#define CLEAR_B_FLAG(x) (x->flags = x->flags & NBIT_4_MASK)
144#define CLEAR_P_FLAG(x) (x->flags = x->flags & NBIT_5_MASK)
145#define CLEAR_V_FLAG(x) (x->flags = x->flags & NBIT_6_MASK)
146#define CLEAR_N_FLAG(x) (x->flags = x->flags & NBIT_7_MASK)
148#define CLEAR_ALL_FLAGS(x) (x->flags = x->flags & 0x00)
156#define indexed_indirect(cpu, addr, offset) \
157 cpu->mem[(cpu->mem[(addr + offset) & 0xFF]) | (cpu->mem[(addr + offset + 1) & 0xFF] << 8)]
165#define indirect_indexed(cpu, addr, offset) \
166 cpu->mem[(cpu->mem[(addr) & 0xFF] | cpu->mem[(addr + 1) & 0xFF] << 8) + offset]
173#define indirect(cpu, addr) cpu->mem[((cpu->mem[(addr)]) | (cpu->mem[(addr) + 1] << 8))]
180#define get_address(cpu) \
181 (cpu->mem[cpu->program_counter + 1] | (cpu->mem[cpu->program_counter + 2] << 8))
189#define is_page_crossed(addr, offset) ((addr & 0x00ff) && !((addr + offset) & 0x00ff))
196#define LD_FLAGS_GENERIC(cpu, reg) \
199 if (cpu->reg == 0) { \
202 } else if (cpu->reg & BIT_7_MASK) { \
217#define LD_immediate_GENERIC(cpu, reg, d) \
223 } else if ((d) & BIT_7_MASK) { \
237#define LD_immediate_ACC(processor, d) (LD_immediate_GENERIC(processor, accumulator, d))
244#define LD_immediate_X(processor, d) (LD_immediate_GENERIC(processor, register_x, d))
251#define LD_immediate_Y(processor, d) (LD_immediate_GENERIC(processor, register_y, d))
260#define LD_offset_GENERIC(cpu, reg, addr, offset) \
261 LD_immediate_GENERIC(cpu, reg, cpu->mem[addr + offset])
269#define LD_offset_ACC(processor, addr, offset) \
270 (LD_offset_GENERIC(processor, accumulator, addr, offset))
278#define LD_offset_X(processor, addr, offset) \
279 (LD_offset_GENERIC(processor, register_x, addr, offset))
287#define LD_offset_Y(processor, addr, offset) \
288 (LD_offset_GENERIC(processor, register_y, addr, offset))
296#define LD_absolute_GENERIC(cpu, reg, addr) LD_immediate_GENERIC(cpu, reg, cpu->mem[addr])
303#define LD_absolute_ACC(processor, addr) (LD_absolute_GENERIC(processor, accumulator, addr))
310#define LD_absolute_X(processor, addr) (LD_absolute_GENERIC(processor, register_x, addr))
317#define LD_absolute_Y(processor, addr) (LD_absolute_GENERIC(processor, register_y, addr))
325#define LD_indirect_GENERIC(cpu, reg, addr) (LD_immediate_GENERIC(cpu, reg, indirect(cpu, addr)))
333#define LD_indirect_ACC(processor, addr) LD_indirect_GENERIC(processor, accumulator, addr)
341#define LD_indirect_X(processor, addr) LD_indirect_GENERIC(processor, register_x, addr)
349#define LD_indirect_Y(processor, addr) LD_indirect_GENERIC(processor, register_y, addr)
357#define DECINC_GENERIC(cpu, reg, op) \
360 if (cpu->reg == 0) { \
363 } else if (cpu->reg & BIT_7_MASK) { \
377#define DEC_absolute(processor, addr) DECINC_GENERIC(processor, mem[addr], --)
384#define INC_absolute(processor, addr) DECINC_GENERIC(processor, mem[addr], ++)
392#define DEC_offset(processor, addr, offset) DECINC_GENERIC(processor, mem[addr + offset], --)
400#define INC_offset(processor, addr, offset) DECINC_GENERIC(processor, mem[addr + offset], ++)
406#define INC_X(processor) DECINC_GENERIC(processor, register_x, ++)
412#define INC_Y(processor) DECINC_GENERIC(processor, register_y, ++)
418#define DEC_X(processor) DECINC_GENERIC(processor, register_x, --)
424#define DEC_Y(processor) DECINC_GENERIC(processor, register_y, --)
432#define LD_indexed_indirect_ACC(processor, addr, offset) \
433 (LD_immediate_GENERIC(processor, accumulator, indexed_indirect(processor, addr, offset)))
441#define LD_indirect_indexed_ACC(processor, addr, offset) \
442 (LD_immediate_GENERIC(processor, accumulator, indirect_indexed(processor, addr, offset)))
450#define STR_absolute_GENERIC(cpu, reg, addr) ({ cpu->mem[addr] = cpu->reg; })
457#define STR_absolute_ACC(processor, addr) STR_absolute_GENERIC(processor, accumulator, addr)
464#define STR_absolute_X(processor, addr) STR_absolute_GENERIC(processor, register_x, addr)
471#define STR_absolute_Y(processor, addr) STR_absolute_GENERIC(processor, register_y, addr)
480#define STR_offset_GENERIC(cpu, reg, addr, offset) STR_absolute_GENERIC(cpu, reg, addr + offset)
488#define STR_offset_ACC(processor, addr, offset) \
489 STR_offset_GENERIC(processor, accumulator, addr, offset)
497#define STR_offset_X(processor, addr, offset) \
498 STR_offset_GENERIC(processor, register_x, addr, offset)
506#define STR_offset_Y(processor, addr, offset) \
507 STR_offset_GENERIC(processor, register_y, addr, offset)
516#define STR_indirect_indexed_ACC(processor, addr, offset) \
517 ({ indirect_indexed(processor, addr, offset) = processor->accumulator; })
526#define STR_indexed_indirect_ACC(processor, addr, offset) \
527 ({ indexed_indirect(processor, addr, offset) = processor->accumulator; })
535#define TR_GENERIC(cpu, reg1, reg2) \
537 cpu->reg2 = cpu->reg1; \
538 LD_FLAGS_GENERIC(cpu, reg2); \
545#define TR_ACC_X(processor) TR_GENERIC(processor, accumulator, register_x)
551#define TR_ACC_Y(processor) TR_GENERIC(processor, accumulator, register_y)
557#define TR_X_ACC(processor) TR_GENERIC(processor, register_x, accumulator)
563#define TR_Y_ACC(processor) TR_GENERIC(processor, register_y, accumulator)
569#define TR_SP_X(processor) TR_GENERIC(processor, stack_pointer, register_x)
575#define TR_X_SP(processor) TR_GENERIC(processor, register_x, stack_pointer)
582#define PUSH_GENERIC(cpu, reg) \
584 cpu->mem[STACK_END | cpu->stack_pointer] = cpu->reg; \
585 --(cpu->stack_pointer); \
593#define PUSH_immediate(cpu, d) \
595 cpu->mem[STACK_END | cpu->stack_pointer] = d; \
596 --(cpu->stack_pointer); \
603#define PUSH_ACC(processor) PUSH_GENERIC(processor, accumulator)
609#define PUSH_FLAGS(processor) PUSH_GENERIC(processor, flags)
615#define PUSH_PC(processor) \
617 PUSH_immediate(processor, GET_HIGHER(processor->program_counter)); \
618 PUSH_immediate(processor, GET_LOWER(processor->program_counter)); \
626#define PULL_GENERIC(cpu, reg) \
628 ++(cpu->stack_pointer); \
629 cpu->reg = cpu->mem[0x1100 | cpu->stack_pointer]; \
636#define PULL_ACC(processor) PULL_GENERIC(processor, accumulator)
642#define PULL_FLAGS(processor) PULL_GENERIC(processor, flags)
648#define PULL_PC(processor) \
650 ++(processor->stack_pointer); \
651 processor->program_counter = ((processor->mem[STACK_END | processor->stack_pointer])); \
652 ++(processor->stack_pointer); \
653 processor->program_counter = (processor->program_counter & 0x00ff) | \
654 (processor->mem[STACK_END | processor->stack_pointer] << 8); \
662#define ADD_immediate(processor, data) \
664 processor->cache = (processor->accumulator); \
665 processor->accumulator += (data + GET_C_FLAG(processor)); \
666 if ((processor->cache & BIT_7_MASK) != (processor->accumulator & BIT_7_MASK)) { \
667 SET_V_FLAG(processor); \
668 SET_C_FLAG(processor); \
669 CLEAR_N_FLAG(processor); \
670 SET_Z_FLAG(processor); \
671 } else if (processor->accumulator & BIT_7_MASK) { \
672 CLEAR_V_FLAG(processor); \
673 SET_N_FLAG(processor); \
674 CLEAR_Z_FLAG(processor); \
675 } else if (processor->accumulator == 0) { \
676 SET_Z_FLAG(processor); \
677 CLEAR_V_FLAG(processor); \
678 CLEAR_N_FLAG(processor); \
680 CLEAR_V_FLAG(processor); \
681 CLEAR_N_FLAG(processor); \
682 CLEAR_Z_FLAG(processor); \
692#define ADD_absolute(processor, addr) ADD_immediate(processor, processor->mem[addr])
701#define ADD_offset(processor, addr, offset) ADD_immediate(processor, processor->mem[addr + offset])
710#define ADD_indexed_indirect(processor, addr, offset) \
711 ADD_immediate(processor, indexed_indirect(processor, addr, offset))
719#define ADD_indirect_indexed(processor, addr, offset) \
720 ADD_immediate(processor, indirect_indexed(processor, addr, offset))
726#define LOGICAL_FLAGS(processor) \
728 if (processor->accumulator & BIT_7_MASK) { \
729 CLEAR_ALL_FLAGS(processor); \
730 SET_N_FLAG(processor); \
731 } else if (processor->accumulator == 0) { \
732 CLEAR_ALL_FLAGS(processor); \
733 SET_Z_FLAG(processor); \
735 CLEAR_ALL_FLAGS(processor); \
744#define AND_immediate(processor, data) \
746 processor->accumulator &= data; \
747 LOGICAL_FLAGS(processor); \
755#define AND_absolute(processor, addr) AND_immediate(processor, processor->mem[addr])
763#define AND_offset(processor, addr, offset) AND_immediate(processor, processor->mem[addr + offset])
772#define AND_indexed_indirect(processor, addr, offset) \
773 AND_immediate(processor, indexed_indirect(processor, addr, offset))
781#define AND_indirect_indexed(processor, addr, offset) \
782 AND_immediate(processor, indirect_indexed(processor, addr, offset))
789#define OR_immediate(processor, data) \
791 processor->accumulator |= data; \
792 LOGICAL_FLAGS(processor); \
800#define OR_absolute(processor, addr) OR_immediate(processor, processor->mem[addr])
808#define OR_offset(processor, addr, offset) OR_immediate(processor, processor->mem[addr + offset])
817#define OR_indexed_indirect(processor, addr, offset) \
818 OR_immediate(processor, indexed_indirect(processor, addr, offset))
826#define OR_indirect_indexed(processor, addr, offset) \
827 OR_immediate(processor, indirect_indexed(processor, addr, offset))
834#define XOR_immediate(processor, data) \
836 processor->accumulator ^= data; \
837 LOGICAL_FLAGS(processor); \
845#define XOR_absolute(processor, addr) XOR_immediate(processor, processor->mem[addr])
853#define XOR_offset(processor, addr, offset) XOR_immediate(processor, processor->mem[addr + offset])
862#define XOR_indexed_indirect(processor, addr, offset) \
863 XOR_immediate(processor, indexed_indirect(processor, addr, offset))
871#define XOR_indirect_indexed(processor, addr, offset) \
872 XOR_immediate(processor, indirect_indexed(processor, addr, offset))
880#define SBC_immediate(processor, data) \
882 processor->cache = (processor->accumulator); \
883 processor->accumulator -= (data + GET_C_FLAG(processor)); \
884 if ((processor->cache & BIT_7_MASK) != (processor->accumulator & BIT_7_MASK)) { \
885 SET_V_FLAG(processor); \
886 CLEAR_C_FLAG(processor); \
887 CLEAR_Z_FLAG(processor); \
888 SET_N_FLAG(processor); \
889 } else if (processor->accumulator & BIT_7_MASK) { \
890 CLEAR_V_FLAG(processor); \
891 SET_N_FLAG(processor); \
892 CLEAR_Z_FLAG(processor); \
893 } else if (processor->accumulator == 0) { \
894 SET_Z_FLAG(processor); \
895 CLEAR_V_FLAG(processor); \
896 CLEAR_N_FLAG(processor); \
898 CLEAR_V_FLAG(processor); \
899 CLEAR_N_FLAG(processor); \
900 CLEAR_Z_FLAG(processor); \
910#define SBC_absolute(processor, addr) SBC_immediate(processor, processor->mem[addr])
919#define SBC_offset(processor, addr, offset) SBC_immediate(processor, processor->mem[addr + offset])
928#define SBC_indexed_indirect(processor, addr, offset) \
929 SBC_immediate(processor, indexed_indirect(processor, addr, offset))
938#define SBC_indirect_indexed(processor, addr, offset) \
939 SBC_immediate(processor, indirect_indexed(processor, addr, offset))
944#define NO_OPERATION()
951#define BIT_TEST(processor, addr) \
953 processor->cache = processor->accumulator & processor->mem[addr]; \
954 if (processor->cache == 0) { \
955 SET_Z_FLAG(processor); \
957 CLEAR_Z_FLAG(processor); \
958 if (processor->cache & BIT_7_MASK) { \
959 SET_N_FLAG(processor); \
961 if (processor->cache & BIT_6_MASK) { \
962 SET_V_FLAG(processor); \
973#define BRANCH_GENERIC_S(processor, flag_mask, offset) \
975 if (processor->flags & flag_mask) { \
976 processor->program_counter += (signed char)(offset); \
985#define BRANCH_GENERIC_C(processor, flag_mask, offset) \
987 if (!(processor->flags & flag_mask)) { \
988 processor->program_counter += (signed char)(offset); \
997#define BRANCH_If_Positive(processor, offset) BRANCH_GENERIC_C(processor, BIT_7_MASK, offset)
1004#define BRANCH_Overflow_C(processor, offset) BRANCH_GENERIC_C(processor, BIT_6_MASK, offset)
1011#define BRANCH_Not_Equal(processor, offset) BRANCH_GENERIC_C(processor, BIT_1_MASK, offset)
1018#define BRANCH_Carry_C(processor, offset) BRANCH_GENERIC_C(processor, BIT_0_MASK, offset)
1025#define BRANCH_If_Minus(processor, offset) BRANCH_GENERIC_S(processor, BIT_7_MASK, offset)
1032#define BRANCH_Overflow_S(processor, offset) BRANCH_GENERIC_S(processor, BIT_6_MASK, offset)
1039#define BRANCH_Equal(processor, offset) BRANCH_GENERIC_S(processor, BIT_1_MASK, offset)
1046#define BRANCH_Carry_S(processor, offset) BRANCH_GENERIC_S(processor, BIT_0_MASK, offset)
1057#define SHIFT_GENERIC(processor, field, operator, flag_shift_offset, flag_mask) \
1059 CLEAR_C_FLAG(processor); \
1060 processor->flags |= ((processor->field & flag_mask) >> (flag_shift_offset)); \
1061 processor->field = processor->field operator(1); \
1062 if (processor->field == 0) { \
1063 SET_Z_FLAG(processor); \
1064 CLEAR_N_FLAG(processor); \
1065 } else if (processor->field & BIT_7_MASK) { \
1066 SET_N_FLAG(processor); \
1067 CLEAR_Z_FLAG(processor); \
1076#define SHIFT_LEFT_ACC(processor) SHIFT_GENERIC(processor, accumulator, <<, 7, BIT_7_MASK)
1083#define SHIFT_RIGHT_ACC(processor) SHIFT_GENERIC(processor, accumulator, >>, 0, BIT_0_MASK)
1091#define SHIFT_LEFT_absolute(processor, addr) SHIFT_GENERIC(processor, mem[addr], <<, 7, BIT_7_MASK)
1098#define SHIFT_RIGHT_absolute(processor, addr) SHIFT_GENERIC(processor, mem[addr], >>, 0, BIT_0_MASK)
1107#define SHIFT_LEFT_offset(processor, addr, offset) SHIFT_LEFT_absolute(processor, addr + offset)
1116#define SHIFT_RIGHT_offset(processor, addr, offset) SHIFT_RIGHT_absolute(processor, addr + offset)
1128#define ROTATION_GENERIC(processor, field, operator, store_offset, pop_offset, flag_mask) \
1130 processor->cache = ((processor->field & flag_mask) >> (store_offset)); \
1131 processor->field = (processor->field operator(1)) | (GET_C_FLAG(processor) << pop_offset); \
1132 CLEAR_C_FLAG(processor); \
1133 processor->flags |= processor->cache; \
1134 if (processor->field == 0) { \
1135 SET_Z_FLAG(processor); \
1136 CLEAR_N_FLAG(processor); \
1137 } else if (processor->field & BIT_7_MASK) { \
1138 SET_N_FLAG(processor); \
1139 CLEAR_Z_FLAG(processor); \
1149#define ROTATION_LEFT_ACC(processor) ROTATION_GENERIC(processor, accumulator, <<, 7, 0, BIT_7_MASK)
1157#define ROTATION_RIGHT_ACC(processor) ROTATION_GENERIC(processor, accumulator, >>, 0, 7, BIT_0_MASK)
1166#define ROTATION_LEFT_absolute(processor, addr) \
1167 ROTATION_GENERIC(processor, mem[addr], <<, 7, 0, BIT_7_MASK)
1176#define ROTATION_RIGHT_absolute(processor, addr) \
1177 ROTATION_GENERIC(processor, mem[addr], >>, 0, 7, BIT_0_MASK)
1187#define ROTATION_LEFT_offset(processor, addr, offset) \
1188 ROTATION_LEFT_absolute(processor, addr + offset)
1198#define ROTATION_RIGHT_offset(processor, addr, offset) \
1199 ROTATION_RIGHT_absolute(processor, addr + offset)
1206#define JUMP_absolute(processor, addr) processor->program_counter = addr
1213#define JUMP_indirect(processor, addr) \
1214 JUMP_absolute(processor, ((cpu->mem[(addr)]) | (cpu->mem[(addr) + 1] << 8)))
1221#define GENERIC_IR(processor, vector_start) \
1223 PUSH_PC(processor); \
1224 PUSH_FLAGS(processor); \
1225 JUMP_indirect(processor, vector_start); \
1232#define BREAK(processor) \
1234 GENERIC_IR(processor, 0xfffe); \
1235 SET_B_FLAG(processor); \
1242#define IRQ(processor) \
1244 GENERIC_IR(processor, 0xfffe); \
1245 CLEAR_B_FLAG(processor); \
1252#define NMI(processor) \
1254 GENERIC_IR(processor, 0xfffa); \
1255 CLEAR_B_FLAG(processor); \
1262#define RESET(processor) \
1264 processor->stack_pointer = 0xff; \
1265 CLEAR_ALL_FLAGS(processor); \
1266 JUMP_indirect(processor, 0xfffc); \
1275#define JUMP_Subroutine(processor, addr) \
1277 processor->program_counter += 2; \
1278 PUSH_PC(processor); \
1279 JUMP_absolute(processor, addr); \
1287#define RETURN_Subroutine(processor) \
1289 PULL_PC(processor); \
1290 ++processor->program_counter; \
1298#define RETURN_Interrupt(processor) \
1300 PULL_FLAGS(processor); \
1301 PULL_PC(processor); \
1310#define COMPARE_GENERIC_Immediate(processor, value, register) \
1312 if (processor->register > value) { \
1313 SET_C_FLAG(processor); \
1314 CLEAR_Z_FLAG(processor); \
1315 CLEAR_N_FLAG(processor); \
1316 } else if (processor->register == value) { \
1317 SET_Z_FLAG(processor); \
1318 SET_C_FLAG(processor); \
1319 CLEAR_N_FLAG(processor); \
1321 CLEAR_Z_FLAG(processor); \
1322 CLEAR_C_FLAG(processor); \
1323 SET_N_FLAG(processor); \
1332#define COMPARE_Immediate_ACC(processor, value) \
1333 COMPARE_GENERIC_Immediate(processor, value, accumulator)
1340#define COMPARE_absolute_ACC(processor, addr) COMPARE_Immediate_ACC(processor, processor->mem[addr])
1349#define COMPARE_offset_ACC(processor, addr, offset) COMPARE_absolute_ACC(processor, addr + offset)
1358#define COMPARE_indexed_indirect_ACC(processor, addr, offset) \
1359 COMPARE_absolute_ACC(processor, indexed_indirect(processor, addr, offset))
1368#define COMPARE_indirect_indexed_ACC(processor, addr, offset) \
1369 COMPARE_absolute_ACC(processor, indirect_indexed(processor, addr, offset))
1377#define COMPARE_Immediate_X(processor, value) \
1378 COMPARE_GENERIC_Immediate(processor, value, register_x)
1386#define COMPARE_absolute_X(processor, addr) COMPARE_Immediate_X(processor, processor->mem[addr])
1394#define COMPARE_Immediate_Y(processor, value) \
1395 COMPARE_GENERIC_Immediate(processor, value, register_y)
1403#define COMPARE_absolute_Y(processor, addr) COMPARE_Immediate_X(processor, processor->mem[addr])
errcode_t step_cpu(CPU *cpu)
Function that step a clock cycle.
void print_stack_expected(memory stack, data start)
Procedure that display the expected state of the stack.
unsigned char get_next_instruction(CPU *cpu)
Function that get the next instruction written in the ROM.
void init_cpu(CPU *cpu, memory mem)
Procedure that initialize the CPU to its boot/reset state.
void print_cpu_state(CPU *processor)
Procedure that displays the current state of the CPU.
void print_cpu_expected(data acc, data x, data y, data flags, address pc, data sp)
Procedure that display the expected state of the CPU.
void reset(CPU *processor)
Procedure that resets the CPU by using the NES reset routine.
void print_stack_state(CPU *cpu)
Procedure that display the current state of the stack.
errcode_t execute_instruction(CPU *cpu)
Function that execute the current instruction in the ROM.
void start_cpu(CPU *cpu)
Procedure that acts like the reset button of the NES.
void free_cpu(CPU *cpu)
Procedure that free the memory used by the CPU and the memory array.
This structure will be used to represent the state of the Central Processing Unit (CPU) of our emulat...
data cache
A 8 bit reserved space that I use for some operations.
data accumulator
A 8 bit register used to perform operations.
data register_y
A 8 bit register. Commonly used to hold offset and counters.
address program_counter
An address pointing to the next instruction to be executed.
unsigned char cycle_counter
The cycle counter. The counter is decremented every step.
data stack_pointer
A register that holds the 8 lower bytes of the address 0x11??.
memory mem
A direct access to the Emulator Memory.
data register_x
A 8 bit register. Commonly used to hold offset and counters.
two_bytes_word address
Definition of the address format used by the CPU.
byte errcode_t
Definition of the error code type used by some function.
byte data
Definition of the data format used by the CPU.