1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /***************************************************************************
4 
5     cop400op.inc
6 
7     National Semiconductor COP400 Emulator.
8 
9 ***************************************************************************/
10 
11 /***************************************************************************
12     ARITHMETIC INSTRUCTIONS
13 ***************************************************************************/
14 
15 /*
16 
17     Mnemonic:           ASC
18 
19     Hex Code:           30
20     Binary:             0 0 1 1 0 0 0 0
21 
22     Data Flow:          A + C + RAM(B) -> A
23                         Carry -> C
24 
25     Skip Conditions:    Carry
26 
27     Description:        Add with Carry, Skip on Carry
28 
29 */
30 
INSTRUCTION(asc)31 INSTRUCTION( asc )
32 {
33 	A = A + C + RAM_R(B);
34 
35 	if (A > 0xF)
36 	{
37 		C = 1;
38 		skip();
39 		A &= 0xF;
40 	}
41 	else
42 	{
43 		C = 0;
44 	}
45 }
46 
47 /*
48 
49     Mnemonic:           ADD
50 
51     Hex Code:           31
52     Binary:             0 0 1 1 0 0 0 1
53 
54     Data Flow:          A + RAM(B) -> A
55 
56     Description:        Add RAM to A
57 
58 */
59 
INSTRUCTION(add)60 INSTRUCTION( add )
61 {
62 	A = (A + RAM_R(B)) & 0x0F;
63 }
64 
65 /*
66 
67     Mnemonic:           AISC
68 
69     Operand:            y
70     Hex Code:           5-
71     Binary:             0 1 0 1 y3 y2 y1 y0
72 
73     Data Flow:          A + y -> A
74 
75     Skip Conditions:    Carry
76 
77     Description:        Add Immediate, Skip on Carry (y != 0)
78 
79 */
80 
INSTRUCTION(aisc)81 INSTRUCTION( aisc )
82 {
83 	uint8_t y = m_opcode & 0x0f;
84 
85 	A = A + y;
86 
87 	if (A > 0x0f)
88 	{
89 		skip();
90 		A &= 0xF;
91 	}
92 }
93 
94 /*
95 
96     Mnemonic:           CLRA
97 
98     Hex Code:           00
99     Binary:             0 0 0 0 0 0 0 0
100 
101     Data Flow:          0 -> A
102 
103     Description:        Clear A
104 
105 */
106 
INSTRUCTION(clra)107 INSTRUCTION( clra )
108 {
109 	A = 0;
110 }
111 
112 /*
113 
114     Mnemonic:           COMP
115 
116     Hex Code:           40
117     Binary:             0 1 0 0 0 0 0 0
118 
119     Data Flow:          ~A -> A
120 
121     Description:        Ones Complement of A to A
122 
123 */
124 
INSTRUCTION(comp)125 INSTRUCTION( comp )
126 {
127 	A = A ^ 0xF;
128 }
129 
130 /*
131 
132     Mnemonic:           NOP
133 
134     Hex Code:           44
135     Binary:             0 1 0 0 0 1 0 0
136 
137     Description:        No Operation
138 
139 */
140 
INSTRUCTION(nop)141 INSTRUCTION( nop )
142 {
143 	// do nothing
144 }
145 
146 /*
147 
148     Mnemonic:           RC
149 
150     Hex Code:           32
151     Binary:             0 0 1 1 0 0 1 0
152 
153     Data Flow:          "0" -> C
154 
155     Description:        Reset C
156 
157 */
158 
INSTRUCTION(rc)159 INSTRUCTION( rc )
160 {
161 	C = 0;
162 }
163 
164 /*
165 
166     Mnemonic:           SC
167 
168     Hex Code:           22
169     Binary:             0 0 1 0 0 0 1 0
170 
171     Data Flow:          "1" -> C
172 
173     Description:        Set C
174 
175 */
176 
INSTRUCTION(sc)177 INSTRUCTION( sc )
178 {
179 	C = 1;
180 }
181 
182 /*
183 
184     Mnemonic:           XOR
185 
186     Hex Code:           02
187     Binary:             0 0 0 0 0 0 1 0
188 
189     Data Flow:          A ^ RAM(B) -> A
190 
191     Description:        Exclusive-OR RAM with A
192 
193 */
194 
INSTRUCTION(xor_)195 INSTRUCTION( xor_ )
196 {
197 	A = A ^ RAM_R(B);
198 }
199 
200 /*
201 
202     Mnemonic:           ADT
203 
204     Hex Code:           4A
205     Binary:             0 1 0 0 1 0 1 0
206 
207     Data Flow:          A + 10 -> A
208 
209     Description:        Add Ten to A
210 
211 */
212 
INSTRUCTION(adt)213 INSTRUCTION( adt )
214 {
215 	A = (A + 10) & 0x0F;
216 }
217 
218 /*
219 
220     Mnemonic:           CASC
221 
222     Hex Code:           10
223     Binary:             0 0 0 1 0 0 0 0
224 
225     Data Flow:          ~A + RAM(B) + C -> A
226                         Carry -> C
227 
228     Skip Conditions:    Carry
229 
230     Description:        Complement and Add with Carry, Skip on Carry
231 
232 */
233 
INSTRUCTION(casc)234 INSTRUCTION( casc )
235 {
236 	A = (A ^ 0xF) + RAM_R(B) + C;
237 
238 	if (A > 0xF)
239 	{
240 		C = 1;
241 		skip();
242 		A &= 0xF;
243 	}
244 	else
245 	{
246 		C = 0;
247 	}
248 }
249 
250 /***************************************************************************
251     TRANSFER-OF-CONTROL INSTRUCTIONS
252 ***************************************************************************/
253 
254 /*
255 
256     Mnemonic:           JID
257 
258     Hex Code:           FF
259     Binary:             1 1 1 1 1 1 1 1
260 
261     Data Flow:          ROM(PC10:8,A,M) -> PC7:0
262 
263     Description:        Jump Indirect
264 
265 */
266 
INSTRUCTION(jid)267 INSTRUCTION( jid )
268 {
269 	PC = (PC & 0x700) | operand;
270 }
271 
272 /*
273 
274     Mnemonic:           JMP
275 
276     Operand:            a
277     Hex Code:           6- --
278     Binary:             0 1 1 0 0 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
279 
280     Data Flow:          a -> PC
281 
282     Description:        Jump
283 
284 */
285 
INSTRUCTION(jmp)286 INSTRUCTION( jmp )
287 {
288 	PC = ((m_opcode & 0x07) << 8) | operand;
289 }
290 
291 /*
292 
293     Mnemonic:           JP
294 
295     Operand:            a
296     Hex Code:           --
297     Binary:             1 a6 a5 a4 a3 a2 a1 a0
298                         (pages 2,3 only)
299 
300                         1 1 a5 a4 a3 a2 a1 a0
301                         (all other pages)
302 
303     Data Flow:          a -> PC6:0
304 
305                         a -> PC5:0
306 
307     Description:        Jump within Page
308 
309 */
310 
INSTRUCTION(jp)311 INSTRUCTION( jp )
312 {
313 	uint8_t page = PC >> 6;
314 
315 	if (page == 2 || page == 3)
316 	{
317 		uint8_t a = m_opcode & 0x7f;
318 		PC = (PC & 0x780) | a;
319 	}
320 	else if ((m_opcode & 0xc0) == 0xc0)
321 	{
322 		uint8_t a = m_opcode & 0x3f;
323 		PC = (PC & 0x7c0) | a;
324 	}
325 	else
326 	{
327 		// JSRP
328 		uint8_t a = m_opcode & 0x3f;
329 		PUSH(PC);
330 		PC = 0x80 | a;
331 	}
332 }
333 
334 /*
335 
336     Mnemonic:           JSR
337 
338     Operand:            a
339     Hex Code:           6- --
340     Binary:             0 1 1 0 1 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
341 
342     Data Flow:          PC + 1 -> SA -> SB -> SC
343                         a -> PC
344 
345     Description:        Jump to Subroutine
346 
347 */
348 
INSTRUCTION(jsr)349 INSTRUCTION( jsr )
350 {
351 	PUSH(PC);
352 	PC = ((m_opcode & 0x07) << 8) | operand;
353 }
354 
355 /*
356 
357     Mnemonic:           RET
358 
359     Hex Code:           48
360     Binary:             0 1 0 0 1 0 0 0
361 
362     Data Flow:          SC -> SB -> SA -> PC
363 
364     Description:        Return from Subroutine
365 
366 */
367 
INSTRUCTION(ret)368 INSTRUCTION( ret )
369 {
370 	POP();
371 }
372 
373 /*
374 
375     Processor:          COP420
376 
377     Mnemonic:           RET
378 
379     Hex Code:           48
380     Binary:             0 1 0 0 1 0 0 0
381 
382     Data Flow:          SC -> SB -> SA -> PC
383 
384     Description:        Return from Subroutine, restore Skip logic
385 
386 */
387 
INSTRUCTION(cop420_ret)388 INSTRUCTION( cop420_ret )
389 {
390 	POP();
391 	m_skip = m_last_skip;
392 }
393 
394 /*
395 
396     Mnemonic:           RETSK
397 
398     Hex Code:           49
399     Binary:             0 1 0 0 1 0 0 1
400 
401     Data Flow:          SC -> SB -> SA -> PC
402 
403     Skip Conditions:    Always Skip on Return
404 
405     Description:        Return from Subroutine then Skip
406 
407 */
408 
INSTRUCTION(retsk)409 INSTRUCTION( retsk )
410 {
411 	POP();
412 	skip();
413 }
414 
415 /*
416 
417     Processor:          COP410C/COP411C
418 
419     Mnemonic:           HALT
420 
421     Hex Code:           33 38
422     Binary:             0 0 1 1 0 0 1 1 0 0 1 1 1 0 0 0
423 
424     Description:        Halt processor
425 
426 */
427 
INSTRUCTION(halt)428 INSTRUCTION( halt )
429 {
430 	m_halt = true;
431 }
432 
433 /*
434 
435     Mnemonic:           IT
436 
437     Hex Code:           33 39
438     Binary:             0 0 1 1 0 0 1 1 0 0 1 1 1 0 0 1
439 
440     Description:        IDLE till Timer Overflows then Continues
441 
442 */
443 
INSTRUCTION(it)444 INSTRUCTION( it )
445 {
446 	m_halt = true;
447 	m_idle = true;
448 }
449 
450 /***************************************************************************
451     MEMORY REFERENCE INSTRUCTIONS
452 ***************************************************************************/
453 
454 /*
455 
456     Mnemonic:           CAMQ
457 
458     Hex Code:           33 3C
459     Binary:             0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0
460 
461     Data Flow:          A -> Q7:4
462                         RAM(B) -> Q3:0
463 
464     Description:        Copy A, RAM to Q
465 
466 */
467 
INSTRUCTION(camq)468 INSTRUCTION( camq )
469 {
470 	/*
471 
472 	    Excerpt from the COP410L data sheet:
473 
474 	    False states may be generated on L0-L7 during the execution of the CAMQ instruction.
475 	    The L-ports should not be used as clocks for edge sensitive devices such as flip-flops,
476 	    counters, shift registers, etc. the following short program that illustrates this situation.
477 
478 	    START:
479 	        CLRA        ;ENABLE THE Q
480 	        LEI 4       ;REGISTER TO L LINES
481 	        LBI TEST
482 	        STII 3
483 	        AISC 12
484 	    LOOP:
485 	        LBI TEST    ;LOAD Q WITH X'C3
486 	        CAMQ
487 	        JP LOOP
488 
489 	    In this program the internal Q register is enabled onto the L lines and a steady bit
490 	    pattern of logic highs is output on L0, L1, L6, L7, and logic lows on L2-L5 via the
491 	    two-byte CAMQ instruction. Timing constraints on the device are such that the Q
492 	    register may be temporarily loaded with the second byte of the CAMQ opcode (3C) prior
493 	    to receiving the valid data pattern. If this occurs, the opcode will ripple onto the L
494 	    lines and cause negative-going glitches on L0, L1, L6, L7, and positive glitches on
495 	    L2-L5. Glitch durations are under 2 ms, although the exact value may vary due to data
496 	    patterns, processing parameters, and L line loading. These false states are peculiar
497 	    only to the CAMQ instruction and the L lines.
498 
499 	*/
500 
501 	uint8_t data = (A << 4) | RAM_R(B);
502 
503 	WRITE_Q(data);
504 
505 #ifdef CAMQ_BUG
506 	WRITE_Q(0x3c);
507 	WRITE_Q(data);
508 #endif
509 }
510 
511 /*
512 
513     Mnemonic:           LD
514 
515     Operand:            r
516     Hex Code:           -5
517     Binary:             0 0 r1 r0 0 1 0 1
518 
519     Data Flow:          RAM(B) -> A
520                         Br ^ r -> Br
521 
522     Description:        Load RAM into A, Exclusive-OR Br with r
523 
524 */
525 
INSTRUCTION(ld)526 INSTRUCTION( ld )
527 {
528 	uint8_t r = m_opcode & 0x30;
529 
530 	A = RAM_R(B);
531 	B = B ^ r;
532 }
533 
534 /*
535 
536     Mnemonic:           LQID
537 
538     Hex Code:           BF
539     Binary:             1 0 1 1 1 1 1 1
540 
541     Data Flow:          ROM(PC10:8,A,M) -> Q
542                         SB -> SC
543 
544     Description:        Load Q Indirect
545 
546 */
547 
INSTRUCTION(lqid)548 INSTRUCTION( lqid )
549 {
550 	WRITE_Q(operand);
551 	POP();
552 }
553 
554 /*
555 
556     Mnemonic:           RMB
557 
558     Operand:            0
559                         1
560                         2
561                         3
562 
563     Hex Code:           4C
564                         45
565                         42
566                         43
567 
568     Binary:             0 1 0 0 1 1 0 0
569                         0 1 0 0 0 1 0 1
570                         0 1 0 0 0 0 1 0
571                         0 1 0 0 0 0 1 1
572 
573     Data Flow:          0 -> RAM(B)0
574                         0 -> RAM(B)1
575                         0 -> RAM(B)2
576                         0 -> RAM(B)3
577 
578     Description:        Reset RAM Bit
579 
580 */
581 
INSTRUCTION(rmb0)582 INSTRUCTION( rmb0 ) { RAM_W(B, RAM_R(B) & 0xE); }
INSTRUCTION(rmb1)583 INSTRUCTION( rmb1 ) { RAM_W(B, RAM_R(B) & 0xD); }
INSTRUCTION(rmb2)584 INSTRUCTION( rmb2 ) { RAM_W(B, RAM_R(B) & 0xB); }
INSTRUCTION(rmb3)585 INSTRUCTION( rmb3 ) { RAM_W(B, RAM_R(B) & 0x7); }
586 
587 /*
588 
589     Mnemonic:           SMB
590 
591     Operand:            0
592                         1
593                         2
594                         3
595 
596     Hex Code:           4D
597                         47
598                         46
599                         4B
600 
601     Binary:             0 1 0 0 1 1 0 1
602                         0 1 0 0 0 1 1 1
603                         0 1 0 0 0 1 1 0
604                         0 1 0 0 1 0 1 1
605 
606     Data Flow:          1 -> RAM(B)0
607                         1 -> RAM(B)1
608                         1 -> RAM(B)2
609                         1 -> RAM(B)3
610 
611     Description:        Set RAM Bit
612 
613 */
614 
INSTRUCTION(smb0)615 INSTRUCTION( smb0 ) { RAM_W(B, RAM_R(B) | 0x1); }
INSTRUCTION(smb1)616 INSTRUCTION( smb1 ) { RAM_W(B, RAM_R(B) | 0x2); }
INSTRUCTION(smb2)617 INSTRUCTION( smb2 ) { RAM_W(B, RAM_R(B) | 0x4); }
INSTRUCTION(smb3)618 INSTRUCTION( smb3 ) { RAM_W(B, RAM_R(B) | 0x8); }
619 
620 /*
621 
622     Mnemonic:           STII
623 
624     Operand:            y
625     Hex Code:           7-
626     Binary:             0 1 1 1 y3 y2 y1 y0
627 
628     Data Flow:          y -> RAM(B)
629                         Bd + 1 -> Bd
630 
631     Description:        Store Memory Immediate and Increment Bd
632 
633 */
634 
INSTRUCTION(stii)635 INSTRUCTION( stii )
636 {
637 	uint8_t y = m_opcode & 0x0f;
638 	uint16_t Bd;
639 
640 	RAM_W(B, y);
641 
642 	Bd = ((B & 0x0f) + 1) & 0x0f;
643 	B = (B & 0x70) + Bd;
644 }
645 
646 /*
647 
648     Mnemonic:           X
649 
650     Operand:            r
651     Hex Code:           -6
652     Binary:             0 0 r1 r0 0 1 1 0
653 
654     Data Flow:          RAM(B) <-> A
655                         Br ^ r -> Br
656 
657     Description:        Exchange RAM with A, Exclusive-OR Br with r
658 
659 */
660 
INSTRUCTION(x)661 INSTRUCTION( x )
662 {
663 	uint8_t r = m_opcode & 0x30;
664 	uint8_t t = RAM_R(B);
665 
666 	RAM_W(B, A);
667 
668 	A = t;
669 	B = B ^ r;
670 }
671 
672 /*
673 
674     Mnemonic:           XAD
675 
676     Operand:            r,d
677     Hex Code:           23 --
678     Binary:             0 0 1 0 0 0 1 1 1 r2 r1 r0 d3 d2 d1 d0
679 
680     Data Flow:          RAM(r,d) <-> A
681 
682     Description:        Exchange A with RAM pointed to directly by r,d
683 
684 */
685 
INSTRUCTION(xad)686 INSTRUCTION( xad )
687 {
688 	uint8_t rd = operand & 0x7f;
689 	uint8_t t = A;
690 
691 	A = RAM_R(rd);
692 
693 	RAM_W(rd, t);
694 }
695 
696 /*
697 
698     Mnemonic:           XDS
699 
700     Operand:            r
701     Hex Code:           -7
702     Binary:             0 0 r1 r0 0 1 1 1
703 
704     Data Flow:          RAM(B) <-> A
705                         Bd - 1 -> Bd
706                         Br ^ r -> Br
707 
708     Skip Conditions:    Bd decrements past 0
709 
710     Description:        Exchange RAM with A and Decrement Bd, Exclusive-OR Br with r
711 
712 */
713 
INSTRUCTION(xds)714 INSTRUCTION( xds )
715 {
716 	uint8_t t, Bd;
717 	uint8_t r = m_opcode & 0x30;
718 
719 	t = RAM_R(B);
720 	RAM_W(B, A);
721 	A = t;
722 
723 	Bd = ((B & 0x0f) - 1) & 0x0f;
724 	B = (B & 0x70) | Bd;
725 
726 	B = B ^ r;
727 
728 	if (Bd == 0x0f)
729 		skip();
730 }
731 
732 /*
733 
734     Mnemonic:           XIS
735 
736     Operand:            r
737     Hex Code:           -4
738     Binary:             0 0 r1 r0 0 1 0 0
739 
740     Data Flow:          RAM(B) <-> A
741                         Bd + 1 -> Bd
742                         Br ^ r -> Br
743 
744     Skip Conditions:    Bd increments past 15
745 
746     Description:        Exchange RAM with A and Increment Bd, Exclusive-OR Br with r
747 
748 */
749 
INSTRUCTION(xis)750 INSTRUCTION( xis )
751 {
752 	uint8_t t, Bd;
753 	uint8_t r = m_opcode & 0x30;
754 
755 	t = RAM_R(B);
756 	RAM_W(B, A);
757 	A = t;
758 
759 	Bd = ((B & 0x0f) + 1) & 0x0f;
760 	B = (B & 0x70) | Bd;
761 
762 	B = B ^ r;
763 
764 	if (Bd == 0x00)
765 		skip();
766 }
767 
768 /*
769 
770     Mnemonic:           CQMA
771 
772     Hex Code:           33 2C
773     Binary:             0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0
774 
775     Data Flow:          Q7:4 -> RAM(B)
776                         Q3:0 -> A
777 
778     Description:        Copy Q to RAM, A
779 
780 */
781 
INSTRUCTION(cqma)782 INSTRUCTION( cqma )
783 {
784 	RAM_W(B, Q >> 4);
785 	A = Q & 0xF;
786 }
787 
788 /*
789 
790     Mnemonic:           LDD
791 
792     Operand:            r, d
793     Hex Code:           23 --
794     Binary:             0 0 1 0 0 0 1 1 0 r2 r1 r0 d3 d2 d1 d0
795 
796     Data Flow:          RAM(r,d) -> A
797 
798     Description:        Load A with RAM pointed to directly by r,d
799 
800 */
801 
INSTRUCTION(ldd)802 INSTRUCTION( ldd )
803 {
804 	uint8_t rd = operand & 0x7f;
805 
806 	A = RAM_R(rd);
807 }
808 
809 /*
810 
811     Mnemonic:           CAMT
812 
813     Hex Code:           33 3F
814     Binary:
815 
816     Data Flow:          A -> T7:4
817                         RAM(B) -> T3:0
818 
819     Description:        Copy A, RAM to T
820 
821 */
822 
INSTRUCTION(camt)823 INSTRUCTION( camt )
824 {
825 	T = (A << 4) | RAM_R(B);
826 }
827 /*
828 
829     Mnemonic:           CTMA
830 
831     Hex Code:           33 2F
832     Binary:
833 
834     Data Flow:          T7:4 -> RAM(B)
835                         T3:0 -> A
836 
837     Description:        Copy T to RAM, A
838 
839 */
840 
INSTRUCTION(ctma)841 INSTRUCTION( ctma )
842 {
843 	RAM_W(B, T >> 4);
844 	A = T & 0x0f;
845 }
846 
847 /***************************************************************************
848     REGISTER REFERENCE INSTRUCTIONS
849 ***************************************************************************/
850 
851 /*
852 
853     Mnemonic:           CAB
854 
855     Hex Code:           50
856     Binary:             0 1 0 1 0 0 0 0 0
857 
858     Data Flow:          A -> Bd
859 
860     Description:        Copy A to Bd
861 
862 */
863 
INSTRUCTION(cab)864 INSTRUCTION( cab )
865 {
866 	B = (B & 0x70) | A;
867 }
868 
869 /*
870 
871     Mnemonic:           CBA
872 
873     Hex Code:           4E
874     Binary:             0 1 0 0 1 1 1 0
875 
876     Data Flow:          Bd -> A
877 
878     Description:        Copy Bd to A
879 
880 */
881 
INSTRUCTION(cba)882 INSTRUCTION( cba )
883 {
884 	A = B & 0xF;
885 }
886 
887 /*
888 
889     Mnemonic:           LBI
890 
891     Operand:            r,d
892     Hex Code:           --
893                         33 --
894 
895     Binary:             0 0 r1 r0 d3 d2 d1 d0 (d-1)
896                         0 0 1 1 0 0 1 1 1 r2 r1 r0 d3 d2 d1 d0
897 
898     Data Flow:          r,d -> B
899 
900     Skip Conditions:    Skip until not a LBI
901 
902     Description:        Load B Immediate with r,d
903 
904 */
905 
INSTRUCTION(lbi)906 INSTRUCTION( lbi )
907 {
908 	m_skip_lbi++;
909 	if (m_skip_lbi > 1) return;
910 	m_skip_lbi++;
911 
912 	if (operand & 0x80)
913 	{
914 		B = operand & 0x7f;
915 	}
916 	else
917 	{
918 		B = (operand & 0x30) | (((operand & 0x0f) + 1) & 0x0f);
919 	}
920 }
921 
922 /*
923 
924     Mnemonic:           LEI
925 
926     Operand:            y
927     Hex Code:           33 6-
928     Binary:             0 0 1 1 0 0 1 1 0 1 1 0 y3 y2 y1 y0
929 
930     Data Flow:          y -> EN
931 
932     Description:        Load EN Immediate
933 
934 */
935 
INSTRUCTION(lei)936 INSTRUCTION( lei )
937 {
938 	uint8_t y = operand & 0x0f;
939 
940 	WRITE_EN(y);
941 }
942 
943 /*
944 
945     Mnemonic:           XABR
946 
947     Hex Code:           12
948     Binary:             0 0 0 1 0 0 1 0
949 
950     Data Flow:          A <-> Br(0,0 -> A3,A2)
951 
952     Description:        Exchange A with Br
953 
954 */
955 
INSTRUCTION(xabr)956 INSTRUCTION( xabr )
957 {
958 	uint8_t Br = A & 0x03;
959 	uint8_t Bd = B & 0x0f;
960 
961 	A = B >> 4;
962 	B = (Br << 4) + Bd;
963 }
964 
965 /*
966 
967     Processor:          COP444L
968 
969     Mnemonic:           XABR
970 
971     Hex Code:           12
972     Binary:             0 0 0 1 0 0 1 0
973 
974     Data Flow:          A <-> Br(0 -> A3)
975 
976     Description:        Exchange A with Br
977 
978 */
979 
INSTRUCTION(cop444l_xabr)980 INSTRUCTION( cop444l_xabr )
981 {
982 	uint8_t Br = A & 0x07;
983 	uint8_t Bd = B & 0x0f;
984 
985 	A = B >> 4;
986 	B = (Br << 4) + Bd;
987 }
988 
989 /***************************************************************************
990     TEST INSTRUCTIONS
991 ***************************************************************************/
992 
993 /*
994 
995     Mnemonic:           SKC
996 
997     Hex Code:           20
998     Binary:             0 0 1 0 0 0 0 0
999 
1000     Skip Conditions:    C = "1"
1001 
1002     Description:        Skip if C is True
1003 
1004 */
1005 
INSTRUCTION(skc)1006 INSTRUCTION( skc )
1007 {
1008 	if (C == 1)
1009 		skip();
1010 }
1011 
1012 /*
1013 
1014     Mnemonic:           SKE
1015 
1016     Hex Code:           21
1017     Binary:             0 0 1 0 0 0 0 1
1018 
1019     Skip Conditions:    A = RAM(B)
1020 
1021     Description:        Skip if A Equals RAM
1022 
1023 */
1024 
INSTRUCTION(ske)1025 INSTRUCTION( ske )
1026 {
1027 	if (A == RAM_R(B))
1028 		skip();
1029 }
1030 
1031 /*
1032 
1033     Mnemonic:           SKGZ
1034 
1035     Hex Code:           33 21
1036     Binary:             00 0 1 1 0 0 1 1 0 0 1 0 0 0 0 1
1037 
1038     Skip Conditions:    G3:0 = 0
1039 
1040     Description:        Skip if G is Zero (all 4 bits)
1041 
1042 */
1043 
INSTRUCTION(skgz)1044 INSTRUCTION( skgz )
1045 {
1046 	if (IN_G() == 0)
1047 		skip();
1048 }
1049 
1050 /*
1051 
1052     Mnemonic:           SKGBZ
1053 
1054     Hex Code:           33 01
1055                         33 11
1056                         33 03
1057                         33 13
1058 
1059     Binary:
1060 
1061     Skip Conditions:    G0 = 0
1062                         G1 = 0
1063                         G2 = 0
1064                         G3 = 0
1065 
1066     Description:        Skip if G Bit is Zero
1067 
1068 */
1069 
skgbz(int bit)1070 void cop400_cpu_device::skgbz(int bit)
1071 {
1072 	if (!BIT(IN_G(), bit))
1073 		skip();
1074 }
1075 
INSTRUCTION(skgbz0)1076 INSTRUCTION( skgbz0 ) { skgbz(0); }
INSTRUCTION(skgbz1)1077 INSTRUCTION( skgbz1 ) { skgbz(1); }
INSTRUCTION(skgbz2)1078 INSTRUCTION( skgbz2 ) { skgbz(2); }
INSTRUCTION(skgbz3)1079 INSTRUCTION( skgbz3 ) { skgbz(3); }
1080 
1081 /*
1082 
1083     Mnemonic:           SKMBZ
1084 
1085     Hex Code:           01
1086                         11
1087                         03
1088                         13
1089 
1090     Binary:
1091 
1092     Skip Conditions:    RAM(B)0 = 0
1093                         RAM(B)0 = 1
1094                         RAM(B)0 = 2
1095                         RAM(B)0 = 3
1096 
1097     Description:        Skip if RAM Bit is Zero
1098 
1099 */
1100 
skmbz(int bit)1101 void cop400_cpu_device::skmbz(int bit)
1102 {
1103 	if (!BIT(RAM_R(B), bit))
1104 		skip();
1105 }
1106 
INSTRUCTION(skmbz0)1107 INSTRUCTION( skmbz0 ) { skmbz(0); }
INSTRUCTION(skmbz1)1108 INSTRUCTION( skmbz1 ) { skmbz(1); }
INSTRUCTION(skmbz2)1109 INSTRUCTION( skmbz2 ) { skmbz(2); }
INSTRUCTION(skmbz3)1110 INSTRUCTION( skmbz3 ) { skmbz(3); }
1111 
1112 /*
1113 
1114     Mnemonic:           SKT
1115 
1116     Hex Code:           41
1117     Binary:             0 1 0 0 0 0 0 1
1118 
1119     Skip Conditions:    A time-base counter carry has occurred since last test
1120 
1121     Description:        Skip on Timer
1122 
1123 */
1124 
INSTRUCTION(skt)1125 INSTRUCTION( skt )
1126 {
1127 	if (m_skt_latch)
1128 	{
1129 		m_skt_latch = 0;
1130 		skip();
1131 	}
1132 }
1133 
1134 /***************************************************************************
1135     INPUT/OUTPUT INSTRUCTIONS
1136 ***************************************************************************/
1137 
1138 /*
1139 
1140     Mnemonic:           ING
1141 
1142     Hex Code:           33 2A
1143     Binary:
1144 
1145     Data Flow:          G -> A
1146 
1147     Description:        Input G Ports to A
1148 
1149 */
1150 
INSTRUCTION(ing)1151 INSTRUCTION( ing )
1152 {
1153 	A = IN_G();
1154 }
1155 
1156 /*
1157 
1158     Mnemonic:           INL
1159 
1160     Hex Code:           33 2E
1161     Binary:
1162 
1163     Data Flow:          L7:4 -> RAM(B)
1164                         L3:0 -> A
1165 
1166     Description:        Input L Ports to RAM,A
1167 
1168 */
1169 
INSTRUCTION(inl)1170 INSTRUCTION( inl )
1171 {
1172 	uint8_t L = IN_L();
1173 
1174 	RAM_W(B, L >> 4);
1175 	A = L & 0xF;
1176 }
1177 
1178 /*
1179 
1180     Mnemonic:           OBD
1181 
1182     Hex Code:           33 3E
1183     Binary:
1184 
1185     Data Flow:          Bd -> D
1186 
1187     Description:        Output Bd to D Outputs
1188 
1189 */
1190 
INSTRUCTION(obd)1191 INSTRUCTION( obd )
1192 {
1193 	OUT_D(B & 0x0f);
1194 }
1195 
1196 /*
1197 
1198     Mnemonic:           OMG
1199 
1200     Hex Code:           33 3A
1201     Binary:
1202 
1203     Data Flow:          RAM(B) -> G
1204 
1205     Description:        Output RAM to G Ports
1206 
1207 */
1208 
INSTRUCTION(omg)1209 INSTRUCTION( omg )
1210 {
1211 	WRITE_G(RAM_R(B));
1212 }
1213 
1214 /*
1215 
1216     Mnemonic:           XAS
1217 
1218     Hex Code:           4F
1219     Binary:             0 1 0 0 1 1 1 1
1220 
1221     Data Flow:          A <-> SIO
1222                         C -> SK
1223 
1224     Description:        Exchange A with SIO
1225 
1226 */
1227 
INSTRUCTION(xas)1228 INSTRUCTION( xas )
1229 {
1230 	uint8_t t = SIO;
1231 	SIO = A;
1232 	A = t;
1233 
1234 	if (SKL != C)
1235 	{
1236 		SKL = C;
1237 		sk_update();
1238 	}
1239 }
1240 
1241 /*
1242 
1243     Mnemonic:           ININ
1244 
1245     Hex Code:           33 28
1246     Binary:
1247 
1248     Data Flow:          IN -> A
1249 
1250     Description:        Input IN Inputs to A
1251 
1252 */
1253 
INSTRUCTION(inin)1254 INSTRUCTION( inin )
1255 {
1256 	A = IN_IN();
1257 }
1258 
1259 /*
1260 
1261     Processor:          COP402M
1262 
1263     Mnemonic:           ININ
1264 
1265     Hex Code:           33 28
1266     Binary:
1267 
1268     Data Flow:          IN -> A, A1 = "1"
1269 
1270     Description:        Input IN Inputs to A
1271 
1272 */
1273 
INSTRUCTION(cop402m_inin)1274 INSTRUCTION( cop402m_inin )
1275 {
1276 	A = IN_IN() | 0x02;
1277 }
1278 
1279 /*
1280 
1281     Mnemonic:           INIL
1282 
1283     Hex Code:           33 29
1284     Binary:
1285 
1286     Data Flow:          IL3,CKO,"0",IL0 -> A
1287 
1288     Description:        Input IL Latches to A
1289 
1290 */
1291 
INSTRUCTION(inil)1292 INSTRUCTION( inil )
1293 {
1294 	A = (IL & 0x09) | IN_CKO() << 2;
1295 
1296 	IL = 0;
1297 }
1298 
1299 /*
1300 
1301     Mnemonic:           OGI
1302 
1303     Operand:            y
1304     Hex Code:           33 5-
1305     Binary:             0 0 1 1 0 0 1 1 0 1 0 1 y3 y2 y1 y0
1306 
1307     Data Flow:          y -> G
1308 
1309     Description:        Output to G Ports Immediate
1310 
1311 */
1312 
INSTRUCTION(ogi)1313 INSTRUCTION( ogi )
1314 {
1315 	uint8_t y = operand & 0x0f;
1316 
1317 	WRITE_G(y);
1318 }
1319