1 // license:BSD-3-Clause
2 // copyright-holders:ElSemi
3 #include "emu.h"
4 #include "se3208.h"
5 #include "se3208dis.h"
6
7 #include "debugger.h"
8
9
10 /*
11 SE3208 CPU Emulator by ElSemi
12
13 For information about this CPU:
14 www.adc.co.kr
15
16 */
17
18
19 #define FLAG_C 0x0080
20 #define FLAG_V 0x0010
21 #define FLAG_S 0x0020
22 #define FLAG_Z 0x0040
23
24 #define FLAG_M 0x0200
25 #define FLAG_E 0x0800
26 #define FLAG_AUT 0x1000
27 #define FLAG_ENI 0x2000
28 #define FLAG_NMI 0x4000
29
30 #define CLRFLAG(f) m_SR&=~(f);
31 #define SETFLAG(f) m_SR|=(f);
32 #define TESTFLAG(f) (m_SR&(f))
33
34 #define EXTRACT(val,sbit,ebit) (((val)>>sbit)&((1<<((ebit-sbit)+1))-1))
35 #define SEX8(val) ((val&0x80)?(val|0xFFFFFF00):(val&0xFF))
36 #define SEX16(val) ((val&0x8000)?(val|0xFFFF0000):(val&0xFFFF))
37 #define ZEX8(val) ((val)&0xFF)
38 #define ZEX16(val) ((val)&0xFFFF)
39 #define SEX(bits,val) ((val)&(1<<(bits-1))?((val)|(~((1<<bits)-1))):(val&((1<<bits)-1)))
40
41 //Precompute the instruction decoding in a big table
42 #define INST(a) void se3208_device::a(uint16_t Opcode)
43
44 // officeye and donghaer perform unaligned DWORD accesses, allowing them to happen causes the games to malfunction.
45 // are such accesses simply illegal, be handled in a different way, or simply not be happening in the first place?
46 #define ALLOW_UNALIGNED_DWORD_ACCESS 0
47
48 DEFINE_DEVICE_TYPE(SE3208, se3208_device, "se3208", "ADChips SE3208")
49
50
se3208_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)51 se3208_device::se3208_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
52 : cpu_device(mconfig, SE3208, tag, owner, clock)
53 , m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0)
54 , m_machinex_cb(*this)
55 , m_iackx_cb(*this)
56 , m_PC(0), m_SR(0), m_SP(0), m_ER(0), m_PPC(0), m_IRQ(0), m_NMI(0), m_icount(0)
57 {
58 }
59
memory_space_config() const60 device_memory_interface::space_config_vector se3208_device::memory_space_config() const
61 {
62 return space_config_vector {
63 std::make_pair(AS_PROGRAM, &m_program_config)
64 };
65 }
66
67
device_resolve_objects()68 void se3208_device::device_resolve_objects()
69 {
70 m_machinex_cb.resolve_safe();
71 m_iackx_cb.resolve_safe(0);
72 }
73
74
SE3208_Read8(uint32_t address)75 uint8_t se3208_device::SE3208_Read8(uint32_t address)
76 {
77 return m_program.read_byte(address);
78 }
79
SE3208_Read16(uint32_t address)80 uint16_t se3208_device::SE3208_Read16(uint32_t address)
81 {
82 if (!WORD_ALIGNED(address))
83 return m_program.read_byte(address) | m_program.read_byte(address+1)<<8;
84 else
85 return m_program.read_word(address);
86 }
87
SE3208_Read32(uint32_t address)88 uint32_t se3208_device::SE3208_Read32(uint32_t address)
89 {
90 if (DWORD_ALIGNED(address))
91 return m_program.read_dword(address);
92 else
93 {
94 osd_printf_debug("%08x: dword READ unaligned %08x\n", m_PC, address);
95 #if ALLOW_UNALIGNED_DWORD_ACCESS
96 return m_program.read_byte(address) | m_program.read_byte(address + 1) << 8 | m_program.read_byte(address + 2) << 16 | m_program.read_byte(address + 3) << 24;
97 #else
98 return 0;
99 #endif
100 }
101 }
102
SE3208_Write8(uint32_t address,uint8_t data)103 void se3208_device::SE3208_Write8(uint32_t address,uint8_t data)
104 {
105 m_program.write_byte(address,data);
106 }
107
SE3208_Write16(uint32_t address,uint16_t data)108 void se3208_device::SE3208_Write16(uint32_t address,uint16_t data)
109 {
110 if (!WORD_ALIGNED(address))
111 {
112 m_program.write_byte(address, data & 0xff);
113 m_program.write_byte(address+1, (data>>8)&0xff);
114 }
115 else
116 {
117 m_program.write_word(address, data);
118 }
119 }
120
SE3208_Write32(uint32_t address,uint32_t data)121 void se3208_device::SE3208_Write32(uint32_t address, uint32_t data)
122 {
123 if (DWORD_ALIGNED(address))
124 m_program.write_dword(address, data);
125 else
126 {
127 #if ALLOW_UNALIGNED_DWORD_ACCESS
128 m_program.write_byte(address, data & 0xff);
129 m_program.write_byte(address + 1, (data >> 8) & 0xff);
130 m_program.write_byte(address + 2, (data >> 16) & 0xff);
131 m_program.write_byte(address + 3, (data >> 24) & 0xff);
132 #endif
133 osd_printf_debug("%08x: dword WRITE unaligned %08x\n", m_PC, address);
134 }
135 }
136
137
138
AddWithFlags(uint32_t a,uint32_t b)139 uint32_t se3208_device::AddWithFlags(uint32_t a,uint32_t b)
140 {
141 uint32_t r=a+b;
142 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
143 if(!r)
144 SETFLAG(FLAG_Z);
145 if(r&0x80000000)
146 SETFLAG(FLAG_S);
147 if(((((a&b)|(~r&(a|b)))>>31))&1)
148 SETFLAG(FLAG_C);
149 if(((((a^r)&(b^r))>>31))&1)
150 SETFLAG(FLAG_V);
151 return r;
152 }
153
SubWithFlags(uint32_t a,uint32_t b)154 uint32_t se3208_device::SubWithFlags(uint32_t a,uint32_t b) //a-b
155 {
156 uint32_t r=a-b;
157 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
158 if(!r)
159 SETFLAG(FLAG_Z);
160 if(r&0x80000000)
161 SETFLAG(FLAG_S);
162 if((((b&r)|(~a&(b|r)))>>31)&1)
163 SETFLAG(FLAG_C);
164 if((((b^a)&(r^a))>>31)&1)
165 SETFLAG(FLAG_V);
166 return r;
167 }
168
AdcWithFlags(uint32_t a,uint32_t b)169 uint32_t se3208_device::AdcWithFlags(uint32_t a,uint32_t b)
170 {
171 uint32_t C=(m_SR&FLAG_C)?1:0;
172 uint32_t r=a+b+C;
173 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
174 if(!r)
175 SETFLAG(FLAG_Z);
176 if(r&0x80000000)
177 SETFLAG(FLAG_S);
178 if(((((a&b)|(~r&(a|b)))>>31))&1)
179 SETFLAG(FLAG_C);
180 if(((((a^r)&(b^r))>>31))&1)
181 SETFLAG(FLAG_V);
182 return r;
183
184 }
185
SbcWithFlags(uint32_t a,uint32_t b)186 uint32_t se3208_device::SbcWithFlags(uint32_t a,uint32_t b)
187 {
188 uint32_t C=(m_SR&FLAG_C)?1:0;
189 uint32_t r=a-b-C;
190 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
191 if(!r)
192 SETFLAG(FLAG_Z);
193 if(r&0x80000000)
194 SETFLAG(FLAG_S);
195 if((((b&r)|(~a&(b|r)))>>31)&1)
196 SETFLAG(FLAG_C);
197 if((((b^a)&(r^a))>>31)&1)
198 SETFLAG(FLAG_V);
199 return r;
200 }
201
MulWithFlags(uint32_t a,uint32_t b)202 uint32_t se3208_device::MulWithFlags(uint32_t a,uint32_t b)
203 {
204 int64_t r=(int64_t) a*(int64_t) b;
205 CLRFLAG(FLAG_V);
206 if(r>>32)
207 SETFLAG(FLAG_V);
208 return (uint32_t) (r&0xffffffff);
209 }
210
NegWithFlags(uint32_t a)211 uint32_t se3208_device::NegWithFlags(uint32_t a)
212 {
213 return SubWithFlags(0,a);
214 }
215
AsrWithFlags(uint32_t Val,uint8_t By)216 uint32_t se3208_device::AsrWithFlags(uint32_t Val, uint8_t By)
217 {
218 signed int v=(signed int) Val;
219 v>>=By;
220 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
221 if(!v)
222 SETFLAG(FLAG_Z);
223 if(v&0x80000000)
224 SETFLAG(FLAG_S);
225 if(Val&(1<<(By-1)))
226 SETFLAG(FLAG_C);
227 return (uint32_t) v;
228 }
229
LsrWithFlags(uint32_t Val,uint8_t By)230 uint32_t se3208_device::LsrWithFlags(uint32_t Val, uint8_t By)
231 {
232 uint32_t v=Val;
233 v>>=By;
234 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
235 if(!v)
236 SETFLAG(FLAG_Z);
237 if(v&0x80000000)
238 SETFLAG(FLAG_S);
239 if(Val&(1<<(By-1)))
240 SETFLAG(FLAG_C);
241 return v;
242 }
243
AslWithFlags(uint32_t Val,uint8_t By)244 uint32_t se3208_device::AslWithFlags(uint32_t Val, uint8_t By)
245 {
246 uint32_t v=Val;
247 v<<=By;
248 CLRFLAG(FLAG_Z|FLAG_C|FLAG_V|FLAG_S);
249 if(!v)
250 SETFLAG(FLAG_Z);
251 if(v&0x80000000)
252 SETFLAG(FLAG_S);
253 if(Val&(1<<(32-By)))
254 SETFLAG(FLAG_C);
255 return v;
256 }
257
258
INST(INVALIDOP)259 INST(INVALIDOP)
260 {
261 //assert(false);
262 }
263
INST(LDB)264 INST(LDB)
265 {
266 uint32_t Offset=EXTRACT(Opcode,0,4);
267 uint32_t Index=EXTRACT(Opcode,5,7);
268 uint32_t SrcDst=EXTRACT(Opcode,8,10);
269 uint32_t Val;
270
271 if(Index)
272 Index=m_R[Index];
273 else
274 Index=0;
275
276 if(TESTFLAG(FLAG_E))
277 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
278
279 Val=SE3208_Read8(Index+Offset);
280 m_R[SrcDst]=SEX8(Val);
281
282 CLRFLAG(FLAG_E);
283 }
284
INST(STB)285 INST(STB)
286 {
287 uint32_t Offset=EXTRACT(Opcode,0,4);
288 uint32_t Index=EXTRACT(Opcode,5,7);
289 uint32_t SrcDst=EXTRACT(Opcode,8,10);
290
291 if(Index)
292 Index=m_R[Index];
293 else
294 Index=0;
295
296 if(TESTFLAG(FLAG_E))
297 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
298
299 SE3208_Write8(Index+Offset,ZEX8(m_R[SrcDst]));
300
301 CLRFLAG(FLAG_E);
302 }
303
INST(LDS)304 INST(LDS)
305 {
306 uint32_t Offset=EXTRACT(Opcode,0,4);
307 uint32_t Index=EXTRACT(Opcode,5,7);
308 uint32_t SrcDst=EXTRACT(Opcode,8,10);
309 uint32_t Val;
310
311 Offset<<=1;
312
313 if(Index)
314 Index=m_R[Index];
315 else
316 Index=0;
317
318 if(TESTFLAG(FLAG_E))
319 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
320
321 Val=SE3208_Read16(Index+Offset);
322 m_R[SrcDst]=SEX16(Val);
323
324 CLRFLAG(FLAG_E);
325 }
326
INST(STS)327 INST(STS)
328 {
329 uint32_t Offset=EXTRACT(Opcode,0,4);
330 uint32_t Index=EXTRACT(Opcode,5,7);
331 uint32_t SrcDst=EXTRACT(Opcode,8,10);
332
333 Offset<<=1;
334
335 if(Index)
336 Index=m_R[Index];
337 else
338 Index=0;
339
340 if(TESTFLAG(FLAG_E))
341 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
342
343 SE3208_Write16(Index+Offset,ZEX16(m_R[SrcDst]));
344
345 CLRFLAG(FLAG_E);
346 }
347
INST(LD)348 INST(LD)
349 {
350 uint32_t Offset=EXTRACT(Opcode,0,4);
351 uint32_t Index=EXTRACT(Opcode,5,7);
352 uint32_t SrcDst=EXTRACT(Opcode,8,10);
353
354 Offset<<=2;
355
356 if(Index)
357 Index=m_R[Index];
358 else
359 Index=0;
360
361 if(TESTFLAG(FLAG_E))
362 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
363
364 m_R[SrcDst]=SE3208_Read32(Index+Offset);
365
366 CLRFLAG(FLAG_E);
367 }
368
INST(ST)369 INST(ST)
370 {
371 uint32_t Offset=EXTRACT(Opcode,0,4);
372 uint32_t Index=EXTRACT(Opcode,5,7);
373 uint32_t SrcDst=EXTRACT(Opcode,8,10);
374
375 Offset<<=2;
376
377 if(Index)
378 Index=m_R[Index];
379 else
380 Index=0;
381
382 if(TESTFLAG(FLAG_E))
383 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
384
385 SE3208_Write32(Index+Offset,m_R[SrcDst]);
386
387 CLRFLAG(FLAG_E);
388 }
389
INST(LDBU)390 INST(LDBU)
391 {
392 uint32_t Offset=EXTRACT(Opcode,0,4);
393 uint32_t Index=EXTRACT(Opcode,5,7);
394 uint32_t SrcDst=EXTRACT(Opcode,8,10);
395 uint32_t Val;
396
397 if(Index)
398 Index=m_R[Index];
399 else
400 Index=0;
401
402 if(TESTFLAG(FLAG_E))
403 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
404
405 Val=SE3208_Read8(Index+Offset);
406 m_R[SrcDst]=ZEX8(Val);
407
408 CLRFLAG(FLAG_E);
409 }
410
INST(LDSU)411 INST(LDSU)
412 {
413 uint32_t Offset=EXTRACT(Opcode,0,4);
414 uint32_t Index=EXTRACT(Opcode,5,7);
415 uint32_t SrcDst=EXTRACT(Opcode,8,10);
416 uint32_t Val;
417
418 Offset<<=1;
419
420 if(Index)
421 Index=m_R[Index];
422 else
423 Index=0;
424
425 if(TESTFLAG(FLAG_E))
426 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
427
428 Val=SE3208_Read16(Index+Offset);
429 m_R[SrcDst]=ZEX16(Val);
430
431 CLRFLAG(FLAG_E);
432 }
433
434
INST(LERI)435 INST(LERI)
436 {
437 uint32_t Imm=EXTRACT(Opcode,0,13);
438 if(TESTFLAG(FLAG_E))
439 m_ER=(EXTRACT(m_ER,0,17)<<14)|Imm;
440 else
441 m_ER=SEX(14,Imm);
442
443
444 SETFLAG(FLAG_E);
445 }
446
INST(LDSP)447 INST(LDSP)
448 {
449 uint32_t Offset=EXTRACT(Opcode,0,7);
450 uint32_t Index=m_SP;
451 uint32_t SrcDst=EXTRACT(Opcode,8,10);
452
453 Offset<<=2;
454
455 if(TESTFLAG(FLAG_E))
456 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
457
458 m_R[SrcDst]=SE3208_Read32(Index+Offset);
459
460 CLRFLAG(FLAG_E);
461 }
462
INST(STSP)463 INST(STSP)
464 {
465 uint32_t Offset=EXTRACT(Opcode,0,7);
466 uint32_t Index=m_SP;
467 uint32_t SrcDst=EXTRACT(Opcode,8,10);
468
469 Offset<<=2;
470
471 if(TESTFLAG(FLAG_E))
472 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
473
474 SE3208_Write32(Index+Offset,m_R[SrcDst]);
475
476 CLRFLAG(FLAG_E);
477 }
478
PushVal(uint32_t Val)479 void se3208_device::PushVal(uint32_t Val)
480 {
481 m_SP-=4;
482 SE3208_Write32(m_SP,Val);
483 }
484
PopVal()485 uint32_t se3208_device::PopVal()
486 {
487 uint32_t Val=SE3208_Read32(m_SP);
488 m_SP+=4;
489 return Val;
490 }
491
INST(PUSH)492 INST(PUSH)
493 {
494 uint32_t Set=EXTRACT(Opcode,0,10);
495 if(Set&(1<<10))
496 PushVal(m_PC);
497 if(Set&(1<<9))
498 PushVal(m_SR);
499 if(Set&(1<<8))
500 PushVal(m_ER);
501 if(Set&(1<<7))
502 PushVal(m_R[7]);
503 if(Set&(1<<6))
504 PushVal(m_R[6]);
505 if(Set&(1<<5))
506 PushVal(m_R[5]);
507 if(Set&(1<<4))
508 PushVal(m_R[4]);
509 if(Set&(1<<3))
510 PushVal(m_R[3]);
511 if(Set&(1<<2))
512 PushVal(m_R[2]);
513 if(Set&(1<<1))
514 PushVal(m_R[1]);
515 if(Set&(1<<0))
516 PushVal(m_R[0]);
517 }
518
INST(POP)519 INST(POP)
520 {
521 uint32_t Set=EXTRACT(Opcode,0,10);
522 if(Set&(1<<0))
523 m_R[0]=PopVal();
524 if(Set&(1<<1))
525 m_R[1]=PopVal();
526 if(Set&(1<<2))
527 m_R[2]=PopVal();
528 if(Set&(1<<3))
529 m_R[3]=PopVal();
530 if(Set&(1<<4))
531 m_R[4]=PopVal();
532 if(Set&(1<<5))
533 m_R[5]=PopVal();
534 if(Set&(1<<6))
535 m_R[6]=PopVal();
536 if(Set&(1<<7))
537 m_R[7]=PopVal();
538 if(Set&(1<<8))
539 m_ER=PopVal();
540 if(Set&(1<<9))
541 m_SR=PopVal();
542 if(Set&(1<<10))
543 {
544 m_PC=PopVal()-2; //PC automatically incresases by 2
545 }
546 }
547
INST(LEATOSP)548 INST(LEATOSP)
549 {
550 uint32_t Offset=EXTRACT(Opcode,9,12);
551 uint32_t Index=EXTRACT(Opcode,3,5);
552
553 if(Index)
554 Index=m_R[Index];
555 else
556 Index=0;
557
558 if(TESTFLAG(FLAG_E))
559 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
560 else
561 Offset=SEX(4,Offset);
562
563 m_SP=(Index+Offset) & (~3);
564
565 CLRFLAG(FLAG_E);
566 }
567
INST(LEAFROMSP)568 INST(LEAFROMSP)
569 {
570 uint32_t Offset=EXTRACT(Opcode,9,12);
571 uint32_t Index=EXTRACT(Opcode,3,5);
572
573 if(TESTFLAG(FLAG_E))
574 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
575 else
576 Offset=SEX(4,Offset);
577
578 m_R[Index]=m_SP+Offset;
579
580 CLRFLAG(FLAG_E);
581 }
582
INST(LEASPTOSP)583 INST(LEASPTOSP)
584 {
585 uint32_t Offset=EXTRACT(Opcode,0,7);
586
587 Offset<<=2;
588
589 if(TESTFLAG(FLAG_E))
590 Offset=(EXTRACT(m_ER,0,23)<<8)|(Offset&0xff);
591 else
592 Offset=SEX(10,Offset);
593
594 m_SP=(m_SP+Offset) & (~3);
595
596 CLRFLAG(FLAG_E);
597 }
598
INST(MOV)599 INST(MOV)
600 {
601 uint32_t Src=EXTRACT(Opcode,3,5);
602 uint32_t Dst=EXTRACT(Opcode,9,11);
603
604 m_R[Dst]=m_R[Src];
605 }
606
INST(LDI)607 INST(LDI)
608 {
609 uint32_t Dst=EXTRACT(Opcode,8,10);
610 uint32_t Imm=EXTRACT(Opcode,0,7);
611
612 if(TESTFLAG(FLAG_E))
613 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
614 else
615 Imm=SEX8(Imm);
616
617 m_R[Dst]=Imm;
618
619 CLRFLAG(FLAG_E);
620 }
621
INST(LDBSP)622 INST(LDBSP)
623 {
624 uint32_t Offset=EXTRACT(Opcode,0,3);
625 uint32_t Index=m_SP;
626 uint32_t SrcDst=EXTRACT(Opcode,4,6);
627 uint32_t Val;
628
629 if(TESTFLAG(FLAG_E))
630 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
631
632 Val=SE3208_Read8(Index+Offset);
633 m_R[SrcDst]=SEX8(Val);
634
635 CLRFLAG(FLAG_E);
636 }
637
INST(STBSP)638 INST(STBSP)
639 {
640 uint32_t Offset=EXTRACT(Opcode,0,3);
641 uint32_t Index=m_SP;
642 uint32_t SrcDst=EXTRACT(Opcode,4,6);
643
644 if(TESTFLAG(FLAG_E))
645 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
646
647 SE3208_Write8(Index+Offset,ZEX8(m_R[SrcDst]));
648
649 CLRFLAG(FLAG_E);
650 }
651
INST(LDSSP)652 INST(LDSSP)
653 {
654 uint32_t Offset=EXTRACT(Opcode,0,3);
655 uint32_t Index=m_SP;
656 uint32_t SrcDst=EXTRACT(Opcode,4,6);
657 uint32_t Val;
658
659 Offset<<=1;
660
661 if(TESTFLAG(FLAG_E))
662 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
663
664 Val=SE3208_Read16(Index+Offset);
665 m_R[SrcDst]=SEX16(Val);
666
667 CLRFLAG(FLAG_E);
668 }
669
INST(STSSP)670 INST(STSSP)
671 {
672 uint32_t Offset=EXTRACT(Opcode,0,3);
673 uint32_t Index=m_SP;
674 uint32_t SrcDst=EXTRACT(Opcode,4,6);
675
676 Offset<<=1;
677
678 if(TESTFLAG(FLAG_E))
679 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
680
681 SE3208_Write16(Index+Offset,ZEX16(m_R[SrcDst]));
682
683 CLRFLAG(FLAG_E);
684 }
685
INST(LDBUSP)686 INST(LDBUSP)
687 {
688 uint32_t Offset=EXTRACT(Opcode,0,3);
689 uint32_t Index=m_SP;
690 uint32_t SrcDst=EXTRACT(Opcode,4,6);
691 uint32_t Val;
692
693 if(TESTFLAG(FLAG_E))
694 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
695
696 Val=SE3208_Read8(Index+Offset);
697 m_R[SrcDst]=ZEX8(Val);
698
699 CLRFLAG(FLAG_E);
700 }
701
INST(LDSUSP)702 INST(LDSUSP)
703 {
704 uint32_t Offset=EXTRACT(Opcode,0,3);
705 uint32_t Index=m_SP;
706 uint32_t SrcDst=EXTRACT(Opcode,4,6);
707 uint32_t Val;
708
709 Offset<<=1;
710
711 if(TESTFLAG(FLAG_E))
712 Offset=(EXTRACT(m_ER,0,27)<<4)|(Offset&0xf);
713
714 Val=SE3208_Read16(Index+Offset);
715 m_R[SrcDst]=ZEX16(Val);
716
717 CLRFLAG(FLAG_E);
718 }
719
INST(ADDI)720 INST(ADDI)
721 {
722 uint32_t Imm=EXTRACT(Opcode,9,12);
723 uint32_t Src=EXTRACT(Opcode,3,5);
724 uint32_t Dst=EXTRACT(Opcode,0,2);
725
726 if(TESTFLAG(FLAG_E))
727 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
728 else
729 Imm=SEX(4,Imm);
730
731 m_R[Dst]=AddWithFlags(m_R[Src],Imm);
732
733 CLRFLAG(FLAG_E);
734 }
735
INST(SUBI)736 INST(SUBI)
737 {
738 uint32_t Imm=EXTRACT(Opcode,9,12);
739 uint32_t Src=EXTRACT(Opcode,3,5);
740 uint32_t Dst=EXTRACT(Opcode,0,2);
741
742 if(TESTFLAG(FLAG_E))
743 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
744 else
745 Imm=SEX(4,Imm);
746
747 m_R[Dst]=SubWithFlags(m_R[Src],Imm);
748
749 CLRFLAG(FLAG_E);
750 }
751
INST(ADCI)752 INST(ADCI)
753 {
754 uint32_t Imm=EXTRACT(Opcode,9,12);
755 uint32_t Src=EXTRACT(Opcode,3,5);
756 uint32_t Dst=EXTRACT(Opcode,0,2);
757
758 if(TESTFLAG(FLAG_E))
759 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
760 else
761 Imm=SEX(4,Imm);
762
763 m_R[Dst]=AdcWithFlags(m_R[Src],Imm);
764
765 CLRFLAG(FLAG_E);
766 }
767
INST(SBCI)768 INST(SBCI)
769 {
770 uint32_t Imm=EXTRACT(Opcode,9,12);
771 uint32_t Src=EXTRACT(Opcode,3,5);
772 uint32_t Dst=EXTRACT(Opcode,0,2);
773
774 if(TESTFLAG(FLAG_E))
775 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
776 else
777 Imm=SEX(4,Imm);
778
779 m_R[Dst]=SbcWithFlags(m_R[Src],Imm);
780
781 CLRFLAG(FLAG_E);
782 }
783
INST(ANDI)784 INST(ANDI)
785 {
786 uint32_t Imm=EXTRACT(Opcode,9,12);
787 uint32_t Src=EXTRACT(Opcode,3,5);
788 uint32_t Dst=EXTRACT(Opcode,0,2);
789
790 if(TESTFLAG(FLAG_E))
791 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
792 else
793 Imm=SEX(4,Imm);
794
795 m_R[Dst]=m_R[Src]&Imm;
796
797 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
798 if(!m_R[Dst])
799 SETFLAG(FLAG_Z);
800 if(m_R[Dst]&0x80000000)
801 SETFLAG(FLAG_S);
802 }
803
INST(ORI)804 INST(ORI)
805 {
806 uint32_t Imm=EXTRACT(Opcode,9,12);
807 uint32_t Src=EXTRACT(Opcode,3,5);
808 uint32_t Dst=EXTRACT(Opcode,0,2);
809
810 if(TESTFLAG(FLAG_E))
811 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
812 else
813 Imm=SEX(4,Imm);
814
815 m_R[Dst]=m_R[Src]|Imm;
816
817 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
818 if(!m_R[Dst])
819 SETFLAG(FLAG_Z);
820 if(m_R[Dst]&0x80000000)
821 SETFLAG(FLAG_S);
822 }
823
INST(XORI)824 INST(XORI)
825 {
826 uint32_t Imm=EXTRACT(Opcode,9,12);
827 uint32_t Src=EXTRACT(Opcode,3,5);
828 uint32_t Dst=EXTRACT(Opcode,0,2);
829
830 if(TESTFLAG(FLAG_E))
831 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
832 else
833 Imm=SEX(4,Imm);
834
835 m_R[Dst]=m_R[Src]^Imm;
836
837 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
838 if(!m_R[Dst])
839 SETFLAG(FLAG_Z);
840 if(m_R[Dst]&0x80000000)
841 SETFLAG(FLAG_S);
842 }
843
INST(CMPI)844 INST(CMPI)
845 {
846 uint32_t Imm=EXTRACT(Opcode,9,12);
847 uint32_t Src=EXTRACT(Opcode,3,5);
848
849 if(TESTFLAG(FLAG_E))
850 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
851 else
852 Imm=SEX(4,Imm);
853
854 SubWithFlags(m_R[Src],Imm);
855
856 CLRFLAG(FLAG_E);
857 }
858
INST(TSTI)859 INST(TSTI)
860 {
861 uint32_t Imm=EXTRACT(Opcode,9,12);
862 uint32_t Src=EXTRACT(Opcode,3,5);
863 uint32_t Dst;
864
865 if(TESTFLAG(FLAG_E))
866 Imm=(EXTRACT(m_ER,0,27)<<4)|(Imm&0xf);
867 else
868 Imm=SEX(4,Imm);
869
870 Dst=m_R[Src]&Imm;
871
872 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
873 if(!Dst)
874 SETFLAG(FLAG_Z);
875 if(Dst&0x80000000)
876 SETFLAG(FLAG_S);
877 }
878
INST(ADD)879 INST(ADD)
880 {
881 uint32_t Src2=EXTRACT(Opcode,9,11);
882 uint32_t Src1=EXTRACT(Opcode,3,5);
883 uint32_t Dst=EXTRACT(Opcode,0,2);
884
885 m_R[Dst]=AddWithFlags(m_R[Src1],m_R[Src2]);
886 }
887
INST(SUB)888 INST(SUB)
889 {
890 uint32_t Src2=EXTRACT(Opcode,9,11);
891 uint32_t Src1=EXTRACT(Opcode,3,5);
892 uint32_t Dst=EXTRACT(Opcode,0,2);
893
894 m_R[Dst]=SubWithFlags(m_R[Src1],m_R[Src2]);
895 }
896
INST(ADC)897 INST(ADC)
898 {
899 uint32_t Src2=EXTRACT(Opcode,9,11);
900 uint32_t Src1=EXTRACT(Opcode,3,5);
901 uint32_t Dst=EXTRACT(Opcode,0,2);
902
903 m_R[Dst]=AdcWithFlags(m_R[Src1],m_R[Src2]);
904 }
905
INST(SBC)906 INST(SBC)
907 {
908 uint32_t Src2=EXTRACT(Opcode,9,11);
909 uint32_t Src1=EXTRACT(Opcode,3,5);
910 uint32_t Dst=EXTRACT(Opcode,0,2);
911
912 m_R[Dst]=SbcWithFlags(m_R[Src1],m_R[Src2]);
913 }
914
INST(AND)915 INST(AND)
916 {
917 uint32_t Src2=EXTRACT(Opcode,9,11);
918 uint32_t Src1=EXTRACT(Opcode,3,5);
919 uint32_t Dst=EXTRACT(Opcode,0,2);
920
921 m_R[Dst]=m_R[Src1]&m_R[Src2];
922
923 CLRFLAG(FLAG_S|FLAG_Z);
924 if(!m_R[Dst])
925 SETFLAG(FLAG_Z);
926 if(m_R[Dst]&0x80000000)
927 SETFLAG(FLAG_S);
928 }
929
INST(OR)930 INST(OR)
931 {
932 uint32_t Src2=EXTRACT(Opcode,9,11);
933 uint32_t Src1=EXTRACT(Opcode,3,5);
934 uint32_t Dst=EXTRACT(Opcode,0,2);
935
936 m_R[Dst]=m_R[Src1]|m_R[Src2];
937
938 CLRFLAG(FLAG_S|FLAG_Z);
939 if(!m_R[Dst])
940 SETFLAG(FLAG_Z);
941 if(m_R[Dst]&0x80000000)
942 SETFLAG(FLAG_S);
943
944 }
945
INST(XOR)946 INST(XOR)
947 {
948 uint32_t Src2=EXTRACT(Opcode,9,11);
949 uint32_t Src1=EXTRACT(Opcode,3,5);
950 uint32_t Dst=EXTRACT(Opcode,0,2);
951
952 m_R[Dst]=m_R[Src1]^m_R[Src2];
953
954 CLRFLAG(FLAG_S|FLAG_Z);
955 if(!m_R[Dst])
956 SETFLAG(FLAG_Z);
957 if(m_R[Dst]&0x80000000)
958 SETFLAG(FLAG_S);
959
960 }
961
INST(CMP)962 INST(CMP)
963 {
964 uint32_t Src2=EXTRACT(Opcode,9,11);
965 uint32_t Src1=EXTRACT(Opcode,3,5);
966
967 SubWithFlags(m_R[Src1],m_R[Src2]);
968 }
969
INST(TST)970 INST(TST)
971 {
972 uint32_t Src2=EXTRACT(Opcode,9,11);
973 uint32_t Src1=EXTRACT(Opcode,3,5);
974 uint32_t Dst;
975
976 Dst=m_R[Src1]&m_R[Src2];
977
978 CLRFLAG(FLAG_S|FLAG_Z);
979 if(!Dst)
980 SETFLAG(FLAG_Z);
981 if(Dst&0x80000000)
982 SETFLAG(FLAG_S);
983 }
984
INST(MULS)985 INST(MULS)
986 {
987 uint32_t Src2=EXTRACT(Opcode,6,8);
988 uint32_t Src1=EXTRACT(Opcode,3,5);
989 uint32_t Dst=EXTRACT(Opcode,0,2);
990
991 m_R[Dst]=MulWithFlags(m_R[Src1],m_R[Src2]);
992
993 CLRFLAG(FLAG_E);
994 }
995
INST(NEG)996 INST(NEG)
997 {
998 uint32_t Dst=EXTRACT(Opcode,9,11);
999 uint32_t Src=EXTRACT(Opcode,3,5);
1000
1001 m_R[Dst]=NegWithFlags(m_R[Src]);
1002 }
1003
INST(CALL)1004 INST(CALL)
1005 {
1006 uint32_t Offset=EXTRACT(Opcode,0,7);
1007
1008 if(TESTFLAG(FLAG_E))
1009 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1010 else
1011 Offset=SEX(8,Offset);
1012 Offset<<=1;
1013 PushVal(m_PC+2);
1014 m_PC=m_PC+Offset;
1015
1016 CLRFLAG(FLAG_E);
1017 }
1018
INST(JV)1019 INST(JV)
1020 {
1021 uint32_t Offset=EXTRACT(Opcode,0,7);
1022
1023 if(TESTFLAG(FLAG_E))
1024 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1025 else
1026 Offset=SEX(8,Offset);
1027 Offset<<=1;
1028
1029 if(TESTFLAG(FLAG_V))
1030 {
1031 m_PC=m_PC+Offset;
1032 }
1033
1034 CLRFLAG(FLAG_E);
1035
1036 }
1037
INST(JNV)1038 INST(JNV)
1039 {
1040 uint32_t Offset=EXTRACT(Opcode,0,7);
1041
1042 if(TESTFLAG(FLAG_E))
1043 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1044 else
1045 Offset=SEX(8,Offset);
1046 Offset<<=1;
1047
1048 if(!TESTFLAG(FLAG_V))
1049 {
1050 m_PC=m_PC+Offset;
1051 }
1052
1053 CLRFLAG(FLAG_E);
1054 }
1055
INST(JC)1056 INST(JC)
1057 {
1058 uint32_t Offset=EXTRACT(Opcode,0,7);
1059
1060 if(TESTFLAG(FLAG_E))
1061 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1062 else
1063 Offset=SEX(8,Offset);
1064 Offset<<=1;
1065
1066 if(TESTFLAG(FLAG_C))
1067 {
1068 m_PC=m_PC+Offset;
1069 }
1070
1071 CLRFLAG(FLAG_E);
1072 }
1073
INST(JNC)1074 INST(JNC)
1075 {
1076 uint32_t Offset=EXTRACT(Opcode,0,7);
1077
1078 if(TESTFLAG(FLAG_E))
1079 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1080 else
1081 Offset=SEX(8,Offset);
1082 Offset<<=1;
1083
1084 if(!TESTFLAG(FLAG_C))
1085 {
1086 m_PC=m_PC+Offset;
1087 }
1088
1089 CLRFLAG(FLAG_E);
1090 }
1091
INST(JP)1092 INST(JP)
1093 {
1094 uint32_t Offset=EXTRACT(Opcode,0,7);
1095
1096 if(TESTFLAG(FLAG_E))
1097 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1098 else
1099 Offset=SEX(8,Offset);
1100 Offset<<=1;
1101
1102 if(!TESTFLAG(FLAG_S))
1103 {
1104 m_PC=m_PC+Offset;
1105 }
1106
1107 CLRFLAG(FLAG_E);
1108 }
1109
INST(JM)1110 INST(JM)
1111 {
1112 uint32_t Offset=EXTRACT(Opcode,0,7);
1113
1114 if(TESTFLAG(FLAG_E))
1115 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1116 else
1117 Offset=SEX(8,Offset);
1118 Offset<<=1;
1119
1120 if(TESTFLAG(FLAG_S))
1121 {
1122 m_PC=m_PC+Offset;
1123 }
1124
1125 CLRFLAG(FLAG_E);
1126 }
1127
INST(JNZ)1128 INST(JNZ)
1129 {
1130 uint32_t Offset=EXTRACT(Opcode,0,7);
1131
1132 if(TESTFLAG(FLAG_E))
1133 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1134 else
1135 Offset=SEX(8,Offset);
1136 Offset<<=1;
1137
1138 if(!TESTFLAG(FLAG_Z))
1139 {
1140 m_PC=m_PC+Offset;
1141 }
1142
1143 CLRFLAG(FLAG_E);
1144 }
1145
INST(JZ)1146 INST(JZ)
1147 {
1148 uint32_t Offset=EXTRACT(Opcode,0,7);
1149
1150 if(TESTFLAG(FLAG_E))
1151 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1152 else
1153 Offset=SEX(8,Offset);
1154 Offset<<=1;
1155
1156 if(TESTFLAG(FLAG_Z))
1157 {
1158 m_PC=m_PC+Offset;
1159 }
1160
1161 CLRFLAG(FLAG_E);
1162 }
1163
INST(JGE)1164 INST(JGE)
1165 {
1166 uint32_t Offset=EXTRACT(Opcode,0,7);
1167 uint32_t S=TESTFLAG(FLAG_S)?1:0;
1168 uint32_t V=TESTFLAG(FLAG_V)?1:0;
1169
1170 if(TESTFLAG(FLAG_E))
1171 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1172 else
1173 Offset=SEX(8,Offset);
1174 Offset<<=1;
1175
1176 if(!(S^V))
1177 {
1178 m_PC=m_PC+Offset;
1179 }
1180
1181 CLRFLAG(FLAG_E);
1182 }
1183
INST(JLE)1184 INST(JLE)
1185 {
1186 uint32_t Offset=EXTRACT(Opcode,0,7);
1187 uint32_t S=TESTFLAG(FLAG_S)?1:0;
1188 uint32_t V=TESTFLAG(FLAG_V)?1:0;
1189
1190 if(TESTFLAG(FLAG_E))
1191 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1192 else
1193 Offset=SEX(8,Offset);
1194 Offset<<=1;
1195
1196 if(TESTFLAG(FLAG_Z) || (S^V))
1197 {
1198 m_PC=m_PC+Offset;
1199 }
1200 CLRFLAG(FLAG_E);
1201 }
1202
INST(JHI)1203 INST(JHI)
1204 {
1205 uint32_t Offset=EXTRACT(Opcode,0,7);
1206
1207 if(TESTFLAG(FLAG_E))
1208 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1209 else
1210 Offset=SEX(8,Offset);
1211 Offset<<=1;
1212
1213 if(!(TESTFLAG(FLAG_Z) || TESTFLAG(FLAG_C)))
1214 {
1215 m_PC=m_PC+Offset;
1216 }
1217
1218 CLRFLAG(FLAG_E);
1219 }
1220
INST(JLS)1221 INST(JLS)
1222 {
1223 uint32_t Offset=EXTRACT(Opcode,0,7);
1224
1225 if(TESTFLAG(FLAG_E))
1226 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1227 else
1228 Offset=SEX(8,Offset);
1229 Offset<<=1;
1230
1231 if(TESTFLAG(FLAG_Z) || TESTFLAG(FLAG_C))
1232 {
1233 m_PC=m_PC+Offset;
1234 }
1235
1236 CLRFLAG(FLAG_E);
1237 }
1238
INST(JGT)1239 INST(JGT)
1240 {
1241 uint32_t Offset=EXTRACT(Opcode,0,7);
1242 uint32_t S=TESTFLAG(FLAG_S)?1:0;
1243 uint32_t V=TESTFLAG(FLAG_V)?1:0;
1244
1245 if(TESTFLAG(FLAG_E))
1246 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1247 else
1248 Offset=SEX(8,Offset);
1249 Offset<<=1;
1250
1251 if(!(TESTFLAG(FLAG_Z) || (S^V)))
1252 {
1253 m_PC=m_PC+Offset;
1254 }
1255
1256 CLRFLAG(FLAG_E);
1257 }
1258
INST(JLT)1259 INST(JLT)
1260 {
1261 uint32_t Offset=EXTRACT(Opcode,0,7);
1262 uint32_t S=TESTFLAG(FLAG_S)?1:0;
1263 uint32_t V=TESTFLAG(FLAG_V)?1:0;
1264
1265 if(TESTFLAG(FLAG_E))
1266 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1267 else
1268 Offset=SEX(8,Offset);
1269 Offset<<=1;
1270
1271 if(S^V)
1272 {
1273 m_PC=m_PC+Offset;
1274 }
1275
1276 CLRFLAG(FLAG_E);
1277 }
1278
1279
1280
INST(JMP)1281 INST(JMP)
1282 {
1283 uint32_t Offset=EXTRACT(Opcode,0,7);
1284
1285 if(TESTFLAG(FLAG_E))
1286 Offset=(EXTRACT(m_ER,0,22)<<8)|Offset;
1287 else
1288 Offset=SEX(8,Offset);
1289
1290 Offset<<=1;
1291
1292 m_PC=m_PC+Offset;
1293
1294 CLRFLAG(FLAG_E);
1295 }
1296
INST(JR)1297 INST(JR)
1298 {
1299 uint32_t Src=EXTRACT(Opcode,0,3);
1300
1301 m_PC=m_R[Src]-2;
1302
1303 CLRFLAG(FLAG_E);
1304 }
1305
INST(CALLR)1306 INST(CALLR)
1307 {
1308 uint32_t Src=EXTRACT(Opcode,0,3);
1309 PushVal(m_PC+2);
1310 m_PC=m_R[Src]-2;
1311
1312 CLRFLAG(FLAG_E);
1313 }
1314
INST(ASR)1315 INST(ASR)
1316 {
1317 uint32_t CS=Opcode&(1<<10);
1318 uint32_t Dst=EXTRACT(Opcode,0,2);
1319 uint32_t Imm=EXTRACT(Opcode,5,9);
1320 uint32_t Cnt=EXTRACT(Opcode,5,7);
1321
1322 if(CS)
1323 m_R[Dst]=AsrWithFlags(m_R[Dst],m_R[Cnt]&0x1f);
1324 else
1325 m_R[Dst]=AsrWithFlags(m_R[Dst],Imm&0x1f);
1326
1327 CLRFLAG(FLAG_E);
1328 }
1329
INST(LSR)1330 INST(LSR)
1331 {
1332 uint32_t CS=Opcode&(1<<10);
1333 uint32_t Dst=EXTRACT(Opcode,0,2);
1334 uint32_t Imm=EXTRACT(Opcode,5,9);
1335 uint32_t Cnt=EXTRACT(Opcode,5,7);
1336
1337 if(CS)
1338 m_R[Dst]=LsrWithFlags(m_R[Dst],m_R[Cnt]&0x1f);
1339 else
1340 m_R[Dst]=LsrWithFlags(m_R[Dst],Imm&0x1f);
1341
1342 CLRFLAG(FLAG_E);
1343 }
1344
INST(ASL)1345 INST(ASL)
1346 {
1347 uint32_t CS=Opcode&(1<<10);
1348 uint32_t Dst=EXTRACT(Opcode,0,2);
1349 uint32_t Imm=EXTRACT(Opcode,5,9);
1350 uint32_t Cnt=EXTRACT(Opcode,5,7);
1351
1352 if(CS)
1353 m_R[Dst]=AslWithFlags(m_R[Dst],m_R[Cnt]&0x1f);
1354 else
1355 m_R[Dst]=AslWithFlags(m_R[Dst],Imm&0x1f);
1356
1357 CLRFLAG(FLAG_E);
1358 }
1359
INST(EXTB)1360 INST(EXTB)
1361 {
1362 uint32_t Dst=EXTRACT(Opcode,0,3);
1363 uint32_t Val=m_R[Dst];
1364
1365 m_R[Dst]=SEX8(Val);
1366
1367 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
1368 if(!m_R[Dst])
1369 SETFLAG(FLAG_Z);
1370 if(m_R[Dst]&0x80000000)
1371 SETFLAG(FLAG_S);
1372
1373 }
1374
INST(EXTS)1375 INST(EXTS)
1376 {
1377 uint32_t Dst=EXTRACT(Opcode,0,3);
1378 uint32_t Val=m_R[Dst];
1379
1380 m_R[Dst]=SEX16(Val);
1381
1382 CLRFLAG(FLAG_S|FLAG_Z|FLAG_E);
1383 if(!m_R[Dst])
1384 SETFLAG(FLAG_Z);
1385 if(m_R[Dst]&0x80000000)
1386 SETFLAG(FLAG_S);
1387 }
1388
INST(SET)1389 INST(SET)
1390 {
1391 uint32_t Imm=EXTRACT(Opcode,0,3);
1392
1393 m_SR|=(1<<Imm);
1394 }
1395
INST(CLR)1396 INST(CLR)
1397 {
1398 uint32_t Imm=EXTRACT(Opcode,0,3);
1399
1400 m_SR&=~(1<<Imm);
1401 }
1402
INST(SWI)1403 INST(SWI)
1404 {
1405 uint32_t Imm=EXTRACT(Opcode,0,3);
1406
1407 if(!TESTFLAG(FLAG_ENI))
1408 return;
1409 PushVal(m_PC);
1410 PushVal(m_SR);
1411
1412 CLRFLAG(FLAG_ENI|FLAG_E|FLAG_M);
1413
1414 m_PC=SE3208_Read32(4*Imm+0x40)-2;
1415 }
1416
INST(HALT)1417 INST(HALT)
1418 {
1419 uint32_t Imm=EXTRACT(Opcode,0,3);
1420
1421 m_machinex_cb(0x10 | Imm);
1422
1423 // DEBUGMESSAGE("HALT\t0x%x",Imm);
1424 }
1425
INST(MVTC)1426 INST(MVTC)
1427 {
1428 // uint32_t Imm=EXTRACT(Opcode,0,3);
1429
1430 // DEBUGMESSAGE("MVTC\t%%R0,%%CR%d",Imm);
1431 }
1432
INST(MVFC)1433 INST(MVFC)
1434 {
1435 // uint32_t Imm=EXTRACT(Opcode,0,3);
1436
1437 // DEBUGMESSAGE("MVFC\t%%CR0%d,%%R0",Imm);
1438 }
1439
1440
DecodeOp(uint16_t Opcode)1441 se3208_device::OP se3208_device::DecodeOp(uint16_t Opcode)
1442 {
1443 switch(EXTRACT(Opcode,14,15))
1444 {
1445 case 0x0:
1446 {
1447 uint8_t Op=EXTRACT(Opcode,11,13);
1448 switch(Op)
1449 {
1450 case 0x0:
1451 return &se3208_device::LDB;
1452 case 0x1:
1453 return &se3208_device::LDS;
1454 case 0x2:
1455 return &se3208_device::LD;
1456 case 0x3:
1457 return &se3208_device::LDBU;
1458 case 0x4:
1459 return &se3208_device::STB;
1460 case 0x5:
1461 return &se3208_device::STS;
1462 case 0x6:
1463 return &se3208_device::ST;
1464 case 0x7:
1465 return &se3208_device::LDSU;
1466 }
1467 }
1468 break;
1469 case 0x1:
1470 return &se3208_device::LERI;
1471 case 0x2:
1472 {
1473 switch(EXTRACT(Opcode,11,13))
1474 {
1475 case 0:
1476 return &se3208_device::LDSP;
1477 case 1:
1478 return &se3208_device::STSP;
1479 case 2:
1480 return &se3208_device::PUSH;
1481 case 3:
1482 return &se3208_device::POP;
1483 case 4:
1484 case 5:
1485 case 6:
1486 case 7:
1487 case 8: //arith
1488 case 9:
1489 case 10:
1490 case 11:
1491 case 12:
1492 case 13:
1493 case 14:
1494 case 15:
1495 switch(EXTRACT(Opcode,6,8))
1496 {
1497 case 0:
1498 return &se3208_device::ADDI;
1499 case 1:
1500 return &se3208_device::ADCI;
1501 case 2:
1502 return &se3208_device::SUBI;
1503 case 3:
1504 return &se3208_device::SBCI;
1505 case 4:
1506 return &se3208_device::ANDI;
1507 case 5:
1508 return &se3208_device::ORI;
1509 case 6:
1510 return &se3208_device::XORI;
1511 case 7:
1512 switch(EXTRACT(Opcode,0,2))
1513 {
1514 case 0:
1515 return &se3208_device::CMPI;
1516 case 1:
1517 return &se3208_device::TSTI;
1518 case 2:
1519 return &se3208_device::LEATOSP;
1520 case 3:
1521 return &se3208_device::LEAFROMSP;
1522 }
1523 break;
1524 }
1525 break;
1526 }
1527 }
1528 break;
1529 case 3:
1530 switch(EXTRACT(Opcode,12,13))
1531 {
1532 case 0:
1533 switch(EXTRACT(Opcode,6,8))
1534 {
1535 case 0:
1536 return &se3208_device::ADD;
1537 case 1:
1538 return &se3208_device::ADC;
1539 case 2:
1540 return &se3208_device::SUB;
1541 case 3:
1542 return &se3208_device::SBC;
1543 case 4:
1544 return &se3208_device::AND;
1545 case 5:
1546 return &se3208_device::OR;
1547 case 6:
1548 return &se3208_device::XOR;
1549 case 7:
1550 switch(EXTRACT(Opcode,0,2))
1551 {
1552 case 0:
1553 return &se3208_device::CMP;
1554 case 1:
1555 return &se3208_device::TST;
1556 case 2:
1557 return &se3208_device::MOV;
1558 case 3:
1559 return &se3208_device::NEG;
1560 }
1561 break;
1562 }
1563 break;
1564 case 1: //Jumps
1565 switch(EXTRACT(Opcode,8,11))
1566 {
1567 case 0x0:
1568 return &se3208_device::JNV;
1569 case 0x1:
1570 return &se3208_device::JV;
1571 case 0x2:
1572 return &se3208_device::JP;
1573 case 0x3:
1574 return &se3208_device::JM;
1575 case 0x4:
1576 return &se3208_device::JNZ;
1577 case 0x5:
1578 return &se3208_device::JZ;
1579 case 0x6:
1580 return &se3208_device::JNC;
1581 case 0x7:
1582 return &se3208_device::JC;
1583 case 0x8:
1584 return &se3208_device::JGT;
1585 case 0x9:
1586 return &se3208_device::JLT;
1587 case 0xa:
1588 return &se3208_device::JGE;
1589 case 0xb:
1590 return &se3208_device::JLE;
1591 case 0xc:
1592 return &se3208_device::JHI;
1593 case 0xd:
1594 return &se3208_device::JLS;
1595 case 0xe:
1596 return &se3208_device::JMP;
1597 case 0xf:
1598 return &se3208_device::CALL;
1599 }
1600 break;
1601 case 2:
1602 if(Opcode&(1<<11))
1603 return &se3208_device::LDI;
1604 else //SP Ops
1605 {
1606 if(Opcode&(1<<10))
1607 {
1608 switch(EXTRACT(Opcode,7,9))
1609 {
1610 case 0:
1611 return &se3208_device::LDBSP;
1612 case 1:
1613 return &se3208_device::LDSSP;
1614 case 3:
1615 return &se3208_device::LDBUSP;
1616 case 4:
1617 return &se3208_device::STBSP;
1618 case 5:
1619 return &se3208_device::STSSP;
1620 case 7:
1621 return &se3208_device::LDSUSP;
1622 }
1623 }
1624 else
1625 {
1626 if(Opcode&(1<<9))
1627 {
1628 return &se3208_device::LEASPTOSP;
1629 }
1630 else
1631 {
1632 if(Opcode&(1<<8))
1633 {
1634 }
1635 else
1636 {
1637 switch(EXTRACT(Opcode,4,7))
1638 {
1639 case 0:
1640 return &se3208_device::EXTB;
1641 case 1:
1642 return &se3208_device::EXTS;
1643 case 8:
1644 return &se3208_device::JR;
1645 case 9:
1646 return &se3208_device::CALLR;
1647 case 10:
1648 return &se3208_device::SET;
1649 case 11:
1650 return &se3208_device::CLR;
1651 case 12:
1652 return &se3208_device::SWI;
1653 case 13:
1654 return &se3208_device::HALT;
1655 }
1656 }
1657 }
1658 }
1659 }
1660 break;
1661 case 3:
1662 switch(EXTRACT(Opcode,9,11))
1663 {
1664 case 0:
1665 case 1:
1666 case 2:
1667 case 3:
1668 switch(EXTRACT(Opcode,3,4))
1669 {
1670 case 0:
1671 return &se3208_device::ASR;
1672 case 1:
1673 return &se3208_device::LSR;
1674 case 2:
1675 return &se3208_device::ASL;
1676 //case 3:
1677 // return &se3208_device::LSL;
1678 }
1679 break;
1680 case 4:
1681 return &se3208_device::MULS;
1682 case 6:
1683 if(Opcode&(1<<3))
1684 return &se3208_device::MVFC;
1685 else
1686 return &se3208_device::MVTC;
1687 }
1688 break;
1689 }
1690 break;
1691
1692 }
1693 return &se3208_device::INVALIDOP;
1694 }
1695
1696
BuildTable(void)1697 void se3208_device::BuildTable(void)
1698 {
1699 int i;
1700 for(i=0;i<0x10000;++i)
1701 OpTable[i]=DecodeOp(i);
1702 }
1703
device_reset()1704 void se3208_device::device_reset()
1705 {
1706 for (auto & elem : m_R)
1707 {
1708 elem = 0;
1709 }
1710 m_SP = 0;
1711 m_ER = 0;
1712 m_PPC = 0;
1713 space(AS_PROGRAM).cache(m_cache);
1714 space(AS_PROGRAM).specific(m_program);
1715 m_PC=SE3208_Read32(0);
1716 m_SR=0;
1717 m_IRQ=CLEAR_LINE;
1718 m_NMI=CLEAR_LINE;
1719 }
1720
SE3208_NMI()1721 void se3208_device::SE3208_NMI()
1722 {
1723 standard_irq_callback(INPUT_LINE_NMI);
1724 m_machinex_cb(0x00);
1725
1726 PushVal(m_PC);
1727 PushVal(m_SR);
1728
1729 CLRFLAG(FLAG_NMI|FLAG_ENI|FLAG_E|FLAG_M);
1730
1731 m_PC=SE3208_Read32(4);
1732 }
1733
SE3208_Interrupt()1734 void se3208_device::SE3208_Interrupt()
1735 {
1736 if(!TESTFLAG(FLAG_ENI))
1737 return;
1738
1739 standard_irq_callback(0);
1740 m_machinex_cb(0x01);
1741
1742 PushVal(m_PC);
1743 PushVal(m_SR);
1744
1745 CLRFLAG(FLAG_ENI|FLAG_E|FLAG_M);
1746
1747 if(!(TESTFLAG(FLAG_AUT)))
1748 m_PC=SE3208_Read32(8);
1749 else
1750 m_PC=SE3208_Read32(4*m_iackx_cb());
1751 }
1752
1753
execute_run()1754 void se3208_device::execute_run()
1755 {
1756 do
1757 {
1758 uint16_t Opcode=m_cache.read_word(m_PC, WORD_XOR_LE(0));
1759
1760 m_PPC = m_PC;
1761 debugger_instruction_hook(m_PC);
1762
1763 (this->*OpTable[Opcode])(Opcode);
1764 m_PC+=2;
1765 //Check interrupts
1766 if(m_NMI==ASSERT_LINE)
1767 {
1768 SE3208_NMI();
1769 m_NMI=CLEAR_LINE;
1770 }
1771 else if(m_IRQ==ASSERT_LINE && TESTFLAG(FLAG_ENI))
1772 {
1773 SE3208_Interrupt();
1774 }
1775 --(m_icount);
1776 } while(m_icount>0);
1777 }
1778
device_start()1779 void se3208_device::device_start()
1780 {
1781 BuildTable();
1782
1783 space(AS_PROGRAM).cache(m_cache);
1784 space(AS_PROGRAM).specific(m_program);
1785
1786 save_item(NAME(m_R));
1787 save_item(NAME(m_PC));
1788 save_item(NAME(m_SR));
1789 save_item(NAME(m_SP));
1790 save_item(NAME(m_ER));
1791 save_item(NAME(m_IRQ));
1792 save_item(NAME(m_NMI));
1793
1794 state_add( SE3208_PC, "PC", m_PC).formatstr("%08X");
1795 state_add( SE3208_SR, "SR", m_SR).formatstr("%08X");
1796 state_add( SE3208_ER, "ER", m_ER).formatstr("%08X");
1797 state_add( SE3208_SP, "SP", m_SP).formatstr("%08X");
1798 state_add( SE3208_R0, "R0", m_R[ 0]).formatstr("%08X");
1799 state_add( SE3208_R1, "R1", m_R[ 1]).formatstr("%08X");
1800 state_add( SE3208_R2, "R2", m_R[ 2]).formatstr("%08X");
1801 state_add( SE3208_R3, "R3", m_R[ 3]).formatstr("%08X");
1802 state_add( SE3208_R4, "R4", m_R[ 4]).formatstr("%08X");
1803 state_add( SE3208_R5, "R5", m_R[ 5]).formatstr("%08X");
1804 state_add( SE3208_R6, "R6", m_R[ 6]).formatstr("%08X");
1805 state_add( SE3208_R7, "R7", m_R[ 7]).formatstr("%08X");
1806 state_add( SE3208_PPC, "PPC", m_PPC).formatstr("%08X");
1807
1808 state_add(STATE_GENPC, "GENPC", m_PC).noshow();
1809 state_add(STATE_GENPCBASE, "CURPC", m_PPC).noshow();
1810 state_add(STATE_GENSP, "GENSP", m_SP).noshow();
1811 state_add(STATE_GENFLAGS, "GENFLAGS", m_SR).formatstr("%10s").noshow();
1812
1813 set_icountptr(m_icount);
1814 }
1815
1816
state_string_export(const device_state_entry & entry,std::string & str) const1817 void se3208_device::state_string_export(const device_state_entry &entry, std::string &str) const
1818 {
1819 switch (entry.index())
1820 {
1821 case STATE_GENFLAGS:
1822 str = string_format("%c%c%c%c %c%c%c%c%c",
1823 m_SR&FLAG_C?'C':'.',
1824 m_SR&FLAG_V?'V':'.',
1825 m_SR&FLAG_S?'S':'.',
1826 m_SR&FLAG_Z?'Z':'.',
1827
1828 m_SR&FLAG_M?'M':'.',
1829 m_SR&FLAG_E?'E':'.',
1830 m_SR&FLAG_AUT?'A':'.',
1831 m_SR&FLAG_ENI?'I':'.',
1832 m_SR&FLAG_NMI?'N':'.'
1833 );
1834 break;
1835 }
1836 }
1837
execute_set_input(int line,int state)1838 void se3208_device::execute_set_input( int line, int state )
1839 {
1840 if(line==INPUT_LINE_NMI) //NMI
1841 m_NMI=state;
1842 else
1843 m_IRQ=state;
1844 }
1845
create_disassembler()1846 std::unique_ptr<util::disasm_interface> se3208_device::create_disassembler()
1847 {
1848 return std::make_unique<se3208_disassembler>();
1849 }
1850