1 /******************************************************* 2 * 3 * Portable (hopefully ;-) 8085A emulator 4 * 5 * Written by J. Buchmueller for use with MAME 6 * 7 * Partially based on Z80Em by Marcel De Kogel 8 * 9 * CPU related macros 10 * 11 *******************************************************/ 12 13 /* Set to 1 for a more exact i8080 emulation */ 14 #define I8080_EXACT 1 15 16 #define SF 0x80 17 #define ZF 0x40 18 #define YF 0x20 19 #define HF 0x10 20 #define XF 0x08 21 #define VF 0x04 22 #define NF 0x02 23 #define CF 0x01 24 25 #define IM_SID 0x80 26 #define IM_SOD 0x40 27 //#define IM_IEN 0x20 28 #define IM_INTR 0x20 //AT: the 8085 ignores bit 0x20. we move IM_INTR here for compatibility. 29 #define IM_TRAP 0x10 30 //#define IM_INTR 0x08 31 #define IM_IEN 0x08 //AT: RIM returns IEN status on this bit. SIM checks this bit to allow masking RST55-75 32 #define IM_RST75 0x04 33 #define IM_RST65 0x02 34 #define IM_RST55 0x01 35 36 #define ADDR_TRAP 0x0024 37 #define ADDR_RST55 0x002c 38 #define ADDR_RST65 0x0034 39 #define ADDR_RST75 0x003c 40 #define ADDR_INTR 0x0038 41 42 #define M_INR(R) ++R; I.AF.b.l=(I.AF.b.l&CF)|ZSP[R]|((R==0x80)?VF:0)|((R&0x0F)?0:HF) 43 #define M_DCR(R) I.AF.b.l=(I.AF.b.l&CF)|NF|((R==0x80)?VF:0)|((R&0x0F)?0:HF); I.AF.b.l|=ZSP[--R] 44 #define M_MVI(R) R=ARG() 45 46 #define M_ANA(R) I.AF.b.h&=R; I.AF.b.l=ZSP[I.AF.b.h]|HF 47 #define M_ORA(R) I.AF.b.h|=R; I.AF.b.l=ZSP[I.AF.b.h] 48 #define M_XRA(R) I.AF.b.h^=R; I.AF.b.l=ZSP[I.AF.b.h] 49 50 #define M_RLC { \ 51 I.AF.b.h = (I.AF.b.h << 1) | (I.AF.b.h >> 7); \ 52 I.AF.b.l = (I.AF.b.l & ~(HF+NF+CF)) | (I.AF.b.h & CF); \ 53 } 54 55 #define M_RRC { \ 56 I.AF.b.l = (I.AF.b.l & ~(HF+NF+CF)) | (I.AF.b.h & CF); \ 57 I.AF.b.h = (I.AF.b.h >> 1) | (I.AF.b.h << 7); \ 58 } 59 60 #define M_RAL { \ 61 int c = I.AF.b.l&CF; \ 62 I.AF.b.l = (I.AF.b.l & ~(HF+NF+CF)) | (I.AF.b.h >> 7); \ 63 I.AF.b.h = (I.AF.b.h << 1) | c; \ 64 } 65 66 #define M_RAR { \ 67 int c = (I.AF.b.l&CF) << 7; \ 68 I.AF.b.l = (I.AF.b.l & ~(HF+NF+CF)) | (I.AF.b.h & CF); \ 69 I.AF.b.h = (I.AF.b.h >> 1) | c; \ 70 } 71 72 #if I8080_EXACT 73 #define M_ADD(R) { \ 74 int q = I.AF.b.h+R; \ 75 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)| \ 76 ((I.AF.b.h^q^R)&HF)| \ 77 (((R^I.AF.b.h^SF)&(R^q)&SF)>>5); \ 78 I.AF.b.h=q; \ 79 } 80 #else 81 #ifdef X86_ASM 82 #define M_ADD(R) \ 83 asm ( \ 84 " addb %2,%0 \n" \ 85 " lahf \n" \ 86 " setob %%al \n" /* al = 1 if overflow */ \ 87 " shlb $2,%%al \n" /* shift to P/V bit position */ \ 88 " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ 89 " orb %%ah,%%al \n" \ 90 :"=mq" (I.AF.b.h), "=a" (I.AF.b.l) \ 91 :"q" (R), "0" (I.AF.b.h) \ 92 ) 93 #else 94 #define M_ADD(R) { \ 95 int q = I.AF.b.h+R; \ 96 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)| \ 97 ((I.AF.b.h^q^R)&HF)| \ 98 (((R^I.AF.b.h^SF)&(R^q)&SF)>>5); \ 99 I.AF.b.h=q; \ 100 } 101 #endif 102 #endif 103 104 #if I8080_EXACT 105 #define M_ADC(R) { \ 106 int q = I.AF.b.h+R+(I.AF.b.l&CF); \ 107 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)| \ 108 ((I.AF.b.h^q^R)&HF)| \ 109 (((R^I.AF.b.h^SF)&(R^q)&SF)>>5); \ 110 I.AF.b.h=q; \ 111 } 112 #else 113 #ifdef X86_ASM 114 #define M_ADC(R) \ 115 asm ( \ 116 " shrb $1,%%al \n" \ 117 " adcb %2,%0 \n" \ 118 " lahf \n" \ 119 " setob %%al \n" /* al = 1 if overflow */ \ 120 " shlb $2,%%al \n" /* shift to P/V bit position */ \ 121 " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ 122 " orb %%ah,%%al \n" /* combine with P/V */ \ 123 :"=mq" (I.AF.b.h), "=a" (I.AF.b.l) \ 124 :"q" (R), "a" (I.AF.b.l), "0" (I.AF.b.h) \ 125 ) 126 #else 127 #define M_ADC(R) { \ 128 int q = I.AF.b.h+R+(I.AF.b.l&CF); \ 129 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)| \ 130 ((I.AF.b.h^q^R)&HF)| \ 131 (((R^I.AF.b.h^SF)&(R^q)&SF)>>5); \ 132 I.AF.b.h=q; \ 133 } 134 #endif 135 #endif 136 137 #if I8080_EXACT 138 #define M_SUB(R) { \ 139 int q = I.AF.b.h-R; \ 140 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 141 ((I.AF.b.h^q^R)&HF)| \ 142 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 143 I.AF.b.h=q; \ 144 } 145 #else 146 #ifdef X86_ASM 147 #define M_SUB(R) \ 148 asm ( \ 149 " subb %2,%0 \n" \ 150 " lahf \n" \ 151 " setob %%al \n" /* al = 1 if overflow */ \ 152 " shlb $2,%%al \n" /* shift to P/V bit position */ \ 153 " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ 154 " orb $2,%%al \n" /* set N flag */ \ 155 " orb %%ah,%%al \n" /* combine with P/V */ \ 156 :"=mq" (I.AF.b.h), "=a" (I.AF.b.l) \ 157 :"q" (R), "0" (I.AF.b.h) \ 158 ) 159 #else 160 #define M_SUB(R) { \ 161 int q = I.AF.b.h-R; \ 162 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 163 ((I.AF.b.h^q^R)&HF)| \ 164 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 165 I.AF.b.h=q; \ 166 } 167 #endif 168 #endif 169 170 #if I8080_EXACT 171 #define M_SBB(R) { \ 172 int q = I.AF.b.h-R-(I.AF.b.l&CF); \ 173 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 174 ((I.AF.b.h^q^R)&HF)| \ 175 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 176 I.AF.b.h=q; \ 177 } 178 #else 179 #ifdef X86_ASM 180 #define M_SBB(R) \ 181 asm ( \ 182 " shrb $1,%%al \n" \ 183 " sbbb %2,%0 \n" \ 184 " lahf \n" \ 185 " setob %%al \n" /* al = 1 if overflow */ \ 186 " shlb $2,%%al \n" /* shift to P/V bit position */ \ 187 " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ 188 " orb $2,%%al \n" /* set N flag */ \ 189 " orb %%ah,%%al \n" /* combine with P/V */ \ 190 :"=mq" (I.AF.b.h), "=a" (I.AF.b.l) \ 191 :"q" (R), "a" (I.AF.b.l), "0" (I.AF.b.h) \ 192 ) 193 #else 194 #define M_SBB(R) { \ 195 int q = I.AF.b.h-R-(I.AF.b.l&CF); \ 196 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 197 ((I.AF.b.h^q^R)&HF)| \ 198 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 199 I.AF.b.h=q; \ 200 } 201 #endif 202 #endif 203 204 #if I8080_EXACT 205 #define M_CMP(R) { \ 206 int q = I.AF.b.h-R; \ 207 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 208 ((I.AF.b.h^q^R)&HF)| \ 209 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 210 } 211 #else 212 #ifdef X86_ASM 213 #define M_CMP(R) \ 214 asm ( \ 215 " cmpb %2,%0 \n" \ 216 " lahf \n" \ 217 " setob %%al \n" /* al = 1 if overflow */ \ 218 " shlb $2,%%al \n" /* shift to P/V bit position */ \ 219 " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ 220 " orb $2,%%al \n" /* set N flag */ \ 221 " orb %%ah,%%al \n" /* combine with P/V */ \ 222 :"=mq" (I.AF.b.h), "=a" (I.AF.b.l) \ 223 :"q" (R), "0" (I.AF.b.h) \ 224 ) 225 #else 226 #define M_CMP(R) { \ 227 int q = I.AF.b.h-R; \ 228 I.AF.b.l=ZSP[q&255]|((q>>8)&CF)|NF| \ 229 ((I.AF.b.h^q^R)&HF)| \ 230 (((R^I.AF.b.h)&(I.AF.b.h^q)&SF)>>5); \ 231 } 232 #endif 233 #endif 234 235 #define M_IN \ 236 I.XX.d=ARG(); \ 237 I.AF.b.h=cpu_readport16(I.XX.d); 238 239 #define M_OUT \ 240 I.XX.d=ARG(); \ 241 cpu_writeport16(I.XX.d,I.AF.b.h) 242 243 #ifdef X86_ASM 244 #define M_DAD(R) \ 245 asm ( \ 246 " andb $0xc4,%1 \n" \ 247 " addb %%al,%%cl \n" \ 248 " adcb %%ah,%%ch \n" \ 249 " lahf \n" \ 250 " andb $0x11,%%ah \n" \ 251 " orb %%ah,%1 \n" \ 252 :"=c" (I.HL.d), "=mq" (I.AF.b.l) \ 253 :"0" (I.HL.d), "1" (I.AF.b.l), "a" (I.R.d) \ 254 ) 255 #else 256 #define M_DAD(R) { \ 257 int q = I.HL.d + I.R.d; \ 258 I.AF.b.l = ( I.AF.b.l & ~(HF+CF) ) | \ 259 ( ((I.HL.d^q^I.R.d) >> 8) & HF ) | \ 260 ( (q>>16) & CF ); \ 261 I.HL.w.l = q; \ 262 } 263 #endif 264 265 #define M_PUSH(R) { \ 266 WM(--I.SP.w.l, I.R.b.h); \ 267 WM(--I.SP.w.l, I.R.b.l); \ 268 } 269 270 #define M_POP(R) { \ 271 I.R.b.l = RM(I.SP.w.l++); \ 272 I.R.b.h = RM(I.SP.w.l++); \ 273 } 274 275 #define M_RET(cc) \ 276 { \ 277 if (cc) \ 278 { \ 279 i8085_ICount -= 6; \ 280 M_POP(PC); \ 281 change_pc16(I.PC.d); \ 282 } \ 283 } 284 285 #define M_JMP(cc) { \ 286 if (cc) { \ 287 i8085_ICount -= 3; \ 288 I.PC.w.l = ARG16(); \ 289 change_pc16(I.PC.d); \ 290 } else I.PC.w.l += 2; \ 291 } 292 293 #define M_CALL(cc) \ 294 { \ 295 if (cc) \ 296 { \ 297 UINT16 a = ARG16(); \ 298 i8085_ICount -= 6; \ 299 M_PUSH(PC); \ 300 I.PC.d = a; \ 301 change_pc16(I.PC.d); \ 302 } else I.PC.w.l += 2; \ 303 } 304 305 #define M_RST(nn) { \ 306 M_PUSH(PC); \ 307 I.PC.d = 8 * nn; \ 308 change_pc16(I.PC.d); \ 309 } 310 311 #define M_DSUB() { \ 312 int q = I.HL.b.l-I.BC.b.l; \ 313 I.AF.b.l=ZS[q&255]|((q>>8)&CF)|NF| \ 314 ((I.HL.b.l^q^I.BC.b.l)&HF)| \ 315 (((I.BC.b.l^I.HL.b.l)&(I.HL.b.l^q)&SF)>>5); \ 316 I.HL.b.l=q; \ 317 q = I.HL.b.h-I.BC.b.h-(I.AF.b.l&CF); \ 318 I.AF.b.l=ZS[q&255]|((q>>8)&CF)|NF| \ 319 ((I.HL.b.h^q^I.BC.b.h)&HF)| \ 320 (((I.BC.b.h^I.HL.b.h)&(I.HL.b.h^q)&SF)>>5); \ 321 if (I.HL.b.l!=0) I.AF.b.l&=~ZF; \ 322 } 323