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