Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# 変更履歴

## 2.3.2 (2026-07-30)

* シフト命令およびローテート命令でソースオペランドに負の値を持つデータレジスタを
指定すると結果が正しくない不具合を修正(エンバグ)。


## 2.3.1 (2026-02-11)

* `ADD.L Dn,<ea>`命令で`CCR`レジスタの変化が正しくない不具合を修正。
Expand Down
137 changes: 21 additions & 116 deletions src/line_e.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// run68x - Human68k CUI Emulator based on run68
// Copyright (C) 2024 TcbnErik
// Copyright (C) 2026 TcbnErik
//
// This program is free software; you can redistribute it and /or modify
// it under the terms of the GNU General Public License as published by
Expand All @@ -20,6 +20,16 @@

#include "run68.h"

// シフト、ローテート命令のシフト回数を得る
static unsigned int getShiftCount(char code1, char code2) {
unsigned int n = (code1 >> 1) & 7; // シフト回数またはデータレジスタ番号

if ((code2 & 0x20) == 0) {
return (n == 0) ? 8 : n; // 即値 1~8
}
return (unsigned int)rd[n] % 64; // データレジスタによる指定 0~63
}

/*
 機能:asl命令を実行する
戻り値: true = 実行終了
Expand All @@ -32,7 +42,7 @@ static bool Asl(char code1, char code2) {
ULong src;
ULong flag;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -46,19 +56,10 @@ static bool Asl(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];
top = (src & mask);
flag = top;

#ifdef TRACE
printf("trace: asl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
CCR_V_OFF();
for (; cnt > 0; cnt--) {
Expand Down Expand Up @@ -126,10 +127,6 @@ static bool Asl2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最上位ビットを保存する */
msb = src & 0x8000;

Expand Down Expand Up @@ -178,7 +175,7 @@ static bool Asr(char code1, char code2) {
ULong src;
ULong flag;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -192,11 +189,6 @@ static bool Asr(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];
flag = (src & mask);
switch (size) {
Expand All @@ -208,10 +200,6 @@ static bool Asr(char code1, char code2) {
break;
}

#ifdef TRACE
printf("trace: asr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
for (; cnt > 0; cnt--) {
btm = (char)(src & 0x01);
Expand Down Expand Up @@ -278,10 +266,6 @@ static bool Asr2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最上位ビットを保存する */
msb = src & 0x8000;

Expand Down Expand Up @@ -326,7 +310,7 @@ static bool Lsl(char code1, char code2) {
ULong mask;
ULong src;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -340,17 +324,8 @@ static bool Lsl(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
for (; cnt > 0; cnt--) {
if ((src & mask) != 0) {
Expand Down Expand Up @@ -416,10 +391,6 @@ static bool Lsl2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最上位ビットを保存する */
msb = src & 0x8000;

Expand Down Expand Up @@ -458,7 +429,7 @@ static bool Lsr(char code1, char code2) {
ULong mask;
ULong src;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -472,11 +443,6 @@ static bool Lsr(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];
switch (size) {
case S_BYTE:
Expand All @@ -487,10 +453,6 @@ static bool Lsr(char code1, char code2) {
break;
}

#ifdef TRACE
printf("trace: lsr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
for (; cnt > 0; cnt--) {
if ((src & 0x01) != 0) {
Expand Down Expand Up @@ -554,10 +516,6 @@ static bool Lsr2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最下位ビットを保存する */
lsb = src & 0x1;

Expand Down Expand Up @@ -597,7 +555,7 @@ static bool Rol(char code1, char code2) {
ULong mask;
ULong src;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -611,17 +569,8 @@ static bool Rol(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];

#ifdef TRACE
printf("trace: rol.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
for (; cnt > 0; cnt--) {
top = (src & mask);
Expand Down Expand Up @@ -689,10 +638,6 @@ static bool Rol2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最上位ビットを保存する */
msb = src & 0x8000;

Expand Down Expand Up @@ -736,7 +681,7 @@ static bool Roxl(char code1, char code2) {
ULong mask;
ULong src;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -750,17 +695,8 @@ static bool Roxl(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];

#ifdef TRACE
printf("trace: roxl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

if (CCR_X_REF() != 0)
CCR_C_ON();
else
Expand Down Expand Up @@ -831,10 +767,6 @@ static bool Roxl2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsl.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最上位ビットを保存する */
msb = src & 0x8000;

Expand Down Expand Up @@ -884,7 +816,7 @@ static bool Ror(char code1, char code2) {
ULong mask;
ULong src;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -898,11 +830,6 @@ static bool Ror(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];
switch (size) {
case S_BYTE:
Expand All @@ -913,10 +840,6 @@ static bool Ror(char code1, char code2) {
break;
}

#ifdef TRACE
printf("trace: ror.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

CCR_C_OFF();
for (; cnt > 0; cnt--) {
btm = (char)(src & 0x01);
Expand Down Expand Up @@ -982,10 +905,6 @@ static bool Ror2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最下位ビットを保存する */
lsb = src & 0x1;

Expand Down Expand Up @@ -1028,9 +947,8 @@ static bool Roxr(char code1, char code2) {
char btm;
ULong mask;
ULong src;
int i;

int cnt = ((code1 & 0x0E) >> 1);
unsigned int cnt = getShiftCount(code1, code2);
size = ((code2 >> 6) & 0x03);
switch (size) {
case S_BYTE:
Expand All @@ -1044,11 +962,6 @@ static bool Roxr(char code1, char code2) {
break;
}
int reg = (code2 & 0x07);
if ((code2 & 0x20) != 0) {
cnt = rd[cnt] % 64;
} else {
if (cnt == 0) cnt = 8;
}
src = rd[reg];
switch (size) {
case S_BYTE:
Expand All @@ -1063,7 +976,7 @@ static bool Roxr(char code1, char code2) {
CCR_C_ON();
else
CCR_C_OFF();
for (i = 0; i < cnt; i++) {
for (; cnt > 0; cnt--) {
btm = (char)(src & 0x01);
src >>= 1;
if (CCR_X_REF() != 0) src |= mask;
Expand All @@ -1074,10 +987,6 @@ static bool Roxr(char code1, char code2) {
}
}

#ifdef TRACE
printf("trace: roxr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

switch (size) {
case S_BYTE:
rd[reg] = ((rd[reg] & 0xFFFFFF00) | src);
Expand Down Expand Up @@ -1131,10 +1040,6 @@ static bool Roxr2(char code2) {
return true;
}

#ifdef TRACE
printf("trace: lsr.%c src=%d PC=%06lX\n", size_char[size], cnt, pc);
#endif

/* シフト前の最下位ビットを保存する */
lsb = src & 0x1;

Expand Down Expand Up @@ -1178,7 +1083,7 @@ static bool Roxr2(char code2) {
戻り値: true = 実行終了
false = 実行継続
*/
bool linee(char *pc_ptr) {
bool linee(char* pc_ptr) {
char code1, code2;

code1 = *(pc_ptr++);
Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define RUN68X_VERSION "2.3.1"
#define RUN68X_VERSION "2.3.2"
Loading