Skip to content

Commit 0b5a6e6

Browse files
committed
Fix all rotate-related instruction
1 parent e723804 commit 0b5a6e6

File tree

3 files changed

+294
-4
lines changed

3 files changed

+294
-4
lines changed

src/emit.dasc

+286
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,75 @@ static bool inst_rr(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
792792
{
793793
| print "RR"
794794
| mov byte state->f_subtract, 0
795+
| pushfq
796+
797+
switch(inst->op1) {
798+
case REG_A:
799+
| mov tmp3, xA
800+
break;
801+
case REG_B:
802+
| mov tmp3, xB
803+
break;
804+
case REG_C:
805+
| mov tmp3, xC
806+
break;
807+
case REG_D:
808+
| mov tmp3, xD
809+
break;
810+
case REG_E:
811+
| mov tmp3, xE
812+
break;
813+
case REG_H:
814+
| mov tmp3, xH
815+
break;
816+
case REG_L:
817+
| mov tmp3, xL
818+
break;
819+
case MEM_HL:
820+
| and xL, 0xff
821+
| and xH, 0xff
822+
| mov tmp2, xH
823+
| shl tmp2, 8
824+
| mov tmp1, xL
825+
| add tmp1, tmp2
826+
| mov tmp3b, [aMem + tmp1]
827+
break;
828+
default:
829+
LOG_ERROR("Invalid operand.\n");
830+
return false;
831+
}
832+
| popfq
833+
| rcr tmp3b, 1
834+
| pushfq
835+
/* warning: macro inst2 will use tmp1 and tmp2!
836+
* that's why we use tmp3 to save the value
837+
*/
838+
| inst2, mov, inst->op1, tmp3b
839+
840+
| pop tmp1
841+
/* clean Z/H flag to zero */
842+
| and tmp1, ~0x50
843+
| cmp tmp3b, 0
844+
| jne >1
845+
/* set Z flag to one */
846+
| or tmp1, 0x40
847+
| 1:
848+
| push tmp1
849+
| popfq
850+
851+
*cycles += inst->cycles;
852+
return true;
853+
}
854+
855+
static bool inst_rra(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
856+
{
857+
| print "RRA"
858+
| mov byte state->f_subtract, 0
795859
| inst2, rcr, inst->op1, 1
860+
861+
/* set zero and half-carry flag to zero */
862+
| clean_flag 0x50
863+
796864
*cycles += inst->cycles;
797865
return true;
798866
}
@@ -801,7 +869,75 @@ static bool inst_rl(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
801869
{
802870
| print "RL"
803871
| mov byte state->f_subtract, 0
872+
| pushfq
873+
874+
switch(inst->op1) {
875+
case REG_A:
876+
| mov tmp3, xA
877+
break;
878+
case REG_B:
879+
| mov tmp3, xB
880+
break;
881+
case REG_C:
882+
| mov tmp3, xC
883+
break;
884+
case REG_D:
885+
| mov tmp3, xD
886+
break;
887+
case REG_E:
888+
| mov tmp3, xE
889+
break;
890+
case REG_H:
891+
| mov tmp3, xH
892+
break;
893+
case REG_L:
894+
| mov tmp3, xL
895+
break;
896+
case MEM_HL:
897+
| and xL, 0xff
898+
| and xH, 0xff
899+
| mov tmp2, xH
900+
| shl tmp2, 8
901+
| mov tmp1, xL
902+
| add tmp1, tmp2
903+
| mov tmp3b, [aMem + tmp1]
904+
break;
905+
default:
906+
LOG_ERROR("Invalid operand.\n");
907+
return false;
908+
}
909+
| popfq
910+
| rcl tmp3b, 1
911+
| pushfq
912+
/* warning: macro inst2 will use tmp1 and tmp2!
913+
* that's why we use tmp3 to save the value
914+
*/
915+
| inst2, mov, inst->op1, tmp3b
916+
917+
| pop tmp1
918+
/* clean Z/H flag to zero */
919+
| and tmp1, ~0x50
920+
| cmp tmp3b, 0
921+
| jne >1
922+
/* set Z flag to one */
923+
| or tmp1, 0x40
924+
| 1:
925+
| push tmp1
926+
| popfq
927+
928+
*cycles += inst->cycles;
929+
return true;
930+
}
931+
932+
static bool inst_rla(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
933+
{
934+
| print "RLA"
935+
| mov byte state->f_subtract, 0
804936
| inst2, rcl, inst->op1, 1
937+
938+
/* set zero and half-carry flag to zero */
939+
| clean_flag 0x50
940+
805941
*cycles += inst->cycles;
806942
return true;
807943
}
@@ -810,7 +946,74 @@ static bool inst_rrc(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
810946
{
811947
| print "RRC"
812948
| mov byte state->f_subtract, 0
949+
950+
switch(inst->op1) {
951+
case REG_A:
952+
| mov tmp3, xA
953+
break;
954+
case REG_B:
955+
| mov tmp3, xB
956+
break;
957+
case REG_C:
958+
| mov tmp3, xC
959+
break;
960+
case REG_D:
961+
| mov tmp3, xD
962+
break;
963+
case REG_E:
964+
| mov tmp3, xE
965+
break;
966+
case REG_H:
967+
| mov tmp3, xH
968+
break;
969+
case REG_L:
970+
| mov tmp3, xL
971+
break;
972+
case MEM_HL:
973+
| and xL, 0xff
974+
| and xH, 0xff
975+
| mov tmp2, xH
976+
| shl tmp2, 8
977+
| mov tmp1, xL
978+
| add tmp1, tmp2
979+
| mov tmp3b, [aMem + tmp1]
980+
break;
981+
default:
982+
LOG_ERROR("Invalid operand.\n");
983+
return false;
984+
}
985+
986+
| ror tmp3b, 1
987+
| pushfq
988+
/* warning: macro inst2 will use tmp1 and tmp2!
989+
* that's why we use tmp3 to save the value
990+
*/
991+
| inst2, mov, inst->op1, tmp3b
992+
993+
| pop tmp1
994+
/* clean Z/H flag to zero */
995+
| and tmp1, ~0x50
996+
| cmp tmp3b, 0
997+
| jne >1
998+
/* set Z flag to one */
999+
| or tmp1, 0x40
1000+
| 1:
1001+
| push tmp1
1002+
| popfq
1003+
1004+
*cycles += inst->cycles;
1005+
return true;
1006+
}
1007+
1008+
static bool inst_rrca(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
1009+
{
1010+
| print "RRCA"
1011+
| mov byte state->f_subtract, 0
8131012
| inst2, ror, inst->op1, 1
1013+
1014+
/* set zero and half-carry flag to zero */
1015+
| clean_flag 0x50
1016+
8141017
*cycles += inst->cycles;
8151018
return true;
8161019
}
@@ -819,7 +1022,74 @@ static bool inst_rlc(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
8191022
{
8201023
| print "RLC"
8211024
| mov byte state->f_subtract, 0
1025+
1026+
switch(inst->op1) {
1027+
case REG_A:
1028+
| mov tmp3, xA
1029+
break;
1030+
case REG_B:
1031+
| mov tmp3, xB
1032+
break;
1033+
case REG_C:
1034+
| mov tmp3, xC
1035+
break;
1036+
case REG_D:
1037+
| mov tmp3, xD
1038+
break;
1039+
case REG_E:
1040+
| mov tmp3, xE
1041+
break;
1042+
case REG_H:
1043+
| mov tmp3, xH
1044+
break;
1045+
case REG_L:
1046+
| mov tmp3, xL
1047+
break;
1048+
case MEM_HL:
1049+
| and xL, 0xff
1050+
| and xH, 0xff
1051+
| mov tmp2, xH
1052+
| shl tmp2, 8
1053+
| mov tmp1, xL
1054+
| add tmp1, tmp2
1055+
| mov tmp3b, [aMem + tmp1]
1056+
break;
1057+
default:
1058+
LOG_ERROR("Invalid operand.\n");
1059+
return false;
1060+
}
1061+
1062+
| rol tmp3b, 1
1063+
| pushfq
1064+
/* warning: macro inst2 will use tmp1 and tmp2!
1065+
* that's why we use tmp3 to save the value
1066+
*/
1067+
| inst2, mov, inst->op1, tmp3b
1068+
1069+
| pop tmp1
1070+
/* clean Z/H flag to zero */
1071+
| and tmp1, ~0x50
1072+
| cmp tmp3b, 0
1073+
| jne >1
1074+
/* set Z flag to one */
1075+
| or tmp1, 0x40
1076+
| 1:
1077+
| push tmp1
1078+
| popfq
1079+
1080+
*cycles += inst->cycles;
1081+
return true;
1082+
}
1083+
1084+
static bool inst_rlca(dasm_State **Dst, gbz80_inst *inst, uint64_t *cycles)
1085+
{
1086+
| print "RLCA"
1087+
| mov byte state->f_subtract, 0
8221088
| inst2, rol, inst->op1, 1
1089+
1090+
/* set zero and half-carry flag to zero */
1091+
| clean_flag 0x50
1092+
8231093
*cycles += inst->cycles;
8241094
return true;
8251095
}
@@ -1222,18 +1492,34 @@ bool emit(gb_block *block, GList *inst)
12221492
if (!inst_rr(Dst, DATA(inst), &cycles))
12231493
goto exit_fail;
12241494
break;
1495+
case RRA:
1496+
if (!inst_rra(Dst, DATA(inst), &cycles))
1497+
goto exit_fail;
1498+
break;
12251499
case RL:
12261500
if (!inst_rl(Dst, DATA(inst), &cycles))
12271501
goto exit_fail;
12281502
break;
1503+
case RLA:
1504+
if (!inst_rla(Dst, DATA(inst), &cycles))
1505+
goto exit_fail;
1506+
break;
12291507
case RRC:
12301508
if(!inst_rrc(Dst, DATA(inst), &cycles))
12311509
goto exit_fail;
12321510
break;
1511+
case RRCA:
1512+
if(!inst_rrca(Dst, DATA(inst), &cycles))
1513+
goto exit_fail;
1514+
break;
12331515
case RLC:
12341516
if (!inst_rlc(Dst, DATA(inst), &cycles))
12351517
goto exit_fail;
12361518
break;
1519+
case RLCA:
1520+
if (!inst_rlca(Dst, DATA(inst), &cycles))
1521+
goto exit_fail;
1522+
break;
12371523
case SBC:
12381524
if (!inst_sbc(Dst, DATA(inst), &cycles))
12391525
goto exit_fail;

src/emit.h

+4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ typedef struct {
2121
DEC16,
2222
DEC,
2323
RLC,
24+
RLCA,
2425
ADD16,
2526
ADD,
2627
RRC,
28+
RRCA,
2729
STOP,
2830
RL,
31+
RLA,
2932
JR,
3033
RR,
34+
RRA,
3135
DAA,
3236
CPL,
3337
SCF,

src/gbz80.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,31 @@ static gbz80_inst inst_table[] = {
1212
[0x04] = {INC, REG_B, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
1313
[0x05] = {DEC, REG_B, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
1414
[0x06] = {LD, REG_B, IMM8, 0, 0, 2, 2, 2, 0},
15-
[0x07] = {RLC, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_AFFECTS_CC},
15+
[0x07] = {RLCA, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_AFFECTS_CC},
1616
[0x08] = {LD16, MEM_16, REG_SP, 0, 0, 3, 5, 5, 0},
1717
[0x09] = {ADD16, REG_HL, REG_BC, 0, 0, 1, 2, 2, INST_FLAG_AFFECTS_CC},
1818
[0x0a] = {LD, REG_A, MEM_BC, 0, 0, 1, 2, 2, 0},
1919
[0x0b] = {DEC16, REG_BC, NONE, 0, 0, 1, 2, 2, 0},
2020
[0x0c] = {INC, REG_C, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
2121
[0x0d] = {DEC, REG_C, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
2222
[0x0e] = {LD, REG_C, IMM8, 0, 0, 2, 2, 2, 0},
23-
[0x0f] = {RRC, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_AFFECTS_CC},
23+
[0x0f] = {RRCA, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_AFFECTS_CC},
2424
[0x10] = {STOP, NONE, NONE, 0, 0, 2, 1, 1, INST_FLAG_ENDS_BLOCK},
2525
[0x11] = {LD16, REG_DE, IMM16, 0, 0, 3, 3, 3, 0},
2626
[0x12] = {LD, MEM_DE, REG_A, 0, 0, 1, 2, 2, 0},
2727
[0x13] = {INC16, REG_DE, NONE, 0, 0, 1, 2, 2, 0},
2828
[0x14] = {INC, REG_D, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
2929
[0x15] = {DEC, REG_D, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
3030
[0x16] = {LD, REG_D, IMM8, 0, 0, 2, 2, 2, 0},
31-
[0x17] = {RL, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
31+
[0x17] = {RLA, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
3232
[0x18] = {JR, NONE, IMM8, 0, 0, 2, 3, 3, INST_FLAG_ENDS_BLOCK},
3333
[0x19] = {ADD16, REG_HL, REG_DE, 0, 0, 1, 2, 2, INST_FLAG_AFFECTS_CC},
3434
[0x1a] = {LD, REG_A, MEM_DE, 0, 0, 1, 2, 2, 0},
3535
[0x1b] = {DEC16, REG_DE, NONE, 0, 0, 1, 2, 2, 0},
3636
[0x1c] = {INC, REG_E, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
3737
[0x1d] = {DEC, REG_E, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
3838
[0x1e] = {LD, REG_E, IMM8, 0, 0, 2, 2, 2, 0},
39-
[0x1f] = {RR, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
39+
[0x1f] = {RRA, REG_A, NONE, 0, 0, 1, 1, 1, INST_FLAG_USES_CC|INST_FLAG_AFFECTS_CC},
4040
[0x20] = {JR, CC_NZ, IMM8, 0, 0, 2, 3, 2, INST_FLAG_USES_CC},
4141
[0x21] = {LD16, REG_HL, IMM16, 0, 0, 3, 3, 3, 0},
4242
[0x22] = {LD, MEM_INC_HL, REG_A, 0,0, 1, 2, 2, 0},

0 commit comments

Comments
 (0)