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) {
357 d_debugger->now_waiting = true;
358 emu->start_waiting_in_debugger();
359 while(d_debugger->now_debugging && d_debugger->now_suspended) {
360 emu->process_waiting_in_debugger();
362 emu->finish_waiting_in_debugger();
363 d_debugger->now_waiting = false;
365 if(d_debugger->now_debugging) {
366 d_mem_tmp = d_io_tmp = d_debugger;
368 now_debugging = false;
371 int first_count = count;
372 run_one_opecode_tmp();
373 total_count += first_count - count;
376 if(!d_debugger->now_going) {
377 d_debugger->now_suspended = true;
379 d_mem_tmp = d_io_tmp = this;
382 int first_count = count;
383 run_one_opecode_tmp();
384 total_count += first_count - count;
387 void TMS9995::run_one_opecode_tmp()
393 if(int_pending && int_enabled) {
394 int level = irq_level;
396 contextswitch(0xfffc);
400 } else if(level <= (ST & ST_IM)) {
401 contextswitch(level*4);
403 ST = (ST & ~ST_IM) | (level -1);
412 int int_mask = 1 << level;
413 int mode_mask = (level == 1) ? 4 : int_mask;
414 int_latch &= ~int_mask;
430 d_debugger->add_cpu_trace(PC);
433 uint16_t op = FETCH16();
435 if((ST & ST_OVIE) && (ST & ST_OV) && (irq_level > 2)) {
442 if(dec_enabled && !(mode & 1)) {
450 dec_timer += dec_interval << 4;
455 void TMS9995::write_signal(int id, uint32_t data, uint32_t mask)
457 if(id == SIG_TMS9995_NMI) {
458 nmi = ((data & mask) != 0);
460 } else if(id == SIG_TMS9995_INT1) {
461 set_irq_line(0, ((data & mask) != 0));
462 } else if(id == SIG_TMS9995_INT4) {
463 set_irq_line(1, ((data & mask) != 0));
467 void TMS9995::set_irq_line(int irqline, bool state)
469 int int_mask = (irqline == 0) ? 2 : 0x10;
470 int mode_mask = (irqline == 0) ? 4 : 0x10;
471 bool prev_state = ((int_state & int_mask) != 0);
473 if(prev_state != state) {
475 int_state |= int_mask;
476 if((irqline == 1) && (mode & 1)) {
478 if((--dec_count) == 0) {
482 dec_count = dec_interval;
486 int_latch |= int_mask;
490 int_state &= ~int_mask;
496 void TMS9995::update_int()
503 cur_int = (int_state & ~0x10) | int_latch;
505 cur_int = int_state | int_latch;
508 for(level = 0; !(cur_int & 1); cur_int >>= 1, level++) {
515 int_pending = (level <= (ST & ST_IM));
519 void TMS9995::update_dec()
521 dec_count = dec_interval;
522 dec_enabled = ((mode & 2) && dec_interval);
523 dec_timer = dec_interval << 4;
526 void TMS9995::contextswitch(uint16_t addr)
531 WP = RM16(addr) & ~1;
532 PC = RM16(addr+2) & ~1;
539 void TMS9995::execute(uint16_t op)
548 case 0x02: case 0x03:
551 case 0x04: case 0x05: case 0x06: case 0x07:
554 case 0x08: case 0x09: case 0x0a: case 0x0b:
557 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
560 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
561 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
564 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
565 case 0x28: case 0x29: case 0x2a: case 0x2b:
566 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
569 case 0x2c: case 0x2d: case 0x2e: case 0x2f:
572 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
575 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
576 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
577 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
578 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
579 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
580 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
581 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
582 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
583 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
584 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
585 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
586 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
589 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
590 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
591 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
592 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
593 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
594 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
595 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
596 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
597 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
598 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
599 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
600 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
606 void TMS9995::h0040(uint16_t op)
608 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1;
610 switch((op & 0xf0) >> 4) {
616 WP = RM16(addr) & ~1;
624 void TMS9995::h0100(uint16_t op)
626 uint16_t src = decipheraddr(op) & ~1;
630 switch((op & 0xc0) >> 6) {
632 d = (int16_t)RM16(src);
633 p = (int32_t)((RREG(R0) << 16) | RREG(R1));
635 if((d == 0) || (q < -32768L) || (q > 32767L)) {
647 p = ((int32_t)(int16_t)RM16(src)) * ((int32_t)(int16_t)RREG(R0));
648 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
650 ST |= (ST_LGT | ST_AGT);
666 void TMS9995::h0200(uint16_t op)
668 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1, val;
670 if(((op < 0x2e0) && (op & 0x10)) || ((op >= 0x2e0) && (op & 0x1f))) {
674 switch((op & 0x1e0) >> 5) {
683 val = setst_add_laeco(RM16(addr), val);
689 val = RM16(addr) & val;
696 val = RM16(addr) | val;
703 setst_c_lae(val, RM16(addr));
721 ST = (ST & ~ST_IM) | (val & ST_IM);
740 addr = (WP + R13) & ~1;
741 WP = RM16(addr) & ~1;
743 PC = RM16(addr) & ~1;
753 EXTOUT8((op & 0xe0) >> 5);
759 void TMS9995::h0400(uint16_t op)
761 uint16_t addr = decipheraddr(op) & ~1, val;
763 switch((op & 0x3c0) >> 6) {
782 val = -(int16_t)RM16(addr);
799 val = setst_add_laeco(RM16(addr), 1);
804 val = setst_add_laeco(RM16(addr), 2);
809 val = setst_sub_laeco(RM16(addr), 1);
814 val = setst_sub_laeco(RM16(addr), 2);
825 val = logical_right_shift(val, 8) | (val << 8);
834 ST &= ~ (ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
837 if(((int16_t)val) > 0) {
838 ST |= ST_LGT | ST_AGT;
839 } else if(((int16_t)val) < 0) {
844 val = -((int16_t)val);
856 void TMS9995::h0800(uint16_t op)
858 uint16_t cnt = (op & 0xf0) >> 4;
859 uint16_t addr = (((op & 0xf) << 1) + WP) & ~1, val;
864 cnt = RREG(R0) & 0xf;
871 switch((op & 0x300) >> 8) {
873 val = setst_sra_laec(RM16(addr), cnt);
877 val = setst_srl_laec(RM16(addr), cnt);
881 val = setst_sla_laeco(RM16(addr), cnt);
885 val = setst_src_laec(RM16(addr), cnt);
891 void TMS9995::h1000(uint16_t op)
893 int16_t ofs = (int8_t)op;
895 switch((op & 0xf00) >> 8) {
901 if(!(ST & (ST_AGT | ST_EQ))) {
907 if((!(ST & ST_LGT)) || (ST & ST_EQ)) {
919 if(ST & (ST_LGT | ST_EQ)) {
955 if(!(ST & (ST_LGT | ST_EQ))) {
961 if((ST & ST_LGT) && !(ST & ST_EQ)) {
968 uint8_t a = lastparity;
982 WCRU((RREG(R12) >> 1) + ofs, 1, 1);
986 WCRU((RREG(R12) >> 1) + ofs, 1, 0);
990 setst_e(RCRU((RREG(R12)>> 1) + ofs, 1) & 1, 1);
996 void TMS9995::h2000(uint16_t op)
998 uint16_t src = decipheraddr(op) & ~1;
999 uint16_t dst = ((((op & 0x3c0) >> 6) << 1) + WP) & ~1, val, d, h;
1002 switch((op & 0x1c00) >> 10) {
1005 setst_e(val & RM16(dst), val);
1010 setst_e(val & ~RM16(dst), val);
1014 val = RM16(src) ^ RM16(dst);
1023 p = (uint32_t)RM16(src) * (uint32_t)RM16(dst);
1025 WM16((dst + 2) & 0xffff, p);
1031 p = (((uint32_t)h) << 16) | RM16((dst + 2) & 0xffff);
1032 if(d == 0 || d <= h) {
1038 WM16((dst + 2) & 0xffff, p % d);
1045 void TMS9995::xop(uint16_t op)
1047 uint16_t tmp = (op & 0x3c0) >> 6;
1048 uint16_t val = decipheraddr(op);
1050 contextswitch(0x40 + (tmp << 2));
1054 int_enabled = false;
1057 void TMS9995::ldcr_stcr(uint16_t op)
1059 uint16_t cnt = (op & 0x3c0) >> 6, addr;
1066 addr = decipheraddrbyte(op);
1068 addr = decipheraddr(op) & ~1;
1073 val = RM16(addr & ~1);
1077 val = (val >> 8) & 0xff;
1079 (void)RREG(cnt + cnt);
1080 setst_byte_laep(val);
1083 (void)RREG(cnt + cnt);
1086 WCRU((RREG(R12) >> 1), cnt, val);
1087 period += 36 + cnt + cnt;
1091 int val2 = RM16(addr & ~1);
1092 (void)RREG(cnt + cnt);
1093 val = RCRU((RREG(R12) >> 1), cnt);
1094 setst_byte_laep(val);
1096 WM16(addr & ~1, (val & 0xff) | (val2 & 0xff00));
1098 WM16(addr & ~1, (val2 & 0xff) | ((val << 8) & 0xff00));
1103 (void)RREG(cnt + cnt);
1104 val = RCRU((RREG(R12) >> 1), cnt);
1107 period += 108 + cnt;
1112 void TMS9995::h4000w(uint16_t op)
1114 uint16_t src = decipheraddr(op) & ~1;
1115 uint16_t dst = decipheraddr(op >> 6) & ~1;
1116 uint16_t val = RM16(src);
1118 switch((op >> 13) & 7) {
1120 val = RM16(dst) & ~val;
1126 val = setst_sub_laeco(RM16(dst), val);
1131 setst_c_lae(RM16(dst), val);
1135 val = setst_add_laeco(RM16(dst), val);
1145 val = val | RM16(dst);
1153 void TMS9995::h4000b(uint16_t op)
1155 uint16_t src = decipheraddrbyte(op);
1156 uint16_t dst = decipheraddrbyte(op >> 6);
1157 uint8_t val = RM8(src);
1159 switch((op >> 13) & 7) {
1161 val = RM8(dst) & ~val;
1162 setst_byte_laep(val);
1167 val = setst_subbyte_laecop(RM8(dst), val);
1172 setst_c_lae(RM8(dst) << 8, val << 8);
1177 val = setst_addbyte_laecop(RM8(dst), val);
1182 setst_byte_laep(val);
1187 val = val | RM8(dst);
1188 setst_byte_laep(val);
1195 void TMS9995::illegal(uint16_t op)
1199 ST = (ST & 0xfe00) | 1;
1200 int_enabled = false;
1203 uint16_t TMS9995::decipheraddr(uint16_t op)
1205 uint16_t reg = (op & 0xf) << 1, tmp;
1212 return RM16(reg + WP);
1217 return RM16(reg + WP) + tmp;
1231 uint16_t TMS9995::decipheraddrbyte(uint16_t op)
1233 uint16_t reg = (op & 0xf) << 1, tmp;
1240 return RM16(reg + WP);
1245 return RM16(reg + WP) + tmp;
1259 inline void TMS9995::setstat()
1262 uint8_t p = lastparity;
1263 for(int i = 0; i < 8; i++) {
1271 inline void TMS9995::getstat()
1280 inline uint16_t TMS9995::logical_right_shift(uint16_t val, int c)
1282 return (val >> c) & right_shift_mask_table[c];
1285 inline int16_t TMS9995::arithmetic_right_shift(int16_t val, int c)
1288 return (val >> c) | inverted_right_shift_mask_table[c];
1290 return (val >> c) & right_shift_mask_table[c];
1294 inline void TMS9995::setst_lae(int16_t val)
1296 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1298 ST |= (ST_LGT | ST_AGT);
1299 } else if(val < 0) {
1306 inline void TMS9995::setst_byte_laep(int8_t val)
1308 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1310 ST |= (ST_LGT | ST_AGT);
1311 } else if(val < 0) {
1319 inline void TMS9995::setst_e(uint16_t val, uint16_t to)
1328 inline void TMS9995::setst_c_lae(uint16_t to, uint16_t val)
1330 ST &= ~(ST_LGT | ST_AGT | ST_EQ);
1334 if(((int16_t)val) > ((int16_t)to)) {
1337 if(((uint16_t)val) > ((uint16_t)to)) {
1343 inline int16_t TMS9995::setst_add_laeco(int a, int b)
1345 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1346 uint32_t res = (a & 0xffff) + (b & 0xffff);
1350 if((res ^ b) & (res ^ a) & 0x8000) {
1353 int16_t res2 = (int16_t)res;
1355 ST |= ST_LGT | ST_AGT;
1356 } else if(res2 < 0) {
1364 inline int16_t TMS9995::setst_sub_laeco(int a, int b)
1366 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1367 uint32_t res = (a & 0xffff) - (b & 0xffff);
1368 if(!(res & 0x10000)) {
1371 if((a ^ b) & (a ^ res) & 0x8000) {
1374 int16_t res2 = (int16_t)res;
1376 ST |= ST_LGT | ST_AGT;
1377 } else if(res2 < 0) {
1385 inline int8_t TMS9995::setst_addbyte_laecop(int a, int b)
1387 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV | ST_OP);
1388 uint32_t res = (a & 0xff) + (b & 0xff);
1392 if((res ^ b) & (res ^ a) & 0x80) {
1395 int8_t res2 = (int8_t)res;
1397 ST |= ST_LGT | ST_AGT;
1398 } else if(res2 < 0) {
1407 inline int8_t TMS9995::setst_subbyte_laecop(int a, int b)
1409 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV | ST_OP);
1410 uint32_t res = (a & 0xff) - (b & 0xff);
1411 if(!(res & 0x100)) {
1414 if((a ^ b) & (a ^ res) & 0x80) {
1417 int8_t res2 = (int8_t)res;
1419 ST |= ST_LGT | ST_AGT;
1420 } else if(res2 < 0) {
1429 inline void TMS9995::setst_laeo(int16_t val)
1431 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_OV);
1433 ST |= ST_LGT | ST_AGT;
1434 } else if(val < 0) {
1436 if(((uint16_t)val) == 0x8000) {
1444 inline uint16_t TMS9995::setst_sra_laec(int16_t a, uint16_t c)
1446 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1448 a = arithmetic_right_shift(a, c-1);
1452 a = arithmetic_right_shift(a, 1);
1455 ST |= ST_LGT | ST_AGT;
1464 inline uint16_t TMS9995::setst_srl_laec(uint16_t a,uint16_t c)
1466 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1468 a = logical_right_shift(a, c-1);
1472 a = logical_right_shift(a, 1);
1474 if(((int16_t)a) > 0) {
1475 ST |= ST_LGT | ST_AGT;
1476 } else if(((int16_t)a) < 0) {
1484 inline uint16_t TMS9995::setst_src_laec(uint16_t a,uint16_t c)
1486 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C);
1488 a = logical_right_shift(a, c) | (a << (16-c));
1493 if(((int16_t)a) > 0) {
1494 ST |= ST_LGT | ST_AGT;
1495 } else if(((int16_t)a) < 0) {
1503 inline uint16_t TMS9995::setst_sla_laeco(uint16_t a, uint16_t c)
1505 ST &= ~(ST_LGT | ST_AGT | ST_EQ | ST_C | ST_OV);
1507 uint16_t mask = 0xFFFF << (16-c-1);
1508 uint16_t bits = a & mask;
1520 if(((int16_t)a) > 0) {
1521 ST |= ST_LGT | ST_AGT;
1522 } else if(((int16_t)a) < 0) {
1531 void TMS9995::write_debug_data8(uint32_t addr, uint32_t data)
1533 this->write_data8(addr, data);
1536 uint32_t TMS9995::read_debug_data8(uint32_t addr)
1538 return this->read_data8(addr);
1541 void TMS9995::write_debug_data16(uint32_t addr, uint32_t data)
1543 this->write_data16(addr, data);
1546 uint32_t TMS9995::read_debug_data16(uint32_t addr)
1548 return this->read_data16(addr);
1551 void TMS9995::write_debug_io8(uint32_t addr, uint32_t data)
1553 this->write_io8(addr, data);
1556 uint32_t TMS9995::read_debug_io8(uint32_t addr)
1558 return this->read_io8(addr);
1561 bool TMS9995::write_debug_reg(const _TCHAR *reg, uint32_t data)
1563 if(_tcsicmp(reg, _T("PC")) == 0) {
1565 } else if(_tcsicmp(reg, _T("WP")) == 0) {
1567 } else if(_tcsicmp(reg, _T("ST")) == 0) {
1569 } else if(_tcsicmp(reg, _T("R0")) == 0) {
1570 this->write_data16((WP + R0 ) & 0xffff, data);
1571 } else if(_tcsicmp(reg, _T("R1")) == 0) {
1572 this->write_data16((WP + R1 ) & 0xffff, data);
1573 } else if(_tcsicmp(reg, _T("R2")) == 0) {
1574 this->write_data16((WP + R2 ) & 0xffff, data);
1575 } else if(_tcsicmp(reg, _T("R3")) == 0) {
1576 this->write_data16((WP + R3 ) & 0xffff, data);
1577 } else if(_tcsicmp(reg, _T("R4")) == 0) {
1578 this->write_data16((WP + R4 ) & 0xffff, data);
1579 } else if(_tcsicmp(reg, _T("R5")) == 0) {
1580 this->write_data16((WP + R5 ) & 0xffff, data);
1581 } else if(_tcsicmp(reg, _T("R6")) == 0) {
1582 this->write_data16((WP + R6 ) & 0xffff, data);
1583 } else if(_tcsicmp(reg, _T("R7")) == 0) {
1584 this->write_data16((WP + R7 ) & 0xffff, data);
1585 } else if(_tcsicmp(reg, _T("R8")) == 0) {
1586 this->write_data16((WP + R8 ) & 0xffff, data);
1587 } else if(_tcsicmp(reg, _T("R9")) == 0) {
1588 this->write_data16((WP + R9 ) & 0xffff, data);
1589 } else if(_tcsicmp(reg, _T("R10")) == 0) {
1590 this->write_data16((WP + R10) & 0xffff, data);
1591 } else if(_tcsicmp(reg, _T("R11")) == 0) {
1592 this->write_data16((WP + R11) & 0xffff, data);
1593 } else if(_tcsicmp(reg, _T("R12")) == 0) {
1594 this->write_data16((WP + R12) & 0xffff, data);
1595 } else if(_tcsicmp(reg, _T("R13")) == 0) {
1596 this->write_data16((WP + R13) & 0xffff, data);
1597 } else if(_tcsicmp(reg, _T("R14")) == 0) {
1598 this->write_data16((WP + R14) & 0xffff, data);
1599 } else if(_tcsicmp(reg, _T("R15")) == 0) {
1600 this->write_data16((WP + R15) & 0xffff, data);
1607 bool TMS9995::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
1610 ST = 0000 [LGT:0 AGT:0 EQ:0 C:0 OV:0 OP:0 X:0 OVIE:0 IM:0]
1612 R0 = 0000 R1 = 0000 R2 = 0000 R3 = 0000 R4 = 0000 R5 = 0000 R6 = 0000 R7 = 0000
1613 R8 = 0000 R9 = 0000 R10= 0000 R11= 0000 R12= 0000 R13= 0000 R14= 0000 R15= 0000
1614 Clocks = 0 (0) Since Scanline = 0/0 (0/0)
1616 my_stprintf_s(buffer, buffer_len,
1617 _T("ST = %04X [LGT:%01X AGT:%01X EQ:%01X C:%01X OV:%01X OP:%01X X:%01X OVIE:%01X IM:%01X]\n")
1618 _T("PC = %04X WP = %04X\n")
1619 _T("R0 = %04X R1 = %04X R2 = %04X R3 = %04X R4 = %04X R5 = %04X R6 = %04X R7 = %04X\n")
1620 _T("R8 = %04X R9 = %04X R10= %04X R11= %04X R12= %04X R13= %04X R14= %04X R15= %04X\n")
1621 _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
1623 (ST & ST_LGT ) ? 1 : 0,
1624 (ST & ST_AGT ) ? 1 : 0,
1625 (ST & ST_EQ ) ? 1 : 0,
1626 (ST & ST_C ) ? 1 : 0,
1627 (ST & ST_OV ) ? 1 : 0,
1628 (ST & ST_OP ) ? 1 : 0,
1629 (ST & ST_LGT ) ? 1 : 0,
1630 (ST & ST_OVIE) ? 1 : 0,
1633 this->read_data16((WP + R0 ) & 0xffff),
1634 this->read_data16((WP + R1 ) & 0xffff),
1635 this->read_data16((WP + R2 ) & 0xffff),
1636 this->read_data16((WP + R3 ) & 0xffff),
1637 this->read_data16((WP + R4 ) & 0xffff),
1638 this->read_data16((WP + R5 ) & 0xffff),
1639 this->read_data16((WP + R6 ) & 0xffff),
1640 this->read_data16((WP + R7 ) & 0xffff),
1641 this->read_data16((WP + R8 ) & 0xffff),
1642 this->read_data16((WP + R9 ) & 0xffff),
1643 this->read_data16((WP + R10) & 0xffff),
1644 this->read_data16((WP + R11) & 0xffff),
1645 this->read_data16((WP + R12) & 0xffff),
1646 this->read_data16((WP + R13) & 0xffff),
1647 this->read_data16((WP + R14) & 0xffff),
1648 this->read_data16((WP + R15) & 0xffff),
1649 total_count, total_count - prev_total_count,
1650 get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
1651 prev_total_count = total_count;
1657 typedef UINT32 offs_t;
1660 #define logerror(...)
1664 #define INLINE inline
1667 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name
1668 #define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol)
1669 #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, opram, d_debugger->first_symbol)
1671 const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
1672 const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
1673 const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
1674 const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
1675 const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
1676 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
1692 #include "mame/emu/cpu/tms9900/9900dasm.c"
1694 int TMS9995::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata)
1696 UINT8 oprom[16], opram[16];
1697 for(int i = 0; i < 16; i++) {
1698 oprom[i] = opram[i] = this->read_data8((pc + i) & 0xffff);
1700 return CPU_DISASSEMBLE_CALL(tms9995) & DASMFLAG_LENGTHMASK;
1704 #define STATE_VERSION 2
1706 bool TMS9995::process_state(FILEIO* state_fio, bool loading)
1708 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1711 if(!state_fio->StateCheckInt32(this_device_id)) {
1715 state_fio->StateValue(total_count);
1717 state_fio->StateValue(count);
1718 state_fio->StateValue(period);
1719 state_fio->StateValue(WP);
1720 state_fio->StateValue(PC);
1721 state_fio->StateValue(prevPC);
1722 state_fio->StateValue(ST);
1723 state_fio->StateArray(RAM, sizeof(RAM), 1);
1724 state_fio->StateValue(irq_level);
1725 state_fio->StateValue(int_state);
1726 state_fio->StateValue(int_latch);
1727 state_fio->StateValue(int_pending);
1728 state_fio->StateValue(int_enabled);
1729 state_fio->StateValue(dec_count);
1730 state_fio->StateValue(dec_interval);
1731 state_fio->StateValue(dec_timer);
1732 state_fio->StateValue(dec_enabled);
1733 state_fio->StateValue(mode);
1734 state_fio->StateValue(lastparity);
1735 state_fio->StateValue(nmi);
1736 state_fio->StateValue(mid);
1737 state_fio->StateValue(idle);
1742 prev_total_count = total_count;