dos33fsprogs/utils/gr-sim/dots/8086_emulator.c
Vince Weaver c05084c289 gr-sim: uppercase the 6502 emulated registers
probably broke something, but this also was a pain as was
often accidentally using the vars, especially X and Y
2023-12-29 13:47:18 -05:00

248 lines
2.8 KiB
C

#include <stdio.h>
#include <unistd.h>
#include "8086_emulator.h"
unsigned short stack[4096];
unsigned short ax,bx,cx,dx,si,di,bp,cs,ds,es,fs,sp;
int cf=0,of=0,zf=0,sf=0;
//int sp=0;
/* unsigned multiply */
void mul_16(unsigned short value) {
unsigned int result;
result=ax*value;
// printf("%x*%x=%x ",value,ax,result);
ax=result&0xffff;
dx=result>>16;
// printf("%x:%x x=%d y=%d\n",dx,ax,
// dx&0xff,(dx>>8)&0xff);
if (dx==0) {
of=0;
cf=0;
}
else {
of=1;
cf=1;
}
}
/*
static void imul(short value) {
int result;
result=ax*value;
ax=result&0xffff;
dx=result>>16;
}
*/
/* signed multiply */
void imul_8(char value) {
short result;
char src;
src=ax;
result=src*value;
// printf("imul: %d*%d=%d ",src,value,result);
ax=result;
if (ax==(ax&0xff)) {
cf=0;
of=0;
}
else {
cf=1;
of=1;
}
}
/* signed multiply */
/* DX:AX = AX * value */
void imul_16(short value) {
int result;
short src;
src=ax;
result=src*value;
// printf("imul: %d*%d=%d ",src,value,result);
ax=(result&0xffff);
dx=((result>>16)&0xffff);
if (dx==0) {
cf=0;
of=0;
}
else {
cf=1;
of=1;
}
}
/* signed multiply */
void imul_16_bx(short value) {
int result;
short src;
src=bx;
result=src*value;
// printf("imul: %d*%d=%d ",src,value,result);
bx=(result&0xffff);
if (bx==result) {
cf=0;
of=0;
}
else {
cf=1;
of=1;
}
}
/* signed multiply */
void imul_16_dx(short value) {
int result;
short src;
src=dx;
result=src*value;
// printf("imul: %d*%d=%d ",src,value,result);
dx=(result&0xffff);
if (dx==result) {
cf=0;
of=0;
}
else {
cf=1;
of=1;
}
}
/* unsigned divide */
void div_8(unsigned char value) {
unsigned char r,q;
unsigned int result,remainder;
// printf("Dividing %d (%x) by %d (%x): ",ax,ax,value,value);
if (value==0) {
printf("Divide by zero!\n");
return;
}
result=ax/value;
remainder=ax%value;
q=result;
r=remainder;
// printf("Result: q=%d r=%d\n",q,r);
ax=(r<<8)|(q&0xff);
}
/* signed divide */
/* DX:AX / word. AX=quotient, DX=remainder */
void idiv_16(unsigned short value) {
short r,q,divisor;
int temp32,result,remainder;
divisor=value;
temp32=ax;
temp32&=0xffff;
temp32|=(dx<<16);
// printf("Dividing %d (%x = %04x:%04x) by %d (%x): ",
// temp32,temp32,dx,ax,value,value);
if (divisor==0) {
printf("Divide by zero!\n");
return;
}
result=temp32/divisor;
remainder=temp32%divisor;
q=result;
r=remainder;
// printf("q=%d r=%d\n",q,r);
ax=q;
dx=r;
}
unsigned short sar(unsigned short value,int shift) {
short temp;
temp=value;
temp>>=shift;
return temp;
}
void push(int value) {
//printf("Pushing %x\n",value);
stack[sp]=value;
sp++;
}
short pop(void) {
if (sp==0) {
printf("Stack underflow!\n");
return 0;
}
sp--;
//printf("Popping %x\n",stack[sp]);
return stack[sp];
}