src/emu/cpu/hcd62121/hcd62121d.c
| r0 | r8064 | |
| 1 | |
| 2 | #include "emu.h" |
| 3 | #include "debugger.h" |
| 4 | #include "hcd62121.h" |
| 5 | |
| 6 | |
| 7 | enum |
| 8 | { |
| 9 | _REG=1, /* register */ |
| 10 | _REGREG, /* register1, register2, or register2, register1 or register1, imm byte */ |
| 11 | _IRG, /* register indirect */ |
| 12 | _IRGREG, /* 2 register indirect */ |
| 13 | _A16, /* 16bit address */ |
| 14 | _A24, /* seg:address */ |
| 15 | _F, /* flag register */ |
| 16 | _CS, /* cs register */ |
| 17 | _DS, /* ds register */ |
| 18 | _SS, /* ss register */ |
| 19 | _PC, /* program counter */ |
| 20 | _SP, /* stack pointer */ |
| 21 | _I8, /* immediate 8 bit value */ |
| 22 | _I16, /* immediate 16 bit value */ |
| 23 | _I64, /* immediate 64 bit value */ |
| 24 | _I80, /* immediate 80 bit value */ |
| 25 | _ILR, /* indirect last address register access */ |
| 26 | _LAR, /* last address register */ |
| 27 | _DSZ, /* dsize register? */ |
| 28 | _TIM, /* timing related register? */ |
| 29 | _KLO, /* KO1 - KO8 output lines */ |
| 30 | _KHI, /* KO9 - KO14(?) output lines */ |
| 31 | _KI, /* K input lines */ |
| 32 | _4, /* for nibble shifts */ |
| 33 | }; |
| 34 | |
| 35 | typedef struct |
| 36 | { |
| 37 | const char *str; |
| 38 | UINT8 arg1; |
| 39 | UINT8 arg2; |
| 40 | } hcd62121_dasm; |
| 41 | |
| 42 | |
| 43 | static const hcd62121_dasm hcd62121_ops[256] = |
| 44 | { |
| 45 | /* 0x00 */ |
| 46 | { "shlb", _REG, _4 }, { "shlw", _REG, _4 }, { "shlq", _REG, _4 }, { "shlt", _REG, _4 }, |
| 47 | { "mskb", _REGREG, 0 }, { "mskw", _REGREG, 0 }, { "mskq", _REGREG, 0 }, { "mskt", _REGREG, 0 }, |
| 48 | { "shrb", _REG, _4 }, { "shrw", _REG, _4 }, { "shrq", _REG, _4 }, { "shrt", _REG, _4 }, |
| 49 | { "tstb", _REGREG, 0 }, { "tstw", _REGREG, 0 }, { "tstq", _REGREG, 0 }, { "tstt", _REGREG, 0 }, |
| 50 | { "xorb", _REGREG, 0 }, { "xorw", _REGREG, 0 }, { "xorq", _REGREG, 0 }, { "xort", _REGREG, 0 }, |
| 51 | { "cmpb", _REGREG, 0 }, { "cmpw", _REGREG, 0 }, { "cmpq", _REGREG, 0 }, { "cmpt", _REGREG, 0 }, |
| 52 | { "movb", _REGREG, 0 }, { "movw", _REGREG, 0 }, { "movq", _REGREG, 0 }, { "movt", _REGREG, 0 }, |
| 53 | { "imskb", _REGREG, 0 }, { "imskw", _REGREG, 0 }, { "imskq", _REGREG, 0 }, { "imskt", _REGREG, 0 }, |
| 54 | |
| 55 | /* 0x20 */ |
| 56 | { "shrb", _REG, 0 }, { "shrw", _REG, 0 }, { "shrq", _REG, 0 }, { "shrt", _REG, 0 }, |
| 57 | { "orb", _REGREG, 0 }, { "orw", _REGREG, 0 }, { "orq", _REGREG, 0 }, { "ort", _REGREG, 0 }, |
| 58 | { "shlb", _REG, 0 }, { "shlw", _REG, 0 }, { "shlq", _REG, 0 }, { "shlt", _REG, 0 }, |
| 59 | { "andb", _REGREG, 0 }, { "andw", _REGREG, 0 }, { "andq", _REGREG, 0 }, { "andt", _REGREG, 0 }, |
| 60 | { "sbbb", _REGREG, 0 }, { "sbbw", _REGREG, 0 }, { "sbbq", _REGREG, 0 }, { "sbbt", _REGREG, 0 }, /* BCD SUB */ |
| 61 | { "subb", _REGREG, 0 }, { "subw", _REGREG, 0 }, { "subq", _REGREG, 0 }, { "subt", _REGREG, 0 }, |
| 62 | { "adbb", _REGREG, 0 }, { "adbw", _REGREG, 0 }, { "adbq", _REGREG, 0 }, { "adbt", _REGREG, 0 }, /* BCD ADD */ |
| 63 | { "addb", _REGREG, 0 }, { "addw", _REGREG, 0 }, { "addq", _REGREG, 0 }, { "addt", _REGREG, 0 }, |
| 64 | |
| 65 | /* 0x40 */ |
| 66 | { "shrb?", _IRG, 0 }, { "shrw?", _IRG, 0 }, { "shrq?", _IRG, 0 }, { "shrt?", _IRG, 0 }, |
| 67 | { "mskb", _IRGREG, 0 }, { "mskw", _IRGREG, 0 }, { "mskq", _IRGREG, 0 }, { "mskt", _IRGREG, 0 }, |
| 68 | { "shrb", _IRG, 0 }, { "shrw", _IRG, 0 }, { "shrq", _IRG, 0 }, { "shrt", _IRG, 0 }, |
| 69 | { "tstb", _IRGREG, 0 }, { "tstw", _IRGREG, 0 }, { "tstq", _IRGREG, 0 }, { "tstt", _IRGREG, 0 }, |
| 70 | { "xorb", _IRGREG, 0 }, { "xorw", _IRGREG, 0 }, { "xorq", _IRGREG, 0 }, { "xort", _IRGREG, 0 }, |
| 71 | { "cmpb", _IRGREG, 0 }, { "cmpw", _IRGREG, 0 }, { "cmpq", _IRGREG, 0 }, { "cmpt", _IRGREG, 0 }, |
| 72 | { "movb", _IRGREG, 0 }, { "movw", _IRGREG, 0 }, { "movq", _IRGREG, 0 }, { "movt", _IRGREG, 0 }, |
| 73 | { "imskb", _IRGREG, 0 }, { "imskw", _IRGREG, 0 }, { "imskq", _IRGREG, 0 }, { "imskt", _IRGREG, 0 }, |
| 74 | |
| 75 | /* 0x60 */ |
| 76 | { "shrb", _IRG, 0 }, { "shrw", _IRG, 0 }, { "shrq", _IRG, 0 }, { "shrt", _IRG, 0 }, |
| 77 | { "orb", _IRGREG, 0 }, { "orw", _IRGREG, 0 }, { "orq", _IRGREG, 0 }, { "ort", _IRGREG, 0 }, |
| 78 | { "shlb", _IRG, 0 }, { "shlw", _IRG, 0 }, { "shlq", _IRG, 0 }, { "shlt", _IRG, 0 }, |
| 79 | { "andb", _IRGREG, 0 }, { "andw", _IRGREG, 0 }, { "andq", _IRGREG, 0 }, { "andt", _IRGREG, 0 }, |
| 80 | { "sbbb", _IRGREG, 0 }, { "sbbw", _IRGREG, 0 }, { "sbbq", _IRGREG, 0 }, { "sbbt", _IRGREG, 0 }, /* BCD SUB */ |
| 81 | { "subb", _IRGREG, 0 }, { "subw", _IRGREG, 0 }, { "subq", _IRGREG, 0 }, { "subt", _IRGREG, 0 }, |
| 82 | { "adbb", _IRGREG, 0 }, { "adbw", _IRGREG, 0 }, { "adbq", _IRGREG, 0 }, { "adbt", _IRGREG, 0 }, /* BCD ADD */ |
| 83 | { "addb", _IRGREG, 0 }, { "addw", _IRGREG, 0 }, { "addq", _IRGREG, 0 }, { "addt", _IRGREG, 0 }, |
| 84 | |
| 85 | /* 0x80 */ |
| 86 | { "un80?", 0, 0 }, { "un81?", 0, 0 }, { "un82?", 0, 0 }, { "un83?", 0, 0 }, |
| 87 | { "un84?", 0, 0 }, { "un85?", 0, 0 }, { "un86?", 0, 0 }, { "un87?", 0, 0 }, |
| 88 | { "jump", _A16, 0 }, { "jump", _A24, 0 }, { "call", _A16, 0 }, { "un8b?", 0, 0 }, |
| 89 | { "un8C?", 0, 0 }, { "un8D?", 0, 0 }, { "un8E?", 0, 0 }, { "un8F?", 0, 0 }, |
| 90 | { "retzh", 0, 0 }, { "retzl", 0, 0 }, { "retc", 0, 0 }, { "retz", 0, 0 }, |
| 91 | { "retzc", 0, 0 }, { "retcl", 0, 0 }, { "retnc", 0, 0 }, { "retnz", 0, 0 }, |
| 92 | { "jump", _IRG, 0 }, { "un99?", 0, 0 }, { "un9A?", 0, 0 }, { "un9b?", 0, 0 }, |
| 93 | { "un9C?", 0, 0 }, { "un9D?", 0, 0 }, { "reti", 0, 0 }, { "ret", 0, 0 }, |
| 94 | |
| 95 | /* 0xa0 */ |
| 96 | { "jmpzh", _A16, 0 }, { "jmpzl", _A16, 0 }, { "jmpc", _A16, 0 }, { "jmpz", _A16, 0 }, |
| 97 | { "jmpzc", _A16, 0 }, { "jmpcl", _A16, 0 }, { "jmpnc", _A16, 0 }, { "jmpnz", _A16, 0 }, |
| 98 | { "callzh", _A16, 0 }, { "callzl", _A16, 0 }, { "callc", _A16, 0 }, { "callz", _A16, 0 }, |
| 99 | { "callzc", _A16, 0 }, { "callcl", _A16, 0 }, { "callnc", _A16, 0 }, { "callnz", _A16, 0 }, |
| 100 | { "unB0?", 0, 0 }, { "unB1?", _I8, 0 }, { "unB2?", 0, 0 }, { "unB3?", _I8, 0 }, |
| 101 | { "out", _KHI, _REG }, { "out", _KHI, _I8 }, { "out", _KLO, _REG }, { "out", _KLO, _I8 }, |
| 102 | { "unB8?", 0, 0 }, { "unB9?", _I8, 0 }, { "unBA?", 0, 0 }, { "jmpcl?", _A16, 0 }, |
| 103 | { "unBC?", 0, 0 }, { "unBD?", 0, 0 }, { "unBE?", 0, 0 }, { "jmpncl?", _A16, 0 }, |
| 104 | |
| 105 | /* 0xc0 */ |
| 106 | { "movb", _REG, _I8 }, { "movw", _REG, _I16 }, { "movq", _REG, _I64 }, { "movt", _REG, _I80 }, |
| 107 | { "movb", _ILR, _ILR }, { "movw", _ILR, _ILR }, { "movq", _ILR, _ILR }, { "movt", _ILR, _ILR }, |
| 108 | { "unC8?", 0, 0 }, { "unC9?", 0, 0 }, { "unCA?", 0, 0 }, { "unCb?", 0, 0 }, |
| 109 | { "swapb", _IRGREG, 0 }, { "swapw", _IRGREG, 0 }, { "swapq", _IRGREG, 0 }, { "swapt", _IRGREG, 0 }, |
| 110 | { "movb", _CS, _REG }, { "movb", _CS, _I8 }, { "movb", _DSZ, _REG }, { "movb", _DSZ, _I8 }, |
| 111 | { "movb", _SS, _REG }, { "movb", _SS, _I8 }, { "movw", _SP, _REG }, { "movw", _SP, _I16 }, |
| 112 | { "movb", _F, _REG }, { "movb", _F, _I8 }, { "unDA?", 0, 0 }, { "unDb?", 0, 0 }, |
| 113 | { "movb", _DS, _REG }, { "movb", _DS, _I8 }, { "movw", _LAR, _REG }, { "movw?", _LAR, _I16 }, |
| 114 | |
| 115 | /* 0xe0 */ |
| 116 | { "unE0?", _I8, 0 }, { "unE1?", _I8, 0 }, { "in", _REG, _KI }, { "movb", _REG, _DSZ }, |
| 117 | { "movb", _REG, _F }, { "movb", _REG, _TIM }, { "unE6?", _I8, 0 }, { "unE7?", _I8, 0 }, |
| 118 | { "movw", _REG, _LAR }, { "movw?", _REG, _LAR }, { "movw", _REG, _PC }, { "movw", _REG, _SP }, |
| 119 | { "unEC?", 0, 0 }, { "movb", _REG, _DS }, { "movb", _REG, _CS }, { "movb", _REG, _SS }, |
| 120 | { "unF0?", _I8, 0 }, { "unF1?", _I8, 0 }, { "unF2?", _I8, 0 }, { "unF3?", _I8, 0 }, |
| 121 | { "unF4?", _I8, 0 }, { "unF5?", _I8, 0 }, { "unF6?", _I8, 0 }, { "unF7?", _I8, 0 }, |
| 122 | { "unF8?", 0, 0 }, { "unF9?", 0, 0 }, { "unFA?", 0, 0 }, { "unFb?", 0, 0 }, |
| 123 | { "unFC?", 0, 0 }, { "unFD?", 0, 0 }, { "unFE?", 0, 0 }, { "nop", 0, 0 } |
| 124 | }; |
| 125 | |
| 126 | |
| 127 | CPU_DISASSEMBLE( hcd62121 ) |
| 128 | { |
| 129 | UINT8 op, op1=0, op2=0; |
| 130 | int pos = 0; |
| 131 | const hcd62121_dasm *inst; |
| 132 | |
| 133 | op = oprom[pos++]; |
| 134 | |
| 135 | inst = &hcd62121_ops[op]; |
| 136 | |
| 137 | buffer += sprintf(buffer,"%-8s", inst->str); |
| 138 | |
| 139 | switch( inst->arg1 ) |
| 140 | { |
| 141 | case _REGREG: |
| 142 | op1 = oprom[pos++]; |
| 143 | op2 = oprom[pos++]; |
| 144 | if ( op1 & 0x80 ) |
| 145 | { |
| 146 | buffer += sprintf( buffer, "r%02x,0x%02x", op1 & 0x7f, op2 ); |
| 147 | } |
| 148 | else |
| 149 | { |
| 150 | if ( op2 & 0x80 ) |
| 151 | buffer += sprintf( buffer, "r%02x,r%02x", op1 & 0x7f, op2 & 0x7f ); |
| 152 | else |
| 153 | buffer += sprintf( buffer, "r%02x,r%02x", op2 & 0x7f, op1 & 0x7f ); |
| 154 | } |
| 155 | break; |
| 156 | case _REG: |
| 157 | buffer += sprintf( buffer, "r%02x", oprom[pos++] & 0x7f ); |
| 158 | break; |
| 159 | case _IRGREG: |
| 160 | /* bit 6 = direction. 0 - regular, 1 - reverse */ |
| 161 | op1 = oprom[pos++]; |
| 162 | op2 = oprom[pos++]; |
| 163 | if ( op1 & 0x80 ) |
| 164 | { |
| 165 | buffer += sprintf( buffer, "(r%02x),0x%02x", 0x40 | ( op1 & 0x3f ), op2 ); |
| 166 | } |
| 167 | else |
| 168 | { |
| 169 | if ( op2 & 0x80 ) |
| 170 | buffer += sprintf( buffer, "(r%02x%s),r%02x", 0x40 | ( op1 & 0x3f ), (op1 & 0x40) ? ".r" : "", op2 & 0x7f ); |
| 171 | else |
| 172 | buffer += sprintf( buffer, "r%02x,(r%02x%s)", op2 & 0x7f, 0x40 | ( op1 & 0x3f ), (op1 & 0x40) ? ".r" : "" ); |
| 173 | } |
| 174 | break; |
| 175 | case _IRG: |
| 176 | /* bit 6 = direction. 0 - regular, 1 - reverse */ |
| 177 | op1 = oprom[pos++]; |
| 178 | buffer += sprintf( buffer, "(r%02x%s)", 0x40 | ( op1 & 0x3f ), (op1 & 0x40) ? ".r" : "" ); |
| 179 | break; |
| 180 | case _F: |
| 181 | buffer += sprintf( buffer, "F" ); |
| 182 | break; |
| 183 | case _CS: |
| 184 | buffer += sprintf( buffer, "CS" ); |
| 185 | break; |
| 186 | case _DS: |
| 187 | buffer += sprintf( buffer, "DS" ); |
| 188 | break; |
| 189 | case _SS: |
| 190 | buffer += sprintf( buffer, "SS" ); |
| 191 | break; |
| 192 | case _PC: |
| 193 | buffer += sprintf( buffer, "PC" ); |
| 194 | break; |
| 195 | case _SP: |
| 196 | buffer += sprintf( buffer, "SP" ); |
| 197 | break; |
| 198 | case _I8: |
| 199 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 200 | break; |
| 201 | case _I16: |
| 202 | case _A16: |
| 203 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 204 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 205 | break; |
| 206 | case _I64: |
| 207 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 208 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 209 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 210 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 211 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 212 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 213 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 214 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 215 | break; |
| 216 | case _I80: |
| 217 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 218 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 219 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 220 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 221 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 222 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 223 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 224 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 225 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 226 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 227 | break; |
| 228 | case _A24: |
| 229 | buffer += sprintf( buffer, "0x%02x:", oprom[pos++] ); |
| 230 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 231 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 232 | break; |
| 233 | case _ILR: |
| 234 | op1 = oprom[pos++]; |
| 235 | op2 = oprom[pos++]; |
| 236 | if ( op1 & 0x80 ) |
| 237 | { |
| 238 | /* (lar),reg */ |
| 239 | buffer += sprintf( buffer, "(%slar%s),r%02x", (op1 & 0x20) ? ( (op1 & 0x40) ? "--" : "++" ) : "", (op1 & 0x20) ? "" : ( (op1 & 0x40) ? "--" : "++" ), op2 & 0x7f ); |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | /* reg,(lar) */ |
| 244 | buffer += sprintf( buffer, "r%02x,(%slar%s)", op2 & 0x7f, (op1 & 0x20) ? ( (op1 & 0x40) ? "--" : "++" ) : "", (op1 & 0x20) ? "" : ( (op1 & 0x40) ? "--" : "++" ) ); |
| 245 | } |
| 246 | break; |
| 247 | case _LAR: |
| 248 | buffer += sprintf( buffer, "lar" ); |
| 249 | break; |
| 250 | case _DSZ: |
| 251 | buffer += sprintf( buffer, "dsize" ); |
| 252 | break; |
| 253 | case _TIM: |
| 254 | buffer += sprintf( buffer, "TIM?" ); |
| 255 | break; |
| 256 | case _KLO: |
| 257 | buffer += sprintf( buffer, "KOL" ); |
| 258 | break; |
| 259 | case _KHI: |
| 260 | buffer += sprintf( buffer, "KOH" ); |
| 261 | break; |
| 262 | default: |
| 263 | break; |
| 264 | } |
| 265 | |
| 266 | switch( inst->arg2 ) |
| 267 | { |
| 268 | case _REG: |
| 269 | buffer += sprintf( buffer, ",r%02x", oprom[pos++] & 0x7f ); |
| 270 | break; |
| 271 | case _F: |
| 272 | buffer += sprintf( buffer, ",F" ); |
| 273 | break; |
| 274 | case _CS: |
| 275 | buffer += sprintf( buffer, ",CS" ); |
| 276 | break; |
| 277 | case _DS: |
| 278 | buffer += sprintf( buffer, ",DS" ); |
| 279 | break; |
| 280 | case _SS: |
| 281 | buffer += sprintf( buffer, ",SS" ); |
| 282 | break; |
| 283 | case _PC: |
| 284 | buffer += sprintf( buffer, ",PC" ); |
| 285 | break; |
| 286 | case _SP: |
| 287 | buffer += sprintf( buffer, ",SP" ); |
| 288 | break; |
| 289 | case _I8: |
| 290 | buffer += sprintf( buffer, ",0x%02x", oprom[pos++] ); |
| 291 | break; |
| 292 | case _I16: |
| 293 | case _A16: |
| 294 | buffer += sprintf( buffer, ",0x%02x", oprom[pos++] ); |
| 295 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 296 | break; |
| 297 | case _I64: |
| 298 | buffer += sprintf( buffer, ",0x%02x", oprom[pos++] ); |
| 299 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 300 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 301 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 302 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 303 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 304 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 305 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 306 | break; |
| 307 | case _I80: |
| 308 | buffer += sprintf( buffer, ",0x%02x", oprom[pos++] ); |
| 309 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 310 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 311 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 312 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 313 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 314 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 315 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 316 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 317 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 318 | break; |
| 319 | case _A24: |
| 320 | buffer += sprintf( buffer, ",0x%02x:", oprom[pos++] ); |
| 321 | buffer += sprintf( buffer, "0x%02x", oprom[pos++] ); |
| 322 | buffer += sprintf( buffer, "%02x", oprom[pos++] ); |
| 323 | break; |
| 324 | case _ILR: |
| 325 | /* Implemented by _ILR section for arg1 */ |
| 326 | break; |
| 327 | case _LAR: |
| 328 | buffer += sprintf( buffer, ",lar" ); |
| 329 | break; |
| 330 | case _DSZ: |
| 331 | buffer += sprintf( buffer, ",dsize" ); |
| 332 | break; |
| 333 | case _TIM: |
| 334 | buffer += sprintf( buffer, ",TIM?" ); |
| 335 | break; |
| 336 | case _KI: |
| 337 | buffer += sprintf( buffer, ",KI" ); |
| 338 | break; |
| 339 | case _4: |
| 340 | buffer += sprintf( buffer, ",4" ); |
| 341 | break; |
| 342 | default: |
| 343 | break; |
| 344 | } |
| 345 | |
| 346 | return pos | DASMFLAG_SUPPORTED; |
| 347 | } |
| 348 | |
src/emu/cpu/hcd62121/hcd62121_ops.h
| r0 | r8064 | |
| 1 | |
| 2 | #define HCD62121_MSK \ |
| 3 | { \ |
| 4 | int i; \ |
| 5 | UINT8 mskres = 1; \ |
| 6 | \ |
| 7 | for ( i = 0; i < size; i++ ) \ |
| 8 | { \ |
| 9 | if ( ( cpustate->temp1[i] & cpustate->temp2[i] ) != cpustate->temp2[i] ) \ |
| 10 | mskres = 0; \ |
| 11 | } \ |
| 12 | \ |
| 13 | if ( mskres ) \ |
| 14 | cpustate->f &= ~_FLAG_Z; \ |
| 15 | else \ |
| 16 | cpustate->f |= _FLAG_Z; \ |
| 17 | } |
| 18 | |
| 19 | #define HCD62121_IMSK \ |
| 20 | { \ |
| 21 | int i; \ |
| 22 | UINT8 mskres = 1; \ |
| 23 | UINT8 set_zero = 0; \ |
| 24 | \ |
| 25 | for ( i = 0; i < size; i++ ) \ |
| 26 | { \ |
| 27 | if ( ( cpustate->temp1[i] & ~cpustate->temp2[i] ) != ~cpustate->temp2[i] ) \ |
| 28 | mskres = 0; \ |
| 29 | if ( cpustate->temp1[i] | cpustate->temp2[i] ) \ |
| 30 | set_zero = 1; \ |
| 31 | } \ |
| 32 | \ |
| 33 | if ( set_zero ) \ |
| 34 | cpustate->f |= _FLAG_Z; \ |
| 35 | else \ |
| 36 | cpustate->f &= ~_FLAG_Z; \ |
| 37 | \ |
| 38 | if ( mskres ) \ |
| 39 | cpustate->f &= ~_FLAG_C; \ |
| 40 | else \ |
| 41 | cpustate->f |= _FLAG_C; \ |
| 42 | } |
| 43 | |
| 44 | |
| 45 | #define HCD62121_AND \ |
| 46 | { \ |
| 47 | int i; \ |
| 48 | UINT8 is_zero = 1; \ |
| 49 | \ |
| 50 | for ( i = 0; i < size; i++ ) \ |
| 51 | { \ |
| 52 | cpustate->temp1[i] = cpustate->temp1[i] & cpustate->temp2[i]; \ |
| 53 | if ( cpustate->temp1[i] ) \ |
| 54 | is_zero = 0; \ |
| 55 | } \ |
| 56 | \ |
| 57 | if ( is_zero ) \ |
| 58 | cpustate->f |= _FLAG_Z; \ |
| 59 | else \ |
| 60 | cpustate->f &= ~_FLAG_Z; \ |
| 61 | \ |
| 62 | if ( cpustate->temp1[0] & 0x0f ) \ |
| 63 | cpustate->f &= ~_FLAG_ZL; \ |
| 64 | else \ |
| 65 | cpustate->f |= _FLAG_ZL; \ |
| 66 | \ |
| 67 | if ( cpustate->temp1[0] & 0xf0 ) \ |
| 68 | cpustate->f &= ~_FLAG_ZH; \ |
| 69 | else \ |
| 70 | cpustate->f |= _FLAG_ZH; \ |
| 71 | } |
| 72 | |
| 73 | #define HCD62121_OR \ |
| 74 | { \ |
| 75 | int i; \ |
| 76 | UINT8 is_zero = 1; \ |
| 77 | \ |
| 78 | for ( i = 0; i < size; i++ ) \ |
| 79 | { \ |
| 80 | cpustate->temp1[i] = cpustate->temp1[i] | cpustate->temp2[i]; \ |
| 81 | if ( cpustate->temp1[i] ) \ |
| 82 | is_zero = 0; \ |
| 83 | } \ |
| 84 | \ |
| 85 | if ( is_zero ) \ |
| 86 | cpustate->f |= _FLAG_Z; \ |
| 87 | else \ |
| 88 | cpustate->f &= ~_FLAG_Z; \ |
| 89 | \ |
| 90 | if ( cpustate->temp1[0] & 0x0f ) \ |
| 91 | cpustate->f &= ~_FLAG_ZL; \ |
| 92 | else \ |
| 93 | cpustate->f |= _FLAG_ZL; \ |
| 94 | \ |
| 95 | if ( cpustate->temp1[0] & 0xf0 ) \ |
| 96 | cpustate->f &= ~_FLAG_ZH; \ |
| 97 | else \ |
| 98 | cpustate->f |= _FLAG_ZH; \ |
| 99 | } |
| 100 | |
| 101 | #define HCD62121_ADD \ |
| 102 | { \ |
| 103 | int i; \ |
| 104 | UINT8 is_zero = 1, carry = 0; \ |
| 105 | \ |
| 106 | if ( ( cpustate->temp1[0] & 0x0f ) + ( cpustate->temp2[0] & 0x0f ) > 15 ) \ |
| 107 | cpustate->f |= _FLAG_CL; \ |
| 108 | else \ |
| 109 | cpustate->f &= ~_FLAG_CL; \ |
| 110 | \ |
| 111 | for ( i = 0; i < size; i++ ) \ |
| 112 | { \ |
| 113 | UINT16 res = cpustate->temp1[i] + cpustate->temp2[i] + carry; \ |
| 114 | \ |
| 115 | cpustate->temp1[i] = res & 0xff; \ |
| 116 | if ( cpustate->temp1[i] ) \ |
| 117 | is_zero = 0; \ |
| 118 | \ |
| 119 | carry = ( res & 0xff00 ) ? 1 : 0; \ |
| 120 | } \ |
| 121 | \ |
| 122 | if ( is_zero ) \ |
| 123 | cpustate->f |= _FLAG_Z; \ |
| 124 | else \ |
| 125 | cpustate->f &= ~_FLAG_Z; \ |
| 126 | \ |
| 127 | if ( carry ) \ |
| 128 | cpustate->f |= _FLAG_C; \ |
| 129 | else \ |
| 130 | cpustate->f &= ~_FLAG_C; \ |
| 131 | \ |
| 132 | if ( cpustate->temp1[0] & 0x0f ) \ |
| 133 | cpustate->f &= ~_FLAG_ZL; \ |
| 134 | else \ |
| 135 | cpustate->f |= _FLAG_ZL; \ |
| 136 | \ |
| 137 | if ( cpustate->temp1[0] & 0xf0 ) \ |
| 138 | cpustate->f &= ~_FLAG_ZH; \ |
| 139 | else \ |
| 140 | cpustate->f |= _FLAG_ZH; \ |
| 141 | } |
| 142 | |
| 143 | /* BCD ADD */ |
| 144 | #define HCD62121_ADDB \ |
| 145 | { \ |
| 146 | int i; \ |
| 147 | UINT8 is_zero = 1, carry = 0; \ |
| 148 | \ |
| 149 | if ( ( cpustate->temp1[0] & 0x0f ) + ( cpustate->temp2[0] & 0x0f ) > 9 ) \ |
| 150 | cpustate->f |= _FLAG_CL; \ |
| 151 | else \ |
| 152 | cpustate->f &= ~_FLAG_CL; \ |
| 153 | \ |
| 154 | for ( i = 0; i < size; i++ ) \ |
| 155 | { \ |
| 156 | UINT16 res = ( cpustate->temp1[i] & 0x0f ) + ( cpustate->temp2[i] & 0x0f ) + carry; \ |
| 157 | \ |
| 158 | carry = 0; \ |
| 159 | if ( res > 9 ) \ |
| 160 | { \ |
| 161 | res += 6; \ |
| 162 | } \ |
| 163 | res += ( cpustate->temp1[i] & 0xf0 ) + ( cpustate->temp2[i] & 0xf0 ); \ |
| 164 | if ( res > 0x9f ) \ |
| 165 | { \ |
| 166 | res += 0x60; \ |
| 167 | } \ |
| 168 | cpustate->temp1[i] = res & 0xff; \ |
| 169 | if ( cpustate->temp1[i] ) \ |
| 170 | is_zero = 0; \ |
| 171 | \ |
| 172 | carry = ( res & 0xff00 ) ? 1 : 0; \ |
| 173 | } \ |
| 174 | \ |
| 175 | if ( is_zero ) \ |
| 176 | cpustate->f |= _FLAG_Z; \ |
| 177 | else \ |
| 178 | cpustate->f &= ~_FLAG_Z; \ |
| 179 | \ |
| 180 | if ( carry ) \ |
| 181 | cpustate->f |= _FLAG_C; \ |
| 182 | else \ |
| 183 | cpustate->f &= ~_FLAG_C; \ |
| 184 | \ |
| 185 | if ( cpustate->temp1[0] & 0x0f ) \ |
| 186 | cpustate->f &= ~_FLAG_ZL; \ |
| 187 | else \ |
| 188 | cpustate->f |= _FLAG_ZL; \ |
| 189 | \ |
| 190 | if ( cpustate->temp1[0] & 0xf0 ) \ |
| 191 | cpustate->f &= ~_FLAG_ZH; \ |
| 192 | else \ |
| 193 | cpustate->f |= _FLAG_ZH; \ |
| 194 | } |
| 195 | |
| 196 | #define HCD62121_SUB \ |
| 197 | { \ |
| 198 | int i; \ |
| 199 | UINT8 is_zero = 1, carry = 0; \ |
| 200 | \ |
| 201 | if ( ( cpustate->temp1[0] & 0x0f ) < ( cpustate->temp2[0] & 0x0f ) ) \ |
| 202 | cpustate->f |= _FLAG_CL; \ |
| 203 | else \ |
| 204 | cpustate->f &= ~_FLAG_CL; \ |
| 205 | \ |
| 206 | for ( i = 0; i < size; i++ ) \ |
| 207 | { \ |
| 208 | UINT16 res = cpustate->temp1[i] - cpustate->temp2[i] - carry; \ |
| 209 | \ |
| 210 | cpustate->temp1[i] = res & 0xff; \ |
| 211 | if ( cpustate->temp1[i] ) \ |
| 212 | is_zero = 0; \ |
| 213 | \ |
| 214 | carry = ( res & 0xff00 ) ? 1 : 0; \ |
| 215 | } \ |
| 216 | \ |
| 217 | if ( is_zero ) \ |
| 218 | cpustate->f |= _FLAG_Z; \ |
| 219 | else \ |
| 220 | cpustate->f &= ~_FLAG_Z; \ |
| 221 | \ |
| 222 | if ( carry ) \ |
| 223 | cpustate->f |= _FLAG_C; \ |
| 224 | else \ |
| 225 | cpustate->f &= ~_FLAG_C; \ |
| 226 | \ |
| 227 | if ( cpustate->temp1[0] & 0x0f ) \ |
| 228 | cpustate->f &= ~_FLAG_ZL; \ |
| 229 | else \ |
| 230 | cpustate->f |= _FLAG_ZL; \ |
| 231 | \ |
| 232 | if ( cpustate->temp1[0] & 0xf0 ) \ |
| 233 | cpustate->f &= ~_FLAG_ZH; \ |
| 234 | else \ |
| 235 | cpustate->f |= _FLAG_ZH; \ |
| 236 | } |
| 237 | |
| 238 | #define HCD62121_PUSHW(source) \ |
| 239 | { \ |
| 240 | UINT16 address = source; \ |
| 241 | mem_writebyte( cpustate, ( cpustate->sseg << 16 ) | cpustate->sp, ( address ) & 0xff ); \ |
| 242 | cpustate->sp--; \ |
| 243 | mem_writebyte( cpustate, ( cpustate->sseg << 16 ) | cpustate->sp, ( address ) >> 8 ); \ |
| 244 | cpustate->sp--; \ |
| 245 | } |
| 246 | |
| 247 | #define HCD62121_POPW(dest) \ |
| 248 | { \ |
| 249 | UINT16 res; \ |
| 250 | cpustate->sp++; \ |
| 251 | res = mem_readbyte( cpustate, ( cpustate->sseg << 16 ) | cpustate->sp ) << 8; \ |
| 252 | cpustate->sp++; \ |
| 253 | res |= mem_readbyte( cpustate, ( cpustate->sseg << 16 ) | cpustate->sp ); \ |
| 254 | dest = res; \ |
| 255 | } |
| 256 | |
| 257 | case 0x04: /* mskb r1,r2 */ |
| 258 | case 0x05: /* mskw r1,r2 */ |
| 259 | case 0x06: /* mskq r1,r2 */ |
| 260 | case 0x07: /* mskt r1,r2 */ |
| 261 | { |
| 262 | int size = datasize( cpustate, op ); |
| 263 | UINT8 reg1 = read_op( cpustate ); |
| 264 | UINT8 reg2 = read_op( cpustate ); |
| 265 | |
| 266 | read_regreg( cpustate, size, reg1, reg2 ); |
| 267 | |
| 268 | HCD62121_MSK; |
| 269 | } |
| 270 | break; |
| 271 | |
| 272 | case 0x08: /* shrb r1 */ |
| 273 | case 0x09: /* shrb r1 */ |
| 274 | case 0x0A: /* shrq r1 */ |
| 275 | case 0x0B: /* shrt r1 */ |
| 276 | /* Shift is a nibble shift! */ |
| 277 | { |
| 278 | int i; |
| 279 | int size = datasize( cpustate, op ); |
| 280 | UINT8 reg1 = read_op( cpustate ); |
| 281 | UINT8 d1 = 0, d2 = 0; |
| 282 | |
| 283 | read_reg( cpustate, size, reg1 ); |
| 284 | |
| 285 | for ( i = 0; i < size; i++ ) |
| 286 | { |
| 287 | d1 = ( cpustate->temp1[i] & 0x0f ) << 4; |
| 288 | cpustate->temp1[i] = ( cpustate->temp1[i] >> 4 ) | d2; |
| 289 | d2 = d1; |
| 290 | } |
| 291 | |
| 292 | write_reg( cpustate, size, reg1 ); |
| 293 | } |
| 294 | break; |
| 295 | |
| 296 | case 0x0C: /* testb r1,r2 */ |
| 297 | case 0x0D: /* testw r1,r2 */ |
| 298 | case 0x0E: /* testq r1,r2 */ |
| 299 | case 0x0F: /* testt r1,r2 */ |
| 300 | { |
| 301 | int size = datasize( cpustate, op ); |
| 302 | UINT8 reg1 = read_op( cpustate ); |
| 303 | UINT8 reg2 = read_op( cpustate ); |
| 304 | |
| 305 | read_regreg( cpustate, size, reg1, reg2 ); |
| 306 | |
| 307 | HCD62121_AND; |
| 308 | } |
| 309 | break; |
| 310 | |
| 311 | case 0x14: /* cmpb r1,r2 */ |
| 312 | case 0x15: /* cmpw r1,r2 */ |
| 313 | case 0x16: /* cmpq r1,r2 */ |
| 314 | case 0x17: /* cmpt r1,r2 */ |
| 315 | { |
| 316 | int size = datasize( cpustate, op ); |
| 317 | UINT8 reg1 = read_op( cpustate ); |
| 318 | UINT8 reg2 = read_op( cpustate ); |
| 319 | |
| 320 | read_regreg( cpustate, size, reg1, reg2 ); |
| 321 | |
| 322 | HCD62121_SUB; |
| 323 | } |
| 324 | break; |
| 325 | |
| 326 | case 0x18: /* movb r1,r2 */ |
| 327 | case 0x19: /* movw r1,r2 */ |
| 328 | case 0x1A: /* movq r1,r2 */ |
| 329 | case 0x1B: /* movt r1,r2 */ |
| 330 | { |
| 331 | int i; |
| 332 | int size = datasize( cpustate, op ); |
| 333 | UINT8 reg1 = read_op( cpustate ); |
| 334 | UINT8 reg2 = read_op( cpustate ); |
| 335 | |
| 336 | read_regreg( cpustate, size, reg1, reg2 ); |
| 337 | |
| 338 | for ( i = 0; i < size; i++ ) |
| 339 | cpustate->temp1[i] = cpustate->temp2[i]; |
| 340 | |
| 341 | write_regreg( cpustate, size, reg1, reg2 ); |
| 342 | } |
| 343 | break; |
| 344 | |
| 345 | case 0x1C: /* imskb r1,r2 */ |
| 346 | case 0x1D: /* imskw r1,r2 */ |
| 347 | case 0x1E: /* imskq r1,r2 */ |
| 348 | case 0x1F: /* imskt r1,r2 */ |
| 349 | { |
| 350 | int size = datasize( cpustate, op ); |
| 351 | UINT8 reg1 = read_op( cpustate ); |
| 352 | UINT8 reg2 = read_op( cpustate ); |
| 353 | |
| 354 | read_regreg( cpustate, size, reg1, reg2 ); |
| 355 | |
| 356 | HCD62121_IMSK; |
| 357 | } |
| 358 | break; |
| 359 | |
| 360 | case 0x20: /* shrb r1 */ |
| 361 | case 0x21: /* shrw r1 */ |
| 362 | case 0x22: /* shrq r1 */ |
| 363 | case 0x23: /* shrt r1 */ |
| 364 | /* Shift is a single shift! */ |
| 365 | { |
| 366 | int i; |
| 367 | int size = datasize( cpustate, op ); |
| 368 | UINT8 reg1 = read_op( cpustate ); |
| 369 | UINT8 d1 = 0, d2 = 0; |
| 370 | |
| 371 | read_reg( cpustate, size, reg1 ); |
| 372 | |
| 373 | for ( i = 0; i < size; i++ ) |
| 374 | { |
| 375 | d1 = ( cpustate->temp1[i] & 0x01 ) << 7; |
| 376 | cpustate->temp1[i] = ( cpustate->temp1[i] >> 1 ) | d2; |
| 377 | d2 = d1; |
| 378 | } |
| 379 | |
| 380 | write_reg( cpustate, size, reg1 ); |
| 381 | } |
| 382 | break; |
| 383 | |
| 384 | case 0x24: /* orb r1,r2 */ |
| 385 | case 0x25: /* orb r1,r2 */ |
| 386 | case 0x26: /* orb r1,r2 */ |
| 387 | case 0x27: /* orb r1,r2 */ |
| 388 | { |
| 389 | int size = datasize( cpustate, op ); |
| 390 | UINT8 reg1 = read_op( cpustate ); |
| 391 | UINT8 reg2 = read_op( cpustate ); |
| 392 | |
| 393 | read_regreg( cpustate, size, reg1, reg2 ); |
| 394 | |
| 395 | HCD62121_OR; |
| 396 | |
| 397 | write_regreg( cpustate, size, reg1, reg2 ); |
| 398 | } |
| 399 | break; |
| 400 | |
| 401 | case 0x28: /* shlb r1 */ |
| 402 | case 0x29: /* shlw r1 */ |
| 403 | case 0x2A: /* shlq r1 */ |
| 404 | case 0x2B: /* shlt r1 */ |
| 405 | /* Shift is a single shift! */ |
| 406 | { |
| 407 | int i; |
| 408 | int size = datasize( cpustate, op ); |
| 409 | UINT8 reg1 = read_op( cpustate ); |
| 410 | UINT8 d1 = 0, d2 = 0; |
| 411 | |
| 412 | read_reg( cpustate, size, reg1 ); |
| 413 | |
| 414 | for ( i = 0; i < size; i++ ) |
| 415 | { |
| 416 | d1 = ( cpustate->temp1[i] & 0x80 ) >> 7; |
| 417 | cpustate->temp1[i] = ( cpustate->temp1[i] << 1 ) | d2; |
| 418 | d2 = d1; |
| 419 | } |
| 420 | |
| 421 | write_reg( cpustate, size, reg1 ); |
| 422 | } |
| 423 | break; |
| 424 | |
| 425 | case 0x2C: /* andb r1,r2 */ |
| 426 | case 0x2D: /* andw r1,r2 */ |
| 427 | case 0x2E: /* andq r1,r2 */ |
| 428 | case 0x2F: /* andt r1,r2 */ |
| 429 | { |
| 430 | int size = datasize( cpustate, op ); |
| 431 | UINT8 reg1 = read_op( cpustate ); |
| 432 | UINT8 reg2 = read_op( cpustate ); |
| 433 | |
| 434 | read_regreg( cpustate, size, reg1, reg2 ); |
| 435 | |
| 436 | HCD62121_AND; |
| 437 | |
| 438 | write_regreg( cpustate, size, reg1, reg2 ); |
| 439 | } |
| 440 | break; |
| 441 | |
| 442 | case 0x34: /* subb r1,r2 */ |
| 443 | case 0x35: /* subw r1,r2 */ |
| 444 | case 0x36: /* subq r1,r2 */ |
| 445 | case 0x37: /* subt r1,r2 */ |
| 446 | { |
| 447 | int size = datasize( cpustate, op ); |
| 448 | UINT8 reg1 = read_op( cpustate ); |
| 449 | UINT8 reg2 = read_op( cpustate ); |
| 450 | |
| 451 | read_regreg( cpustate, size, reg1, reg2 ); |
| 452 | |
| 453 | HCD62121_SUB; |
| 454 | |
| 455 | write_regreg( cpustate, size, reg1, reg2 ); |
| 456 | } |
| 457 | break; |
| 458 | |
| 459 | case 0x38: /* adbb r1,r2 */ |
| 460 | case 0x39: /* adbw r1,r2 */ |
| 461 | case 0x3A: /* adbq r1,r2 */ |
| 462 | case 0x3B: /* adbt r1,r2 */ |
| 463 | { |
| 464 | int size = datasize( cpustate, op ); |
| 465 | UINT8 reg1 = read_op( cpustate ); |
| 466 | UINT8 reg2 = read_op( cpustate ); |
| 467 | |
| 468 | read_regreg( cpustate, size, reg1, reg2 ); |
| 469 | |
| 470 | HCD62121_ADDB; |
| 471 | |
| 472 | write_regreg( cpustate, size, reg1, reg2 ); |
| 473 | } |
| 474 | break; |
| 475 | |
| 476 | case 0x3C: /* addb r1,r2 */ |
| 477 | case 0x3D: /* addw r1,r2 */ |
| 478 | case 0x3E: /* addq r1,r2 */ |
| 479 | case 0x3F: /* addt r1,r2 */ |
| 480 | { |
| 481 | int size = datasize( cpustate, op ); |
| 482 | UINT8 reg1 = read_op( cpustate ); |
| 483 | UINT8 reg2 = read_op( cpustate ); |
| 484 | |
| 485 | read_regreg( cpustate, size, reg1, reg2 ); |
| 486 | |
| 487 | HCD62121_ADD; |
| 488 | |
| 489 | write_regreg( cpustate, size, reg1, reg2 ); |
| 490 | } |
| 491 | break; |
| 492 | |
| 493 | case 0x4C: /* testb ir1,r2 */ |
| 494 | case 0x4D: /* testw ir1,r2 */ |
| 495 | case 0x4E: /* testq ir1,r2 */ |
| 496 | case 0x4F: /* testt ir1,r2 */ |
| 497 | { |
| 498 | int size = datasize( cpustate, op ); |
| 499 | UINT8 reg1 = read_op( cpustate ); |
| 500 | UINT8 reg2 = read_op( cpustate ); |
| 501 | |
| 502 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 503 | |
| 504 | HCD62121_AND; |
| 505 | } |
| 506 | break; |
| 507 | |
| 508 | case 0x54: /* cmpb ir1,r2 */ |
| 509 | case 0x55: /* cmpw ir1,r2 */ |
| 510 | case 0x56: /* cmpq ir1,r2 */ |
| 511 | case 0x57: /* cmpt ir1,r2 */ |
| 512 | { |
| 513 | int size = datasize( cpustate, op ); |
| 514 | UINT8 reg1 = read_op( cpustate ); |
| 515 | UINT8 reg2 = read_op( cpustate ); |
| 516 | |
| 517 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 518 | |
| 519 | HCD62121_SUB; |
| 520 | } |
| 521 | break; |
| 522 | |
| 523 | case 0x58: /* movb ir1,r2 */ |
| 524 | case 0x59: /* movw ir1,r2 */ |
| 525 | case 0x5A: /* movq ir1,r2 */ |
| 526 | case 0x5B: /* movt ir1,r2 */ |
| 527 | { |
| 528 | int i; |
| 529 | int size = datasize( cpustate, op ); |
| 530 | UINT8 reg1 = read_op( cpustate ); |
| 531 | UINT8 reg2 = read_op( cpustate ); |
| 532 | |
| 533 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 534 | |
| 535 | for ( i = 0; i < size; i++ ) |
| 536 | cpustate->temp1[i] = cpustate->temp2[i]; |
| 537 | |
| 538 | write_iregreg( cpustate, size, reg1, reg2 ); |
| 539 | } |
| 540 | break; |
| 541 | |
| 542 | case 0x64: /* orb ir1,r2 */ |
| 543 | case 0x65: /* orb ir1,r2 */ |
| 544 | case 0x66: /* orb ir1,r2 */ |
| 545 | case 0x67: /* orb ir1,r2 */ |
| 546 | { |
| 547 | int size = datasize( cpustate, op ); |
| 548 | UINT8 reg1 = read_op( cpustate ); |
| 549 | UINT8 reg2 = read_op( cpustate ); |
| 550 | |
| 551 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 552 | |
| 553 | HCD62121_OR; |
| 554 | |
| 555 | write_iregreg( cpustate, size, reg1, reg2 ); |
| 556 | } |
| 557 | break; |
| 558 | |
| 559 | case 0x6C: /* andb ir1,r2 */ |
| 560 | case 0x6D: /* andw ir1,r2 */ |
| 561 | case 0x6E: /* andq ir1,r2 */ |
| 562 | case 0x6F: /* andt ir1,r2 */ |
| 563 | { |
| 564 | int size = datasize( cpustate, op ); |
| 565 | UINT8 reg1 = read_op( cpustate ); |
| 566 | UINT8 reg2 = read_op( cpustate ); |
| 567 | |
| 568 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 569 | |
| 570 | HCD62121_AND; |
| 571 | |
| 572 | write_iregreg( cpustate, size, reg1, reg2 ); |
| 573 | } |
| 574 | break; |
| 575 | |
| 576 | case 0x7C: /* addb ir1,r2 */ |
| 577 | case 0x7D: /* addw ir1,r2 */ |
| 578 | case 0x7E: /* addq ir1,r2 */ |
| 579 | case 0x7F: /* addt ir1,r2 */ |
| 580 | { |
| 581 | int size = datasize( cpustate, op ); |
| 582 | UINT8 reg1 = read_op( cpustate ); |
| 583 | UINT8 reg2 = read_op( cpustate ); |
| 584 | |
| 585 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 586 | |
| 587 | HCD62121_ADD; |
| 588 | |
| 589 | write_iregreg( cpustate, size, reg1, reg2 ); |
| 590 | } |
| 591 | break; |
| 592 | |
| 593 | case 0x88: /* jump _a16 */ |
| 594 | cpustate->ip = ( read_op( cpustate ) << 8 ) | read_op( cpustate ); |
| 595 | break; |
| 596 | |
| 597 | case 0x89: /* jumpf cs:a16 */ |
| 598 | { |
| 599 | UINT8 cs = read_op( cpustate ); |
| 600 | UINT8 a1 = read_op( cpustate ); |
| 601 | UINT8 a2 = read_op( cpustate ); |
| 602 | |
| 603 | cpustate->cseg = cs; |
| 604 | cpustate->ip = ( a1 << 8 ) | a2; |
| 605 | } |
| 606 | break; |
| 607 | |
| 608 | case 0x8A: /* call a16 */ |
| 609 | { |
| 610 | UINT8 a1 = read_op( cpustate ); |
| 611 | UINT8 a2 = read_op( cpustate ); |
| 612 | |
| 613 | HCD62121_PUSHW( cpustate->ip ); |
| 614 | |
| 615 | cpustate->ip = ( a1 << 8 ) | a2; |
| 616 | } |
| 617 | break; |
| 618 | |
| 619 | case 0x8C: /* unk_8C */ |
| 620 | case 0x8D: /* unk_8D */ |
| 621 | case 0x8E: /* unk_8E */ |
| 622 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 623 | break; |
| 624 | |
| 625 | case 0x90: /* retzh */ |
| 626 | case 0x91: /* retzl */ |
| 627 | case 0x92: /* retc */ |
| 628 | case 0x93: /* retz */ |
| 629 | case 0x94: /* retzc */ |
| 630 | case 0x95: /* retcl */ |
| 631 | case 0x96: /* retnc */ |
| 632 | case 0x97: /* retnz */ |
| 633 | if ( check_cond( cpustate, op ) ) |
| 634 | HCD62121_POPW( cpustate->ip ); |
| 635 | break; |
| 636 | |
| 637 | case 0x98: /* jump (r1) */ |
| 638 | { |
| 639 | UINT8 reg1 = read_op( cpustate ); |
| 640 | UINT16 ad = cpustate->reg[ ( reg1 | 0x40 ) & 0x7f ] << 8; |
| 641 | |
| 642 | if ( reg1 & 0x40 ) |
| 643 | ad |= cpustate->reg[ ( ( reg1 - 1 ) | 0x40 ) & 0x7f ]; |
| 644 | else |
| 645 | ad |= cpustate->reg[ ( ( reg1 + 1 ) | 0x40 ) & 0x7f ]; |
| 646 | |
| 647 | cpustate->ip = ad; |
| 648 | } |
| 649 | break; |
| 650 | |
| 651 | case 0x9F: /* ret */ |
| 652 | HCD62121_POPW( cpustate->ip ); |
| 653 | break; |
| 654 | |
| 655 | case 0xA0: /* jmpzh a16 */ |
| 656 | case 0xA1: /* jmpzl a16 */ |
| 657 | case 0xA2: /* jmpc a16 */ |
| 658 | case 0xA3: /* jmpz a16 */ |
| 659 | case 0xA4: /* jmpzc a16 */ |
| 660 | case 0xA5: /* jmpcl a16 */ |
| 661 | case 0xA6: /* jmpnc a16 */ |
| 662 | case 0xA7: /* jmpnz a16 */ |
| 663 | { |
| 664 | UINT8 a1 = read_op( cpustate ); |
| 665 | UINT8 a2 = read_op( cpustate ); |
| 666 | |
| 667 | if ( check_cond( cpustate, op ) ) |
| 668 | cpustate->ip = ( a1 << 8 ) | a2; |
| 669 | } |
| 670 | break; |
| 671 | |
| 672 | case 0xA8: /* callzh a16 */ |
| 673 | case 0xA9: /* callzl a16 */ |
| 674 | case 0xAA: /* callc a16 */ |
| 675 | case 0xAB: /* callz a16 */ |
| 676 | case 0xAC: /* callzc a16 */ |
| 677 | case 0xAD: /* callcl a16 */ |
| 678 | case 0xAE: /* callnc a16 */ |
| 679 | case 0xAF: /* callnz a16 */ |
| 680 | { |
| 681 | UINT8 a1 = read_op( cpustate ); |
| 682 | UINT8 a2 = read_op( cpustate ); |
| 683 | |
| 684 | if ( check_cond( cpustate, op ) ) |
| 685 | { |
| 686 | HCD62121_PUSHW( cpustate->ip ); |
| 687 | |
| 688 | cpustate->ip = ( a1 << 8 ) | a2; |
| 689 | } |
| 690 | } |
| 691 | break; |
| 692 | |
| 693 | case 0xB1: /* unk_B1 reg/i8 */ |
| 694 | case 0xB3: /* unk_B3 reg/i8 */ |
| 695 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 696 | read_op( cpustate ); |
| 697 | break; |
| 698 | |
| 699 | case 0xB4: /* out koh,reg */ |
| 700 | io_writebyte( cpustate, HCD62121_KOH, cpustate->reg[ read_op( cpustate ) & 0x7f ] ); |
| 701 | break; |
| 702 | |
| 703 | case 0xB5: /* out koh,i8 */ |
| 704 | io_writebyte( cpustate, HCD62121_KOH, read_op( cpustate ) ); |
| 705 | break; |
| 706 | |
| 707 | case 0xB6: /* out kol,reg */ |
| 708 | io_writebyte( cpustate, HCD62121_KOL, cpustate->reg[ read_op( cpustate ) & 0x7f ] ); |
| 709 | break; |
| 710 | |
| 711 | case 0xB7: /* out kol,i8 */ |
| 712 | io_writebyte( cpustate, HCD62121_KOL, read_op( cpustate ) ); |
| 713 | break; |
| 714 | |
| 715 | case 0xB9: /* unk_B9 reg/i8 */ |
| 716 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 717 | read_op( cpustate ); |
| 718 | break; |
| 719 | |
| 720 | case 0xBB: /* jmpcl? a16 */ |
| 721 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 722 | { |
| 723 | UINT8 a1 = read_op( cpustate ); |
| 724 | UINT8 a2 = read_op( cpustate ); |
| 725 | |
| 726 | if ( cpustate->f & _FLAG_CL ) |
| 727 | cpustate->ip = ( a1 << 8 ) | a2; |
| 728 | } |
| 729 | break; |
| 730 | |
| 731 | case 0xBF: /* jmpncl? a16 */ |
| 732 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 733 | { |
| 734 | UINT8 a1 = read_op( cpustate ); |
| 735 | UINT8 a2 = read_op( cpustate ); |
| 736 | |
| 737 | if ( ! ( cpustate->f & _FLAG_CL ) ) |
| 738 | cpustate->ip = ( a1 << 8 ) | a2; |
| 739 | } |
| 740 | break; |
| 741 | |
| 742 | case 0xC0: /* movb reg,i8 */ |
| 743 | case 0xC1: /* movw reg,i16 */ |
| 744 | case 0xC2: /* movw reg,i64 */ |
| 745 | case 0xC3: /* movw reg,i80 */ |
| 746 | { |
| 747 | int i; |
| 748 | int size = datasize( cpustate, op ); |
| 749 | UINT8 reg = read_op( cpustate ); |
| 750 | |
| 751 | for( i = 0; i < size; i++ ) |
| 752 | { |
| 753 | cpustate->reg[(reg + i) & 0x7f] = read_op( cpustate ); |
| 754 | } |
| 755 | } |
| 756 | break; |
| 757 | |
| 758 | case 0xC4: /* movb (lar),r1 / r1,(lar) */ |
| 759 | case 0xC5: /* movw (lar),r1 / r1,(lar) */ |
| 760 | case 0xC6: /* movq (lar),r1 / r1,(lar) */ |
| 761 | case 0xC7: /* movt (lar),r1 / r1,(lar) */ |
| 762 | { |
| 763 | int i; |
| 764 | int size = datasize( cpustate, op ); |
| 765 | UINT8 reg1 = read_op( cpustate ); |
| 766 | UINT8 reg2 = read_op( cpustate ); |
| 767 | int pre_inc = 0; |
| 768 | int post_inc = 1; |
| 769 | |
| 770 | switch( reg1 & 0x60 ) |
| 771 | { |
| 772 | case 0x00: |
| 773 | pre_inc = 0; |
| 774 | post_inc = 1; |
| 775 | break; |
| 776 | case 0x20: |
| 777 | pre_inc = 1; |
| 778 | post_inc = 0; |
| 779 | break; |
| 780 | case 0x40: |
| 781 | pre_inc = 0; |
| 782 | post_inc = -1; |
| 783 | break; |
| 784 | case 0x60: |
| 785 | pre_inc = -1; |
| 786 | post_inc = 0; |
| 787 | break; |
| 788 | } |
| 789 | |
| 790 | if ( reg1 & 0x80 ) |
| 791 | { |
| 792 | /* (lar) <- r1 */ |
| 793 | for ( i = 0; i < size; i++ ) |
| 794 | { |
| 795 | cpustate->lar += pre_inc; |
| 796 | mem_writebyte( cpustate, ( cpustate->dseg << 16 ) | cpustate->lar, cpustate->reg[ ( reg2 + i ) & 0x7f ] ); |
| 797 | cpustate->lar += post_inc; |
| 798 | } |
| 799 | } |
| 800 | else |
| 801 | { |
| 802 | /* r1 <- (lar) */ |
| 803 | for ( i = 0; i < size; i++ ) |
| 804 | { |
| 805 | cpustate->lar += pre_inc; |
| 806 | cpustate->reg[ ( reg2 + i ) & 0x7f ] = mem_readbyte( cpustate, ( cpustate->dseg << 16 ) | cpustate->lar ); |
| 807 | cpustate->lar += post_inc; |
| 808 | } |
| 809 | } |
| 810 | } |
| 811 | break; |
| 812 | |
| 813 | case 0xCC: /* swapb ir1,r2 */ |
| 814 | case 0xCD: /* swapw ir1,r2 */ |
| 815 | case 0xCE: /* swapq ir1,r2 */ |
| 816 | case 0xCF: /* swapt ir1,r2? */ |
| 817 | { |
| 818 | int i; |
| 819 | int size = datasize( cpustate, op ); |
| 820 | UINT8 reg1 = read_op( cpustate ); |
| 821 | UINT8 reg2 = read_op( cpustate ); |
| 822 | |
| 823 | read_iregreg( cpustate, size, reg1, reg2 ); |
| 824 | |
| 825 | for ( i = 0; i < size; i++ ) |
| 826 | { |
| 827 | UINT8 d = cpustate->temp1[i]; |
| 828 | cpustate->temp1[i] = cpustate->temp2[i]; |
| 829 | cpustate->temp2[i] = d; |
| 830 | } |
| 831 | |
| 832 | write_iregreg( cpustate, size, reg1, reg2 ); |
| 833 | write_iregreg2( cpustate, size, reg1, reg2 ); |
| 834 | } |
| 835 | break; |
| 836 | |
| 837 | case 0xD0: /* movb cs,reg */ |
| 838 | cpustate->cseg = cpustate->reg[ read_op( cpustate ) & 0x7f ]; |
| 839 | break; |
| 840 | |
| 841 | case 0xD1: /* movb cs,i8 */ |
| 842 | cpustate->cseg = read_op( cpustate ); |
| 843 | break; |
| 844 | |
| 845 | case 0xD2: /* movb dsize,reg */ |
| 846 | cpustate->dsize = cpustate->reg[ read_op( cpustate ) & 0x7f ]; |
| 847 | break; |
| 848 | |
| 849 | case 0xD3: /* movb dsize,i8 */ |
| 850 | cpustate->dsize = read_op( cpustate ); |
| 851 | break; |
| 852 | |
| 853 | case 0xD4: /* movb ss,reg */ |
| 854 | cpustate->sseg = cpustate->reg[ read_op( cpustate ) & 0x7f ]; |
| 855 | break; |
| 856 | |
| 857 | case 0xD5: /* movb ss,i8 */ |
| 858 | cpustate->sseg = read_op( cpustate ); |
| 859 | break; |
| 860 | |
| 861 | case 0xD6: /* movw sp,reg */ |
| 862 | { |
| 863 | UINT8 reg1 = read_op( cpustate ); |
| 864 | |
| 865 | cpustate->sp = cpustate->reg[ reg1 & 0x7f ] | ( cpustate->reg[ ( reg1 + 1 ) & 0x7f ] << 8 ); |
| 866 | } |
| 867 | break; |
| 868 | |
| 869 | case 0xD7: /* movw sp,i16 */ |
| 870 | cpustate->sp = read_op( cpustate) << 8; |
| 871 | cpustate->sp |= read_op( cpustate ); |
| 872 | break; |
| 873 | |
| 874 | case 0xD8: /* movb f,reg */ |
| 875 | cpustate->f = cpustate->reg[ read_op( cpustate ) & 0x7f ]; |
| 876 | break; |
| 877 | |
| 878 | case 0xD9: /* movb f,i8 */ |
| 879 | cpustate->f = read_op( cpustate ); |
| 880 | break; |
| 881 | |
| 882 | case 0xDC: /* movb ds,reg */ |
| 883 | cpustate->dseg = cpustate->reg[ read_op( cpustate ) & 0x7f ]; |
| 884 | break; |
| 885 | |
| 886 | case 0xDD: /* movb ds,i8 */ |
| 887 | cpustate->dseg = read_op( cpustate ); |
| 888 | break; |
| 889 | |
| 890 | case 0xDE: /* movw lar,reg */ |
| 891 | { |
| 892 | UINT8 reg1 = read_op( cpustate ); |
| 893 | |
| 894 | cpustate->lar = cpustate->reg[ reg1 & 0x7f ] | ( cpustate->reg[ ( reg1 + 1 ) & 0x7f ] << 8 ); |
| 895 | } |
| 896 | break; |
| 897 | |
| 898 | case 0xE0: /* ld0,b? reg (in?) */ |
| 899 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 900 | { |
| 901 | UINT8 reg1 = read_op( cpustate ); |
| 902 | |
| 903 | /* This is incorrect. _Something_ gets stored to the register */ |
| 904 | /* This is to hack around the testb instruction at 001039. */ |
| 905 | cpustate->reg[ reg1 & 0x7f ] = 0x10; |
| 906 | } |
| 907 | break; |
| 908 | |
| 909 | case 0xE1: /* unk_E1 reg/i8 (in?) */ |
| 910 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 911 | break; |
| 912 | |
| 913 | case 0xE2: /* in kb, reg */ |
| 914 | cpustate->reg[ read_op( cpustate ) & 0x7f ] = io_readbyte( cpustate, HCD62121_KI ); |
| 915 | break; |
| 916 | |
| 917 | case 0xE3: /* unk_e3 reg/i8 (in?) */ |
| 918 | case 0xE4: /* unk_e4 reg/i8 (in?) */ |
| 919 | case 0xE5: /* unk_e5 reg/i8 (in?) */ |
| 920 | case 0xE6: /* unk_e6 reg/i8 (in?) */ |
| 921 | case 0xE7: /* unk_e7 reg/i8 (in?) */ |
| 922 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 923 | read_op( cpustate ); |
| 924 | break; |
| 925 | |
| 926 | case 0xE8: /* movw r1,lar */ |
| 927 | { |
| 928 | UINT8 reg1 = read_op( cpustate ); |
| 929 | |
| 930 | cpustate->reg[ reg1 & 0x7f ] = cpustate->lar & 0xff; |
| 931 | cpustate->reg[ ( reg1 + 1 ) & 0x7f ] = cpustate->lar >> 8; |
| 932 | } |
| 933 | break; |
| 934 | |
| 935 | case 0xEB: /* movw reg,ss */ |
| 936 | { |
| 937 | UINT8 reg1 = read_op( cpustate ); |
| 938 | |
| 939 | cpustate->reg[ reg1 & 0x7f ] = cpustate->sp & 0xff; |
| 940 | cpustate->reg[ ( reg1 + 1 ) & 0x7f ] = cpustate->sp >> 8; |
| 941 | } |
| 942 | break; |
| 943 | |
| 944 | case 0xEF: /* movb reg,ss */ |
| 945 | cpustate->reg[ read_op( cpustate ) & 0x7f ] = cpustate->sseg; |
| 946 | break; |
| 947 | |
| 948 | case 0xF0: /* unk_F0 reg/i8 (out?) */ |
| 949 | case 0xF1: /* unk_F1 reg/i8 (out?) */ |
| 950 | case 0xF2: /* unk_F2 reg/i8 (out?) */ |
| 951 | case 0xF3: /* unk_F3 reg/i8 (out?) */ |
| 952 | case 0xF4: /* unk_F4 reg/i8 (out?) */ |
| 953 | case 0xF5: /* unk_F5 reg/i8 (out?) */ |
| 954 | case 0xF6: /* unk_F6 reg/i8 (out?) */ |
| 955 | case 0xF7: /* unk_F7 reg/i8 (out?) */ |
| 956 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 957 | read_op( cpustate ); |
| 958 | break; |
| 959 | |
| 960 | case 0xFC: /* unk_FC */ |
| 961 | case 0xFD: /* unk_FD */ |
| 962 | case 0xFE: /* unk_FE */ |
| 963 | logerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 964 | break; |
| 965 | |
| 966 | case 0xFF: /* nop */ |
| 967 | break; |
| 968 | |
| 969 | default: |
| 970 | /*logerror*/fatalerror( "%02x:%04x: unimplemented instruction %02x encountered\n", cpustate->cseg, cpustate->ip-1, op ); |
| 971 | break; |
| 972 | |
src/emu/cpu/hcd62121/hcd62121.c
| r0 | r8064 | |
| 1 | /********************************************************************** |
| 2 | |
| 3 | Hitachi hcd62121 cpu core emulation. |
| 4 | |
| 5 | The Hitachi hcd62121 is the custom cpu which was used in the Casio |
| 6 | CFX-9850 (and maybe some other things too). |
| 7 | |
| 8 | This CPU core is based on the information provided by Martin Poupe. |
| 9 | Martin Poupe's site can be found at http://prg.rkk.cz/~mpoupe/ |
| 10 | |
| 11 | **********************************************************************/ |
| 12 | |
| 13 | #include "emu.h" |
| 14 | #include "debugger.h" |
| 15 | #include "hcd62121.h" |
| 16 | |
| 17 | |
| 18 | struct _hcd62121_state |
| 19 | { |
| 20 | UINT32 prev_pc; |
| 21 | UINT16 sp; |
| 22 | UINT16 ip; |
| 23 | UINT8 dsize; |
| 24 | UINT8 cseg; |
| 25 | UINT8 dseg; |
| 26 | UINT8 sseg; |
| 27 | UINT8 f; |
| 28 | UINT16 lar; |
| 29 | UINT8 reg[0x80]; |
| 30 | UINT8 temp1[0x10]; |
| 31 | UINT8 temp2[0x10]; |
| 32 | cpu_irq_callback irq_callback; |
| 33 | running_device *device; |
| 34 | const address_space *program; |
| 35 | const address_space *io; |
| 36 | int icount; |
| 37 | }; |
| 38 | |
| 39 | typedef struct _hcd62121_state hcd62121_state; |
| 40 | |
| 41 | |
| 42 | /* From the battery check routine at 20:e874 it looks like |
| 43 | bit 3 of the flag register should be the Zero flag. */ |
| 44 | #define _FLAG_Z 0x08 |
| 45 | #define _FLAG_C 0x02 |
| 46 | #define _FLAG_ZL 0x04 |
| 47 | #define _FLAG_CL 0x01 |
| 48 | #define _FLAG_ZH 0x10 |
| 49 | |
| 50 | |
| 51 | #define mem_readbyte(cs,A) (memory_read_byte_8le((cs)->program,A)) |
| 52 | #define mem_writebyte(cs,A,V) (memory_write_byte_8le((cs)->program,A,V)) |
| 53 | #define io_readbyte(cs,A) (memory_read_byte_8le((cs)->io,A)) |
| 54 | #define io_writebyte(cs,A,V) (memory_write_byte_8le((cs)->io,A,V)) |
| 55 | |
| 56 | |
| 57 | INLINE UINT8 read_op(hcd62121_state *cpustate) |
| 58 | { |
| 59 | UINT8 d = mem_readbyte(cpustate, ( cpustate->cseg << 16 ) | cpustate->ip ); |
| 60 | cpustate->ip++; |
| 61 | return d; |
| 62 | } |
| 63 | |
| 64 | |
| 65 | INLINE UINT8 datasize( hcd62121_state *cpustate, UINT8 op ) |
| 66 | { |
| 67 | switch( op & 0x03 ) |
| 68 | { |
| 69 | case 0: |
| 70 | return 1; |
| 71 | case 1: |
| 72 | return 2; |
| 73 | case 2: |
| 74 | return ( cpustate->dsize >> 4 ) + 1; |
| 75 | case 3: |
| 76 | return ( cpustate->dsize & 0x0f ) + 1; |
| 77 | } |
| 78 | return 1; |
| 79 | } |
| 80 | |
| 81 | |
| 82 | INLINE void read_reg( hcd62121_state *cpustate, int size, UINT8 op1 ) |
| 83 | { |
| 84 | int i; |
| 85 | |
| 86 | if ( op1 & 0x80 ) |
| 87 | { |
| 88 | for ( i = 0; i < size; i++ ) |
| 89 | cpustate->temp1[i] = cpustate->reg[ ( op1 - i ) & 0x7f ]; |
| 90 | } |
| 91 | else |
| 92 | { |
| 93 | for ( i = 0; i < size; i++ ) |
| 94 | cpustate->temp1[i] = cpustate->reg[ ( op1 + i ) & 0x7f ]; |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | |
| 99 | INLINE void write_reg( hcd62121_state *cpustate, int size, UINT8 op1 ) |
| 100 | { |
| 101 | int i; |
| 102 | |
| 103 | if ( op1 & 0x80 ) |
| 104 | { |
| 105 | for ( i = 0; i < size; i++ ) |
| 106 | cpustate->reg[ ( op1 - i ) & 0x7f ] = cpustate->temp1[i]; |
| 107 | } |
| 108 | else |
| 109 | { |
| 110 | for ( i = 0; i < size; i++ ) |
| 111 | cpustate->reg[ ( op1 + i ) & 0x7f ] = cpustate->temp1[i]; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | |
| 116 | INLINE void read_regreg( hcd62121_state *cpustate, int size, UINT8 op1, UINT8 op2 ) |
| 117 | { |
| 118 | int i; |
| 119 | |
| 120 | for ( i = 0; i < size; i++ ) |
| 121 | cpustate->temp1[i] = cpustate->reg[ (op1 + i) & 0x7f]; |
| 122 | |
| 123 | if ( op1 & 0x80 ) |
| 124 | { |
| 125 | cpustate->temp2[0] = op2; |
| 126 | for ( i = 1; i < size; i++ ) |
| 127 | cpustate->temp2[i] = 0; |
| 128 | } |
| 129 | else |
| 130 | { |
| 131 | for ( i = 0; i < size; i++ ) |
| 132 | cpustate->temp2[i] = cpustate->reg[ (op2 + i) & 0x7f ]; |
| 133 | } |
| 134 | |
| 135 | if ( ! ( op1 & 0x80 ) && ! ( op2 & 0x80 ) ) |
| 136 | { |
| 137 | /* We need to swap parameters */ |
| 138 | for ( i = 0; i < size; i++ ) |
| 139 | { |
| 140 | UINT8 v = cpustate->temp1[i]; |
| 141 | cpustate->temp1[i] = cpustate->temp2[i]; |
| 142 | cpustate->temp2[i] = v; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | |
| 148 | INLINE void write_regreg( hcd62121_state *cpustate, int size, UINT8 op1, UINT8 op2 ) |
| 149 | { |
| 150 | int i; |
| 151 | |
| 152 | if ( ( op1 & 0x80 ) || ( op2 & 0x80 ) ) |
| 153 | { |
| 154 | /* store in reg1 */ |
| 155 | for ( i = 0; i < size; i++ ) |
| 156 | cpustate->reg[ (op1 + i) & 0x7f] = cpustate->temp1[i]; |
| 157 | } |
| 158 | else |
| 159 | { |
| 160 | /* store in reg2 */ |
| 161 | for ( i = 0; i < size; i++ ) |
| 162 | cpustate->reg[ (op2 + i) & 0x7f] = cpustate->temp1[i]; |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | |
| 167 | INLINE void read_iregreg( hcd62121_state *cpustate, int size, UINT8 op1, UINT8 op2 ) |
| 168 | { |
| 169 | int i; |
| 170 | UINT16 ad; |
| 171 | |
| 172 | ad = cpustate->reg[ ( 0x40 | op1 ) & 0x7f ] | ( cpustate->reg[ ( 0x40 | ( op1 + 1 ) ) & 0x7f ] << 8 ); |
| 173 | |
| 174 | for ( i = 0; i < size; i++ ) |
| 175 | { |
| 176 | cpustate->temp1[i] = mem_readbyte( cpustate, ( cpustate->dseg << 16 ) | ad ); |
| 177 | ad += ( op1 & 0x40 ) ? -1 : 1; |
| 178 | } |
| 179 | cpustate->lar = ad; |
| 180 | |
| 181 | if ( op1 & 0x80 ) |
| 182 | { |
| 183 | cpustate->temp2[0] = op2; |
| 184 | for ( i = 1; i < size; i++ ) |
| 185 | cpustate->temp2[i] = 0; |
| 186 | } |
| 187 | else |
| 188 | { |
| 189 | for ( i = 0; i < size; i++ ) |
| 190 | cpustate->temp2[i] = cpustate->reg[ (op2 + i) & 0x7f ]; |
| 191 | } |
| 192 | |
| 193 | if ( ! ( op1 & 0x80 ) && ! ( op2 & 0x80 ) ) |
| 194 | { |
| 195 | /* We need to swap parameters */ |
| 196 | for ( i = 0; i < size; i++ ) |
| 197 | { |
| 198 | UINT8 v = cpustate->temp1[i]; |
| 199 | cpustate->temp1[i] = cpustate->temp2[i]; |
| 200 | cpustate->temp2[i] = v; |
| 201 | } |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | |
| 206 | INLINE void write_iregreg( hcd62121_state *cpustate, int size, UINT8 op1, UINT8 op2 ) |
| 207 | { |
| 208 | int i; |
| 209 | |
| 210 | if ( ( op1 & 0x80 ) || ( op2 & 0x80 ) ) |
| 211 | { |
| 212 | /* store in (reg1) */ |
| 213 | UINT16 ad = cpustate->reg[ ( 0x40 | op1 ) & 0x7f ] | ( cpustate->reg[ ( 0x40 | ( op1 + 1 ) ) & 0x7f ] << 8 ); |
| 214 | |
| 215 | for ( i = 0; i < size; i++ ) |
| 216 | { |
| 217 | mem_writebyte( cpustate, ( cpustate->dseg << 16 ) | ad, cpustate->temp1[i] ); |
| 218 | ad += ( op1 & 0x40 ) ? -1 : 1; |
| 219 | } |
| 220 | cpustate->lar = ad; |
| 221 | } |
| 222 | else |
| 223 | { |
| 224 | /* store in reg2 */ |
| 225 | for ( i = 0; i < size; i++ ) |
| 226 | cpustate->reg[ (op2 + i) & 0x7f] = cpustate->temp1[i]; |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | |
| 231 | INLINE void write_iregreg2( hcd62121_state *cpustate, int size, UINT8 op1, UINT8 op2 ) |
| 232 | { |
| 233 | int i; |
| 234 | |
| 235 | if ( ( op1 & 0x80 ) || ( op2 & 0x80 ) ) |
| 236 | { |
| 237 | /* store in reg2 */ |
| 238 | for ( i = 0; i < size; i++ ) |
| 239 | cpustate->reg[ (op2 + i) & 0x7f] = cpustate->temp2[i]; |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | /* store in (reg1) */ |
| 244 | UINT16 ad = cpustate->reg[ ( 0x40 | op1 ) & 0x7f ] | ( cpustate->reg[ ( 0x40 | ( op1 + 1 ) ) & 0x7f ] << 8 ); |
| 245 | |
| 246 | for ( i = 0; i < size; i++ ) |
| 247 | { |
| 248 | mem_writebyte( cpustate, ( cpustate->dseg << 16 ) | ad, cpustate->temp2[i] ); |
| 249 | ad += ( op1 & 0x40 ) ? -1 : 1; |
| 250 | } |
| 251 | cpustate->lar = ad; |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | |
| 256 | INLINE int check_cond( hcd62121_state *cpustate, UINT8 op ) |
| 257 | { |
| 258 | switch ( op & 0x07 ) |
| 259 | { |
| 260 | case 0x00: /* ZH set */ |
| 261 | if ( cpustate->f & _FLAG_ZH ) |
| 262 | return 1; |
| 263 | break; |
| 264 | |
| 265 | case 0x01: /* ZL set */ |
| 266 | if ( cpustate->f & _FLAG_ZL ) |
| 267 | return 1; |
| 268 | break; |
| 269 | |
| 270 | case 0x02: /* C set */ |
| 271 | if ( cpustate->f & _FLAG_C ) |
| 272 | return 1; |
| 273 | break; |
| 274 | |
| 275 | case 0x03: /* Z set */ |
| 276 | if ( cpustate->f & _FLAG_Z ) |
| 277 | return 1; |
| 278 | break; |
| 279 | |
| 280 | case 0x04: /* Z or C set */ |
| 281 | if ( cpustate->f & ( _FLAG_Z | _FLAG_C ) ) |
| 282 | return 1; |
| 283 | break; |
| 284 | |
| 285 | case 0x05: /* CL set */ |
| 286 | if ( cpustate->f & _FLAG_CL ) |
| 287 | return 1; |
| 288 | break; |
| 289 | |
| 290 | case 0x06: /* C clear */ |
| 291 | if ( ! ( cpustate->f & _FLAG_C ) ) |
| 292 | return 1; |
| 293 | break; |
| 294 | |
| 295 | case 0x07: /* Z clear */ |
| 296 | if ( ! ( cpustate->f & _FLAG_Z ) ) |
| 297 | return 1; |
| 298 | break; |
| 299 | } |
| 300 | |
| 301 | return 0; |
| 302 | } |
| 303 | |
| 304 | |
| 305 | INLINE hcd62121_state *get_safe_token(running_device *device) |
| 306 | { |
| 307 | assert(device != NULL); |
| 308 | assert(device->token != NULL); |
| 309 | assert(device->type == CPU); |
| 310 | assert(cpu_get_type(device) == CPU_HCD62121); |
| 311 | return (hcd62121_state *)device->token; |
| 312 | } |
| 313 | |
| 314 | |
| 315 | static CPU_INIT( hcd62121 ) |
| 316 | { |
| 317 | hcd62121_state *cpustate = get_safe_token(device); |
| 318 | |
| 319 | cpustate->irq_callback = irqcallback; |
| 320 | cpustate->device = device; |
| 321 | cpustate->program = device->space(AS_PROGRAM); |
| 322 | cpustate->io = device->space(AS_IO); |
| 323 | } |
| 324 | |
| 325 | |
| 326 | static CPU_RESET( hcd62121 ) |
| 327 | { |
| 328 | hcd62121_state *cpustate = get_safe_token(device); |
| 329 | |
| 330 | cpustate->sp = 0x0000; |
| 331 | cpustate->ip = 0x0000; |
| 332 | cpustate->cseg = 0; |
| 333 | cpustate->dseg = 0; |
| 334 | cpustate->sseg = 0; |
| 335 | cpustate->lar = 0; |
| 336 | cpustate->f = 0; |
| 337 | cpustate->dsize = 0; |
| 338 | |
| 339 | for( int i = 0; i < 0x80; i++ ) |
| 340 | { |
| 341 | cpustate->reg[i] = 0; |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | |
| 346 | static CPU_EXECUTE( hcd62121 ) |
| 347 | { |
| 348 | hcd62121_state *cpustate = get_safe_token(device); |
| 349 | |
| 350 | cpustate->icount = cycles; |
| 351 | |
| 352 | do |
| 353 | { |
| 354 | UINT32 pc = ( cpustate->cseg << 16 ) | cpustate->ip; |
| 355 | UINT8 op; |
| 356 | |
| 357 | debugger_instruction_hook(device, pc); |
| 358 | cpustate->prev_pc = pc; |
| 359 | |
| 360 | op = read_op( cpustate ); |
| 361 | |
| 362 | cpustate->icount -= 4; |
| 363 | |
| 364 | switch ( op ) |
| 365 | { |
| 366 | #include "hcd62121_ops.h" |
| 367 | }; |
| 368 | |
| 369 | } while (cpustate->icount > 0); |
| 370 | |
| 371 | return cycles - cpustate->icount; |
| 372 | } |
| 373 | |
| 374 | |
| 375 | static CPU_SET_INFO( hcd62121 ) |
| 376 | { |
| 377 | hcd62121_state *cpustate = get_safe_token(device); |
| 378 | |
| 379 | switch (state) |
| 380 | { |
| 381 | /* --- the following bits of info are set as 64-bit signed integers --- */ |
| 382 | case CPUINFO_INT_INPUT_STATE + 0: |
| 383 | case CPUINFO_INT_INPUT_STATE + 1: |
| 384 | break; |
| 385 | |
| 386 | case CPUINFO_INT_SP: cpustate->sp = info->i; break; |
| 387 | case CPUINFO_INT_PC: cpustate->ip = info->i; break; |
| 388 | |
| 389 | case CPUINFO_INT_REGISTER + HCD62121_IP: cpustate->ip = info->i; break; |
| 390 | case CPUINFO_INT_REGISTER + HCD62121_SP: cpustate->sp = info->i; break; |
| 391 | // case CPUINFO_INT_REGISTER + HCD62121_R00: break; |
| 392 | // case CPUINFO_INT_REGISTER + HCD62121_R02: break; |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | |
| 397 | CPU_GET_INFO( hcd62121 ) |
| 398 | { |
| 399 | hcd62121_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; |
| 400 | |
| 401 | switch (state) |
| 402 | { |
| 403 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 404 | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(hcd62121_state); break; |
| 405 | case CPUINFO_INT_INPUT_LINES: info->i = 2; break; |
| 406 | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break; |
| 407 | case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break; |
| 408 | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; |
| 409 | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; |
| 410 | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; |
| 411 | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 18; break; |
| 412 | case CPUINFO_INT_MIN_CYCLES: info->i = 4; /* right? */ break; |
| 413 | case CPUINFO_INT_MAX_CYCLES: info->i = 48; /* right? */ break; |
| 414 | |
| 415 | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; |
| 416 | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break; |
| 417 | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; |
| 418 | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 419 | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 420 | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 421 | case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; |
| 422 | case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break; |
| 423 | case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; |
| 424 | |
| 425 | case CPUINFO_INT_SP: info->i = cpustate->sp; break; |
| 426 | case CPUINFO_INT_PC: info->i = ( cpustate->cseg << 16 ) | cpustate->ip; break; |
| 427 | case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->prev_pc; break; |
| 428 | |
| 429 | case CPUINFO_INT_INPUT_STATE + 0: |
| 430 | case CPUINFO_INT_INPUT_STATE + 1: |
| 431 | /* TODO */ break; |
| 432 | |
| 433 | case CPUINFO_INT_REGISTER + HCD62121_IP: info->i = cpustate->ip; break; |
| 434 | case CPUINFO_INT_REGISTER + HCD62121_SP: info->i = cpustate->sp; break; |
| 435 | case CPUINFO_INT_REGISTER + HCD62121_LAR: info->i = cpustate->lar; break; |
| 436 | case CPUINFO_INT_REGISTER + HCD62121_CS: info->i = cpustate->cseg; break; |
| 437 | case CPUINFO_INT_REGISTER + HCD62121_DS: info->i = cpustate->dseg; break; |
| 438 | case CPUINFO_INT_REGISTER + HCD62121_SS: info->i = cpustate->sseg; break; |
| 439 | case CPUINFO_INT_REGISTER + HCD62121_DSIZE: info->i = cpustate->dsize; break; |
| 440 | case CPUINFO_INT_REGISTER + HCD62121_R00: info->i = ( cpustate->reg[0x00] << 24 ) | ( cpustate->reg[0x01] << 16 ) | ( cpustate->reg[0x02] << 8 ) | cpustate->reg[0x03]; break; |
| 441 | // case CPUINFO_INT_REGISTER + HCD62121_R02: info->i = cpustate->; break; |
| 442 | |
| 443 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 444 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(hcd62121); break; |
| 445 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(hcd62121); break; |
| 446 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(hcd62121); break; |
| 447 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(hcd62121); break; |
| 448 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(hcd62121); break; |
| 449 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; |
| 450 | |
| 451 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 452 | case DEVINFO_STR_NAME: strcpy(info->s, "HCD62121"); break; |
| 453 | case DEVINFO_STR_FAMILY: strcpy(info->s, "Hitachi HCD62121"); break; |
| 454 | case DEVINFO_STR_VERSION: strcpy(info->s, "0.1"); break; |
| 455 | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 456 | case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright The MESS Team."); break; |
| 457 | |
| 458 | case CPUINFO_STR_FLAGS: |
| 459 | sprintf(info->s, "%s-%s-%s-%c-%c", |
| 460 | cpustate->f & _FLAG_ZH ? "ZH":"__", |
| 461 | cpustate->f & _FLAG_CL ? "CL":"__", |
| 462 | cpustate->f & _FLAG_ZL ? "ZL":"__", |
| 463 | cpustate->f & _FLAG_C ? 'C':'_', |
| 464 | cpustate->f & _FLAG_Z ? 'Z':'_' |
| 465 | ); |
| 466 | break; |
| 467 | |
| 468 | case CPUINFO_STR_REGISTER + HCD62121_IP: sprintf(info->s, "IP:%04X", cpustate->ip); break; |
| 469 | case CPUINFO_STR_REGISTER + HCD62121_SP: sprintf(info->s, "SP:%04X", cpustate->sp); break; |
| 470 | case CPUINFO_STR_REGISTER + HCD62121_LAR: sprintf(info->s, "LAR:%04X", cpustate->lar); break; |
| 471 | case CPUINFO_STR_REGISTER + HCD62121_CS: sprintf(info->s, "CS:%02X", cpustate->cseg); break; |
| 472 | case CPUINFO_STR_REGISTER + HCD62121_DS: sprintf(info->s, "DS:%02X", cpustate->dseg); break; |
| 473 | case CPUINFO_STR_REGISTER + HCD62121_SS: sprintf(info->s, "SS:%02X", cpustate->sseg); break; |
| 474 | case CPUINFO_STR_REGISTER + HCD62121_DSIZE: sprintf(info->s, "DSIZE:%02X", cpustate->dsize); break; |
| 475 | case CPUINFO_STR_REGISTER + HCD62121_R00: sprintf(info->s, "R00:%02X%02X%02X%02X", cpustate->reg[0x00], cpustate->reg[0x01], cpustate->reg[0x02], cpustate->reg[0x03]); break; |
| 476 | case CPUINFO_STR_REGISTER + HCD62121_R04: sprintf(info->s, "R04:%02X%02X%02X%02X", cpustate->reg[0x04], cpustate->reg[0x05], cpustate->reg[0x06], cpustate->reg[0x07]); break; |
| 477 | case CPUINFO_STR_REGISTER + HCD62121_R08: sprintf(info->s, "R08:%02X%02X%02X%02X", cpustate->reg[0x08], cpustate->reg[0x09], cpustate->reg[0x0a], cpustate->reg[0x0b]); break; |
| 478 | case CPUINFO_STR_REGISTER + HCD62121_R0C: sprintf(info->s, "R0C:%02X%02X%02X%02X", cpustate->reg[0x0c], cpustate->reg[0x0d], cpustate->reg[0x0e], cpustate->reg[0x0f]); break; |
| 479 | case CPUINFO_STR_REGISTER + HCD62121_R10: sprintf(info->s, "R10:%02X%02X%02X%02X", cpustate->reg[0x10], cpustate->reg[0x11], cpustate->reg[0x12], cpustate->reg[0x13]); break; |
| 480 | case CPUINFO_STR_REGISTER + HCD62121_R14: sprintf(info->s, "R14:%02X%02X%02X%02X", cpustate->reg[0x14], cpustate->reg[0x15], cpustate->reg[0x16], cpustate->reg[0x17]); break; |
| 481 | case CPUINFO_STR_REGISTER + HCD62121_R18: sprintf(info->s, "R18:%02X%02X%02X%02X", cpustate->reg[0x18], cpustate->reg[0x19], cpustate->reg[0x1a], cpustate->reg[0x1b]); break; |
| 482 | case CPUINFO_STR_REGISTER + HCD62121_R1C: sprintf(info->s, "R1C:%02X%02X%02X%02X", cpustate->reg[0x1c], cpustate->reg[0x1d], cpustate->reg[0x1e], cpustate->reg[0x1f]); break; |
| 483 | case CPUINFO_STR_REGISTER + HCD62121_R20: sprintf(info->s, "R20:%02X%02X%02X%02X", cpustate->reg[0x20], cpustate->reg[0x21], cpustate->reg[0x22], cpustate->reg[0x23]); break; |
| 484 | case CPUINFO_STR_REGISTER + HCD62121_R24: sprintf(info->s, "R24:%02X%02X%02X%02X", cpustate->reg[0x24], cpustate->reg[0x25], cpustate->reg[0x26], cpustate->reg[0x27]); break; |
| 485 | case CPUINFO_STR_REGISTER + HCD62121_R28: sprintf(info->s, "R28:%02X%02X%02X%02X", cpustate->reg[0x28], cpustate->reg[0x29], cpustate->reg[0x2a], cpustate->reg[0x2b]); break; |
| 486 | case CPUINFO_STR_REGISTER + HCD62121_R2C: sprintf(info->s, "R2C:%02X%02X%02X%02X", cpustate->reg[0x2c], cpustate->reg[0x2d], cpustate->reg[0x2e], cpustate->reg[0x2f]); break; |
| 487 | case CPUINFO_STR_REGISTER + HCD62121_R30: sprintf(info->s, "R30:%02X%02X%02X%02X", cpustate->reg[0x30], cpustate->reg[0x31], cpustate->reg[0x32], cpustate->reg[0x33]); break; |
| 488 | case CPUINFO_STR_REGISTER + HCD62121_R34: sprintf(info->s, "R34:%02X%02X%02X%02X", cpustate->reg[0x34], cpustate->reg[0x35], cpustate->reg[0x36], cpustate->reg[0x37]); break; |
| 489 | case CPUINFO_STR_REGISTER + HCD62121_R38: sprintf(info->s, "R38:%02X%02X%02X%02X", cpustate->reg[0x38], cpustate->reg[0x39], cpustate->reg[0x3a], cpustate->reg[0x3b]); break; |
| 490 | case CPUINFO_STR_REGISTER + HCD62121_R3C: sprintf(info->s, "R3C:%02X%02X%02X%02X", cpustate->reg[0x3c], cpustate->reg[0x3d], cpustate->reg[0x3e], cpustate->reg[0x3f]); break; |
| 491 | case CPUINFO_STR_REGISTER + HCD62121_R40: sprintf(info->s, "R40:%02X%02X%02X%02X", cpustate->reg[0x40], cpustate->reg[0x41], cpustate->reg[0x42], cpustate->reg[0x43]); break; |
| 492 | case CPUINFO_STR_REGISTER + HCD62121_R44: sprintf(info->s, "R44:%02X%02X%02X%02X", cpustate->reg[0x44], cpustate->reg[0x45], cpustate->reg[0x46], cpustate->reg[0x47]); break; |
| 493 | case CPUINFO_STR_REGISTER + HCD62121_R48: sprintf(info->s, "R48:%02X%02X%02X%02X", cpustate->reg[0x48], cpustate->reg[0x49], cpustate->reg[0x4a], cpustate->reg[0x4b]); break; |
| 494 | case CPUINFO_STR_REGISTER + HCD62121_R4C: sprintf(info->s, "R4C:%02X%02X%02X%02X", cpustate->reg[0x4c], cpustate->reg[0x4d], cpustate->reg[0x4e], cpustate->reg[0x4f]); break; |
| 495 | case CPUINFO_STR_REGISTER + HCD62121_R50: sprintf(info->s, "R50:%02X%02X%02X%02X", cpustate->reg[0x50], cpustate->reg[0x51], cpustate->reg[0x52], cpustate->reg[0x53]); break; |
| 496 | case CPUINFO_STR_REGISTER + HCD62121_R54: sprintf(info->s, "R54:%02X%02X%02X%02X", cpustate->reg[0x54], cpustate->reg[0x55], cpustate->reg[0x56], cpustate->reg[0x57]); break; |
| 497 | case CPUINFO_STR_REGISTER + HCD62121_R58: sprintf(info->s, "R58:%02X%02X%02X%02X", cpustate->reg[0x58], cpustate->reg[0x59], cpustate->reg[0x5a], cpustate->reg[0x5b]); break; |
| 498 | case CPUINFO_STR_REGISTER + HCD62121_R5C: sprintf(info->s, "R5C:%02X%02X%02X%02X", cpustate->reg[0x5c], cpustate->reg[0x5d], cpustate->reg[0x5e], cpustate->reg[0x5f]); break; |
| 499 | case CPUINFO_STR_REGISTER + HCD62121_R60: sprintf(info->s, "R60:%02X%02X%02X%02X", cpustate->reg[0x60], cpustate->reg[0x61], cpustate->reg[0x62], cpustate->reg[0x63]); break; |
| 500 | case CPUINFO_STR_REGISTER + HCD62121_R64: sprintf(info->s, "R64:%02X%02X%02X%02X", cpustate->reg[0x64], cpustate->reg[0x65], cpustate->reg[0x66], cpustate->reg[0x67]); break; |
| 501 | case CPUINFO_STR_REGISTER + HCD62121_R68: sprintf(info->s, "R68:%02X%02X%02X%02X", cpustate->reg[0x68], cpustate->reg[0x69], cpustate->reg[0x6a], cpustate->reg[0x6b]); break; |
| 502 | case CPUINFO_STR_REGISTER + HCD62121_R6C: sprintf(info->s, "R6C:%02X%02X%02X%02X", cpustate->reg[0x6c], cpustate->reg[0x6d], cpustate->reg[0x6e], cpustate->reg[0x6f]); break; |
| 503 | case CPUINFO_STR_REGISTER + HCD62121_R70: sprintf(info->s, "R70:%02X%02X%02X%02X", cpustate->reg[0x70], cpustate->reg[0x71], cpustate->reg[0x72], cpustate->reg[0x73]); break; |
| 504 | case CPUINFO_STR_REGISTER + HCD62121_R74: sprintf(info->s, "R74:%02X%02X%02X%02X", cpustate->reg[0x74], cpustate->reg[0x75], cpustate->reg[0x76], cpustate->reg[0x77]); break; |
| 505 | case CPUINFO_STR_REGISTER + HCD62121_R78: sprintf(info->s, "R78:%02X%02X%02X%02X", cpustate->reg[0x78], cpustate->reg[0x79], cpustate->reg[0x7a], cpustate->reg[0x7b]); break; |
| 506 | case CPUINFO_STR_REGISTER + HCD62121_R7C: sprintf(info->s, "R7C:%02X%02X%02X%02X", cpustate->reg[0x7c], cpustate->reg[0x7d], cpustate->reg[0x7e], cpustate->reg[0x7f]); break; |
| 507 | } |
| 508 | } |
| 509 | |
src/mess/drivers/cfx9850.c
| r0 | r8064 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Driver for Casio CFX-9850 |
| 4 | |
| 5 | ***************************************************************************/ |
| 6 | |
| 7 | #include "emu.h" |
| 8 | #include "cpu/hcd62121/hcd62121.h" |
| 9 | |
| 10 | |
| 11 | class cfx9850_state |
| 12 | { |
| 13 | public: |
| 14 | static void *alloc(running_machine &machine) { return auto_alloc_clear(&machine, cfx9850_state(machine)); } |
| 15 | |
| 16 | cfx9850_state(running_machine &machine) { } |
| 17 | |
| 18 | UINT8 *video_ram; |
| 19 | UINT8 *display_ram; |
| 20 | |
| 21 | UINT16 ko; /* KO lines KO1 - KO14 */ |
| 22 | }; |
| 23 | |
| 24 | |
| 25 | static ADDRESS_MAP_START( cfx9850, ADDRESS_SPACE_PROGRAM, 8 ) |
| 26 | AM_RANGE( 0x000000, 0x007fff ) AM_ROM |
| 27 | AM_RANGE( 0x080000, 0x0807ff ) AM_RAM AM_BASE_MEMBER( cfx9850_state, video_ram ) |
| 28 | // AM_RANGE( 0x100000, 0x10ffff ) /* some memory mapped i/o? */ |
| 29 | // AM_RANGE( 0x110000, 0x11ffff ) /* some memory mapped i/o? */ |
| 30 | AM_RANGE( 0x200000, 0x27ffff ) AM_ROM AM_REGION( "bios", 0 ) |
| 31 | AM_RANGE( 0x400000, 0x40ffff ) AM_RAM |
| 32 | AM_RANGE( 0x600000, 0x601fff ) AM_MIRROR(0xe000) AM_RAM AM_BASE_MEMBER( cfx9850_state, display_ram ) |
| 33 | // AM_RANGE( 0xe10000, 0xe1ffff ) /* some memory mapped i/o? */ |
| 34 | ADDRESS_MAP_END |
| 35 | |
| 36 | |
| 37 | static WRITE8_HANDLER( cfx9850_kol_w ) |
| 38 | { |
| 39 | cfx9850_state *state = (cfx9850_state *)space->machine->driver_data; |
| 40 | |
| 41 | state->ko = ( state->ko & 0xff00 ) | data; |
| 42 | } |
| 43 | |
| 44 | static WRITE8_HANDLER( cfx9850_koh_w ) |
| 45 | { |
| 46 | cfx9850_state *state = (cfx9850_state *)space->machine->driver_data; |
| 47 | |
| 48 | state->ko = ( state->ko & 0x00ff ) | ( data << 8 ); |
| 49 | } |
| 50 | |
| 51 | |
| 52 | static READ8_HANDLER( cfx9850_ki_r ) |
| 53 | { |
| 54 | cfx9850_state *state = (cfx9850_state *)space->machine->driver_data; |
| 55 | UINT8 data = 0; |
| 56 | |
| 57 | if ( state->ko & 0x0001 ) |
| 58 | data |= input_port_read( space->machine, "KO1" ); |
| 59 | if ( state->ko & 0x0002 ) |
| 60 | data |= input_port_read( space->machine, "KO2" ); |
| 61 | if ( state->ko & 0x0004 ) |
| 62 | data |= input_port_read( space->machine, "KO3" ); |
| 63 | if ( state->ko & 0x0008 ) |
| 64 | data |= input_port_read( space->machine, "KO4" ); |
| 65 | if ( state->ko & 0x0010 ) |
| 66 | data |= input_port_read( space->machine, "KO5" ); |
| 67 | if ( state->ko & 0x0020 ) |
| 68 | data |= input_port_read( space->machine, "KO6" ); |
| 69 | if ( state->ko & 0x0040 ) |
| 70 | data |= input_port_read( space->machine, "KO7" ); |
| 71 | if ( state->ko & 0x0080 ) |
| 72 | data |= input_port_read( space->machine, "KO8" ); |
| 73 | if ( state->ko & 0x0100 ) |
| 74 | data |= input_port_read( space->machine, "KO9" ); |
| 75 | if ( state->ko & 0x0200 ) |
| 76 | data |= input_port_read( space->machine, "KO10" ); |
| 77 | /* KO11 is not connected */ |
| 78 | if ( state->ko & 0x0800 ) |
| 79 | data |= input_port_read( space->machine, "KO12" ); |
| 80 | /* KO13 is not connected */ |
| 81 | /* KO14 is not connected */ |
| 82 | |
| 83 | return data; |
| 84 | } |
| 85 | |
| 86 | |
| 87 | static ADDRESS_MAP_START( cfx9850_io, ADDRESS_SPACE_IO, 8 ) |
| 88 | AM_RANGE( HCD62121_KOL, HCD62121_KOL ) AM_WRITE( cfx9850_kol_w ) |
| 89 | AM_RANGE( HCD62121_KOH, HCD62121_KOH ) AM_WRITE( cfx9850_koh_w ) |
| 90 | AM_RANGE( HCD62121_KI, HCD62121_KI ) AM_READ( cfx9850_ki_r ) |
| 91 | ADDRESS_MAP_END |
| 92 | |
| 93 | |
| 94 | static INPUT_PORTS_START( cfx9850 ) |
| 95 | PORT_START( "KO1" ) |
| 96 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "AC On/Off" ) PORT_CODE(KEYCODE_Q) |
| 97 | |
| 98 | PORT_START( "KO2" ) |
| 99 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "EXE Enter" ) |
| 100 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "(-) Ares" ) |
| 101 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "EXP Pi" ) |
| 102 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( ". SPACE" ) |
| 103 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "0 Z" ) |
| 104 | |
| 105 | PORT_START( "KO3" ) |
| 106 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "- ] Y" ) |
| 107 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "+ [ X" ) |
| 108 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "3 W" ) |
| 109 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "2 V" ) |
| 110 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "1 U" ) |
| 111 | |
| 112 | PORT_START( "KO4" ) |
| 113 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "/ } T" ) |
| 114 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "* { S" ) |
| 115 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "6 R" ) |
| 116 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "5 Q" ) |
| 117 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "4 P" ) |
| 118 | |
| 119 | PORT_START( "KO5" ) |
| 120 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "DEL DG" ) |
| 121 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "9 O" ) |
| 122 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "8 N" ) |
| 123 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "7 M" ) |
| 124 | |
| 125 | PORT_START( "KO6" ) |
| 126 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "TAB L" ) |
| 127 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( ", K" ) |
| 128 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( ") x^-1 J" ) |
| 129 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "( .. I" ) |
| 130 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F<=>0 H" ) |
| 131 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "a b/c G" ) |
| 132 | |
| 133 | PORT_START( "KO7" ) |
| 134 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "tan tan^-1 F" ) |
| 135 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "cos cas^-1 E" ) |
| 136 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "sin sin^-1 D" ) |
| 137 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "ln e^x C" ) |
| 138 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "log 10^x B" ) |
| 139 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "x,d,t A" ) |
| 140 | |
| 141 | PORT_START( "KO8" ) |
| 142 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Right" ) |
| 143 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Down" ) |
| 144 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "EXIT QUIT" ) |
| 145 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "/\\ .. .." ) |
| 146 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "x^2 sqrt .." ) |
| 147 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "ALPHA ..-LOCK" ) |
| 148 | |
| 149 | PORT_START( "KO9" ) |
| 150 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Up" ) |
| 151 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Left" ) |
| 152 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "MENU SET UP" ) |
| 153 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "VARS PRGM" ) |
| 154 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "OPTN" ) |
| 155 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "SHIFT" ) |
| 156 | |
| 157 | PORT_START( "KO10" ) |
| 158 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F6 G<=>T" ) |
| 159 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F5 G-Solv" ) |
| 160 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F4 Sketch" ) |
| 161 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F3 V-Window" ) |
| 162 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F2 Zoom" ) |
| 163 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F1 Trace" ) |
| 164 | |
| 165 | /* KO11 is not connected */ |
| 166 | // PORT_START( "KO11" ) |
| 167 | |
| 168 | PORT_START( "KO12" ) |
| 169 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "TEST" ) |
| 170 | |
| 171 | /* KO13 is not connected */ |
| 172 | // PORT_START( "KO13" ) |
| 173 | |
| 174 | /* KO14 is not connected */ |
| 175 | // PORT_START( "KO14" ) |
| 176 | INPUT_PORTS_END |
| 177 | |
| 178 | |
| 179 | static MACHINE_DRIVER_START( cfx9850 ) |
| 180 | MDRV_DRIVER_DATA( cfx9850_state ) |
| 181 | |
| 182 | MDRV_CPU_ADD( "maincpu", HCD62121, 4300000 ) /* 4.3 MHz */ |
| 183 | MDRV_CPU_PROGRAM_MAP( cfx9850 ) |
| 184 | MDRV_CPU_IO_MAP( cfx9850_io ) |
| 185 | |
| 186 | MDRV_SCREEN_ADD( "screen", LCD ) |
| 187 | MDRV_SCREEN_REFRESH_RATE( 60 ) |
| 188 | MDRV_SCREEN_FORMAT( BITMAP_FORMAT_INDEXED16 ) |
| 189 | MDRV_SCREEN_SIZE( 128, 64 ) |
| 190 | MDRV_SCREEN_VISIBLE_AREA( 0, 127, 0, 63 ) |
| 191 | MDRV_DEFAULT_LAYOUT(layout_lcd) |
| 192 | |
| 193 | /* TODO: It uses a color display, but I'm being lazy here. 3 colour lcd */ |
| 194 | MDRV_PALETTE_LENGTH( 2 ) |
| 195 | MDRV_PALETTE_INIT(black_and_white) |
| 196 | |
| 197 | MACHINE_DRIVER_END |
| 198 | |
| 199 | |
| 200 | ROM_START( cfx9850 ) |
| 201 | ROM_REGION( 0x8000, "maincpu", 0 ) |
| 202 | ROM_LOAD( "hcd62121.bin", 0x0000, 0x8000, CRC(e72075f8) SHA1(f50d176e1c225dab69abfc67702c9dfb296b6a78) ) |
| 203 | ROM_REGION( 0x80000, "bios", 0 ) |
| 204 | /* No idea yet which rom is what version. */ |
| 205 | ROM_SYSTEM_BIOS( 0, "rom1", "rom1, version unknown" ) |
| 206 | ROMX_LOAD( "cfx9850.bin", 0x00000, 0x80000, CRC(6c9bd903) SHA1(d5b6677ab4e0d3f84e5769e89e8f3d101f98f848), ROM_BIOS(1) ) |
| 207 | ROM_SYSTEM_BIOS( 1, "rom2", "rom2, version unknown" ) |
| 208 | ROMX_LOAD( "cfx9850b.bin", 0x00000, 0x80000, CRC(cd3c497f) SHA1(1d1aa38205eec7aba3ed6bef7389767e38afe075), ROM_BIOS(2) ) |
| 209 | ROM_END |
| 210 | |
| 211 | |
| 212 | CONS( 1996, cfx9850, 0, 0, cfx9850, cfx9850, 0, "Casio", "CFX9850", GAME_NO_SOUND | GAME_NOT_WORKING ) |
| 213 | |