2 ; This is part of the Z80-CP/M emulator written by Sprite_tm.
5 ; Copyright (C) 2010 Sprite_tm
6 ; Copyright (C) 2010 Leo C.
7 ; Copyright (C) 2010 Horst S.
9 ; This file is part of avrcpm.
11 ; avrcpm is free software: you can redistribute it and/or modify it
12 ; under the terms of the GNU General Public License as published by
13 ; the Free Software Foundation, either version 3 of the License, or
14 ; (at your option) any later version.
16 ; avrcpm is distributed in the hope that it will be useful,
17 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ; GNU General Public License for more details.
21 ; You should have received a copy of the GNU General Public License
22 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
80 .equ IM_MASK = 0x03 ;Mask IM 0..2
85 .equ IFF1 = 2 ;IFF1 Flag
86 .equ IFF2 = 3 ;IFF2 Flag
94 ldi z_pcl,low (IPLADDR)
95 ldi z_pch,high(IPLADDR)
99 printstring "Ok, CPU is live!"
105 cpi z_pch,DBG_TRACE_BOTTOM
107 cpi z_pch,DBG_TRACE_TOP
114 cpi z_pch,DBG_TRACE_BOTTOM
116 cpi z_pch,DBG_TRACE_TOP
132 ;hier kommt die Interruptbehandlung rein
134 mem_read_s z_pc ;temp=memReadByte(z_pc)
136 ldi zl,low(todo_table*2) ;zhl=todo_table
137 ldi zh,high(todo_table*2) ;
142 lpm insdecl,Z+ ;do_store
143 lpm insdech,Z+ ;do_op
145 ldi zh,high(fetch_ops)
150 ;-----------------------------------------------------
151 ; Generate jump to target and position in table
155 .ifndef opjmp_table_pos_
156 .set opjmp_table_page_ = high(PC)
157 .set opjmp_table_pos_ = PC
159 .equ @0 = low(opjmp_table_pos_)
160 .set opjmp_table_pos_ = opjmp_table_pos_ + 1
161 .if high(opjmp_table_pos_) != opjmp_table_page_
162 .warning "Table 'opjump' crosses page boarder."
163 .message "Program will not work, unless the opjump table is relocated."
168 ;--------------------------------------------------
169 ; Generate a table entry for one instruction
171 ; instr fetch, op, store
174 .ifndef inst_table_odd_
175 .set inst_table_odd_ = 0
179 .db inst_table_next_, low(@2), @1, low(@0)
180 .set inst_table_odd_ = 0
182 .set inst_table_next_ = low(@0)
184 .set inst_table_odd_ = 1
188 ;-----------------------------------
197 ;-----------------------------------
201 ldi zh,high(store_ops) ;
206 ;-----------------------------------
213 ;-----------------------------------
214 ; go back to main directly
221 ; ------------ Fetch phase stuff -----------------
223 .org (PC+255) & 0xff00
306 mem_read_ds opl, z_pc
311 mem_read_ds opl, z_pc
313 mem_read_ds oph, z_pc
325 ; ------------ Store phase stuff -----------------
327 .org (PC+255) & 0xff00
423 printstring "Stack pop "
426 printstring ", SP is now "
443 printstring "Stack push "
446 printstring ", SP is now "
461 ; ------------ Operation phase stuff -----------------
463 ;.org (PC+255) & 0xff00
512 ;----------------------------------------------------------------
516 ;| ZZZZZZZ 88888 000 |
522 ;| ZZZZZZZ 88888 000 |
524 ;| Z80 MICROPROCESSOR Instruction Set Summary |
526 ;----------------------------------------------------------------
527 ;----------------------------------------------------------------
528 ;|Mnemonic |SZHPNC|Description |Notes |
529 ;|----------+------+---------------------+----------------------|
530 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
531 ;|ADC HL,ss |**?V0*|Add with Carry |HL=HL+ss+CY |
532 ;|ADD A,s |***V0*|Add |A=A+s |
533 ;|ADD HL,ss |--*-0*|Add |HL=HL+ss |
534 ;|ADD IX,pp |--*-0*|Add |IX=IX+pp |
535 ;|ADD IY,rr |--*-0*|Add |IY=IY+rr |
536 ;|AND s |**1P00|Logical AND |A=A&s |
537 ;|BIT b,m |?*1?0-|Test Bit |m&{2^b} |
538 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
539 ;|CALL nn |------|Unconditional Call |-[SP]=PC,PC=nn |
540 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY |
541 ;|CP s |***V1*|Compare |A-s |
542 ;|CPD |****1-|Compare and Decrement|A-[HL],HL=HL-1,BC=BC-1|
543 ;|CPDR |****1-|Compare, Dec., Repeat|CPD till A=[HL]or BC=0|
544 ;|CPI |****1-|Compare and Increment|A-[HL],HL=HL+1,BC=BC-1|
545 ;|CPIR |****1-|Compare, Inc., Repeat|CPI till A=[HL]or BC=0|
546 ;|CPL |--1-1-|Complement |A=~A |
547 ;|DAA |***P-*|Decimal Adjust Acc. |A=BCD format |
548 ;|DEC s |***V1-|Decrement |s=s-1 |
549 ;|DEC xx |------|Decrement |xx=xx-1 |
550 ;|DEC ss |------|Decrement |ss=ss-1 |
551 ;|DI |------|Disable Interrupts |IFF1 = IFF2 = 0 |
552 ;|DJNZ e |------|Dec., Jump Non-Zero |B=B-1 till B=0 |
553 ;|EI |------|Enable Interrupts |IFF1 = IFF2 = 1 |
554 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
555 ;|EX [SP],xx|------|Exchange |[SP]<->xx |
556 ;|EX AF,AF' |------|Exchange |AF<->AF' |
557 ;|EX DE,HL |------|Exchange |DE<->HL |
558 ;|EXX |------|Exchange |qq<->qq' (except AF)|
559 ;|HALT |------|Halt | |
560 ;|IM n |------|Interrupt Mode | (n=0,1,2)|
561 ;|IN A,[n] |------|Input |A=[n] |
562 ;|IN r,[C] |***P0-|Input |r=[C] |
563 ;|INC r |***V0-|Increment |r=r+1 |
564 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
565 ;|INC xx |------|Increment |xx=xx+1 |
566 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
567 ;|INC ss |------|Increment |ss=ss+1 |
568 ;|IND |?*??1-|Input and Decrement |[HL]=[C],HL=HL-1,B=B-1|
569 ;|INDR |?1??1-|Input, Dec., Repeat |IND till B=0 |
570 ;|INI |?*??1-|Input and Increment |[HL]=[C],HL=HL+1,B=B-1|
571 ;|INIR |?1??1-|Input, Inc., Repeat |INI till B=0 |
572 ;|JP [HL] |------|Unconditional Jump |PC=[HL] |
573 ;|JP [xx] |------|Unconditional Jump |PC=[xx] |
574 ;|JP nn |------|Unconditional Jump |PC=nn |
575 ;|JP cc,nn |------|Conditional Jump |If cc JP |
576 ;|JR e |------|Unconditional Jump |PC=PC+e |
577 ;|JR cc,e |------|Conditional Jump |If cc JR(cc=C,NC,NZ,Z)|
578 ;|LD dst,src|------|Load |dst=src |
579 ;|LD A,i |**0*0-|Load |A=i (i=I,R)|
580 ;|LDD |--0*0-|Load and Decrement |[DE]=[HL],HL=HL-1,# |
581 ;|LDDR |--000-|Load, Dec., Repeat |LDD till BC=0 |
582 ;|LDI |--0*0-|Load and Increment |[DE]=[HL],HL=HL+1,# |
583 ;|LDIR |--000-|Load, Inc., Repeat |LDI till BC=0 |
584 ;|NEG |***V1*|Negate |A=-A |
585 ;|NOP |------|No Operation | |
586 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
587 ;|OTDR |?1??1-|Output, Dec., Repeat |OUTD till B=0 |
588 ;|OTIR |?1??1-|Output, Inc., Repeat |OUTI till B=0 |
589 ;|OUT [C],r |------|Output |[C]=r |
590 ;|OUT [n],A |------|Output |[n]=A |
591 ;|OUTD |?*??1-|Output and Decrement |[C]=[HL],HL=HL-1,B=B-1|
592 ;|OUTI |?*??1-|Output and Increment |[C]=[HL],HL=HL+1,B=B-1|
593 ;|POP xx |------|Pop |xx=[SP]+ |
594 ;|POP qq |------|Pop |qq=[SP]+ |
595 ;|PUSH xx |------|Push |-[SP]=xx |
596 ;|PUSH qq |------|Push |-[SP]=qq |
597 ;|RES b,m |------|Reset bit |m=m&{~2^b} |
598 ;|RET |------|Return |PC=[SP]+ |
599 ;|RET cc |------|Conditional Return |If cc RET |
600 ;|RETI |------|Return from Interrupt|PC=[SP]+ |
601 ;|RETN |------|Return from NMI |PC=[SP]+ |
602 ;|RL m |**0P0*|Rotate Left |m={CY,m}<- |
603 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
604 ;|RLC m |**0P0*|Rotate Left Circular |m=m<- |
605 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
606 ;|RLD |**0P0-|Rotate Left 4 bits |{A,[HL]}={A,[HL]}<- ##|
607 ;|RR m |**0P0*|Rotate Right |m=->{CY,m} |
608 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
609 ;|RRC m |**0P0*|Rotate Right Circular|m=->m |
610 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
611 ;|RRD |**0P0-|Rotate Right 4 bits |{A,[HL]}=->{A,[HL]} ##|
612 ;|RST p |------|Restart | (p=0H,8H,10H,...,38H)|
613 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
614 ;|SBC HL,ss |***V1*|Subtract with Carry |HL=HL-ss-CY |
615 ;|SCF |--0-01|Set Carry Flag |CY=1 |
616 ;|SET b,m |------|Set bit |m=mv{2^b} |
617 ;|SLA m |**0P0*|Shift Left Arithmetic|m=m*2 |
618 ;|SRA m |**0P0*|Shift Right Arith. |m=m/2 |
619 ;|SRL m |**0P0*|Shift Right Logical |m=->{0,m,CY} |
620 ;|SUB s |***V1*|Subtract |A=A-s |
621 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
622 ;|----------+------+--------------------------------------------|
623 ;| F |-*01? |Flag unaffected/affected/reset/set/unknown |
624 ;| S |S |Sign flag (Bit 7) |
625 ;| Z | Z |Zero flag (Bit 6) |
626 ;| HC | H |Half Carry flag (Bit 4) |
627 ;| P/V | P |Parity/Overflow flag (Bit 2, V=overflow) |
628 ;| N | N |Add/Subtract flag (Bit 1) |
629 ;| CY | C|Carry flag (Bit 0) |
630 ;|-----------------+--------------------------------------------|
631 ;| n |Immediate addressing |
632 ;| nn |Immediate extended addressing |
633 ;| e |Relative addressing (PC=PC+2+offset) |
634 ;| [nn] |Extended addressing |
635 ;| [xx+d] |Indexed addressing |
636 ;| r |Register addressing |
637 ;| [rr] |Register indirect addressing |
638 ;| |Implied addressing |
639 ;| b |Bit addressing |
640 ;| p |Modified page zero addressing (see RST) |
641 ;|-----------------+--------------------------------------------|
642 ;|DEFB n(,...) |Define Byte(s) |
643 ;|DEFB 'str'(,...) |Define Byte ASCII string(s) |
644 ;|DEFS nn |Define Storage Block |
645 ;|DEFW nn(,...) |Define Word(s) |
646 ;|-----------------+--------------------------------------------|
647 ;| A B C D E |Registers (8-bit) |
648 ;| AF BC DE HL |Register pairs (16-bit) |
649 ;| F |Flag register (8-bit) |
650 ;| I |Interrupt page address register (8-bit) |
651 ;| IX IY |Index registers (16-bit) |
652 ;| PC |Program Counter register (16-bit) |
653 ;| R |Memory Refresh register |
654 ;| SP |Stack Pointer register (16-bit) |
655 ;|-----------------+--------------------------------------------|
656 ;| b |One bit (0 to 7) |
657 ;| cc |Condition (C,M,NC,NZ,P,PE,PO,Z) |
658 ;| d |One-byte expression (-128 to +127) |
659 ;| dst |Destination s, ss, [BC], [DE], [HL], [nn] |
660 ;| e |One-byte expression (-126 to +129) |
661 ;| m |Any register r, [HL] or [xx+d] |
662 ;| n |One-byte expression (0 to 255) |
663 ;| nn |Two-byte expression (0 to 65535) |
664 ;| pp |Register pair BC, DE, IX or SP |
665 ;| qq |Register pair AF, BC, DE or HL |
666 ;| qq' |Alternative register pair AF, BC, DE or HL |
667 ;| r |Register A, B, C, D, E, H or L |
668 ;| rr |Register pair BC, DE, IY or SP |
669 ;| s |Any register r, value n, [HL] or [xx+d] |
670 ;| src |Source s, ss, [BC], [DE], [HL], nn, [nn] |
671 ;| ss |Register pair BC, DE, HL or SP |
672 ;| xx |Index register IX or IY |
673 ;|-----------------+--------------------------------------------|
674 ;| + - * / ^ |Add/subtract/multiply/divide/exponent |
675 ;| & ~ v x |Logical AND/NOT/inclusive OR/exclusive OR |
676 ;| <- -> |Rotate left/right |
677 ;| [ ] |Indirect addressing |
678 ;| [ ]+ -[ ] |Indirect addressing auto-increment/decrement|
679 ;| { } |Combination of operands |
680 ;| # |Also BC=BC-1,DE=DE-1 |
681 ;| ## |Only lower 4 bits of accumulator A used |
682 ;----------------------------------------------------------------
684 ;How the flags are supposed to work:
685 ;7 ZFL_S - Sign flag (=MSBit of result)
686 ;6 ZFL_Z - Zero flag. Is 1 when the result is 0
687 ;4 ZFL_H - Half-carry (carry from bit 3 to 4)
688 ;2 ZFL_P - Parity/2-complement Overflow
689 ;1 ZFL_N - Subtract - set if last op was a subtract
692 ;I sure hope I got the mapping between flags and instructions correct...
709 ;------------------------------------------------;
710 ; Load table value from flash indexed by source reg.
712 ; ldpmx dstreg,tablebase,indexreg
714 ; (6 words, 8 cycles)
717 ldi zh,high(@1*2) ; table must be page aligned
722 .macro do_z80_flags_V
724 bmov z_flags, ZFL_P, temp, AVR_V
728 .macro do_z80_flags_H
730 bmov z_flags, ZFL_H, temp, AVR_H
734 .macro do_z80_flags_set_N
736 ori z_flags, (1<<ZFL_N) ; Negation auf 1
740 .macro do_z80_flags_set_HN
742 ori z_flags,(1<<ZFL_N)|(1<<ZFL_H)
746 .macro do_z80_flags_clear_N
748 andi z_flags,~(1<<ZFL_N)
752 .macro do_z80_flags_clear_HN
754 andi z_flags,~((1<<ZFL_H)|(1<<ZFL_N))
759 .macro do_z80_flags_copy_HC
761 bmov z_flags, ZFL_H, z_flags, ZFL_H
765 .macro do_z80_flags_op_rotate
766 ; must not change avr carry flag!
768 andi z_flags, ~( (1<<ZFL_H) | (1<<ZFL_N) | (1<<ZFL_C) )
770 andi z_flags, ~( (1<<ZFL_C) )
774 .macro do_z80_flags_op_and
776 ori z_flags,(1<<ZFL_H)
780 .macro do_z80_flags_op_or
787 ;----------------------------------------------------------------
792 printstring "Invalid opcode! "
800 ;----------------------------------------------------------------
801 ;|Mnemonic |SZHPNC|Description |Notes |
802 ;----------------------------------------------------------------
803 ;|OUT [n],A |------|Output |[n]=A |
806 ;Interface with peripherials goes here :)
807 do_op_outa: ; out (opl),a
810 printstring "Port write: "
823 ;----------------------------------------------------------------
824 ;|Mnemonic |SZHPNC|Description |Notes |
825 ;----------------------------------------------------------------
826 ;|IN A,[n] |------|Input |A=[n] |
829 do_op_ina: ; in a,(opl)
832 printstring "Port read: ("
848 ;----------------------------------------------------------------
849 ;|Mnemonic |SZHPNC|Description |Notes |
850 ;----------------------------------------------------------------
851 ;|INC r |***V0-|Increment |r=r+1 |
852 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
853 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
854 ;|----------|SZHP C|---------- 8080 ----------------------------|
855 ;|INC r |**-P0-|Increment |r=r+1 |
856 ;|INC [HL] |**-P0-|Increment |[HL]=[HL]+1 |
863 andi z_flags,(1<<ZFL_C) ; preserve C-flag
864 ldpmx temp2, sz53p_tab, opl
866 bmov z_flags, ZFL_H, temp, AVR_H
874 andi z_flags,(1<<ZFL_C) ; preserve C-flag
875 ldpmx temp2, sz53p_tab, z_a
877 bmov z_flags, ZFL_H, temp, AVR_H
881 ;----------------------------------------------------------------
882 ;|Mnemonic |SZHPNC|Description |Notes |
883 ;----------------------------------------------------------------
884 ;|DEC r |***V1-|Decrement |s=s-1 |
885 ;|INC [HL] |***V0-|Increment |[HL]=[HL]+1 |
886 ;|INC [xx+d]|***V0-|Increment |[xx+d]=[xx+d]+1 |
887 ;|----------|SZHP C|---------- 8080 ----------------------------|
888 ;|DEC r |**-P -|Increment |r=r+1 |
889 ;|DEC [HL] |**-P -|Increment |[HL]=[HL]+1 |
895 andi z_flags,(1<<ZFL_C) ; preserve C-flag
896 ldpmx temp2, sz53p_tab, opl
898 bmov z_flags, ZFL_H, temp, AVR_H
907 andi z_flags,(1<<ZFL_C) ; preserve C-flag
908 ldpmx temp2, sz53p_tab, z_a
910 bmov z_flags, ZFL_H, temp, AVR_H
915 ;----------------------------------------------------------------
916 ;|Mnemonic |SZHPNC|Description |Notes |
917 ;----------------------------------------------------------------
918 ;|INC xx |------|Increment |xx=xx+1 |
919 ;|INC ss |------|Increment |ss=ss+1 |
927 ;----------------------------------------------------------------
928 ;|Mnemonic |SZHPNC|Description |Notes |
929 ;----------------------------------------------------------------
930 ;|DEC xx |------|Decrement |xx=xx-1 |
931 ;|DEC ss |------|Decrement |ss=ss-1 |
939 ;----------------------------------------------------------------
940 ;|Mnemonic |SZHPNC|Description |Notes |
941 ;----------------------------------------------------------------
942 ;|RLCA |--0-0*|Rotate Left Circular |A=A<- |
943 ;|----------|SZHP C|---------- 8080 ----------------------------|
944 ;|RLCA |---- *|Rotate Left Circular |A=A<- |
948 ;Rotate Left Cyclical. All bits move 1 to the
949 ;left, the msb becomes c and lsb.
950 do_z80_flags_op_rotate
955 ori z_flags, (1<<ZFL_C)
959 ;----------------------------------------------------------------
960 ;|Mnemonic |SZHPNC|Description |Notes |
961 ;----------------------------------------------------------------
962 ;|RRCA |--0-0*|Rotate Right Circular|A=->A |
963 ;|----------|SZHP C|---------- 8080 ----------------------------|
964 ;|RRCA |---- *|Rotate Right Circular|A=->A |
968 ;Rotate Right Cyclical. All bits move 1 to the
969 ;right, the lsb becomes c and msb.
970 do_z80_flags_op_rotate
975 ori z_flags, (1<<ZFL_C)
979 ;----------------------------------------------------------------
980 ;|Mnemonic |SZHPNC|Description |Notes |
981 ;----------------------------------------------------------------
982 ;|RRA |--0-0*|Rotate Right Acc. |A=->{CY,A} |
983 ;|----------|SZHP C|---------- 8080 ----------------------------|
984 ;|RRA |---- *|Rotate Right Acc. |A=->{CY,A} |
988 ;Rotate Right. All bits move 1 to the right, the lsb
989 ;becomes c, c becomes msb.
990 clc ; get z80 carry to avr carry
993 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
994 bmov z_flags,ZFL_C, z_a,0 ; Bit 0 --> CY
998 ;----------------------------------------------------------------
999 ;|Mnemonic |SZHPNC|Description |Notes |
1000 ;----------------------------------------------------------------
1001 ;|RLA |--0-0*|Rotate Left Acc. |A={CY,A}<- |
1002 ;|----------|SZHP C|---------- 8080 ----------------------------|
1003 ;|RLA |---- *|Rotate Left Acc. |A={CY,A}<- |
1007 ;Rotate Left. All bits move 1 to the left, the msb
1008 ;becomes c, c becomes lsb.
1012 do_z80_flags_op_rotate ; (clear ZFL_C, doesn't change AVR_C)
1013 bmov z_flags,ZFL_C, z_a,7 ; Bit 7 --> CY
1017 ;----------------------------------------------------------------
1018 ;|Mnemonic |SZHPNC|Description |Notes |
1019 ;----------------------------------------------------------------
1020 ;|ADD A,s |***V0*|Add |A=A+s |
1021 ;|----------|SZHP C|---------- 8080 ----------------------------|
1022 ;|ADD A,s |***P *|Add |A=A+s |
1028 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P flag
1029 bmov z_flags,ZFL_C, temp,AVR_C
1030 bmov z_flags,ZFL_H, temp,AVR_H
1034 ;----------------------------------------------------------------
1035 ;|Mnemonic |SZHPNC|Description |Notes |
1036 ;----------------------------------------------------------------
1037 ;|ADC A,s |***V0*|Add with Carry |A=A+s+CY |
1038 ;|----------|SZHP C|---------- 8080 ----------------------------|
1039 ;|ADC A,s |***P *|Add with Carry |A=A+s+CY |
1048 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1049 bmov z_flags,ZFL_C, temp,AVR_C
1050 bmov z_flags,ZFL_H, temp,AVR_H
1054 ;----------------------------------------------------------------
1055 ;|Mnemonic |SZHPNC|Description |Notes |
1056 ;----------------------------------------------------------------
1057 ;|SUB s |***V1*|Subtract |A=A-s |
1058 ;|----------|SZHP C|---------- 8080 ----------------------------|
1059 ;|SUB s |***P *|Subtract |A=A-s |
1065 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1066 bmov z_flags,ZFL_C, temp,AVR_C
1067 bmov z_flags,ZFL_H, temp,AVR_H
1072 ;----------------------------------------------------------------
1073 ;|Mnemonic |SZHPNC|Description |Notes |
1074 ;----------------------------------------------------------------
1075 ;|CP s |***V1*|Compare |A-s |
1076 ;|----------|SZHP C|---------- 8080 ----------------------------|
1077 ;|CP s |***P *|Compare |A-s |
1084 ldpmx z_flags,sz53p_tab,temp2 ;S,Z,P
1085 bmov z_flags,ZFL_C, temp,AVR_C
1086 bmov z_flags,ZFL_H, temp,AVR_H
1091 ;----------------------------------------------------------------
1092 ;|Mnemonic |SZHPNC|Description |Notes |
1093 ;----------------------------------------------------------------
1094 ;|SBC A,s |***V1*|Subtract with Carry |A=A-s-CY |
1095 ;|----------|SZHP C|---------- 8080 ----------------------------|
1096 ;|SBC A,s |***P *|Subtract with Carry |A=A-s-CY |
1105 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P
1106 bmov z_flags,ZFL_C, temp,AVR_C
1107 bmov z_flags,ZFL_H, temp,AVR_H
1112 ;----------------------------------------------------------------
1113 ;|Mnemonic |SZHPNC|Description |Notes |
1114 ;----------------------------------------------------------------
1115 ;|AND s |**1P00|Logical AND |A=A&s |
1116 ;|----------|SZHP C|---------- 8080 ----------------------------|
1117 ;|AND s |**-P 0|Logical AND |A=A&s |
1122 ldpmx z_flags,sz53p_tab,z_a ;S,Z,P,N,C
1127 ;----------------------------------------------------------------
1128 ;|Mnemonic |SZHPNC|Description |Notes |
1129 ;----------------------------------------------------------------
1130 ;|OR s |**0P00|Logical inclusive OR |A=Avs |
1131 ;|----------|SZHP C|---------- 8080 ----------------------------|
1132 ;|OR s |**-P00|Logical inclusive OR |A=Avs |
1137 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1141 ;----------------------------------------------------------------
1142 ;|Mnemonic |SZHPNC|Description |Notes |
1143 ;----------------------------------------------------------------
1144 ;|XOR s |**0P00|Logical Exclusive OR |A=Axs |
1145 ;|----------|SZHP C|---------- 8080 ----------------------------|
1146 ;|XOR s |**-P 0|Logical Exclusive OR |A=Axs |
1151 ldpmx z_flags,sz53p_tab,z_a ;S,Z,H,P,N,C
1155 ;----------------------------------------------------------------
1156 ;|Mnemonic |SZHPNC|Description |Notes |
1157 ;----------------------------------------------------------------
1158 ;|ADD HL,ss |--?-0*|Add |HL=HL+ss |
1159 ;|----------|SZHP C|---------- 8080 ----------------------------|
1160 ;|ADD HL,ss |---- *|Add |HL=HL+ss |
1171 bmov z_flags,ZFL_C, temp,AVR_C
1173 do_z80_flags_clear_N
1176 ;----------------------------------------------------------------
1177 ;|Mnemonic |SZHPNC|Description |Notes |
1178 ;----------------------------------------------------------------
1179 ;|LD dst,src|------|Load |dst=src |
1182 do_op_sthl: ;store hl to mem loc in opl:h
1191 ;----------------------------------------------------------------
1192 ;|Mnemonic |SZHPNC|Description |Notes |
1193 ;----------------------------------------------------------------
1194 ;|LD dst,src|------|Load |dst=src |
1204 ;----------------------------------------------------------------
1205 ;|Mnemonic |SZHPNC|Description |Notes |
1206 ;----------------------------------------------------------------
1207 ;|LD dst,src|------|Load |dst=src |
1214 ;----------------------------------------------------------------
1215 ;|Mnemonic |SZHPNC|Description |Notes |
1216 ;----------------------------------------------------------------
1217 ;|DAA |***P-*|Decimal Adjust Acc. | |
1218 ;|----------|SZHP C|---------- 8080 ----------------------------|
1222 ; Description (http://www.z80.info/z80syntx.htm#DAA):
1223 ; This instruction conditionally adjusts the accumulator for BCD addition
1224 ; and subtraction operations. For addition (ADD, ADC, INC) or subtraction
1225 ; (SUB, SBC, DEC, NEC), the following table indicates the operation performed:
1227 ; -------------------------------------------------------------------
1228 ; | |C Flag |HEX value in|H Flag |HEX val in | Number |C flag |
1229 ; | Oper |Before |upper digit |Before |lower digit| added |After |
1230 ; | |DAA |(bit 7-4) |DAA |(bit 3-0) | to A |DAA |
1231 ; |-------+-------+------------+-------+-----------+--------+-------|
1232 ; | | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1233 ; | ADD | 0 | 0-8 | 0 | A-F | 06 | 0 |
1234 ; | | 0 | 0-9 | 1 | 0-3 | 06 | 0 |
1235 ; | ADC | 0 | A-F | 0 | 0-9 | 60 | 1 |
1236 ; | | 0 | 9-F | 0 | A-F | 66 | 1 |
1237 ; | INC | 0 | A-F | 1 | 0-3 | 66 | 1 |
1238 ; | | 1 | 0-2 | 0 | 0-9 | 60 | 1 |
1239 ; | | 1 | 0-2 | 0 | A-F | 66 | 1 |
1240 ; | | 1 | 0-3 | 1 | 0-3 | 66 | 1 |
1241 ; |-------+-------+------------+-------+-----------+--------+-------|
1242 ; | SUB | 0 | 0-9 | 0 | 0-9 | 00 | 0 |
1243 ; | SBC | 0 | 0-8 | 1 | 6-F | FA | 0 |
1244 ; | DEC | 1 | 7-F | 0 | 0-9 | A0 | 1 |
1245 ; | NEG | 1 | 6-F | 1 | 6-F | 9A | 1 |
1246 ; -------------------------------------------------------------------
1248 ; The H flag is affected as follows:
1250 ; ---------------------
1251 ; | N | H | low |H' |
1253 ; |---+---+-------+---|
1254 ; | 0 | * | 0-9 | 0 |
1255 ; | 0 | * | a-f | 1 |
1257 ; | 1 | 1 | 6-f | 0 |
1258 ; | 1 | 1 | 0-5 | 1 |
1259 ; ---------------------
1263 ; P/V: Set if Acc. is even parity after operation, reset otherwise.
1264 ; Z: Set if Acc. is Zero after operation, reset otherwise.
1265 ; S: Set if most significant bit of Acc. is 1 after operation, reset otherwise.
1272 sbrc z_flags,ZFL_N ;if add-op
1273 rjmp op_da_sub ;then
1277 ldi temp2,0 ; new C and H flag
1278 sbrc z_flags,ZFL_H ; |
1279 rjmp op_da_a01 ; if (H flag ...
1282 cpi temp,0x0a ; or (lower nibble >= 0x0A))
1285 ldi oph,0x06 ; add 6 to lower nibble
1288 ori temp2,(1<<ZFL_H) ; set new H flag
1291 ori temp2,(1<<ZFL_C) ; set new H flag
1293 sbrc z_flags,ZFL_C ; |
1294 rjmp op_da_a12 ; if (C flag ...
1295 cpi opl,0xA0 ; |... or upper nibble >= 0xA0)
1298 ldi oph,0x60 ; add 6 to lower nibble
1300 ori temp2,(1<<ZFL_C) ; set new C flag
1302 ldpmx z_flags, sz53p_tab, opl ; get S,Z,P flag
1303 or z_flags,temp2 ; merge new C and H flag
1308 op_da_sub: ;else (sub-op)
1309 rcall do_op_inv ; TODO: !
1316 ldi temp2,0 ;new C and H flag
1317 ldi oph,0 ;oph: what to add
1319 sbrc z_flags,ZFL_N ;if add-op
1320 rjmp op_da_sub ;then
1324 cpi temp,0x0a ; if (lower nibble >= 0x0A)
1326 ori oph,0x06 ; add 6
1327 ori temp2,(1<<ZFL_H) ; set new H flag
1329 sbrc z_flags,ZFL_C ; |
1330 rjmp op_da_a02 ; if (C flag ...
1331 cpi opl,0x90 ; |... or upper nibble >= 0x90)
1334 ori oph,0x60 ; add 0x60
1335 ori temp2,(1<<ZFL_C) ; set new C flag
1338 op_da_a10: ; else (lower nibble is 0x09 or lower)
1339 sbrc z_flags,ZFL_C ; |
1340 rjmp op_da_a12 ; if (C flag ...
1341 cpi opl,0xA0 ; |... or upper nibble >= 0xA0)
1344 ori oph,0x60 ; add 0x60
1345 ori temp2,(1<<ZFL_C) ; set new C flag
1347 sbrs z_flags,ZFL_H ; if (H flag)
1349 ori oph,0x06 ; add 0x06
1352 cpi temp,0x06 ; if (lower nibble >= 0x0A)
1354 ori temp2,(1<<ZFL_H) ; set new H flag
1359 ldpmx z_flags, sz53p_tab, opl ; get S,Z,P flag
1360 or z_flags,temp2 ; merge new C and H flag
1363 op_da_sub: ;else (sub-op)
1364 rcall do_op_inv ; TODO: !
1369 ;----------------------------------------------------------------
1370 ;|Mnemonic |SZHPNC|Description |Notes |
1371 ;----------------------------------------------------------------
1372 ;|SCF |--0-01|Set Carry Flag |CY=1 |
1373 ;|----------|SZHP C|---------- 8080 ----------------------------|
1377 do_z80_flags_clear_HN
1378 ori z_flags,(1<<ZFL_C)
1381 ;----------------------------------------------------------------
1382 ;|Mnemonic |SZHPNC|Description |Notes |
1383 ;----------------------------------------------------------------
1384 ;|CCF |--?-0*|Complement Carry Flag|CY=~CY, HC=previous CY|
1385 ;|----------|SZHP C|---------- 8080 ----------------------------|
1386 ;|CCF |---- 1|Set Carry Flag |CY=1 |
1389 do_z80_flags_clear_N
1390 do_z80_flags_copy_HC
1395 ;----------------------------------------------------------------
1396 ;|Mnemonic |SZHPNC|Description |Notes |
1397 ;----------------------------------------------------------------
1398 ;|CPL |--1-1-|Complement |A=~A |
1399 ;|----------|SZHP C|---------- 8080 ----------------------------|
1400 ;|CPL |---- -|Complement |A=~A |
1409 ;----------------------------------------------------------------
1410 ;|Mnemonic |SZHPNC|Description |Notes |
1411 ;----------------------------------------------------------------
1412 ;|PUSH xx |------|Push |-[SP]=xx |
1413 ;|PUSH qq |------|Push |-[SP]=qq |
1426 printstring "Stack push "
1429 printstring ", SP is now "
1437 ;----------------------------------------------------------------
1438 ;|Mnemonic |SZHPNC|Description |Notes |
1439 ;----------------------------------------------------------------
1440 ;|POP xx |------|Pop |xx=[SP]+ |
1441 ;|POP qq |------|Pop |qq=[SP]+ |
1454 printstring "Stack pop "
1457 printstring ", SP is now "
1464 ;----------------------------------------------------------------
1465 ;|Mnemonic |SZHPNC|Description |Notes |
1466 ;----------------------------------------------------------------
1467 ;|EX [SP],HL|------|Exchange |[SP]<->HL |
1468 ;|EX DE,HL |------|Exchange |DE<->HL |
1469 ;-----------------------------Z80--------------------------------
1479 ;----------------------------------------------------------------
1480 ;|Mnemonic |SZHPNC|Description |Notes |
1481 ;----------------------------------------------------------------
1483 ; TODO: Implement IFF1, IFF2
1487 ;----------------------------------------------------------------
1488 ;|Mnemonic |SZHPNC|Description |Notes |
1489 ;----------------------------------------------------------------
1491 ; TODO: Implement IFF1, IFF2
1495 ;----------------------------------------------------------------
1496 ;|Mnemonic |SZHPNC|Description |Notes |
1497 ;----------------------------------------------------------------
1498 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1499 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1500 ;|RET cc |------|Conditional Return |If cc RET |
1508 ;----------------------------------------------------------------
1509 ;|Mnemonic |SZHPNC|Description |Notes |
1510 ;----------------------------------------------------------------
1511 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1512 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1513 ;|RET cc |------|Conditional Return |If cc RET |
1521 ;----------------------------------------------------------------
1522 ;|Mnemonic |SZHPNC|Description |Notes |
1523 ;----------------------------------------------------------------
1524 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1525 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1526 ;|RET cc |------|Conditional Return |If cc RET |
1534 ;----------------------------------------------------------------
1535 ;|Mnemonic |SZHPNC|Description |Notes |
1536 ;----------------------------------------------------------------
1537 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1538 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1539 ;|RET cc |------|Conditional Return |If cc RET |
1547 ;----------------------------------------------------------------
1548 ;|Mnemonic |SZHPNC|Description |Notes |
1549 ;----------------------------------------------------------------
1550 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1551 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1552 ;|RET cc |------|Conditional Return |If cc RET |
1560 ;----------------------------------------------------------------
1561 ;|Mnemonic |SZHPNC|Description |Notes |
1562 ;----------------------------------------------------------------
1563 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1564 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1565 ;|RET cc |------|Conditional Return |If cc RET |
1573 ;----------------------------------------------------------------
1574 ;|Mnemonic |SZHPNC|Description |Notes |
1575 ;----------------------------------------------------------------
1576 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1577 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1578 ;|RET cc |------|Conditional Return |If cc RET |
1581 do_op_ifp: ;sign positive, aka s=0
1586 ;----------------------------------------------------------------
1587 ;|Mnemonic |SZHPNC|Description |Notes |
1588 ;----------------------------------------------------------------
1589 ;|CALL cc,nn|------|Conditional Call |If cc CALL |
1590 ;|JP cc,nn |------|Conditional Jump |If cc JP |
1591 ;|RET cc |------|Conditional Return |If cc RET |
1594 do_op_ifm: ;sign negative, aka s=1
1600 ; ----------------------- Opcode decoding -------------------------
1602 ; Lookup table for Z80 opcodes. Translates the first byte of the instruction word into three
1603 ; operations: fetch, do something, store.
1604 ; The table is made of 256 words.
1606 ;.org (PC+255) & 0xff00
1608 instr do_fetch_nop, op_nop, do_store_nop ;00 ;NOP
1609 instr do_fetch_DIR16, op_nop, do_store_BC ;01 nn nn ;LD BC,nn
1610 instr do_fetch_nop, op_nop, do_store_MBC ;02 ;LD (BC),A
1611 instr do_fetch_BC, op_INC16, do_store_BC ;03 ;INC BC
1612 instr do_fetch_B, op_INC, do_store_B ;04 ;INC B
1613 instr do_fetch_B, op_DEC, do_store_B ;05 ;DEC B
1614 instr do_fetch_DIR8, op_nop, do_store_B ;06 ;LD B,n
1615 instr do_fetch_nop, op_RLCA, do_store_nop ;07 ;RLCA
1616 instr do_fetch_nop, op_INV, do_store_nop ;08 ;EX AF,AF'
1617 instr do_fetch_BC, op_ADDHL, do_store_nop ;09 ;ADD HL,BC
1618 instr do_fetch_MBC, op_nop, do_store_nop ;0A ;LD A,(BC)
1619 instr do_fetch_BC, op_DEC16, do_store_BC ;0B ;DEC BC
1620 instr do_fetch_C, op_INC, do_store_C ;0C ;INC C
1621 instr do_fetch_C, op_DEC, do_store_C ;0D ;DEC C
1622 instr do_fetch_DIR8, op_nop, do_store_C ;0E nn ;LD C,n
1623 instr do_fetch_nop, op_RRCA, do_store_nop ;0F ;RRCA
1624 instr do_fetch_nop, op_INV, do_store_nop ;10 oo ;DJNZ o
1625 instr do_fetch_DIR16, op_nop, do_store_DE ;11 nn nn ;LD DE,nn
1626 instr do_fetch_nop, op_nop, do_store_MDE ;12 ;LD (DE),A
1627 instr do_fetch_DE, op_INC16, do_store_DE ;13 ;INC DE
1628 instr do_fetch_D, op_INC, do_store_D ;14 ;INC D
1629 instr do_fetch_D, op_DEC, do_store_D ;15 ;DEC D
1630 instr do_fetch_DIR8, op_nop, do_store_D ;16 nn ;LD D,n
1631 instr do_fetch_nop, op_RLA, do_store_nop ;17 ;RLA
1632 instr do_fetch_nop, op_INV, do_store_nop ;18 oo ;JR o
1633 instr do_fetch_DE, op_ADDHL, do_store_nop ;19 ;ADD HL,DE
1634 instr do_fetch_MDE, op_nop, do_store_nop ;1A ;LD A,(DE)
1635 instr do_fetch_DE, op_DEC16, do_store_DE ;1B ;DEC DE
1636 instr do_fetch_E, op_INC, do_store_E ;1C ;INC E
1637 instr do_fetch_E, op_DEC, do_store_E ;1D ;DEC E
1638 instr do_fetch_DIR8, op_nop, do_store_E ;1E nn ;LD E,n
1639 instr do_fetch_nop, op_RRA, do_store_nop ;1F ;RRA
1640 instr do_fetch_nop, op_INV, do_store_nop ;20 oo ;JR NZ,o
1641 instr do_fetch_DIR16, op_nop, do_store_HL ;21 nn nn ;LD HL,nn
1642 instr do_fetch_DIR16, op_STHL, do_store_nop ;22 nn nn ;LD (nn),HL
1643 instr do_fetch_HL, op_INC16, do_store_HL ;23 ;INC HL
1644 instr do_fetch_H, op_INC, do_store_H ;24 ;INC H
1645 instr do_fetch_H, op_DEC, do_store_H ;25 ;DEC H
1646 instr do_fetch_DIR8, op_nop, do_store_H ;26 nn ;LD H,n
1647 instr do_fetch_A, op_DA, do_store_A ;27 ;DAA
1648 instr do_fetch_nop, op_INV, do_store_nop ;28 oo ;JR Z,o
1649 instr do_fetch_HL, op_ADDHL, do_store_nop ;29 ;ADD HL,HL
1650 instr do_fetch_DIR16, op_RMEM16, do_store_HL ;2A nn nn ;LD HL,(nn)
1651 instr do_fetch_HL, op_DEC16, do_store_HL ;2B ;DEC HL
1652 instr do_fetch_L, op_INC, do_store_L ;2C ;INC L
1653 instr do_fetch_L, op_DEC, do_store_L ;2D ;DEC L
1654 instr do_fetch_DIR8, op_nop, do_store_L ;2E nn ;LD L,n
1655 instr do_fetch_nop, op_CPL, do_store_nop ;2F ;CPL
1656 instr do_fetch_nop, op_INV, do_store_nop ;30 oo ;JR NC,o
1657 instr do_fetch_DIR16, op_nop, do_store_SP ;31 nn nn ;LD SP,nn
1658 instr do_fetch_DIR16, op_nop, do_store_AM ;32 nn nn ;LD (nn),A
1659 instr do_fetch_SP, op_INC16, do_store_SP ;33 ;INC SP
1660 instr do_fetch_MHL, op_INC, do_store_MHL ;34 ;INC (HL)
1661 instr do_fetch_MHL, op_DEC, do_store_MHL ;35 ;DEC (HL)
1662 instr do_fetch_DIR8, op_nop, do_store_MHL ;36 nn ;LD (HL),n
1663 instr do_fetch_nop, op_SCF, do_store_nop ;37 ;SCF
1664 instr do_fetch_nop, op_INV, do_store_nop ;38 oo ;JR C,o
1665 instr do_fetch_SP, op_ADDHL, do_store_nop ;39 ;ADD HL,SP
1666 instr do_fetch_DIR16, op_RMEM8, do_store_A ;3A nn nn ;LD A,(nn)
1667 instr do_fetch_SP, op_DEC16, do_store_SP ;3B ;DEC SP
1668 instr do_fetch_nop, op_INCA, do_store_nop ;3C ;INC A
1669 instr do_fetch_nop, op_DECA, do_store_nop ;3D ;DEC A
1670 instr do_fetch_DIR8, op_nop, do_store_A ;3E nn ;LD A,n
1671 instr do_fetch_nop, op_CCF, do_store_nop ;3F ;CCF (Complement Carry Flag, gvd)
1672 instr do_fetch_nop, op_nop, do_store_nop ;40 ;LD B,B
1673 instr do_fetch_C, op_nop, do_store_B ;41 ;LD B,C
1674 instr do_fetch_D, op_nop, do_store_B ;42 ;LD B,D
1675 instr do_fetch_E, op_nop, do_store_B ;43 ;LD B,E
1676 instr do_fetch_H, op_nop, do_store_B ;44 ;LD B,H
1677 instr do_fetch_L, op_nop, do_store_B ;45 ;LD B,L
1678 instr do_fetch_MHL, op_nop, do_store_B ;46 ;LD B,(HL)
1679 instr do_fetch_A, op_nop, do_store_B ;47 ;LD B,A
1680 instr do_fetch_B, op_nop, do_store_C ;48 ;LD C,B
1681 instr do_fetch_nop, op_nop, do_store_nop ;49 ;LD C,C
1682 instr do_fetch_D, op_nop, do_store_C ;4A ;LD C,D
1683 instr do_fetch_E, op_nop, do_store_C ;4B ;LD C,E
1684 instr do_fetch_H, op_nop, do_store_C ;4C ;LD C,H
1685 instr do_fetch_L, op_nop, do_store_C ;4D ;LD C,L
1686 instr do_fetch_MHL, op_nop, do_store_C ;4E ;LD C,(HL)
1687 instr do_fetch_A, op_nop, do_store_C ;4F ;LD C,A
1688 instr do_fetch_B, op_nop, do_store_D ;50 ;LD D,B
1689 instr do_fetch_C, op_nop, do_store_D ;51 ;LD D,C
1690 instr do_fetch_nop, op_nop, do_store_nop ;52 ;LD D,D
1691 instr do_fetch_E, op_nop, do_store_D ;53 ;LD D,E
1692 instr do_fetch_H, op_nop, do_store_D ;54 ;LD D,H
1693 instr do_fetch_L, op_nop, do_store_D ;55 ;LD D,L
1694 instr do_fetch_MHL, op_nop, do_store_D ;56 ;LD D,(HL)
1695 instr do_fetch_A, op_nop, do_store_D ;57 ;LD D,A
1696 instr do_fetch_B, op_nop, do_store_E ;58 ;LD E,B
1697 instr do_fetch_C, op_nop, do_store_E ;59 ;LD E,C
1698 instr do_fetch_D, op_nop, do_store_E ;5A ;LD E,D
1699 instr do_fetch_nop, op_nop, do_store_nop ;5B ;LD E,E
1700 instr do_fetch_H, op_nop, do_store_E ;5C ;LD E,H
1701 instr do_fetch_L, op_nop, do_store_E ;5D ;LD E,L
1702 instr do_fetch_MHL, op_nop, do_store_E ;5E ;LD E,(HL)
1703 instr do_fetch_A, op_nop, do_store_E ;5F ;LD E,A
1704 instr do_fetch_B, op_nop, do_store_H ;60 ;LD H,B
1705 instr do_fetch_C, op_nop, do_store_H ;61 ;LD H,C
1706 instr do_fetch_D, op_nop, do_store_H ;62 ;LD H,D
1707 instr do_fetch_E, op_nop, do_store_H ;63 ;LD H,E
1708 instr do_fetch_nop, op_nop, do_store_nop ;64 ;LD H,H
1709 instr do_fetch_L, op_nop, do_store_H ;65 ;LD H,L
1710 instr do_fetch_MHL, op_nop, do_store_H ;66 ;LD H,(HL)
1711 instr do_fetch_A, op_nop, do_store_H ;67 ;LD H,A
1712 instr do_fetch_B, op_nop, do_store_L ;68 ;LD L,B
1713 instr do_fetch_C, op_nop, do_store_L ;69 ;LD L,C
1714 instr do_fetch_D, op_nop, do_store_L ;6A ;LD L,D
1715 instr do_fetch_E, op_nop, do_store_L ;6B ;LD L,E
1716 instr do_fetch_H, op_nop, do_store_L ;6C ;LD L,H
1717 instr do_fetch_nop, op_nop, do_store_nop ;6D ;LD L,L
1718 instr do_fetch_MHL, op_nop, do_store_L ;6E ;LD L,(HL)
1719 instr do_fetch_A, op_nop, do_store_L ;6F ;LD L,A
1720 instr do_fetch_B, op_nop, do_store_MHL ;70 ;LD (HL),B
1721 instr do_fetch_C, op_nop, do_store_MHL ;71 ;LD (HL),C
1722 instr do_fetch_D, op_nop, do_store_MHL ;72 ;LD (HL),D
1723 instr do_fetch_E, op_nop, do_store_MHL ;73 ;LD (HL),E
1724 instr do_fetch_H, op_nop, do_store_MHL ;74 ;LD (HL),H
1725 instr do_fetch_L, op_nop, do_store_MHL ;75 ;LD (HL),L
1726 instr do_fetch_nop, op_INV, do_store_nop ;76 ;HALT
1727 instr do_fetch_A, op_nop, do_store_MHL ;77 ;LD (HL),A
1728 instr do_fetch_B, op_nop, do_store_A ;78 ;LD A,B
1729 instr do_fetch_C, op_nop, do_store_A ;79 ;LD A,C
1730 instr do_fetch_D, op_nop, do_store_A ;7A ;LD A,D
1731 instr do_fetch_E, op_nop, do_store_A ;7B ;LD A,E
1732 instr do_fetch_H, op_nop, do_store_A ;7C ;LD A,H
1733 instr do_fetch_L, op_nop, do_store_A ;7D ;LD A,L
1734 instr do_fetch_MHL, op_nop, do_store_A ;7E ;LD A,(HL)
1735 instr do_fetch_nop, op_nop, do_store_nop ;7F ;LD A,A
1736 instr do_fetch_B, op_ADDA, do_store_nop ;80 ;ADD A,B
1737 instr do_fetch_C, op_ADDA, do_store_nop ;81 ;ADD A,C
1738 instr do_fetch_D, op_ADDA, do_store_nop ;82 ;ADD A,D
1739 instr do_fetch_E, op_ADDA, do_store_nop ;83 ;ADD A,E
1740 instr do_fetch_H, op_ADDA, do_store_nop ;84 ;ADD A,H
1741 instr do_fetch_L, op_ADDA, do_store_nop ;85 ;ADD A,L
1742 instr do_fetch_MHL, op_ADDA, do_store_nop ;86 ;ADD A,(HL)
1743 instr do_fetch_A, op_ADDA, do_store_nop ;87 ;ADD A,A
1744 instr do_fetch_B, op_ADCA, do_store_nop ;88 ;ADC A,B
1745 instr do_fetch_C, op_ADCA, do_store_nop ;89 ;ADC A,C
1746 instr do_fetch_D, op_ADCA, do_store_nop ;8A ;ADC A,D
1747 instr do_fetch_E, op_ADCA, do_store_nop ;8B ;ADC A,E
1748 instr do_fetch_H, op_ADCA, do_store_nop ;8C ;ADC A,H
1749 instr do_fetch_L, op_ADCA, do_store_nop ;8D ;ADC A,L
1750 instr do_fetch_MHL, op_ADCA, do_store_nop ;8E ;ADC A,(HL)
1751 instr do_fetch_A, op_ADCA, do_store_nop ;8F ;ADC A,A
1752 instr do_fetch_B, op_SUBFA, do_store_nop ;90 ;SUB A,B
1753 instr do_fetch_C, op_SUBFA, do_store_nop ;91 ;SUB A,C
1754 instr do_fetch_D, op_SUBFA, do_store_nop ;92 ;SUB A,D
1755 instr do_fetch_E, op_SUBFA, do_store_nop ;93 ;SUB A,E
1756 instr do_fetch_H, op_SUBFA, do_store_nop ;94 ;SUB A,H
1757 instr do_fetch_L, op_SUBFA, do_store_nop ;95 ;SUB A,L
1758 instr do_fetch_MHL, op_SUBFA, do_store_nop ;96 ;SUB A,(HL)
1759 instr do_fetch_A, op_SUBFA, do_store_nop ;97 ;SUB A,A
1760 instr do_fetch_B, op_SBCFA, do_store_nop ;98 ;SBC A,B
1761 instr do_fetch_C, op_SBCFA, do_store_nop ;99 ;SBC A,C
1762 instr do_fetch_D, op_SBCFA, do_store_nop ;9A ;SBC A,D
1763 instr do_fetch_E, op_SBCFA, do_store_nop ;9B ;SBC A,E
1764 instr do_fetch_H, op_SBCFA, do_store_nop ;9C ;SBC A,H
1765 instr do_fetch_L, op_SBCFA, do_store_nop ;9D ;SBC A,L
1766 instr do_fetch_MHL, op_SBCFA, do_store_nop ;9E ;SBC A,(HL)
1767 instr do_fetch_A, op_SBCFA, do_store_nop ;9F ;SBC A,A
1768 instr do_fetch_B, op_ANDA, do_store_nop ;A0 ;AND A,B
1769 instr do_fetch_C, op_ANDA, do_store_nop ;A1 ;AND A,C
1770 instr do_fetch_D, op_ANDA, do_store_nop ;A2 ;AND A,D
1771 instr do_fetch_E, op_ANDA, do_store_nop ;A3 ;AND A,E
1772 instr do_fetch_H, op_ANDA, do_store_nop ;A4 ;AND A,H
1773 instr do_fetch_L, op_ANDA, do_store_nop ;A5 ;AND A,L
1774 instr do_fetch_MHL, op_ANDA, do_store_nop ;A6 ;AND A,(HL)
1775 instr do_fetch_A, op_ANDA, do_store_nop ;A7 ;AND A,A
1776 instr do_fetch_B, op_XORA, do_store_nop ;A8 ;XOR A,B
1777 instr do_fetch_C, op_XORA, do_store_nop ;A9 ;XOR A,C
1778 instr do_fetch_D, op_XORA, do_store_nop ;AA ;XOR A,D
1779 instr do_fetch_E, op_XORA, do_store_nop ;AB ;XOR A,E
1780 instr do_fetch_H, op_XORA, do_store_nop ;AC ;XOR A,H
1781 instr do_fetch_L, op_XORA, do_store_nop ;AD ;XOR A,L
1782 instr do_fetch_MHL, op_XORA, do_store_nop ;AE ;XOR A,(HL)
1783 instr do_fetch_A, op_XORA, do_store_nop ;AF ;XOR A,A
1784 instr do_fetch_B, op_ORA, do_store_nop ;B0 ;OR A,B
1785 instr do_fetch_C, op_ORA, do_store_nop ;B1 ;OR A,C
1786 instr do_fetch_D, op_ORA, do_store_nop ;B2 ;OR A,D
1787 instr do_fetch_E, op_ORA, do_store_nop ;B3 ;OR A,E
1788 instr do_fetch_H, op_ORA, do_store_nop ;B4 ;OR A,H
1789 instr do_fetch_L, op_ORA, do_store_nop ;B5 ;OR A,L
1790 instr do_fetch_MHL, op_ORA, do_store_nop ;B6 ;OR A,(HL)
1791 instr do_fetch_A, op_ORA, do_store_nop ;B7 ;OR A,A
1792 instr do_fetch_B, op_CPFA, do_store_nop ;B8 ;CP A,B
1793 instr do_fetch_C, op_CPFA, do_store_nop ;B9 ;CP A,C
1794 instr do_fetch_D, op_CPFA, do_store_nop ;BA ;CP A,D
1795 instr do_fetch_E, op_CPFA, do_store_nop ;BB ;CP A,E
1796 instr do_fetch_H, op_CPFA, do_store_nop ;BC ;CP A,H
1797 instr do_fetch_L, op_CPFA, do_store_nop ;BD ;CP A,L
1798 instr do_fetch_MHL, op_CPFA, do_store_nop ;BE ;CP A,(HL)
1799 instr do_fetch_A, op_CPFA, do_store_nop ;BF ;CP A,A
1800 instr do_fetch_nop, op_IFNZ, do_store_RET ;C0 ;RET NZ
1801 instr do_fetch_nop, op_POP16, do_store_BC ;C1 ;POP BC
1802 instr do_fetch_DIR16, op_IFNZ, do_store_PC ;C2 nn nn ;JP NZ,nn
1803 instr do_fetch_DIR16, op_nop, do_store_PC ;C3 nn nn ;JP nn
1804 instr do_fetch_DIR16, op_IFNZ, do_store_CALL ;C4 nn nn ;CALL NZ,nn
1805 instr do_fetch_BC, op_PUSH16, do_store_nop ;C5 ;PUSH BC
1806 instr do_fetch_DIR8, op_ADDA, do_store_nop ;C6 nn ;ADD A,n
1807 instr do_fetch_RST, op_nop, do_store_CALL ;C7 ;RST 0
1808 instr do_fetch_nop, op_IFZ, do_store_RET ;C8 ;RET Z
1809 instr do_fetch_nop, op_nop, do_store_RET ;C9 ;RET
1810 instr do_fetch_DIR16, op_IFZ, do_store_PC ;CA nn nn ;JP Z,nn
1811 instr do_fetch_nop, op_INV, do_store_nop ;CB ;(Z80 specific)
1812 instr do_fetch_DIR16, op_IFZ, do_store_CALL ;CC nn nn ;CALL Z,nn
1813 instr do_fetch_DIR16, op_nop, do_store_CALL ;CD nn nn ;CALL nn
1814 instr do_fetch_DIR8, op_ADCA, do_store_nop ;CE nn ;ADC A,n
1815 instr do_fetch_RST, op_nop, do_store_CALL ;CF ;RST 8H
1816 instr do_fetch_nop, op_IFNC, do_store_RET ;D0 ;RET NC
1817 instr do_fetch_nop, op_POP16, do_store_DE ;D1 ;POP DE
1818 instr do_fetch_DIR16, op_IFNC, do_store_PC ;D2 nn nn ;JP NC,nn
1819 instr do_fetch_DIR8, op_OUTA, do_store_nop ;D3 nn ;OUT (n),A
1820 instr do_fetch_DIR16, op_IFNC, do_store_CALL ;D4 nn nn ;CALL NC,nn
1821 instr do_fetch_DE, op_PUSH16, do_store_nop ;D5 ;PUSH DE
1822 instr do_fetch_DIR8, op_SUBFA, do_store_nop ;D6 nn ;SUB n
1823 instr do_fetch_RST, op_nop, do_store_CALL ;D7 ;RST 10H
1824 instr do_fetch_nop, op_IFC, do_store_RET ;D8 ;RET C
1825 instr do_fetch_nop, op_nop, do_store_nop ;D9 ;EXX
1826 instr do_fetch_DIR16, op_IFC, do_store_PC ;DA nn nn ;JP C,nn
1827 instr do_fetch_DIR8, op_INA, do_store_nop ;DB nn ;IN A,(n)
1828 instr do_fetch_DIR16, op_IFC, do_store_CALL ;DC nn nn ;CALL C,nn
1829 instr do_fetch_nop, op_INV, do_store_nop ;DD ;(Z80 specific)
1830 instr do_fetch_DIR8, op_SBCFA, do_store_nop ;DE nn ;SBC A,n
1831 instr do_fetch_RST, op_nop, do_store_CALL ;DF ;RST 18H
1832 instr do_fetch_nop, op_IFPO, do_store_RET ;E0 ;RET PO
1833 instr do_fetch_nop, op_POP16, do_store_HL ;E1 ;POP HL
1834 instr do_fetch_DIR16, op_IFPO, do_store_PC ;E2 nn nn ;JP PO,nn
1835 instr do_fetch_MSP, op_EXHL, do_store_MSP ;E3 ;EX (SP),HL
1836 instr do_fetch_DIR16, op_IFPO, do_store_CALL ;E4 nn nn ;CALL PO,nn
1837 instr do_fetch_HL, op_PUSH16, do_store_nop ;E5 ;PUSH HL
1838 instr do_fetch_DIR8, op_ANDA, do_store_nop ;E6 nn ;AND n
1839 instr do_fetch_RST, op_nop, do_store_CALL ;E7 ;RST 20H
1840 instr do_fetch_nop, op_IFPE, do_store_RET ;E8 ;RET PE
1841 instr do_fetch_HL, op_nop, do_store_PC ;E9 ;JP HL
1842 instr do_fetch_DIR16, op_IFPE, do_store_PC ;EA nn nn ;JP PE,nn
1843 instr do_fetch_DE, op_EXHL, do_store_DE ;EB ;EX DE,HL
1844 instr do_fetch_DIR16, op_IFPE, do_store_CALL ;EC nn nn ;CALL PE,nn
1845 instr do_fetch_nop, op_INV, do_store_nop ;ED ;(Z80 specific)
1846 instr do_fetch_DIR8, op_XORA, do_store_nop ;EE nn ;XOR n
1847 instr do_fetch_RST, op_nop, do_store_CALL ;EF ;RST 28H
1848 instr do_fetch_nop, op_IFP, do_store_RET ;F0 ;RET P
1849 instr do_fetch_nop, op_POP16, do_store_AF ;F1 ;POP AF
1850 instr do_fetch_DIR16, op_IFP, do_store_PC ;F2 nn nn ;JP P,nn
1851 instr do_fetch_nop, op_DI, do_store_nop ;F3 ;DI
1852 instr do_fetch_DIR16, op_IFP, do_store_CALL ;F4 nn nn ;CALL P,nn
1853 instr do_fetch_AF, op_PUSH16, do_store_nop ;F5 ;PUSH AF
1854 instr do_fetch_DIR8, op_ORA, do_store_nop ;F6 nn ;OR n
1855 instr do_fetch_RST, op_nop, do_store_CALL ;F7 ;RST 30H
1856 instr do_fetch_nop, op_IFM, do_store_RET ;F8 ;RET M
1857 instr do_fetch_HL, op_nop, do_store_SP ;F9 ;LD SP,HL
1858 instr do_fetch_DIR16, op_IFM, do_store_PC ;FA nn nn ;JP M,nn
1859 instr do_fetch_nop, op_EI, do_store_nop ;FB ;EI
1860 instr do_fetch_DIR16, op_IFM, do_store_CALL ;FC nn nn ;CALL M,nn
1861 instr do_fetch_nop, op_INV, do_store_nop ;FD ;(Z80 specific)
1862 instr do_fetch_DIR8, op_CPFA, do_store_nop ;FE nn ;CP n
1863 instr do_fetch_RST, op_nop, do_store_CALL ;FF ;RST 38H
1866 ;----------------------------------------------------------------
1867 ; Lookup table, stolen from z80ex, Z80 emulation library.
1868 ; http://z80ex.sourceforge.net/
1870 ; The S, Z, 5 and 3 bits and the parity of the lookup value
1872 .org (PC+255) & 0xff00
1874 .db 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1875 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1876 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1877 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1878 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1879 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1880 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1881 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1882 .db 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04
1883 .db 0x0c,0x08,0x08,0x0c,0x08,0x0c,0x0c,0x08
1884 .db 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00
1885 .db 0x08,0x0c,0x0c,0x08,0x0c,0x08,0x08,0x0c
1886 .db 0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20
1887 .db 0x28,0x2c,0x2c,0x28,0x2c,0x28,0x28,0x2c
1888 .db 0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24
1889 .db 0x2c,0x28,0x28,0x2c,0x28,0x2c,0x2c,0x28
1890 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1891 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1892 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1893 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1894 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1895 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1896 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1897 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1898 .db 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80
1899 .db 0x88,0x8c,0x8c,0x88,0x8c,0x88,0x88,0x8c
1900 .db 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84
1901 .db 0x8c,0x88,0x88,0x8c,0x88,0x8c,0x8c,0x88
1902 .db 0xa0,0xa4,0xa4,0xa0,0xa4,0xa0,0xa0,0xa4
1903 .db 0xac,0xa8,0xa8,0xac,0xa8,0xac,0xac,0xa8
1904 .db 0xa4,0xa0,0xa0,0xa4,0xa0,0xa4,0xa4,0xa0
1905 .db 0xa8,0xac,0xac,0xa8,0xac,0xa8,0xa8,0xac
1907 ; vim:set ts=8 noet nowrap