2 Skelton for retropc emulator
4 Origin : MAME TMS99xx Core
5 Author : Takeda.Toshiya
23 #define ST_OVIE 0x0020
43 #define MEM_WAIT_BYTE 4
44 #define MEM_WAIT_WORD 12
47 #define BYTE_XOR_BE(a) (a)
49 #define BYTE_XOR_BE(a) ((a) ^ 1)
52 #define CRU_MASK_R ((1 << 12) - 1)
53 #define CRU_MASK_W ((1 << 15) - 1)
55 static const uint16_t right_shift_mask_table[17] = {
57 0x7fff, 0x3fff, 0x1fff, 0x0fff, 0x07ff, 0x03ff, 0x01ff, 0x00ff,
58 0x007f, 0x003f, 0x001f, 0x000f, 0x0007, 0x0003, 0x0001, 0x0000
60 static const uint16_t inverted_right_shift_mask_table[17] = {
62 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
63 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff
67 uint16_t TMS9995::RM16(uint16_t addr)
70 return d_mem_tmp->read_data16(addr);
72 uint32_t TMS9995::read_data16(uint32_t addr)
76 period += MEM_WAIT_WORD;
77 uint16_t tmp = d_mem->read_data8(addr);
78 return (tmp << 8) | d_mem->read_data8(addr + 1);
79 } else if(addr < 0xf0fc) {
80 return *(uint16_t *)(&RAM[addr & 0xff]);
81 } else if(addr < 0xfffa) {
82 period += MEM_WAIT_WORD;
83 uint16_t tmp = d_mem->read_data8(addr);
84 return (tmp << 8) | d_mem->read_data8(addr + 1);
85 } else if(addr < 0xfffc) {
86 if(dec_enabled && !(mode & 1)) {
87 return (dec_timer >> 4) & 0xffff;
92 return *(uint16_t *)(&RAM[addr & 0xff]);
96 void TMS9995::WM16(uint16_t addr, uint16_t val)
99 d_mem_tmp->write_data16(addr, val);
101 void TMS9995::write_data16(uint32_t addr, uint32_t val)
105 period += MEM_WAIT_WORD;
106 d_mem->write_data8(addr, val >> 8);
107 d_mem->write_data8(addr + 1, val & 0xff);
108 } else if(addr < 0xf0fc) {
109 *(uint16_t *)(&RAM[addr & 0xff]) = val;
110 } else if(addr < 0xfffa) {
111 period += MEM_WAIT_WORD;
112 d_mem->write_data8(addr, val >> 8);
113 d_mem->write_data8(addr + 1, val & 0xff);
114 } else if(addr < 0xfffc) {
118 *(uint16_t *)(&RAM[addr & 0xff]) = val;
122 uint8_t TMS9995::RM8(uint16_t addr)
125 return d_mem_tmp->read_data8(addr);
127 uint32_t TMS9995::read_data8(uint32_t addr)
130 if((addr < 0xf000)) {
131 period += MEM_WAIT_BYTE;
132 return d_mem->read_data8(addr);
133 } else if(addr < 0xf0fc) {
134 return RAM[BYTE_XOR_BE(addr & 0xff)];
135 } else if(addr < 0xfffa) {
136 period += MEM_WAIT_BYTE;
137 return d_mem->read_data8(addr);
138 } else if(addr < 0xfffc) {
140 if(dec_enabled && !(mode & 1)) {
141 tmp = (dec_timer >> 4) & 0xffff;
145 return (addr & 1) ? (tmp & 0xff) : (tmp >> 8);
147 return RAM[BYTE_XOR_BE(addr & 0xff)];
151 void TMS9995::WM8(uint32_t addr, uint8_t val)
154 d_mem_tmp->write_data8(addr, val);
156 void TMS9995::write_data8(uint32_t addr, uint32_t val)
159 if((addr < 0xf000)) {
160 period += MEM_WAIT_BYTE;
161 d_mem->write_data8(addr, val);
162 } else if(addr < 0xf0fc) {
163 RAM[BYTE_XOR_BE(addr & 0xff)] = val;
164 } else if(addr < 0xfffa) {
165 period += MEM_WAIT_BYTE;
166 d_mem->write_data8(addr, val);
167 } else if(addr < 0xfffc) {
168 dec_interval = (val << 8) | val;
171 RAM[BYTE_XOR_BE(addr & 0xff)] = val;
175 inline uint16_t TMS9995::FETCH16()
177 uint16_t tmp = RM16(PC);
182 #define RREG(reg) RM16((WP + (reg)) & 0xffff)
183 #define WREG(reg, val) WM16((WP + (reg)) & 0xffff, (val))
186 uint16_t TMS9995::IN8(int addr)
189 return d_io_tmp->read_io8(addr);
191 uint32_t TMS9995::read_io8(uint32_t addr)
198 return (mode >> 8) & 0xff;
201 return d_io->read_io8(addr) | 0x10;
203 return d_io->read_io8(addr) & ~ 0x10;
206 return d_io->read_io8(addr);
209 void TMS9995::OUT8(uint16_t addr, uint16_t val)
212 d_io_tmp->write_io8(addr, val);
214 void TMS9995::write_io8(uint32_t addr, uint32_t val)
250 mode |= (1 << (addr - 0xf70));
252 mode &= ~(1 << (addr - 0xf70));
256 mid = ((val & 1) != 0);
259 d_io->write_io8(addr, val & 1);
262 inline void TMS9995::EXTOUT8(uint16_t addr)
265 d_io_tmp->write_io8(addr << 15, 0); // or is it 1 ???
267 d_io->write_io8(addr << 15, 0); // or is it 1 ???
271 uint16_t TMS9995::RCRU(uint16_t addr, int bits)
273 static const uint16_t bitmask[] = {
275 0x0001,0x0003,0x0007,0x000f,0x001f,0x003f,0x007f,0x00ff,
276 0x01ff,0x03ff,0x07ff,0x0fff,0x1fff,0x3fff,0x7fff,0xffff
278 uint16_t loc = (uint16_t)((addr >> 3) & CRU_MASK_R);
279 uint16_t ofs = addr & 7;
280 uint16_t val = IN8(loc);
282 if((ofs + bits) > 8) {
283 loc = (uint16_t)((loc + 1) & CRU_MASK_R);
284 val |= IN8(loc) << 8;
285 if((ofs + bits) > 16) {
286 loc = (uint16_t)((loc + 1) & CRU_MASK_R);
287 val |= IN8(loc) << 16;
291 return val & bitmask[bits];
294 void TMS9995::WCRU(uint16_t addr, int bits, uint16_t val)
297 for(int i = 0; i < bits; i++) {
300 addr = (uint16_t)((addr + 1) & CRU_MASK_W);
304 void TMS9995::initialize()
306 DEVICE::initialize();
308 d_mem_tmp = d_io_tmp = this;
309 d_debugger->set_context_mem(this);
310 d_debugger->set_context_io(this);
314 void TMS9995::reset()
325 contextswitch(0x0000);
330 int TMS9995::run(int clock)
334 // run only one opcode
339 // run cpu while given clocks
341 int first_count = count;
346 return first_count - count;
350 void TMS9995::run_one_opecode()
353 bool now_debugging = d_debugger->now_debugging;
355 d_debugger->check_break_points(PC);
356 if(d_debugger->now_suspended) {
358 d_debugger->now_waiting = true;
359 while(d_debugger->now_debugging && d_debugger->now_suspended) {
362 d_debugger->now_waiting = false;
364 if(d_debugger->now_debugging) {
365 d_mem_tmp = d_io_tmp = d_debugger;
367 now_debugging = false;
370 int first_count = count;
371 run_one_opecode_tmp();
372 total_count += first_count - count;
375 if(!d_debugger->now_going) {
376 d_debugger->now_suspended = true;
378 d_mem_tmp = d_io_tmp = this;
381 int first_count = count;
382 run_one_opecode_tmp();
383 total_count += first_count - count;
386 void TMS9995::run_one_opecode_tmp()
392 if(int_pending && int_enabled) {
393 int level = irq_level;
395 contextswitch(0xfffc);
399 } else if(level <= (ST & ST_IM)) {
400 contextswitch(level*4);
402 ST = (ST & ~ST_IM) | (level -1);
411 int int_mask = 1 << level;
412 int mode_mask = (level == 1) ? 4 : int_mask;
413 int_latch &= ~int_mask;
429 d_debugger->add_cpu_trace(PC);
432 uint16_t op = FETCH16();
434 if((ST & ST_OVIE) && (ST & ST_OV) && (irq_level > 2)) {
441 if(dec_enabled && !(mode & 1)) {
449 dec_timer += dec_interval << 4;
454 void TMS9995::write_signal(int id, uint32_t data, uint32_t mask)
456 if(id == SIG_TMS9995_NMI) {
457 nmi = ((data & mask) != 0);
459 } else if(id == SIG_TMS9995_INT1) {
460 set_irq_line(0, ((data & mask) != 0));
461 } else if(id == SIG_TMS9995_INT4) {
462 set_irq_line(1, ((data & mask) != 0));
466 void TMS9995::set_irq_line(int irqline, bool state)
468 int int_mask = (irqline == 0) ? 2 : 0x10;
469 int mode_mask = (irqline == 0) ? 4 : 0x10;
470 bool prev_state = ((int_state & int_mask) != 0);
472 if(prev_state != state) {
474 int_state |= int_mask;
475 if((irqline == 1) && (mode & 1)) {
477 if((--dec_count) == 0) {
481 dec_count = dec_interval;
485 int_latch |= int_mask;
489 int_state &= ~int_mask;
495 void TMS9995::update_int()
502 cur_int = (int_state & ~0x10) | int_latch;
504 cur_int = int_state | int_latch;
507 for (level = 0; !(cur_int & 1); cur_int >>= 1, level++) {
514 int_pending = (level <= (ST & ST_IM));
518 void TMS9995::update_dec()
520 dec_count = dec_interval;
521 dec_enabled = ((mode & 2) && dec_interval);
522 dec_timer = dec_interval << 4;
525 void TMS9995::contextswitch(uint16_t addr)
530 WP = RM16(addr) & ~1;
531 PC = RM16(addr+2) & ~1;
538 void TMS9995::execute(uint16_t op)
547 case 0x02: case 0x03:
550 case 0x04: case 0x05: case 0x06: case 0x07:
553 case 0x08: case 0x09: case 0x0a: case 0x0b:
556 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
559 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
560 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
563 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
564 case 0x28: case 0x29: case 0x2a: case 0x2b:
565 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
568 case 0x2c: case 0x2d: case 0x2e: case 0x2f:
571 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
574 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
575 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
576 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
577 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
578 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
579 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
580 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
581 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
582 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
583 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
584 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
585 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
588 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
589 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
590 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
591 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
592 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
593 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
594 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
595 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
596 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
597 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
598 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
599 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
605 void TMS9995::h0040(uint16_t op)
607 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1;
609 switch((op & 0xf0) >> 4) {
615 WP = RM16(addr) & ~1;
623 void TMS9995::h0100(uint16_t op)
625 uint16_t src = decipheraddr(op) & ~1;
629 switch((op & 0xc0) >> 6) {
631 d = (int16_t)RM16(src);
632 p = (int32_t)((RREG(R0) << 16) | RREG(R1));
634 if((d == 0) || (q < -32768L) || (q > 32767L)) {
646 p = ((int32_t)(int16_t)RM16(src)) * ((int32_t)(int16_t)RREG(R0));
647 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
649 ST |= (ST_LGT | ST_AGT);
665 void TMS9995::h0200(uint16_t op)
667 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1, val;
669 if(((op < 0x2e0) && (op & 0x10)) || ((op >= 0x2e0) && (op & 0x1f))) {
673 switch((op & 0x1e0) >> 5) {
682 val = setst_add_laeco(RM16(addr), val);
688 val = RM16(addr) & val;
695 val = RM16(addr) | val;
702 setst_c_lae(val, RM16(addr));
720 ST = (ST & ~ST_IM) | (val & ST_IM);
739 addr = (WP + R13) & ~1;
740 WP = RM16(addr) & ~1;
742 PC = RM16(addr) & ~1;
752 EXTOUT8((op & 0xe0) >> 5);
758 void TMS9995::h0400(uint16_t op)
760 uint16_t addr = decipheraddr(op) & ~1, val;
762 switch((op & 0x3c0) >> 6) {
781 val = -(int16_t)RM16(addr);
798 val = setst_add_laeco(RM16(addr), 1);
803 val = setst_add_laeco(RM16(addr), 2);
808 val = setst_sub_laeco(RM16(addr), 1);
813 val = setst_sub_laeco(RM16(addr), 2);
824 val = logical_right_shift(val, 8) | (val << 8);
833 ST &= ~ (ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
836 if(((int16_t)val) > 0) {
837 ST |= ST_LGT | ST_AGT;
838 } else if(((int16_t)val) < 0) {
843 val = -((int16_t)val);
855 void TMS9995::h0800(uint16_t op)
857 uint16_t cnt = (op & 0xf0) >> 4;
858 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1, val;
863 cnt = RREG(R0) & 0xf;
870 switch((op & 0x300) >> 8) {
872 val = setst_sra_laec(RM16(addr), cnt);
876 val = setst_srl_laec(RM16(addr), cnt);
880 val = setst_sla_laeco(RM16(addr), cnt);
884 val = setst_src_laec(RM16(addr), cnt);
890 void TMS9995::h1000(uint16_t op)
892 int16_t ofs = (int8_t)op;
894 switch((op & 0xf00) >> 8) {
900 if(!(ST & (ST_AGT | ST_EQ))) {
906 if((!(ST & ST_LGT)) || (ST & ST_EQ)) {
918 if(ST & (ST_LGT | ST_EQ)) {
954 if(!(ST & (ST_LGT | ST_EQ))) {
960 if((ST & ST_LGT) && !(ST & ST_EQ)) {
967 uint8_t a = lastparity;
981 WCRU((RREG(R12) >> 1) + ofs, 1, 1);
985 WCRU((RREG(R12) >> 1) + ofs, 1, 0);
989 setst_e(RCRU((RREG(R12)>> 1) + ofs, 1) & 1, 1);
995 void TMS9995::h2000(uint16_t op)
997 uint16_t src = decipheraddr(op) & ~1;
998 uint16_t dst = ((((op & 0x3c0) >> 6) << 1) + WP) & ~1, val, d, h;
1001 switch((op & 0x1c00) >> 10) {
1004 setst_e(val & RM16(dst), val);
1009 setst_e(val & ~RM16(dst), val);
1013 val = RM16(src) ^ RM16(dst);
1022 p = (uint32_t)RM16(src) * (uint32_t)RM16(dst);
1024 WM16((dst + 2) & 0xffff, p);
1030 p = (((uint32_t)h) << 16) | RM16((dst + 2) & 0xffff);
1031 if(d == 0 || d <= h) {
1037 WM16((dst + 2) & 0xffff, p % d);
1044 void TMS9995::xop(uint16_t op)
1046 uint16_t tmp = (op & 0x3c0) >> 6;
1047 uint16_t val = decipheraddr(op);
1049 contextswitch(0x40 + (tmp << 2));
1053 int_enabled = false;
1056 void TMS9995::ldcr_stcr(uint16_t op)
1058 uint16_t cnt = (op & 0x3c0) >> 6, addr;
1065 addr = decipheraddrbyte(op);
1067 addr = decipheraddr(op) & ~1;
1072 val = RM16(addr & ~1);
1076 val = (val >> 8) & 0xff;
1078 (void)RREG(cnt + cnt);
1079 setst_byte_laep(val);
1082 (void)RREG(cnt + cnt);
1085 WCRU((RREG(R12) >> 1), cnt, val);
1086 period += 36 + cnt + cnt;
1090 int val2 = RM16(addr & ~1);
1091 (void)RREG(cnt + cnt);
1092 val = RCRU((RREG(R12) >> 1), cnt);
1093 setst_byte_laep(val);
1095 WM16(addr & ~1, (val & 0xff) | (val2 & 0xff00));
1097 WM16(addr & ~1, (val2 & 0xff) | ((val << 8) & 0xff00));
1102 (void)RREG(cnt + cnt);
1103 val = RCRU((RREG(R12) >> 1), cnt);
1106 period += 108 + cnt;
1111 void TMS9995::h4000w(uint16_t op)
1113 uint16_t src = decipheraddr(op) & ~1;
1114 uint16_t dst = decipheraddr(op >> 6) & ~1;
1115 uint16_t val = RM16(src);
1117 switch((op >> 13) & 7) {
1119 val = RM16(dst) & ~val;
1125 val = setst_sub_laeco(RM16(dst), val);
1130 setst_c_lae(RM16(dst), val);
1134 val = setst_add_laeco(RM16(dst), val);
1144 val = val | RM16(dst);
1152 void TMS9995::h4000b(uint16_t op)
1154 uint16_t src = decipheraddrbyte(op);
1155 uint16_t dst = decipheraddrbyte(op >> 6);
1156 uint8_t val = RM8(src);
1158 switch((op >> 13) & 7) {
1160 val = RM8(dst) & ~val;
1161 setst_byte_laep(val);
1166 val = setst_subbyte_laecop(RM8(dst), val);
1171 setst_c_lae(RM8(dst) << 8, val << 8);
1176 val = setst_addbyte_laecop(RM8(dst), val);
1181 setst_byte_laep(val);
1186 val = val | RM8(dst);
1187 setst_byte_laep(val);
1194 void TMS9995::illegal(uint16_t op)
1198 ST = (ST & 0xfe00) | 1;
1199 int_enabled = false;
1202 uint16_t TMS9995::decipheraddr(uint16_t op)
1204 uint16_t reg = (op & 0xf) << 1, tmp;
1211 return RM16(reg + WP);
1216 return RM16(reg + WP) + tmp;
1230 uint16_t TMS9995::decipheraddrbyte(uint16_t op)
1232 uint16_t reg = (op & 0xf) << 1, tmp;
1239 return RM16(reg + WP);
1244 return RM16(reg + WP) + tmp;
1258 inline void TMS9995::setstat()
1261 uint8_t p = lastparity;
1262 for(int i = 0; i < 8; i++) {
1270 inline void TMS9995::getstat()
1279 inline uint16_t TMS9995::logical_right_shift(uint16_t val, int c)
1281 return (val >> c) & right_shift_mask_table[c];
1284 inline int16_t TMS9995::arithmetic_right_shift(int16_t val, int c)
1287 return (val >> c) | inverted_right_shift_mask_table[c];
1289 return (val >> c) & right_shift_mask_table[c];
1293 inline void TMS9995::setst_lae(int16_t val)
1295 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1297 ST |= (ST_LGT | ST_AGT);
1298 } else if(val < 0) {
1305 inline void TMS9995::setst_byte_laep(int8_t val)
1307 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1309 ST |= (ST_LGT | ST_AGT);
1310 } else if(val < 0) {
1318 inline void TMS9995::setst_e(uint16_t val, uint16_t to)
1327 inline void TMS9995::setst_c_lae(uint16_t to, uint16_t val)
1329 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1333 if(((int16_t)val) > ((int16_t)to)) {
1336 if(((uint16_t)val) > ((uint16_t)to)) {
1342 inline int16_t TMS9995::setst_add_laeco(int a, int b)
1344 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1345 uint32_t res = (a & 0xffff) + (b & 0xffff);
1349 if((res ^ b) & (res ^ a) & 0x8000) {
1352 int16_t res2 = (int16_t)res;
1354 ST |= ST_LGT | ST_AGT;
1355 } else if(res2 < 0) {
1363 inline int16_t TMS9995::setst_sub_laeco(int a, int b)
1365 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1366 uint32_t res = (a & 0xffff) - (b & 0xffff);
1367 if(!(res & 0x10000)) {
1370 if((a ^ b) & (a ^ res) & 0x8000) {
1373 int16_t res2 = (int16_t)res;
1375 ST |= ST_LGT | ST_AGT;
1376 } else if(res2 < 0) {
1384 inline int8_t TMS9995::setst_addbyte_laecop(int a, int b)
1386 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV | ST_OP);
1387 uint32_t res = (a & 0xff) + (b & 0xff);
1391 if((res ^ b) & (res ^ a) & 0x80) {
1394 int8_t res2 = (int8_t)res;
1396 ST |= ST_LGT | ST_AGT;
1397 } else if(res2 < 0) {
1406 inline int8_t TMS9995::setst_subbyte_laecop(int a, int b)
1408 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV | ST_OP);
1409 uint32_t res = (a & 0xff) - (b & 0xff);
1410 if(!(res & 0x100)) {
1413 if((a ^ b) & (a ^ res) & 0x80) {
1416 int8_t res2 = (int8_t)res;
1418 ST |= ST_LGT | ST_AGT;
1419 } else if(res2 < 0) {
1428 inline void TMS9995::setst_laeo(int16_t val)
1430 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_OV);
1432 ST |= ST_LGT | ST_AGT;
1433 } else if(val < 0) {
1435 if(((uint16_t)val) == 0x8000) {
1443 inline uint16_t TMS9995::setst_sra_laec(int16_t a, uint16_t c)
1445 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1447 a = arithmetic_right_shift(a, c-1);
1451 a = arithmetic_right_shift(a, 1);
1454 ST |= ST_LGT | ST_AGT;
1463 inline uint16_t TMS9995::setst_srl_laec(uint16_t a,uint16_t c)
1465 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1467 a = logical_right_shift(a, c-1);
1471 a = logical_right_shift(a, 1);
1473 if(((int16_t)a) > 0) {
1474 ST |= ST_LGT | ST_AGT;
1475 } else if(((int16_t)a) < 0) {
1483 inline uint16_t TMS9995::setst_src_laec(uint16_t a,uint16_t c)
1485 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1487 a = logical_right_shift(a, c) | (a << (16-c));
1492 if(((int16_t)a) > 0) {
1493 ST |= ST_LGT | ST_AGT;
1494 } else if(((int16_t)a) < 0) {
1502 inline uint16_t TMS9995::setst_sla_laeco(uint16_t a, uint16_t c)
1504 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1506 uint16_t mask = 0xFFFF << (16-c-1);
1507 uint16_t bits = a & mask;
1519 if(((int16_t)a) > 0) {
1520 ST |= ST_LGT | ST_AGT;
1521 } else if(((int16_t)a) < 0) {
1530 void TMS9995::write_debug_data8(uint32_t addr, uint32_t data)
1532 this->write_data8(addr, data);
1535 uint32_t TMS9995::read_debug_data8(uint32_t addr)
1537 return this->read_data8(addr);
1540 void TMS9995::write_debug_data16(uint32_t addr, uint32_t data)
1542 this->write_data16(addr, data);
1545 uint32_t TMS9995::read_debug_data16(uint32_t addr)
1547 return this->read_data16(addr);
1550 void TMS9995::write_debug_io8(uint32_t addr, uint32_t data)
1552 this->write_io8(addr, data);
1555 uint32_t TMS9995::read_debug_io8(uint32_t addr)
1557 return this->read_io8(addr);
1560 bool TMS9995::write_debug_reg(const _TCHAR *reg, uint32_t data)
1562 if(_tcsicmp(reg, _T("PC")) == 0) {
1564 } else if(_tcsicmp(reg, _T("WP")) == 0) {
1566 } else if(_tcsicmp(reg, _T("ST")) == 0) {
1568 } else if(_tcsicmp(reg, _T("R0")) == 0) {
1569 this->write_data16((WP + R0 ) & 0xffff, data);
1570 } else if(_tcsicmp(reg, _T("R1")) == 0) {
1571 this->write_data16((WP + R1 ) & 0xffff, data);
1572 } else if(_tcsicmp(reg, _T("R2")) == 0) {
1573 this->write_data16((WP + R2 ) & 0xffff, data);
1574 } else if(_tcsicmp(reg, _T("R3")) == 0) {
1575 this->write_data16((WP + R3 ) & 0xffff, data);
1576 } else if(_tcsicmp(reg, _T("R4")) == 0) {
1577 this->write_data16((WP + R4 ) & 0xffff, data);
1578 } else if(_tcsicmp(reg, _T("R5")) == 0) {
1579 this->write_data16((WP + R5 ) & 0xffff, data);
1580 } else if(_tcsicmp(reg, _T("R6")) == 0) {
1581 this->write_data16((WP + R6 ) & 0xffff, data);
1582 } else if(_tcsicmp(reg, _T("R7")) == 0) {
1583 this->write_data16((WP + R7 ) & 0xffff, data);
1584 } else if(_tcsicmp(reg, _T("R8")) == 0) {
1585 this->write_data16((WP + R8 ) & 0xffff, data);
1586 } else if(_tcsicmp(reg, _T("R9")) == 0) {
1587 this->write_data16((WP + R9 ) & 0xffff, data);
1588 } else if(_tcsicmp(reg, _T("R10")) == 0) {
1589 this->write_data16((WP + R10) & 0xffff, data);
1590 } else if(_tcsicmp(reg, _T("R11")) == 0) {
1591 this->write_data16((WP + R11) & 0xffff, data);
1592 } else if(_tcsicmp(reg, _T("R12")) == 0) {
1593 this->write_data16((WP + R12) & 0xffff, data);
1594 } else if(_tcsicmp(reg, _T("R13")) == 0) {
1595 this->write_data16((WP + R13) & 0xffff, data);
1596 } else if(_tcsicmp(reg, _T("R14")) == 0) {
1597 this->write_data16((WP + R14) & 0xffff, data);
1598 } else if(_tcsicmp(reg, _T("R15")) == 0) {
1599 this->write_data16((WP + R15) & 0xffff, data);
1606 void TMS9995::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
1609 ST = 0000 [LGT:0 AGT:0 EQ:0 C:0 OV:0 OP:0 X:0 OVIE:0 IM:0]
1611 R0 = 0000 R1 = 0000 R2 = 0000 R3 = 0000 R4 = 0000 R5 = 0000 R6 = 0000 R7 = 0000
1612 R8 = 0000 R9 = 0000 R10= 0000 R11= 0000 R12= 0000 R13= 0000 R14= 0000 R15= 0000
1613 Clocks = 0 (0) Since Scanline = 0/0 (0/0)
1615 my_stprintf_s(buffer, buffer_len,
1616 _T("ST = %04X [LGT:%01X AGT:%01X EQ:%01X C:%01X OV:%01X OP:%01X X:%01X OVIE:%01X IM:%01X]\nPC = %04X WP = %04X\nR0 = %04X R1 = %04X R2 = %04X R3 = %04X R4 = %04X R5 = %04X R6 = %04X R7 = %04X\nR8 = %04X R9 = %04X R10= %04X R11= %04X R12= %04X R13= %04X R14= %04X R15= %04X\nClocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
1618 (ST & ST_LGT ) ? 1 : 0,
1619 (ST & ST_AGT ) ? 1 : 0,
1620 (ST & ST_EQ ) ? 1 : 0,
1621 (ST & ST_C ) ? 1 : 0,
1622 (ST & ST_OV ) ? 1 : 0,
1623 (ST & ST_OP ) ? 1 : 0,
1624 (ST & ST_LGT ) ? 1 : 0,
1625 (ST & ST_OVIE) ? 1 : 0,
1628 this->read_data16((WP + R0 ) & 0xffff),
1629 this->read_data16((WP + R1 ) & 0xffff),
1630 this->read_data16((WP + R2 ) & 0xffff),
1631 this->read_data16((WP + R3 ) & 0xffff),
1632 this->read_data16((WP + R4 ) & 0xffff),
1633 this->read_data16((WP + R5 ) & 0xffff),
1634 this->read_data16((WP + R6 ) & 0xffff),
1635 this->read_data16((WP + R7 ) & 0xffff),
1636 this->read_data16((WP + R8 ) & 0xffff),
1637 this->read_data16((WP + R9 ) & 0xffff),
1638 this->read_data16((WP + R10) & 0xffff),
1639 this->read_data16((WP + R11) & 0xffff),
1640 this->read_data16((WP + R12) & 0xffff),
1641 this->read_data16((WP + R13) & 0xffff),
1642 this->read_data16((WP + R14) & 0xffff),
1643 this->read_data16((WP + R15) & 0xffff),
1644 total_count, total_count - prev_total_count,
1645 get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
1646 prev_total_count = total_count;
1651 typedef UINT32 offs_t;
1654 #define logerror(...)
1658 #define INLINE inline
1661 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name
1662 #define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol)
1663 #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, opram, d_debugger->first_symbol)
1665 const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
1666 const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
1667 const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
1668 const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
1669 const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
1670 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
1686 #include "mame/emu/cpu/tms9900/9900dasm.c"
1688 int TMS9995::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
1690 UINT8 oprom[16], opram[16];
1691 for(int i = 0; i < 16; i++) {
1692 oprom[i] = opram[i] = this->read_data8((pc + i) & 0xffff);
1694 return CPU_DISASSEMBLE_CALL(tms9995) & DASMFLAG_LENGTHMASK;
1698 #define STATE_VERSION 2
1700 bool TMS9995::process_state(FILEIO* state_fio, bool loading)
1702 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1705 if(!state_fio->StateCheckInt32(this_device_id)) {
1709 state_fio->StateUint64(total_count);
1711 state_fio->StateInt32(count);
1712 state_fio->StateInt32(period);
1713 state_fio->StateUint16(WP);
1714 state_fio->StateUint16(PC);
1715 state_fio->StateUint16(prevPC);
1716 state_fio->StateUint16(ST);
1717 state_fio->StateBuffer(RAM, sizeof(RAM), 1);
1718 state_fio->StateUint8(irq_level);
1719 state_fio->StateUint8(int_state);
1720 state_fio->StateUint8(int_latch);
1721 state_fio->StateBool(int_pending);
1722 state_fio->StateBool(int_enabled);
1723 state_fio->StateUint16(dec_count);
1724 state_fio->StateUint16(dec_interval);
1725 state_fio->StateInt32(dec_timer);
1726 state_fio->StateBool(dec_enabled);
1727 state_fio->StateUint16(mode);
1728 state_fio->StateUint8(lastparity);
1729 state_fio->StateBool(nmi);
1730 state_fio->StateBool(mid);
1731 state_fio->StateBool(idle);
1736 prev_total_count = total_count;