📄 cpu.cpp
字号:
/*
* Softcam plugin to VDR (C++)
*
* This code is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <unistd.h>
#include <ctype.h>
#include "stdafx.h"
//#include <vdr/tools.h>
#include "common.h"
#include "data.h"
#include "debug.h"
#include "cpu.h"
#include "xnprintf.h"
#include "main.h"
extern class DllClass m_DLLInstance;
static bool pc80flag=false;
// -- cMapMem ------------------------------------------------------------------
cMapMem::cMapMem(unsigned short Offset, int Size)
{
offset=Offset; size=Size;
if((mem=(unsigned char *)malloc(size)))
memset(mem,0,size);
dn(printf("mapmem: new map off=%04x size=%04x\n",offset,size))
}
cMapMem::~cMapMem()
{
free(mem);
}
bool cMapMem::IsFine(void)
{
return (mem!=0);
}
unsigned char cMapMem::Get(unsigned short ea)
{
return (ea>=offset && ea<offset+size) ? mem[ea-offset] : 0;
}
void cMapMem::Set(unsigned short ea, unsigned char val)
{
if(ea>=offset && ea<offset+size)
mem[ea-offset]=val;
}
// -- cMapRom ------------------------------------------------------------------
cMapRom::cMapRom(unsigned short Offset, const char *Filename, int InFileOffset)
{
offset=Offset; addr=0;
fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,false);
if(fm && fm->Map()) {
addr=fm->Addr()+InFileOffset;
size=fm->Size()-InFileOffset;
dn(printf("maprom: new map off=%04x size=%04x\n",offset,size))
}
}
cMapRom::~cMapRom()
{
if(fm) fm->Unmap();
}
bool cMapRom::IsFine(void)
{
return (addr!=0);
}
unsigned char cMapRom::Get(unsigned short ea)
{
return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
}
void cMapRom::Set(unsigned short ea, unsigned char val)
{
Show_Diss = m_DLLInstance.m_show_diss;
if(ea>=offset && ea<offset+size) if (Show_Diss==1) de(printf("[ROM] "))
// this is a ROM!
}
// -- cMapEeprom ---------------------------------------------------------------
cMapEeprom::cMapEeprom(unsigned short Offset, const char *Filename, int OtpSize, int InFileOffset)
{
offset=Offset; otpSize=OtpSize; addr=0;
fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,true);
if(fm && fm->Map()) {
addr=fm->Addr()+InFileOffset;
size=fm->Size()-InFileOffset;
dn(printf("mapeeprom: new map off=%04x size=%04x otp=%04x\n",offset,size,otpSize))
}
}
cMapEeprom::~cMapEeprom()
{
if(fm) fm->Unmap();
}
bool cMapEeprom::IsFine(void)
{
return (addr!=0);
}
unsigned char cMapEeprom::Get(unsigned short ea)
{
return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
}
void cMapEeprom::Set(unsigned short ea, unsigned char val)
{
Show_Diss = m_DLLInstance.m_show_diss;
if(ea>=offset && ea<offset+otpSize) {
if(addr[ea-offset]==0) {
addr[ea-offset]=val;
if (Show_Diss==1) de(printf("[OTP-SET] "))
}
if (Show_Diss==1) de(printf("[OTP] "))
}
if(ea>=offset+otpSize && ea<offset+size) {
addr[ea-offset]=val;
if (Show_Diss==1) de(printf("[EEP] "))
}
}
// -- c6805 --------------------------------------------------------------------
#define HILO(ea) ((Get(ea)<<8)+Get((ea)+1))
#define HILOS(s,ea) ((Get((ea),(s))<<8)+Get((ea)+1,(s)))
#define PAGEOFF(ea,s) (((ea)&0x8000) ? pageMap[s]:0)
static char * __paddr(unsigned char s, unsigned short ea)
{
static char addr[32];
_snprintf(addr,sizeof(addr),((ea&0x8000) && s>0)?"%2$x:%1$04x":"%04x",ea,s);
return addr;
}
#define PADDR(s,ea) __paddr(s,ea)
c6805::c6805(void) {
cc.c=0; cc.z=0; cc.n=0; cc.i=0; cc.h=0; cc.v=1;
pc=0; a=0; x=0; y=0; cr=dr=0; sp=spHi=0x100; spLow=0xC0;
ClearBreakpoints();
InitMapper();
#ifdef DEBUG_STAT
memset(stats,0,sizeof(stats));
#endif
}
c6805::~c6805()
{
#ifdef DEBUG_STAT
int i, j, sort[256];
bool done=false;
for(i=0 ; i<256 ; i++) sort[i]=i;
for(i=0 ; i<256 && !done ; i++)
for(j=0 ; j<255 ; j++)
if(stats[sort[j]]<stats[sort[j+1]]) {
int x=sort[j];
sort[j]=sort[j+1];
sort[j+1]=x;
done=false;
}
printf("6805: opcode statistics\n");
for(i=0 ; i<256 ; i++)
if((j=stats[sort[i]])) printf("6805: opcode %02x: %d\n",sort[i],j);
#endif
ClearMapper();
}
bool c6805::AddMapper(cMap *map, unsigned short start, int size, unsigned char seg)
{
if(map && map->IsFine()) {
if(nextMapper<MAX_MAPPER) {
mapper[nextMapper]=map;
memset(&mapMap[start+PAGEOFF(start,seg)],nextMapper,size);
nextMapper++;
return true;
}
else if (Show_Diss==1) dee(printf("6805: too many mappers\n"))
}
else if (Show_Diss==1) dee(printf("6805: mapper not ready\n"))
delete map;
return false;
}
void c6805::ResetMapper(void)
{
ClearMapper(); InitMapper();
}
void c6805::InitMapper(void)
{
memset(mapMap,0,sizeof(mapMap));
memset(mapper,0,sizeof(mapper));
mapper[0]=new cMapMem(0,PAGE_SIZE*2);
nextMapper=1;
memset(pageMap,0,sizeof(pageMap));
pageMap[0]=PAGE_SIZE*0;
pageMap[1]=PAGE_SIZE*1;
pageMap[2]=PAGE_SIZE*2;
pageMap[0x80]=PAGE_SIZE*3;
}
void c6805::ClearMapper(void)
{
for(int i=0; i<MAX_MAPPER; i++) delete mapper[i];
}
unsigned char c6805::Get(unsigned short ea) const
{
return mapper[mapMap[ea+PAGEOFF(ea,cr)]&0x7f]->Get(ea);
}
unsigned char c6805::Get(unsigned char seg, unsigned short ea) const
{
return mapper[mapMap[ea+PAGEOFF(ea,seg)]&0x7f]->Get(ea);
}
void c6805::Set(unsigned short ea, unsigned char val)
{
unsigned char mapId=mapMap[ea+PAGEOFF(ea,cr)];
if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
}
void c6805::Set(unsigned char seg, unsigned short ea, unsigned char val)
{
unsigned char mapId=mapMap[ea+PAGEOFF(ea,seg)];
if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
}
void c6805::ForceSet(unsigned short ea, unsigned char val, bool ro)
{
mapMap[ea]=0; // reset to RAM map
Set(0,ea,val); // set value
if(ro) mapMap[ea]|=0x80; // protect byte
}
void c6805::SetMem(unsigned short addr, const unsigned char *data, int len, unsigned char seg)
{
while(len>0) { Set(seg,addr++,*data++); len--; }
}
void c6805::GetMem(unsigned short addr, unsigned char *data, int len, unsigned char seg) const
{
while(len>0) { *data++=Get(seg,addr++); len--; }
}
void c6805::SetSp(unsigned short SpHi, unsigned short SpLow)
{
spHi =sp=SpHi;
spLow =SpLow;
}
void c6805::SetPc(unsigned short addr)
{
pc=addr;
}
void c6805::AddBreakpoint(unsigned short addr)
{
Show_Diss = m_DLLInstance.m_show_diss;
if(numBp<MAX_BREAKPOINTS) {
bp[numBp++]=addr;
if (Show_Diss==1) dee(printf("6805: setting breakpoint at 0x%04x\n",addr))
}
else if (Show_Diss==1) dee(printf("6805: too many breakpoints\n"))
}
void c6805::ClearBreakpoints(void)
{
numBp=0;
memset(bp,0,sizeof(bp));
}
static const char * const ops[] = {
// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
/* 0x00 */ "BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR",
/* 0x10 */ "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR",
/* 0x20 */ "BRA", "BRN", "BHI", "BLS", "BCC", "BCS", "BNE", "BEQ", "BHCC", "BHCS", "BPL", "BMI", "BMC", "BMS", "BIL", "BIH",
/* 0x30 */ "NEG", "pre31","pre32","COM", "LSR", "op35", "ROR", "ASR", "ASL", "ROL", "DEC", "op3b", "INC", "TST", "SWAP", "CLR",
/* 0x40 */ "NEG", "op41", "MUL", "COM", "LSR", "op45", "ROR", "ASR", "ASL", "ROL", "DEC", "op4b", "INC", "TST", "SWAP", "CLR",
/* 0x50 */ "NEG", "op51", "MUL", "COM", "LSR", "op55", "ROR", "ASR", "ASL", "ROL", "DEC", "op5b", "INC", "TST", "SWAP", "CLR",
/* 0x60 */ "NEG", "op61", "op62", "COM", "LSR", "op65", "ROR", "ASR", "ASL", "ROL", "DEC", "op6b", "INC", "TST", "SWAP", "CLR",
/* 0x70 */ "NEG", "LDD", "LDD", "COM", "LSR", "LDD", "ROR", "ASR", "ASL", "ROL", "DEC", "TAD", "INC", "TST", "SWAP", "CLR",
/* 0x80 */ "RTI", "RTS", "op82", "SWI", "POPA", "POP%c","POPC", "PRTS", "PUSHA","PUSH%c","PUSHC","TDA", "TCA", "PJSR", "STOP", "WAIT",
/* 0x90 */ "pre90","pre91","pre92","T%2$c%1$c","T%cS","TAS","TS%c","TA%c", "CLC", "SEC", "CLI", "SEI", "RSP", "NOP", "TSA", "T%cA",
/* 0xa0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "opa7", "EOR", "ADC", "ORA", "ADD", "PUSHD","BSR", "LD%c", "POPD",
/* 0xb0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "STA", "EOR", "ADC", "ORA", "ADD", "JMP", "JSR", "LD%c", "ST%c",
/* 0xc0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "STA", "EOR", "ADC", "ORA", "ADD", "JMP", "JSR", "LD%c", "ST%c",
/* 0xd0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "STA", "EOR", "ADC", "ORA", "ADD", "JMP", "JSR", "LD%c", "ST%c",
/* 0xe0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "STA", "EOR", "ADC", "ORA", "ADD", "JMP", "JSR", "LD%c", "ST%c",
/* 0xf0 */ "SUB", "CMP", "SBC", "CP%c", "AND", "BIT", "LDA", "STA", "EOR", "ADC", "ORA", "ADD", "JMP", "JSR", "LD%c", "ST%c",
};
static const char * const vops[] = {
"BVGT","BVLE","BVGE","BVLT","BVC","BVS"
};
// Flags:
// 1 - read operant
// 2 - write operant
// 4 - use dr register
// 8 - special address mode in high nibble
static const char opFlags[] = {
// 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
/* 0x00 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x10 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x30 */ 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
/* 0x40 */ 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
/* 0x50 */ 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
/* 0x60 */ 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
/* 0x70 */ 0x03, 0xA9, 0xB9, 0x03, 0x03, 0xC9, 0x03, 0x03, 0x03, 0x03, 0x03, 0x88, 0x03, 0x01, 0x03, 0x02,
/* 0x80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0xa0 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x88, 0x88, 0x01, 0x88,
/* 0xb0 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
/* 0xc0 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
/* 0xd0 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
/* 0xe0 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
/* 0xf0 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
};
// OP Code - Instruction Set Length
static const unsigned int ISlen[] = {
// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
/* 0x00 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
/* 0x10 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0x20 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0x30 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0x40 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x60 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0x70 */ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x80 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x90 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0xa0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01,
/* 0xb0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0xc0 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
/* 0xd0 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
/* 0xe0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
/* 0xf0 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};
int c6805::Run(int max_count)
{
// returns:
// 0 - breakpoint
// 1 - stack overflow
// 2 - instruction counter exeeded
// 3 - unsupported instruction
Show_Diss = m_DLLInstance.m_show_diss;
pc80flag=false;
LoopCount=0;
if (Show_Diss==1) dee(printf("6805: cr:-pc- aa xx yy dr -sp- VHINZC -mem@pc- -mem@sp-\n"))
while (1) {
if (sp<spLow) {
printf("*** stack overflow (count=%d)\n",LoopCount);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -