104 {
105
106 int opt;
108
109 while ((opt = getopt(argc, argv, ":i:")) != -1) {
110 switch (opt) {
111 case 'i':
112 printf("Filepath: %s\n", optarg);
114 if (my_rom != NULL) {
117 }
119 break;
120 default:
121 break;
122 }
123 }
124
126 data stack_test[256];
127
131
132 for (unsigned int i = 0; i < 50; ++i) {
134 }
135
136 printf("##### Load Tests #####\n\n");
137
141
144
148
151
155
158
159 cpu->
mem[0 | 1 << 8] = 121;
160 cpu->
mem[1 | 2 << 8] = 122;
161 cpu->
mem[2 | 3 << 8] = 123;
162
166
169
172
173 printf("##### INC/DEC Tests #####\n\n");
174
177
180
183
186
187 printf("##### Indirections test #####\n\n");
188
189 cpu->
mem[(5) | (6) << 8] = 150;
190
193
196
199
200 cpu->
mem[((1) | (1) << 8) + 2] = 5;
201
203
205
208
209 stack_test[0xFF] = 5;
210
211 printf("##### PUSH/PULL tests #####\n\n");
212
215
218
222
224
227
230
232
233 stack_test[0xFF] = 0xFC;
234 stack_test[0xFE] = 0xFF;
235
238
239 stack_test[0xFF] = 0x0C;
240 stack_test[0xFE] = 0x81;
241
244
247
249
252
254
256
257 stack_test[0xFF] = 0x9c;
258
261
264
266
268
270
273
276
277 printf("##### ADD Tests #####\n\n");
278
280
283
286
289
292
295
298
302
305
308
311 cpu->
mem[0x1111] = 20;
312
314
317
320
322
325
328
330
333
336
337 printf("##### And Tests #####\n\n");
338
340
343
344 cpu->
mem[0x5040] = 0xf1;
345
347
350
353
355
358
361 cpu->
mem[0x1111] = 0x00;
362
364
367
369
371
374
375 printf("##### Or Tests #####\n\n");
376
378
381
382 cpu->
mem[0] = 0b00000010;
383
385
388
389 cpu->
mem[1] = 0b00000100;
390
392
395
398 cpu->
mem[0x1111] = 0b00001000;
399
401
404
405 cpu->
mem[0x1111] = 0b00010000;
406
408
411
412 printf("##### Xor Tests #####\n\n");
413
416
419
420 cpu->
mem[0] = 0b11000011;
421
423
426
427 cpu->
mem[1] = 0b10101010;
429
432
435
436 cpu->
mem[0x5555] = 0b01010101;
437
439
442
443 cpu->
mem[0x5555] = 0xff;
444
446
449
450 printf("##### Sbc Tests #####\n\n");
451
453
456
459
461
463
466
468
470
473
476
477 cpu->
mem[0x1111] = 10;
478
480
483
485
488
489 printf("##### TR Tests #####\n\n");
490
494
497
499
502
505
508
510
513
515
518
521
524
528
529 printf("##### STR Tests #####\n\n");
530
532 printf(
"\nExpected: 10 | %i\n", cpu->
mem[0x1100]);
533
535 printf(
"\nExpected: 10 | %i\n", cpu->
mem[0x1101]);
536
538 printf(
"\nExpected: 10 | %i\n", cpu->
mem[0x1102]);
539
543
545 printf(
"\nExpected: 15 | %i\n", cpu->
mem[0x05]);
546
548 printf(
"\nExpected: 16 | %i\n", cpu->
mem[0x06]);
549
551 printf(
"\nExpected: 17 | %i\n", cpu->
mem[0x07]);
552
555
558
559 printf("##### BIT Tests #####\n\n");
560
561 cpu->
mem[0x00] = 0xFF;
562 cpu->
mem[0x01] = 0b00110011;
563 cpu->
mem[0x02] = 0x00;
568
570
573
577
579
583
585
589
590 printf("##### Branch Tests #####\n\n");
591
595
598
601
604
607
610
613
616
618
621
623
626
629
631
634
636
639
640 printf("##### Shifts Tests #####\n\n");
641
644
646
649
651
654
655 for (int i = 0; i < 3; ++i) {
657 }
658
661
663 cpu->
mem[10] = 0b10000001;
664
666
669
670 printf(
"\nExpected: 2 | %i\n\n", cpu->
mem[10]);
671
673
676
677 printf(
"\nExpected: 4 | %i\n\n", cpu->
mem[10]);
678
680
683
684 printf(
"\nExpected: 2 | %i\n\n", cpu->
mem[10]);
685
688
691
692 printf(
"\nExpected: 0 | %i\n\n", cpu->
mem[10]);
693
694 printf("##### Rotations Tests #####\n\n");
695
698
701
704
707
710
713
715
718
721
724
727
728 cpu->
mem[10] = 0b00000110;
731
734
735 printf(
"\nExpected: 1 | %i\n\n", cpu->
mem[10]);
736
739
742
743 printf(
"\nExpected: %i | %i\n\n", 0b11000000, cpu->
mem[10]);
744
747
749
752
753 printf(
"\nExpected: 1 | %i\n\n", cpu->
mem[10]);
754
757
760
761 printf(
"\nExpected: 6 | %i\n\n", cpu->
mem[10]);
762
763 printf("##### Jump Tests #####\n\n");
764
766
769
770 cpu->
mem[0x00ff] = 0x0c;
771 cpu->
mem[0x0100] = 0x81;
772
774
777
778 printf("##### Break Test #####\n\n");
779
780 cpu->
mem[0xfffe] = 0xaa;
781 cpu->
mem[0xffff] = 0xff;
782
783 stack_test[0xff] = 0x81;
784 stack_test[0xfe] = 0x0c;
785 stack_test[0xfd] = 0;
786
788
791
794
795 printf("##### RTI, RTS, JSR Test #####\n\n");
796
798
801
803
804 stack_test[0xff] = 0x81;
805 stack_test[0xfe] = 0x0e;
806
809
812
814
817
819
820 if (my_rom != NULL) {
822 }
823
825}
#define ADD_indexed_indirect(processor, addr, offset)
Procedure that perform a ADD with the carry flag (A,Z,C,N=A+M+C) with indexed indirect addressing mod...
#define STR_absolute_X(processor, addr)
Procedure that store the X register value to a memory address.
#define TR_ACC_X(processor)
Procedure that store the value in the accumulator in the X register.
#define OR_indexed_indirect(processor, addr, offset)
Procedure that perform a OR with the carry flag (A,Z,C,N=A+M+C) with indexed indirect addressing mode...
#define PULL_FLAGS(processor)
Procedure that pop the top value of the stack and return it to the flags register.
#define OR_absolute(processor, addr)
Procedure that performs a bitwise logic OR (A,Z,N = A&M) using absolute addressing mode.
#define BRANCH_If_Minus(processor, offset)
Procedure that performs a BMI (branch if positive, if the N flag is clear)
#define AND_indirect_indexed(processor, addr, offset)
Procedure that perform a AND with the carry flag (A,Z,C,N=A+M+C) with indirect indexed.
#define TR_ACC_Y(processor)
Procedure that store the value in accumulator in the Y register.
#define ROTATION_RIGHT_absolute(processor, addr)
Procedure that performs a bit shift with rotation to the right (ROR operation) at the memory address ...
#define ROTATION_RIGHT_offset(processor, addr, offset)
Procedure that performs a bit shift with rotation to the right (ROR operation) at the memory address ...
#define LD_indirect_ACC(processor, addr)
Procedure that lods a value from memory at the address contained in addr|addr+1. (indirection)
#define ADD_immediate(processor, data)
Procedure that perform a ADD with the carry flag (A,Z,C,N=A+data+C) with an immediate.
#define SHIFT_RIGHT_absolute(processor, addr)
Procedure that performs a bitshift to the right (LSR operation) at the address addr and place the 0th...
#define ROTATION_RIGHT_ACC(processor)
Procedure that performs a bit shift with rotation to the right (ROR operation) on the accumulator....
#define TR_X_SP(processor)
Procedure that store the value in the X register in the stack pointer.
#define STR_offset_ACC(processor, addr, offset)
Procedure that store the accumulator value to a memory address + offset.
#define XOR_immediate(processor, data)
Procedure that performs a bitwise logic XOR (A,Z,N = A & data)
#define DEC_Y(processor)
Procedure that decrements the Y register.
#define XOR_indexed_indirect(processor, addr, offset)
Procedure that perform a XOR with the carry flag (A,Z,C,N=A+M+C) with indexed indirect addressing mod...
void init_cpu(CPU *cpu, memory mem)
Procedure that initialize the CPU to its boot/reset state.
#define STR_offset_X(processor, addr, offset)
Procedure that store the X register value to a memory address + offset.
#define PULL_PC(processor)
Procedure that pop the top value of the stack and return it to the program counter.
#define STR_absolute_ACC(processor, addr)
Procedure that store the accumulator value to a memory address.
#define LD_indirect_indexed_ACC(processor, addr, offset)
Procedure that loads to the accmulator using Inderect Indexed.
#define OR_immediate(processor, data)
Procedure that performs a bitwise logic OR (A,Z,N = A & data)
#define LD_indirect_X(processor, addr)
Procedure that lods a value from memory at the address contained in addr|addr+1. (indirection)
#define ADD_indirect_indexed(processor, addr, offset)
Procedure that perform a ADD with the carry flag (A,Z,C,N=A+M+C) with indirect indexed.
#define AND_absolute(processor, addr)
Procedure that performs a bitwise logic AND (A,Z,N = A&M) using absolute addressing mode.
#define BRANCH_Carry_S(processor, offset)
Procedure that performs a BCS (branch if positive, if the N flag is clear)
#define AND_indexed_indirect(processor, addr, offset)
Procedure that perform a AND with the carry flag (A,Z,C,N=A+M+C) with indexed indirect addressing mod...
#define LD_indirect_Y(processor, addr)
Procedure that lods a value from memory at the address contained in addr|addr+1. (indirection)
#define BRANCH_Not_Equal(processor, offset)
Procedure that performs a BNE (if the Z flag is clear)
#define BRANCH_If_Positive(processor, offset)
Procedure that performs a BPL (branch if positive, if the N flag is clear)
#define STR_indirect_indexed_ACC(processor, addr, offset)
Procedure that store the accumulator value to a memory address using indirect indexed addressing mode...
#define STR_offset_Y(processor, addr, offset)
Procedure that store the Y register value to a memory address + offset.
#define DEC_X(processor)
Procedure that decrements the X register.
#define BREAK(processor)
Procedure that performs a break instruction (forces an interrupt).
#define RETURN_Subroutine(processor)
Procedure that performs a return from subroutine (RTS instruction) by pulling the top two elements of...
#define LD_absolute_X(processor, addr)
Procedure that loads a value from memory at the address addr to the X register.
#define LD_immediate_ACC(processor, d)
Procedure that loads an immediate (const value) in the accumulator.
#define LD_immediate_X(processor, d)
Procedure that loads an immediate (const value) in the X register.
#define SHIFT_LEFT_ACC(processor)
Procedure that performs a bitshift to the left (ASL operation) on the accumulator and place the 7th b...
#define BIT_TEST(processor, addr)
Procedure that performs a BIT test (A & M, N = M7, V = M6)
#define ADD_offset(processor, addr, offset)
Procedure that perform a ADD with the carry flag (A,Z,C,N=A+M+C) with absolute+offset addressing addr...
#define PUSH_ACC(processor)
Procedure that push the accumulator value to the top of the stack.
#define SHIFT_LEFT_absolute(processor, addr)
Procedure that performs a bitshift to the left (ASL operation) at the address addr and place the 7th ...
#define SBC_indexed_indirect(processor, addr, offset)
Procedure that perform a SBC with the carry flag (A,Z,C,N=A-M-C) with indexed indirect addressing mod...
#define INC_Y(processor)
Procedure that increments the Y register.
#define XOR_absolute(processor, addr)
Procedure that performs a bitwise logic XOR (A,Z,N = A&M) using absolute addressing mode.
#define LD_absolute_Y(processor, addr)
Procedure that loads a value from memory at the address addr to the Y register.
#define JUMP_absolute(processor, addr)
Procedure that sets the program counter to a certain address (JMP instruction)
#define PULL_ACC(processor)
Procedure that pop the top value of the stack and return it to the accumulator.
#define SBC_offset(processor, addr, offset)
Procedure that perform a SBC with the carry flag (A,Z,C,N=A-M-C) with offset addressing mode.
#define SBC_absolute(processor, addr)
Procedure that perform a SBC with the carry flag (A,Z,C,N=A-M-C) with absolute addressing mode.
#define OR_offset(processor, addr, offset)
Procedure that performs a bitwise logic OR (A,Z,N = A&M) using offset addressing mode.
#define SBC_immediate(processor, data)
Procedure that perform a substract with the carry flag (A,Z,C,N=A-data-C) with an immediate.
#define BRANCH_Equal(processor, offset)
Procedure that performs a BEQ (branch if positive, if the N flag is clear)
#define TR_SP_X(processor)
Procedure that store the stack pointer in the X register.
#define LD_indexed_indirect_ACC(processor, addr, offset)
Procedure that loads to the accumulator using Indexed Indirect.
#define LD_offset_ACC(processor, addr, offset)
Procedure that loads a value from memory at address addr+offset to the X register.
#define RETURN_Interrupt(processor)
Procedure that performs a return from interrupt (RTI instruction) by pulling the flags from the top o...
#define LD_absolute_ACC(processor, addr)
Procedure that loads a value from memory at the address addr to the accumulator.
#define indirect_indexed(cpu, addr, offset)
Macro to access memory by indirect indexed addressing mode.
#define CLEAR_ALL_FLAGS(x)
#define XOR_offset(processor, addr, offset)
Procedure that performs a bitwise logic XOR (A,Z,N = A&M) using offset addressing mode.
#define PUSH_PC(processor)
Procedure that push the program_counter to the top of the stack.
#define AND_offset(processor, addr, offset)
Procedure that performs a bitwise logic AND (A,Z,N = A&M) using offset addressing mode.
#define TR_X_ACC(processor)
Procedure that store the value in the X register in the accumulator.
#define indexed_indirect(cpu, addr, offset)
Macro to access memory by indexed indirect addressing mode.
#define SHIFT_RIGHT_ACC(processor)
Procedure that performs a bitshift to the right (LSR operation) on the accumulator and place the 0th ...
#define OR_indirect_indexed(processor, addr, offset)
Procedure that perform a OR with the carry flag (A,Z,C,N=A+M+C) with indirect indexed.
#define XOR_indirect_indexed(processor, addr, offset)
Procedure that perform a XOR with the carry flag (A,Z,C,N=A+M+C) with indirect indexed.
#define ROTATION_LEFT_offset(processor, addr, offset)
Procedure that performs a bit shift with rotation to the left (ROL operation) at the memory address (...
#define TR_Y_ACC(processor)
Procedure that store the value in the Y register in the accumulator.
#define SBC_indirect_indexed(processor, addr, offset)
Procedure that perform a SBC with the carry flag (A,Z,C,N=A-M-C) with indirect indexed addressing mod...
#define JUMP_Subroutine(processor, addr)
Procedure that performs a Jump to a subroutine (JSR instruction) located at the address addr.
#define SHIFT_RIGHT_offset(processor, addr, offset)
Procedure that performs a bitshift to the right (LSR operation) at the address (addr + offset) and pl...
#define LD_immediate_Y(processor, d)
Procedure that loads an immediate (const value) in the Y register.
#define JUMP_indirect(processor, addr)
Procedure that sets the program counter to a certain indirect address (JMP instruction)
#define INC_X(processor)
Procedure that increments the X register.
#define BRANCH_Overflow_S(processor, offset)
Procedure that performs a BVS (branch if positive, if the N flag is clear)
#define BRANCH_Overflow_C(processor, offset)
Procedure that performs a BVC (branch if overflow clear, if the V flag is clear)
#define ROTATION_LEFT_absolute(processor, addr)
Procedure that performs a bit shift with rotation to the left (ROL operation) at the memory address a...
#define PUSH_FLAGS(processor)
Procedure that push the processor flags to the top of the stack.
#define LD_offset_X(processor, addr, offset)
Procedure that loads a value from memory at address addr+offset to the X register.
#define AND_immediate(processor, data)
Procedure that performs a bitwise logic AND (A,Z,N = A & data)
#define BRANCH_Carry_C(processor, offset)
Procedure that performs a BCC (if the C flag is clear)
void free_cpu(CPU *cpu)
Procedure that free the memory used by the CPU and the memory array.
#define STR_absolute_Y(processor, addr)
Procedure that store the Y register value to a memory address.
#define ROTATION_LEFT_ACC(processor)
Procedure that performs a bit shift with rotation to the left (ROL operation) on the accumulator....
#define SHIFT_LEFT_offset(processor, addr, offset)
Procedure that performs a bitshift to the left (ASL operation) at the address (addr + offset) and pla...
#define STR_indexed_indirect_ACC(processor, addr, offset)
Procedure that store the accumulator value to a memory address using indexes indirect addressing mode...
#define LD_offset_Y(processor, addr, offset)
Procedure that loads a value from memory at address addr+offset to the Y register.
void reset_memory(memory mem)
This procedure set the entire memory to 0.
memory init_memory()
This function allocate on the heap a memory of exactly TOTAL_MEMORY_SIZE.
void free_rom(rom *r)
Frees the rom struct.
void display_rom(rom *r)
Procedure that displays the content of the rom in hexadecimal.
rom * open_rom(char *filepath)
A function that open the NES rom at a specified path.
This structure will be used to represent the state of the Central Processing Unit (CPU) of our emulat...
data accumulator
A 8 bit register used to perform operations.
data register_y
A 8 bit register. Commonly used to hold offset and counters.
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.
byte data
Definition of the data format used by the CPU.
void print_stack_expected(memory stack, data start)
Procedure that display the expected state of the stack.
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 print_stack_state(CPU *cpu)
Procedure that display the current state of the stack.