blob: 3db9514dd71e19bb634ab42953bfaa5590ac7f12 [file] [log] [blame] [raw]
#include "cpu.h"
#include "mnemonic.h"
#include "types.h"
#include "tedmem.h"
#include <stdio.h>
#include <string.h>
// converts a decimal number to 'len' long '0' delimited hexa
static void hexform(unsigned int len, int numbr, char *tempstr)
{
char hex[5];
sprintf(hex,"%x",numbr);
strcpy(tempstr,"");
while ((len--)>strlen(hex))
strcat(tempstr,"0");
strcat(tempstr,hex);
}
static inline int bytetobin(int decnum)
{
int i, j;
//fprintf(stderr,"Input %02X.\n", decnum);
j = 0;
for ( i=7; i>=0 ; i--) {
int k = (decnum >> i ) & 1;
j += k;
j *= 10;
}
j /= 10;
//fprintf(stderr,"Output %i.\n", j);
return j;
}
int CPU::disassemble(int pc, char *line)
{
char hexstr[40], out[64];
int current = mem->Read(pc);
int next = mem->Read(pc+1);
int word = (mem->Read(pc+2)<<8)|next;
int mnetyp = ins[current].type;
int mnelen = typlen[mnetyp];
int reladdr;
// put current PC
sprintf(line,". %04X ",pc);
// put bytes
switch (mnelen) {
case 2 :
sprintf( hexstr, "%02X %02X ",current,next);
break;
case 3 :
sprintf( hexstr, "%02X %02X %02X ",current,next,(word&0xFF00)>>8);
break;
default :
sprintf( hexstr,"%02X ", current);
}
strcat(line,hexstr);
// put current instruction
sprintf(hexstr,"%4s ",ins[current].name);
strcat(line,hexstr);
// take the appropriate formatting for the mnemonic
switch (mnetyp) {
case 2 : hexform(mnelen,next,hexstr);
sprintf(out,"#$%s",hexstr);
break;
case 3 : sprintf(out,"$%04X",word);
break;
case 4 : sprintf(out,"($%04X)",word);
break;
case 5 : hexform(mnelen,next,hexstr);
sprintf(out,"$%s",hexstr);
break;
case 6 : hexform(mnelen,next,hexstr);
sprintf(out,"$%s,X",hexstr);
break;
case 7 : hexform(mnelen,next,hexstr);
sprintf(out,"$%s,Y",hexstr);
break;
case 8 : sprintf(out,"$%04X,X",word);
break;
case 9 : sprintf(out,"$%04X,Y",word);
break;
case 10 :hexform(mnelen,next,hexstr);
sprintf(out,"($%s),Y",hexstr);
break;
case 11 :hexform(mnelen,next,hexstr);
sprintf(out,"($%s,X)",hexstr);
break;
case 12 :reladdr = (pc + 2 + (signed char) next)&0xFFFF;
hexform(4,reladdr,hexstr);
sprintf(out,"$%s",hexstr);
break;
default :strcpy(out,"");
break;
}
strcat(line, out);
strcat(line, "\n");
return pc + mnelen;
}
void CPU::regDump(char *line, int rowcount)
{
int flagmask = 0;
if (rowcount == 0) {
sprintf( line, "AC:%02X,XR:%02X,YR:%02X,SP:%02X,PC:%04X,ST:%04X|NV-BCIZC\n",
REG_AC, REG_X, REG_Y, REG_SP, REG_PC, REG_ST);
} else if (rowcount == 1) {
char txt[][5] = {"HI","LO"};
flagmask = bytetobin( REG_ST );
sprintf( line, "IRQ(%s)|HC($%02X)|VC($%03X)|CPU:%s |FL:%08i\n",
txt[*irq_register ? 1 : 0], theTed->getHorizontalCount(), theTed->getVerticalCount(), getName(),
flagmask);
}
}
void CPU::step()
{
#if 0
if (cycle == 0)
process();
while(cycle != 0)
process();
#else
// make sure we are after the first CPU cycle...
while (getcycle()!=1)
theTed->ted_process(0);
while (getcycle()!=0)
theTed->ted_process(0);
#endif
}