SASC-NG
DVBSoftCAM

cpu.c

Go to the documentation of this file.
00001 /*
00002  * Softcam plugin to VDR (C++)
00003  *
00004  * This code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00018  */
00019 
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 
00024 #include "data.h"
00025 #include "cpu.h"
00026 #include "log-nagra.h"
00027 
00028 #define LOGLBPUT(...)   loglb->Printf(__VA_ARGS__)
00029 #define CCLOGLBPUT(...) do { if(doDisAsm) loglb->Printf(__VA_ARGS__); } while(0)
00030 
00031 // -- cMapMem ------------------------------------------------------------------
00032 
00033 cMapMem::cMapMem(unsigned short Offset, int Size)
00034 {
00035   offset=Offset; size=Size;
00036   if((mem=(unsigned char *)malloc(size)))
00037     memset(mem,0,size);
00038 //  PRINTF(L_SYS_EMU,"mapmem: new map off=%04x size=%04x",offset,size);
00039 }
00040 
00041 cMapMem::~cMapMem()
00042 {
00043   free(mem);
00044 }
00045 
00046 bool cMapMem::IsFine(void)
00047 {
00048   return (mem!=0);
00049 }
00050 
00051 unsigned char cMapMem::Get(unsigned short ea)
00052 {
00053   return (ea>=offset && ea<offset+size) ? mem[ea-offset] : 0;
00054 }
00055 
00056 void cMapMem::Set(unsigned short ea, unsigned char val)
00057 {
00058   if(ea>=offset && ea<offset+size)
00059     mem[ea-offset]=val;
00060 }
00061 
00062 // -- cMapRom ------------------------------------------------------------------
00063 
00064 cMapRom::cMapRom(unsigned short Offset, const char *Filename, int InFileOffset)
00065 {
00066   offset=Offset; addr=0;
00067   fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,false);
00068   if(fm && fm->Map()) {
00069     addr=fm->Addr()+InFileOffset;
00070     size=fm->Size()-InFileOffset;
00071     PRINTF(L_SYS_EMU,"maprom: new map off=%04x size=%04x",offset,size);
00072     }
00073 }
00074 
00075 cMapRom::~cMapRom()
00076 {
00077   if(fm) fm->Unmap();
00078 }
00079 
00080 bool cMapRom::IsFine(void)
00081 {
00082   return addr!=0 && size>0;
00083 }
00084 
00085 unsigned char cMapRom::Get(unsigned short ea)
00086 {
00087   return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
00088 }
00089 
00090 void cMapRom::Set(unsigned short ea, unsigned char val)
00091 {
00092   if(ea>=offset && ea<offset+size) LOGLBPUT("[ROM] ");
00093   // this is a ROM!
00094 }
00095 
00096 // -- cMapEeprom ---------------------------------------------------------------
00097 
00098 cMapEeprom::cMapEeprom(unsigned short Offset, const char *Filename, int OtpSize, int InFileOffset)
00099 {
00100   offset=Offset; otpSize=OtpSize; addr=0;
00101   fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,true);
00102   if(fm && fm->Map()) {
00103     addr=fm->Addr()+InFileOffset;
00104     size=fm->Size()-InFileOffset;
00105     PRINTF(L_SYS_EMU,"mapeeprom: new map off=%04x size=%04x otp=%04x",offset,size,otpSize);
00106     }
00107 }
00108 
00109 cMapEeprom::~cMapEeprom()
00110 {
00111   if(fm) fm->Unmap();
00112 }
00113 
00114 bool cMapEeprom::IsFine(void)
00115 {
00116   return (addr!=0);
00117 }
00118 
00119 unsigned char cMapEeprom::Get(unsigned short ea)
00120 {
00121   return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
00122 }
00123 
00124 void cMapEeprom::Set(unsigned short ea, unsigned char val)
00125 {
00126   if(ea>=offset && ea<offset+otpSize) {
00127     if(addr[ea-offset]==0) {
00128       addr[ea-offset]=val;
00129       LOGLBPUT("[OTP-SET] ");
00130       }
00131     LOGLBPUT("[OTP] ");
00132     }
00133   if(ea>=offset+otpSize && ea<offset+size) {
00134     addr[ea-offset]=val;
00135     LOGLBPUT("[EEP] ");
00136     }
00137 }
00138 
00139 // -- c6805 --------------------------------------------------------------------
00140 
00141 #define PAGEOFF(ea,s) (((ea)&0x8000) ? pageMap[s]:0)
00142 
00143 c6805::c6805(void)
00144 {
00145   cc.c=0; cc.z=0; cc.n=0; cc.i=0; cc.h=0; cc.v=1;
00146   pc=0; a=0; x=0; y=0; cr=dr=0; sp=spHi=0x100; spLow=0xC0;
00147   hasReadHandler=hasWriteHandler=false;
00148   exptBase=0x4000;
00149   ResetCycles();
00150   ClearExceptions();
00151   ClearBreakpoints();
00152   InitMapper();
00153   memset(stats,0,sizeof(stats));
00154   loglb=new cLineBuff(128);
00155 }
00156 
00157 c6805::~c6805()
00158 {
00159   if(LOG(L_SYS_CPUSTATS)) {
00160     int i, j, sort[256];
00161     for(i=0; i<256; i++) sort[i]=i;
00162     for(i=0; i<256; i++)
00163       for(j=0; j<255; j++)
00164         if(stats[sort[j]]<stats[sort[j+1]]) {
00165           int x=sort[j]; sort[j]=sort[j+1]; sort[j+1]=x;
00166           }
00167     PRINTF(L_SYS_CPUSTATS,"opcode statistics");
00168     for(i=0; i<256; i++)
00169       if((j=stats[sort[i]])) PRINTF(L_SYS_CPUSTATS,"opcode %02x: %d",sort[i],j);
00170     }
00171   ClearMapper();
00172   delete loglb;
00173 }
00174 
00175 bool c6805::AddMapper(cMap *map, unsigned short start, int size, unsigned char seg)
00176 {
00177   if(map && map->IsFine()) {
00178     if(nextMapper<MAX_MAPPER) {
00179       map->loglb=loglb;
00180       mapper[nextMapper]=map;
00181       memset(&mapMap[start+PAGEOFF(start,seg)],nextMapper,size);
00182       nextMapper++;
00183       return true;
00184       }
00185     else PRINTF(L_SYS_EMU,"6805: too many mappers");
00186     }
00187   else PRINTF(L_SYS_EMU,"6805: mapper not ready (start=%02x:%04x size=%04x)",seg,start,size);
00188   delete map;
00189   return false;
00190 }
00191 
00192 void c6805::ResetMapper(void)
00193 {
00194   ClearMapper(); InitMapper();
00195 }
00196 
00197 void c6805::InitMapper(void)
00198 {
00199   memset(mapMap,0,sizeof(mapMap));
00200   memset(mapper,0,sizeof(mapper));
00201   mapper[0]=new cMapMem(0,PAGE_SIZE*2);
00202   nextMapper=1;
00203   memset(pageMap,0,sizeof(pageMap));
00204   pageMap[0]=PAGE_SIZE*0;
00205   pageMap[1]=PAGE_SIZE*1;
00206   pageMap[2]=PAGE_SIZE*2;
00207   pageMap[0x80]=PAGE_SIZE*3;
00208   pageMap[0x40]=PAGE_SIZE*4;
00209 }
00210 
00211 void c6805::ClearMapper(void)
00212 {
00213   for(int i=0; i<MAX_MAPPER; i++) delete mapper[i];
00214 }
00215 
00216 unsigned char c6805::Get(unsigned short ea) const
00217 {
00218   return mapper[mapMap[ea+PAGEOFF(ea,cr)]&0x7f]->Get(ea);
00219 }
00220 
00221 unsigned char c6805::Get(unsigned char seg, unsigned short ea) const
00222 {
00223   return mapper[mapMap[ea+PAGEOFF(ea,seg)]&0x7f]->Get(ea);
00224 }
00225 
00226 void c6805::Set(unsigned short ea, unsigned char val)
00227 {
00228   if(hasWriteHandler) WriteHandler(cr,ea,val);
00229   unsigned char mapId=mapMap[ea+PAGEOFF(ea,cr)];
00230   if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
00231 }
00232 
00233 void c6805::Set(unsigned char seg, unsigned short ea, unsigned char val)
00234 {
00235   if(hasWriteHandler) WriteHandler(seg,ea,val);
00236   unsigned char mapId=mapMap[ea+PAGEOFF(ea,seg)];
00237   if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
00238 }
00239 
00240 void c6805::ForceSet(unsigned short ea, unsigned char val, bool ro)
00241 {
00242   mapMap[ea]=0;                 // reset to RAM map
00243   Set(0,ea,val);                // set value
00244   if(ro) mapMap[ea]|=0x80;      // protect byte
00245 }
00246 
00247 void c6805::SetMem(unsigned short addr, const unsigned char *data, int len, unsigned char seg)
00248 {
00249   while(len>0) { Set(seg,addr++,*data++); len--; }
00250 }
00251 
00252 void c6805::GetMem(unsigned short addr, unsigned char *data, int len, unsigned char seg) const
00253 {
00254   while(len>0) { *data++=Get(seg,addr++); len--; }
00255 }
00256 
00257 void c6805::SetSp(unsigned short SpHi, unsigned short SpLow)
00258 {
00259   spHi =sp=SpHi;
00260   spLow   =SpLow;
00261 }
00262 
00263 void c6805::SetPc(unsigned short addr, unsigned char seg)
00264 {
00265   pc=addr; cr=seg;
00266   ResetCycles();
00267   ClearExceptions();
00268 }
00269 
00270 void c6805::PopPc(void)
00271 {
00272   poppc();
00273 }
00274 
00275 void c6805::PopCr(void)
00276 {
00277   cr=pop();
00278 }
00279 
00280 void c6805::Push(unsigned char c)
00281 {
00282   push(c);
00283 }
00284 
00285 void c6805::AddBreakpoint(unsigned short addr)
00286 {
00287   if(numBp<MAX_BREAKPOINTS) {
00288     bp[numBp++]=addr;
00289     PRINTF(L_SYS_EMU,"6805: setting breakpoint at 0x%04x",addr);
00290     }
00291   else PRINTF(L_SYS_EMU,"6805: too many breakpoints");
00292 }
00293 
00294 void c6805::ClearBreakpoints(void)
00295 {
00296   numBp=0;
00297   memset(bp,0,sizeof(bp));
00298 }
00299 
00300 void c6805::AddCycles(unsigned int num)
00301 {
00302   if(num>0) {
00303     clockcycles+=num;
00304     if(timerDisable>0) {
00305       timerDisable-=num;
00306       if(timerDisable<0) timerDisable=0;
00307       }
00308     if(!timerDisable)
00309       TimerHandler(num);
00310     }
00311 }
00312 
00313 void c6805::ResetCycles(void)
00314 {
00315   clockcycles=0;
00316 }
00317 
00318 void c6805::RaiseException(int num)
00319 {
00320   if(num<EXPT_MAX) {
00321     exptPending=true;
00322     expt[num]=true;
00323     }
00324 }
00325 
00326 void c6805::ClearExceptions(void)
00327 {
00328   exptPending=false; exptReady=true; timerDisable=0;
00329   for(int i=0; i<EXPT_MAX; i++) expt[i]=false;
00330 }
00331 
00332 void c6805::DisableTimers(int num)
00333 {
00334   timerDisable=num;
00335 }
00336 
00337 void c6805::SetExptBase(unsigned short base)
00338 {
00339   exptBase=base;
00340 }
00341 
00342 static const char * const ops[] = {
00343 //         0x00    0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08    0x09    0x0a    0x0b    0x0c    0x0d    0x0e    0x0f
00344 /* 0x00 */ "BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR",
00345 /* 0x10 */ "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR",
00346 /* 0x20 */ "BRA",  "BRN",  "BHI",  "BLS",  "BCC",  "BCS",  "BNE",  "BEQ",  "BHCC", "BHCS", "BPL",  "BMI",  "BMC",  "BMS",  "BIL",  "BIH",
00347 /* 0x30 */ "NEG",  "pre31","pre32","COM",  "LSR",  "op35", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op3b", "INC",  "TST",  "SWAP", "CLR",
00348 /* 0x40 */ "NEG",  "op41", "MUL",  "COM",  "LSR",  "op45", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op4b", "INC",  "TST",  "SWAP", "CLR",
00349 /* 0x50 */ "NEG",  "op51", "MUL",  "COM",  "LSR",  "op55", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op5b", "INC",  "TST",  "SWAP", "CLR",
00350 /* 0x60 */ "NEG",  "op61", "op62", "COM",  "LSR",  "op65", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op6b", "INC",  "TST",  "SWAP", "CLR",
00351 /* 0x70 */ "NEG",  "LDD",  "LDD",  "COM",  "LSR",  "LDD",  "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "TAD",  "INC",  "TST",  "SWAP", "CLR",
00352 /* 0x80 */ "RTI",  "RTS",  "op82", "SWI",  "POPA", "POP%c","POPC", "PRTS", "PUSHA","PUSH%c","PUSHC","TDA", "TCA",  "PJSR", "STOP", "WAIT",
00353 /* 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",
00354 /* 0xa0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "opa7", "EOR",  "ADC",  "ORA",  "ADD",  "PUSHD","BSR",  "LD%c", "POPD",
00355 /* 0xb0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
00356 /* 0xc0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
00357 /* 0xd0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
00358 /* 0xe0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
00359 /* 0xf0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
00360   };
00361 static const char * const vops[] = {
00362   "BVGT","BVLE","BVGE","BVLT","BVC","BVS"
00363   };
00364 
00365 // Flags:
00366 // 1 - read operant
00367 // 2 - write operant
00368 // 4 - use dr register
00369 // 8 - special address mode in high nibble
00370 static const char opFlags[] = {
00371 //            00    01    02    03    04    05    06    07    08    09    0a    0b    0c    0d    0e    0f
00372 /* 0x00 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00373 /* 0x10 */  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
00374 /* 0x20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00375 /* 0x30 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
00376 /* 0x40 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
00377 /* 0x50 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
00378 /* 0x60 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
00379 /* 0x70 */  0x03, 0xA9, 0xB9, 0x03, 0x03, 0xC9, 0x03, 0x03, 0x03, 0x03, 0x03, 0x88, 0x03, 0x01, 0x03, 0x02,
00380 /* 0x80 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00381 /* 0x90 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00382 /* 0xa0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x88, 0x88, 0x01, 0x88,
00383 /* 0xb0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
00384 /* 0xc0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
00385 /* 0xd0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
00386 /* 0xe0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
00387 /* 0xf0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
00388   };
00389 
00390 static const unsigned char clock_cycles[] = {
00391 //         00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f
00392 /* 0x00 */  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
00393 /* 0x10 */  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
00394 /* 0x20 */  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
00395 /* 0x30 */  5,  0,  0,  5,  5,  0,  5,  5,  5,  5,  5,  0,  5,  4,  5,  5,
00396 /* 0x40 */  3,  0, 11,  3,  3,  0,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,
00397 /* 0x50 */  3,  0,  0,  3,  3,  0,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,
00398 /* 0x60 */  6,  0,  0,  6,  6,  0,  6,  6,  6,  6,  6,  0,  6,  5,  6,  6,
00399 /* 0x70 */  5,  2,  3,  5,  5,  4,  5,  5,  5,  5,  5,  2,  5,  4,  5,  5,
00400 /* 0x80 */  9,  6,  0, 10,  4,  4,  4,  6,  3,  3,  3,  2,  2,  7,  2,  2,
00401 /* 0x90 */  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
00402 /* 0xa0 */  2,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  3,  6,  2,  4,
00403 /* 0xb0 */  3,  3,  3,  3,  3,  3,  3,  4,  3,  3,  3,  3,  2,  5,  3,  4,
00404 /* 0xc0 */  4,  4,  4,  4,  4,  4,  4,  5,  4,  4,  4,  4,  3,  6,  4,  5,
00405 /* 0xd0 */  5,  5,  5,  5,  5,  5,  5,  6,  5,  5,  5,  5,  4,  7,  5,  6,
00406 /* 0xe0 */  4,  4,  4,  4,  4,  4,  4,  5,  4,  4,  4,  4,  3,  6,  4,  5,
00407 /* 0xf0 */  3,  3,  3,  3,  3,  3,  3,  4,  3,  3,  3,  3,  2,  5,  3,  4, 
00408   };
00409 
00410 char * c6805::PADDR(unsigned char s, unsigned short ea)
00411 {
00412   snprintf(addrBuff,sizeof(addrBuff),((ea&0x8000) && s>0)?"%2$x:%1$04x":"%04x",ea,s);
00413   return addrBuff;
00414 }
00415 
00416 int c6805::Run(int max_count)
00417 {
00418 // returns:
00419 // 0 - breakpoint
00420 // 1 - stack overflow
00421 // 2 - instruction counter exeeded
00422 // 3 - unsupported instruction
00423 
00424   bool disAsmHeader=false;
00425   disAsmLogClass=L_SYS_DISASM;
00426   if(LOG(L_SYS_DISASM)) doDisAsm=true;
00427   else {
00428     doDisAsm=false;
00429     if(LOG(L_SYS_DISASM80)) disAsmLogClass=L_SYS_DISASM80;
00430     }
00431 
00432   int count=0;
00433   while (1) {
00434     if(exptPending && exptReady) {
00435       exptPending=false;
00436       for(int i=0; i<EXPT_MAX; ++i)
00437         if(expt[i]) {
00438           exptPending=true; // to force check for another interrupt in next Run pass
00439           expt[i]=false;
00440           pushpc(); push(x); push(a); pushc(); cc.i=1;
00441           pc=exptBase+4*i;
00442           timerDisable=0;
00443           break;
00444           }
00445       }
00446     exptReady=!cc.i;
00447     Stepper();
00448     if(sp<spLow) {
00449       PRINTF(L_SYS_EMU,"stack overflow (count=%d)",count);
00450       return 1;
00451       }
00452     if(spHi>spLow && sp>spHi) {
00453       PRINTF(L_SYS_EMU,"stack underflow (count=%d)",count);
00454       return 1;
00455       }
00456     if(pc>0x0400 && mapMap[pc+PAGEOFF(pc,cr)]==0) {
00457       PRINTF(L_SYS_EMU,"NX protection at %04x (count=%d)",pc,count);
00458       return 1;
00459       }
00460     count++;
00461 
00462     if(!LOG(L_SYS_DISASM) && LOG(L_SYS_DISASM80)) {
00463       bool flag=(pc>=0x80 && pc<0x200);
00464       if(doDisAsm && !flag) PRINTF(disAsmLogClass,"[...]");
00465       doDisAsm=flag;
00466       }
00467 
00468     if(doDisAsm && !disAsmHeader) {
00469       PRINTF(disAsmLogClass,"cr:-pc- aa xx yy dr -sp- VHINZC -mem@pc- -mem@sp- -cycles-");
00470       disAsmHeader=true;
00471       }
00472     CCLOGLBPUT("%02x:%04x %02x %02x %02x %02x %04x %c%c%c%c%c%c %02x%02x%02x%02x %02x%02x%02x%02x %08x ",
00473                cr,pc,a,x,y,dr,sp,
00474                cc.v?'V':'.',cc.h?'H':'.',cc.i?'I':'.',cc.n?'N':'.',cc.z?'Z':'.',cc.c?'C':'.',
00475                Get(pc),Get(pc+1),Get(pc+2),Get(pc+3),Get(sp+1),Get(sp+2),Get(sp+3),Get(sp+4),
00476                clockcycles);
00477 
00478     unsigned char *ex=&x;
00479     unsigned short idx=*ex;
00480     indirect=false;
00481     bool paged=false, vbra=false;
00482     unsigned char ins=Get(pc++);
00483     char xs='X', xi='X';
00484     int cycles=0;
00485  
00486     // check pre-bytes
00487     switch(ins) {
00488       case 0x31: // use SP indexed or indirect paged mode (ST19)
00489         cycles+=2;
00490         ins=Get(pc++);
00491         switch(ins) {
00492           case 0x22: case 0x23: case 0x24: case 0x25:
00493           case 0x26: case 0x27:
00494             vbra=true; break;
00495           case 0x8D:
00496             cycles++;
00497             // fall through
00498           case 0x75:
00499           case 0xC0: case 0xC1: case 0xC2: case 0xC3:
00500           case 0xC4: case 0xC5: case 0xC6: case 0xC7:
00501           case 0xC8: case 0xC9: case 0xCA: case 0xCB:
00502           case 0xCE: case 0xCF:
00503           case 0xD0: case 0xD1: case 0xD2: case 0xD3:
00504           case 0xD4: case 0xD5: case 0xD6: case 0xD7:
00505           case 0xD8: case 0xD9: case 0xDA: case 0xDB:
00506           case 0xDE: case 0xDF:
00507             paged=true; indirect=true; break;
00508           case 0xE0: case 0xE1: case 0xE2: case 0xE3:
00509           case 0xE4: case 0xE5: case 0xE6: case 0xE7:
00510           case 0xE8: case 0xE9: case 0xEA: case 0xEB:
00511           case 0xEE: case 0xEF:
00512             idx=sp; xi='S'; break;
00513           }
00514         break;
00515       case 0x32: // use indirect SP indexed or indirect paged Y indexed mode (ST19)
00516         cycles+=2;
00517         ins=Get(pc++);
00518         switch(ins) {
00519           case 0x22: case 0x23: case 0x24: case 0x25:
00520           case 0x26: case 0x27:
00521             vbra=true; indirect=true; break;
00522           case 0xC3:
00523           case 0xCE: case 0xCF:
00524           case 0xD0: case 0xD1: case 0xD2: case 0xD3:
00525           case 0xD4: case 0xD5: case 0xD6: case 0xD7:
00526           case 0xD8: case 0xD9: case 0xDA: case 0xDB:
00527           case 0xDE: case 0xDF:
00528             paged=true; indirect=true; ex=&y; idx=*ex; xs='Y'; xi='Y'; break;
00529           case 0xE0: case 0xE1: case 0xE2: case 0xE3:
00530           case 0xE4: case 0xE5: case 0xE6: case 0xE7:
00531           case 0xE8: case 0xE9: case 0xEA: case 0xEB:
00532           case 0xEE: case 0xEF:
00533             indirect=true; idx=sp; xi='S'; break;
00534           }
00535         break;
00536       case 0x91: // use Y register with indirect addr mode (ST7)
00537         cycles++;
00538         indirect=true;
00539         // fall through
00540       case 0x90: // use Y register (ST7)
00541         cycles++;
00542         ex=&y; idx=*ex; xs='Y'; xi='Y';
00543         ins=Get(pc++);
00544         break;
00545       case 0x92: // use indirect addr mode (ST7)
00546         cycles+=2;
00547         indirect=true;
00548         ins=Get(pc++);
00549         break;
00550       }
00551     cycles+=clock_cycles[ins];
00552     int readCycles=clock_cycles[ins]>=2 ? 2:0;
00553     AddCycles(readCycles);
00554 
00555     if(doDisAsm) {
00556       char str[8];
00557       if(!vbra) snprintf(str,sizeof(str),ops[ins],xs,xs^1);
00558       else snprintf(str,sizeof(str),"%s",vops[ins-0x22]);
00559       LOGLBPUT("%-5s ",str);
00560       }
00561 
00562     // address decoding
00563     unsigned short ea=0;
00564     unsigned char flags=opFlags[ins];
00565     unsigned char pr=(flags&4) ? dr:cr;
00566     switch(((flags&8) ? flags:ins)>>4) {
00567       case 0x2:                 // no or special address mode
00568       case 0x8:
00569       case 0x9:
00570         break;
00571       case 0xA:                 // immediate
00572         CCLOGLBPUT("#%02x ",Get(pc));
00573         ea=pc++; break;
00574       case 0x3:                 // short
00575       case 0xB:
00576         ea=Get(pc++);
00577         if(!indirect) {         // short direct
00578           }
00579         else {                  // short indirect
00580           CCLOGLBPUT("[%02x] -> ",ea);
00581           ea=Get(ea);
00582           }
00583         CCLOGLBPUT("%02x ",ea);
00584         break;
00585       case 0xC:                 // long
00586         if(!indirect) {         // long direct
00587           ea=HILO(pc); pc+=2;
00588           }
00589         else {                  // long indirect
00590           if(paged) {
00591             ea=HILO(pc); pc+=2;
00592             CCLOGLBPUT("[%s] -> ",PADDR(pr,ea));
00593             unsigned char s=Get(pr,ea);
00594             ea=HILOS(pr,ea+1);
00595             pr=s;
00596             }
00597           else {
00598             ea=Get(pc++);
00599             CCLOGLBPUT("[%02x] -> ",ea);
00600             ea=HILO(ea);
00601             }
00602           }
00603         CCLOGLBPUT("%s ",PADDR(pr,ea));
00604         break;
00605       case 0xD:                 // long indexed
00606         if(!indirect) {         // long direct indexed
00607           ea=HILO(pc); pc+=2;
00608           CCLOGLBPUT("(%s",PADDR(cr,ea));
00609           }
00610         else {                  // long indirect indexed
00611           if(paged) {
00612             ea=HILO(pc); pc+=2;
00613             CCLOGLBPUT("([%s]",PADDR(pr,ea));
00614             unsigned char s=Get(pr,ea++);
00615             ea=HILOS(pr,ea);
00616             pr=s;
00617             }
00618           else {
00619             ea=Get(pc++);
00620             CCLOGLBPUT("([%02x]",ea);
00621             ea=HILO(ea);
00622             }
00623           CCLOGLBPUT(",%c) -> (%s",xi,PADDR(pr,ea));
00624           }
00625         ea+=idx;
00626         CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea));
00627         break;
00628       case 0x6:                 // short indexed
00629       case 0xE:
00630         ea=Get(pc++);
00631         if(!indirect) {         // short direct indexed
00632           CCLOGLBPUT("(%02x",ea);
00633           }
00634         else {                  // short indirect indexed
00635           CCLOGLBPUT("([%02x]",ea);
00636           ea=Get(ea);
00637           CCLOGLBPUT(",%c) -> (%02x",xi,ea);
00638           }
00639         ea+=idx;
00640         CCLOGLBPUT(",%c) -> %s ",xi,PADDR(pr,ea));
00641         break;
00642       case 0x7:                 // indexed
00643       case 0xF:
00644         ea=idx;
00645         CCLOGLBPUT("(%c) -> %s ",xi,PADDR(pr,ea));
00646         break;
00647       case 0x4:                 // inherent A
00648         CCLOGLBPUT("A ");
00649         break;
00650       case 0x5:                 // inherent X/Y
00651         CCLOGLBPUT("%c ",xs);
00652         break;
00653       case 0x0:                 // bit
00654       case 0x1:
00655         ea=Get(pc++);
00656         if(!indirect) {
00657           }
00658         else {
00659           CCLOGLBPUT("[%02x] -> ",ea);
00660           ea=Get(ea);
00661           indirect=false; // don't use indirect mode in case this is a bit branch
00662           }
00663         CCLOGLBPUT("%02x ",ea);
00664         break;
00665       }
00666 
00667     // read operant
00668     unsigned char op=0;
00669     if(flags & 1) {
00670       switch(((flags&8) ? flags:ins)>>4) {
00671         case 0x2:                       // no or special address mode
00672         case 0x8:
00673         case 0x9:
00674           break;
00675         case 0x3:                       // short
00676         case 0xB:
00677         case 0xC:                       // long
00678         case 0xD:                       // long indexed
00679         case 0x6:                       // short indexed
00680         case 0xE:
00681         case 0x7:                       // indexed
00682         case 0xF:
00683         case 0x0:                       // bit
00684         case 0x1:
00685           op=Get(pr,ea);
00686           if(hasReadHandler) ReadHandler(pr,ea,op);
00687           CCLOGLBPUT("{%02x} ",op);
00688           break;
00689         case 0xA:                       // immediate
00690           op=Get(pr,ea);
00691           break;
00692         case 0x4:                       // inherent A
00693           op=a; break;
00694         case 0x5:                       // inherent X/Y
00695           op=*ex; break;
00696         }
00697       }
00698 
00699     AddCycles(cycles-readCycles);
00700 
00701     // command decoding
00702     stats[ins]++;
00703     switch(ins) {
00704       case 0xA6: // LDA
00705       case 0xB6:
00706       case 0xC6:
00707       case 0xD6:
00708       case 0xE6:
00709       case 0xF6:
00710         a=op; tst(op); break;
00711       case 0xAE: // LDX
00712       case 0xBE:
00713       case 0xCE:
00714       case 0xDE:
00715       case 0xEE:
00716       case 0xFE:
00717         *ex=op; tst(op); break;
00718       case 0xB7: // STA
00719       case 0xC7:
00720       case 0xD7:
00721       case 0xE7:
00722       case 0xF7:
00723         op=a; tst(op); break;
00724       case 0xBF: // STX
00725       case 0xCF:
00726       case 0xDF:
00727       case 0xEF:
00728       case 0xFF:
00729         op=*ex; tst(op); break;
00730       case 0x97: // TAX
00731         *ex=a; break;
00732       case 0x9F: // TXA
00733         a=*ex; break;
00734       case 0x93: // TYX (ST7)
00735         if(ex==&x) *ex=y; else *ex=x; break;
00736       case 0x3D: // TST
00737       case 0x4D:
00738       case 0x5D:
00739       case 0x6D:
00740       case 0x7D:
00741         tst(op); break;
00742       case 0x3F: // CLR
00743       case 0x4F:
00744       case 0x5F:
00745       case 0x6F:
00746       case 0x7F:
00747         op=0; tst(0); break;
00748       case 0x3C: // INC
00749       case 0x4C:
00750       case 0x5C:
00751       case 0x6C:
00752       case 0x7C:
00753         op++; cc.v=(op==0x80); tst(op); break;
00754       case 0x3A: // DEC
00755       case 0x4A:
00756       case 0x5A:
00757       case 0x6A:
00758       case 0x7A:
00759         op--; cc.v=(op==0x7f); tst(op); break;
00760       case 0x33: // COM
00761       case 0x43:
00762       case 0x53:
00763       case 0x63:
00764       case 0x73:
00765         op=~op; cc.c=1; tst(op); break;
00766       case 0x30: // NEG
00767       case 0x40:
00768       case 0x50:
00769       case 0x60:
00770       case 0x70:
00771         op=~op+1; cc.c=(op!=0); cc.v=(op==0x80); tst(op); break;
00772       case 0x42: // MUL
00773       case 0x52:
00774         {
00775         unsigned short res=*ex * a;
00776         *ex=(res>>8); a=res&0xff; cc.c=0; cc.h=0;
00777         break;
00778         }
00779       case 0xA9: // ADC
00780       case 0xB9:
00781       case 0xC9:
00782       case 0xD9:
00783       case 0xE9:
00784       case 0xF9:
00785         a=add(op,cc.c); break;
00786       case 0xAB: // ADD
00787       case 0xBB:
00788       case 0xCB:
00789       case 0xDB:
00790       case 0xEB:
00791       case 0xFB:
00792         a=add(op,0); break;
00793       case 0xA2: // SBC
00794       case 0xB2:
00795       case 0xC2:
00796       case 0xD2:
00797       case 0xE2:
00798       case 0xF2:
00799         a=sub(a,op,cc.c); break;
00800       case 0xA0: // SUB
00801       case 0xB0:
00802       case 0xC0:
00803       case 0xD0:
00804       case 0xE0:
00805       case 0xF0:
00806         a=sub(a,op,0); break;
00807       case 0xA1: // CMP
00808       case 0xB1:
00809       case 0xC1:
00810       case 0xD1:
00811       case 0xE1:
00812       case 0xF1:
00813         sub(a,op,0); break;
00814       case 0xA3: // CPX
00815       case 0xB3:
00816       case 0xC3:
00817       case 0xD3:
00818       case 0xE3:
00819       case 0xF3:
00820         sub(*ex,op,0); break;
00821       case 0xA4: // AND
00822       case 0xB4:
00823       case 0xC4:
00824       case 0xD4:
00825       case 0xE4:
00826       case 0xF4:
00827         a &= op; tst(a); break;
00828       case 0xAA: // ORA
00829       case 0xBA:
00830       case 0xCA:
00831       case 0xDA:
00832       case 0xEA:
00833       case 0xFA:
00834         a |= op; tst(a); break;
00835       case 0xA8: // EOR
00836       case 0xB8:
00837       case 0xC8:
00838       case 0xD8:
00839       case 0xE8:
00840       case 0xF8:
00841         a ^= op; tst(a); break;
00842       case 0xA5: // BIT
00843       case 0xB5:
00844       case 0xC5:
00845       case 0xD5:
00846       case 0xE5:
00847       case 0xF5:
00848         tst(a & op); break;
00849       case 0x38: // ASL
00850       case 0x48:
00851       case 0x58:
00852       case 0x68:
00853       case 0x78:
00854         op=rollL(op,0); break;
00855       case 0x39: // ROL
00856       case 0x49:
00857       case 0x59:
00858       case 0x69:
00859       case 0x79:
00860         op=rollL(op,cc.c); break;
00861       case 0x37: // ASR
00862       case 0x47:
00863       case 0x57:
00864       case 0x67:
00865       case 0x77:
00866         op=rollR(op,bitset(op,7)); break;
00867       case 0x34: // LSR
00868       case 0x44:
00869       case 0x54:
00870       case 0x64:
00871       case 0x74:
00872         op=rollR(op,0); break;
00873       case 0x36: // ROR
00874       case 0x46:
00875       case 0x56:
00876       case 0x66:
00877       case 0x76:
00878         op=rollR(op,cc.c); break;
00879       case 0x3E: // SWAP (ST7)
00880       case 0x4E:
00881       case 0x5E:
00882       case 0x6E:
00883       case 0x7E:
00884         op=(op<<4)|(op>>4); tst(op); break;
00885       //case 0x00 ... 0x0F: // BRSET BRCLR
00886       case 0x00: case 0x01: case 0x02: case 0x03:
00887       case 0x04: case 0x05: case 0x06: case 0x07:
00888       case 0x08: case 0x09: case 0x0A: case 0x0B:
00889       case 0x0C: case 0x0D: case 0x0E: case 0x0F:
00890         {
00891         int bit=(ins&0x0F)>>1;
00892         CCLOGLBPUT(",#%x,",bit);
00893         cc.c=bitset(op,bit);
00894         branch((ins&0x01) ? !cc.c:cc.c);
00895         break;
00896         }
00897       //case 0x10 ... 0x1F: // BSET BCLR
00898       case 0x10: case 0x11: case 0x12: case 0x13:
00899       case 0x14: case 0x15: case 0x16: case 0x17:
00900       case 0x18: case 0x19: case 0x1A: case 0x1B:
00901       case 0x1C: case 0x1D: case 0x1E: case 0x1F:
00902         {
00903         int bit=(ins&0x0F)>>1;
00904         CCLOGLBPUT(",#%x",bit);
00905         if(ins&0x01) op &= ~(1<<bit);
00906         else         op |=  (1<<bit);
00907         break;
00908         }
00909       case 0x20: // BRA
00910         branch(true); break;
00911       case 0x21: // BRN
00912         branch(false); break;
00913       case 0x22: // BHI
00914         if(vbra) branch(!cc.z && ((cc.n && cc.v) || (!cc.n && !cc.v)));
00915         else branch(!cc.c && !cc.z);
00916         break;
00917       case 0x23: // BLS
00918         if(vbra) branch(cc.z || (cc.n && !cc.v) || (!cc.n && cc.v));
00919         else branch( cc.c ||  cc.z);
00920         break;
00921       case 0x24: // BCC BHS
00922         if(vbra) branch((cc.n && cc.v) || (!cc.n && !cc.v));
00923         else branch(!cc.c);
00924         break;
00925       case 0x25: // BCS BLO
00926         if(vbra) branch((cc.n && !cc.v) || (!cc.n && cc.v));
00927         else branch( cc.c);
00928         break;
00929       case 0x26: // BNE
00930         if(vbra) branch(!cc.v);
00931         else branch(!cc.z);
00932         break;
00933       case 0x27: // BEQ
00934         if(vbra) branch(cc.v);
00935         else branch( cc.z); break;
00936       case 0x28: // BHCC
00937         branch(!cc.h); break;
00938       case 0x29: // BHCS
00939         branch( cc.h); break;
00940       case 0x2A: // BPL
00941         branch(!cc.n); break;
00942       case 0x2B: // BMI
00943         branch( cc.n); break;
00944       case 0x2C: // BMC
00945         branch(!cc.i); break;
00946       case 0x2D: // BMS
00947         branch( cc.i); break;
00948       case 0xBC: // JMP
00949       case 0xCC:
00950       case 0xDC:
00951       case 0xEC:
00952       case 0xFC:
00953         pc=ea; break;
00954       case 0xAD: // BSR
00955         pc++; pushpc(); pc--; branch(true); break;
00956       case 0xBD: // JSR
00957       case 0xCD:
00958       case 0xDD:
00959       case 0xED:
00960       case 0xFD:
00961         pushpc(); pc=ea; break;
00962       case 0x81: // RTS
00963         poppc(); break;
00964       case 0x83: // SWI
00965         pushpc(); push(x); push(a); pushc();
00966         cc.i=1; pc=HILO(0x1ffc); break;
00967       case 0x80: // RTI
00968         popc(); a=pop(); x=pop(); poppc(); break;
00969       case 0x9C: // RSP
00970         sp=spHi; break;
00971       case 0x96: // TSX
00972         *ex=sp&0xFF; break;
00973       case 0x94: // TXS (ST7)
00974         sp=(sp&0xFF00)|*ex; break;
00975       case 0x9E: // TSA
00976         a=sp&0xFF; break;
00977       case 0x95: // TAS (ST7)
00978         sp=(sp&0xFF00)|a; break;
00979       case 0x84: // POPA (ST7)
00980         a=pop(); break;
00981       case 0x85: // POPX (ST7)
00982         *ex=pop(); break;
00983       case 0x86: // POPC (ST7)
00984         popc(); break;
00985       case 0x88: // PUSHA (ST7)
00986         push(a); break;
00987       case 0x89: // PUSHX (ST7)
00988         push(*ex); break;
00989       case 0x8A: // PUSHC (ST7)
00990         pushc(); break;
00991       case 0x98: // CLC
00992         cc.c=0; break;
00993       case 0x99: // SEC
00994         cc.c=1; break;
00995       case 0x9A: // CLI
00996         cc.i=0; break;
00997       case 0x9B: // SEI
00998         cc.i=1; break;
00999       case 0x9D: // NOP
01000         break;
01001 
01002       case 0x71: // LDD (ST19)
01003       case 0x72:
01004       case 0x75:
01005         dr=op; break;
01006       case 0x7B: // TAD (ST19)
01007         dr=a; break;
01008       case 0x8B: // TDA (ST19)
01009         a=dr; break;
01010       case 0x8C: // TCA (ST19)
01011         a=cr; break;
01012       case 0xAC: // PUSHD (ST19)
01013         push(dr); break;
01014       case 0xAF: // POPD (ST19)
01015         dr=pop(); break;
01016       case 0x87: // PRTS (ST19)
01017         cr=pop(); poppc(); break;
01018       case 0x8D: // PJSR (ST19)
01019         if(paged) {
01020           ea=HILO(pc); pc+=2;
01021           CCLOGLBPUT("[%s] -> ",PADDR(cr,ea));
01022           }
01023         else {
01024           ea=pc; pc+=3;
01025           }
01026         pr=Get(ea++);
01027         ea=HILO(ea);
01028         CCLOGLBPUT("%s ",PADDR(pr,ea));
01029         pushpc(); push(cr); cr=pr; pc=ea; break;
01030 
01031       case 0x90: // pre-bytes
01032       case 0x91:
01033       case 0x92:
01034       case 0x31:
01035       case 0x32:
01036         PRINTF(L_SYS_EMU,"pre-byte %02x in command decoding (count=%d)",ins,count);
01037         loglb->cLineBuff::Flush();
01038         return 3;
01039       default:
01040         PRINTF(L_SYS_EMU,"unsupported instruction 0x%02x (count=%d)",ins,count);
01041         loglb->cLineBuff::Flush();
01042         return 3;
01043       }
01044 
01045     // write operant
01046     if(flags & 2) {
01047       switch(((flags&8) ? flags:ins)>>4) {
01048         case 0x2:                       // no or special address mode
01049         case 0x8:
01050         case 0x9:
01051           break;
01052         case 0xA:                       // immediate
01053         case 0x3:                       // short
01054         case 0xB:
01055         case 0xC:                       // long
01056         case 0xD:                       // long indexed
01057         case 0x6:                       // short indexed
01058         case 0xE:
01059         case 0x7:                       // indexed
01060         case 0xF:
01061         case 0x0:                       // bit
01062         case 0x1:
01063           Set(ea,op); break;
01064         case 0x4:                       // inherent A
01065           a=op; break;
01066         case 0x5:                       // inherent X/Y
01067           *ex=op; break;
01068         }
01069       }
01070     if(doDisAsm) PUTLB(disAsmLogClass,loglb);
01071     else loglb->cLineBuff::Flush();
01072 
01073     for(int i=numBp-1 ; i>=0 ; i--) {
01074       if(bp[i]==pc) {
01075         PRINTF(L_SYS_EMU,"6805: breakpoint at %04x (count=%d)",pc,count);
01076         return 0;
01077         }
01078       }
01079     if(count>=max_count) {
01080       PRINTF(L_SYS_EMU,"max. instruction counter exceeded (count=%d)",count);
01081       return 2;
01082       }
01083     }
01084 }
01085 
01086 void c6805::branch(bool branch)
01087 {
01088   if(doDisAsm) {
01089     unsigned char off=Get(pc);
01090     if(indirect) {
01091       LOGLBPUT("[%02x] -> ",off);
01092       off=Get(off);
01093       }
01094     unsigned short npc=pc+off+1;
01095     if(off&0x80) npc-=0x100; // gcc fixup. take care of sign
01096     LOGLBPUT("%s ",PADDR(cr,npc));
01097     if(branch) LOGLBPUT("(taken) ");
01098     }
01099   pc++;
01100   if(branch) {
01101     unsigned char offset=Get(pc-1);
01102     if(indirect) offset=Get(offset);
01103     pc+=offset;
01104     if(offset&0x80) pc-=0x100; // gcc fixup. take care of sign
01105     }
01106 }
01107 
01108 void c6805::push(unsigned char c)
01109 {
01110   Set(sp--,c);
01111 }
01112 
01113 unsigned char c6805::pop(void)
01114 {
01115   return Get(++sp);
01116 }
01117 
01118 void c6805::pushpc(void)
01119 {
01120   push(pc & 0xff);
01121   push(pc >> 8);
01122 }
01123 
01124 void c6805::poppc(void)
01125 {
01126   pc=(pop()<<8) | pop();
01127 }
01128 
01129 void c6805::pushc(void)
01130 {
01131   unsigned char c=0xC0+(cc.v?32:0)+(cc.h?16:0)+(cc.i?8:0)+(cc.n?4:0)+(cc.z?2:0)+(cc.c?1:0);
01132   push(c);
01133 }
01134 
01135 void c6805::popc(void)
01136 {
01137   unsigned char c=pop();
01138   cc.v=(c&32) ? 1:0;
01139   cc.h=(c&16) ? 1:0;
01140   cc.i=(c& 8) ? 1:0;
01141   cc.n=(c& 4) ? 1:0;
01142   cc.z=(c& 2) ? 1:0;
01143   cc.c=(c& 1) ? 1:0;
01144 }
01145 
01146 void c6805::tst(unsigned char c)
01147 {
01148   cc.z=!c;
01149   cc.n=bitset(c,7);
01150 }
01151 
01152 unsigned char c6805::add(unsigned char op, unsigned char c)
01153 {
01154   unsigned short res_half=(a&0x0f) + (op&0x0f) + c;
01155   unsigned short res=(unsigned short)a + (unsigned short)op + (unsigned short)c;
01156   cc.h=res_half > 0x0f;
01157   cc.c=res > 0xff;
01158   res&=0xff;
01159   cc.v=((op+c)&0x80) ? ((a&0x80) && !(res&0x80)) : (!(a&0x80) && (res&0x80));
01160   tst(res);
01161   return res;
01162 }
01163 
01164 unsigned char c6805::sub(unsigned char op1, unsigned char op2, unsigned char c)
01165 {
01166   short res=(short)op1 - (short)op2 - (short)c;
01167   cc.c=res < 0;
01168   res&=0xff;
01169   cc.v=((op2+c)&0x80) ? (!(op1&0x80) && (res&0x80)) : ((op1&0x80) && !(res&0x80));
01170   tst(res);
01171   return res;
01172 }
01173 
01174 unsigned char c6805::rollR(unsigned char op, unsigned char c)
01175 {
01176   cc.c=bitset(op,0);
01177   op >>= 1;
01178   op |= c << 7;
01179   tst(op);
01180   return op;
01181 }
01182 
01183 unsigned char c6805::rollL(unsigned char op, unsigned char c)
01184 {
01185   cc.c=bitset(op,7);
01186   op <<= 1;
01187   op |= c;
01188   tst(op);
01189   return op;
01190 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines