1use crate::CodeGen;
7
8impl CodeGen {
9 pub fn ld_a(&mut self, n: u8) {
13 self.emit(&[0x3E, n]);
14 }
15
16 pub fn ld_b(&mut self, n: u8) {
18 self.emit(&[0x06, n]);
19 }
20
21 pub fn ld_c(&mut self, n: u8) {
23 self.emit(&[0x0E, n]);
24 }
25
26 pub fn ld_d(&mut self, n: u8) {
28 self.emit(&[0x16, n]);
29 }
30
31 pub fn ld_e(&mut self, n: u8) {
33 self.emit(&[0x1E, n]);
34 }
35
36 pub fn ld_h(&mut self, n: u8) {
38 self.emit(&[0x26, n]);
39 }
40
41 pub fn ld_l(&mut self, n: u8) {
43 self.emit(&[0x2E, n]);
44 }
45
46 pub fn ld_a_hl_ind(&mut self) {
48 self.emit(&[0x7E]);
49 }
50
51 pub fn ld_hl_ind_a(&mut self) {
53 self.emit(&[0x77]);
54 }
55
56 pub fn ld_a_b(&mut self) {
58 self.emit(&[0x78]);
59 }
60
61 pub fn ld_a_c(&mut self) {
63 self.emit(&[0x79]);
64 }
65
66 pub fn ld_a_d(&mut self) {
68 self.emit(&[0x7A]);
69 }
70
71 pub fn ld_a_e(&mut self) {
73 self.emit(&[0x7B]);
74 }
75
76 pub fn ld_b_a(&mut self) {
78 self.emit(&[0x47]);
79 }
80
81 pub fn ld_c_a(&mut self) {
83 self.emit(&[0x4F]);
84 }
85
86 pub fn ld_d_a(&mut self) {
88 self.emit(&[0x57]);
89 }
90
91 pub fn ld_e_a(&mut self) {
93 self.emit(&[0x5F]);
94 }
95
96 pub fn ld_a_addr(&mut self, addr: u16) {
98 self.emit(&[0x3A]);
99 self.emit_word(addr);
100 }
101
102 pub fn ld_addr_a(&mut self, addr: u16) {
104 self.emit(&[0x32]);
105 self.emit_word(addr);
106 }
107
108 pub fn ld_bc(&mut self, nn: u16) {
112 self.emit(&[0x01]);
113 self.emit_word(nn);
114 }
115
116 pub fn ld_de(&mut self, nn: u16) {
118 self.emit(&[0x11]);
119 self.emit_word(nn);
120 }
121
122 pub fn ld_hl(&mut self, nn: u16) {
124 self.emit(&[0x21]);
125 self.emit_word(nn);
126 }
127
128 pub fn ld_sp(&mut self, nn: u16) {
130 self.emit(&[0x31]);
131 self.emit_word(nn);
132 }
133
134 pub fn ld_hl_addr(&mut self, addr: u16) {
136 self.emit(&[0x2A]);
137 self.emit_word(addr);
138 }
139
140 pub fn ld_addr_hl(&mut self, addr: u16) {
142 self.emit(&[0x22]);
143 self.emit_word(addr);
144 }
145
146 pub fn ld_de_addr(&mut self, addr: u16) {
148 self.emit(&[0xED, 0x5B]);
149 self.emit_word(addr);
150 }
151
152 pub fn ld_addr_de(&mut self, addr: u16) {
154 self.emit(&[0xED, 0x53]);
155 self.emit_word(addr);
156 }
157
158 pub fn ld_sp_hl(&mut self) {
160 self.emit(&[0xF9]);
161 }
162
163 pub fn push_af(&mut self) {
167 self.emit(&[0xF5]);
168 }
169
170 pub fn push_bc(&mut self) {
172 self.emit(&[0xC5]);
173 }
174
175 pub fn push_de(&mut self) {
177 self.emit(&[0xD5]);
178 }
179
180 pub fn push_hl(&mut self) {
182 self.emit(&[0xE5]);
183 }
184
185 pub fn pop_af(&mut self) {
187 self.emit(&[0xF1]);
188 }
189
190 pub fn pop_bc(&mut self) {
192 self.emit(&[0xC1]);
193 }
194
195 pub fn pop_de(&mut self) {
197 self.emit(&[0xD1]);
198 }
199
200 pub fn pop_hl(&mut self) {
202 self.emit(&[0xE1]);
203 }
204
205 pub fn ex_de_hl(&mut self) {
209 self.emit(&[0xEB]);
210 }
211
212 pub fn ex_af(&mut self) {
214 self.emit(&[0x08]);
215 }
216
217 pub fn exx(&mut self) {
219 self.emit(&[0xD9]);
220 }
221
222 pub fn add_a(&mut self, n: u8) {
226 self.emit(&[0xC6, n]);
227 }
228
229 pub fn add_a_b(&mut self) {
231 self.emit(&[0x80]);
232 }
233
234 pub fn add_a_hl_ind(&mut self) {
236 self.emit(&[0x86]);
237 }
238
239 pub fn sub_a(&mut self, n: u8) {
241 self.emit(&[0xD6, n]);
242 }
243
244 pub fn sub_b(&mut self) {
246 self.emit(&[0x90]);
247 }
248
249 pub fn inc_a(&mut self) {
251 self.emit(&[0x3C]);
252 }
253
254 pub fn inc_b(&mut self) {
256 self.emit(&[0x04]);
257 }
258
259 pub fn inc_c(&mut self) {
261 self.emit(&[0x0C]);
262 }
263
264 pub fn dec_a(&mut self) {
266 self.emit(&[0x3D]);
267 }
268
269 pub fn dec_b(&mut self) {
271 self.emit(&[0x05]);
272 }
273
274 pub fn dec_c(&mut self) {
276 self.emit(&[0x0D]);
277 }
278
279 pub fn inc_hl(&mut self) {
283 self.emit(&[0x23]);
284 }
285
286 pub fn inc_de(&mut self) {
288 self.emit(&[0x13]);
289 }
290
291 pub fn inc_bc(&mut self) {
293 self.emit(&[0x03]);
294 }
295
296 pub fn dec_hl(&mut self) {
298 self.emit(&[0x2B]);
299 }
300
301 pub fn dec_de(&mut self) {
303 self.emit(&[0x1B]);
304 }
305
306 pub fn dec_bc(&mut self) {
308 self.emit(&[0x0B]);
309 }
310
311 pub fn add_hl_bc(&mut self) {
313 self.emit(&[0x09]);
314 }
315
316 pub fn add_hl_de(&mut self) {
318 self.emit(&[0x19]);
319 }
320
321 pub fn add_hl_hl(&mut self) {
323 self.emit(&[0x29]);
324 }
325
326 pub fn sbc_hl_de(&mut self) {
328 self.emit(&[0xED, 0x52]);
329 }
330
331 pub fn sbc_hl_bc(&mut self) {
333 self.emit(&[0xED, 0x42]);
334 }
335
336 pub fn and_a(&mut self, n: u8) {
340 self.emit(&[0xE6, n]);
341 }
342
343 pub fn or_a(&mut self, n: u8) {
345 self.emit(&[0xF6, n]);
346 }
347
348 pub fn or_a_a(&mut self) {
350 self.emit(&[0xB7]);
351 }
352
353 pub fn or_b(&mut self) {
355 self.emit(&[0xB0]);
356 }
357
358 pub fn or_l(&mut self) {
360 self.emit(&[0xB5]);
361 }
362
363 pub fn xor_a(&mut self) {
365 self.emit(&[0xAF]);
366 }
367
368 pub fn xor_n(&mut self, n: u8) {
370 self.emit(&[0xEE, n]);
371 }
372
373 pub fn cp(&mut self, n: u8) {
375 self.emit(&[0xFE, n]);
376 }
377
378 pub fn cp_b(&mut self) {
380 self.emit(&[0xB8]);
381 }
382
383 pub fn cp_hl_ind(&mut self) {
385 self.emit(&[0xBE]);
386 }
387
388 pub fn cpl(&mut self) {
390 self.emit(&[0x2F]);
391 }
392
393 pub fn jp(&mut self, label: &str) {
397 self.emit(&[0xC3]);
398 self.fixup(label);
399 }
400
401 pub fn jp_addr(&mut self, addr: u16) {
403 self.emit(&[0xC3]);
404 self.emit_word(addr);
405 }
406
407 pub fn jp_z(&mut self, label: &str) {
409 self.emit(&[0xCA]);
410 self.fixup(label);
411 }
412
413 pub fn jp_nz(&mut self, label: &str) {
415 self.emit(&[0xC2]);
416 self.fixup(label);
417 }
418
419 pub fn jp_c(&mut self, label: &str) {
421 self.emit(&[0xDA]);
422 self.fixup(label);
423 }
424
425 pub fn jp_nc(&mut self, label: &str) {
427 self.emit(&[0xD2]);
428 self.fixup(label);
429 }
430
431 pub fn jp_p(&mut self, label: &str) {
433 self.emit(&[0xF2]);
434 self.fixup(label);
435 }
436
437 pub fn jp_m(&mut self, label: &str) {
439 self.emit(&[0xFA]);
440 self.fixup(label);
441 }
442
443 pub fn jp_hl(&mut self) {
445 self.emit(&[0xE9]);
446 }
447
448 pub fn jr(&mut self, label: &str) {
450 self.emit(&[0x18]);
451 self.emit_relative(label);
452 }
453
454 pub fn jr_z(&mut self, label: &str) {
456 self.emit(&[0x28]);
457 self.emit_relative(label);
458 }
459
460 pub fn jr_nz(&mut self, label: &str) {
462 self.emit(&[0x20]);
463 self.emit_relative(label);
464 }
465
466 pub fn jr_c(&mut self, label: &str) {
468 self.emit(&[0x38]);
469 self.emit_relative(label);
470 }
471
472 pub fn jr_nc(&mut self, label: &str) {
474 self.emit(&[0x30]);
475 self.emit_relative(label);
476 }
477
478 pub fn djnz(&mut self, label: &str) {
480 self.emit(&[0x10]);
481 self.emit_relative(label);
482 }
483
484 pub fn call(&mut self, label: &str) {
488 self.emit(&[0xCD]);
489 self.fixup(label);
490 }
491
492 pub fn call_addr(&mut self, addr: u16) {
494 self.emit(&[0xCD]);
495 self.emit_word(addr);
496 }
497
498 pub fn call_z(&mut self, label: &str) {
500 self.emit(&[0xCC]);
501 self.fixup(label);
502 }
503
504 pub fn call_nz(&mut self, label: &str) {
506 self.emit(&[0xC4]);
507 self.fixup(label);
508 }
509
510 pub fn ret(&mut self) {
512 self.emit(&[0xC9]);
513 }
514
515 pub fn ret_z(&mut self) {
517 self.emit(&[0xC8]);
518 }
519
520 pub fn ret_nz(&mut self) {
522 self.emit(&[0xC0]);
523 }
524
525 pub fn ret_c(&mut self) {
527 self.emit(&[0xD8]);
528 }
529
530 pub fn ret_nc(&mut self) {
532 self.emit(&[0xD0]);
533 }
534
535 pub fn in_a(&mut self, port: u8) {
539 self.emit(&[0xDB, port]);
540 }
541
542 pub fn out_a(&mut self, port: u8) {
544 self.emit(&[0xD3, port]);
545 }
546
547 pub fn nop(&mut self) {
551 self.emit(&[0x00]);
552 }
553
554 pub fn halt(&mut self) {
556 self.emit(&[0x76]);
557 }
558
559 pub fn di(&mut self) {
561 self.emit(&[0xF3]);
562 }
563
564 pub fn ei(&mut self) {
566 self.emit(&[0xFB]);
567 }
568
569 pub fn scf(&mut self) {
571 self.emit(&[0x37]);
572 }
573
574 pub fn ccf(&mut self) {
576 self.emit(&[0x3F]);
577 }
578
579 pub fn bit_a(&mut self, bit: u8) {
583 self.emit(&[0xCB, 0x47 | (bit << 3)]);
584 }
585
586 pub fn set_a(&mut self, bit: u8) {
588 self.emit(&[0xCB, 0xC7 | (bit << 3)]);
589 }
590
591 pub fn res_a(&mut self, bit: u8) {
593 self.emit(&[0xCB, 0x87 | (bit << 3)]);
594 }
595
596 pub fn rla(&mut self) {
598 self.emit(&[0x17]);
599 }
600
601 pub fn rra(&mut self) {
603 self.emit(&[0x1F]);
604 }
605
606 pub fn rlca(&mut self) {
608 self.emit(&[0x07]);
609 }
610
611 pub fn rrca(&mut self) {
613 self.emit(&[0x0F]);
614 }
615
616 pub fn sla_a(&mut self) {
618 self.emit(&[0xCB, 0x27]);
619 }
620
621 pub fn sra_a(&mut self) {
623 self.emit(&[0xCB, 0x2F]);
624 }
625
626 pub fn srl_a(&mut self) {
628 self.emit(&[0xCB, 0x3F]);
629 }
630}
631
632#[cfg(test)]
633mod tests {
634 use super::*;
635
636 #[test]
637 fn test_ld_a() {
638 let mut cg = CodeGen::new();
639 cg.ld_a(0x42);
640 assert_eq!(cg.rom(), &[0x3E, 0x42]);
641 }
642
643 #[test]
644 fn test_ld_hl() {
645 let mut cg = CodeGen::new();
646 cg.ld_hl(0x1234);
647 assert_eq!(cg.rom(), &[0x21, 0x34, 0x12]);
648 }
649
650 #[test]
651 fn test_call_and_ret() {
652 let mut cg = CodeGen::new();
653 cg.label("start");
654 cg.call("func");
655 cg.halt();
656 cg.label("func");
657 cg.ret();
658 cg.resolve_fixups();
659
660 assert_eq!(cg.rom()[0], 0xCD);
662 assert_eq!(cg.rom()[1], 0x04);
663 assert_eq!(cg.rom()[2], 0x00);
664 }
665
666 #[test]
667 fn test_8bit_loads() {
668 let mut cg = CodeGen::new();
669 cg.ld_b(0x10);
670 cg.ld_c(0x20);
671 cg.ld_d(0x30);
672 cg.ld_e(0x40);
673 assert_eq!(cg.rom(), &[0x06, 0x10, 0x0E, 0x20, 0x16, 0x30, 0x1E, 0x40]);
674 }
675
676 #[test]
677 fn test_16bit_loads() {
678 let mut cg = CodeGen::new();
679 cg.ld_bc(0x1234);
680 cg.ld_de(0x5678);
681 cg.ld_sp(0x3FFF);
682 assert_eq!(cg.rom(), &[
683 0x01, 0x34, 0x12, 0x11, 0x78, 0x56, 0x31, 0xFF, 0x3F, ]);
687 }
688
689 #[test]
690 fn test_register_transfers() {
691 let mut cg = CodeGen::new();
692 cg.ld_a_b();
693 cg.ld_a_c();
694 cg.ld_b_a();
695 cg.ld_c_a();
696 assert_eq!(cg.rom(), &[0x78, 0x79, 0x47, 0x4F]);
697 }
698
699 #[test]
700 fn test_memory_access() {
701 let mut cg = CodeGen::new();
702 cg.ld_a_hl_ind();
703 cg.ld_hl_ind_a();
704 cg.ld_a_addr(0x3000);
705 cg.ld_addr_a(0x3000);
706 assert_eq!(cg.rom(), &[
707 0x7E, 0x77, 0x3A, 0x00, 0x30, 0x32, 0x00, 0x30, ]);
712 }
713
714 #[test]
715 fn test_stack_operations() {
716 let mut cg = CodeGen::new();
717 cg.push_af();
718 cg.push_bc();
719 cg.push_de();
720 cg.push_hl();
721 cg.pop_hl();
722 cg.pop_de();
723 cg.pop_bc();
724 cg.pop_af();
725 assert_eq!(cg.rom(), &[0xF5, 0xC5, 0xD5, 0xE5, 0xE1, 0xD1, 0xC1, 0xF1]);
726 }
727
728 #[test]
729 fn test_arithmetic() {
730 let mut cg = CodeGen::new();
731 cg.add_a(5);
732 cg.sub_a(3);
733 cg.inc_a();
734 cg.dec_a();
735 cg.inc_hl();
736 cg.dec_de();
737 assert_eq!(cg.rom(), &[
738 0xC6, 0x05, 0xD6, 0x03, 0x3C, 0x3D, 0x23, 0x1B, ]);
745 }
746
747 #[test]
748 fn test_16bit_arithmetic() {
749 let mut cg = CodeGen::new();
750 cg.add_hl_bc();
751 cg.add_hl_de();
752 cg.add_hl_hl();
753 cg.sbc_hl_de();
754 assert_eq!(cg.rom(), &[
755 0x09, 0x19, 0x29, 0xED, 0x52, ]);
760 }
761
762 #[test]
763 fn test_logic() {
764 let mut cg = CodeGen::new();
765 cg.and_a(0x0F);
766 cg.or_a(0xF0);
767 cg.xor_a();
768 cg.cp(0x0D);
769 cg.cpl();
770 assert_eq!(cg.rom(), &[
771 0xE6, 0x0F, 0xF6, 0xF0, 0xAF, 0xFE, 0x0D, 0x2F, ]);
777 }
778
779 #[test]
780 fn test_jumps() {
781 let mut cg = CodeGen::new();
782 cg.label("target");
783 cg.nop();
784 cg.jp("target");
785 cg.jp_z("target");
786 cg.jp_nz("target");
787 cg.jp_c("target");
788 cg.jp_nc("target");
789 cg.resolve_fixups();
790
791 assert_eq!(cg.rom()[0], 0x00); assert_eq!(cg.rom()[1], 0xC3); assert_eq!(cg.rom()[4], 0xCA); assert_eq!(cg.rom()[7], 0xC2); assert_eq!(cg.rom()[10], 0xDA); assert_eq!(cg.rom()[13], 0xD2); }
798
799 #[test]
800 fn test_relative_jumps() {
801 let mut cg = CodeGen::new();
802 cg.label("loop");
803 cg.nop();
804 cg.nop();
805 cg.jr("loop");
806
807 assert_eq!(cg.rom(), &[0x00, 0x00, 0x18, 0xFC]); }
810
811 #[test]
812 fn test_djnz() {
813 let mut cg = CodeGen::new();
814 cg.ld_b(10);
815 cg.label("loop");
816 cg.dec_a();
817 cg.djnz("loop");
818
819 assert_eq!(cg.rom(), &[
820 0x06, 0x0A, 0x3D, 0x10, 0xFD, ]);
824 }
825
826 #[test]
827 fn test_io() {
828 let mut cg = CodeGen::new();
829 cg.in_a(0x80);
830 cg.out_a(0x81);
831 assert_eq!(cg.rom(), &[0xDB, 0x80, 0xD3, 0x81]);
832 }
833
834 #[test]
835 fn test_misc() {
836 let mut cg = CodeGen::new();
837 cg.nop();
838 cg.halt();
839 cg.di();
840 cg.ei();
841 cg.ex_de_hl();
842 assert_eq!(cg.rom(), &[0x00, 0x76, 0xF3, 0xFB, 0xEB]);
843 }
844
845 #[test]
846 fn test_conditional_returns() {
847 let mut cg = CodeGen::new();
848 cg.ret();
849 cg.ret_z();
850 cg.ret_nz();
851 cg.ret_c();
852 cg.ret_nc();
853 assert_eq!(cg.rom(), &[0xC9, 0xC8, 0xC0, 0xD8, 0xD0]);
854 }
855
856 #[test]
857 fn test_bit_operations() {
858 let mut cg = CodeGen::new();
859 cg.bit_a(0);
860 cg.bit_a(7);
861 cg.set_a(3);
862 cg.res_a(5);
863 assert_eq!(cg.rom(), &[
864 0xCB, 0x47, 0xCB, 0x7F, 0xCB, 0xDF, 0xCB, 0xAF, ]);
869 }
870
871 #[test]
872 fn test_rotates() {
873 let mut cg = CodeGen::new();
874 cg.rla();
875 cg.rra();
876 cg.rlca();
877 cg.rrca();
878 assert_eq!(cg.rom(), &[0x17, 0x1F, 0x07, 0x0F]);
879 }
880}