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