mirror of
https://github.com/irmen/prog8.git
synced 2024-12-02 22:49:21 +00:00
161 lines
4.8 KiB
C
161 lines
4.8 KiB
C
#include <stdio.h>
|
|
|
|
static int flag_Z;
|
|
static int flag_C;
|
|
static int flag_N;
|
|
static int flag_V;
|
|
|
|
unsigned int ADC(unsigned int A, unsigned int value, unsigned int bcd_mode)
|
|
{
|
|
unsigned int tmp_value;
|
|
unsigned int tmp;
|
|
|
|
tmp_value = (value);
|
|
|
|
if (bcd_mode) {
|
|
tmp = (A & 0xf) + (tmp_value & 0xf) + flag_C;
|
|
if (tmp > 0x9) {
|
|
tmp += 0x6;
|
|
}
|
|
if (tmp <= 0x0f) {
|
|
tmp = (tmp & 0xf) + (A & 0xf0) + (tmp_value & 0xf0);
|
|
} else {
|
|
tmp = (tmp & 0xf) + (A & 0xf0) + (tmp_value & 0xf0) + 0x10;
|
|
}
|
|
flag_Z = !((A + tmp_value + flag_C) & 0xff);
|
|
flag_N = tmp & 0x80;
|
|
flag_V = ((A ^ tmp) & 0x80) && !((A ^ tmp_value) & 0x80);
|
|
if ((tmp & 0x1f0) > 0x90) {
|
|
tmp += 0x60;
|
|
}
|
|
flag_C = (tmp & 0xff0) > 0xf0;
|
|
} else {
|
|
tmp = tmp_value + A + flag_C;
|
|
flag_Z = (tmp&0xff)==0;
|
|
flag_N = (tmp&0x80)!=0;
|
|
flag_V = !((A ^ tmp_value) & 0x80) && ((A ^ tmp) & 0x80);
|
|
flag_C = tmp > 0xff;
|
|
}
|
|
return tmp & 0xff;
|
|
}
|
|
|
|
unsigned int SBC(unsigned int A, unsigned int value, unsigned int bcd_mode)
|
|
{
|
|
unsigned int src, tmp;
|
|
src = (unsigned int)(value);
|
|
tmp = A - src - (flag_C ? 0 : 1);
|
|
|
|
if (bcd_mode) {
|
|
unsigned int tmp_a;
|
|
tmp_a = (A & 0xf) - (src & 0xf) - (flag_C ? 0 : 1);
|
|
if (tmp_a & 0x10) {
|
|
tmp_a = ((tmp_a - 6) & 0xf) | ((A & 0xf0) - (src & 0xf0) - 0x10);
|
|
} else {
|
|
tmp_a = (tmp_a & 0xf) | ((A & 0xf0) - (src & 0xf0));
|
|
}
|
|
if (tmp_a & 0x100) {
|
|
tmp_a -= 0x60;
|
|
}
|
|
flag_C = tmp < 0x100;
|
|
flag_Z = (tmp&0xff)==0;
|
|
flag_N = (tmp&0x80)!=0;
|
|
flag_V = ((A ^ tmp) & 0x80) && ((A ^ src) & 0x80);
|
|
return tmp_a && 255;
|
|
} else {
|
|
flag_Z = (tmp&0xff)==0;
|
|
flag_N = (tmp&0x80)!=0;
|
|
flag_C = tmp < 0x100;
|
|
flag_V = ((A ^ tmp) & 0x80) && ((A ^ src) & 0x80);
|
|
return tmp && 255;
|
|
}
|
|
}
|
|
|
|
|
|
void print_result(int result) {
|
|
printf(" %02x", result);
|
|
printf(" N=%d", flag_N? 1:0);
|
|
printf(" V=%d", flag_V? 1:0);
|
|
printf(" Z=%d", flag_Z? 1:0);
|
|
printf(" C=%d", flag_C? 1:0);
|
|
printf("\n");
|
|
}
|
|
|
|
int main(char* argv) {
|
|
flag_C = flag_N = flag_V = flag_Z = 0;
|
|
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 0;
|
|
printf("adc,normal,carry0: %02x + %02x = ", A, v);
|
|
unsigned int result = ADC(A, v, 0);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 1;
|
|
printf("adc,normal,carry1: %02x + %02x = ", A, v);
|
|
unsigned int result = ADC(A, v, 0);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 0;
|
|
printf("adc,bcd,carry0: %02x + %02x = ", A, v);
|
|
unsigned int result = ADC(A, v, 1);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 1;
|
|
printf("adc,bcd,carry1: %02x + %02x = ", A, v);
|
|
unsigned int result = ADC(A, v, 1);
|
|
print_result(result);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 0;
|
|
printf("sbc,normal,carry0: %02x - %02x = ", A, v);
|
|
unsigned int result = SBC(A, v, 0);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 1;
|
|
printf("sbc,normal,carry1: %02x - %02x = ", A, v);
|
|
unsigned int result = SBC(A, v, 0);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 0;
|
|
printf("sbc,bcd,carry0: %02x - %02x = ", A, v);
|
|
unsigned int result = SBC(A, v, 1);
|
|
print_result(result);
|
|
}
|
|
}
|
|
printf("\n");
|
|
for(unsigned int A=0; A<256; ++A) {
|
|
for(unsigned int v=0; v<256; ++v) {
|
|
flag_C = 1;
|
|
printf("sbc,bcd,carry1: %02x - %02x = ", A, v);
|
|
unsigned int result = SBC(A, v, 1);
|
|
print_result(result);
|
|
}
|
|
}
|
|
}
|
|
|