cpu.cpp

Upload User: lihuahe
Upload Date: 2009-10-16
Package Size: 7122k
Code Size: 34k
Category: CA program
Development Platform: C++
  1. /*
  2.  * Softcam plugin to VDR (C++)
  3.  *
  4.  * This code is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This code is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  18.  */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. //#include <unistd.h>
  23. #include <ctype.h>
  24. #include "stdafx.h"
  25. //#include <vdr/tools.h>
  26. #include "common.h"
  27. #include "data.h"
  28. #include "debug.h"
  29. #include "cpu.h"
  30. #include "xnprintf.h"
  31. #include "main.h"
  32. extern class DllClass m_DLLInstance;
  33. static bool pc80flag=false;
  34. // -- cMapMem ------------------------------------------------------------------
  35. cMapMem::cMapMem(unsigned short Offset, int Size)
  36. {
  37. offset=Offset; size=Size;
  38. if((mem=(unsigned char *)malloc(size)))
  39. memset(mem,0,size);
  40. dn(printf("mapmem: new map off=%04x size=%04xn",offset,size))
  41. }
  42. cMapMem::~cMapMem()
  43. {
  44. free(mem);
  45. }
  46. bool cMapMem::IsFine(void)
  47. {
  48. return (mem!=0);
  49. }
  50. unsigned char cMapMem::Get(unsigned short ea)
  51. {
  52. return (ea>=offset && ea<offset+size) ? mem[ea-offset] : 0;
  53. }
  54. void cMapMem::Set(unsigned short ea, unsigned char val)
  55. {
  56. if(ea>=offset && ea<offset+size)
  57. mem[ea-offset]=val;
  58. }
  59. // -- cMapRom ------------------------------------------------------------------
  60. cMapRom::cMapRom(unsigned short Offset, const char *Filename, int InFileOffset)
  61. {
  62. offset=Offset; addr=0;
  63. fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,false);
  64. if(fm && fm->Map()) {
  65. addr=fm->Addr()+InFileOffset;
  66. size=fm->Size()-InFileOffset;
  67. dn(printf("maprom: new map off=%04x size=%04xn",offset,size))
  68. }
  69. }
  70. cMapRom::~cMapRom()
  71. {
  72. if(fm) fm->Unmap();
  73. }
  74. bool cMapRom::IsFine(void)
  75. {
  76. return (addr!=0);
  77. }
  78. unsigned char cMapRom::Get(unsigned short ea)
  79. {
  80. return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
  81. }
  82. void cMapRom::Set(unsigned short ea, unsigned char val)
  83. {
  84. Show_Diss = m_DLLInstance.m_show_diss;
  85. if(ea>=offset && ea<offset+size) if (Show_Diss==1) de(printf("[ROM] "))
  86. // this is a ROM!
  87. }
  88. // -- cMapEeprom ---------------------------------------------------------------
  89. cMapEeprom::cMapEeprom(unsigned short Offset, const char *Filename, int OtpSize, int InFileOffset)
  90. {
  91. offset=Offset; otpSize=OtpSize; addr=0;
  92. fm=filemaps.GetFileMap(Filename,FILEMAP_DOMAIN,true);
  93. if(fm && fm->Map()) {
  94. addr=fm->Addr()+InFileOffset;
  95. size=fm->Size()-InFileOffset;
  96. dn(printf("mapeeprom: new map off=%04x size=%04x otp=%04xn",offset,size,otpSize))
  97. }
  98. }
  99. cMapEeprom::~cMapEeprom()
  100. {
  101. if(fm) fm->Unmap();
  102. }
  103. bool cMapEeprom::IsFine(void)
  104. {
  105. return (addr!=0);
  106. }
  107. unsigned char cMapEeprom::Get(unsigned short ea)
  108. {
  109. return (ea>=offset && ea<offset+size) ? addr[ea-offset] : 0;
  110. }
  111. void cMapEeprom::Set(unsigned short ea, unsigned char val)
  112. {
  113. Show_Diss = m_DLLInstance.m_show_diss;
  114. if(ea>=offset && ea<offset+otpSize) {
  115. if(addr[ea-offset]==0) {
  116. addr[ea-offset]=val;
  117. if (Show_Diss==1) de(printf("[OTP-SET] "))
  118. }
  119. if (Show_Diss==1) de(printf("[OTP] "))
  120. }
  121. if(ea>=offset+otpSize && ea<offset+size) {
  122. addr[ea-offset]=val;
  123. if (Show_Diss==1) de(printf("[EEP] "))
  124. }
  125. }
  126. // -- c6805 --------------------------------------------------------------------
  127. #define HILO(ea)      ((Get(ea)<<8)+Get((ea)+1))
  128. #define HILOS(s,ea)   ((Get((ea),(s))<<8)+Get((ea)+1,(s)))
  129. #define PAGEOFF(ea,s) (((ea)&0x8000) ? pageMap[s]:0)
  130. static char * __paddr(unsigned char s, unsigned short ea)
  131. {
  132. static char addr[32];
  133. _snprintf(addr,sizeof(addr),((ea&0x8000) && s>0)?"%2$x:%1$04x":"%04x",ea,s);
  134. return addr;
  135. }
  136. #define PADDR(s,ea)   __paddr(s,ea)
  137. c6805::c6805(void) {
  138. cc.c=0; cc.z=0; cc.n=0; cc.i=0; cc.h=0; cc.v=1;
  139. pc=0; a=0; x=0; y=0; cr=dr=0; sp=spHi=0x100; spLow=0xC0;
  140. ClearBreakpoints();
  141. InitMapper();
  142. #ifdef DEBUG_STAT
  143. memset(stats,0,sizeof(stats));
  144. #endif
  145. }
  146. c6805::~c6805()
  147. {
  148. #ifdef DEBUG_STAT
  149. int i, j, sort[256];
  150. bool done=false;
  151. for(i=0 ; i<256 ; i++) sort[i]=i;
  152. for(i=0 ; i<256 && !done ; i++)
  153. for(j=0 ; j<255 ; j++)
  154. if(stats[sort[j]]<stats[sort[j+1]]) {
  155. int x=sort[j];
  156. sort[j]=sort[j+1];
  157. sort[j+1]=x;
  158. done=false;
  159. }
  160. printf("6805: opcode statisticsn");
  161. for(i=0 ; i<256 ; i++)
  162. if((j=stats[sort[i]])) printf("6805: opcode %02x: %dn",sort[i],j);
  163. #endif
  164. ClearMapper();
  165. }
  166. bool c6805::AddMapper(cMap *map, unsigned short start, int size, unsigned char seg)
  167. {
  168. if(map && map->IsFine()) {
  169. if(nextMapper<MAX_MAPPER) {
  170. mapper[nextMapper]=map;
  171. memset(&mapMap[start+PAGEOFF(start,seg)],nextMapper,size);
  172. nextMapper++;
  173. return true;
  174. }
  175. else if (Show_Diss==1) dee(printf("6805: too many mappersn"))
  176. }
  177. else if (Show_Diss==1) dee(printf("6805: mapper not readyn"))
  178. delete map;
  179. return false;
  180. }
  181. void c6805::ResetMapper(void)
  182. {
  183. ClearMapper(); InitMapper();
  184. }
  185. void c6805::InitMapper(void)
  186. {
  187. memset(mapMap,0,sizeof(mapMap));
  188. memset(mapper,0,sizeof(mapper));
  189. mapper[0]=new cMapMem(0,PAGE_SIZE*2);
  190. nextMapper=1;
  191. memset(pageMap,0,sizeof(pageMap));
  192. pageMap[0]=PAGE_SIZE*0;
  193. pageMap[1]=PAGE_SIZE*1;
  194. pageMap[2]=PAGE_SIZE*2;
  195. pageMap[0x80]=PAGE_SIZE*3;
  196. }
  197. void c6805::ClearMapper(void)
  198. {
  199. for(int i=0; i<MAX_MAPPER; i++) delete mapper[i];
  200. }
  201. unsigned char c6805::Get(unsigned short ea) const
  202. {
  203. return mapper[mapMap[ea+PAGEOFF(ea,cr)]&0x7f]->Get(ea);
  204. }
  205. unsigned char c6805::Get(unsigned char seg, unsigned short ea) const
  206. {
  207. return mapper[mapMap[ea+PAGEOFF(ea,seg)]&0x7f]->Get(ea);
  208. }
  209. void c6805::Set(unsigned short ea, unsigned char val)
  210. {
  211. unsigned char mapId=mapMap[ea+PAGEOFF(ea,cr)];
  212. if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
  213. }
  214. void c6805::Set(unsigned char seg, unsigned short ea, unsigned char val)
  215. {
  216. unsigned char mapId=mapMap[ea+PAGEOFF(ea,seg)];
  217. if(!(mapId&0x80)) mapper[mapId&0x7f]->Set(ea,val);
  218. }
  219. void c6805::ForceSet(unsigned short ea, unsigned char val, bool ro)
  220. {
  221. mapMap[ea]=0;      // reset to RAM map
  222. Set(0,ea,val);       // set value
  223. if(ro) mapMap[ea]|=0x80;  // protect byte
  224. }
  225. void c6805::SetMem(unsigned short addr, const unsigned char *data, int len, unsigned char seg)
  226. {
  227. while(len>0) { Set(seg,addr++,*data++); len--; }
  228. }
  229. void c6805::GetMem(unsigned short addr, unsigned char *data, int len, unsigned char seg) const
  230. {
  231. while(len>0) { *data++=Get(seg,addr++); len--; }
  232. }
  233. void c6805::SetSp(unsigned short SpHi, unsigned short SpLow)
  234. {
  235. spHi =sp=SpHi;
  236. spLow   =SpLow;
  237. }
  238. void c6805::SetPc(unsigned short addr)
  239. {
  240. pc=addr;
  241. }
  242. void c6805::AddBreakpoint(unsigned short addr)
  243. {
  244. Show_Diss = m_DLLInstance.m_show_diss;
  245. if(numBp<MAX_BREAKPOINTS) {
  246. bp[numBp++]=addr;
  247. if (Show_Diss==1) dee(printf("6805: setting breakpoint at 0x%04xn",addr))
  248. }
  249. else if (Show_Diss==1) dee(printf("6805: too many breakpointsn"))
  250. }
  251. void c6805::ClearBreakpoints(void)
  252. {
  253. numBp=0;
  254. memset(bp,0,sizeof(bp));
  255. }
  256. static const char * const ops[] = {
  257. //         0x00    0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08    0x09    0x0a    0x0b    0x0c    0x0d    0x0e    0x0f
  258. /* 0x00 */ "BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR","BRSET","BRCLR",
  259. /* 0x10 */ "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR", "BSET", "BCLR",
  260. /* 0x20 */ "BRA",  "BRN",  "BHI",  "BLS",  "BCC",  "BCS",  "BNE",  "BEQ",  "BHCC", "BHCS", "BPL",  "BMI",  "BMC",  "BMS",  "BIL",  "BIH",
  261. /* 0x30 */ "NEG",  "pre31","pre32","COM",  "LSR",  "op35", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op3b", "INC",  "TST",  "SWAP", "CLR",
  262. /* 0x40 */ "NEG",  "op41", "MUL",  "COM",  "LSR",  "op45", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op4b", "INC",  "TST",  "SWAP", "CLR",
  263. /* 0x50 */ "NEG",  "op51", "MUL",  "COM",  "LSR",  "op55", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op5b", "INC",  "TST",  "SWAP", "CLR",
  264. /* 0x60 */ "NEG",  "op61", "op62", "COM",  "LSR",  "op65", "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "op6b", "INC",  "TST",  "SWAP", "CLR",
  265. /* 0x70 */ "NEG",  "LDD",  "LDD",  "COM",  "LSR",  "LDD",  "ROR",  "ASR",  "ASL",  "ROL",  "DEC",  "TAD",  "INC",  "TST",  "SWAP", "CLR",
  266. /* 0x80 */ "RTI",  "RTS",  "op82", "SWI",  "POPA", "POP%c","POPC", "PRTS", "PUSHA","PUSH%c","PUSHC","TDA", "TCA",  "PJSR", "STOP", "WAIT",
  267. /* 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",
  268. /* 0xa0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "opa7", "EOR",  "ADC",  "ORA",  "ADD",  "PUSHD","BSR",  "LD%c", "POPD",
  269. /* 0xb0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
  270. /* 0xc0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
  271. /* 0xd0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
  272. /* 0xe0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
  273. /* 0xf0 */ "SUB",  "CMP",  "SBC",  "CP%c", "AND",  "BIT",  "LDA",  "STA",  "EOR",  "ADC",  "ORA",  "ADD",  "JMP",  "JSR",  "LD%c", "ST%c",
  274. };
  275. static const char * const vops[] = {
  276. "BVGT","BVLE","BVGE","BVLT","BVC","BVS"
  277. };
  278. // Flags:
  279. // 1 - read operant
  280. // 2 - write operant
  281. // 4 - use dr register
  282. // 8 - special address mode in high nibble
  283. static const char opFlags[] = {
  284. //            00    01    02    03    04    05    06    07    08    09    0a    0b    0c    0d    0e    0f
  285. /* 0x00 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  286. /* 0x10 */  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  287. /* 0x20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  288. /* 0x30 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
  289. /* 0x40 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
  290. /* 0x50 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
  291. /* 0x60 */  0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02,
  292. /* 0x70 */  0x03, 0xA9, 0xB9, 0x03, 0x03, 0xC9, 0x03, 0x03, 0x03, 0x03, 0x03, 0x88, 0x03, 0x01, 0x03, 0x02,
  293. /* 0x80 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  294. /* 0x90 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  295. /* 0xa0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x88, 0x88, 0x01, 0x88,
  296. /* 0xb0 */  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
  297. /* 0xc0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
  298. /* 0xd0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
  299. /* 0xe0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
  300. /* 0xf0 */  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x05, 0x06,
  301. };
  302. // OP Code - Instruction Set Length
  303. static const unsigned int ISlen[] = {
  304. //         0x00  0x01  0x02  0x03  0x04  0x05  0x06  0x07  0x08  0x09  0x0a  0x0b  0x0c  0x0d  0x0e  0x0f
  305. /* 0x00 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  306. /* 0x10 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  307. /* 0x20 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  308. /* 0x30 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  309. /* 0x40 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  310. /* 0x50 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  311. /* 0x60 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  312. /* 0x70 */ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  313. /* 0x80 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  314. /* 0x90 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  315. /* 0xa0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01,
  316. /* 0xb0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  317. /* 0xc0 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  318. /* 0xd0 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  319. /* 0xe0 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  320. /* 0xf0 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  321. };
  322. int c6805::Run(int max_count)
  323. {
  324. // returns:
  325. // 0 - breakpoint
  326. // 1 - stack overflow
  327. // 2 - instruction counter exeeded
  328. // 3 - unsupported instruction
  329. Show_Diss = m_DLLInstance.m_show_diss;
  330. pc80flag=false;
  331. LoopCount=0;
  332. if (Show_Diss==1) dee(printf("6805: cr:-pc- aa xx yy dr -sp- VHINZC -mem@pc- -mem@sp-n"))
  333. while (1) {
  334. if (sp<spLow) {
  335. printf("*** stack overflow (count=%d)n",LoopCount);
  336. return 1;
  337. }
  338. if (spHi>spLow && sp>spHi) {
  339. printf("*** stack underflow (count=%d)n",LoopCount);
  340. return 1;
  341. }
  342. LoopCount++;
  343. bool flag=(pc>=0x80 && pc<0xE0);
  344. if (pc80flag && !flag && Show_Diss==1) printf("6805: [...]n");
  345. pc80flag=flag;
  346. sprintf(displaystr1,"  %.4X: ", pc);
  347.     sprintf(displaystr2,"");
  348. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  349. if (Show_Diss==1) de(printf("6805: %02x:%04x %02x %02x %02x %02x %04x %c%c%c%c%c%c %02x%02x%02x%02x %02x%02x%02x%02x ",
  350.        cr,pc,a,x,y,dr,sp,
  351.        cc.v?'V':'.',cc.h?'H':'.',cc.i?'I':'.',cc.n?'N':'.',cc.z?'Z':'.',cc.c?'C':'.',
  352.        Get(pc),Get(pc+1),Get(pc+2),Get(pc+3),Get(sp+1),Get(sp+2),Get(sp+3),Get(sp+4)))
  353. Stepper();
  354. unsigned char *ex=&x;
  355. unsigned short idx=*ex;
  356. indirect=false;
  357. bool paged=false, vbra=false;
  358. unsigned char ins=Get(pc++);
  359. char xs='X', xi='X';
  360.  
  361.   // check pre-bytes
  362. switch (ins) {
  363. case 0x31: // use SP indexed or indirect paged mode (ST19)
  364. ins=Get(pc++);
  365. switch(ins) {
  366. case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: 
  367. vbra=true; 
  368. if (Show_Diss==1) printf("WARN: V-flag not yet calculated ");
  369. break;
  370. case 0x75:
  371. case 0x8D:
  372. case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB:
  373. case 0xCE: case 0xCF:
  374. case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB:
  375. case 0xDE: case 0xDF: 
  376. paged=true; 
  377. indirect=true; 
  378. break;
  379. case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA: case 0xEB:
  380. case 0xEE: case 0xEF: 
  381. idx=sp; 
  382. de(xi='S') 
  383. break;
  384. }
  385. break;
  386. case 0x32: // use indirect SP indexed or indirect paged Y indexed mode (ST19)
  387. ins=Get(pc++);
  388. switch(ins) {
  389. case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: 
  390. vbra=true; 
  391. if (Show_Diss==1) printf("WARN: V-flag not yet calculated ");
  392. indirect=true; 
  393. break;
  394. case 0xC3:
  395. case 0xCE: case 0xCF:
  396. case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB:
  397. case 0xDE: case 0xDF: 
  398. paged=true; 
  399. indirect=true; 
  400. ex=&y; idx=*ex; 
  401. de(xs='Y') 
  402. de(xi='Y') 
  403. break;
  404. case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA: case 0xEB:
  405. case 0xEE: case 0xEF: indirect=true; idx=sp; de(xi='S') break;
  406. }
  407. break;
  408. case 0x91: // use Y register with indirect addr mode (ST7)
  409. indirect=true;
  410. // fall through
  411. case 0x90: // use Y register (ST7)
  412. ex=&y; idx=*ex; de(xs='Y') de(xi='Y')
  413. ins=Get(pc++);
  414. break;
  415. case 0x92: // use indirect addr mode (ST7)
  416. indirect=true;
  417. ins=Get(pc++);
  418. break;
  419. }
  420. char str[8];
  421. if (!vbra) _snprintf(str,sizeof(str),ops[ins],xs,xs^1);
  422. else       _snprintf(str,sizeof(str),"%s",vops[ins-0x22]);
  423. sprintf(txt,"%-5s ", str); strcat(displaystr2, txt);
  424. if (pc80flag && Show_Diss==1) printf(txt);
  425.   // address decoding
  426. unsigned short ea=0;
  427. unsigned char flags=opFlags[ins];
  428. unsigned char pr=(flags&4) ? dr:cr;
  429. switch (((flags&8) ? flags:ins)>>4) {
  430. case 0x2: // no or special address mode
  431. case 0x8:
  432. case 0x9:
  433. if (ISlen[ins] == 2) {
  434. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  435. }
  436. break;
  437. case 0xA: // immediate
  438. if (ISlen[ins] == 2) {
  439. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  440. }
  441. sprintf(txt,"#%02x ",Get(pc)); strcat(displaystr2, txt);
  442. if (pc80flag && Show_Diss==1) printf(txt);
  443. ea=pc++; break;
  444. case 0x3: // short
  445. case 0xB:
  446. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  447. ea=Get(pc++);
  448. if (ea==5) 
  449. //Special Attribute bit
  450. ea = 5;
  451. else {
  452. if(!indirect) { // short direct
  453.   }
  454. else { // short indirect
  455.   de(printf("[%02x] -> ",ea))
  456.   ea=Get(ea);
  457. }
  458. }
  459. sprintf(txt,"%02x ",ea); strcat(displaystr2, txt);
  460. if (pc80flag && Show_Diss==1) printf(txt);
  461. break;
  462. case 0xC: // long
  463. if(!indirect) { // long direct
  464. sprintf(txt,"%.2X%.2X", Get(pc),Get(pc+1)); strcat(displaystr1, txt);
  465. ea=HILO(pc); pc+=2;
  466. } else { // long indirect
  467. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  468. if (paged) {
  469. ea=HILO(pc); pc+=2;
  470. sprintf(txt,"[%s] -> ",PADDR(pr,ea)); strcat(displaystr2, txt);
  471. if (pc80flag && Show_Diss==1) printf(txt);
  472. unsigned char s=Get(pr,ea);
  473. ea=HILOS(pr,ea+1);
  474. pr=s;
  475.     } else {
  476. ea=Get(pc++);
  477. sprintf(txt,"[%02x] -> ",ea); strcat(displaystr2, txt);
  478. if (pc80flag && Show_Diss==1) printf(txt);
  479. ea=HILO(ea);
  480.     }
  481. }
  482. sprintf(txt,"%s ",PADDR(pr,ea)); strcat(displaystr2, txt);
  483. if (pc80flag && Show_Diss==1) printf(txt);
  484. break;
  485. case 0xD: // long indexed
  486. if(!indirect) { // long direct indexed
  487. sprintf(txt,"%.2X%.2X", Get(pc),Get(pc+1)); strcat(displaystr1, txt);
  488. ea=HILO(pc); pc+=2;
  489. sprintf(txt,"(%s",PADDR(cr,ea)); strcat(displaystr2, txt);
  490. if (pc80flag && Show_Diss==1) printf(txt);
  491. } else { // long indirect indexed
  492. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  493. if(paged) {
  494. ea=HILO(pc); pc+=2;
  495. sprintf(txt,"([%s]",PADDR(pr,ea)); strcat(displaystr2, txt);
  496. if (pc80flag && Show_Diss==1) printf(txt);
  497. unsigned char s=Get(pr,ea++);
  498. ea=HILOS(pr,ea);
  499. pr=s;
  500.     } else {
  501. ea=Get(pc++);
  502. sprintf(txt,"([%02x]",ea); strcat(displaystr2, txt);
  503. if (pc80flag && Show_Diss==1) printf(txt);
  504. ea=HILO(ea);
  505.     }
  506. sprintf(txt,",%c) -> (%s",xi,PADDR(pr,ea)); strcat(displaystr2, txt);
  507. if (pc80flag && Show_Diss==1) printf(txt);
  508. }
  509. ea+=idx;
  510. sprintf(txt,",%c) -> %s ",xi,PADDR(pr,ea)); strcat(displaystr2, txt);
  511. if (pc80flag && Show_Diss==1) printf(txt);
  512. break;
  513. case 0x6: // short indexed
  514. case 0xE:
  515. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  516. ea=Get(pc++);
  517. if(!indirect) { // short direct indexed
  518. sprintf(txt,"(%02x",ea); strcat(displaystr2, txt);
  519. if (pc80flag && Show_Diss==1) printf(txt);
  520. } else { // short indirect indexed
  521. sprintf(txt,"([%02x]",ea); strcat(displaystr2, txt);
  522. if (pc80flag && Show_Diss==1) printf(txt);
  523. ea=Get(ea);
  524. sprintf(txt,",%c) -> (%02x",xi,ea); strcat(displaystr2, txt);
  525. if (pc80flag && Show_Diss==1) printf(txt);
  526. }
  527. ea+=idx;
  528. sprintf(txt,",%c) -> %s ",xi,PADDR(pr,ea)); strcat(displaystr2, txt);
  529. if (pc80flag && Show_Diss==1) printf(txt);
  530. break;
  531. case 0x7: // indexed
  532. case 0xF:
  533. ea=idx;
  534. sprintf(txt,"(%c) -> %s ",xi,PADDR(pr,ea)); strcat(displaystr2, txt);
  535. if (pc80flag && Show_Diss==1) printf(txt);
  536. break;
  537. case 0x4: // inherent A
  538. sprintf(txt,"A "); strcat(displaystr2, txt);
  539. if (pc80flag && Show_Diss==1) printf(txt);
  540. break;
  541. case 0x5: // inherent X/Y
  542. sprintf(txt,"%c ",xs); strcat(displaystr2, txt);
  543. if (pc80flag && Show_Diss==1) printf(txt);
  544. break;
  545. case 0x0: // bit
  546. case 0x1:
  547. sprintf(txt,"%.2X", Get(pc)); strcat(displaystr1, txt);
  548. ea=Get(pc++);
  549. if(!indirect) {
  550. } else {
  551. sprintf(txt,"[%02x] -> ",ea); strcat(displaystr2, txt);
  552. if (pc80flag && Show_Diss==1) printf(txt);
  553. ea=Get(ea);
  554. indirect=false; // don't use indirect mode in case this is a bit branch
  555. }
  556. sprintf(txt,"%02x ",ea); strcat(displaystr2, txt);
  557. if (pc80flag && Show_Diss==1) printf(txt);
  558. break;
  559. }
  560. // read operant
  561. unsigned char op=0;
  562. if (flags & 1) {
  563. switch (((flags&8) ? flags:ins)>>4) {
  564. case 0x2: // no or special address mode
  565. case 0x8:
  566. case 0x9:
  567.   break;
  568. case 0xA: // immediate
  569. case 0x3: // short
  570. case 0xB:
  571. case 0xC: // long
  572. case 0xD: // long indexed
  573. case 0x6: // short indexed
  574. case 0xE:
  575. case 0x7: // indexed
  576. case 0xF:
  577. case 0x0: // bit
  578. case 0x1:
  579.   //if register 5 bit 7 is set
  580.   if (Get(0x00,0x05)& 0x40) {
  581.   //Get Start and end of codespace from bin
  582.   unsigned short start = Get(0, 0x30C0);
  583.   unsigned short end =  Get(0,0x30C1);
  584.   if ( ((ea>>8) >=start) && ((ea>>8)<=end))
  585.   //its in the dataspace - return 0
  586.   op = 0x00;
  587.   else
  588.   //its in the codespace return 1
  589.   op = 0x01;
  590.   }
  591.   else
  592.   op=Get(pr,ea); 
  593.   break;
  594. case 0x4: // inherent A
  595.   op=a; break;
  596. case 0x5: // inherent X/Y
  597.   op=*ex; break;
  598. }
  599. }
  600. // command decoding
  601. #ifdef DEBUG_STAT
  602. stats[ins]++;
  603. #endif
  604. switch (ins) {
  605. case 0xA6: // LDA
  606. case 0xB6:
  607. case 0xC6:
  608. case 0xD6:
  609. case 0xE6:
  610. case 0xF6:
  611. a=op; tst(op); break;
  612. case 0xAE: // LDX
  613. case 0xBE:
  614. case 0xCE:
  615. case 0xDE:
  616. case 0xEE:
  617. case 0xFE:
  618. *ex=op; tst(op); break;
  619. case 0xB7: // STA
  620. case 0xC7:
  621. case 0xD7:
  622. case 0xE7:
  623. case 0xF7:
  624. op=a; tst(op); break;
  625. case 0xBF: // STX
  626. case 0xCF:
  627. case 0xDF:
  628. case 0xEF:
  629. case 0xFF:
  630. op=*ex; tst(op); break;
  631. case 0x97: // TAX
  632. *ex=a; break;
  633. case 0x9F: // TXA
  634. a=*ex; break;
  635. case 0x93: // TYX (ST7)
  636. if(ex==&x) *ex=y; else *ex=x; break;
  637. case 0x3D: // TST
  638. case 0x4D:
  639. case 0x5D:
  640. case 0x6D:
  641. case 0x7D:
  642. tst(op); break;
  643. case 0x3F: // CLR
  644. case 0x4F:
  645. case 0x5F:
  646. case 0x6F:
  647. case 0x7F:
  648. op=0; tst(0); break;
  649. case 0x3C: // INC
  650. case 0x4C:
  651. case 0x5C:
  652. case 0x6C:
  653. case 0x7C:
  654. op++; tst(op); break;
  655. case 0x3A: // DEC
  656. case 0x4A:
  657. case 0x5A:
  658. case 0x6A:
  659. case 0x7A:
  660. op--; tst(op); break;
  661. case 0x33: // COM
  662. case 0x43:
  663. case 0x53:
  664. case 0x63:
  665. case 0x73:
  666. op=~op; cc.c=1; tst(op); break;
  667. case 0x30: // NEG
  668. case 0x40:
  669. case 0x50:
  670. case 0x60:
  671. case 0x70:
  672. op=~op+1; if(!op) cc.c=0; tst(op); break;
  673. case 0x42: // MUL
  674. case 0x52:
  675. {
  676. unsigned short res=*ex * a;
  677. *ex=(res>>8); a=res&0xff; cc.c=0; cc.h=0;
  678. break;
  679. }
  680. case 0xA9: // ADC
  681. case 0xB9:
  682. case 0xC9:
  683. case 0xD9:
  684. case 0xE9:
  685. case 0xF9:
  686. a=add(op,cc.c); break;
  687. case 0xAB: // ADD
  688. case 0xBB:
  689. case 0xCB:
  690. case 0xDB:
  691. case 0xEB:
  692. case 0xFB:
  693. a=add(op,0); break;
  694. case 0xA2: // SBC
  695. case 0xB2:
  696. case 0xC2:
  697. case 0xD2:
  698. case 0xE2:
  699. case 0xF2:
  700. a=sub(a,op,cc.c); break;
  701. case 0xA0: // SUB
  702. case 0xB0:
  703. case 0xC0:
  704. case 0xD0:
  705. case 0xE0:
  706. case 0xF0:
  707. a=sub(a,op,0); break;
  708. case 0xA1: // CMP
  709. case 0xB1:
  710. case 0xC1:
  711. case 0xD1:
  712. case 0xE1:
  713. case 0xF1:
  714. sub(a,op,0); break;
  715. case 0xA3: // CPX
  716. case 0xB3:
  717. case 0xC3:
  718. case 0xD3:
  719. case 0xE3:
  720. case 0xF3:
  721. sub(*ex,op,0); break;
  722. case 0xA4: // AND
  723. case 0xB4:
  724. case 0xC4:
  725. case 0xD4:
  726. case 0xE4:
  727. case 0xF4:
  728. a &= op; tst(a); break;
  729. case 0xAA: // ORA
  730. case 0xBA:
  731. case 0xCA:
  732. case 0xDA:
  733. case 0xEA:
  734. case 0xFA:
  735. a |= op; tst(a); break;
  736. case 0xA8: // EOR
  737. case 0xB8:
  738. case 0xC8:
  739. case 0xD8:
  740. case 0xE8:
  741. case 0xF8:
  742. a ^= op; tst(a); break;
  743. case 0xA5: // BIT
  744. case 0xB5:
  745. case 0xC5:
  746. case 0xD5:
  747. case 0xE5:
  748. case 0xF5:
  749. tst(a & op); break;
  750. case 0x38: // ASL
  751. case 0x48:
  752. case 0x58:
  753. case 0x68:
  754. case 0x78:
  755. op=rollL(op,0); break;
  756. case 0x39: // ROL
  757. case 0x49:
  758. case 0x59:
  759. case 0x69:
  760. case 0x79:
  761. op=rollL(op,cc.c); break;
  762. case 0x37: // ASR
  763. case 0x47:
  764. case 0x57:
  765. case 0x67:
  766. case 0x77:
  767. op=rollR(op,bitset(op,7)); break;
  768. case 0x34: // LSR
  769. case 0x44:
  770. case 0x54:
  771. case 0x64:
  772. case 0x74:
  773. op=rollR(op,0); break;
  774. case 0x36: // ROR
  775. case 0x46:
  776. case 0x56:
  777. case 0x66:
  778. case 0x76:
  779. op=rollR(op,cc.c); break;
  780. case 0x3E: // SWAP (ST7)
  781. case 0x4E:
  782. case 0x5E:
  783. case 0x6E:
  784. case 0x7E:
  785. op=(op<<4)|(op>>4); tst(op); break;
  786.   case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: // BRSET BRCLR
  787. {
  788. int bit=(ins&0x0F)>>1;
  789. sprintf(txt,",#%x,",bit); strcat(displaystr2, txt);
  790. if (pc80flag && Show_Diss==1) printf(txt);
  791. cc.c=bitset(op,bit);
  792. branch((ins&0x01) ? !cc.c:cc.c);
  793. break;
  794. }
  795.   case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: // BSET BCLR
  796. {
  797. int bit=(ins&0x0F)>>1;
  798. sprintf(txt,",#%x",bit); strcat(displaystr2, txt);
  799. if (pc80flag && Show_Diss==1) printf(txt);
  800. if(ins&0x01) op &= ~(1<<bit);
  801. else         op |=  (1<<bit);
  802. break;
  803. }
  804. case 0x20: // BRA
  805. branch(true); break;
  806. case 0x21: // BRN
  807. branch(false); break;
  808. case 0x22: // BHI
  809. if(vbra) branch(!cc.z && ((cc.n && cc.v) || (!cc.n && !cc.v)));
  810. else branch(!cc.c && !cc.z);
  811. break;
  812. case 0x23: // BLS
  813. if(vbra) branch(cc.z || (cc.n && !cc.v) || (!cc.n && cc.v));
  814. else branch( cc.c ||  cc.z);
  815. break;
  816. case 0x24: // BCC BHS
  817. if(vbra) branch((cc.n && cc.v) || (!cc.n && !cc.v));
  818. else branch(!cc.c);
  819. break;
  820. case 0x25: // BCS BLO
  821. if(vbra) branch((cc.n && !cc.v) || (!cc.n && cc.v));
  822. else branch( cc.c);
  823. break;
  824. case 0x26: // BNE
  825. if(vbra) branch(!cc.v);
  826. else branch(!cc.z);
  827. break;
  828. case 0x27: // BEQ
  829. if(vbra) branch(cc.v);
  830. else branch( cc.z); break;
  831. case 0x28: // BHCC
  832. branch(!cc.h); break;
  833. case 0x29: // BHCS
  834. branch( cc.h); break;
  835. case 0x2A: // BPL
  836. branch(!cc.n); break;
  837. case 0x2B: // BMI
  838. branch( cc.n); break;
  839. case 0x2C: // BMC
  840. branch(!cc.i); break;
  841. case 0x2D: // BMS
  842. branch( cc.i); break;
  843. case 0xBC: // JMP
  844. case 0xCC:
  845. case 0xDC:
  846. case 0xEC:
  847. case 0xFC:
  848. pc=ea; break;
  849. case 0xAD: // BSR
  850. pc++; pushpc(); pc--; branch(true); break;
  851. case 0xBD: // JSR
  852. case 0xCD:
  853. case 0xDD:
  854. case 0xED:
  855. case 0xFD:
  856. pushpc(); pc=ea; break;
  857. case 0x81: // RTS
  858. poppc(); break;
  859. case 0x83: // SWI
  860. pushpc(); push(x); push(a); pushc();
  861. cc.i=1; pc=HILO(0x1ffc); break;
  862. case 0x80: // RTI
  863. popc(); a=pop(); x=pop(); poppc(); break;
  864. case 0x9C: // RSP
  865. sp=spHi; break;
  866. case 0x96: // TSX
  867. *ex=sp; break;
  868. case 0x94: // TXS (ST7)
  869. sp=*ex; break;
  870. case 0x9E: // TSA
  871. a=sp; break;
  872. case 0x95: // TAS (ST7)
  873. sp=a; break;
  874. case 0x84: // POPA (ST7)
  875. a=pop(); break;
  876. case 0x85: // POPX (ST7)
  877. *ex=pop(); break;
  878. case 0x86: // POPC (ST7)
  879. popc(); break;
  880. case 0x88: // PUSHA (ST7)
  881. push(a); break;
  882. case 0x89: // PUSHX (ST7)
  883. push(*ex); break;
  884. case 0x8A: // PUSHC (ST7)
  885. pushc(); break;
  886. case 0x98: // CLC
  887. cc.c=0; break;
  888. case 0x99: // SEC
  889. cc.c=1; break;
  890. case 0x9A: // CLI
  891. cc.i=0; break;
  892. case 0x9B: // SEI
  893. cc.i=1; break;
  894. case 0x9D: // NOP
  895. break;
  896. case 0x71: // LDD (ST19)
  897. case 0x72:
  898. case 0x75:
  899. dr=op; break;
  900. case 0x7B: // TAD (ST19)
  901. dr=a; break;
  902. case 0x8B: // TDA (ST19)
  903. a=dr; break;
  904. case 0x8C: // TCA (ST19)
  905. a=cr; break;
  906. case 0xAC: // PUSHD (ST19)
  907. push(dr); break;
  908. case 0xAF: // POPD (ST19)
  909. dr=pop(); break;
  910. case 0x87: // PRTS (ST19)
  911. cr=pop(); poppc(); break;
  912. case 0x8D: // PJSR (ST19)
  913. if (paged) {
  914. ea=HILO(pc); pc+=2;
  915. sprintf(txt,"[%s] -> ",PADDR(cr,ea)); strcat(displaystr2, txt);
  916. if (pc80flag && Show_Diss==1) printf(txt);
  917. } else {
  918. ea=pc; pc+=3;
  919. }
  920. sprintf(txt,"%s ",PADDR(pr,ea)); strcat(displaystr2, txt);
  921. if (pc80flag && Show_Diss==1) printf(txt);
  922. pr=Get(ea++);
  923. ea=HILO(ea);
  924. pushpc(); push(cr); cr=pr; pc=ea; 
  925. break;
  926. case 0x90: // pre-bytes
  927. case 0x91:
  928. case 0x92:
  929. case 0x31:
  930. case 0x32:
  931. printf("*** pre-byte %02x in command decoding (count=%d)n",ins,LoopCount);
  932. return 3;
  933. default:
  934. printf("*** unsupported instruction 0x%02x (count=%d)n",ins,LoopCount);
  935. return 3;
  936. }
  937. // write operant
  938. if(flags & 2) {
  939. switch(((flags&8) ? flags:ins)>>4) {
  940. case 0x2: // no or special address mode
  941. case 0x8:
  942. case 0x9:
  943. break;
  944. case 0xA: // immediate
  945. case 0x3: // short
  946. case 0xB:
  947. case 0xC: // long
  948. case 0xD: // long indexed
  949. case 0x6: // short indexed
  950. case 0xE:
  951. case 0x7: // indexed
  952. case 0xF:
  953. case 0x0: // bit
  954. case 0x1:
  955. if (ea==0x16) op = op & 0x7F; // This is new
  956. Set(ea,op); break;
  957. case 0x4: // inherent A
  958. a=op; break;
  959. case 0x5: // inherent X/Y
  960. *ex=op; break;
  961. }
  962. for (int i=numBp-1 ; i>=0 ; i--) {
  963. if (bp[i] == pc) {
  964.        if (bp[i]==0x9569 && Show_Diss==0 ) {
  965. // printf("*** %s {next EMM_CMD}nn", displaystr2);
  966. } else if (bp[i]==0x9569 && Show_Diss==1 ) {
  967. printf(" {next EMM_CMD}nn");
  968. } else if (bp[i]==0x9569 && Show_Diss==2 ) {
  969. printf("%-18s ;%s {next EMM_CMD}nn", displaystr1, displaystr2);
  970. } else {
  971. printf("*** Breakpoint at: %04x (count=%d)nn",pc,LoopCount);
  972. }
  973. return 0;
  974. }
  975. }
  976. if (pc80flag && Show_Diss==1) printf("n");
  977. if (LoopCount >= max_count) {
  978. printf("*** Max. instruction counter exceeded (count=%d)n",LoopCount);
  979. return 2;
  980. }
  981. if (Show_Diss==2) printf("%-18s ;%sn", displaystr1, displaystr2);
  982. }
  983. }
  984. void c6805::branch(bool branch)
  985. {
  986. if (pc80flag) {
  987. unsigned char off=Get(pc);
  988. if (indirect) {
  989. sprintf(txt,"[%02x] -> ",off); strcat(displaystr2, txt);
  990. if (pc80flag && Show_Diss==1) printf(txt);
  991. off=Get(off);
  992. }
  993. unsigned short npc=pc+off+1;
  994. if (off&0x80) npc-=0x100; // gcc fixup. take care of sign
  995. sprintf(txt,"%s ",PADDR(cr,npc)); strcat(displaystr2, txt);
  996. if (pc80flag && Show_Diss==1) printf(txt);
  997. if (branch) {
  998. sprintf(txt,"(taken) "); strcat(displaystr2, txt);
  999. if (pc80flag && Show_Diss==1) printf(txt);
  1000. }
  1001. }
  1002. pc++;
  1003. if(branch) {
  1004. unsigned char offset=Get(pc-1);
  1005. if(indirect) offset=Get(offset);
  1006. pc+=offset;
  1007. if(offset&0x80) pc-=0x100; // gcc fixup. take care of sign
  1008. }
  1009. }
  1010. void c6805::push(unsigned char c)
  1011. {
  1012. Set(sp--,c);
  1013. }
  1014. unsigned char c6805::pop(void)
  1015. {
  1016. return Get(++sp);
  1017. }
  1018. void c6805::pushpc(void)
  1019. {
  1020. push(pc & 0xff);
  1021. push(pc >> 8);
  1022. }
  1023. void c6805::poppc(void)
  1024. {
  1025. pc=(pop()<<8) | pop();
  1026. }
  1027. void c6805::pushc(void)
  1028. {
  1029. 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);
  1030. push(c);
  1031. }
  1032. void c6805::popc(void)
  1033. {
  1034. unsigned char c=pop();
  1035. cc.v=(c&32) ? 1:0;
  1036. cc.h=(c&16) ? 1:0;
  1037. cc.i=(c& 8) ? 1:0;
  1038. cc.n=(c& 4) ? 1:0;
  1039. cc.z=(c& 2) ? 1:0;
  1040. cc.c=(c& 1) ? 1:0;
  1041. }
  1042. void c6805::tst(unsigned char c)
  1043. {
  1044. cc.z=!c;
  1045. cc.n=bitset(c,7);
  1046. }
  1047. unsigned char c6805::add(unsigned char op, unsigned char c)
  1048. {
  1049. unsigned short res_half=(a&0x0f) + (op&0x0f) + c;
  1050. unsigned short res=(unsigned short)a + (unsigned short)op + (unsigned short)c;
  1051. cc.h=res_half > 0x0f;
  1052. cc.c=res > 0xff;
  1053. res&=0xff;
  1054. tst(res);
  1055. return res;
  1056. }
  1057. unsigned char c6805::sub(unsigned char op1, unsigned char op2, unsigned char c)
  1058. {
  1059. short res=(short)op1 - (short)op2 - (short)c;
  1060. cc.c=res < 0;
  1061. res&=0xff;
  1062. tst(res);
  1063. return res;
  1064. }
  1065. unsigned char c6805::rollR(unsigned char op, unsigned char c)
  1066. {
  1067. cc.c=bitset(op,0);
  1068. op >>= 1;
  1069. op |= c << 7;
  1070. tst(op);
  1071. return op;
  1072. }
  1073. unsigned char c6805::rollL(unsigned char op, unsigned char c)
  1074. {
  1075. cc.c=bitset(op,7);
  1076. op <<= 1;
  1077. op |= c;
  1078. tst(op);
  1079. return op;
  1080. }